Files
phokus/docs/ui-lab.md
T
LyAhn 7a18011b0f feat: add Phokus UI Lab
Add a dev-only Vite UI mode with Tauri API mocks, in-memory fixture scenarios, reusable media source handling, and documentation for browser-based visual testing.
2026-06-29 00:04:48 +01:00

4.9 KiB

Phokus UI Lab

Phokus UI Lab is a browser-only development mode for visual work on the real Phokus frontend. It runs the same App.tsx, Zustand store, components, and CSS as the Tauri app, but installs Tauri JavaScript mocks before the app imports.

This gives UI agents and contributors a stable browser target without launching the Rust backend or a Tauri window.

Run It

pnpm dev:ui

Then open:

http://127.0.0.1:1422

The script runs Vite in the custom ui mode:

vite --mode ui --host 127.0.0.1 --port 1422 --strictPort --open

The normal app development commands are unchanged:

pnpm dev:app   # Tauri app + Rust backend
pnpm dev:vite  # frontend dev server for Tauri dev

Scenarios

UI Lab reads ?scenario= from the URL. If no scenario is provided, it uses rich.

URL Purpose
/?scenario=rich Default realistic library with folders, albums, ratings, favorites, tags, images, and videos
/?scenario=empty First-run state with no folders or media
/?scenario=busy Background workers with pending thumbnail, metadata, embedding, caption, and tagging jobs
/?scenario=duplicates Duplicate Finder opened with duplicate groups already available
/?scenario=album Gallery opened directly into an album
/?scenario=errors Broken thumbnails, folder scan errors, failed embeddings, failed tagging, and metadata issues
/?scenario=huge Large mock library for virtualization and layout checks

Examples:

http://127.0.0.1:1422/?scenario=duplicates
http://127.0.0.1:1422/?scenario=errors
http://127.0.0.1:1422/?scenario=huge

How It Works

src/main.tsx bootstraps the app asynchronously. In ui mode it imports src/dev/setupMockTauri.ts first, then imports the real App.

That order matters because static imports are hoisted. The Tauri mocks must be installed before App, the store, the title bar, or visual components import Tauri APIs.

The mock setup installs:

  • mockWindows("main") for window APIs used by the title bar
  • mockConvertFileSrc("windows") as a baseline Tauri file URL mock
  • mockIPC(..., { shouldMockEvents: true }) for invoke, listen, and emit

The in-memory backend lives in:

src/dev/mockBackend.ts
src/dev/mockFixtures.ts
src/dev/mockScenarios.ts
src/dev/applyMockScenario.ts

Happy-path fixture media is imported from the existing onboarding assets in:

src/assets/onboarding/

Synthetic or deliberately broken fixture paths can still use the mock:// scheme described below.

Mock Media

Visual components should use mediaSrc(...) instead of calling convertFileSrc(...) directly:

import { mediaSrc } from "../lib/mediaSrc";

const src = mediaSrc(image.thumbnail_path);

In normal Tauri modes, mediaSrc delegates to convertFileSrc. In UI Lab, already-resolved Vite asset URLs are returned as-is, so fixtures can reuse existing imported assets. Paths beginning with mock:// are served from public/dev-media:

mock://thumb-1.svg -> /dev-media/thumb-1.svg

Use mediaSrc when adding components that render thumbnails, album covers, preview images, or video posters.

Adding A Mock Command

If the browser console logs an unmocked command, add it to src/dev/mockBackend.ts.

Prefer returning realistic data for commands that affect visible UI. For actions that would touch the machine, return a safe no-op:

case "open_app_data_folder":
  return null;

When adding fixture data, keep it shaped like the real store/Rust contracts. Most frontend-facing types are exported from src/store.ts, so the mocks can stay type-checked against the real UI.

Adding A Scenario

  1. Add the scenario name to MockScenario and SCENARIOS in src/dev/mockScenarios.ts.
  2. Adjust fixture creation in src/dev/mockFixtures.ts.
  3. If the scenario should open a specific view, add that behavior in src/dev/applyMockScenario.ts.
  4. Visit http://127.0.0.1:1422/?scenario=your-scenario and check for console errors.

What UI Lab Is For

UI Lab is intended for:

  • visual iteration on the real app shell
  • layout and responsive checks
  • state-heavy views like Explore, Timeline, Duplicates, albums, and Settings
  • AI-agent screenshot/browser inspection
  • safe UI work without filesystem or Rust-side effects

It is not a replacement for Tauri app testing. Validate native behavior with pnpm dev:app when touching:

  • file or folder pickers
  • filesystem permissions
  • real thumbnail/video loading
  • window drag, minimize, maximize, or close behavior
  • Rust backend performance
  • updater installation
  • WebView2-specific behavior

Verification

Useful checks after changing UI Lab:

pnpm exec tsc --noEmit
pnpm build:vite
pnpm dev:ui

Then smoke-test at least:

http://127.0.0.1:1422/?scenario=rich
http://127.0.0.1:1422/?scenario=empty
http://127.0.0.1:1422/?scenario=duplicates
http://127.0.0.1:1422/?scenario=errors
http://127.0.0.1:1422/?scenario=huge