Skip to content

UX improvements: inline filter settings, resizable panels, temp directory setting - #54

Merged
StuartCameronCode merged 4 commits into
mainfrom
feat/ux-improvements
Aug 1, 2026
Merged

UX improvements: inline filter settings, resizable panels, temp directory setting#54
StuartCameronCode merged 4 commits into
mainfrom
feat/ux-improvements

Conversation

@StuartCameronCode

Copy link
Copy Markdown
Owner

A batch of UX work, plus one pre-existing macOS bug found along the way. Four commits, each independent.

Inline filter settings (e0d8dbc)

Pass settings used to render in a separate panel below the pass list, so the controls you were editing sat far from the filter they belonged to. Each pass now expands in place — tapping a row reveals its settings directly underneath, tapping again collapses it. selectedPass became nullable to allow the collapsed state.

Above each filter's options is a description block: the schema's one-line description, with a More expander revealing a new longDescription covering what the filter does and when you'd reach for it. All twelve core schemas carry one.

Panels are resizable. The new ResizableSplit widget puts a draggable divider between two panes (resize cursor, hover highlight), used for preview ↔ right panel and queue ↔ pipeline list. Dragged sizes persist across launches; double-clicking a divider resets to automatic.

The queue pane's automatic height now follows its contents instead of a fixed 180px, so a single file no longer leaves a mostly-empty box — it grows per item up to 260px, then scrolls.

Opaque macOS window (a27bf98)

WindowOptions carried backgroundColor: Colors.transparent, which has window_manager set the native window to NSColor.clear with isOpaque false. The Flutter view only covers the content area, so nothing painted behind the macOS title bar — it rendered as a floating title and traffic lights over the desktop. Present since the Flutter migration; visible on macOS 26.

Bug reporting, About moved into Settings (c992872)

The toolbar had accumulated an icon per destination. About moves into Settings alongside a new "Report a bug or give feedback" entry that opens the GitHub issue tracker, both under About & Feedback on the General tab. The issues URL is built from githubRepo in deps-version.json, so a fork points at its own tracker.

Settings tabs reordered General, Output, Input, so the tab that opens first holds app-wide settings rather than per-job input options.

Configurable temp directory (449fc3f)

Scratch files — generated .vpy scripts, job config, preview frames, progress files, extracted DVD titles — always went to the system temp directory. A DVD rip alone can need several GB, which is a problem when system temp sits on a small or slow volume. Settings → General → Temporary Files now points them anywhere, with ✕ to reset to the system default.

Two mechanisms cover the two processes:

  • Dart call sites go through the new TempDirectoryService.
  • Rust needs no per-path plumbing: ToolLocator.workerEnvironment sets TMPDIR/TMP/TEMP from the effective path, so every env::temp_dir() in the worker follows it — scripts, progress files, preview raw frames, GPU probes, the macOS vspipe conf — as do the ffmpeg and vspipe children. Applied per call rather than baked into the cached env map, so a change needs no restart.

Choosing a directory writes a probe file first, so a read-only volume is rejected at selection time rather than failing mid-job. If it later disappears, resolve() recreates it, falling back to system temp if it can't.

Testing

  • flutter test --exclude-tags heavy — 227 passing, including 8 new tests in app/test/temp_directory_service_test.dart
  • cargo test — 207 passing (subtitle_integration_test needs a locally-downloaded whisper model, unrelated)
  • The worker half of the temp redirect was verified directly: generating a script with TMPDIR pointed elsewhere put the .vpy in the override
  • The heavy nightly suite has been dispatched against this branch, since the temp-directory change touches every worker spawn

Docs: CLAUDE.md and README.md updated for the temp directory setting, including the two rules a future change could trip on — don't add new Directory.systemTemp uses, and any new worker/tool spawn must pass workerEnvironment.

The pass settings used to render in a separate panel below the pass
list, so the controls you were editing sat far from the filter they
belonged to. Each pass now expands in place: tapping a row reveals its
settings directly underneath in a bordered block, and tapping it again
collapses it. `selectedPass` is nullable to allow that collapsed state.

Above every filter's options is a description block — the schema's
one-line `description`, with a "More" expander revealing the new
`longDescription`: what the filter does and when you'd reach for it.
All twelve core schemas carry one.

Panels are now resizable. `ResizableSplit` puts a draggable divider
between two panes (proper resize cursor, hover highlight); it is used
for preview vs. right-hand panel and for queue vs. pipeline list. The
dragged size persists across launches, and double-clicking a divider
returns the pane to its automatic size.

The queue pane's automatic size now follows its contents rather than a
fixed 180px, so a single file no longer leaves a mostly-empty box; it
grows per item up to 260px, after which the list scrolls.
WindowOptions carried backgroundColor: Colors.transparent, which has
window_manager set the native window to NSColor.clear with isOpaque
false. The Flutter view only covers the content area, so nothing paints
behind the macOS title bar — it renders as a floating title and traffic
lights over whatever is behind the window. Dropping the option restores
the platform default background, which follows light/dark mode.

Present since the Flutter migration; visible on macOS 26.
The toolbar had accumulated an icon per destination. About moves into
Settings alongside a new "Report a bug or give feedback" entry that
opens the project's GitHub issue tracker, both under an "About &
Feedback" section on the General tab. The toolbar keeps only the
controls that act on the current job.

The issues URL is built from the githubRepo in deps-version.json — the
same source the About dialog uses — so a fork points at its own tracker,
falling back to the upstream repo if that read fails. If no browser
handler is available it offers the URL to copy rather than doing
nothing.

Settings tabs are reordered General, Output, Input, so the tab that
opens first is the one holding app-wide settings rather than per-job
input options.
Scratch files — generated .vpy scripts, job config, preview frames,
progress files and extracted DVD titles — always went to the system temp
directory. A DVD rip alone can need several GB, which is a problem when
system temp sits on a small or slow volume. Settings → General →
Temporary Files now points them anywhere; the ✕ resets to the system
default. The choice persists in shared_preferences.

Two mechanisms cover the two processes. Dart call sites go through the
new TempDirectoryService (worker job config, preview frames, DVD
extraction, deps and whisper downloads). The worker needs no per-path
plumbing: ToolLocator.workerEnvironment now sets TMPDIR/TMP/TEMP from
the effective path, so every env::temp_dir() in the Rust side follows
it — scripts, progress files, preview raw frames, GPU probes, the macOS
vspipe conf — as do the ffmpeg and vspipe children. Those vars are
applied per call rather than baked into the cached env map, so a change
takes effect without a restart.

Choosing a directory writes a probe file first, so a read-only volume is
rejected at selection time rather than failing mid-job. If the directory
later disappears, resolve() recreates it, falling back to system temp if
it can't — a job in the wrong temp directory beats a job that can't run.

Covered by app/test/temp_directory_service_test.dart; the worker half
was verified by generating a script with TMPDIR pointed elsewhere.
@StuartCameronCode
StuartCameronCode merged commit e03bea3 into main Aug 1, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant