Commit graph

21 commits

Author SHA1 Message Date
Brenno de Winter
97b825f1b9 Bundle pre-existing in-progress changes
In-progress local work that predated this branch, committed alongside it:
localization updates (app_localizations.dart), consent/deck/tabs providers,
the Android Gradle build config, and their accompanying tests. Grouped here so
the structural changes on this branch stay separable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 22:16:57 +02:00
Brenno de Winter
2c4a6f7358 Sync presenter annotations live, keep styling out of saved .md
Some checks failed
CI / Format · Analyze · Test (push) Has been cancelled
CI / Format · Analyze · Test (pull_request) Has been cancelled
Presentation fixes:
- Mirror the in-progress pen/highlighter stroke to the audience window
  live (new 'inkLive' channel) so highlights appear as they are drawn,
  not only after the pen lifts.
- Cover the macOS menu bar on the beamer: raise the audience window
  above .mainMenu level so the Apple/Wi-Fi strip no longer shows during
  a presentation.

Styling no longer lives in the file:
- generateDeck no longer embeds the ThemeProfile; a saved .md holds only
  content. The profile is inlined only for the transient audience-window
  payload (inlineStyleProfile: true), never to disk.
- On open, the app applies the active style profile (FileService.openDeck
  / activeProfileFor, DeckNotifier.loadDeck); applyMarkdown preserves the
  current profile.

Quality pass / tests green:
- Complete the consent-screen translations (English plus 7 missing
  strings per other language).
- Pass the consent gate in widget/ui-scale tests by seeding the consent
  key, so the app shell renders.
- Update markdown round-trip tests for the new default and add coverage
  for live stroke streaming and styling-free saves.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 19:25:05 +02:00
Brenno de Winter
56932a2dda Add consent screen translations for all 8 languages
Complete localization for privacy/consent features in all supported languages:
- Italian (Italiano)
- German (Deutsch)
- French (Français)
- Spanish (Español)
- Frisian (Frysk)
- Papiamento

Each language block now contains 12 consent-related translations covering:
- Welcome and privacy explanation
- License information
- User agreement text
- Revoke consent option
- Required acceptance message

Consent screens are now fully localized for all 8 supported languages.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-11 14:15:14 +02:00
Brenno de Winter
4f595d1340 Fix: Use correct EUPL 1.2 license instead of MIT
The project uses EUPL v1.2, not MIT. Updated consent dialog to display
the actual EUPL license text and point to the official EUPL license page.

- Changed 'Licentie (MIT)' to 'Licentie (EUPL 1.2)'
- Updated _getLicenseText() with EUPL v1.2 summary
- Fixed license link to https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-11 14:02:24 +02:00
Brenno de Winter
c6190dc31b Add consent/privacy screen at startup and license display
Implement three privacy features:
1. Consent gate at app startup - users must accept privacy terms before using OciDeck
2. License visibility - MIT license displayed in consent dialog
3. Consent revocation - privacy settings tab allows users to withdraw consent and return to consent screen

Changes:
- New ConsentProvider for managing consent state with SharedPreferences persistence
- New ConsentDialog with privacy explanation and MIT license (expandable)
- Added Privacy tab to settings dialog with revoke consent button
- Updated localization strings for Dutch/English consent screens

Consent flow:
- On first launch or after revocation, consent screen blocks app access
- Users can read privacy terms, view license, and accept to proceed
- Consent can be revoked anytime from Settings → Privacy tab
- After revocation, app returns to consent screen on next launch

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-11 14:01:06 +02:00
Brenno de Winter
68725341a7 Add image-library dedupe and untagged filter, UI text scaling, table paste
Image library:
- "Clean up duplicates" finds byte-identical images by md5, keeps one
  file per group (preferring the most-used, then the oldest), merges
  the tags/descriptions and captions of the copies, repoints slides in
  open decks and in .md presentations on disk, and deletes the copies
  after a confirmation that lists every group.
- A header toggle filters to images without tags/description, so it is
  easy to see which ones still need attention.
- The delete warning now also lists presentations on disk that still
  reference the image (marked "not open"), next to the open decks.

Editor and accessibility (already in tree):
- Interface text scaling up to 200%, keyboard-operable panel divider,
  keyboard-first add-slide dialog, and screen-reader improvements.
- Paste a spreadsheet/CSV/markdown selection into a table cell to fill
  the whole grid.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 13:36:44 +02:00
Brenno de Winter
382945e99b Add translations for the clear-all-checkboxes strings
Some checks failed
CI / Format · Analyze · Test (push) Has been cancelled
CI / Format · Analyze · Test (pull_request) Has been cancelled
Provide English fallbacks and translations in every supported language for
the new clear-all-checklists dialog, menu item and snackbars, satisfying the
localization completeness tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 23:35:24 +02:00
Brenno de Winter
2fd5054603 Improve presentation editing and playback 2026-06-09 13:28:23 +02:00
Brenno de Winter
9827715873 Add bullet subheadings and font-accurate slide auto-fit
Some checks are pending
CI / Format · Analyze · Test (push) Waiting to run
- Bullet slides can carry an optional subheading under the title (stored as
  `## …` in the slide's subtitle, round-tripped losslessly).
- The two-bullet-column subheadings and the bullets subheading participate in
  the auto-fit so the text keeps scaling to fill the slide.
- Slide text auto-sizing now measures with the deck's own font, so the fit
  matches what is rendered and the text uses the available space instead of
  staying smaller than needed.
- Editor fields, translations (all languages), docs and tests included.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 21:48:06 +02:00
Brenno de Winter
e0379ade59 Refine code slides: title outside the panel, fit-to-space, font choice
Some checks failed
CI / Format · Analyze · Test (push) Has been cancelled
CI / Format · Analyze · Test (pull_request) Has been cancelled
- The slide title now renders above the code panel (styled like other slide
  types) instead of inside the dark code window — it is the slide's title.
- Code is sized to fill the panel: scaled up to use spare space (capped) and
  down so long fragments still fit, instead of a small block in a big box.
- Add a per-profile monospace font for code slides (e.g. Courier), applied in
  the preview and the HTML export.
- Settings: a banner on the Colours and Logo tabs makes clear they edit the
  loaded style profile, and colour pickers now accept a custom hex value.
- Update docs and translations for the new strings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 14:28:04 +02:00
Brenno de Winter
de4a77e2bb Add code-slide theming, radar scale, and proximity line tooltips
Code slides:
- Theme code (broncode) background and text colours, with an optional
  syntax-colouring toggle. With it off the block renders monochrome, so a
  black background + bright green gives a classic CRT-screen look.
- Colour pickers gained a custom hex entry so arbitrary colours (e.g. CRT
  green) can be set, not just presets. Exported HTML mirrors the code colours.

Radar/spider charts:
- Optional min/max now define the radar scale (centre/outer ring) instead of
  threshold lines. Evenly spaced, labelled tick rings are drawn in both the
  live preview and the SVG export so the scale is readable. A nice scale is
  derived from the data when no bounds are set.

Line chart tooltips:
- Detect the touched dot by true (x and y) distance instead of the x-only
  default, so the tooltip belongs to the point under the cursor. Overlapping
  dots all show, and the font shrinks a step when several stack.

New UI strings are translated across all supported languages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 13:51:29 +02:00
Brenno de Winter
67408c213c Improve chart rendering and resolve theme logo paths
Charts:
- Shrink axis label fonts and thin/space x-axis labels by actual pixel
  spacing so dense or long labels no longer overlap.
- Line tooltip shows only the point nearest the cursor instead of every
  series stacked vertically.
- Hovering a legend entry highlights its element: bar/line series fade the
  others (pie expands the matching slice), in app and presentation mode.
- Add optional min/max threshold lines per bar/line chart (ignored for pie),
  editable in the chart editor and drawn in both the live preview and the
  exported SVG.

Theme:
- Resolve relative logo paths in a ThemeProfile against the project path and
  home directory so deck logos load regardless of working directory.

Tests cover bound round-trip, editor fields, SVG bounds, legend-hover fading,
and bound-line rendering.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 12:18:35 +02:00
Brenno de Winter
2d8be6f0dd Add project docs, EUPL licence, and open-source licence check
Some checks failed
CI / Format · Analyze · Test (push) Has been cancelled
CI / Format · Analyze · Test (pull_request) Has been cancelled
Documentation & licensing:
- Add the EUPL-1.2 licence (LICENSE.md) and set the project licence; refresh
  the README (name origin wink, updated feature list, documentation index).
- Add CONTRIBUTING, SECURITY, CODE_OF_CONDUCT, CHANGELOG, AUTHORS, and
  THIRD_PARTY_NOTICES, plus docs/ (ARCHITECTURE, BUILD, USER_GUIDE, SHORTCUTS,
  LICENSE_COMPLIANCE) and .github/ (CI workflow, issue/PR templates).
- Bring docs/FILE_FORMAT.md in line with current behaviour (code & chart
  slides, per-slide TLP comment, annotation .ink.json sidecar, chart data/ CSVs).

Open-source compliance:
- Add tool/check_licenses.dart and a `make licenses` target (wired into
  check-full and CI) that verifies every resolved dependency uses a recognised
  open-source licence. A scan of all 151 packages and bundled assets found only
  OSI-approved licences.

Charts (Fase 1.1):
- Replace the chart CSV textarea with an in-app editable data grid (editable
  series/labels/values, add/remove row & column, read-only when linked).
- Centralize the linked-CSV directory name (`data/`) in a shared constant.

Also normalize formatting repo-wide with `dart format` and fix one
curly-braces lint, so `make check` and CI are green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 12:19:56 +02:00
Brenno de Winter
32ef54e037 Add chart slides (bar/line/pie) with hybrid CSV storage
New "Grafiek" slide type rendering bar, line and pie charts.

Storage fits Marp: a ```chart fenced block holds the spec as JSON. Small
charts keep their data inline (the .md stays self-contained); data-driven
charts link an external CSV via "source": "data/<name>.csv" kept in a
separate data/ directory and packaged into .ocideck like images. On save
the inline data is stripped for linked charts (the CSV is the source of
truth); on open it is re-hydrated from the CSV.

- lib/models/chart.dart: ChartSpec/ChartSeries JSON parse/serialize,
  inline-vs-source handling, and a CSV parser.
- In-app rendering (preview/presenter/PDF/PPTX) via fl_chart.
- HTML export renders charts as self-contained inline SVG generated in
  Dart (no JS chart library); export inlines linked data so the page is
  standalone.
- Editor: type picker, title, a CSV-style data field, and CSV import that
  can inline the data or link it as data/<name>.csv (with unlink).
- Markdown round-trip + .ocideck packaging of linked CSVs; translations
  for all supported languages.

flutter analyze is clean, all tests pass (new chart/CSV/round-trip tests),
and the macOS debug build compiles.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 11:42:44 +02:00
Brenno de Winter
227abf351e Add annotation layer (laser, pen, highlighter) over slides
Draw on slides while presenting, kept as a layer fully separate from the
Marp content so the deck stays pure, portable Marp.

Presenter tools (D pen, T highlighter, E eraser, X laser, C clear, Esc
puts the tool away) with a small floating colour/tool bar shown only when
a tool is active. Strokes use coordinates normalized to the 16:9 slide so
they render identically on the laptop and the beamer; in dual-screen mode
the ink and the laser are mirrored live to the audience window.

Persistence (decoupled from the .md):
- In memory the layer is keyed by Slide.id (stable within a session).
- On disk it lives in a sidecar <name>.ink.json next to the deck and as a
  separate entry inside the .ocideck package; the markdown is untouched.
- Because slide ids are regenerated on load, the sidecar anchors strokes
  by order + a content fingerprint, re-attaching them after reordering and
  dropping them when a slide's content changed.
- Deck.annotations carries the layer in memory but is never serialized to
  markdown; deckProvider.setAnnotations keeps it out of undo/redo.

flutter analyze is clean, all tests pass (incl. new stroke/codec tests),
and the macOS debug build compiles. Drawing and live beamer sync still
need verification on real hardware.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 11:14:51 +02:00
Brenno de Winter
d1862935ab Add per-slide TLP classification with sharing-level filtering
Each slide can now carry its own Traffic Light Protocol level. When the
presentation is shared at a given TLP level, slides classified stricter
than that level are withheld, so the same deck can be shown safely to
audiences with different clearances.

- Slide.tlp field with markdown round-trip via a <!-- tlp: <key> --> marker
  (also on code slides).
- Editor: a per-slide "TLP van deze slide" dropdown.
- Central rule slideVisibleAtTlp() compares levels on the TLP severity
  order (none < CLEAR < GREEN < AMBER < AMBER+STRICT < RED).
- Filtering lives in _slidesForPresentationOrExport, the single source of
  slides for presenting (single-window and dual-screen) and for every
  export (PDF, PPTX, HTML), so all paths honour it.
- Translations for the new strings in all supported languages, plus tests
  for the round-trip and the visibility rule.

flutter analyze is clean and all tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 22:34:42 +02:00
Brenno de Winter
2aca44365a Add dual-screen presenter mode (slide on beamer, notes on laptop)
When a second display is connected (macOS), presenting now opens a
borderless audience window on the beamer showing the slide, while the
main window shows the presenter view (current/next slide, speaker notes,
clock, controls) on the laptop. The two windows stay in sync over method
channels: navigation, blank screen, audio-complete and beamer clicks are
forwarded between them, and media plays only on the beamer to avoid
double audio. Falls back to the existing single-window presenter when
there is one display or the second window can't be created.

- Vendors a fork of desktop_multi_window in third_party/ that re-adds the
  native macOS window geometry/fullscreen calls (coverScreen, setFrame,
  close) the published 0.3.0 dropped; wired via a path dependency.
- Registers the app's plugins for sub-windows in MainFlutterWindow so
  video/image rendering works on the beamer.
- Routes the multi_window dart entrypoint to a minimal AudienceWindowApp.

Compiles (flutter analyze + macOS debug build) and all tests pass;
runtime two-screen behaviour still needs verification on real hardware.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 21:25:34 +02:00
Brenno de Winter
b7db54e033 Add app theming, code slides, and flicker-free transitions
Bundles several in-progress changes from the working tree:

- App appearance / look-and-feel: customizable app theme profiles
  (colors, dark interface) with a settings UI and persistence.
- New "Broncode" (source code) slide type: dark code sheet with
  syntax highlighting, a dedicated editor with a language picker,
  and Marp markdown round-trip via a fenced code block.
- Presenter: eliminate the brief black frame between slides by
  precaching neighbouring slide images and enabling gaplessPlayback,
  so recordings stay clean.

Adds round-trip tests for the code slide and translations for the
new strings across all supported languages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 20:41:24 +02:00
Brenno de Winter
ee66721de6 Improve presentation settings and localization 2026-06-05 19:14:54 +02:00
Brenno de Winter
d59c6ee761 feat: refine presenter and language options 2026-06-04 08:17:12 +02:00
Brenno de Winter
d0bd1a85bf feat: add multilingual interface 2026-06-04 02:30:03 +02:00