summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Borovkov <iborovkov@productengine.com>2009-10-26 17:40:48 +0200
committerIgor Borovkov <iborovkov@productengine.com>2009-10-26 17:40:48 +0200
commit5892411348cdc5ff107caa525570ee0db3ac34f6 (patch)
tree1189b289fbe75b4a6338bd0996c3254805cf8ff4
parente931d2d6f1a7d981bebf07b1d089fa4751096830 (diff)
parentf22f829b8642d59cb5953eb33f5297a1da90fadd (diff)
merge
--HG-- branch : product-engine
-rw-r--r--indra/newview/llimfloater.cpp135
-rw-r--r--indra/newview/llimfloater.h18
-rw-r--r--indra/newview/llimview.cpp6
-rw-r--r--indra/newview/skins/default/xui/en/floater_nearby_chat.xml1
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml10
5 files changed, 158 insertions, 12 deletions
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 57e3fba3f5..5813faa133 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -61,7 +61,14 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
mLastMessageIndex(-1),
mDialog(IM_NOTHING_SPECIAL),
mChatHistory(NULL),
- mInputEditor(NULL),
+ mInputEditor(NULL),
+ mSavedTitle(),
+ mTypingStart(),
+ mShouldSendTypingState(false),
+ mMeTyping(false),
+ mOtherTyping(false),
+ mTypingTimer(),
+ mTypingTimeoutTimer(),
mPositioned(false),
mSessionInitialized(false)
{
@@ -95,6 +102,7 @@ void LLIMFloater::onFocusReceived()
// virtual
void LLIMFloater::onClose(bool app_quitting)
{
+ setTyping(false);
gIMMgr->leaveSession(mSessionID);
}
@@ -141,6 +149,7 @@ void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
{
LLIMFloater* self = (LLIMFloater*) userdata;
self->sendMsg();
+ self->setTyping(false);
}
void LLIMFloater::sendMsg()
@@ -228,12 +237,27 @@ BOOL LLIMFloater::postBuild()
LLLogChat::loadHistory(getTitle(), &chatFromLogFile, (void *)this);
}
+ mTypingStart = LLTrans::getString("IM_typing_start_string");
+
//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
//see LLFloaterIMPanel for how it is done (IB)
return LLDockableFloater::postBuild();
}
+// virtual
+void LLIMFloater::draw()
+{
+ if ( mMeTyping )
+ {
+ // Time out if user hasn't typed for a while.
+ if ( mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS )
+ {
+ setTyping(false);
+ }
+ }
+ LLFloater::draw();
+}
// static
@@ -451,7 +475,7 @@ void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void*
void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
{
LLIMFloater* self = (LLIMFloater*) userdata;
- self->setTyping(FALSE);
+ self->setTyping(false);
}
// static
@@ -461,19 +485,118 @@ void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
std::string text = self->mInputEditor->getText();
if (!text.empty())
{
- self->setTyping(TRUE);
+ self->setTyping(true);
}
else
{
// Deleting all text counts as stopping typing.
- self->setTyping(FALSE);
+ self->setTyping(false);
+ }
+}
+
+void LLIMFloater::setTyping(bool typing)
+{
+ if ( typing )
+ {
+ // Started or proceeded typing, reset the typing timeout timer
+ mTypingTimeoutTimer.reset();
+ }
+
+ if ( mMeTyping != typing )
+ {
+ // Typing state is changed
+ mMeTyping = typing;
+ // So, should send current state
+ mShouldSendTypingState = true;
+ // In case typing is started, send state after some delay
+ mTypingTimer.reset();
+ }
+
+ // Don't want to send typing indicators to multiple people, potentially too
+ // much network traffic. Only send in person-to-person IMs.
+ if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL )
+ {
+ if ( mMeTyping )
+ {
+ if ( mTypingTimer.getElapsedTimeF32() > 1.f )
+ {
+ // Still typing, send 'start typing' notification
+ LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, TRUE);
+ mShouldSendTypingState = false;
+ }
+ }
+ else
+ {
+ // Send 'stop typing' notification immediately
+ LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, FALSE);
+ mShouldSendTypingState = false;
+ }
+ }
+
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (speaker_mgr)
+ speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
+
+}
+
+void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
+{
+ if ( typing )
+ {
+ // other user started typing
+ addTypingIndicator(im_info);
+ }
+ else
+ {
+ // other user stopped typing
+ removeTypingIndicator(im_info);
}
}
+void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info)
+{
+ // We may have lost a "stop-typing" packet, don't add it twice
+ if ( im_info && !mOtherTyping )
+ {
+ mOtherTyping = true;
-//just a stub for now
-void LLIMFloater::setTyping(BOOL typing)
+ // Create typing is started title string
+ LLUIString typing_start(mTypingStart);
+ typing_start.setArg("[NAME]", im_info->mName);
+
+ // Save and set new title
+ mSavedTitle = getTitle();
+ setTitle (typing_start);
+
+ // Update speaker
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if ( speaker_mgr )
+ {
+ speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE);
+ }
+ }
+}
+
+void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
{
+ if ( mOtherTyping )
+ {
+ mOtherTyping = false;
+
+ // Revert the title to saved one
+ setTitle(mSavedTitle);
+
+ if ( im_info )
+ {
+ // Update speaker
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if ( speaker_mgr )
+ {
+ speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
+ }
+ }
+
+ }
}
void LLIMFloater::chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata)
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 99810b6d6d..3559e14c89 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -55,6 +55,8 @@ public:
// LLView overrides
/*virtual*/ BOOL postBuild();
/*virtual*/ void setVisible(BOOL visible);
+ // Check typing timeout timer.
+ /*virtual*/ void draw();
// LLFloater overrides
/*virtual*/ void onClose(bool app_quitting);
@@ -85,6 +87,7 @@ public:
void setPositioned(bool b) { mPositioned = b; };
void onVisibilityChange(const LLSD& new_visibility);
+ void processIMTyping(const LLIMInfo* im_info, BOOL typing);
private:
// process focus events to set a currently active session
@@ -94,7 +97,7 @@ private:
static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata );
static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
- void setTyping(BOOL typing);
+ void setTyping(bool typing);
void onSlide();
static void* createPanelIMControl(void* userdata);
static void* createPanelGroupControl(void* userdata);
@@ -103,6 +106,11 @@ private:
static void chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata);
+ // Add the "User is typing..." indicator.
+ void addTypingIndicator(const LLIMInfo* im_info);
+
+ // Remove the "User is typing..." indicator.
+ void removeTypingIndicator(const LLIMInfo* im_info = NULL);
LLPanelChatControlPanel* mControlPanel;
LLUUID mSessionID;
@@ -114,6 +122,14 @@ private:
LLLineEditor* mInputEditor;
bool mPositioned;
+ std::string mSavedTitle;
+ LLUIString mTypingStart;
+ bool mMeTyping;
+ bool mOtherTyping;
+ bool mShouldSendTypingState;
+ LLFrameTimer mTypingTimer;
+ LLFrameTimer mTypingTimeoutTimer;
+
bool mSessionInitialized;
LLSD mQueuedMsgsForInit;
};
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 439f0b3d1e..7414ebbbad 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1965,6 +1965,12 @@ void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
{
floater->processIMTyping(im_info, typing);
}
+
+ LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+ if ( im_floater )
+ {
+ im_floater->processIMTyping(im_info, typing);
+ }
}
class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
index 25d337ccec..d24d1b7064 100644
--- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
@@ -14,6 +14,7 @@
save_rect="true"
title="Nearby Chat"
save_visibility="true"
+ single_instance="true"
width="320">
<chat_history
allow_html="true"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 4c19b22ac5..7efda2b882 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -264,10 +264,6 @@
<string name="TrackYourCamera">Track your camera</string>
<string name="ControlYourCamera">Control your camera</string>
- <!-- IM -->
- <string name="IM_logging_string">-- Instant message logging enabled --</string>
- <string name="Unnamed">(Unnamed)</string>
-
<!-- Sim Access labels -->
<string name="SIM_ACCESS_PG">PG</string>
<string name="SIM_ACCESS_MATURE">Mature</string>
@@ -2884,7 +2880,11 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
Failed to start viewer
</string>
- <!-- IM system messages -->
+ <!-- IM system messages -->
+ <string name="IM_logging_string">-- Instant message logging enabled --</string>
+ <string name="IM_typing_start_string">[NAME] is typing...</string>
+ <string name="Unnamed">(Unnamed)</string>
+
<string name="ringing-im">
Joining Voice Chat...
</string>