summaryrefslogtreecommitdiff
path: root/indra/newview/llnotificationhandlerutil.cpp
diff options
context:
space:
mode:
authorpepper <3782201+rohvani@users.noreply.github.com>2026-09-10 12:58:32 -0400
committerpepper <3782201+rohvani@users.noreply.github.com>2026-09-10 17:22:48 -0400
commitfe57d2caf1949abcdb54a35cb610b0eb9d783fd1 (patch)
tree15e822a42fe98bc69655100f85974aac9292179d /indra/newview/llnotificationhandlerutil.cpp
parent56b34b332727299f2d54d4d6e8dbe5a7cb54cb11 (diff)
Consolidate ChatService reconciliation and fix live IM replay
Merge archives, plaintext and head previews by service ID and occurrence before applying history limits. Keep loaded history and visible context in ChatService so IM sessions and previews share one composer, with ordinary live appends remaining independent of history replay. Preserve original bodies and send-versus-receipt timing through offline delivery and translation. Match known send times exactly and online receipt times within a rolling 60-second window. Consume eligible occurrences once in chronological order so repeated messages survive reconciliation across minute boundaries. Link offer fallback text to its notification ID and advance the replay cursor for each actual row. Missing or delayed fallback rows can no longer cause the following live IM to be skipped. Dispatch ChatService presentation through the main-loop queue with runtime and current-state checks. This prevents login deadlocks from reentering font initialization in another coroutine. Await deletion invalidation before continuing cleanup so a delayed clear cannot erase later messages. Validated with the Release viewer build, all 34 LLChatServiceHistoryCore cases, and native delivery, archive, offer replay and coroutine-deadlock fixtures. The deadlock fixtures reproduce the original hangs and pass with deferred presentation.
Diffstat (limited to 'indra/newview/llnotificationhandlerutil.cpp')
-rw-r--r--indra/newview/llnotificationhandlerutil.cpp27
1 files changed, 19 insertions, 8 deletions
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index fc973e00ae..935094fdc0 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -72,7 +72,7 @@ bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
const std::string& session_name, const std::string& from_name,
const std::string& message, const LLUUID& session_owner_id,
- const LLUUID& from_id)
+ const LLUUID& from_id, const LLUUID& notification_id)
{
std::string from = from_name;
if (from_name.empty())
@@ -111,6 +111,14 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
S32 participant_unread = session->mParticipantUnreadMessageCount;
LLIMModel::instance().addMessageSilently(session_id, from, from_id,
message);
+
+ // Link the text fallback to its inline offer before the floater sees it.
+ // Name lookup may complete after other messages have arrived.
+ if (notification_id.notNull())
+ {
+ session->mMsgs.front()["notification_log_id"] = notification_id;
+ }
+
// we shouldn't increment counters when logging, so restore them
session->mNumUnread = unread;
session->mParticipantUnreadMessageCount = participant_unread;
@@ -121,15 +129,17 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
}
void log_name_callback(const LLAvatarName& av_name, const std::string& from_name,
- const std::string& message, const LLUUID& from_id)
+ const std::string& message, const LLUUID& from_id,
+ const LLUUID& notification_id)
{
LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, av_name.getUserName(), from_name, message,
- from_id, LLUUID());
+ from_id, LLUUID(), notification_id);
}
// static
-void LLHandlerUtil::logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only)
+void LLHandlerUtil::logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only,
+ const LLUUID& notification_id)
{
if (!gCacheName)
{
@@ -145,19 +155,20 @@ void LLHandlerUtil::logToIMP2P(const LLUUID& from_id, const std::string& message
if(to_file_only)
{
- LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", message, LLUUID()));
+ LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", message, LLUUID(), notification_id));
}
else
{
- LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, message, from_id));
+ LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, message, from_id, notification_id));
}
}
// static
-void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
+void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only,
+ const LLUUID& notification_id)
{
LLUUID from_id = notification->getPayload()["from_id"];
- logToIMP2P(from_id, notification->getMessage(), to_file_only);
+ logToIMP2P(from_id, notification->getMessage(), to_file_only, notification_id);
}
// static