pub struct ChatState {
pub profiles: Vec<Profile>,
pub chats: Vec<Chat>,
pub interner: NpubInterner,
pub is_syncing: bool,
pub db_loaded: bool,
pub unread_cache: HashMap<String, u32>,
pub unread_seeded: bool,
pub cache_stats: CacheStats,
}Fields§
§profiles: Vec<Profile>§chats: Vec<Chat>§interner: NpubInterner§is_syncing: bool§db_loaded: bool§unread_cache: HashMap<String, u32>Authoritative per-chat RAW unread counts (chat_identifier → count), so the badge recount is an
in-RAM fold instead of a whole-DB scan. Seeded once per account from db::unread_counts (see
unread_seeded), then kept current per-chat: cleared on read, reconciled from the DB
(db::unread_count_for_chat) on inbound / delete / mark-unread. RAW = pre muted/blocked
filter; the sum applies those, matching sum_unread_from. Cleared on account reset.
unread_seeded: boolFalse until unread_cache has been seeded from the DB for this account. Guards the one-time
seed so the full-scan query runs once per login, never per message.
cache_stats: CacheStatsImplementations§
Source§impl ChatState
impl ChatState
pub fn new() -> Self
pub fn merge_db_profiles( &mut self, slim_profiles: Vec<SlimProfile>, my_npub: &str, )
pub fn insert_or_replace_profile(&mut self, npub: &str, profile: Profile)
pub fn get_profile(&self, npub: &str) -> Option<&Profile>
pub fn get_profile_mut(&mut self, npub: &str) -> Option<&mut Profile>
pub fn get_profile_by_id(&self, id: u16) -> Option<&Profile>
pub fn get_profile_mut_by_id(&mut self, id: u16) -> Option<&mut Profile>
pub fn serialize_profile(&self, id: u16) -> Option<SlimProfile>
pub fn get_chat(&self, id: &str) -> Option<&Chat>
pub fn get_chat_mut(&mut self, id: &str) -> Option<&mut Chat>
pub fn create_dm_chat(&mut self, their_npub: &str) -> String
Sourcepub fn ensure_community_chat(&mut self, channel_id: &str)
pub fn ensure_community_chat(&mut self, channel_id: &str)
Ensure a Community channel chat exists, created as ChatType::Community.
Sourcepub fn upsert_community_chat(
&mut self,
channel_id: &str,
name: &str,
description: &str,
community_id: &str,
is_owner: bool,
has_icon: bool,
owner_npub: Option<&str>,
created_at_ms: Option<u64>,
dissolved: bool,
protocol: ConcordProtocol,
channel_name: &str,
primary_channel: &str,
)
pub fn upsert_community_chat( &mut self, channel_id: &str, name: &str, description: &str, community_id: &str, is_owner: bool, has_icon: bool, owner_npub: Option<&str>, created_at_ms: Option<u64>, dissolved: bool, protocol: ConcordProtocol, channel_name: &str, primary_channel: &str, )
Create-or-update a Community channel chat with its display metadata, so the chat
row carries name/description/owning-community directly (and persists + loads like
any DM — no separate hydrate). is_owner/has_icon are stored as “true”/“1”
strings in custom_fields. The caller persists the row (save_slim_chat).
name is the COMMUNITY’s name (every channel row carries it, so the chat list can
label a community from any one of its rows); channel_name is this channel’s own.
primary_channel is the community’s primary channel id — equal to channel_id on
that row, and what the UI uses to render one list row per community while still
holding a chat per channel.
pub fn add_message_to_chat(&mut self, chat_id: &str, message: &Message) -> bool
pub fn add_messages_to_chat_batch( &mut self, chat_id: &str, messages: Vec<Message>, ) -> usize
Sourcepub fn add_message_to_participant(
&mut self,
their_npub: &str,
message: &Message,
) -> bool
pub fn add_message_to_participant( &mut self, their_npub: &str, message: &Message, ) -> bool
Add a message to a participant’s DM chat. Creates profile if missing.
Unlike the src-tauri version, emitting profile_update is the caller’s responsibility.
pub fn find_message(&self, message_id: &str) -> Option<(&Chat, Message)>
pub fn find_chat_for_message(&self, message_id: &str) -> Option<(usize, String)>
pub fn update_message<F>(
&mut self,
message_id: &str,
f: F,
) -> Option<(String, Message)>where
F: FnOnce(&mut CompactMessage),
pub fn update_message_in_chat<F>(
&mut self,
chat_id: &str,
message_id: &str,
f: F,
) -> Option<Message>where
F: FnOnce(&mut CompactMessage),
pub fn finalize_pending_message( &mut self, chat_id: &str, pending_id: &str, real_id: &str, ) -> Option<(String, Message)>
pub fn update_attachment<F>(
&mut self,
chat_hint: &str,
msg_id: &str,
attachment_id: &str,
f: F,
) -> boolwhere
F: FnOnce(&mut CompactAttachment),
pub fn add_attachment_to_message( &mut self, chat_id: &str, msg_id: &str, attachment: CompactAttachment, ) -> bool
pub fn add_reaction_to_message( &mut self, message_id: &str, reaction: Reaction, ) -> Option<(String, bool)>
Sourcepub fn find_reaction(
&self,
reaction_id: &str,
) -> Option<(String, String, String, bool)>
pub fn find_reaction( &self, reaction_id: &str, ) -> Option<(String, String, String, bool)>
Locate a reaction by its event id across all chats.
Returns (chat_id, parent_message_id, author_npub, is_community).
Sourcepub fn remove_reaction_from_message(
&mut self,
message_id: &str,
reaction_id: &str,
) -> Option<(String, Message)>
pub fn remove_reaction_from_message( &mut self, message_id: &str, reaction_id: &str, ) -> Option<(String, Message)>
Remove a reaction from its parent message. Returns (chat_id, updated Message)
for the UI refresh, or None if the reaction wasn’t present.
pub fn remove_message(&mut self, message_id: &str) -> Option<(String, Message)>
pub fn message_exists(&self, message_id: &str) -> bool
Sourcepub fn sum_unread_from(&self, counts: &HashMap<String, u32>) -> u32
pub fn sum_unread_from(&self, counts: &HashMap<String, u32>) -> u32
Sum DB-computed per-chat unread counts, applying the same muted/blocked filters as
[count_unread_messages] but sourcing each COUNT from counts (chat_identifier → unread)
rather than walking in-memory messages — so it’s correct even when only the last message per
chat is in RAM (the boot state). Muted chats and blocked-DM contacts contribute 0.
Sourcepub fn unread_seed(&mut self, counts: HashMap<String, u32>)
pub fn unread_seed(&mut self, counts: HashMap<String, u32>)
Seed the whole cache from a DB unread_counts() result and mark it seeded. Idempotent per
login; a later call replaces the map wholesale (used only if a reseed is ever forced).
Sourcepub fn unread_clear(&mut self, chat_id: &str)
pub fn unread_clear(&mut self, chat_id: &str)
The chat was read (opened / marked): zero its unread.
Sourcepub fn unread_set(&mut self, chat_id: &str, count: u32)
pub fn unread_set(&mut self, chat_id: &str, count: u32)
Reconcile a chat to an exact DB-computed count (delete / retreat / backfill). A zero drops the
entry so the map stays small and unwrap_or(0) reads it as caught-up.
Sourcepub fn sum_unread(&self) -> u32
pub fn sum_unread(&self) -> u32
Total unread for the badge, from the cache, applying the same muted/blocked filters as
[sum_unread_from].
Sourcepub fn unread_snapshot(&self) -> HashMap<String, u32>
pub fn unread_snapshot(&self) -> HashMap<String, u32>
A snapshot of the raw per-chat counts, for the frontend’s boot badges.
pub fn count_unread_messages(&self) -> u32
pub fn update_typing_and_get_active( &mut self, chat_id: &str, npub: &str, expires_at: u64, ) -> Vec<String>
Trait Implementations§
Auto Trait Implementations§
impl Freeze for ChatState
impl RefUnwindSafe for ChatState
impl Send for ChatState
impl Sync for ChatState
impl Unpin for ChatState
impl UnsafeUnpin for ChatState
impl UnwindSafe for ChatState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more