Meldingen-hardening: verwerp-optie bij sluiten, classificatie-gate, presentatietimer #7

Merged
brenno merged 3 commits from feature/meldingen-hardening into main 2026-06-13 05:54:43 +00:00
Owner

Resterende wijzigingen op feature/meldingen-hardening:

  • Verwerp-optie bij sluiten: de "niet-opgeslagen wijzigingen"-dialoog bood alleen Annuleren of Opslaan-en-sluiten. Wie wilde sluiten zonder op te slaan kon dat alleen via force-quit, wat een recovery-snapshot achterliet en versie-ambiguiteit gaf tussen het bestand op schijf en de herstelde niet-opgeslagen versie. Toegevoegd: een derde keuze "Niet opslaan" die sluit zonder op te slaan; closeTab()/_destroy() ruimen de herstelbestanden op, zodat er geen schaduwversie overblijft. Vertaling van "Niet opslaan" toegevoegd voor alle 8 talen.
  • Fail-closed export classificatie-gate (release-plafond).
  • Presentatietimer / rehearsal-modus in de presenter.
Resterende wijzigingen op feature/meldingen-hardening: - **Verwerp-optie bij sluiten**: de "niet-opgeslagen wijzigingen"-dialoog bood alleen Annuleren of Opslaan-en-sluiten. Wie wilde sluiten zonder op te slaan kon dat alleen via force-quit, wat een recovery-snapshot achterliet en versie-ambiguiteit gaf tussen het bestand op schijf en de herstelde niet-opgeslagen versie. Toegevoegd: een derde keuze "Niet opslaan" die sluit zonder op te slaan; closeTab()/_destroy() ruimen de herstelbestanden op, zodat er geen schaduwversie overblijft. Vertaling van "Niet opslaan" toegevoegd voor alle 8 talen. - Fail-closed export classificatie-gate (release-plafond). - Presentatietimer / rehearsal-modus in de presenter.
brenno added 3 commits 2026-06-13 05:54:24 +00:00
Enforce an optional TLP release ceiling at the single export chokepoint
so no format (PDF/PPTX/HTML) can bypass it. Classifying a deck stays
optional; the gate only blocks decks classified above the configured
ceiling, and is off by default.

- ClassificationPolicy + ExportDecision: pure, tested decision logic
  (release ceiling, fail-closed; null = no gate).
- ExportService.export() evaluates the policy first and refuses without
  building or writing anything when blocked.
- Persist the ceiling as maxReleaseExportTlpKey in app settings/prefs
  (default off) with a setter on SettingsNotifier.
- Export dialog runs the same check up front and explains a blocked
  export before any work starts; app shell builds the policy from
  settings.
- Tests: classification_policy_test plus export_service chokepoint tests
  asserting a blocked export fails and writes no file.
- Docs: CHANGELOG, README, USER_GUIDE, ARCHITECTURE, SECURITY.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The presenter view now doubles as a rehearsal clock that measures without
coaching: a countdown against a target time, the time spent on the current
slide, and an end-of-run summary (total vs. target and per-slide times, with
copy-to-clipboard). Timing lives in a plain, unit-tested RehearsalController fed
via an idempotent observe() on every build, so it captures every navigation
path. The default target is stored in AppSettings; live adjustment is the K key
(typed as MMSS). All rehearsal state is session-only -- nothing is written to
disk or into the .md file.

- New: models/rehearsal.dart, services/rehearsal_controller.dart,
  widgets/presentation/rehearsal_summary.dart, plus a controller unit test.
- Presenter: countdown + per-slide timer in the clock bar, K to set the target,
  R resets the run, end-of-run summary dialog, and help/cheatsheet entries.
- Settings: presentationTargetSeconds (default target) with a dropdown in the
  General tab, threaded into FullscreenPresenter.present().
- l10n: new Dutch source strings translated in all seven languages.
- Docs: README, CHANGELOG, USER_GUIDE, SHORTCUTS, ARCHITECTURE.

Also bundles a pre-existing in-progress change already in the working tree: wire
the existing ThemeProfile.tableHeaderBackgroundColor into table rendering
(preview, HTML export, file_service) and the settings dialog, plus its
translations.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add "discard" option to the unsaved-changes close dialog
Some checks are pending
CI / Format · Analyze · Test (push) Waiting to run
CI / Format · Analyze · Test (pull_request) Waiting to run
483264b652
Closing a presentation only offered Cancel or "Save and close", so
unsaved edits could only be dropped by force-quitting. That left an
autosave recovery snapshot behind, creating version ambiguity between
the saved file on disk and the restored unsaved copy on next launch.

Add a third "Niet opslaan" (discard) choice to the close/quit dialog.
Discarding closes without saving; closeTab() and _destroy() already
clear the recovery files, so no shadow version remains and there is a
single unambiguous version afterwards.

Register the "Niet opslaan" string for all 8 supported languages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
brenno merged commit 4859d66d95 into main 2026-06-13 05:54:43 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: LibreKAT/Ocideck#7
No description provided.