Sidebar: real attachment thumbnails and hover previews (attachments, notes) #27

Open
opened 2026-09-15 06:49:35 +00:00 by kayg · 6 comments
Owner

Report (user, 2026-09-15)

Sidebar attachment cards show no thumbnails for real photos; and there is no hover preview (mailternal-style popover) for attachments — nor for notes.

Root cause

SidebarAttachment.thumbnailResourceName is only populated by SyntheticDataSource (bundle PNGs in SyntheticAttachments); AttachmentDeck loads thumbnails solely from the bundle (AttachmentThumbnailCache.image(named:)). Real vault attachments never get a thumbnail.

Acceptance

  • Real image attachments (jpg/png/heic/…) show a 64 px thumbnail in the deck, generated off-main via QuickLookThumbnailing (QLThumbnailGenerator) for any file type, cached in memory + on disk under the Space's .calternal/ (per-Space state, DECISIONS.md #20); no sync file IO on hover or in row rendering; scroll-spam gate unaffected.
  • Hover preview popover for attachments AND note chips like mailternal's ReaderTabBar hover popover (same delays, size, material, dismissal): attachment → Quick Look preview; note → rendered excerpt (title + first lines).
  • VoiceOver labels; Reduce Motion respected.
## Report (user, 2026-09-15) Sidebar attachment cards show no thumbnails for real photos; and there is no hover preview (mailternal-style popover) for attachments — nor for notes. ## Root cause `SidebarAttachment.thumbnailResourceName` is only populated by `SyntheticDataSource` (bundle PNGs in `SyntheticAttachments`); `AttachmentDeck` loads thumbnails solely from the bundle (`AttachmentThumbnailCache.image(named:)`). Real vault attachments never get a thumbnail. ## Acceptance - Real image attachments (jpg/png/heic/…) show a 64 px thumbnail in the deck, generated off-main via QuickLookThumbnailing (`QLThumbnailGenerator`) for any file type, cached in memory + on disk under the Space's `.calternal/` (per-Space state, DECISIONS.md #20); no sync file IO on hover or in row rendering; scroll-spam gate unaffected. - Hover preview popover for attachments AND note chips like mailternal's ReaderTabBar hover popover (same delays, size, material, dismissal): attachment → Quick Look preview; note → rendered excerpt (title + first lines). - VoiceOver labels; Reduce Motion respected.
Author
Owner

Implemented on wave19/sidebar-previews: real QuickLook thumbnails (off-main, NSCache + per-Space .calternal/thumbnails, bounded), attachment hover popover (Quick Look) and note hover popover (excerpt) with mailternal's timing. Profiling on the VM caught a main-thread dispatch_sync in the QL cancel path (fixed e08cd27). Reviewer pass (9 findings) fixed in 7872b0b/046bfd5: symlink containment within the Space, Space+revision keyed identity, dismissal on scroll/selection/resign, note cache invalidation, bounded disk cache, apptests runner exit status. VM screenshots on the real QA fixture. On the user's desktop in wave19/desktop-test @ 5b72a45.

Implemented on wave19/sidebar-previews: real QuickLook thumbnails (off-main, NSCache + per-Space .calternal/thumbnails, bounded), attachment hover popover (Quick Look) and note hover popover (excerpt) with mailternal's timing. Profiling on the VM caught a main-thread dispatch_sync in the QL cancel path (fixed e08cd27). Reviewer pass (9 findings) fixed in 7872b0b/046bfd5: symlink containment within the Space, Space+revision keyed identity, dismissal on scroll/selection/resign, note cache invalidation, bounded disk cache, apptests runner exit status. VM screenshots on the real QA fixture. On the user's desktop in wave19/desktop-test @ 5b72a45.
Author
Owner

User feedback 2026-09-15: the note hover preview shows RAW markdown ('# Design review' with the hash). Rule for the whole app: rendered rich text everywhere; raw markdown is opt-in only (Show Markdown Source). The popover must render the excerpt with the editor's rendering (headings, lists, links, emphasis), not the source text.

User feedback 2026-09-15: the note hover preview shows RAW markdown ('# Design review' with the hash). Rule for the whole app: rendered rich text everywhere; raw markdown is opt-in only (Show Markdown Source). The popover must render the excerpt with the editor's rendering (headings, lists, links, emphasis), not the source text.
Author
Owner

User (2026-09-15): hover popovers must appear to the RIGHT of the attachment card / note chip (never above); note previews must be scrollable like mailternal (whole note in an NSScrollView-hosted text view, scroll wheel keeps the popover open), not a 6-line excerpt.

User (2026-09-15): hover popovers must appear to the RIGHT of the attachment card / note chip (never above); note previews must be scrollable like mailternal (whole note in an NSScrollView-hosted text view, scroll wheel keeps the popover open), not a 6-line excerpt.
Author
Owner

Settled (user): note thumbnail = miniature rendered page (64 pt) from the same projection as the hover preview, cached like image thumbnails; expanded chip rows show the same thumbnail (20 pt) + the real file/note name, never 'Media attachment'; hover popover shows the rendered body only (no header — the chip already names the note).

Settled (user): note thumbnail = miniature rendered page (64 pt) from the same projection as the hover preview, cached like image thumbnails; expanded chip rows show the same thumbnail (20 pt) + the real file/note name, never 'Media attachment'; hover popover shows the rendered body only (no header — the chip already names the note).
Author
Owner

Overnight (Main): sidebar-thumbs-preview @ 3a0f4c67 merged. VM: expanded child rows show a real thumbnail + real filename ('sidebar-real.jpg') (/tmp/vm/thumbs-main-selected2.png); sample during 120 key-repeat Down presses shows no NotePageThumbnail/MarkdownProjection frames on main (thumbnail generation moved off-main, memory cache now read). Note-page thumbnails and headerless popover are implemented; the cua checker's page/name assertions still depend on fixture navigation and did not run green — verify visually in the morning.

Overnight (Main): sidebar-thumbs-preview @ 3a0f4c67 merged. VM: expanded child rows show a real thumbnail + real filename ('sidebar-real.jpg') (/tmp/vm/thumbs-main-selected2.png); sample during 120 key-repeat Down presses shows no NotePageThumbnail/MarkdownProjection frames on main (thumbnail generation moved off-main, memory cache now read). Note-page thumbnails and headerless popover are implemented; the cua checker's page/name assertions still depend on fixture navigation and did not run green — verify visually in the morning.
Author
Owner

Overnight (Main) review fixes: note-page thumbnails were drawn with NSImage.lockFocus/TextKit on a detached utility thread and cached to disk as PNG (appearance baked in). Now the projection runs off-main behind the gate and the draw is deferred to NSImage(size:flipped:drawingHandler:) (renders in the displaying view's context, cached per scale); note pages are never persisted to .calternal/thumbnails (persistsToDisk on the generator; test testNotePageThumbnailIsNeverPersistedToDisk). VM merged build: sidebar_preview_check.py PASS real thumbnail / rendered note page / chip names / popovers right of row / popover scrolls; the "no header title" assertion still FAILs (pixel heuristic; not verified either way).

Overnight (Main) review fixes: note-page thumbnails were drawn with `NSImage.lockFocus`/TextKit on a detached utility thread and cached to disk as PNG (appearance baked in). Now the projection runs off-main behind the gate and the draw is deferred to `NSImage(size:flipped:drawingHandler:)` (renders in the displaying view's context, cached per scale); note pages are never persisted to `.calternal/thumbnails` (`persistsToDisk` on the generator; test `testNotePageThumbnailIsNeverPersistedToDisk`). VM merged build: `sidebar_preview_check.py` PASS real thumbnail / rendered note page / chip names / popovers right of row / popover scrolls; the "no header title" assertion still FAILs (pixel heuristic; not verified either way).
Sign in to join this conversation.
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
kayg/calternal-macos#27
No description provided.