Skip to content

feat: show recent files with font previews in the launcher - #468

Merged
kostyafarber merged 11 commits into
mainfrom
feat/launcher-recent-files
Sep 30, 2026
Merged

kostyafarber merged 11 commits into
mainfrom
feat/launcher-recent-files

Conversation

@kostyafarber

@kostyafarber kostyafarber commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • The launcher is rebuilt around recent files: a centred lockup, then a Recent header with New Font ⌘N (primary), Open Font… ⌘O, and a grid/list toggle. It opens as a 960×720 window (capped to 90% of smaller screens) and appears only once its recent files have rendered; the lockup and header sit at a fixed position so switching views never moves them.
  • Grid cards show a specimen drawn from the font, the filename (middle-truncated so the extension stays visible), and when it was opened; list rows add a specimen chip and the full path. Hovering reveals a ⋯ menu with Reveal in Finder, Copy Path, and Remove from Recents (with undo). Missing files are dimmed and offer Locate… and Remove.
  • File → Open Recent lists the same files and has Clear Menu.
  • Recents live in main (recent-documents.json in userData, capped at 20), keyed by DocumentId with a canonical-path fallback, and are recorded on every open, Save As, and preview conversion. Updates are held back from the launcher while a font opens, so it never shows a half-ready card.
  • New shift-specimen crate: picks the specimen from the compiled font (symbol glyphs → declared non-Latin dlng languages → Ag → script pair → AG/ag → first drawn glyphs), shapes it with HarfRust at the default location, and returns SVG path data fitted to the ink. .shift documents and sources compile through the existing fontc exporter (FontExporter::compile_ttf); binaries are read as they are.
  • Specimens are built in the session's utility process after an open (when missing or stale) and after each save, then cached per file with a rules revision. The launcher never opens fonts.
  • Shared UI: ToggleGroup/Toggle, a strong Separator variant, Select options that align and don't wrap, and an on-accent theme token so primary buttons stay readable on pale accents (e.g. Dracula).

Issue

Closes #467

Testing

  • pnpm check (lint, typecheck, desktop unit tests)
  • Pre-commit hooks: cargo check, fmt, clippy, cargo test, oxlint, tsgo, vitest, dead-code, sdk API report
  • cargo test -p shift-specimen — rule selection, dlng parsing, viewport fitting
  • Specimen choice spot-checked through the native addon against real fonts: SF Arabic → حب, SF Hebrew → אב, AppleGothic → 한, Ayuthaya → กข, Georgia / New York / Open Sans → Ag, MutatorSans → AG, Homenaje.glyphs (compiled from source) → Ag, symbol fonts → first drawn glyphs
  • Manually verified in the running app in light and dark themes: grid, specimens, ⋯ menu, New font, Open Font…
  • E2E not run locally: new e2e/recent-files.spec.ts (platform project) covers reopen-from-card after relaunch, specimen text, remove + undo, and Open Recent + Clear Menu; existing specs and fixtures now use the "New Font" and "Open Font…" buttons
  • landing-default.png will fail until regenerated with ci: update visual snapshots

Follow-up

  • Stale specimens (after a rules revision bump, or for fonts never reopened) only rebuild on the next open; building them in the background on launcher start is not in this PR.
  • fontc does not write meta dlng, so compiled documents and sources always take the Ag-first path.

🤖 Generated with Claude Code

The launcher lists recently opened fonts as cards with a specimen drawn
from each font, and File gains Open Recent with Clear Menu. Recents live
in main, keyed by DocumentId with a path fallback, and are recorded on
every open, Save As, and preview conversion.

Specimens are chosen from the compiled font (symbol glyphs, a declared
non-Latin design language, Ag, a script pair, then AG or ag), shaped
with HarfRust at the default location, and cached per file. Documents
and sources compile through the existing fontc exporter in the session's
utility process, so the launcher never opens fonts itself.
Themes now choose an on-accent text colour, white or the palette's darkest
colour, by contrast with their accent, so primary buttons stay legible on
palettes such as Dracula whose accent is pale.
The launcher opens as a 4:3 window that appears only once its recent
files have rendered, with the lockup and Recent header at a fixed
position so switching between the new grid and list views never moves
them. New Font becomes a primary header button beside Open Font and the
view toggle, replacing the New font card. Opening a font no longer
flashes a blank card in the launcher it replaces.

Adds shared ToggleGroup and Toggle components and a strong Separator
variant.
@kostyafarber kostyafarber added the ci: update visual snapshots Regenerate visual snapshots on a same-repository pull request label Sep 30, 2026
Comment thread apps/desktop/src/main/app/App.ts Outdated
Comment thread apps/desktop/src/main/recents/RecentDocuments.ts Outdated
Comment thread crates/shift-specimen/src/lib.rs
Comment thread crates/shift-specimen/src/lib.rs
@kostyafarber kostyafarber added ci: update visual snapshots Regenerate visual snapshots on a same-repository pull request and removed ci: update visual snapshots Regenerate visual snapshots on a same-repository pull request labels Sep 30, 2026
github-actions Bot and others added 4 commits September 30, 2026 10:16
Specimens for documents and sources were compiled from the whole font.
The specimen rules now plan from the character map which characters they
could shape, and only those glyphs (with their components, .notdef, and
the first drawn glyphs) are compiled, without features or kerning. Fonts
whose specimen needs contextual forms (Arabic without Latin) still
compile whole. On Fraunces (697 glyphs) the compile drops from 38 ms to
2 ms.
List rows now show just the filename; holding Alt (Option) prefixes it
with its folder, home-shortened to ~, so the path reads inline without
cluttering every row. The launcher also takes the theme's text colour,
so unstyled text such as Open Font follows dark palettes.
@kostyafarber kostyafarber added ci: update visual snapshots Regenerate visual snapshots on a same-repository pull request and removed ci: update visual snapshots Regenerate visual snapshots on a same-repository pull request labels Sep 30, 2026
@kostyafarber kostyafarber added the release: nightly Run a Nightly build after this pull request merges label Sep 30, 2026
@kostyafarber
kostyafarber added this pull request to the merge queue Sep 30, 2026
Merged via the queue into main with commit cd7be80 Sep 30, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci: update visual snapshots Regenerate visual snapshots on a same-repository pull request release: nightly Run a Nightly build after this pull request merges

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show recent files with previews in the launcher and Open Recent

1 participant