Skip to content

Avalonia Port: MVVM Refactor, macOS Fixes, and UI Improvements#4529

Merged
Gabriel Dufresne (GabrielDuf) merged 8 commits intomainfrom
Avalonia-port
Mar 26, 2026
Merged

Avalonia Port: MVVM Refactor, macOS Fixes, and UI Improvements#4529
Gabriel Dufresne (GabrielDuf) merged 8 commits intomainfrom
Avalonia-port

Conversation

@GabrielDuf
Copy link
Contributor

Full MVVM refactor of the Avalonia port: all user actions are now driven by [RelayCommand] bindings in AXAML, code-behind files are reduced to minimal UI wiring, and several macOS-specific crashes and visual issues have been fixed.

MVVM / Architecture

  • All Click= handlers on buttons, menu items, and navigation controls replaced with Command="{Binding ...Command}" compiled bindings
  • Settings pages: SettingName, Text, and StateChanged assignments moved from code-behind to AXAML attributes; ViewModels now own the [RelayCommand] and [ObservableProperty] definitions
  • AbstractPackagesPage: sort commands on PackagesPageViewModel; Share / Help / Manage-Ignored-Updates moved to ViewModel events with view-side handlers for clipboard and dialogs
  • OperationOutputWindow: rewritten as proper .axaml + .axaml.cs + OperationOutputViewModel, replacing the code-only Window

UI / Style

  • Sidebar collapse/expand implemented
  • Per-platform stylesheets (Styles.macOS.axaml, Styles.Windows.axaml, Styles.Linux.axaml) extracted from App.axaml
  • t:Translate} markup extension added for inline translated strings in AXAML

Bug fixes

  • Fixed untranslated strings across settings and dialog pages
  • Fixed AbstractPackagesPage bugs
  • Fixed SvgIcon foreground visibility in dark theme
  • Fixed namespace collisions in settings-suffixed namespaces

@GabrielDuf Gabriel Dufresne (GabrielDuf) changed the title Avalonia port Avalonia Port: MVVM Refactor, macOS Fixes, and UI Improvements Mar 25, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ports additional UI interactions to MVVM for the Avalonia front-end by replacing code-behind click handlers with RelayCommand bindings, moving toolbar construction and several dialogs/navigation requests into ViewModels, and extracting platform/common styles into separate AXAML resource files (plus adding a {t:Translate} markup extension for inline translations).

Changes:

  • Replaced many Click=/code-behind handlers with Command bindings and ViewModel-driven requests (navigation, help, share, manage-ignored).
  • Refactored settings pages to declarative AXAML (setting keys/labels/commands) with supporting Settings* control enhancements (command properties).
  • Introduced per-platform/common style resources and a translation markup extension; updated several dialogs/windows to AXAML + ViewModel.

Reviewed changes

Copilot reviewed 78 out of 78 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/UniGetUI.Avalonia/Views/SoftwarePages/SoftwareUpdatesPage.cs Toolbar actions moved toward ViewModel request commands (share/help/manage ignored).
src/UniGetUI.Avalonia/Views/SoftwarePages/PackageBundlesPage.cs Toolbar actions moved toward ViewModel request commands (share/help).
src/UniGetUI.Avalonia/Views/SoftwarePages/InstalledPackagesPage.cs Toolbar actions moved toward ViewModel request commands (share/help/manage ignored).
src/UniGetUI.Avalonia/Views/SoftwarePages/DiscoverSoftwarePage.cs Toolbar actions moved toward ViewModel request commands (share/help).
src/UniGetUI.Avalonia/Views/SoftwarePages/AbstractPackagesPage.axaml.cs Wires ViewModel events for dialogs/navigation; removes sort/search UI handlers; updates sort menu check syncing.
src/UniGetUI.Avalonia/Views/SoftwarePages/AbstractPackagesPage.axaml Converts sort/search to commands & translated strings; adds list header select-all; toolbar styling tweaks.
src/UniGetUI.Avalonia/Views/SidebarView.axaml.cs Removes legacy click handlers; routes selection to ViewModel navigation request API.
src/UniGetUI.Avalonia/Views/SidebarView.axaml Sidebar UI refresh (collapse support, tooltips, badges) and command-based navigation.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Updates.axaml.cs Moves interval items/navigation/restart signaling to ViewModel.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Updates.axaml Declarative settings wiring via SettingName/Text/commands + {t:Translate}.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/SettingsHomepage.axaml.cs Replaces button click wiring with ViewModel navigation event; minor text tweak.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/SettingsHomepage.axaml Switches settings homepage buttons to command bindings + translated strings.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/SettingsBasePage.axaml.cs Removes direct button wiring; listens to VM back request.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/SettingsBasePage.axaml Back/restart buttons now bind to VM commands; back icon updated.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Operations.axaml.cs Moves restart/navigation and max-ops logic into ViewModel.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Operations.axaml Declarative setting bindings + commands for restart/navigation/max-ops update.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Notifications.axaml.cs Removes imperative settings wiring in code-behind.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Notifications.axaml Declarative setting bindings + commands and translated strings.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Internet.axaml.cs Moves credentials/proxy table building into ViewModel; wires restart event.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Internet.axaml Declarative proxy settings bindings + commands and translated strings.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Interface_P.axaml.cs Reduces code-behind; translation usage tweaks; restart signal wiring.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Interface_P.axaml Declarative settings bindings/commands + translated strings; icon-cache header binding.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/General.axaml.cs Moves restart/navigation signaling into ViewModel; keeps language list in code.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/General.axaml Declarative settings wiring + translated strings and command binding.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Experimental.axaml.cs Moves restart signaling into ViewModel; sets one label in code-behind.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Experimental.axaml Declarative experimental settings wiring + translated strings + restart commands.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Backup.axaml.cs Moves restart signaling/state init into ViewModel.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Backup.axaml Declarative backup settings wiring + commands and translated strings.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Administrator.axaml.cs Moves restart signaling into ViewModel; removes imperative wiring.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/Administrator.axaml Administrator settings converted to declarative bindings/commands; warning banner bound to VM strings.
src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs Removes click handlers in favor of command bindings.
src/UniGetUI.Avalonia/Views/MainWindow.axaml Adds sidebar toggle button; binds sidebar width; binds search submit command.
src/UniGetUI.Avalonia/Views/DialogPages/TelemetryDialog.axaml.cs Removes string initialization moved to AXAML.
src/UniGetUI.Avalonia/Views/DialogPages/TelemetryDialog.axaml Telemetry dialog strings moved to AXAML with {t:Translate}.
src/UniGetUI.Avalonia/Views/DialogPages/PackageDetailsWindow.axaml.cs Removes direct Close button handler; uses VM close request.
src/UniGetUI.Avalonia/Views/DialogPages/PackageDetailsWindow.axaml Close button now binds to VM command.
src/UniGetUI.Avalonia/Views/DialogPages/OperationOutputWindow.cs Removes code-only operation output window.
src/UniGetUI.Avalonia/Views/DialogPages/OperationOutputWindow.axaml.cs New AXAML-backed operation output window with VM.
src/UniGetUI.Avalonia/Views/DialogPages/OperationOutputWindow.axaml Defines operation output window UI and bindings.
src/UniGetUI.Avalonia/Views/DialogPages/ManageIgnoredUpdatesWindow.axaml.cs Adds flyout reset click handlers; hooks reset command execution.
src/UniGetUI.Avalonia/Views/DialogPages/ManageIgnoredUpdatesWindow.axaml UI refinements + translated tooltip; flyout theme styling.
src/UniGetUI.Avalonia/Views/Controls/Settings/TranslatedTextBlock.cs Clarifies preferred translation approach (markup extension).
src/UniGetUI.Avalonia/Views/Controls/Settings/TextboxCard.cs Adds ValueChangedCommand; stops auto-translating setters.
src/UniGetUI.Avalonia/Views/Controls/Settings/SettingsPageButton.cs Stops auto-translating setters (expects translated input).
src/UniGetUI.Avalonia/Views/Controls/Settings/SettingsCard.cs Adds Header/Description/Command styled properties and command execution on click.
src/UniGetUI.Avalonia/Views/Controls/Settings/SecureCheckboxCard.cs Adds StateChangedCommand; improves warning layout/formatting; stops auto-translate in setters.
src/UniGetUI.Avalonia/Views/Controls/Settings/ComboboxCard.cs Adds ValueChangedCommand; stops auto-translating header.
src/UniGetUI.Avalonia/Views/Controls/Settings/CheckboxCard.cs Adds StateChangedCommand; stops auto-translating setters.
src/UniGetUI.Avalonia/Views/Controls/Settings/CheckboxButtonCard.cs Stops auto-translating setters (expects translated input).
src/UniGetUI.Avalonia/Views/Controls/Settings/ButtonCard.cs Relies on base SettingsCard command properties; stops auto-translating setters.
src/UniGetUI.Avalonia/ViewModels/SoftwarePages/PackagesPageViewModel.cs Adds view-mode enum, toolbar builder APIs, sort/search commands, and dialog/navigation request events.
src/UniGetUI.Avalonia/ViewModels/SidebarViewModel.cs Adds collapsible pane state, compact badges, navigation command API, and version label binding.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/UpdatesViewModel.cs Adds restart/navigation events, interval list, and related commands.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/SettingsHomepageViewModel.cs Adds navigation commands for each settings section.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/SettingsBasePageViewModel.cs Adds Back/Restart commands and restart implementation.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/OperationsViewModel.cs Adds max-ops update logic and navigation/restart commands.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/NotificationsViewModel.cs Initializes state from settings and adds command to refresh enabled state.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/InternetViewModel.cs Moves proxy UI construction and restart signaling into ViewModel; adds related commands.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/Interface_PViewModel.cs Adds ShowRestartRequiredCommand.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/GeneralViewModel.cs Adds navigation command; exposes restart command.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/ExperimentalViewModel.cs Adds restart event and command.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/BackupViewModel.cs Initializes local-backup state; adds command to refresh and request restart.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/AdministratorViewModel.cs Adds restart signaling, warning text bindings, and state-refresh commands.
src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs Adds sidebar toggle, banner close commands, and search submit command.
src/UniGetUI.Avalonia/ViewModels/DialogPages/PackageDetailsViewModel.cs Adjusts several label strings; adds close relay command.
src/UniGetUI.Avalonia/ViewModels/DialogPages/OperationViewModel.cs Switches to Toolkit observable properties via base ViewModel.
src/UniGetUI.Avalonia/ViewModels/DialogPages/OperationOutputViewModel.cs New VM for operation output window (title + output text).
src/UniGetUI.Avalonia/ViewModels/DialogPages/ManageIgnoredUpdatesViewModel.cs Text/label updates for ignored-updates management dialog.
src/UniGetUI.Avalonia/UniGetUI.Avalonia.csproj Treats style-only AXAML as resources; adds dependent file mapping for new window.
src/UniGetUI.Avalonia/Models/PackageCollections.cs Migrates observable package collection to AvaloniaList; adjusts displayed version string.
src/UniGetUI.Avalonia/MarkupExtensions/TranslateExtension.cs Adds {t:Translate} markup extension for inline translated strings.
src/UniGetUI.Avalonia/Infrastructure/AvaloniaOperationRegistry.cs Uses AvaloniaList for operation view models.
src/UniGetUI.Avalonia/Assets/Styles/Styles.macOS.axaml New macOS-specific theme resources.
src/UniGetUI.Avalonia/Assets/Styles/Styles.Windows.axaml New Windows-specific theme resources.
src/UniGetUI.Avalonia/Assets/Styles/Styles.Linux.axaml New Linux-specific theme resources.
src/UniGetUI.Avalonia/Assets/Styles/Styles.Common.axaml New shared styling (SettingsCard, warning banner, SvgIcon foreground, DataGrid theme include).
src/UniGetUI.Avalonia/App.axaml.cs Loads platform stylesheet dynamically at startup.
src/UniGetUI.Avalonia/App.axaml Removes inline resources/styles; includes shared styles file.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@GabrielDuf Gabriel Dufresne (GabrielDuf) merged commit fd0b395 into main Mar 26, 2026
1 check passed
@GabrielDuf Gabriel Dufresne (GabrielDuf) deleted the Avalonia-port branch March 26, 2026 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants