From acde8c08330dbdd21c8453ff9fcc75395fcbe244 Mon Sep 17 00:00:00 2001 From: DanS Date: Fri, 17 Jul 2026 18:44:29 -0500 Subject: [PATCH] feat(config): chat-customization + app-wide clock settings Persisted (additive JSON, clamped on load) preferences backing the new chat settings surface and the global clock: - chat: emoji style (color default), poll rate, bubble style + accent, message density, text scale, per-tab timestamp override, Enter-to-send. - app-wide time_format (0=24h, 1=12h) that the Chat tab falls back to and every other user-facing timestamp now follows. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/config/settings.cpp | 19 +++++++++++++++++++ src/config/settings.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/config/settings.cpp b/src/config/settings.cpp index 499a742..858dfd8 100644 --- a/src/config/settings.cpp +++ b/src/config/settings.cpp @@ -157,6 +157,16 @@ bool Settings::load(const std::string& path) for (const auto& c : j["hidden_chat_cids"]) if (c.is_string()) hidden_chat_cids_.push_back(c.get()); } + // Chat-tab customization (re-clamped through the setters so hand-edited JSON stays in range). + loadScalar(j, "chat_emoji_color", chat_emoji_color_); + loadScalar(j, "chat_poll_rate_sec", chat_poll_rate_sec_); setChatPollRateSec(chat_poll_rate_sec_); + loadScalar(j, "chat_bubble_style", chat_bubble_style_); setChatBubbleStyle(chat_bubble_style_); + loadScalar(j, "chat_bubble_accent", chat_bubble_accent_); setChatBubbleAccent(chat_bubble_accent_); + loadScalar(j, "chat_density", chat_density_); setChatDensity(chat_density_); + loadScalar(j, "chat_font_scale", chat_font_scale_); setChatFontScale(chat_font_scale_); + loadScalar(j, "chat_time_format", chat_time_format_); setChatTimeFormat(chat_time_format_); + loadScalar(j, "chat_enter_sends", chat_enter_sends_); + loadScalar(j, "time_format", time_format_); setTimeFormat(time_format_); loadScalar(j, "acrylic_enabled", acrylic_enabled_); loadScalar(j, "acrylic_quality", acrylic_quality_); loadScalar(j, "blur_multiplier", blur_multiplier_); @@ -438,6 +448,15 @@ bool Settings::save(const std::string& path) j["hidden_chat_cids"] = json::array(); for (const auto& c : hidden_chat_cids_) j["hidden_chat_cids"].push_back(c); + j["chat_emoji_color"] = chat_emoji_color_; + j["chat_poll_rate_sec"] = chat_poll_rate_sec_; + j["chat_bubble_style"] = chat_bubble_style_; + j["chat_bubble_accent"] = chat_bubble_accent_; + j["chat_density"] = chat_density_; + j["chat_font_scale"] = chat_font_scale_; + j["chat_time_format"] = chat_time_format_; + j["chat_enter_sends"] = chat_enter_sends_; + j["time_format"] = time_format_; j["acrylic_enabled"] = acrylic_enabled_; j["acrylic_quality"] = acrylic_quality_; j["blur_multiplier"] = blur_multiplier_; diff --git a/src/config/settings.h b/src/config/settings.h index 59f31d4..527b3ca 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -143,6 +143,27 @@ public: hidden_chat_cids_.end()); } + // ── Chat-tab customization (chat settings modal + Settings → Chat & Contacts) ────── + bool getChatEmojiColor() const { return chat_emoji_color_; } + void setChatEmojiColor(bool v) { chat_emoji_color_ = v; } + float getChatPollRateSec() const { return chat_poll_rate_sec_; } + void setChatPollRateSec(float v) { chat_poll_rate_sec_ = std::max(0.5f, std::min(15.0f, v)); } + int getChatBubbleStyle() const { return chat_bubble_style_; } + void setChatBubbleStyle(int v) { chat_bubble_style_ = (v < 0 || v > 2) ? 0 : v; } + int getChatBubbleAccent() const { return chat_bubble_accent_; } + void setChatBubbleAccent(int v) { chat_bubble_accent_ = (v < 0 || v > 5) ? 0 : v; } + int getChatDensity() const { return chat_density_; } + void setChatDensity(int v) { chat_density_ = (v < 0 || v > 1) ? 0 : v; } + float getChatFontScale() const { return chat_font_scale_; } + void setChatFontScale(float v) { chat_font_scale_ = std::max(0.8f, std::min(1.5f, v)); } + int getChatTimeFormat() const { return chat_time_format_; } // 0=follow global, 1=24h, 2=12h + void setChatTimeFormat(int v) { chat_time_format_ = (v < 0 || v > 2) ? 0 : v; } + bool getChatEnterSends() const { return chat_enter_sends_; } + void setChatEnterSends(bool v) { chat_enter_sends_ = v; } + // Global clock format (0=24h, 1=12h) — chat can override it for the Chat tab only. + int getTimeFormat() const { return time_format_; } + void setTimeFormat(int v) { time_format_ = (v < 0 || v > 1) ? 0 : v; } + // Privacy bool getSaveZtxs() const { return save_ztxs_; } void setSaveZtxs(bool save) { save_ztxs_ = save; } @@ -500,6 +521,16 @@ private: std::string chat_reply_zaddr_; std::vector muted_chat_cids_; // muted chat conversations by cid (Q10) std::vector hidden_chat_cids_; // hidden chat conversations by cid + // Chat-tab customization (chat settings modal + Settings → Chat & Contacts). + bool chat_emoji_color_ = true; // true = color (needs FreeType; falls back to mono if absent), false = monochrome + float chat_poll_rate_sec_ = 2.5f; // 0-conf chat fast-scan cadence (full node) + int chat_bubble_style_ = 0; // 0 = rounded, 1 = square, 2 = minimal + int chat_bubble_accent_ = 0; // outgoing-bubble accent preset (0 = theme primary) + int chat_density_ = 0; // 0 = comfortable, 1 = compact + float chat_font_scale_ = 1.0f; // message text scale + int chat_time_format_ = 0; // 0 = follow global, 1 = 24h, 2 = 12h (Chat tab only) + bool chat_enter_sends_ = true; // Enter sends (vs. inserts newline; Ctrl+Enter sends) + int time_format_ = 0; // global clock: 0 = 24h, 1 = 12h bool save_ztxs_ = true; bool auto_shield_ = true; bool use_tor_ = false;