From 2f447dea73917b81d13f403a2f5b3c5c28379666 Mon Sep 17 00:00:00 2001 From: Nika <155402319+nacklequack@users.noreply.github.com> Date: Thu, 2 Jul 2026 19:29:18 -0700 Subject: [PATCH] Add group chat snooze menu --- indra/newview/llfloaterimsession.cpp | 23 ++++++++ indra/newview/llfloaterimsession.h | 1 + indra/newview/llgroupactions.cpp | 33 ++++++++++++ indra/newview/llgroupactions.h | 2 + indra/newview/llimprocessing.cpp | 7 ++- indra/newview/llimview.cpp | 52 ++++++++++++++++++- indra/newview/llimview.h | 15 ++++++ .../default/xui/en/floater_im_session.xml | 50 ++++++++++++++++++ 8 files changed, 180 insertions(+), 3 deletions(-) diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 5e17ece2487..799cfb85017 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -278,6 +278,28 @@ void LLFloaterIMSession::GearDoToSelectedGroup(const LLSD& userdata) // [/SL:KB] // [SL:KB] - Patch: Chat-Misc | Checked: 2014-03-22 (Catznip-3.6) +void LLFloaterIMSession::onSnoozeGroupClicked(const LLUICtrl* pCtrl) +{ + if (!pCtrl) + { + return; + } + + const std::string value = pCtrl->getValue().asString(); + if (value == "-1") + { + LLGroupActions::leaveIM(mSessionID); + } + else if (value.empty()) + { + LLGroupActions::snoozeIM(mSessionID, 0); + } + else + { + LLGroupActions::snoozeIM(mSessionID, boost::lexical_cast(value) * 60); + } +} + void LLFloaterIMSession::onTeleportClicked(const LLUICtrl* pCtrl) { if (pCtrl) @@ -478,6 +500,7 @@ bool LLFloaterIMSession::postBuild() mExtendedButtonPanel->getChild("profile_btn")->setCommitCallback(boost::bind(&LLFloaterIMSession::GearDoToSelectedGroup, this, "view_profile")); mExtendedButtonPanel->getChild("chat_history_btn")->setCommitCallback(boost::bind(&LLFloaterIMSession::GearDoToSelectedGroup, this, "chat_history")); mExtendedButtonPanel->getChild("view_notices_btn")->setCommitCallback(boost::bind(&LLFloaterIMSession::GearDoToSelectedGroup, this, "view_notices")); + mExtendedButtonPanel->getChild("snooze_groupt_btn")->setCommitCallback(boost::bind(&LLFloaterIMSession::onSnoozeGroupClicked, this, _1)); } // [/SL:KB] diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h index 72c780a319b..edc8961e667 100644 --- a/indra/newview/llfloaterimsession.h +++ b/indra/newview/llfloaterimsession.h @@ -112,6 +112,7 @@ class LLFloaterIMSession bool checkGearMenuItem(const LLSD& userdata); // [SL:KB] - Patch: Chat-Misc | Checked: 2014-03-22 (Catznip-3.6) void onTeleportClicked(const LLUICtrl* pCtrl); + void onSnoozeGroupClicked(const LLUICtrl* pCtrl); // [/SL:KB] // [SL:KB] - Patch: Chat-BaseGearBtn | Checked: 2014-04-10 (Catznip-3.6) void GearDoToSelectedGroup(const LLSD& userdata); diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index f6a796b95fd..2f637748d09 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -605,6 +605,27 @@ LLUUID LLGroupActions::startIM(const LLUUID& group_id) } } +static void close_group_im(const LLUUID& group_id, LLIMModel::LLIMSession::SCloseAction close_action, S32 snooze_duration = -1) +{ + if (group_id.isNull()) + { + return; + } + + LLUUID session_id = gIMMgr->computeSessionID(IM_SESSION_GROUP_START, group_id); + if (session_id.notNull()) + { + LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id); + if (session) + { + session->mCloseAction = close_action; + session->mSnoozeDuration = snooze_duration; + } + + gIMMgr->leaveSession(session_id); + } +} + // static void LLGroupActions::endIM(const LLUUID& group_id) { @@ -618,6 +639,18 @@ void LLGroupActions::endIM(const LLUUID& group_id) } } +// static +void LLGroupActions::leaveIM(const LLUUID& group_id) +{ + close_group_im(group_id, LLIMModel::LLIMSession::SCloseAction::CLOSE_LEAVE); +} + +// static +void LLGroupActions::snoozeIM(const LLUUID& group_id, S32 snooze_duration) +{ + close_group_im(group_id, LLIMModel::LLIMSession::SCloseAction::CLOSE_SNOOZE, snooze_duration); +} + // static bool LLGroupActions::isInGroup(const LLUUID& group_id) { diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h index 4e1613f26c4..8f406583190 100644 --- a/indra/newview/llgroupactions.h +++ b/indra/newview/llgroupactions.h @@ -105,6 +105,8 @@ class LLGroupActions * End group instant messaging session. */ static void endIM(const LLUUID& group_id); + static void leaveIM(const LLUUID& group_id); + static void snoozeIM(const LLUUID& group_id, S32 snooze_duration = -1); /// Returns if the current user is a member of the group static bool isInGroup(const LLUUID& group_id); diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 7e69cb65aac..149aebf609e 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -1345,7 +1345,12 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, // should happen after you get an "invitation" if (!gIMMgr->hasSession(session_id)) { - return; + if (!gAgent.isInGroup(session_id) || + !gIMMgr->checkSnoozeExpiration(session_id) || + !gIMMgr->restoreSnoozedSession(session_id)) + { + return; + } } else if (offline == IM_ONLINE && is_do_not_disturb) diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index db91136e324..fa9b4a053b2 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -3556,7 +3556,17 @@ bool LLIMMgr::leaveSession(const LLUUID& session_id) LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id); if (!im_session) return false; - LLIMModel::getInstance()->sendLeaveSession(session_id, im_session->mOtherParticipantID); + if (im_session->isGroupSessionType() && im_session->mCloseAction == LLIMModel::LLIMSession::SCloseAction::CLOSE_SNOOZE) + { + const F64 duration = llmax(0, im_session->mSnoozeDuration); + mSnoozedSessions[session_id] = LLTimer::getTotalSeconds() + duration; + } + else + { + LLIMModel::getInstance()->sendLeaveSession(session_id, im_session->mOtherParticipantID); + mSnoozedSessions.erase(session_id); + } + gIMMgr->removeSession(session_id); return true; } @@ -3747,6 +3757,45 @@ bool LLIMMgr::hasSession(const LLUUID& session_id) return LLIMModel::getInstance()->findIMSession(session_id) != NULL; } +bool LLIMMgr::checkSnoozeExpiration(const LLUUID& session_id) const +{ + snoozed_sessions_t::const_iterator it = mSnoozedSessions.find(session_id); + return it != mSnoozedSessions.end() && it->second <= LLTimer::getTotalSeconds(); +} + +bool LLIMMgr::isSnoozedSession(const LLUUID& session_id) const +{ + return mSnoozedSessions.find(session_id) != mSnoozedSessions.end(); +} + +bool LLIMMgr::restoreSnoozedSession(const LLUUID& session_id) +{ + snoozed_sessions_t::iterator it = mSnoozedSessions.find(session_id); + if (it == mSnoozedSessions.end()) + { + return false; + } + + mSnoozedSessions.erase(it); + + LLGroupData group_data; + if (!gAgent.getGroupData(session_id, group_data)) + { + return false; + } + + gIMMgr->addSession(group_data.mName, IM_SESSION_GROUP_START, session_id); + + uuid_vec_t ids; + LLIMModel::sendStartSession(session_id, session_id, ids, IM_SESSION_GROUP_START, false); + + if (!gAgent.isDoNotDisturb()) + { + make_ui_sound("UISndStartIM"); + } + return true; +} + void LLIMMgr::clearPendingInvitation(const LLUUID& session_id) { if ( mPendingInvitations.has(session_id.asString()) ) @@ -4441,4 +4490,3 @@ LLHTTPRegistration LLHTTPRegistration gHTTPRegistrationMessageChatterBoxInvitation( "/message/ChatterBoxInvitation"); - diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 23f90ca7958..6f286212583 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -79,6 +79,13 @@ class LLIMModel : public LLSingleton NONE_SESSION, } SType; + enum class SCloseAction + { + CLOSE_DEFAULT, + CLOSE_LEAVE, + CLOSE_SNOOZE + }; + LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const LLSD& voiceChannelInfo, const uuid_vec_t& ids, bool has_offline_msg); virtual ~LLIMSession(); @@ -122,6 +129,8 @@ class LLIMModel : public LLSingleton std::string mName; EInstantMessage mType; SType mSessionType; + SCloseAction mCloseAction = SCloseAction::CLOSE_DEFAULT; + S32 mSnoozeDuration = -1; LLUUID mOtherParticipantID; uuid_vec_t mInitialTargetIDs; std::string mHistoryFileName; @@ -444,6 +453,9 @@ class LLIMMgr : public LLSingleton void disconnectAllSessions(); bool hasSession(const LLUUID& session_id); + bool checkSnoozeExpiration(const LLUUID& session_id) const; + bool isSnoozedSession(const LLUUID& session_id) const; + bool restoreSnoozedSession(const LLUUID& session_id); static LLUUID computeSessionID(EInstantMessage dialog, const LLUUID& other_participant_id); @@ -529,6 +541,9 @@ class LLIMMgr : public LLSingleton LLSD mPendingInvitations; LLSD mPendingAgentListUpdates; + + typedef std::map snoozed_sessions_t; + snoozed_sessions_t mSnoozedSessions; }; class LLCallDialogManager : public LLSingleton diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 7c719b93f3b..980ff878dc1 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -301,6 +301,56 @@ tool_tip="View group notices" top="1" width="31" /> + + + + + + + + + + +