feat: add system-aware dark mode - #271
Open
livvaa wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The theming service’s window Loaded class-handler registration captures an instance in a way that isn’t cleanly disposable and needs adjustment or a clear lifecycle decision to avoid leaks/inconsistent disposal behavior.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds an application-level theming system (Light/Dark/System) for the WPF UI, persists the selected theme in configuration, and updates key views/resources to consume centralized theme brushes so the UI can respond to theme changes at runtime.
Changes:
- Introduces
ApplicationThemeand a newThemeManagerservice that applies a light/dark palette and follows Windows theme when set to System. - Persists the theme choice in configuration and wires it into configuration application + Settings UI selection.
- Refactors various WPF resources/views to use shared theme brushes via
DynamicResource.
File summaries
| File | Description |
|---|---|
| src/SyncTrayzor/Xaml/Resources.xaml | Adds shared theme brushes and broad control styles/templates to consume them via DynamicResource. |
| src/SyncTrayzor/Xaml/PassiveListView.xaml | Switches list view visuals to shared theme resources. |
| src/SyncTrayzor/Xaml/BoringListView.xaml | Switches list view visuals to shared theme resources. |
| src/SyncTrayzor/Services/Theming/ThemeManager.cs | New theming service applying palette resources and window dark-mode attributes; listens for system preference changes. |
| src/SyncTrayzor/Services/Theming/ApplicationTheme.cs | New enum for Light/Dark/System selection. |
| src/SyncTrayzor/Services/ConfigurationApplicator.cs | Applies configured theme via IThemeManager when configuration changes. |
| src/SyncTrayzor/Services/Config/Configuration.cs | Adds persisted Theme setting with default System and includes it in copy/ToString. |
| src/SyncTrayzor/Properties/Resources.tr.resx | Adds Turkish localized strings for theme setting labels. |
| src/SyncTrayzor/Properties/Resources.resx | Adds English strings for theme setting labels. |
| src/SyncTrayzor/Properties/Resources.Designer.cs | Regenerates strongly-typed resource accessors for new strings. |
| src/SyncTrayzor/Pages/Tray/NetworkGraphView.xaml | Updates text color to use themed muted foreground. |
| src/SyncTrayzor/Pages/Tray/FileTransfersTrayView.xaml | Updates tray transfer UI to use themed background/border/muted foreground/hover brushes. |
| src/SyncTrayzor/Pages/Settings/SettingsViewModel.cs | Adds theme options list and binds theme setting item. |
| src/SyncTrayzor/Pages/Settings/SettingsView.xaml | Adds Theme selector UI and bases local styles on global themed styles. |
| src/SyncTrayzor/Pages/NewVersionInstalledToastView.xaml | Updates toast styling to themed brushes. |
| src/SyncTrayzor/Pages/NewVersionAlertToastView.xaml | Updates toast styling to themed brushes. |
| src/SyncTrayzor/Pages/ConflictResolution/MultipleConflictsResolutionView.xaml | Bases local button style on global themed button style. |
| src/SyncTrayzor/Pages/BarAlerts/BarAlertsView.xaml | Updates alert bar separators to themed border brush. |
| src/SyncTrayzor/Bootstrapper.cs | Registers IThemeManager singleton in IoC. |
| src/SyncTrayzor/App.Portable.config | Adds default Theme setting value (System). |
| src/SyncTrayzor/App.Installed.config | Adds default Theme setting value (System). |
| src/SyncTrayzor.Tests/ConfigurationThemeTests.cs | Adds tests verifying default theme and copy-constructor behavior. |
Review details
Files not reviewed (1)
- src/SyncTrayzor/Properties/Resources.Designer.cs: Generated file
- Files reviewed: 21/22 changed files
- Comments generated: 5
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+6
to
+18
| <SolidColorBrush x:Key="AppBackgroundBrush" Color="#FFFFFF"/> | ||
| <SolidColorBrush x:Key="AppSurfaceBrush" Color="#F5F5F5"/> | ||
| <SolidColorBrush x:Key="AppControlBackgroundBrush" Color="#FFFFFF"/> | ||
| <SolidColorBrush x:Key="AppForegroundBrush" Color="#1B1B1B"/> | ||
| <SolidColorBrush x:Key="AppMutedForegroundBrush" Color="#606060"/> | ||
| <SolidColorBrush x:Key="AppBorderBrush" Color="#B8B8B8"/> | ||
| <SolidColorBrush x:Key="AppAccentBrush" Color="#0078D4"/> | ||
| <SolidColorBrush x:Key="AppFocusBorderBrush" Color="#6A6A6A"/> | ||
| <SolidColorBrush x:Key="AppHoverBrush" Color="#E8F2FA"/> | ||
| <SolidColorBrush x:Key="AppPressedBrush" Color="#D4E8F7"/> | ||
| <SolidColorBrush x:Key="AppScrollBarTrackBrush" Color="#E5E5E5"/> | ||
| <SolidColorBrush x:Key="AppScrollBarThumbBrush" Color="#8A8A8A"/> | ||
| <SolidColorBrush x:Key="AppScrollBarThumbHoverBrush" Color="#6F6F6F"/> |
Comment on lines
+31
to
+38
| public ThemeManager() | ||
| { | ||
| EventManager.RegisterClassHandler( | ||
| typeof(Window), | ||
| FrameworkElement.LoadedEvent, | ||
| new RoutedEventHandler(WindowLoaded)); | ||
| SystemEvents.UserPreferenceChanged += UserPreferenceChanged; | ||
| } |
Comment on lines
+124
to
+128
| private void UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) | ||
| { | ||
| if (SelectedTheme == ApplicationTheme.System) | ||
| Apply(ApplicationTheme.System); | ||
| } |
Comment on lines
+108
to
+111
| private static void SetBrush(ResourceDictionary resources, object key, Color color) | ||
| { | ||
| resources[key] = new SolidColorBrush(color); | ||
| } |
Comment on lines
183
to
186
| $"ConflictResolverDeletesToRecycleBin={ConflictResolverDeletesToRecycleBin} PauseDevicesOnMeteredNetworks={PauseDevicesOnMeteredNetworks} " + | ||
| $"HaveDonated={HaveDonated} IconAnimationMode={IconAnimationMode} OpenFolderCommand={OpenFolderCommand} ShowFileInFolderCommand={ShowFileInFolderCommand}" + | ||
| $"LogLevel={LogLevel}" + | ||
| $"LogLevel={LogLevel} Theme={Theme}" + | ||
| $"KeepActivityPopupOpen={KeepActivityPopupOpen}>" + |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Testing
dotnet test src -c Release --no-restore