The shared body of every notification surface: it loads its filter, resolves
the loading / failed / empty / list phase (see feedPhase), formats the
relative time and export-expiry sub-labels against one shared clock, and wires
the per-row mark-read and delete actions.
It owns no chrome — no header, no tabs, no title — so a popover, a bottom
sheet and a drawer can each wrap it in their own. State lives in the shared
@enode/core notifications store, so several mounted feeds stay consistent.
The shared body of every notification surface: it loads its filter, resolves the loading / failed / empty / list phase (see feedPhase), formats the relative time and export-expiry sub-labels against one shared clock, and wires the per-row mark-read and delete actions.
It owns no chrome — no header, no tabs, no title — so a popover, a bottom sheet and a drawer can each wrap it in their own. State lives in the shared
@enode/corenotifications store, so several mounted feeds stay consistent.