feat(chat): message bubbles, empty states, search, export, richer composer

Chat-tab backlog from the audit:

- V3/V7/Q7/Q9 — thread overhaul: direction-aligned rounded bubbles with
  sender/minute grouping and a grouped meta line; peer avatar in the header;
  hover shows the full timestamp; a right-aligned "not sent · Retry" affordance
  re-sends failed outgoing messages; a floating "Latest" pill appears when the
  thread is scrolled up.
- V4 — centered empty states (icon + title + hint) for the locked, no-conversations,
  and no-selection panes.
- V6 — faint sidebar tint on the conversation list + a tight single-line seam.
- Q5 — compact relative time ("now"/"5m"/"3h"/"2d"/"Mon DD") in the list preview.
- Q6 — multi-line composer (Enter sends, Ctrl+Enter newline) with a live byte
  counter against the on-chain body cap (= (512−len"utf8:")/2 − ABYTES = 236),
  Send disabled + counter reddened when over.
- Q8 — case-insensitive conversation search over name + last body (thread stays
  open even when filtered out); "no matches" hint.
- Q11 — export a decrypted conversation to a plaintext file in the config dir
  (restricted perms, plaintext-warning tooltip), toasting the path.

English strings added to i18n.cpp; per-language JSONs follow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-16 16:41:00 -05:00
parent 7f46d9e2d5
commit bce69362eb
2 changed files with 254 additions and 36 deletions

View File

@@ -236,6 +236,20 @@ void I18n::loadBuiltinEnglish()
strings_["chat_toast_compose_failed"] = "Could not compose the message (too long?).";
strings_["chat_toast_request_compose_failed"] = "Could not compose the contact request (invalid address / text?).";
strings_["chat_toast_request_queued"] = "Contact request queued.";
strings_["chat_time_now"] = "now";
strings_["chat_retry"] = "Retry";
strings_["chat_jump_latest"] = "Latest";
strings_["chat_empty_title"] = "No conversations yet";
strings_["chat_empty_hint"] = "Start one with \"New conversation\".";
strings_["chat_search"] = "Search conversations";
strings_["chat_no_matches"] = "No conversations match your search.";
strings_["chat_export"] = "Export chat\xE2\x80\xA6";
strings_["chat_export_warn"] = "Saves the decrypted messages as plain text. Store the file securely.";
strings_["chat_export_done"] = "Conversation exported";
strings_["chat_export_failed"] = "Could not write the export file.";
strings_["chat_len_over"] = "Message too long";
strings_["chat_mute"] = "Mute";
strings_["chat_unmute"] = "Unmute";
// Seed-phrase backup (full-node)
strings_["seed_backup_button"] = "Seed phrase";
strings_["tt_seed_backup"] = "Show and back up your wallet's 24-word recovery seed phrase";