pub struct NotificationArchiveModel { /* private fields */ }Expand description
Shared model — clones share state. Constructed by the install
helper from NotificationArchive + AppPaths; apps reach it
via ctx.app_state::<Rc<RefCell<NotificationArchiveModel>>>().
NotificationLog and NotificationCenterButton
consume this model directly.
Implementations§
Source§impl NotificationArchiveModel
impl NotificationArchiveModel
Sourcepub fn open(
archive: &NotificationArchive,
paths: &AppPaths,
debounce: Duration,
) -> Result<Self, NotificationArchiveError>
pub fn open( archive: &NotificationArchive, paths: &AppPaths, debounce: Duration, ) -> Result<Self, NotificationArchiveError>
Construct from a NotificationArchive config. For
Persistent mode, resolves the path through AppPaths.
Tests use AppPaths::for_testing(tmpdir) + Duration::ZERO
debounce.
Sourcepub fn in_memory() -> Self
pub fn in_memory() -> Self
Convenience: construct an NotificationArchive::InMemory
archive with the default cap, without going through paths.
Mostly useful for tests and apps that explicitly want no
persistence.
Sourcepub fn entries(&self) -> &ListModel<NotificationEntry>
pub fn entries(&self) -> &ListModel<NotificationEntry>
Reactive handle on the entries. Bind to a ListView /
Repeater for live UI.
Sourcepub fn unread_count(&self) -> &Signal<usize>
pub fn unread_count(&self) -> &Signal<usize>
Signal of the unread count. Drives the bell-button badge.
Sourcepub fn version_signal(&self) -> &Signal<u64>
pub fn version_signal(&self) -> &Signal<u64>
Reactive handle on the archive’s mutation version. Widgets
that render the archive (NotificationLog,
NotificationCenterButton) bind to this at
BindingLevel::Rebuild, in every window — one signal is enough
for N of them, see
ToastRegistry::version_signal
for the history of why that had to be said out loud.
pub fn limit(&self) -> usize
Sourcepub fn flush_now(&self) -> Result<(), SettingsFileError>
pub fn flush_now(&self) -> Result<(), SettingsFileError>
Force the persistent backing file to disk synchronously.
No-op for InMemory. Tests call this between mutations and
re-opening the file to verify persistence.
Sourcepub fn push(&self, entry: NotificationEntry)
pub fn push(&self, entry: NotificationEntry)
Push a new entry. Inserts at index 0 (newest first), evicts
the oldest if the resulting length exceeds limit. Stamps
the entry’s id field from next_id. Bumps unread_count
when the entry is unread (which is the typical case from a
toast push).
If entry.dedup_id matches an existing entry, the existing
entry is updated in place (title / body / progress collapsed
into a NotificationUpdate appended to updates) and no
new row is inserted. Unread count increments either way (an
in-place update IS new information for the user).
Sourcepub fn mark_read_where(&self, predicate: impl FnMut(&NotificationEntry) -> bool)
pub fn mark_read_where(&self, predicate: impl FnMut(&NotificationEntry) -> bool)
Mark every UNREAD entry matching predicate as read,
decrementing unread_count by exactly how many were flipped.
This is the scoped counterpart of mark_all_read:
a bell scoped to one window/audience must only mark ITS
entries read on close — calling the unscoped mark_all_read
from a scoped bell would incorrectly clear every OTHER
window’s/audience’s unread state too.
Sourcepub fn mark_all_read(&self)
pub fn mark_all_read(&self)
Mark every archived entry as read; reset unread_count to 0.
Called by NotificationCenterButton when its popover opens.
Sourcepub fn clear_where(&self, predicate: impl FnMut(&NotificationEntry) -> bool)
pub fn clear_where(&self, predicate: impl FnMut(&NotificationEntry) -> bool)
Remove every entry matching predicate, decrementing
unread_count for each removed entry that was unread. The
scoped counterpart of clear: a bell scoped to
one window/audience must only clear ITS entries — the unscoped
clear() wipes the ENTIRE shared archive (every window’s
history), which would be wrong for a scoped “Clear” button.
Sourcepub fn remove_by_id(&self, id: u64)
pub fn remove_by_id(&self, id: u64)
Remove the entry with the given stable id (see
NotificationEntry::id — “assigned by the archive on first
push; never reused”). Updates unread_count if the removed entry
was unread. No-op (no version bump) when no entry has that id.
Deliberately id-based rather than index-based: an index is a
snapshot of the list’s shape at the moment it was read, and is
meaningless once anything else — a concurrent peer-process reload
merged in via the live archive, another push, another remove —
has shifted rows out from under it. A caller that captured “the row
I want to dismiss” as an index earlier and replays it later against
a since-mutated list can silently remove the wrong entry; keying
off id instead re-resolves the row’s current position at the
moment of removal, so it always removes the entry the caller meant.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for NotificationArchiveModel
impl !RefUnwindSafe for NotificationArchiveModel
impl !Send for NotificationArchiveModel
impl !Sync for NotificationArchiveModel
impl !UnwindSafe for NotificationArchiveModel
impl Unpin for NotificationArchiveModel
impl UnsafeUnpin for NotificationArchiveModel
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.impl<T> ErasedDestructor for Twhere
T: 'static,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§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