Sync to fix using gMessageSystem when it may not have the right message
This commit is contained in:
@@ -801,7 +801,7 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol
|
||||
// Now we're adding the actual line of text, so erase the
|
||||
// "Foo is typing..." text segment, and the optional timestamp
|
||||
// if it was present. JC
|
||||
removeTypingIndicator(NULL);
|
||||
removeTypingIndicator(source);
|
||||
|
||||
// Actually add the line
|
||||
bool prepend_newline = true;
|
||||
@@ -1458,7 +1458,7 @@ void LLFloaterIMPanel::onSendMsg()
|
||||
|
||||
bool other_was_typing = mOtherTyping;
|
||||
addHistoryLine(utf8_text, gSavedSettings.getColor("UserChatColor"), true, gAgentID, name);
|
||||
if (other_was_typing) addTypingIndicator(mOtherTypingName);
|
||||
if (other_was_typing) addTypingIndicator(mOtherParticipantUUID);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1588,53 +1588,84 @@ void LLFloaterIMPanel::sendTypingState(bool typing)
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterIMPanel::processIMTyping(const LLIMInfo* im_info, bool typing)
|
||||
void LLFloaterIMPanel::processIMTyping(const LLUUID& from_id, BOOL typing)
|
||||
{
|
||||
if (typing)
|
||||
{
|
||||
// other user started typing
|
||||
std::string name;
|
||||
if (!LLAvatarNameCache::getNSName(im_info->mFromID, name)) name = im_info->mName;
|
||||
addTypingIndicator(name);
|
||||
addTypingIndicator(from_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// other user stopped typing
|
||||
removeTypingIndicator(im_info);
|
||||
removeTypingIndicator(from_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterIMPanel::addTypingIndicator(const std::string &name)
|
||||
void LLFloaterIMPanel::addTypingIndicator(const LLUUID& from_id)
|
||||
{
|
||||
// we may have lost a "stop-typing" packet, don't add it twice
|
||||
if (!mOtherTyping)
|
||||
// Singu TODO: Actually implement this?
|
||||
/* Operation of "<name> is typing" state machine:
|
||||
Not Typing state:
|
||||
|
||||
User types in P2P IM chat ... Send Start Typing, save Started time,
|
||||
start Idle Timer (N seconds) go to Typing state
|
||||
|
||||
Typing State:
|
||||
|
||||
User enters a non-return character: if Now - Started > ME_TYPING_TIMEOUT, send
|
||||
Start Typing, restart Idle Timer
|
||||
User enters a return character: stop Idle Timer, send IM and Stop
|
||||
Typing, go to Not Typing state
|
||||
Idle Timer expires: send Stop Typing, go to Not Typing state
|
||||
|
||||
The recipient has a complementary state machine in which a Start Typing
|
||||
that is not followed by either an IM or another Start Typing within OTHER_TYPING_TIMEOUT
|
||||
seconds switches the sender out of typing state.
|
||||
|
||||
This has the nice quality of being self-healing for lost start/stop
|
||||
messages while adding messages only for the (relatively rare) case of a
|
||||
user who types a very long message (one that takes more than ME_TYPING_TIMEOUT seconds
|
||||
to type).
|
||||
|
||||
Note: OTHER_TYPING_TIMEOUT must be > ME_TYPING_TIMEOUT for proper operation of the state machine
|
||||
|
||||
*/
|
||||
|
||||
// We may have lost a "stop-typing" packet, don't add it twice
|
||||
if (from_id.notNull() && !mOtherTyping)
|
||||
{
|
||||
mOtherTyping = true;
|
||||
// Save im_info so that removeTypingIndicator can be properly called because a timeout has occurred
|
||||
LLAvatarNameCache::getNSName(from_id, mOtherTypingName);
|
||||
|
||||
mTypingLineStartIndex = mHistoryEditor->getWText().length();
|
||||
LLUIString typing_start = sTypingStartString;
|
||||
typing_start.setArg("[NAME]", name);
|
||||
typing_start.setArg("[NAME]", mOtherTypingName);
|
||||
addHistoryLine(typing_start, gSavedSettings.getColor4("SystemChatColor"), false);
|
||||
mOtherTypingName = name;
|
||||
mOtherTyping = true;
|
||||
|
||||
// Update speaker
|
||||
LLIMSpeakerMgr* speaker_mgr = mSpeakers;
|
||||
if ( speaker_mgr )
|
||||
{
|
||||
speaker_mgr->setSpeakerTyping(from_id, TRUE);
|
||||
}
|
||||
}
|
||||
// MBW -- XXX -- merge from release broke this (argument to this function changed from an LLIMInfo to a name)
|
||||
// Richard will fix.
|
||||
// mSpeakers->setSpeakerTyping(im_info->mFromID, TRUE);
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info)
|
||||
void LLFloaterIMPanel::removeTypingIndicator(const LLUUID& from_id)
|
||||
{
|
||||
if (mOtherTyping)
|
||||
{
|
||||
// Must do this first, otherwise addHistoryLine calls us again.
|
||||
mOtherTyping = false;
|
||||
|
||||
S32 chars_to_remove = mHistoryEditor->getWText().length() - mTypingLineStartIndex;
|
||||
mHistoryEditor->removeTextFromEnd(chars_to_remove);
|
||||
if (im_info)
|
||||
|
||||
if (from_id.notNull())
|
||||
{
|
||||
mSpeakers->setSpeakerTyping(im_info->mFromID, FALSE);
|
||||
mSpeakers->setSpeakerTyping(from_id, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public:
|
||||
void sessionInitReplyReceived(const LLUUID& im_session_id);
|
||||
|
||||
// Handle other participant in the session typing.
|
||||
void processIMTyping(const LLIMInfo* im_info, bool typing);
|
||||
void processIMTyping(const LLUUID& from_id, BOOL typing);
|
||||
static void chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata);
|
||||
|
||||
//show error statuses to the user
|
||||
@@ -177,10 +177,10 @@ private:
|
||||
void setTyping(bool typing);
|
||||
|
||||
// Add the "User is typing..." indicator.
|
||||
void addTypingIndicator(const std::string &name);
|
||||
void addTypingIndicator(const LLUUID& from_id);
|
||||
|
||||
// Remove the "User is typing..." indicator.
|
||||
void removeTypingIndicator(const LLIMInfo* im_info);
|
||||
void removeTypingIndicator(const LLUUID& from_id = LLUUID::null);
|
||||
|
||||
void sendTypingState(bool typing);
|
||||
|
||||
|
||||
@@ -641,8 +641,7 @@ void LLIMProcessing::processNewMessage(const LLUUID& from_id,
|
||||
{
|
||||
RlvUtil::sendBusyMessage(from_id, RlvStrings::getVersion(), session_id);
|
||||
// We won't receive a typing stop message, so do that manually (see comment at the end of LLFloaterIMPanel::sendMsg)
|
||||
LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
|
||||
gIMMgr->processIMTypingStop(im_info);
|
||||
gIMMgr->processIMTypingStop(from_id, dialog);
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
else if (offline == IM_ONLINE
|
||||
@@ -918,16 +917,15 @@ void LLIMProcessing::processNewMessage(const LLUUID& from_id,
|
||||
autoresponder_finish(show_autoresponded, session_id, from_id, name, itemid, is_muted);
|
||||
}
|
||||
}
|
||||
LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
|
||||
gIMMgr->processIMTypingStart(im_info);
|
||||
|
||||
gIMMgr->processIMTypingStart(from_id, dialog);
|
||||
script_msg_api(from_id.asString() + ", 4");
|
||||
}
|
||||
break;
|
||||
|
||||
case IM_TYPING_STOP:
|
||||
{
|
||||
LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
|
||||
gIMMgr->processIMTypingStop(im_info);
|
||||
gIMMgr->processIMTypingStop(from_id, dialog);
|
||||
script_msg_api(from_id.asString() + ", 5");
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1138,23 +1138,23 @@ void LLIMMgr::noteMutedUsers(LLFloaterIMPanel* floater,
|
||||
}
|
||||
}
|
||||
|
||||
void LLIMMgr::processIMTypingStart(const LLIMInfo* im_info)
|
||||
void LLIMMgr::processIMTypingStart(const LLUUID& from_id, const EInstantMessage im_type)
|
||||
{
|
||||
processIMTypingCore(im_info, TRUE);
|
||||
processIMTypingCore(from_id, im_type, TRUE);
|
||||
}
|
||||
|
||||
void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info)
|
||||
void LLIMMgr::processIMTypingStop(const LLUUID& from_id, const EInstantMessage im_type)
|
||||
{
|
||||
processIMTypingCore(im_info, FALSE);
|
||||
processIMTypingCore(from_id, im_type, FALSE);
|
||||
}
|
||||
|
||||
void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
|
||||
void LLIMMgr::processIMTypingCore(const LLUUID& from_id, const EInstantMessage im_type, BOOL typing)
|
||||
{
|
||||
LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID);
|
||||
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
|
||||
if (floater)
|
||||
LLUUID session_id = computeSessionID(im_type, from_id);
|
||||
LLFloaterIMPanel* im_floater = findFloaterBySession(session_id);
|
||||
if (im_floater)
|
||||
{
|
||||
floater->processIMTyping(im_info, typing);
|
||||
im_floater->processIMTyping(from_id, typing);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1275,10 +1275,10 @@ LLFloaterChatterBox* LLIMMgr::getFloater()
|
||||
return LLFloaterChatterBox::getInstance(LLSD());
|
||||
}
|
||||
|
||||
class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
|
||||
class LLViewerChatterBoxSessionStartReply final : public LLHTTPNode
|
||||
{
|
||||
public:
|
||||
virtual void describe(Description& desc) const
|
||||
void describe(Description& desc) const override
|
||||
{
|
||||
desc.shortInfo("Used for receiving a reply to a request to initialize an ChatterBox session");
|
||||
desc.postAPI();
|
||||
@@ -1287,18 +1287,15 @@ public:
|
||||
desc.source(__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
virtual void post(ResponsePtr response,
|
||||
void post(ResponsePtr response,
|
||||
const LLSD& context,
|
||||
const LLSD& input) const
|
||||
const LLSD& input) const override
|
||||
{
|
||||
LLSD body;
|
||||
LLUUID temp_session_id;
|
||||
LLUUID session_id;
|
||||
bool success;
|
||||
|
||||
body = input["body"];
|
||||
success = body["success"].asBoolean();
|
||||
temp_session_id = body["temp_session_id"].asUUID();
|
||||
LLSD body = input["body"];
|
||||
bool success = body["success"].asBoolean();
|
||||
LLUUID temp_session_id = body["temp_session_id"].asUUID();
|
||||
|
||||
if ( success )
|
||||
{
|
||||
@@ -1336,10 +1333,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class LLViewerChatterBoxSessionEventReply : public LLHTTPNode
|
||||
class LLViewerChatterBoxSessionEventReply final : public LLHTTPNode
|
||||
{
|
||||
public:
|
||||
virtual void describe(Description& desc) const
|
||||
void describe(Description& desc) const override
|
||||
{
|
||||
desc.shortInfo("Used for receiving a reply to a ChatterBox session event");
|
||||
desc.postAPI();
|
||||
@@ -1348,24 +1345,18 @@ public:
|
||||
desc.source(__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
virtual void post(ResponsePtr response,
|
||||
void post(ResponsePtr response,
|
||||
const LLSD& context,
|
||||
const LLSD& input) const
|
||||
const LLSD& input) const override
|
||||
{
|
||||
LLUUID session_id;
|
||||
bool success;
|
||||
|
||||
LLSD body = input["body"];
|
||||
success = body["success"].asBoolean();
|
||||
session_id = body["session_id"].asUUID();
|
||||
bool success = body["success"].asBoolean();
|
||||
LLUUID session_id = body["session_id"].asUUID();
|
||||
|
||||
if ( !success )
|
||||
{
|
||||
//throw an error dialog
|
||||
LLFloaterIMPanel* floater =
|
||||
gIMMgr->findFloaterBySession(session_id);
|
||||
|
||||
if (floater)
|
||||
if (auto* floater = gIMMgr->findFloaterBySession(session_id))
|
||||
{
|
||||
floater->showSessionEventError(
|
||||
body["event"].asString(),
|
||||
@@ -1378,46 +1369,40 @@ public:
|
||||
class LLViewerForceCloseChatterBoxSession: public LLHTTPNode
|
||||
{
|
||||
public:
|
||||
virtual void post(ResponsePtr response,
|
||||
void post(ResponsePtr response,
|
||||
const LLSD& context,
|
||||
const LLSD& input) const
|
||||
const LLSD& input) const override
|
||||
{
|
||||
LLUUID session_id;
|
||||
std::string reason;
|
||||
LLUUID session_id = input["body"]["session_id"].asUUID();
|
||||
std::string reason = input["body"]["reason"].asString();
|
||||
|
||||
session_id = input["body"]["session_id"].asUUID();
|
||||
reason = input["body"]["reason"].asString();
|
||||
|
||||
LLFloaterIMPanel* floater =
|
||||
gIMMgr ->findFloaterBySession(session_id);
|
||||
|
||||
if ( floater )
|
||||
if (auto* floater = gIMMgr ->findFloaterBySession(session_id))
|
||||
{
|
||||
floater->showSessionForceClose(reason);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class LLViewerChatterBoxSessionAgentListUpdates : public LLHTTPNode
|
||||
class LLViewerChatterBoxSessionAgentListUpdates final : public LLHTTPNode
|
||||
{
|
||||
public:
|
||||
virtual void post(
|
||||
void post(
|
||||
ResponsePtr responder,
|
||||
const LLSD& context,
|
||||
const LLSD& input) const
|
||||
const LLSD& input) const override
|
||||
{
|
||||
const LLUUID& session_id = input["body"]["session_id"].asUUID();
|
||||
gIMMgr->processAgentListUpdates(session_id, input["body"]);
|
||||
}
|
||||
};
|
||||
|
||||
class LLViewerChatterBoxSessionUpdate : public LLHTTPNode
|
||||
class LLViewerChatterBoxSessionUpdate final : public LLHTTPNode
|
||||
{
|
||||
public:
|
||||
virtual void post(
|
||||
void post(
|
||||
ResponsePtr responder,
|
||||
const LLSD& context,
|
||||
const LLSD& input) const
|
||||
const LLSD& input) const override
|
||||
{
|
||||
LLUUID session_id = input["body"]["session_id"].asUUID();
|
||||
LLFloaterIMPanel* im_floater = gIMMgr->findFloaterBySession(session_id);
|
||||
@@ -1445,14 +1430,14 @@ void leave_group_chat(const LLUUID& from_id, const LLUUID& session_id)
|
||||
gIMMgr->removeSession(session_id);
|
||||
}
|
||||
|
||||
class LLViewerChatterBoxInvitation : public LLHTTPNode
|
||||
class LLViewerChatterBoxInvitation final : public LLHTTPNode
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void post(
|
||||
void post(
|
||||
ResponsePtr response,
|
||||
const LLSD& context,
|
||||
const LLSD& input) const
|
||||
const LLSD& input) const override
|
||||
{
|
||||
//for backwards compatiblity reasons...we need to still
|
||||
//check for 'text' or 'voice' invitations...bleh
|
||||
@@ -1582,10 +1567,9 @@ public:
|
||||
LLFloaterChat::addChat(chat, TRUE, is_this_agent);
|
||||
|
||||
//K now we want to accept the invitation
|
||||
std::string url = gAgent.getRegion()->getCapability(
|
||||
"ChatSessionRequest");
|
||||
std::string url = gAgent.getRegionCapability("ChatSessionRequest");
|
||||
|
||||
if ( url != "" )
|
||||
if (!url.empty())
|
||||
{
|
||||
LLSD data;
|
||||
data["method"] = "accept invitation";
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
class LLFloaterChatterBox;
|
||||
class LLFloaterIMPanel;
|
||||
|
||||
class LLIMMgr : public LLSingleton<LLIMMgr>
|
||||
class LLIMMgr final : public LLSingleton<LLIMMgr>
|
||||
{
|
||||
public:
|
||||
enum EInvitationType
|
||||
@@ -121,8 +121,8 @@ public:
|
||||
void updateFloaterSessionID(const LLUUID& old_session_id,
|
||||
const LLUUID& new_session_id);
|
||||
|
||||
void processIMTypingStart(const LLIMInfo* im_info);
|
||||
void processIMTypingStop(const LLIMInfo* im_info);
|
||||
void processIMTypingStart(const LLUUID& from_id, const EInstantMessage im_type);
|
||||
void processIMTypingStop(const LLUUID& from_id, const EInstantMessage im_type);
|
||||
|
||||
void clearNewIMNotification();
|
||||
|
||||
@@ -209,7 +209,7 @@ private:
|
||||
void noteOfflineUsers(LLFloaterIMPanel* panel, const uuid_vec_t& ids);
|
||||
void noteMutedUsers(LLFloaterIMPanel* panel, const uuid_vec_t& ids);
|
||||
|
||||
void processIMTypingCore(const LLIMInfo* im_info, BOOL typing);
|
||||
void processIMTypingCore(const LLUUID& from_id, const EInstantMessage im_type, BOOL typing);
|
||||
|
||||
private:
|
||||
std::set<LLHandle<LLFloater> > mFloaters;
|
||||
|
||||
Reference in New Issue
Block a user