From 3a31faafebcc5a24e56110ed6497cfce7b2f4716 Mon Sep 17 00:00:00 2001 From: Adrian Georg Herrmann Date: Fri, 27 Jun 2025 21:22:46 +0200 Subject: [PATCH 1/5] Add LaunchPageOption setting and infrastructure Add a LaunchPageOption setting and surrounding enums, getters and setters. --- Screenbox.Core/Enums/SettingsOptions.cs | 12 ++++++++++++ Screenbox.Core/Services/ISettingsService.cs | 1 + Screenbox.Core/Services/SettingsService.cs | 8 ++++++++ Screenbox.Core/ViewModels/SettingsPageViewModel.cs | 8 ++++++++ 4 files changed, 29 insertions(+) diff --git a/Screenbox.Core/Enums/SettingsOptions.cs b/Screenbox.Core/Enums/SettingsOptions.cs index c9f905afd..00263f0bf 100644 --- a/Screenbox.Core/Enums/SettingsOptions.cs +++ b/Screenbox.Core/Enums/SettingsOptions.cs @@ -20,3 +20,15 @@ public enum ThemeOption Light, Dark } + +public enum LaunchPageOption +{ + Home, + Songs, + Albums, + Artists, + VideoFolders, + AllVideos, + Network, + PlayQueue +} diff --git a/Screenbox.Core/Services/ISettingsService.cs b/Screenbox.Core/Services/ISettingsService.cs index cf456da4e..9c93a6d85 100644 --- a/Screenbox.Core/Services/ISettingsService.cs +++ b/Screenbox.Core/Services/ISettingsService.cs @@ -18,6 +18,7 @@ public interface ISettingsService ThemeOption Theme { get; set; } bool EnqueueAllFilesInFolder { get; set; } bool RestorePlaybackPosition { get; set; } + LaunchPageOption LaunchPage { get; set; } bool SearchRemovableStorage { get; set; } int MaxVolume { get; set; } string GlobalArguments { get; set; } diff --git a/Screenbox.Core/Services/SettingsService.cs b/Screenbox.Core/Services/SettingsService.cs index bfa8c45a6..83b7e6254 100644 --- a/Screenbox.Core/Services/SettingsService.cs +++ b/Screenbox.Core/Services/SettingsService.cs @@ -26,6 +26,7 @@ public sealed class SettingsService : ISettingsService private const string GeneralShowRecent = "General/ShowRecent"; private const string GeneralEnqueueAllInFolder = "General/EnqueueAllInFolder"; private const string GeneralRestorePlaybackPosition = "General/RestorePlaybackPosition"; + private const string GeneralLaunchPage = "General/LaunchPage"; private const string AdvancedModeKey = "Advanced/IsEnabled"; private const string AdvancedVideoUpscaleKey = "Advanced/VideoUpscale"; private const string AdvancedMultipleInstancesKey = "Advanced/MultipleInstances"; @@ -108,6 +109,12 @@ public bool RestorePlaybackPosition set => SetValue(GeneralRestorePlaybackPosition, value); } + public LaunchPageOption LaunchPage + { + get => (LaunchPageOption)GetValue(GeneralLaunchPage); + set => SetValue(GeneralLaunchPage, (int)value); + } + public bool PlayerShowControls { get => GetValue(PlayerShowControlsKey); @@ -174,6 +181,7 @@ public SettingsService() SetDefault(LibrariesUseIndexerKey, true); SetDefault(LibrariesSearchRemovableStorageKey, true); SetDefault(GeneralShowRecent, true); + SetDefault(GeneralLaunchPage, (int)LaunchPageOption.Home); SetDefault(PersistentRepeatModeKey, (int)MediaPlaybackAutoRepeatMode.None); SetDefault(AdvancedModeKey, false); SetDefault(AdvancedVideoUpscaleKey, (int)VideoUpscaleOption.Linear); diff --git a/Screenbox.Core/ViewModels/SettingsPageViewModel.cs b/Screenbox.Core/ViewModels/SettingsPageViewModel.cs index 839bda72f..8d99d1178 100644 --- a/Screenbox.Core/ViewModels/SettingsPageViewModel.cs +++ b/Screenbox.Core/ViewModels/SettingsPageViewModel.cs @@ -35,6 +35,7 @@ public sealed partial class SettingsPageViewModel : ObservableRecipient [ObservableProperty] private int _theme; [ObservableProperty] private bool _enqueueAllFilesInFolder; [ObservableProperty] private bool _restorePlaybackPosition; + [ObservableProperty] private int _launchPage; [ObservableProperty] private bool _searchRemovableStorage; [ObservableProperty] private bool _advancedMode; [ObservableProperty] private int _videoUpscaling; @@ -104,6 +105,7 @@ public SettingsPageViewModel(ISettingsService settingsService, ILibraryService l _theme = ((int)_settingsService.Theme + 2) % 3; _enqueueAllFilesInFolder = _settingsService.EnqueueAllFilesInFolder; _restorePlaybackPosition = _settingsService.RestorePlaybackPosition; + _launchPage = (int)_settingsService.LaunchPage; _searchRemovableStorage = _settingsService.SearchRemovableStorage; _advancedMode = _settingsService.AdvancedMode; _useMultipleInstances = _settingsService.UseMultipleInstances; @@ -211,6 +213,12 @@ partial void OnRestorePlaybackPositionChanged(bool value) Messenger.Send(new SettingsChangedMessage(nameof(RestorePlaybackPosition), typeof(SettingsPageViewModel))); } + partial void OnLaunchPageChanged(int value) + { + _settingsService.LaunchPage = (LaunchPageOption)value; + Messenger.Send(new SettingsChangedMessage(nameof(LaunchPage), typeof(SettingsPageViewModel))); + } + async partial void OnSearchRemovableStorageChanged(bool value) { _settingsService.SearchRemovableStorage = value; From 15155dbed8d4f2f58a5d831bdfb1fa6dc9939b21 Mon Sep 17 00:00:00 2001 From: Adrian Georg Herrmann Date: Fri, 27 Jun 2025 21:26:06 +0200 Subject: [PATCH 2/5] Add LaunchPageOption setting to GUI Add an item to the settings GUI page to view and modify the LaunchPageOption setting, plus locale resources (en-US and de-DE). --- Screenbox/Pages/SettingsPage.xaml | 22 ++++++++++++++++++++++ Screenbox/Strings/en-US/Resources.resw | 6 ++++++ 2 files changed, 28 insertions(+) diff --git a/Screenbox/Pages/SettingsPage.xaml b/Screenbox/Pages/SettingsPage.xaml index 2648555be..4b151d2da 100644 --- a/Screenbox/Pages/SettingsPage.xaml +++ b/Screenbox/Pages/SettingsPage.xaml @@ -355,6 +355,28 @@ + + + + + + + + Home + Songs + Albums + Artists + VideoFolders + AllVideos + Network + PlayQueue + + + diff --git a/Screenbox/Strings/en-US/Resources.resw b/Screenbox/Strings/en-US/Resources.resw index 38e172989..742392483 100644 --- a/Screenbox/Strings/en-US/Resources.resw +++ b/Screenbox/Strings/en-US/Resources.resw @@ -947,4 +947,10 @@ Use system language + + Select what to show at launch + + + This page will be shown when the app is launched + \ No newline at end of file From 4123b5e7749858459641387ae0d1360d785db91d Mon Sep 17 00:00:00 2001 From: Adrian Georg Herrmann Date: Fri, 27 Jun 2025 21:31:04 +0200 Subject: [PATCH 3/5] Add EnumExtensions.cs to Screenbox\Helpers Add a EnumExtensions.cs file to Screenbox\Helpers, which includes two helper methods for the LaunchPageOption enum type: - GetNavPageFirstLevel() returns the name of the first navigation level (left NavigationView) for each LaunchPageOption setting. - GetNavPageSecondLevel() returns the name of the second navigation level (top NavigationView) for each LaunchPageOption setting. --- Screenbox/Helpers/EnumExtensions.cs | 36 +++++++++++++++++++++++++++++ Screenbox/Screenbox.csproj | 1 + 2 files changed, 37 insertions(+) create mode 100644 Screenbox/Helpers/EnumExtensions.cs diff --git a/Screenbox/Helpers/EnumExtensions.cs b/Screenbox/Helpers/EnumExtensions.cs new file mode 100644 index 000000000..e895979c8 --- /dev/null +++ b/Screenbox/Helpers/EnumExtensions.cs @@ -0,0 +1,36 @@ +using Screenbox.Core.Enums; +using Screenbox.Pages; +using System; + +namespace Screenbox.Helpers; +public static class EnumExtensions +{ + public static string GetNavPageFirstLevel(this LaunchPageOption launchPageOption) + { + return launchPageOption switch + { + LaunchPageOption.Home => "home", + LaunchPageOption.Songs => "music", + LaunchPageOption.Albums => "music", + LaunchPageOption.Artists => "music", + LaunchPageOption.VideoFolders => "videos", + LaunchPageOption.AllVideos => "videos", + LaunchPageOption.Network => "network", + LaunchPageOption.PlayQueue => "queue", + _ => throw new ArgumentOutOfRangeException(nameof(launchPageOption), launchPageOption, null), + }; + } + + public static string GetNavPageSecondLevel(this LaunchPageOption launchPageOption) + { + return launchPageOption switch + { + LaunchPageOption.Songs => "songs", + LaunchPageOption.Albums => "albums", + LaunchPageOption.Artists => "artists", + LaunchPageOption.VideoFolders => "folders", + LaunchPageOption.AllVideos => "all", + _ => throw new ArgumentOutOfRangeException(nameof(launchPageOption), launchPageOption, null), + }; + } +} diff --git a/Screenbox/Screenbox.csproj b/Screenbox/Screenbox.csproj index 164a38e04..b98743866 100644 --- a/Screenbox/Screenbox.csproj +++ b/Screenbox/Screenbox.csproj @@ -239,6 +239,7 @@ + From 95ab5a7887133b781a74eb603aaedd06abd5a1e7 Mon Sep 17 00:00:00 2001 From: Adrian Georg Herrmann Date: Fri, 27 Jun 2025 21:32:07 +0200 Subject: [PATCH 4/5] Navigate to first (left) NavigationView level Navigate to the first (left) NavigationView level on app launch, as indicated by the LaunchPageOption setting. --- Screenbox/Pages/MainPage.xaml.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Screenbox/Pages/MainPage.xaml.cs b/Screenbox/Pages/MainPage.xaml.cs index a8dbae963..95b43ae54 100644 --- a/Screenbox/Pages/MainPage.xaml.cs +++ b/Screenbox/Pages/MainPage.xaml.cs @@ -7,7 +7,9 @@ using System.Numerics; using CommunityToolkit.Mvvm.DependencyInjection; using Screenbox.Core; +using Screenbox.Core.Services; using Screenbox.Core.ViewModels; +using Screenbox.Helpers; using Sentry; using Windows.ApplicationModel.Core; using Windows.ApplicationModel.DataTransfer; @@ -36,6 +38,8 @@ public sealed partial class MainPage : Page, IContentFrame private readonly Dictionary _pages; + private ISettingsService Settings => Ioc.Default.GetRequiredService(); + public MainPage() { InitializeComponent(); @@ -145,7 +149,12 @@ private void MainPage_Loaded(object sender, RoutedEventArgs e) if (!ViewModel.PlayerVisible) { SetTitleBar(); - NavView.SelectedItem = NavView.MenuItems[0]; + var launchPage = Settings.LaunchPage; + var launchPageTag = launchPage.GetNavPageFirstLevel(); + var navItem = NavView.MenuItems + .OfType() + .FirstOrDefault(item => item.Tag?.ToString() == launchPageTag); + NavView.SelectedItem = navItem ?? NavView.MenuItems[0]; _ = ViewModel.FetchLibraries(); } } From a09a2d8f3e98fa44d01d95a5d8ffe8563cfe635e Mon Sep 17 00:00:00 2001 From: Adrian Georg Herrmann Date: Fri, 27 Jun 2025 21:33:06 +0200 Subject: [PATCH 5/5] Navigate to second (top) NavigationView level Navigate to the second (top) NavigationView level on app launch, as indicated by the LaunchPageOption setting, and applicable for the music and video library pages. --- Screenbox/Pages/MusicPage.xaml.cs | 26 ++++++++++++++++++++++---- Screenbox/Pages/VideosPage.xaml.cs | 26 ++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Screenbox/Pages/MusicPage.xaml.cs b/Screenbox/Pages/MusicPage.xaml.cs index c33292a92..c8b6a2bee 100644 --- a/Screenbox/Pages/MusicPage.xaml.cs +++ b/Screenbox/Pages/MusicPage.xaml.cs @@ -1,16 +1,19 @@ #nullable enable -using CommunityToolkit.Mvvm.DependencyInjection; -using Screenbox.Core; -using Screenbox.Core.ViewModels; using System; using System.Collections.Generic; using System.Linq; +using CommunityToolkit.Mvvm.DependencyInjection; +using Screenbox.Core; +using Screenbox.Core.Services; +using Screenbox.Core.ViewModels; +using Screenbox.Helpers; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media.Animation; using Windows.UI.Xaml.Navigation; using NavigationView = Microsoft.UI.Xaml.Controls.NavigationView; using NavigationViewSelectionChangedEventArgs = Microsoft.UI.Xaml.Controls.NavigationViewSelectionChangedEventArgs; +using muxc = Microsoft.UI.Xaml.Controls; // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 @@ -31,6 +34,8 @@ public sealed partial class MusicPage : Page, IContentFrame private readonly Dictionary _pages; + private ISettingsService Settings => Ioc.Default.GetRequiredService(); + public MusicPage() { this.InitializeComponent(); @@ -55,7 +60,20 @@ protected override void OnNavigatedTo(NavigationEventArgs e) } else { - LibraryNavView.SelectedItem = LibraryNavView.MenuItems[0]; + muxc.NavigationViewItem? libraryNavItem = null; + var launchPage = Settings.LaunchPage; + if (launchPage.GetNavPageFirstLevel() != "music") + { + libraryNavItem = (muxc.NavigationViewItem?)LibraryNavView.MenuItems[0]; + } + else + { + var launchPageTag = launchPage.GetNavPageSecondLevel(); + libraryNavItem = LibraryNavView.MenuItems + .OfType() + .FirstOrDefault(item => item.Tag?.ToString() == launchPageTag); + } + LibraryNavView.SelectedItem = libraryNavItem ?? LibraryNavView.MenuItems[0]; } ViewModel.UpdateSongs(); diff --git a/Screenbox/Pages/VideosPage.xaml.cs b/Screenbox/Pages/VideosPage.xaml.cs index 960cafa26..d22afa5e4 100644 --- a/Screenbox/Pages/VideosPage.xaml.cs +++ b/Screenbox/Pages/VideosPage.xaml.cs @@ -1,16 +1,19 @@ #nullable enable -using CommunityToolkit.Mvvm.DependencyInjection; -using Screenbox.Core; -using Screenbox.Core.ViewModels; using System; using System.Collections.Generic; using System.Linq; +using CommunityToolkit.Mvvm.DependencyInjection; +using Screenbox.Core; +using Screenbox.Core.Services; +using Screenbox.Core.ViewModels; +using Screenbox.Helpers; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media.Animation; using Windows.UI.Xaml.Navigation; using NavigationView = Microsoft.UI.Xaml.Controls.NavigationView; using NavigationViewSelectionChangedEventArgs = Microsoft.UI.Xaml.Controls.NavigationViewSelectionChangedEventArgs; +using muxc = Microsoft.UI.Xaml.Controls; // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 @@ -33,6 +36,8 @@ public sealed partial class VideosPage : Page, IContentFrame private readonly Dictionary _pages; + private ISettingsService Settings => Ioc.Default.GetRequiredService(); + public VideosPage() { this.InitializeComponent(); @@ -56,7 +61,20 @@ protected override void OnNavigatedTo(NavigationEventArgs e) } else { - LibraryNavView.SelectedItem = LibraryNavView.MenuItems[0]; + muxc.NavigationViewItem? libraryNavItem = null; + var launchPage = Settings.LaunchPage; + if (launchPage.GetNavPageFirstLevel() != "videos") + { + libraryNavItem = (muxc.NavigationViewItem?)LibraryNavView.MenuItems[0]; + } + else + { + var launchPageTag = launchPage.GetNavPageSecondLevel(); + libraryNavItem = LibraryNavView.MenuItems + .OfType() + .FirstOrDefault(item => item.Tag?.ToString() == launchPageTag); + } + LibraryNavView.SelectedItem = libraryNavItem ?? LibraryNavView.MenuItems[0]; } ViewModel.UpdateVideos();