Expand description
Notification levels and mutes, for communities, channels and DMs alike.
Two settings per scope, doing different jobs. Level decides what rings:
every message, only your name, or nothing. Mute greys the row, drops its
unread weight, and clamps the level to at most Mentions — a volume knob,
not an off switch, which is why Nothing is not a synonym for it.
Level resolves down the chain Community → Channel, most specific opinion winning. Mute unions down it: muting a community mutes every channel in it. A scope with no stored row inherits everything, so an untouched account behaves exactly as it did before any of this existed.
Structs§
- Resolved
- A scope’s settings after the chain has been walked.
- Scope
Prefs - One scope’s stored settings.
Nonemeans inherit;suppress_everyoneis only ever set at community scope.
Enums§
- Message
Class - What a message is, loudest first. Resolved once at classification so a
suppressed @everyone is
Normaleverywhere downstream: notification, ping badge and muted-row count alike. - Notify
Level - What rings. Ordered loudest first, so the numeric rank orders “quieter”.
Constants§
- MUTE_
FOREVER mute_untilsentinel for a mute with no end.- MUTE_
OFF mute_untilsentinel for “not muted”.
Functions§
- all_
prefs - apply_
wire - Adopt a sibling device’s list wholesale. Returns the scopes whose settings actually moved, so the caller only has to repaint those.
- channel_
is_ listed - Whether
channel_idis one its community still lists. A channel nobody lists has no row to open, so its unread can never be seen or cleared. - community_
muted_ for_ chat - Whether a chat’s COMMUNITY is itself silenced, rather than this one room inside it. A surface that stands for the whole space must not grey because one channel is quiet.
- everyone_
allowed - Whether an authorized @everyone may ping, for a community. Two levers: the App Settings kill switch, which wins outright, and the community’s own choice under it. A channel has no say, deliberately.
- everyone_
pings_ for_ chat - Whether an @everyone in this chat still counts as someone calling your name.
- in_
legacy_ mute_ list - The predicate the older
vector/mutesprojection is both WRITTEN and READ with. Publishing one shape and applying another is how an inherited mute ratchets into a permanent per-channel one. - invalidate
- Drop the cache so the next warm re-reads the table.
- invalidate_
live_ channels - Forget which channels are listed; their community’s set was rewritten.
- is_
loaded - Whether the table has actually been read. An unloaded cache answers
“default” for every scope, which is indistinguishable from “nothing is
stored” — so anything that WRITES state derived from it must check this
first, the same rule
synced_prefs::is_hydratedapplies to publishing. - is_
muted_ at - legacy_
muted_ for_ chat in_legacy_mute_listfor a chat, stored flag folded in likeresolve_chat.- muted_
for_ chat - next_
expiry - The soonest mute expiry still ahead of
now_ms, for arming one timer rather than one per mute. - now_ms
- passes
- Whether a message of this class rings at this level.
- prefs
- resolve
- Walk the chain for one scope.
community_idis the channel’s community, orNonefor a DM or for a community resolving itself. - resolve_
chat - A chat’s settings, with its stored
mutedflag folded in. That flag is the mirror this module keeps for the paths that predate it, and the landing point for a mute arriving over the oldervector/mutesprojection, so it counts as a mute in its own right rather than being assumed to agree. - resolve_
from - The chain arithmetic on its own: level takes the most specific opinion, mute takes either, and the mute clamps the level it hands back.
- ring_
for_ chat - What a chat’s row should badge with: full unread at
All, pings atMentions, nothing atNothing. - set_
level - set_
mute - set_
prefs - Write a scope through to the database and the cache.
- set_
suppress_ everyone - sweep_
expired - Clear every mute whose timer has run out, returning the scopes that just
lapsed. Expiry is a write rather than a read: the callers of
mutedread a cached boolean, and making them all consult the clock instead would be the wrong fix. - to_wire
- This device’s table as the publishable projection.
- warm
- Read the table into memory. Called once when a database is opened, because every badge recount resolves every chat and a lazy load would put a SQLite round trip on that path.