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:
2026-07-16 16:48:57 -05:00
co-authored by Claude Opus 4.8
parent fecc9015fb
commit 24c661f743
4 changed files with 40 additions and 4 deletions
+13
View File
@@ -118,6 +118,18 @@ public:
std::string getChatReplyZaddr() const { return chat_reply_zaddr_; }
void setChatReplyZaddr(const std::string& z) { chat_reply_zaddr_ = z; }
// Muted chat conversations (by cid) — muted conversations don't badge or raise a toast (Q10).
bool isChatMuted(const std::string& cid) const {
return std::find(muted_chat_cids_.begin(), muted_chat_cids_.end(), cid) != muted_chat_cids_.end();
}
void setChatMuted(const std::string& cid, bool muted) {
const bool already = isChatMuted(cid);
if (muted && !already) muted_chat_cids_.push_back(cid);
else if (!muted && already)
muted_chat_cids_.erase(std::remove(muted_chat_cids_.begin(), muted_chat_cids_.end(), cid),
muted_chat_cids_.end());
}
// Privacy
bool getSaveZtxs() const { return save_ztxs_; }
void setSaveZtxs(bool save) { save_ztxs_ = save; }
@@ -473,6 +485,7 @@ private:
std::string theme_ = "dragonx";
std::string skin_id_ = "dragonx";
std::string chat_reply_zaddr_;
std::vector<std::string> muted_chat_cids_; // muted chat conversations by cid (Q10)
bool save_ztxs_ = true;
bool auto_shield_ = true;
bool use_tor_ = false;