feat(chat): mute conversations (Q10)
Per-conversation mute toggle in the thread header. Muted conversations (tracked by cid in settings, so it persists) are skipped by chatUnreadCount(), so they neither raise the nav-item unread badge nor the new-message toast — the toast now gates on a chatUnreadCount() delta across ingest, which already skips muted cids, so mute is respected for free. "Block" (rejecting a peer's inbound memos) is a larger ingest-filter change and is intentionally left out of this pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1233,6 +1233,7 @@ int App::chatUnreadCount() const
|
||||
int unread = 0;
|
||||
const auto& store = chat_service_.store();
|
||||
for (const auto& cid : store.conversationIds()) {
|
||||
if (settings_ && settings_->isChatMuted(cid)) continue; // muted conversations don't badge (Q10)
|
||||
std::int64_t seen = 0;
|
||||
const auto it = chat_seen_watermark_.find(cid);
|
||||
if (it != chat_seen_watermark_.end()) seen = it->second;
|
||||
@@ -1688,9 +1689,12 @@ void App::refreshTransactionData()
|
||||
!result.hushChatMetadata.empty()) {
|
||||
std::unordered_map<std::string, std::int64_t> chatTxTimes;
|
||||
for (const auto& tx : result.transactions) chatTxTimes[tx.txid] = tx.timestamp;
|
||||
const int unreadBefore = chatUnreadCount();
|
||||
const int newMsgs = chat_service_.ingest(result.hushChatMetadata, chatTxTimes, std::time(nullptr));
|
||||
if (newMsgs > 0 && current_page_ != ui::NavPage::Chat)
|
||||
ui::Notifications::instance().info(TR("chat_new_message_toast")); // Q4: alert when not on the Chat tab
|
||||
// Toast only when a non-muted conversation gained an unread message — chatUnreadCount()
|
||||
// already skips muted cids, so a delta cleanly respects mute (Q10 + Q4).
|
||||
if (newMsgs > 0 && current_page_ != ui::NavPage::Chat && chatUnreadCount() > unreadBefore)
|
||||
ui::Notifications::instance().info(TR("chat_new_message_toast"));
|
||||
}
|
||||
NetworkRefreshService::applyTransactionRefreshResult(
|
||||
state_, cacheUpdate, std::move(result), std::time(nullptr));
|
||||
@@ -1748,9 +1752,12 @@ void App::refreshRecentTransactionData()
|
||||
!result.hushChatMetadata.empty()) {
|
||||
std::unordered_map<std::string, std::int64_t> chatTxTimes;
|
||||
for (const auto& tx : result.transactions) chatTxTimes[tx.txid] = tx.timestamp;
|
||||
const int unreadBefore = chatUnreadCount();
|
||||
const int newMsgs = chat_service_.ingest(result.hushChatMetadata, chatTxTimes, std::time(nullptr));
|
||||
if (newMsgs > 0 && current_page_ != ui::NavPage::Chat)
|
||||
ui::Notifications::instance().info(TR("chat_new_message_toast")); // Q4: alert when not on the Chat tab
|
||||
// Toast only when a non-muted conversation gained an unread message — chatUnreadCount()
|
||||
// already skips muted cids, so a delta cleanly respects mute (Q10 + Q4).
|
||||
if (newMsgs > 0 && current_page_ != ui::NavPage::Chat && chatUnreadCount() > unreadBefore)
|
||||
ui::Notifications::instance().info(TR("chat_new_message_toast"));
|
||||
}
|
||||
NetworkRefreshService::applyTransactionRefreshResult(
|
||||
state_, cacheUpdate, std::move(result), std::time(nullptr));
|
||||
|
||||
Reference in New Issue
Block a user