fix(chat): un-hide on lite receives + scope the contact picker per wallet

Review of fc414ee found two issues:

- HIGH: the lite variant harvests chat via ingestLiteChatMemos, which called
  ingest() without the newIncomingCids out-param — so the un-hide never ran and a
  hidden conversation stayed hidden PERMANENTLY on new messages (chat is default-ON
  and fully supported in Lite), breaking the "a new message brings it back"
  invariant. Wire the same un-hide + off-tab toast into the lite path.

- LOW: the new-conversation contact picker listed every z-address contact,
  ignoring the per-wallet scope the Contacts tab enforces — leaking another
  wallet's scoped contact into this wallet's picker. Apply the same scope test
  (global + legacy fail open; "w:" scopes match the active wallet).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-16 23:36:14 -05:00
parent fc414eeed4
commit 29fbe46cce
2 changed files with 22 additions and 1 deletions

View File

@@ -635,9 +635,15 @@ void RenderChatTab(App* app)
// Selecting one fills the field above (manual paste still works).
ImGui::SetNextItemWidth(fieldW);
if (ImGui::BeginCombo("##newzpick", TR("chat_pick_contact"), ImGuiComboFlags_HeightLarge)) {
const std::string activeHash = app->activeWalletScopeId(); // per-wallet contact scope
int shown = 0;
for (const auto& e : book.entries()) {
if (e.address.empty() || e.address[0] != 'z') continue; // chat requires a z-address
// Respect the same per-wallet scope the Contacts tab enforces — don't leak another
// wallet's scoped contact into this wallet's picker (global + legacy fail open).
const bool visible = e.isGlobal() ||
(e.scope.rfind("w:", 0) == 0 ? (!activeHash.empty() && e.scope == activeHash) : true);
if (!visible) continue;
++shown;
const std::string item = e.label + " " + shorten(e.address, 16, 8);
if (ImGui::Selectable(item.c_str())) {