feat(chat): show a progress hint while a tier-3 message is still arriving

Until now an incoming large message was invisible until every part landed.
ChatService::pendingLargeMessages() exposes the in-progress tier-3 receives
(conversation, chunks gathered / chunks needed) from the reassembly buffer, and
the chat tab renders a subtle centred line below the thread — "Receiving a large
message…  24 / 36 parts" — that updates each scan and disappears when the message
completes and surfaces as an ordinary bubble. A complete-but-withheld (sensitive
vault locked) group is not reported as incoming.

New string chat_receiving_large (English; 8 locales fall back). Unit test extended:
after the first slice the receive is reported in progress; after the whole message
arrives it is no longer pending.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 12:47:37 -05:00
co-authored by Claude Opus 4.8
parent acb6446076
commit dba97c8b35
5 changed files with 51 additions and 1 deletions
+7 -1
View File
@@ -15862,13 +15862,19 @@ void testHushChatTier3Reassembly()
ChatService svc;
svc.setIdentity(bob);
// Stage 1: only the FIRST transaction's slice has arrived — the message is incomplete, nothing surfaces.
// Stage 1: only the FIRST transaction's slice has arrived — the message is incomplete, nothing surfaces,
// but the in-progress receive is reported so the UI can show an "incoming large message" hint.
std::vector<HushChatTransactionMetadata> firstOnly(all.begin(), all.begin() + 1);
EXPECT_EQ(svc.ingest(firstOnly, {}, 1000), 0);
EXPECT_EQ((int)svc.store().conversation(cid).size(), 0);
auto prog = svc.pendingLargeMessages();
EXPECT_EQ((int)prog.size(), 1);
EXPECT_EQ(prog[0].conversation_id, cid);
EXPECT_TRUE(prog[0].received > 0 && prog[0].received < prog[0].total);
// Stage 2: the whole history re-arrives (every slice) — reassembled, decrypted and surfaced once.
EXPECT_EQ(svc.ingest(all, {}, 1000), 1);
EXPECT_EQ((int)svc.pendingLargeMessages().size(), 0); // completed -> no longer "incoming"
std::vector<ChatMessage> conv = svc.store().conversation(cid);
EXPECT_EQ((int)conv.size(), 1);
EXPECT_EQ(conv[0].body, big);