FModel/.github/agents
Rob Trame 40d8b73ec5
fix: address remaining WPF→Avalonia gaps for phase 2 completion (#85)
* fix: address remaining WPF→Avalonia gaps for phase 2 completion

Resolves r6e/FModel-Linux#84

- Convert Colors.xaml & Icons.xaml to Avalonia xmlns
- Migrate CommitControl to Avalonia (replace DataTriggers with IsVisible)
- Migrate SearchTextBox to Avalonia (StyledProperty, native Watermark)
- Migrate TreeViewItemBehavior to Avalonia attached properties
- Replace ListCollectionView with DataGridCollectionView in 8 ViewModels
- Add Framework/CompositeCollection as WPF CompositeCollection replacement
- Remove AdonisUI.Controls refs from LoadCommand & AddEditDirectoryCommand
- Replace SystemParameters with Avalonia screen API in CUE4ParseViewModel
- Rewrite Resources.xaml for Avalonia Fluent theme (~2150→290 lines)
- Extend CommitMessageConverter with HasDescription parameter support

* fix: address review findings for PR #85

- C1: Fix ToolTip syntax (TextBlock.ToolTip → ToolTip.Tip) in tree view
- C2: Add Fill binding to folder icons via ConverterParameter=Brush
- C3: Convert AddEditDirectoryCommand.ShowDialog() to async with owner
- M1: Convert keyed Style → ControlTheme + Theme= in all consumers
- M2: Fix CommitControl badge overlap (Latest/Current mutual exclusivity)
  Add FallbackValue=False for null-safe Asset.IsLatest binding
- M3: Add TODO(P4-004) markers for OpenFileDialog/SaveFileDialog
- M4: Implement IDisposable on CompositeCollection; dispose on replace
- PR: Add UrlToBitmapConverter for HTTP avatar image loading
- PR: Fix ContextMenu DataContext in GameFilesTabControl ContentTemplate
  Restore 'Disable Alpha Channel' toggle (NoAlpha binding)
- PR: Replace ElementName=TabControlName with direct DataContext bindings
- PR: TreeViewItemBehavior uses GetObservable(IsSelectedProperty) with
  proper IDisposable subscription cleanup
- S1: Clarify UpdateViewModel grouping TODO (non-DataGrid limitation)
- S2: Cache compiled Regex in SearchViewModel.ItemFilter
- m3: Implement TabItemFillSpace with HorizontalAlignment=Stretch

Also updates FolderToGeometryConverter to support ConverterParameter
for explicit brush/geometry selection.

* fix: address review #2 findings on PR #85

- M1/m1/m2: UrlToBitmapConverter — sync download with ConcurrentDictionary
  URL cache, 4-space indent, doc comment noting async limitation
- M2: Remove duplicate IsVisible attribute on Latest badge Border
  (MultiBinding property element takes precedence; attribute was dead code)
- m3: Add TimeSpan.FromSeconds(1) timeout to user-input Regex construction
- PR: ZIndex → Panel.ZIndex in SearchTextBox.xaml (Avalonia attached prop)
- PR: ShadowEffect comment updated to reflect key removal (no consumers)
- PR: CustomSeparator Tag TextBlock hidden when empty via
  StringConverters.IsNotNullOrEmpty (eliminates unwanted 10px margin)
- PR: CustomVerticalSeparator BasedOn changed from default Separator to
  CustomSeparator (preserves tagged template inheritance from WPF)
- PR: AddEditDirectoryCommand — early return when owner is null instead
  of silently skipping dialog
- PR: CompositeCollection.Count — skip non-ICollection sources instead
  of O(n) enumeration fallback

* Fix Avalonia parity gaps in updates, styles, and dialogs

* fix: address parity review follow-ups and unresolved PR comments

* Fix remaining PR review thread regressions

* Address review findings: thread safety, Linux guards, indentation, and cleanup

- [C1] Fix LoadCoAuthors thread race by snapshotting Commits before Task.Run
- [M1] Remove IsAsync=True (WPF-only) from Avalonia bindings
- [M2] Add OperatingSystem.IsWindows() guard for Win32 OpenFileDialog
- [M3] Add null-safety for Application.Current in PlayPause converter
- [N1] Add BrushTransition to HighlightedCheckBox for animation parity
- [N2] Dispose TreeViewItem subscriptions on DetachedFromVisualTree
- [N3] Fix SelectionMode converter: only Multiple uses multi-select
- [S1] Simplify AddEditDirectoryCommand owner-null to early return
- [S3] Remove dead WPF trigger comments from UpdateView.xaml
- [S4] Add 10s timeout to UrlToBitmapConverter HttpClient
- PR: Reformat UrlToBitmapConverter to 4-space indentation
- PR: Catch RegexMatchTimeoutException in SearchViewModel filter

* Fix review round 2: ActualWidth→Bounds, IsAsync removal, FindAncestor xmlns, misc

Critical:
- C1: Replace ActualHeight/ActualWidth with Bounds.Height/Bounds.Width
  in UpdateView, MainWindow, SettingsView, DirectorySelector (Avalonia
  has no ActualWidth/ActualHeight properties)
- C2: Remove remaining IsAsync=True from SearchView.xaml and
  AudioPlayer.xaml (WPF-only, no-op in Avalonia)

Major:
- M1: Add xmlns:views for FModel.Views and replace dotted sub-namespace
  local:Views.SettingsView with views:SettingsView in all 23
  FindAncestor bindings (avoids ambiguous XAML type resolution)
- M2: CompositeCollection.Count now skips non-ICollection sources
  instead of enumerating them (O(1) for current callers)

Minor:
- N1: Add Application.Current null guard in FolderToGeometryConverter
  (matches PlaybackStateToPlayPauseConverter pattern)

Suggestions:
- S1: UrlToBitmapConverter.LoadAsync now cleans up _inFlight on all
  exit paths (defense-in-depth for exceptional failures)
- S2: Add comment in CommitMessageConverter documenting interaction
  with LoadCoAuthors co-author cleanup

* fix: merge resource dicts, regex cache, handler cleanup, null-init

- Merge Colors.xaml, Icons.xaml, Resources.xaml into App.xaml so
  StaticResource/DynamicResource lookups resolve at runtime
- Cache invalid regex state in SearchViewModel to avoid repeated
  recompilation on every filter invocation
- Detach DetachedFromVisualTree handler in TreeViewItemBehavior
  when IsBroughtIntoViewWhenSelected is set to false
- Fix LoadingModeToSelectionModeConverter doc to match behavior
- Initialize Commit/Author backing fields with null! to satisfy
  non-nullable contract before JSON deserialization
- Add Debug.Fail in CompositeCollection.Count for non-ICollection
  sources to surface unexpected usage in development

* fix: load missing resource dictionaries, remove dead style refs, fix using

- App.xaml: add ResourceInclude for FileContextMenu, FolderContextMenu,
  and TiledExplorer/Resources.xaml so StaticResource lookups resolve at
  runtime (C1 fix)
- TiledExplorer/Resources.xaml: remove ContextMenu Setters from both
  TiledExplorer and AssetsListBox styles; Avalonia does not support
  x:Shared="False", so the shared instance would break when two
  ListBoxes reference the same ContextMenu. ListBoxItemBehavior already
  handles assignment programmatically via TryFindResource on right-click.
- SettingsView.xaml: remove 11 references to undefined TextBoxDefaultStyle;
  HotkeyTextBox inherits FluentTheme TextBox styling by default (C2 fix)
- LoadingModeToSelectionModeConverter.cs: add missing 'using FModel' for
  ELoadingMode resolution (M1 fix)

* fix: convert Resources.xaml to Styles root, restore toggle button states

- Resources.xaml: change root from <ResourceDictionary> to <Styles> so
  StyleInclude in App.xaml correctly loads an IStyle-implementing element.
  All keyed resources (ControlThemes, converters) moved into
  <Styles.Resources>; selector-based styles (audio controls, FoldingMargin)
  are direct <Styles> children.
- AssetsExplorerToggleButtonStyle: restore IsChecked-dependent behavior
  using Avalonia selectors. :checked shows FolderIconAlt + accent background,
  :unchecked shows AssetIcon + default background. Tooltip shows hotkey.
- MainWindow.xaml: add Classes="AssetsExplorerToggle" to the toggle button
  so the selector-based checked/unchecked styles match.

* Fix Round 7 review findings: ControlTheme, ToolTip.Tip, dead code

- C1: Convert keyed Styles to ControlTheme in TiledExplorer/Resources.xaml,
  update Style= to Theme= in MainWindow.xaml, convert CustomRichTextBox
  to auto-applying Style Selector in Resources.xaml
- M1: Fix ToolTip= to ToolTip.Tip= across SearchView, SettingsView,
  AudioPlayer, and DirectorySelector (22 occurrences)
- m1: Remove duplicate _inFlight.TryRemove in UrlToBitmapConverter.cs
- m2: Remove dead Result property from CustomDir.xaml.cs
- S2: Remove unused InvertBooleanConverter from Resources.xaml

* Fix PR review findings: image column collapse, thread safety

- Add HasImageToColumnSpanConverter so AvalonEditor spans all columns
  when HasImage is false, preventing unused blank space from the image
  column width (Resources.xaml GameFilesTabControl ContentTemplate)
- Marshal LoadAssets and LoadCoAuthors collection/property mutations to
  Dispatcher.UIThread.InvokeAsync for explicit thread safety

* fix: reformat HasImageToColumnSpanConverter to 4-space indentation

* fix: map All/AllButNew/AllButModified/AllButPatched to multi-select

LoadingModeToSelectionModeConverter only mapped Multiple to
SelectionMode.Multiple. The original WPF DataTriggers also enabled
Extended selection for All, AllButNew, AllButModified, and
AllButPatched modes. Add those mappings to restore parity.
2026-03-16 21:35:16 -06:00
..
audio-subsystem-porter.agent.md Set up dev env 2026-03-11 15:51:34 -06:00
avalonia-migration-reviewer.agent.md feat(images): Migrate BitmapImage/ImageSource to Avalonia.Media.Imaging.Bitmap [P2-011] (#79) 2026-03-15 19:09:04 -06:00
cross-platform-dotnet-reviewer.agent.md Set up dev env 2026-03-11 15:51:34 -06:00
dependency-modernizer.agent.md phase2: migrate App.xaml + App.xaml.cs to Avalonia bootstrap (#14) (#67) 2026-03-11 20:32:20 -06:00
game-detection-porter.agent.md Set up dev env 2026-03-11 15:51:34 -06:00
linux-ci-cd-setup.agent.md Set up dev env 2026-03-11 15:51:34 -06:00
port-planner.agent.md Finish setting up env 2026-03-11 17:28:01 -06:00
snooper-imgui-fixer.agent.md Set up dev env 2026-03-11 15:51:34 -06:00
windows-api-abstractor.agent.md Set up dev env 2026-03-11 15:51:34 -06:00
wpf-to-avalonia-migrator.agent.md fix: address remaining WPF→Avalonia gaps for phase 2 completion (#85) 2026-03-16 21:35:16 -06:00