6.6 KiB
IMAGE_VIEWER_AND_INFO_V1.md
1. Doel
Een volledige image viewer voegt nu directe waarde toe omdat de app al image-bestanden kan tonen in de lijst, thumbnails kent, en type-specifieke viewers heeft voor tekst, video en PDF. Voor afbeeldingen ontbreekt nog de logische volgende stap: het geselecteerde bestand volledig bekijken zonder download- of externe viewerstap.
Een kleine uitbreiding van File Info met image-specifieke metadata voegt ook waarde toe. Voor afbeeldingen zijn afmetingen vaak net zo relevant als naam, grootte en modified time. Dat helpt bij snelle selectie, kwaliteitscontrole en onderscheid tussen vergelijkbare bestanden.
Dit past goed binnen de bestaande dual-pane workflow zolang:
- openen een lichte modalactie blijft
- de browse-flow niet verandert
- de info-uitbreiding read-only en goedkoop blijft
2. Scope
In scope voor v1:
- volledige image viewer voor:
jpgjpegpngwebpgifbmpavifals browser-native rendering zonder extra complexiteit werkt
- aparte image-modal
- read-only
- standaard
fit-to-view - basis zoom:
- zoom in
- zoom out
- reset
- File Info uitbreiding met:
widthheight
Niet in scope:
- edit
- crop/rotate
- slideshow
- metadata editor
- EXIF-inspectie als brede feature
- thumbnails in de viewer
- multi-image navigation
Aanbevolen v1-richting:
jpg/jpeg/png/webp/gif/bmpvolwaardig ondersteunenavifbest-effort, zonder extra garanties- geen extra dependency alleen om
avifof exotische metadata te forceren
3. Startgedrag
Aanbevolen v1-gedrag:
F3opent de image viewer bij exact 1 geselecteerd image-bestand- de bestaande
View-knop gebruikt dezelfde centrale type-dispatch - gewone
Enter-semantiek blijft intact
Concreet:
F3/Viewdispatch:- tekst -> text viewer
- video -> video viewer
- pdf -> pdf viewer
- image -> image viewer
- bij geen selectie of multi-select doet
F3niets alsViewdisabled zou zijn - directory-open gedrag via gewone
Enterof directorynaam blijft onaangetast
4. Viewer-richting
Aanbevolen v1-richting: aparte image-modal met browser-native afbeeldingselement (img) en lichte frontend-zoom.
Waarom:
- geen extra dependency nodig
- laag regressierisico
- goed te combineren met bestaande modalarchitectuur
- voldoende voor een bruikbare eerste viewer
Aanbevolen UX:
- afbeelding centraal in een aparte modal
- standaard
fit-to-view - controls:
Zoom inZoom outReset
- sluiten via:
XEscape
- overlay-click alleen meenemen als dat geen conflict geeft met zoom/pan-interactie; anders weglaten in v1
Pannen/slepen:
- optioneel in v1
- alleen toevoegen als licht en stabiel
- geen ingewikkelde canvas/viewer-stack bouwen
Aanbevolen minimalistische v1:
- CSS transform zoom
- centreren zolang mogelijk
- eventueel natuurlijke browser-scroll/pan bij grotere zoom, in plaats van custom drag-logica
5. Backend-impact
Aanbevolen backendrichting:
- nieuw read-only image endpoint, analoog aan PDF/video, bijvoorbeeld:
GET /api/files/image?path=...
Waarom een apart endpoint beter is dan hergebruik van random file-serving:
- consistente foutmapping
- duidelijke content-type-afhandeling
- hergebruik van bestaande
path_guard - expliciete scheiding van concerns per viewertype
Eisen:
- padvalidatie via bestaand
path_guard - alleen files
- directory -> bestaande
type_conflict - path not found -> bestaande not-found fout
- traversal / invalid root alias / outside whitelist -> bestaande securityfouten
- streaming/serving zonder onnodige buffering
- passend
Content-Type
Geen nieuwe backendsemantiek nodig buiten een read-only route.
6. Frontend-impact
Aanbevolen frontendrichting:
- aparte image-modal
- geen hergebruik van text/video/pdf modalbody
- wel dezelfde modalstructuur en focusregels als bestaande viewers
Waarom een aparte modal:
- image viewing heeft eigen interactie (fit/zoom)
- voorkomt rommelige uitzonderingslogica in de bestaande text viewer
- houdt type-dispatch helder
Focusgedrag:
- terwijl image-modal open is, geen paneelkeyboardnavigatie
Escapesluit modalF3enViewblijven via dezelfde dispatch werken
7. File Info uitbreiding
Aanbevolen extra velden voor image-bestanden in v1:
widthheightcontent_type
Optioneel, maar niet nodig voor v1:
- kleurprofiel
- EXIF orientation
- camera metadata
- creation date uit EXIF
Aanbevolen aanpak:
- alleen goedkope metadata
- afmetingen server-side afleiden zonder zware analyse
- geen brede EXIF feature
Voor niet-image bestanden blijven width en height gewoon null.
8. Regressierisico
Belangrijkste risico's:
- view-dispatch wordt rommeliger als image niet netjes als eigen type wordt behandeld
- modalfocus kan bestaande keyboardflow blokkeren of laten lekken
- grote afbeeldingen kunnen trager laden of veel viewport-ruimte vragen
- File Info response-uitbreiding moet backward-compatible blijven
Mitigatie:
- aparte image-modal
- eigen
isImageSelection(...)helper in dezelfde dispatchstijl als video/pdf - geen wijziging aan gewone
Enter - alleen extra velden aan File Info toevoegen, geen bestaande velden wijzigen
- zoom klein en beheersbaar houden
9. Teststrategie
Backend golden tests:
- image endpoint success voor ondersteund imagebestand
- directory ->
type_conflict - path not found
- traversal blocked
- invalid root alias
- non-image blocked of duidelijke unsupported fout
- File Info success voor imagebestand met
width/height - File Info voor niet-image met
width/height = null
UI smoke/regressietests:
- image-modal container aanwezig
- image viewer wiring aanwezig in
F3/Viewdispatch - text/video/pdf modal containers blijven aanwezig
- File Info modal blijft aanwezig
- geen extra zichtbare knop toegevoegd
Handmatige validatie:
F3opent image viewer bij exact 1 imageViewopent dezelfde image viewer- zoom in/out/reset werkt
- sluiten via
XenEscapewerkt - gewone
Enterblijft directory/open-semantiek houden - File Info toont width/height voor images
- grote afbeelding blijft bruikbaar zonder layoutbreuk
10. Aanbeveling
Aanbevolen v1-richting met laag regressierisico:
- nieuw read-only image endpoint
- aparte image-modal met browser-native
img - lichte zoombediening zonder externe image-viewer library
F3enViewgebruiken de bestaande centrale type-dispatch- File Info uitbreiden met alleen goedkope image metadata:
widthheight- bestaand
content_type
avifalleen best-effort, zonder extra dependency of browsergarantie
Dit houdt de stap klein, veilig en consistent met de bestaande architectuur:
- viewers blijven type-specifiek
- File Info blijft read-only
- browse- en keyboardflow blijven intact