diff --git a/src/app_network.cpp b/src/app_network.cpp index 181a89d..3a213df 100644 --- a/src/app_network.cpp +++ b/src/app_network.cpp @@ -3147,7 +3147,22 @@ void App::ingestLiteChatMemos(const wallet::LiteWalletAppRefreshModel& model) auto extracted = chat::extractHushChatTransactionMetadata(entry.second, true); for (auto& meta : extracted.metadata) metadata.push_back(std::move(meta)); } - if (!metadata.empty()) chat_service_.ingest(metadata, txTimestamps, std::time(nullptr)); + if (!metadata.empty()) { + std::vector newChatCids; + chat_service_.ingest(metadata, txTimestamps, std::time(nullptr), &newChatCids); + // Mirror the full-node paths: a new incoming message un-hides a hidden conversation (you can't + // un-receive), and a non-muted new message toasts when we're off the Chat tab. + if (settings_) { + bool unhid = false; + for (const auto& cid : newChatCids) + if (settings_->isChatHidden(cid)) { settings_->setChatHidden(cid, false); unhid = true; } + if (unhid) settings_->save(); + } + if (current_page_ != ui::NavPage::Chat && + std::any_of(newChatCids.begin(), newChatCids.end(), + [this](const std::string& cid){ return !(settings_ && settings_->isChatMuted(cid)); })) + ui::Notifications::instance().info(TR("chat_new_message_toast")); + } } bool App::lockLiteWallet() diff --git a/src/ui/windows/chat_tab.cpp b/src/ui/windows/chat_tab.cpp index 32c5571..a31443e 100644 --- a/src/ui/windows/chat_tab.cpp +++ b/src/ui/windows/chat_tab.cpp @@ -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())) {