| D-M4-33-0 |
2026-10-23 |
Built on main after M4-20, M4-30 and M3-11 landed; the changelog entry and these rulings are fragments. The brief's names differ from the merged code in these places: the D9 page lives in notifications_settings/ and opens inside the Notifications section of D8 below the note of M4-30 (the section is the page; no second route); the tree, the menus and the export dialog read the levels through LevelContext and the sidebar's notificationPreferencesProvider; the thread header's menu is a "More" button (TargetMenuButton), which shows the channel's menu for the main history of a text channel. |
Build steering of 2026-10-21 and 2026-10-23; D-W-100 and D-W-114 (merged code wins over the brief's names). |
| D-M4-33-1 |
2026-10-23 |
The effective level is computed for display only (effective_level.dart, the order of 13 3.1 with muted_until of the selected row; a row with a level this version does not know counts as absent). The instance default notify.user_default_level is not delivered by any API operation (getInstance and the snapshot carry no notification defaults), so the display uses the reference default mentions of 13 17; the server decides with its own value. The defaults of notify.preview_mode (full), notify.input_needed_breaks_quiet_hours (false) and notify.admin_enabled (true) are the reference defaults of 13 17 too. |
Brief Design note 1; P-11 forbids an own API extension. |
| D-M4-33-2 |
2026-10-23 |
"Mute until" offers one hour, tomorrow 08:00 in the person's time zone (an unknown zone counts as UTC, as D-M3-18-8 does for the server) and a chosen date and time. It writes the target's own row with the level that applies afterwards (the own row's level, else the level the target inherits now) and muted_until, because 13 3.1 applies mute only while muted_until lies in the future and the stored level after it. The sidebar's muted mark (D-M4-19-1) follows the same rule: the own row's level is mute, or its muted_until lies in the future. "Following" is shown for an own thread row at all without an active mute, which is what the server writes on automatic following (13 3.2). |
Brief Design note 2; a stored mute with a future end would stay muted after it ends. |
| D-M4-33-3 |
2026-10-23 |
The export streams exportChannel with ResponseType.stream straight into the file the platform's save dialog returned; the step-up comes from the server's 401 step_up_required through the session's StepUpInterceptor (the binary problem body is decoded since M4-22, D-M4-29-8), with the purpose "Export the history of ". The range is whole days in the person's time zone, from the start of the first to the start of the day after the last (the end is exclusive). Cancel aborts the request, a stream that ends with an error counts as broken; both delete the partial file. Nothing is cached. A 403 or 404 shows the server's reason. |
Brief Design note 3; 07 2.4; 15 1. |
| D-M4-33-4 |
2026-10-23 |
D9 shows "Runs I triggered" as an explanation of 01 10.1 (a question always notifies, the end or a failure follows the level) and offers no switch, because 13 3.3 has no key for it; 01 5.1 D9 says so. |
Brief fixed requirement 10. |
| D-M4-33-5 |
2026-10-23 |
The snapshot carries no notification preferences or quiet hours (04 6.3), so the app loads listMyNotificationPreferences and listMyQuietHours once per session when a menu or D9 first needs them and stores them by the version rule; a local row the server no longer lists goes unless a write of it still waits in the outbox, and the quiet hours list is left to the next quiet_hours.updated while a rule write waits. A new quiet hours rule is shown at once under the ID of its outbox entry; edits and the delete of a rule whose create still waits depend on that entry and get the server's ID from its result (rule_id, D-M4-15-6); deleting a rule whose create was never sent drops the create. |
04 14 (personal data through REST and events); brief Design note 2 ("the local row updates at once"). |
| D-M4-33-6 |
2026-10-23 |
The menus build their entries only while open, inside a Consumer with the region's own context, so the sidebar rows and post rows stay plain views without providers, and an entry that opens a dialog after the menu closed (the date picker, the export) has a mounted context. |
Found by the export integration test: the dialog's context was the closed menu's. |
| D-M4-33-7 |
2026-10-23 |
The fake server follows the server for 13 3.2: every message of a person (origin human, kind of principal user) in a thread with kind = thread without an own row of that thread creates the row at all and appends notification_pref.updated. One existing fake test that counts dispatch seq values sets Sam's row first, so no follow event lies between its two messages. |
Brief Scope "Fake server handlers ... with automatic following on a write in a thread". |