Commit Graph
8 Commits
Author SHA1 Message Date
Mika Kuns 9fc8ed391e fix(ui): offload UnifiedDiffParser.Parse off the UI thread in DiffViewerViewModel
Both call sites (LoadFilesAsync, OnDisplayedDiffChanged) ran the parser
synchronously on the dispatcher, freezing the window on a large diff. The
Files-mode parse+tree-build now runs via Task.Run behind a ParseOp
OperationStatus wired to the toolbar; the planning-mode parse is
fire-and-forget with a generation counter so a fast second DisplayedDiff
change can't write stale PlanningFiles.
2026-08-12 13:19:20 +02:00
mika kuns f74c7dd70b fix(ui): diff viewer opens non-modal and maximizable
The diff viewer used ShowDialog at both call sites (task details, worktrees
overview), blocking navigation of the rest of the app while open. Switch both
to Window.Show(owner) and reuse the one open window (swap DataContext,
Activate()) instead of stacking a second one on re-open.

Add an opt-in maximize/restore button + double-click-titlebar toggle to
ModalShell (ShowMaximizeButton, default false so other modals are untouched),
wired on for DiffViewerView only. Reuses the existing Icon.WinMax/WinRestore
geometry and OffScreenMargin inset from MainWindow's own maximize handling.

The review gate (Approve & Merge locked until the diff is opened) already
fires DiffViewed before the dialog/window is shown, so it is unaffected by
the modal-to-non-modal change.
2026-08-10 13:46:56 +02:00
mika kuns 9437121f3a fix(diff): label split panes, unify the mode switch, sync split scrolling
Three things were wrong with the fresh side-by-side viewer:

- The panes scrolled independently. The sync hunted the editors' templated
  ScrollViewers at load time, but the viewer starts collapsed (no file selected),
  so nothing was ever measured, no template existed, and the hook silently
  no-opped for the lifetime of the window. Reading now goes through
  TextView.ScrollOffsetChanged, which exists from construction; writing goes
  through a lazily resolved ScrollViewer.Offset. TextEditor.ScrollToVerticalOffset
  is NOT usable here - it is a silent no-op in AvaloniaEdit 12.0.0 even with the
  editor templated (verified headlessly).
- Neither pane said what it showed. Added a BASE | WORKTREE header row inside
  DiffTextView, sharing the pane grid's columns so each label sits over its editor.
- The layout picker was two lookalike ToggleButtons. It is now a segmented switch
  (Border.segmented + Button.segment.active), with wrap demoted to an icon toggle
  since it is orthogonal to the layout mode.

The scroll sync, TextMate setup, grammar switching, brush fallback and segment
struct were duplicated between this control and the 3-pane conflict resolver,
which the design doc had used as a copy-paste template. They now live in
DiffEditorSetup; both surfaces migrated. They stay separate controls on purpose -
a read-only two-way renderer over aligned rows with filler lines is not a variant
of a three-way editor over a writable document.

The resolver thereby also picks up the fixed scroll sync and the TryFindResource
brush lookup (its TryGetResource never resolved anything). All four merge tokens
happen to equal their hardcoded fallbacks, so nothing changes on screen.
2026-08-07 13:30:34 +02:00
mika kuns f7fa8292e0 refactor(diff): render planning mode per file and retire DiffLinesView 2026-08-07 09:56:02 +02:00
mika kuns cf80fe3cd6 feat(diff): add persisted side-by-side and wrap toggles to the diff viewer 2026-08-07 09:42:43 +02:00
Mika Kuns 6c8de4aef3 style(ui): pad the diff-viewer file-tree stats off the right edge 2026-07-27 15:02:50 +02:00
mika kuns b9b3053051 fix(ui): clearer rename display in diff viewer
Show renames as old → new in the file header and suppress the misleading
"+0 −0" stats for a pure rename (the R badge already conveys it).
2026-07-24 11:21:20 +02:00
Mika Kuns 167d2fec6a refactor(diff): single DiffViewer replaces DiffModal + WorktreeModal + PlanningDiff 2026-06-26 16:11:49 +02:00