Record Images
UI for attaching images to a time record and viewing them. A record carries a list of image filenames (TimeRecord.images); the image bytes live on disk alongside the record’s month directory.
Source: Minuta/Sources/Views/Components/RecordImageViews.swift.
Data model
TimeRecord.images is an array of filenames, not bytes. The files are stored in the record’s day directory under the Automerge records/ tree and resolved through the storage service (storage.loadImage(filename:for:) / saveImage / deleteImage). See TimeRecord.
Components
ImageGalleryView
A horizontal scroll of 60×60 thumbnails for record.images. Thumbnails load lazily in loadImages() via appState.storage.loadImage(...); images that fail to load are skipped and logged. Each thumbnail:
- taps to open the full-screen viewer,
- offers a context menu with View, a
ShareLink, and (whenonDeleteis provided) Delete.
onDelete is an optional (Int) -> Void callback keyed by index, so the gallery is reusable in both read-only and editable contexts.
FullScreenImageView
A modal (NavigationStack) that shows one image fit-to-screen with pinch-to-zoom (MagnificationGesture) and drag-to-pan (DragGesture). Zooming below 1.0 snaps back. The toolbar has a Done button, a ShareLink, and an optional Delete action.
ImagePickerView
A UIViewControllerRepresentable wrapping PHPickerViewController (single image, images-only) for picking from the photo library. On Mac Catalyst, DocumentImagePickerView wraps UIDocumentPickerViewController instead, handling the security-scoped resource so a file can be picked from the filesystem.
ImageUtilities
Before an image is stored it is normalized:
static let maxDimension: CGFloat = 1920
static let compressionQuality: CGFloat = 0.8 processImage(_:) resizes (preserving aspect ratio) so the longest side is at most 1920px, then encodes JPEG at 0.8 quality. This keeps attachments small without a separate thumbnail pipeline.
Editing flow
The picker and gallery are presented from the record editor, which owns the add/remove actions and persists the updated images list on save.
Report embedding
The same on-disk images can be embedded into exported reports. The SVG report renderer inlines up to a few images as data: URIs (the CLI’s export report --with-images). See SVG report renderer.
Related
- TimeRecord — the
imagesfield and on-disk layout. - Record editor — where images are attached and removed.
- SVG report renderer — embedding images in reports.