[Feature] Presentatie-import (Keiko) als Uitbreidingen-module + Integraties-tab #772
Labels
No labels
accepted
bug
declined
docs
duplicate
enhancement
good first issue
in-progress
needs-info
privacy
security
triage
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
LibreKAT/Ocideck#772
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Het losse project Keiko (
https://pawprint.vigilis.online/brenno/Keiko) importeert PowerPoint (.pptx), LibreOffice Impress (.odp) en Apple Keynote (.key) en zet ze om naar OciDeck-decks (Marp Markdown + assets). Deze issue brengt die functionaliteit in OciDeck, onder de kwaliteits- en look-and-feel-eisen van deze repo, als optionele module onder Uitbreidingen, met een Integraties-tab in de instellingen voor de OpenKAT-rapportagelocatie.Grote, samenhangende brok: veel commits, weinig PR's (fasegewijs, §8). Op basis van dit stappenplan moet direct gestart kunnen worden — elke integratieplek staat met bestand:regel benoemd (uit codeverkenning tegen huidige main,
66cbb473).Vastgelegde besluiten (23-07-2026)
feat/openkat-invoerpunt-767..keyvanaf het begin; de enige nieuwe dependencyprotobuf(IWA-parsing) komt er meteen bij, met SBOM/licentie/security-poort.queued_files_provider.1. Scheidslijn met #767 — geen dubbeling
Twee verschillende importsoorten; ze mogen niet door elkaar lopen.
OpenkatImportServicec.s. (wip/openkat-services-672, geadopteerd opfeat/openkat-invoerpunt-767)Afspraak: deze issue herbouwt de OpenKAT-parser niet. Wél levert deze issue (a) de Integraties → OpenKAT-tab met de vaste rapportagelocatie (§3), en (b) — per besluit B1 — de gedeelde "Importeren"-module die #767's menu-actie herbergt. Coördineer met
feat/openkat-invoerpunt-767: die tak levertOpenkatImportService+ de menu-actie; deze issue plaatst dat invoerpunt onder de module en achter de reveal-regel. Beide importsoorten landen in de bestaande menusectie "Pakket en import" (lib/widgets/app_shell_menu.dart:127) en het commandopalet (lib/widgets/shell/command_palette_actions.dart:95).2. Keiko is gebouwd tegen een oudere OciDeck — herijk tegen huidige main
Keiko dateert van vóór de wijzigingen van vandaag. Bij het overzetten expliciet herijken:
SlideType-enum. De geldige set (lib/models/slide.dart:19-48) telt 24 waarden:title, section, bullets, twoBullets, bulletsImage, twoImages, image, video, quote, table, freeMarkdown, code, chart, cockpit, question, timeline, scorecard, assets, discoveries, finding, findingsSummary, checklist, scopeMatrix, signOff. Keiko kentscorecard,assets,discoveriesnog niet — heroverweeg de salvage-doelen daarop.lib/ocideck/(writer +markdown_emitter+ eigenSlideType+style_profile) dupliceert een contract dat OciDeck al heeft — én dat sindsdien is veranderd (themeProfile, chirurgische front-matter, sidecars). Vervangen door het echte model (§ hieronder).3. Porteergrens — wat overkomt en wat wordt vervangen
Keiko is ~9.500 regels niet-gegenereerde Dart, Riverpod (net als OciDeck). De importers/pipeline hebben géén Flutter-imports (unit-testbaar).
Overnemen (format-neutraal, de kernwaarde):
lib/importers/— pptx, odp, keynote (IWA: snappy, protobuf-wire, object-graph, table/chart/media-reconstructie). Het zware, waardevolle deel.lib/models/—SourceSlideen vrienden (het format-neutrale tussenmodel).lib/pipeline/—format_detector,slide_classifier(herijkt, §2),importer_registry,unconverted_tracker,problem_slide.lib/utils/—archive_utils,xml_utils,safe_extensions.Vervangen door OciDeck-equivalenten (niet dupliceren) — de API die de importer hoort aan te roepen (uit opslagverkenning):
Slide.create(SlideType.x)(lib/models/slide.dart:619) +copyWith(...)— nooit een eigen dia-serialiser.Deck(title:, theme: 'ocideck', slides:, themeProfile:)(lib/models/deck.dart:155); styling gaat níét in de.md(dat legt de app als stijlprofiel eroverheen).Settings.homeDirectory(lib/models/settings.dart:551) met terugvalgetApplicationDocumentsDirectory()(patroonlib/state/tabs_provider_import.dart:21); elk deck krijgt een eigen submap.FileService.saveDeck(deck, '<submap>/<naam>.md')(lib/services/file_service.dart:741) →_writeProject(lib/services/file/file_service_project.dart:8) regeltimages/media/logos/themes/data, asset-kopie + inhoud-dedupe, projectrelatieve herschrijving, thema-CSS, atomische.mdviaMarkdownService.generateDeck(lib/services/markdown_service.dart:60), en sidecars.TabsNotifier.newDeckInNewTab(...)(lib/state/tabs_provider.dart:357) /DeckNotifier.loadDeck(...)(lib/state/deck_provider.dart:269).resolveAssetDestinationForBytes(destDir, filename, bytes)(lib/utils/asset_destination.dart:57) — leesbare namen mét inhoud-dedupe. Dit vervangt Keiko's gedeeldeimages/<sha256>-hack, die botst met de containment-garantie (lib/utils/project_path.dart:90) en met_discardImportArtifacts(tabs_provider_import.dart:11, ruimt een mislukte import op door de submap te verwijderen).Verder vervangen:
lib/state/→ module-providers (§5);lib/ui/→ OciDeck-dialogen/look-and-feel (§7);lib/l10n/(ARB) →l10n.d('…')-keten (§6);core/theme.dart/core/result.dart→ OciDeck-equivalenten.4. Integraties-tab (req 2)
Nieuwe instellingen-tab Integraties, onderverdeeld per systeem, OpenKAT eerst. Eén aanwijsbare map voor OpenKAT-rapportages volstaat. Gebruik het OpenKAT-kattenlogo (de string
'Mascotte van OpenKAT.'en het asset-gebruik inlib/widgets/dialogs/parts/settings_dialog_about.dart:274bestaan al — hergebruiken).Integratieplekken (uit UI-verkenning):
lib/widgets/dialogs/parts/settings_dialog_sections.dart:21-33— enum-waardeintegrations(Icons.hub_outlined)(positie = zijbalkpositie, vóórdocumentation/about).settings_dialog_sections.dart:43-56—integrations => l10n.d('Integraties')in delabel-switch.lib/widgets/dialogs/settings_dialog.dart:757-773—SettingsSection.integrations => _integrationsTab()in debodies-switch (verplicht;test/settings_search_test.dart:144eist een body per enum-waarde in volgorde).parts/settings_dialog_integrations.dart(part-regel bijsettings_dialog.dart:71-89); per systeem een_sectionTitle(...)-kop (OpenKAT eerst) — die kop is meteen het zoekanker.parts/settings_dialog_search_index.dart(section:exact gelijk aan de_sectionTitle-tekst;keywords: "openkat", "integratie", "rapportage", "map"). Getoetst doorsettings_search_test.dart:233/314.De OpenKAT-locatie is een nieuwe persistente instelling (SharedPreferences, eigen unieke sleutel). #767's importactie leest deze als standaardmap.
5. Uitbreidingen-module (req 1) — "Importeren", standaard uit
Vierde module in het register. Standaard uit; reveal houdt bestaand werk bereikbaar. Checklist (uit UI-verkenning):
lib/state/module_registry.dart:26—ModuleId.import(volgorde = kaartvolgorde).module_registry.dart:75-91— vierdeModuleEntry(enabled:, revealed:).lib/state/online_storage_provider.dart(notifier +enabledProvider+revealProvider; unieke prefs-sleutel die nooit hernoemt — zieinfo_safety_provider.dart:55). Harde default-uit (?? false).lib/widgets/dialogs/settings/online_storage_module_card.dart.parts/settings_dialog_modules.dart:27-34— armModuleId.import => const ImportModuleCard()inswitch (entry.id)(verplicht, compileert anders niet).revealed = enabled || heeftImportInhoud(tonen zodra de inhoud er is; uitzetten mag geïmporteerd werk of het OpenKAT-invoerpunt nooit onbereikbaar maken).Tests:
test/online_storage_module_test.dart:115(registervolgorde, harde lijst → naar vier),:215(moduletelling =SwitchListTileper kaart),test/module_surface_leak_test.dart(modulescheiding + reveal-regel).6. Bulk-import, menu & doelmap (req 4) — logisch landen, niet 1-op-1
app_shell_menu.dart:127) en het commandopalet (command_palette_actions.dart:95); naast (niet los van) #767's OpenKAT-actie. Ook via drag-drop (app_shell.dart:439/411desktop/web) en bestandskiezer (FileService.pickMarkdownFile/pickDeckFileBytes).queued_files_provider) — meerdere bestanden toevoegen/verwijderen/herordenen vóór start, voortgang per bestand.ConversionIssue) — niets verdwijnt stil. Plus de per-slide-beslisdialoog (best-effort + notitie / rasteriseren / overslaan / annuleren).7. Look-and-feel (req 6)
Keiko's eigen shell/home/settings/convert-pagina's + thema vervallen. Herimplementeer met OciDeck-patronen: modulekaart, instellingen-tab,
AlertDialog/FilledButtonin OciDeck-stijl, voortgang (0..1 + statusmelding) en de per-slide-beslisdialoog met OciDeck-widgets.8. Eisen van deze repo (req 5) — poorten waar geport werk doorheen moet
l10n.d('…'); Keiko's ~56 ARB-sleutels →make add-l10n SPEC=…(alle 31 talen ingevuld, anders valtl10n-check).lib-bestand): grote importers opsplitsen inpart-extensies.lib-bestand dat in geen test voorkomt valt de dekkingspoort — port de relevante Keiko-tests (33 testbestanden + fixtures) en pas ze aan OciDeck-API's aan.protobufis de enige nieuwe dependency →make sbom+ licentiecontrole + security-blik.file_selectorniet overnemen (OciDeck gebruiktfile_picker). Al aanwezig: archive, xml, crypto, path, path_provider, shared_preferences, desktop_drop, window_manager, image.maxArchiveInputSize, sluit aan bijopenDeck'smaxDeckMarkdownBytes). Marp-Markdown-output = maximaal uitwisselbaar (past bij de kern);protobufis het enige "specifieke buiten de kern" — bewust gewogen bij B2.9. Fasering (weinig PR's, veel commits)
protobuf+ SBOM erbij (B2). Acceptatie: module verschijnt/verdwijnt correct, tab + zoekingangen groen,make checkgroen.Deck/Slide.create→FileService.saveDeck. Acceptatie: een echte.pptx→ deck met assets in eigen projectmap; notitieslides voor verlies; round-trip viaMarkdownServicestabiel; tests groen..keyend-to-end.10. Herkomst
Afgesplitst van de OpenKAT-integratie (#672 weergavelimieten geland, #767 OpenKAT-invoerpunt lopend). De importfunctionaliteit komt uit het losse project Keiko en wordt tegen de huidige main geherijkt en aan de repo-eisen onderworpen.
Opgepakt. Tak: feat/keiko-import-772 (vanaf verse main, incl. #771 weergavelimieten). Verwachte reikwijdte F1: nieuwe Uitbreidingen-module 'Importeren' (module_registry + eigen state/provider + module-card), Integraties-tab (settings_dialog_sections + settings_dialog + nieuw part + search-index), l10n via add-l10n, en de deckbouw-seam naar het echte Deck-model. Raakt #767's bestanden bewust niet (app_shell_menu/command_palette) tot dat op main staat; dan bedraad ik B1 (module herbergt het OpenKAT-invoerpunt).
Voortgang op tak
feat/keiko-import-772(vanaf main met #767 erin).F1 + B1 — af,
make checkgroen. Module "Importeren" (4e Uitbreiding, standaard uit) en het nieuwe tabblad Integraties met de OpenKAT-rapportagemap. Het OpenKAT-invoerpunt van #767 valt nu onder de module (reveal = module aan óf map aangewezen) en gebruikt die map rechtstreeks in plaats van elke keer de mapkiezer. OpenKAT-logo staat erin.F2 (PowerPoint) — af,
make checkgroen (6206 tests, dekking 85,9%). De format-neutrale laag en de PPTX-parser zijn geport en web-veilig gemaakt (alles via bytes, geendart:io). Keiko's eigen writer is NIET meegekomen: er is een deck-builder die op het échte Deck-model bouwt (Slide.create+ copyWith) en afbeeldingsbytes alsmem:-pad neerzet, zodatFileService.saveDeckze met inhoud-dedupe in de per-deckimages/materialiseert. Menu-actie + waarschuwing ("best-effort, geen één-op-één-kopie", met de tip om een aparte importmap te gebruiken), 31 talen l10n.F3 (LibreOffice Impress) — af. ODP-importer geport, deelt de hele pipeline met PPTX; 10 geporte tests die hun ODP inline bouwen.
F4 (Keynote) — onderhanden.
Besluit B2 wordt goedkoper dan gedacht. De aanname was dat Keynote
protobufals nieuwe dependency nodig heeft, met SBOM- en licentiegang. Dat blijkt niet zo: Keiko's pubspec noemtprotobufwel, maarpackage:protobufwordt nergens geïmporteerd —iwa/proto_wire.dartis een eigen, schema-vrije wire-decoder (zoalsprotoc --decode_raw). De hele import komt er dus zonder één nieuwe afhankelijkheid. Geen extra toeleveringsketen, geen SBOM-ronde.Twee dingen die onderweg zijn opgelost en geen poort zag: de zip-bom-melding interpoleerde
$bytes.lengthen drukte daarmee de hele bytelijst af (nu gefixt én voor het eerst toetsbaar door de grenzen injecteerbaar te maken), en de meegekomensafe_extensions/importer_loggerwaren dode respectievelijk dubbele code.Nog te doen: F4 afronden, F5 (bulk-wachtrij, de niet-destructieve weergavelimieten uit #672 toepassen, USER_GUIDE/CHANGELOG).
PR staat klaar: #807 (tak
feat/keiko-presentatie-import-772, gerebased op de huidige main).Belangrijk voor de beoordeling: dit is een herbouw. Terwijl ik bouwde landde #789 met de module Importeren, het Integraties-tabblad, de vaste OpenKAT-map en 31 talen — exact wat mijn eerste zeven commits ook deden, tot dezelfde bestandsnamen toe. Die zijn dus vervallen; de oude tak is verwijderd zodat niemand hem per ongeluk mergt. Wat er nu ligt is uitsluitend wat main níét heeft: de parsers, de deck-builder, de weergavelimieten en de bulk-wachtrij, aangehaakt op main's bestaande
importModuleRevealProvider.Besluit B2 blijkt goedkoper dan gedacht: er komt géén enkele nieuwe afhankelijkheid bij. Keiko's pubspec noemde
protobuf, maar dat pakket wordt nergens geïmporteerd — de IWA-laag heeft een eigen, schema-vrije wire-decoder.De bewaker keurde de eerste versie af, en dat heeft de PR beter gemaakt. De belofte 'niets verdwijnt stil' werd op zes plekken niet waargemaakt en 'video komt over' was aantoonbaar onwaar: de bytes werden weggegooid en het deck hield een dood pad over. Dat is allemaal gerepareerd, elk met een test, en de rondgangstest die daarbij hoorde legde nog een echte datalek-bug bloot (een zachte regelafbreking uit PowerPoint at tekst op bij opslaan-en-heropenen).
Twee dingen zitten er bewust niet in en staan apart: #806 (import-meldingen en notitiedia's zijn Nederlands ongeacht de taal — vraagt reden-codes en een vertaalnaad) en #803 (sneltoetsteksten ontsnappen aan de vertaalpoort, bestond al).
Eerlijk over de beproeving: alle fixtures bouwen hun archief zélf, er staat geen door PowerPoint/Impress/Keynote weggeschreven bestand in de repo. Dat staat als punt 11 in VERIFICATION.md.
make checkgroen, 6500 tests, dekking 86,5%, geen basislijn verhoogd.Geland op main met merge-commit
e3e3c29b(PR #807, zes commits). Geverifieerd op main, niet op de tak: 53 lib-bestanden onderlib/services/import/en 30 testbestanden staan er.Wat erin zit: import van .pptx, .odp en .key naar echte OciDeck-decks, achter de bestaande module Importeren; deck-builder op het echte Deck-model (Keiko's eigen writer is bewust niet meegekomen); niet-destructieve weergavelimieten in plaats van snoeien; bulk-wachtrij met eigen doelmap; en een waarschuwing die vooraf zegt dat het best-effort is en geen één-op-één-kopie. Zonder één nieuwe afhankelijkheid — B2 bleek goedkoper dan gedacht.
Wat er níét in zit, met opzet en apart vastgelegd:
SourceThemedie vervolgens door niemand gelezen wordt. Zo staat het ook in de gids. Geparste data die nergens landt is een losse draad; wie hem oppakt heeft het parswerk al klaar.De belangrijkste beperking, en die staat als punt 11 in VERIFICATION.md: alle testfixtures bouwen hun archief zélf. Er staat geen enkel bestand in de repo dat PowerPoint, Impress of Keynote werkelijk heeft weggeschreven. De parsers zijn dus tegen nagebouwde invoer beproefd, niet tegen de echte wereld — een paar echte presentaties erdoorheen halen is de meest waardevolle volgende toets.
Hiermee is de reikwijdte van dit issue af; ik sluit het.