Transactions that carried a chat message (sent or received, messages + contact requests) now show a "Message" badge in the History tab, and a new "Chat" option in the type-filter combo shows only those transactions. Detection reuses what the chat store already tracks: ChatStore gains an inline chatTxids() returning the set of on-chain txids that carried a chat message; the tab builds it once per frame (cheap — O(chat messages)) and tests txid membership for the badge and the filter. Empty when chat is disabled or the wallet has no chat identity. Both variants populate the chat store before this tab renders, so the same code serves full-node and lite with no separate handling. The "Message" badge reuses the stacked top-pill slot (chat txs are send/receive, not the autoshield "shield" type, so it and the "Shielded" badge are mutually exclusive; chat takes precedence) in a distinct Secondary() colour. Guards the summary-card accent idx_map so the new filter value (4) can't index it OOB. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
53 lines
1.9 KiB
C++
53 lines
1.9 KiB
C++
#pragma once
|
|
|
|
// DragonX Wallet - HushChat in-memory message store: the fast read model / dedup view. Durable
|
|
// persistence lives in ChatDatabase; ChatService rehydrates this store from it on unlock.
|
|
|
|
#include "chat_message.h"
|
|
|
|
#include <string>
|
|
#include <unordered_set>
|
|
#include <vector>
|
|
|
|
namespace dragonx::chat {
|
|
|
|
// Threads messages by conversation_id (cid) and deduplicates by (txid, payload_position) so
|
|
// re-scanning the chain never double-inserts. Not thread-safe — drive from the main thread.
|
|
class ChatStore {
|
|
public:
|
|
// Returns true if newly inserted, false if a duplicate was ignored.
|
|
bool append(const ChatMessage& message);
|
|
|
|
// Messages in a conversation, in insertion order.
|
|
std::vector<ChatMessage> conversation(const std::string& conversationId) const;
|
|
|
|
// Update an outgoing echo's delivery status by its local txid. Returns a pointer to the updated
|
|
// message (for the caller to persist), or nullptr if no message has that txid.
|
|
const ChatMessage* updateDelivery(const std::string& txid, ChatDelivery delivery);
|
|
|
|
// Distinct conversation ids, in first-seen order.
|
|
std::vector<std::string> conversationIds() const;
|
|
|
|
// The set of on-chain txids that carried a chat message (sent or received, messages + contact
|
|
// requests) — used by the History tab to badge / filter chat transactions. O(messages), no copies.
|
|
std::unordered_set<std::string> chatTxids() const {
|
|
std::unordered_set<std::string> out;
|
|
out.reserve(messages_.size());
|
|
for (const auto& m : messages_)
|
|
if (!m.txid.empty()) out.insert(m.txid);
|
|
return out;
|
|
}
|
|
|
|
std::size_t size() const { return messages_.size(); }
|
|
bool empty() const { return messages_.empty(); }
|
|
void clear();
|
|
|
|
private:
|
|
static std::string dedupKey(const ChatMessage& message);
|
|
|
|
std::vector<ChatMessage> messages_;
|
|
std::unordered_set<std::string> seen_;
|
|
};
|
|
|
|
} // namespace dragonx::chat
|