diff --git a/Files/App.xaml.cs b/Files/App.xaml.cs index 33c214c5268a..9921e9f51c38 100644 --- a/Files/App.xaml.cs +++ b/Files/App.xaml.cs @@ -4,11 +4,16 @@ using Files.Filesystem; using Files.Filesystem.FilesystemHistory; using Files.Helpers; -using Files.Models.Settings; -using Files.SettingsInterfaces; +using Files.Services; +using Files.Services.Implementation; using Files.UserControls.MultitaskingControl; using Files.ViewModels; using Files.Views; +using Microsoft.AppCenter; +using Microsoft.AppCenter.Analytics; +using Microsoft.AppCenter.Crashes; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using Microsoft.Toolkit.Uwp.Helpers; using Microsoft.Toolkit.Uwp.Notifications; @@ -41,7 +46,6 @@ sealed partial class App : Application public static SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1, 1); public static StorageHistoryWrapper HistoryWrapper = new StorageHistoryWrapper(); - public static IBundlesSettings BundlesSettings = new BundlesSettingsModel(); public static SettingsViewModel AppSettings { get; private set; } public static MainViewModel MainViewModel { get; private set; } public static JumpListManager JumpList { get; private set; } @@ -61,6 +65,10 @@ sealed partial class App : Application public static OngoingTasksViewModel OngoingTasksViewModel { get; } = new OngoingTasksViewModel(); public static SecondaryTileHelper SecondaryTileHelper { get; private set; } = new SecondaryTileHelper(); + public static string AppVersion = $"{Package.Current.Id.Version.Major}.{Package.Current.Id.Version.Minor}.{Package.Current.Id.Version.Build}.{Package.Current.Id.Version.Revision}"; + + public IServiceProvider Services { get; private set; } + public App() { // Initialize logger @@ -71,12 +79,52 @@ public App() InitializeComponent(); Suspending += OnSuspending; LeavingBackground += OnLeavingBackground; + AppServiceConnectionHelper.Register(); + + this.Services = ConfigureServices(); + Ioc.Default.ConfigureServices(Services); + } + + private IServiceProvider ConfigureServices() + { + ServiceCollection services = new ServiceCollection(); + + services + // TODO: Loggers: + + // Settings: + // Base IUserSettingsService as parent settings store (to get ISettingsSharingContext from) + .AddSingleton() + // Children settings (from IUserSettingsService) + .AddSingleton((sp) => new FilesAndFoldersSettingsService(sp.GetService().GetSharingContext())) + .AddSingleton((sp) => new StartupSettingsService(sp.GetService().GetSharingContext())) + .AddSingleton((sp) => new MultitaskingSettingsService(sp.GetService().GetSharingContext())) + .AddSingleton((sp) => new WidgetsSettingsService(sp.GetService().GetSharingContext())) + .AddSingleton((sp) => new SidebarSettingsService(sp.GetService().GetSharingContext())) + .AddSingleton((sp) => new PreferencesSettingsService(sp.GetService().GetSharingContext())) + .AddSingleton((sp) => new AppearanceSettingsService(sp.GetService().GetSharingContext())) + .AddSingleton((sp) => new PreviewPaneSettingsService(sp.GetService().GetSharingContext())) + .AddSingleton((sp) => new LayoutSettingsService(sp.GetService().GetSharingContext())) + // Settings not related to IUserSettingsService: + .AddSingleton() + .AddSingleton() + + // TODO: Dialogs: + + // TODO: FileSystem operations: + // (IFilesystemHelpersService, IFilesystemOperationsService) + + ; // End of service configuration + + + return services.BuildServiceProvider(); } private static async Task EnsureSettingsAndConfigurationAreBootstrapped() { AppSettings ??= new SettingsViewModel(); + RegistryToJsonSettingsMerger.MergeSettings(); ExternalResourcesHelper ??= new ExternalResourcesHelper(); await ExternalResourcesHelper.LoadSelectedTheme(); @@ -92,6 +140,24 @@ private static async Task EnsureSettingsAndConfigurationAreBootstrapped() TerminalController ??= new TerminalController(); } + private static async void StartAppCenter() + { + try + { + if (!AppCenter.Configured) + { + var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(@"ms-appx:///Resources/AppCenterKey.txt")); + var lines = await FileIO.ReadTextAsync(file); + var obj = Newtonsoft.Json.Linq.JObject.Parse(lines); + AppCenter.Start((string)obj.SelectToken("key"), typeof(Analytics), typeof(Crashes)); + } + } + catch (Exception ex) + { + Logger.Warn(ex, "AppCenter could not be started."); + } + } + public static async Task LoadOtherStuffAsync() { // Start off a list of tasks we need to run before we can continue startup @@ -437,9 +503,16 @@ await Common.Extensions.IgnoreExceptions(async () => public static void SaveSessionTabs() // Enumerates through all tabs and gets the Path property and saves it to AppSettings.LastSessionPages { - if (AppSettings != null) + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + IBundlesSettingsService bundlesSettingsService = Ioc.Default.GetService(); + + if (bundlesSettingsService != null) + { + bundlesSettingsService.FlushSettings(); + } + if (userSettingsService?.StartupSettingsService != null) { - AppSettings.LastSessionPages = MainPageViewModel.AppInstances.DefaultIfEmpty().Select(tab => + userSettingsService.StartupSettingsService.LastSessionTabList = MainPageViewModel.AppInstances.DefaultIfEmpty().Select(tab => { if (tab != null && tab.TabItemArguments != null) { @@ -450,7 +523,7 @@ public static void SaveSessionTabs() // Enumerates through all tabs and gets the var defaultArg = new TabItemArguments() { InitialPageType = typeof(PaneHolderPage), NavigationArg = "NewTab".GetLocalized() }; return defaultArg.Serialize(); } - }).ToArray(); + }).ToList(); } } diff --git a/Files/BaseLayout.cs b/Files/BaseLayout.cs index 983fe3d71bd9..eecfa811c4f8 100644 --- a/Files/BaseLayout.cs +++ b/Files/BaseLayout.cs @@ -6,10 +6,12 @@ using Files.Helpers; using Files.Helpers.ContextFlyouts; using Files.Interacts; +using Files.Services; using Files.UserControls; using Files.ViewModels; using Files.ViewModels.Previews; using Files.Views; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using Microsoft.Toolkit.Uwp.UI; using System; @@ -42,6 +44,10 @@ public abstract class BaseLayout : Page, IBaseLayout, INotifyPropertyChanged { private readonly DispatcherTimer jumpTimer; + protected IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + + protected IFileTagsSettingsService FileTagsSettingsService { get; } = Ioc.Default.GetService(); + protected Task Connection => AppServiceConnectionHelper.Instance; public SelectedItemsPropertiesViewModel SelectedItemsPropertiesViewModel { get; } @@ -416,7 +422,7 @@ protected override async void OnNavigatedTo(NavigationEventArgs eventArgs) // pathRoot will be empty on recycle bin path var workingDir = ParentShellPageInstance.FilesystemViewModel.WorkingDirectory ?? string.Empty; string pathRoot = GetPathRoot(workingDir); - if (string.IsNullOrEmpty(pathRoot) || workingDir.StartsWith(AppSettings.RecycleBinPath)) // Can't go up from recycle bin + if (string.IsNullOrEmpty(pathRoot) || workingDir.StartsWith(CommonPaths.RecycleBinPath)) // Can't go up from recycle bin { ParentShellPageInstance.NavToolbarViewModel.CanNavigateToParent = false; } @@ -425,7 +431,7 @@ protected override async void OnNavigatedTo(NavigationEventArgs eventArgs) ParentShellPageInstance.NavToolbarViewModel.CanNavigateToParent = true; } - ParentShellPageInstance.InstanceViewModel.IsPageTypeRecycleBin = workingDir.StartsWith(App.AppSettings.RecycleBinPath); + ParentShellPageInstance.InstanceViewModel.IsPageTypeRecycleBin = workingDir.StartsWith(CommonPaths.RecycleBinPath); ParentShellPageInstance.InstanceViewModel.IsPageTypeMtpDevice = workingDir.StartsWith("\\\\?\\"); ParentShellPageInstance.InstanceViewModel.IsPageTypeFtp = FtpHelpers.IsFtpPath(workingDir); ParentShellPageInstance.InstanceViewModel.IsPageTypeZipFolder = ZipStorageFolder.IsZipPath(workingDir); @@ -619,7 +625,7 @@ private async Task LoadMenuItemsAsync() secondaryElements.OfType().ForEach(i => i.MinWidth = 250); // Set menu min width secondaryElements.ForEach(i => ItemContextMenuFlyout.SecondaryCommands.Add(i)); - if (AppSettings.AreFileTagsEnabled && !InstanceViewModel.IsPageTypeSearchResults && !InstanceViewModel.IsPageTypeRecycleBin && !InstanceViewModel.IsPageTypeFtp && !InstanceViewModel.IsPageTypeZipFolder) + if (UserSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled && !InstanceViewModel.IsPageTypeSearchResults && !InstanceViewModel.IsPageTypeRecycleBin && !InstanceViewModel.IsPageTypeFtp && !InstanceViewModel.IsPageTypeZipFolder) { AddFileTagsItemToMenu(ItemContextMenuFlyout); } @@ -640,7 +646,7 @@ private void AddFileTagsItemToMenu(Microsoft.UI.Xaml.Controls.CommandBarFlyout c { var fileTagMenuFlyout = new MenuFlyoutItemFileTag() { - ItemsSource = AppSettings.FileTagsSettings.FileTagList, + ItemsSource = FileTagsSettingsService.FileTagList, SelectedItems = SelectedItems }; var overflowSeparator = contextMenu.SecondaryCommands.FirstOrDefault(x => x is FrameworkElement fe && fe.Tag as string == "OverflowSeparator") as AppBarSeparator; @@ -656,7 +662,7 @@ private void AddFileTagsItemToMenu(Microsoft.UI.Xaml.Controls.CommandBarFlyout c private void AddShellItemsToMenu(List shellMenuItems, Microsoft.UI.Xaml.Controls.CommandBarFlyout contextMenuFlyout, bool shiftPressed) { var openWithSubItems = ItemModelListToContextFlyoutHelper.GetMenuFlyoutItemsFromModel(ShellContextmenuHelper.GetOpenWithItems(shellMenuItems)); - var mainShellMenuItems = shellMenuItems.RemoveFrom(!App.AppSettings.MoveOverflowMenuItemsToSubMenu ? int.MaxValue : shiftPressed ? 6 : 4); + var mainShellMenuItems = shellMenuItems.RemoveFrom(!UserSettingsService.AppearanceSettingsService.MoveOverflowMenuItemsToSubMenu ? int.MaxValue : shiftPressed ? 6 : 4); var overflowShellMenuItems = shellMenuItems.Except(mainShellMenuItems).ToList(); var overflowItems = ItemModelListToContextFlyoutHelper.GetMenuFlyoutItemsFromModel(overflowShellMenuItems); diff --git a/Files/Constants.cs b/Files/Constants.cs index 0933eb8924be..70a0b297453f 100644 --- a/Files/Constants.cs +++ b/Files/Constants.cs @@ -15,6 +15,13 @@ public static class AdaptiveLayout public const float ExtraSmallThreshold = 15.0f; } + public static class CommonPaths + { + public const string RecycleBinPath = @"Shell:RecycleBinFolder"; + + public const string NetworkFolderPath = @"Shell:NetworkPlacesFolder"; + } + public static class ImageRes { // See imageres.dll for more icon indexes to add @@ -106,6 +113,8 @@ public static class LocalSettings public const string BundlesSettingsFileName = "bundles.json"; + public const string UserSettingsFileName = "user_settings.json"; + public const string FileTagSettingsFileName = "filetags.json"; } diff --git a/Files/DataModels/SidebarPinnedModel.cs b/Files/DataModels/SidebarPinnedModel.cs index bd8c41660823..bf07884fcd1e 100644 --- a/Files/DataModels/SidebarPinnedModel.cs +++ b/Files/DataModels/SidebarPinnedModel.cs @@ -3,8 +3,10 @@ using Files.DataModels.NavigationControlItems; using Files.Filesystem; using Files.Helpers; +using Files.Services; using Files.UserControls; using Files.ViewModels; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using Newtonsoft.Json; using System; @@ -22,13 +24,12 @@ namespace Files.DataModels { public class SidebarPinnedModel { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + private SidebarPinnedController controller; private LocationItem favoriteSection, homeSection; - [JsonIgnore] - public SettingsViewModel AppSettings => App.AppSettings; - [JsonIgnore] public MainViewModel MainViewModel => App.MainViewModel; @@ -51,8 +52,8 @@ public void AddDefaultItems() { var udp = UserDataPaths.GetDefault(); - FavoriteItems.Add(AppSettings.DesktopPath); - FavoriteItems.Add(AppSettings.DownloadsPath); + FavoriteItems.Add(CommonPaths.DesktopPath); + FavoriteItems.Add(CommonPaths.DownloadsPath); FavoriteItems.Add(udp.Documents); } @@ -61,7 +62,7 @@ private void RemoveFavoritesSideBarSection() try { var item = (from n in SidebarControl.SideBarItems where n.Text.Equals("SidebarFavorites".GetLocalized()) select n).FirstOrDefault(); - if (!App.AppSettings.ShowFavoritesSection && item != null) + if (!UserSettingsService.SidebarSettingsService.ShowFavoritesSection && item != null) { SidebarControl.SideBarItems.Remove(item); } @@ -72,7 +73,7 @@ private void RemoveFavoritesSideBarSection() public async void UpdateFavoritesSectionVisibility() { - if (App.AppSettings.ShowFavoritesSection) + if (UserSettingsService.SidebarSettingsService.ShowFavoritesSection) { await AddAllItemsToSidebar(); } @@ -113,11 +114,11 @@ public async Task ShowHideRecycleBinItemAsync(bool show) Text = ApplicationData.Current.LocalSettings.Values.Get("RecycleBin_Title", "Recycle Bin"), IsDefaultLocation = true, Icon = await CoreApplication.MainView.DispatcherQueue.EnqueueAsync(() => UIHelpers.GetIconResource(Constants.ImageRes.RecycleBin)), - Path = App.AppSettings.RecycleBinPath + Path = CommonPaths.RecycleBinPath }; // Add recycle bin to sidebar, title is read from LocalSettings (provided by the fulltrust process) // TODO: the very first time the app is launched localized name not available - if (!favoriteSection.ChildItems.Any(x => x.Path == App.AppSettings.RecycleBinPath)) + if (!favoriteSection.ChildItems.Any(x => x.Path == CommonPaths.RecycleBinPath)) { await CoreApplication.MainView.DispatcherQueue.EnqueueAsync(() => favoriteSection.ChildItems.Add(recycleBinItem)); } @@ -126,7 +127,7 @@ public async Task ShowHideRecycleBinItemAsync(bool show) { foreach (INavigationControlItem item in favoriteSection.ChildItems.ToList()) { - if (item is LocationItem && item.Path == App.AppSettings.RecycleBinPath) + if (item is LocationItem && item.Path == CommonPaths.RecycleBinPath) { await CoreApplication.MainView.DispatcherQueue.EnqueueAsync(() => favoriteSection.ChildItems.Remove(item)); } @@ -251,7 +252,7 @@ public async Task AddItemToSidebarAsync(string path) var res = await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderFromPathAsync(path, item)); if (res || (FilesystemResult)FolderHelpers.CheckFolderAccessWithWin32(path)) { - var lastItem = favoriteSection.ChildItems.LastOrDefault(x => x.ItemType == NavigationControlItemType.Location && !x.Path.Equals(App.AppSettings.RecycleBinPath)); + var lastItem = favoriteSection.ChildItems.LastOrDefault(x => x.ItemType == NavigationControlItemType.Location && !x.Path.Equals(CommonPaths.RecycleBinPath)); int insertIndex = lastItem != null ? favoriteSection.ChildItems.IndexOf(lastItem) + 1 : 0; var locationItem = new LocationItem { @@ -299,7 +300,7 @@ public async Task AddItemToSidebarAsync(string path) /// The section. private void AddItemToSidebarAsync(LocationItem section) { - var lastItem = favoriteSection.ChildItems.LastOrDefault(x => x.ItemType == NavigationControlItemType.Location && !x.Path.Equals(App.AppSettings.RecycleBinPath)); + var lastItem = favoriteSection.ChildItems.LastOrDefault(x => x.ItemType == NavigationControlItemType.Location && !x.Path.Equals(CommonPaths.RecycleBinPath)); int insertIndex = lastItem != null ? favoriteSection.ChildItems.IndexOf(lastItem) + 1 : 0; if (!favoriteSection.ChildItems.Contains(section)) @@ -313,7 +314,7 @@ private void AddItemToSidebarAsync(LocationItem section) /// public async Task AddAllItemsToSidebar() { - if (!App.AppSettings.ShowFavoritesSection) + if (!UserSettingsService.SidebarSettingsService.ShowFavoritesSection) { return; } @@ -365,7 +366,7 @@ public async Task AddAllItemsToSidebar() await AddItemToSidebarAsync(path); } - await ShowHideRecycleBinItemAsync(App.AppSettings.PinRecycleBinToSideBar); + await ShowHideRecycleBinItemAsync(UserSettingsService.SidebarSettingsService.PinRecycleBinToSidebar); } /// diff --git a/Files/Enums/SortOption.cs b/Files/Enums/SortOptions.cs similarity index 71% rename from Files/Enums/SortOption.cs rename to Files/Enums/SortOptions.cs index 80ba96ffc978..e820facc4e5a 100644 --- a/Files/Enums/SortOption.cs +++ b/Files/Enums/SortOptions.cs @@ -26,4 +26,10 @@ public enum GroupOption : byte OriginalFolder, DateDeleted } + + public enum SortDirection : byte // We cannot use Microsoft.Toolkit.Uwp.UI.SortDirection since it's UI-tied and we need Model-tied + { + Ascending = 0, + Descending = 1 + } } \ No newline at end of file diff --git a/Files/EventArguments/BaseJsonSettingsModelEventArgs.cs b/Files/EventArguments/BaseJsonSettingsModelEventArgs.cs new file mode 100644 index 000000000000..b8fd34b7cc92 --- /dev/null +++ b/Files/EventArguments/BaseJsonSettingsModelEventArgs.cs @@ -0,0 +1,17 @@ +using System; + +namespace Files.EventArguments +{ + public sealed class SettingChangedEventArgs : EventArgs + { + public readonly string settingName; + + public readonly object newValue; + + public SettingChangedEventArgs(string settingName, object newValue) + { + this.settingName = settingName; + this.newValue = newValue; + } + } +} diff --git a/Files/Files.csproj b/Files/Files.csproj index 64b0a5482d76..63a5bd59ce98 100644 --- a/Files/Files.csproj +++ b/Files/Files.csproj @@ -162,6 +162,7 @@ + @@ -186,6 +187,8 @@ + + @@ -232,6 +235,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ColoredIcon.xaml @@ -340,7 +375,7 @@ - + @@ -366,8 +401,6 @@ - - PreviewPane.xaml @@ -458,7 +491,7 @@ - + @@ -1411,6 +1444,9 @@ 5.0.10 + + 5.0.2 + 6.2.12 diff --git a/Files/Filesystem/CloudDrivesManager.cs b/Files/Filesystem/CloudDrivesManager.cs index 53c28167f5d0..8d8664d36400 100644 --- a/Files/Filesystem/CloudDrivesManager.cs +++ b/Files/Filesystem/CloudDrivesManager.cs @@ -2,7 +2,10 @@ using Files.DataModels.NavigationControlItems; using Files.Filesystem.Cloud; using Files.Helpers; +using Files.Services; using Files.UserControls; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Generic; @@ -16,6 +19,8 @@ namespace Files.Filesystem { public class CloudDrivesManager { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + private static readonly Logger Logger = App.Logger; private readonly List drivesList = new List(); @@ -30,13 +35,9 @@ public IReadOnlyList Drives } } - public CloudDrivesManager() - { - } - public async Task EnumerateDrivesAsync() { - if (!App.AppSettings.ShowCloudDrivesSection) + if (!UserSettingsService.SidebarSettingsService.ShowCloudDrivesSection) { return; } @@ -105,7 +106,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio try { var section = SidebarControl.SideBarItems.FirstOrDefault(x => x.Text == "SidebarCloudDrives".GetLocalized()) as LocationItem; - if (App.AppSettings.ShowCloudDrivesSection && section == null && Drives.Any()) + if (UserSettingsService.SidebarSettingsService.ShowCloudDrivesSection && section == null && Drives.Any()) { section = new LocationItem() { @@ -146,7 +147,7 @@ private void RemoveCloudDrivesSideBarSection() try { var item = (from n in SidebarControl.SideBarItems where n.Text.Equals("SidebarCloudDrives".GetLocalized()) select n).FirstOrDefault(); - if (!App.AppSettings.ShowCloudDrivesSection && item != null) + if (!UserSettingsService.SidebarSettingsService.ShowCloudDrivesSection && item != null) { SidebarControl.SideBarItems.Remove(item); } @@ -157,7 +158,7 @@ private void RemoveCloudDrivesSideBarSection() public async void UpdateCloudDrivesSectionVisibility() { - if (App.AppSettings.ShowCloudDrivesSection) + if (UserSettingsService.SidebarSettingsService.ShowCloudDrivesSection) { await EnumerateDrivesAsync(); } diff --git a/Files/Filesystem/Drives.cs b/Files/Filesystem/Drives.cs index 53ddb00c75c2..f78bf3d72345 100644 --- a/Files/Filesystem/Drives.cs +++ b/Files/Filesystem/Drives.cs @@ -3,9 +3,11 @@ using Files.DataModels.NavigationControlItems; using Files.Enums; using Files.Helpers; +using Files.Services; using Files.UserControls; using Files.UserControls.Widgets; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Generic; @@ -25,6 +27,8 @@ namespace Files.Filesystem { public class DrivesManager : ObservableObject { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + private static readonly Logger Logger = App.Logger; private readonly List drivesList = new List(); @@ -130,7 +134,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio try { var section = SidebarControl.SideBarItems.FirstOrDefault(x => x.Text == "SidebarDrives".GetLocalized()) as LocationItem; - if (App.AppSettings.ShowDrivesSection && section == null) + if (UserSettingsService.SidebarSettingsService.ShowDrivesSection && section == null) { section = new LocationItem() { @@ -313,7 +317,7 @@ private void RemoveDrivesSideBarSection() try { var item = (from n in SidebarControl.SideBarItems where n.Text.Equals("SidebarDrives".GetLocalized()) select n).FirstOrDefault(); - if (!App.AppSettings.ShowDrivesSection && item != null) + if (!UserSettingsService.SidebarSettingsService.ShowDrivesSection && item != null) { SidebarControl.SideBarItems.Remove(item); } @@ -324,7 +328,7 @@ private void RemoveDrivesSideBarSection() public async void UpdateDrivesSectionVisibility() { - if (App.AppSettings.ShowDrivesSection) + if (UserSettingsService.SidebarSettingsService.ShowDrivesSection) { await EnumerateDrivesAsync(); } diff --git a/Files/Filesystem/FileTagsHelper.cs b/Files/Filesystem/FileTagsHelper.cs index 9b0269d1b7f2..d0974f1edfff 100644 --- a/Files/Filesystem/FileTagsHelper.cs +++ b/Files/Filesystem/FileTagsHelper.cs @@ -1,7 +1,7 @@ using Common; using Files.Filesystem.StorageItems; using Files.Helpers; -using Files.Models.Settings; +using Files.Models.JsonSettings; using Microsoft.Toolkit.Uwp; using Microsoft.Toolkit.Uwp.Helpers; using Newtonsoft.Json; @@ -69,7 +69,7 @@ private FileTagsHelper() } } - public class FileTag + public class FileTag // TODO: Change name to FileTagModel { public string TagName { get; set; } public string Uid { get; set; } @@ -95,42 +95,4 @@ public FileTag(string tagName, string colorString, string uid) Uid = uid; } } - - public class FileTagsSettings : BaseJsonSettingsModel - { - public FileTagsSettings() - : base(System.IO.Path.Combine(ApplicationData.Current.LocalFolder.Path, Constants.LocalSettings.SettingsFolderName, Constants.LocalSettings.FileTagSettingsFileName), - isCachingEnabled: true) - { - } - - public IList FileTagList - { - get => Get>(() => new List() - { - new FileTag("Blue", "#0072BD"), - new FileTag("Orange", "#D95319"), - new FileTag("Yellow", "#EDB120"), - new FileTag("Green", "#77AC30"), - new FileTag("Azure", "#4DBEEE") - }); - set => Set(value); - } - - public FileTag GetTagByID(string uid) - { - var tag = FileTagList.SingleOrDefault(x => x.Uid == uid); - if (!string.IsNullOrEmpty(uid) && tag == null) - { - tag = new FileTag("FileTagUnknown".GetLocalized(), "#9ea3a1", uid); - FileTagList = FileTagList.Append(tag).ToList(); - } - return tag; - } - - public IEnumerable GetTagsByName(string tagName) - { - return FileTagList.Where(x => x.TagName.Equals(tagName, StringComparison.OrdinalIgnoreCase)); - } - } } \ No newline at end of file diff --git a/Files/Filesystem/FilesystemOperations/FilesystemOperations.cs b/Files/Filesystem/FilesystemOperations/FilesystemOperations.cs index acdc0d2f45cc..2f5ba4a752d0 100644 --- a/Files/Filesystem/FilesystemOperations/FilesystemOperations.cs +++ b/Files/Filesystem/FilesystemOperations/FilesystemOperations.cs @@ -184,7 +184,7 @@ public async Task CopyAsync(IStorageItemWithPath source, IProgress errorCode, CancellationToken cancellationToken) { - if (destination.StartsWith(App.AppSettings.RecycleBinPath)) + if (destination.StartsWith(CommonPaths.RecycleBinPath)) { errorCode?.Report(FileSystemStatusCode.Unauthorized); progress?.Report(100.0f); @@ -400,7 +400,7 @@ public async Task MoveAsync(IStorageItemWithPath source, return await CopyAsync(source, destination, collision, progress, errorCode, cancellationToken); } - if (destination.StartsWith(App.AppSettings.RecycleBinPath)) + if (destination.StartsWith(CommonPaths.RecycleBinPath)) { errorCode?.Report(FileSystemStatusCode.Unauthorized); progress?.Report(100.0f); diff --git a/Files/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs b/Files/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs index da686b2240ff..23057d108b86 100644 --- a/Files/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs +++ b/Files/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs @@ -6,8 +6,10 @@ using Files.Filesystem.FilesystemHistory; using Files.Helpers; using Files.Interacts; +using Files.Services; using Files.ViewModels; using Files.ViewModels.Dialogs; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Generic; @@ -61,6 +63,12 @@ public class FilesystemHelpers : IFilesystemHelpers #endregion Private Members + #region Properties + + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + + #endregion + #region Constructor public FilesystemHelpers(IShellPage associatedInstance, CancellationToken cancellationToken) @@ -107,7 +115,7 @@ public async Task DeleteItemsAsync(IEnumerable item.Path).Any(path => recycleBinHelpers.IsPathUnderRecycleBin(path)); var canBeSentToBin = !deleteFromRecycleBin && await recycleBinHelpers.HasRecycleBin(source.FirstOrDefault()?.Path); - if (App.AppSettings.ShowConfirmDeleteDialog && showDialog) // Check if the setting to show a confirmation dialog is on + if (UserSettingsService.PreferencesSettingsService.ShowConfirmDeleteDialog && showDialog) // Check if the setting to show a confirmation dialog is on { List incomingItems = new List(); @@ -292,7 +300,7 @@ public async Task DeleteItemAsync(IStorageItemWithPath source, boo banner.ErrorCode.ProgressChanged += (s, e) => returnStatus = e.ToStatus(); - if (App.AppSettings.ShowConfirmDeleteDialog && showDialog) // Check if the setting to show a confirmation dialog is on + if (UserSettingsService.PreferencesSettingsService.ShowConfirmDeleteDialog && showDialog) // Check if the setting to show a confirmation dialog is on { List incomingItems = new List(); @@ -391,7 +399,7 @@ public async Task PerformOperationTypeAsync(DataPackageOperation o { return default; } - if (destination.StartsWith(App.AppSettings.RecycleBinPath)) + if (destination.StartsWith(CommonPaths.RecycleBinPath)) { return await RecycleItemsFromClipboard(packageView, destination, showDialog, registerHistory); } diff --git a/Files/Filesystem/LibraryManager.cs b/Files/Filesystem/LibraryManager.cs index 86bf2522072d..162396d5305f 100644 --- a/Files/Filesystem/LibraryManager.cs +++ b/Files/Filesystem/LibraryManager.cs @@ -3,8 +3,11 @@ using Files.DataModels.NavigationControlItems; using Files.Extensions; using Files.Helpers; +using Files.Services; using Files.UserControls; using Files.ViewModels; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.ObjectModel; @@ -19,6 +22,8 @@ namespace Files.Filesystem { public class LibraryManager : IDisposable { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public MainViewModel MainViewModel => App.MainViewModel; private LocationItem librarySection; @@ -32,7 +37,7 @@ public LibraryManager() private async void Libraries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { - if (!App.AppSettings.ShowLibrarySection) + if (!UserSettingsService.SidebarSettingsService.ShowLibrarySection) { return; } @@ -133,18 +138,17 @@ private void RemoveLibrariesSideBarSection() try { var item = (from n in SidebarControl.SideBarItems where n.Text.Equals("SidebarLibraries".GetLocalized()) select n).FirstOrDefault(); - if (!App.AppSettings.ShowLibrarySection && item != null) + if (!UserSettingsService.SidebarSettingsService.ShowLibrarySection && item != null) { SidebarControl.SideBarItems.Remove(item); } } - catch (Exception) - { } + catch (Exception) { } } public async void UpdateLibrariesSectionVisibility() { - if (App.AppSettings.ShowLibrarySection) + if (UserSettingsService.SidebarSettingsService.ShowLibrarySection) { await EnumerateLibrariesAsync(); } @@ -190,7 +194,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio try { var section = SidebarControl.SideBarItems.FirstOrDefault(x => x.Text == "SidebarLibraries".GetLocalized()) as LocationItem; - if (App.AppSettings.ShowLibrarySection && section == null) + if (UserSettingsService.SidebarSettingsService.ShowLibrarySection && section == null) { librarySection = new LocationItem { diff --git a/Files/Filesystem/ListedItem.cs b/Files/Filesystem/ListedItem.cs index 9f8d92b120cd..3b9e093fb9a6 100644 --- a/Files/Filesystem/ListedItem.cs +++ b/Files/Filesystem/ListedItem.cs @@ -4,9 +4,11 @@ using Files.Filesystem.Cloud; using Files.Filesystem.StorageItems; using Files.Helpers; +using Files.Services; using Files.ViewModels.Properties; using FluentFTP; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using Newtonsoft.Json; using System; @@ -21,6 +23,9 @@ namespace Files.Filesystem { public class ListedItem : ObservableObject, IGroupableItem { + private static IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + private static IFileTagsSettingsService FileTagsSettingsService { get; } = Ioc.Default.GetService(); + public bool IsHiddenItem { get; set; } = false; public StorageItemTypes PrimaryItemAttribute { get; set; } @@ -120,7 +125,7 @@ public string FileTag public FileTag FileTagUI { - get => App.AppSettings.AreFileTagsEnabled ? App.AppSettings.FileTagsSettings.GetTagByID(FileTag) : null; + get => UserSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled ? FileTagsSettingsService.GetTagById(FileTag) : null; } private Uri customIconSource; diff --git a/Files/Filesystem/NetworkDrivesManager.cs b/Files/Filesystem/NetworkDrivesManager.cs index dcc6e2535f96..91ac9e3d8680 100644 --- a/Files/Filesystem/NetworkDrivesManager.cs +++ b/Files/Filesystem/NetworkDrivesManager.cs @@ -2,7 +2,10 @@ using Files.DataModels; using Files.DataModels.NavigationControlItems; using Files.Helpers; +using Files.Services; using Files.UserControls; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Generic; @@ -18,6 +21,8 @@ namespace Files.Filesystem { public class NetworkDrivesManager { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + private static readonly Logger Logger = App.Logger; private readonly List drivesList = new List(); @@ -38,7 +43,7 @@ public NetworkDrivesManager() { DeviceID = "network-folder", Text = "Network".GetLocalized(), - Path = App.AppSettings.NetworkFolderPath, + Path = CommonPaths.NetworkFolderPath, Type = DriveType.Network, ItemType = NavigationControlItemType.Drive }; @@ -50,7 +55,7 @@ public NetworkDrivesManager() public async Task EnumerateDrivesAsync() { - if (!App.AppSettings.ShowNetworkDrivesSection) + if (!UserSettingsService.SidebarSettingsService.ShowNetworkDrivesSection) { return; } @@ -117,7 +122,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio try { var section = SidebarControl.SideBarItems.FirstOrDefault(x => x.Text == "SidebarNetworkDrives".GetLocalized()) as LocationItem; - if (App.AppSettings.ShowNetworkDrivesSection && section == null) + if (UserSettingsService.SidebarSettingsService.ShowNetworkDrivesSection && section == null) { section = new LocationItem() { @@ -167,7 +172,7 @@ private void RemoveNetworkDrivesSideBarSection() try { var item = (from n in SidebarControl.SideBarItems where n.Text.Equals("SidebarNetworkDrives".GetLocalized()) select n).FirstOrDefault(); - if (!App.AppSettings.ShowNetworkDrivesSection && item != null) + if (!UserSettingsService.SidebarSettingsService.ShowNetworkDrivesSection && item != null) { SidebarControl.SideBarItems.Remove(item); } @@ -178,7 +183,7 @@ private void RemoveNetworkDrivesSideBarSection() public async void UpdateNetworkDrivesSectionVisibility() { - if (App.AppSettings.ShowNetworkDrivesSection) + if (UserSettingsService.SidebarSettingsService.ShowNetworkDrivesSection) { await EnumerateDrivesAsync(); } diff --git a/Files/Filesystem/Search/FolderSearch.cs b/Files/Filesystem/Search/FolderSearch.cs index 41cb79c4fbfb..df1daaf93681 100644 --- a/Files/Filesystem/Search/FolderSearch.cs +++ b/Files/Filesystem/Search/FolderSearch.cs @@ -3,6 +3,8 @@ using Files.Extensions; using Files.Filesystem.StorageItems; using Files.Helpers; +using Files.Services; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Generic; @@ -22,6 +24,10 @@ namespace Files.Filesystem.Search { public class FolderSearch { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + + private IFileTagsSettingsService FileTagsSettingsService { get; } = Ioc.Default.GetService(); + private const uint defaultStepSize = 500; public string Query { get; set; } @@ -165,7 +171,7 @@ private async Task SearchTagsAsync(string folder, IList results, Can { //var sampler = new IntervalSampler(500); var tagName = AQSQuery.Substring("tag:".Length); - var tags = App.AppSettings.FileTagsSettings.GetTagsByName(tagName); + var tags = FileTagsSettingsService.GetTagsByName(tagName); if (!tags.Any()) { return; @@ -185,7 +191,8 @@ private async Task SearchTagsAsync(string folder, IList results, Can { var isSystem = ((FileAttributes)findData.dwFileAttributes & FileAttributes.System) == FileAttributes.System; var isHidden = ((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) == FileAttributes.Hidden; - bool shouldBeListed = !isHidden || (App.AppSettings.AreHiddenItemsVisible && (!isSystem || !App.AppSettings.AreSystemItemsHidden)); + + bool shouldBeListed = !isHidden || (UserSettingsService.FilesAndFoldersSettingsService.AreHiddenItemsVisible && (!isSystem || !UserSettingsService.FilesAndFoldersSettingsService.AreSystemItemsHidden)); if (shouldBeListed) { @@ -245,7 +252,7 @@ private async Task AddItemsAsync(string folder, IList results, Cance hiddenOnlyFromWin32 = true; } - if (!hiddenOnlyFromWin32 || App.AppSettings.AreHiddenItemsVisible) + if (!hiddenOnlyFromWin32 || UserSettingsService.FilesAndFoldersSettingsService.AreHiddenItemsVisible) { await SearchWithWin32Async(folder, hiddenOnlyFromWin32, UsedMaxItemCount - (uint)results.Count, results, token); //foreach (var item in) @@ -283,8 +290,8 @@ await Task.Run(() => var isSystem = ((FileAttributes)findData.dwFileAttributes & FileAttributes.System) == FileAttributes.System; var isHidden = ((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) == FileAttributes.Hidden; bool shouldBeListed = hiddenOnly ? - isHidden && (!isSystem || !App.AppSettings.AreSystemItemsHidden) : - !isHidden || (App.AppSettings.AreHiddenItemsVisible && (!isSystem || !App.AppSettings.AreSystemItemsHidden)); + isHidden && (!isSystem || !UserSettingsService.FilesAndFoldersSettingsService.AreSystemItemsHidden) : + !isHidden || (UserSettingsService.FilesAndFoldersSettingsService.AreHiddenItemsVisible && (!isSystem || !UserSettingsService.FilesAndFoldersSettingsService.AreSystemItemsHidden)); if (shouldBeListed) { diff --git a/Files/Filesystem/StorageEnumerators/UniversalStorageEnumerator.cs b/Files/Filesystem/StorageEnumerators/UniversalStorageEnumerator.cs index 146b58255a23..cf0c004551a9 100644 --- a/Files/Filesystem/StorageEnumerators/UniversalStorageEnumerator.cs +++ b/Files/Filesystem/StorageEnumerators/UniversalStorageEnumerator.cs @@ -2,7 +2,9 @@ using Files.Extensions; using Files.Filesystem.StorageItems; using Files.Helpers; +using Files.Services; using Files.Views.LayoutModes; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Generic; @@ -170,9 +172,11 @@ private static async Task AddFileAsync( CancellationToken cancellationToken ) { + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + var basicProperties = await file.GetBasicPropertiesAsync(); // Display name does not include extension - var itemName = string.IsNullOrEmpty(file.DisplayName) || App.AppSettings.ShowFileExtensions ? + var itemName = string.IsNullOrEmpty(file.DisplayName) || userSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions ? file.Name : file.DisplayName; var itemModifiedDate = basicProperties.DateModified; var itemCreatedDate = file.DateCreated; diff --git a/Files/Filesystem/StorageEnumerators/Win32StorageEnumerator.cs b/Files/Filesystem/StorageEnumerators/Win32StorageEnumerator.cs index 234b8f722e84..51834365e94c 100644 --- a/Files/Filesystem/StorageEnumerators/Win32StorageEnumerator.cs +++ b/Files/Filesystem/StorageEnumerators/Win32StorageEnumerator.cs @@ -2,6 +2,8 @@ using Files.Extensions; using Files.Helpers; using Files.Helpers.FileListCache; +using Files.Services; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Generic; @@ -37,11 +39,13 @@ Func, Task> intermediateAction var hasNextFile = false; var count = 0; + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + do { var isSystem = ((FileAttributes)findData.dwFileAttributes & FileAttributes.System) == FileAttributes.System; var isHidden = ((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) == FileAttributes.Hidden; - if (!isHidden || (App.AppSettings.AreHiddenItemsVisible && (!isSystem || !App.AppSettings.AreSystemItemsHidden))) + if (!isHidden || (userSettingsService.FilesAndFoldersSettingsService.AreHiddenItemsVisible && (!isSystem || !userSettingsService.FilesAndFoldersSettingsService.AreSystemItemsHidden))) { if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) != FileAttributes.Directory) { @@ -158,10 +162,12 @@ public static async Task GetFile( CancellationToken cancellationToken ) { + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + var itemPath = Path.Combine(pathRoot, findData.cFileName); string itemName; - if (App.AppSettings.ShowFileExtensions && !findData.cFileName.EndsWith(".lnk") && !findData.cFileName.EndsWith(".url")) + if (userSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions && !findData.cFileName.EndsWith(".lnk") && !findData.cFileName.EndsWith(".url")) { itemName = findData.cFileName; // never show extension for shortcuts } diff --git a/Files/Filesystem/StorageFileHelpers/StorageFileExtensions.cs b/Files/Filesystem/StorageFileHelpers/StorageFileExtensions.cs index d5d5bc5f4686..32a773dcfb7b 100644 --- a/Files/Filesystem/StorageFileHelpers/StorageFileExtensions.cs +++ b/Files/Filesystem/StorageFileHelpers/StorageFileExtensions.cs @@ -22,7 +22,7 @@ public static class StorageFileExtensions private static PathBoxItem GetPathItem(string component, string path) { - if (component.StartsWith(AppSettings.RecycleBinPath)) + if (component.StartsWith(CommonPaths.RecycleBinPath)) { // Handle the recycle bin: use the localized folder name return new PathBoxItem() @@ -233,27 +233,27 @@ public static string GetPathWithoutEnvironmentVariable(string path) { if (path.StartsWith("~\\")) { - path = $"{AppSettings.HomePath}{path.Remove(0, 1)}"; + path = $"{CommonPaths.HomePath}{path.Remove(0, 1)}"; } if (path.Contains("%temp%", StringComparison.OrdinalIgnoreCase)) { - path = path.Replace("%temp%", AppSettings.TempPath, StringComparison.OrdinalIgnoreCase); + path = path.Replace("%temp%", CommonPaths.TempPath, StringComparison.OrdinalIgnoreCase); } if (path.Contains("%tmp%", StringComparison.OrdinalIgnoreCase)) { - path = path.Replace("%tmp%", AppSettings.TempPath, StringComparison.OrdinalIgnoreCase); + path = path.Replace("%tmp%", CommonPaths.TempPath, StringComparison.OrdinalIgnoreCase); } if (path.Contains("%localappdata%", StringComparison.OrdinalIgnoreCase)) { - path = path.Replace("%localappdata%", AppSettings.LocalAppDataPath, StringComparison.OrdinalIgnoreCase); + path = path.Replace("%localappdata%", CommonPaths.LocalAppDataPath, StringComparison.OrdinalIgnoreCase); } if (path.Contains("%homepath%", StringComparison.OrdinalIgnoreCase)) { - path = path.Replace("%homepath%", AppSettings.HomePath, StringComparison.OrdinalIgnoreCase); + path = path.Replace("%homepath%", CommonPaths.HomePath, StringComparison.OrdinalIgnoreCase); } return Environment.ExpandEnvironmentVariables(path); diff --git a/Files/Filesystem/WSLDistroManager.cs b/Files/Filesystem/WSLDistroManager.cs index 6a34120e198f..848f979f7169 100644 --- a/Files/Filesystem/WSLDistroManager.cs +++ b/Files/Filesystem/WSLDistroManager.cs @@ -1,5 +1,8 @@ using Files.DataModels.NavigationControlItems; +using Files.Services; using Files.UserControls; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.ObjectModel; @@ -13,9 +16,7 @@ namespace Files.Filesystem { public class WSLDistroManager { - public WSLDistroManager() - { - } + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); public async Task EnumerateDrivesAsync() { @@ -48,7 +49,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio if ((await distroFolder.GetFoldersAsync()).Count != 0) { var section = SidebarControl.SideBarItems.FirstOrDefault(x => x.Text == "WSL".GetLocalized()) as LocationItem; - if (App.AppSettings.ShowWslSection && section == null) + if (UserSettingsService.SidebarSettingsService.ShowWslSection && section == null) { section = new LocationItem() { @@ -127,7 +128,7 @@ private void RemoveWslSideBarSection() try { var item = (from n in SidebarControl.SideBarItems where n.Text.Equals("WSL".GetLocalized()) select n).FirstOrDefault(); - if (!App.AppSettings.ShowWslSection && item != null) + if (!UserSettingsService.SidebarSettingsService.ShowWslSection && item != null) { SidebarControl.SideBarItems.Remove(item); } @@ -138,7 +139,7 @@ private void RemoveWslSideBarSection() public async void UpdateWslSectionVisibility() { - if (App.AppSettings.ShowWslSection) + if (UserSettingsService.SidebarSettingsService.ShowWslSection) { await EnumerateDrivesAsync(); } diff --git a/Files/Helpers/AdaptiveLayoutHelpers.cs b/Files/Helpers/AdaptiveLayoutHelpers.cs index 7ac5bffa7c36..4e82bb464a69 100644 --- a/Files/Helpers/AdaptiveLayoutHelpers.cs +++ b/Files/Helpers/AdaptiveLayoutHelpers.cs @@ -1,5 +1,7 @@ -using Files.ViewModels; +using Files.Services; +using Files.ViewModels; using Files.ViewModels.Previews; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using System; using System.Linq; using Windows.Storage; @@ -10,7 +12,9 @@ public static class AdaptiveLayoutHelpers { public static bool PredictLayoutMode(FolderSettingsViewModel folderSettings, ItemViewModel filesystemViewModel) { - if (App.AppSettings.AreLayoutPreferencesPerFolder && App.AppSettings.AdaptiveLayoutEnabled && !folderSettings.LayoutPreference.IsAdaptiveLayoutOverridden) + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + + if (userSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder && userSettingsService.FilesAndFoldersSettingsService.AdaptiveLayoutEnabled && !folderSettings.LayoutPreference.IsAdaptiveLayoutOverridden) { Action layoutDetails = () => folderSettings.ToggleLayoutModeDetailsView.Execute(false); Action layoutTiles = () => folderSettings.ToggleLayoutModeTiles.Execute(false); diff --git a/Files/Helpers/AppServiceConnectionHelper.cs b/Files/Helpers/AppServiceConnectionHelper.cs index ff582076346b..b719348451f8 100644 --- a/Files/Helpers/AppServiceConnectionHelper.cs +++ b/Files/Helpers/AppServiceConnectionHelper.cs @@ -170,7 +170,7 @@ private void EndReadCallBack(IAsyncResult result) } // Begin a new reading operation - var nextInfo = (Buffer: new byte[clientStream.InBufferSize], Message: new StringBuilder()); + var nextInfo = (Buffer: new byte[clientStream?.InBufferSize ?? 0], Message: new StringBuilder()); BeginRead(nextInfo); } } diff --git a/Files/Helpers/CommonPaths.cs b/Files/Helpers/CommonPaths.cs new file mode 100644 index 000000000000..3c4d3d3ed9f4 --- /dev/null +++ b/Files/Helpers/CommonPaths.cs @@ -0,0 +1,23 @@ +using System; +using Windows.Storage; + +namespace Files.Helpers +{ + public static class CommonPaths + { + public static readonly string DesktopPath = UserDataPaths.GetDefault().Desktop; + + public static readonly string DownloadsPath = UserDataPaths.GetDefault().Downloads; + + public static readonly string LocalAppDataPath = UserDataPaths.GetDefault().LocalAppData; + + // Currently is the command to open the folder from cmd ("cmd /c start Shell:RecycleBinFolder") + public static readonly string RecycleBinPath = Constants.CommonPaths.RecycleBinPath; + + public static readonly string NetworkFolderPath = Constants.CommonPaths.NetworkFolderPath; + + public static readonly string TempPath = (string)Microsoft.Win32.Registry.GetValue(@"HKEY_CURRENT_USER\Environment", "TEMP", null); + + public static readonly string HomePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + } +} diff --git a/Files/Helpers/ContextFlyoutItemHelper.cs b/Files/Helpers/ContextFlyoutItemHelper.cs index b11b62604ffa..a03493061ba0 100644 --- a/Files/Helpers/ContextFlyoutItemHelper.cs +++ b/Files/Helpers/ContextFlyoutItemHelper.cs @@ -2,7 +2,9 @@ using Files.Enums; using Files.Filesystem; using Files.Interacts; +using Files.Services; using Files.ViewModels; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using System; @@ -62,10 +64,12 @@ public static List Filter(List Check(item: x, currentInstanceViewModel: currentInstanceViewModel, selectedItems: selectedItems, shiftPressed: shiftPressed)).ToList(); items.ForEach(x => x.Items = x.Items?.Where(y => Check(item: y, currentInstanceViewModel: currentInstanceViewModel, selectedItems: selectedItems, shiftPressed: shiftPressed)).ToList()); + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + var overflow = items.Where(x => x.ID == "ItemOverflow").FirstOrDefault(); if (overflow != null) { - if (!shiftPressed && App.AppSettings.MoveOverflowMenuItemsToSubMenu) // items with ShowOnShift to overflow menu + if (!shiftPressed && userSettingsService.AppearanceSettingsService.MoveOverflowMenuItemsToSubMenu) // items with ShowOnShift to overflow menu { var overflowItems = items.Where(x => x.ShowOnShift).ToList(); @@ -101,6 +105,8 @@ private static bool Check(ContextMenuFlyoutItemViewModel item, CurrentInstanceVi public static List GetBaseLayoutMenuItems(CurrentInstanceViewModel currentInstanceViewModel, ItemViewModel itemViewModel, BaseLayoutCommandsViewModel commandsViewModel) { + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + return new List() { new ContextMenuFlyoutItemViewModel() @@ -282,7 +288,7 @@ public static List GetBaseLayoutMenuItems(Curren Text = "BaseLayoutContextFlyoutSortByFileTag/Text".GetLocalized(), IsChecked = itemViewModel.IsSortedByFileTag, Command = new RelayCommand(() => itemViewModel.IsSortedByFileTag = true), - ShowItem = App.AppSettings.AreFileTagsEnabled, + ShowItem = userSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled, ShowInRecycleBin = true, ShowInSearchPage = true, ItemType = ItemType.Toggle @@ -432,7 +438,7 @@ public static List GetBaseLayoutMenuItems(Curren { Text = "BaseLayoutContextFlyoutSortByFileTag/Text".GetLocalized(), IsChecked = currentInstanceViewModel.FolderSettings.DirectoryGroupOption == GroupOption.FileTag, - ShowItem = App.AppSettings.AreFileTagsEnabled, + ShowItem = userSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled, ShowInRecycleBin = true, ShowInSearchPage = true, Command = currentInstanceViewModel.FolderSettings.ChangeGroupOptionCommand, @@ -531,7 +537,7 @@ public static List GetBaseLayoutMenuItems(Curren Text = "BaseLayoutItemContextFlyoutPinToFavorites/Text".GetLocalized(), Glyph = "\uE840", Command = commandsViewModel.PinDirectoryToFavoritesCommand, - ShowItem = !itemViewModel.CurrentFolder.IsPinned & App.AppSettings.ShowFavoritesSection, + ShowItem = !itemViewModel.CurrentFolder.IsPinned & userSettingsService.SidebarSettingsService.ShowFavoritesSection, ShowInFtpPage = true, }, new ContextMenuFlyoutItemViewModel() @@ -539,7 +545,7 @@ public static List GetBaseLayoutMenuItems(Curren Text = "BaseLayoutContextFlyoutUnpinFromFavorites/Text".GetLocalized(), Glyph = "\uE77A", Command = commandsViewModel.UnpinDirectoryFromFavoritesCommand, - ShowItem = itemViewModel.CurrentFolder.IsPinned & App.AppSettings.ShowFavoritesSection, + ShowItem = itemViewModel.CurrentFolder.IsPinned & userSettingsService.SidebarSettingsService.ShowFavoritesSection, ShowInFtpPage = true, }, new ContextMenuFlyoutItemViewModel() @@ -601,6 +607,8 @@ public static List GetBaseLayoutMenuItems(Curren public static List GetBaseItemMenuItems(BaseLayoutCommandsViewModel commandsViewModel, List selectedItems, SelectedItemsPropertiesViewModel selectedItemsPropertiesViewModel, CurrentInstanceViewModel currentInstanceViewModel) { + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + return new List() { new ContextMenuFlyoutItemViewModel() @@ -661,7 +669,7 @@ public static List GetBaseItemMenuItems(BaseLayo Glyph = "\uE117", GlyphFontFamilyName = "CustomGlyph", Command = commandsViewModel.OpenDirectoryInNewPaneCommand, - ShowItem = App.AppSettings.IsDualPaneEnabled && selectedItems.All(i => i.PrimaryItemAttribute == Windows.Storage.StorageItemTypes.Folder), + ShowItem = userSettingsService.MultitaskingSettingsService.IsDualPaneEnabled && selectedItems.All(i => i.PrimaryItemAttribute == Windows.Storage.StorageItemTypes.Folder), SingleItemOnly = true, ShowInSearchPage = true, ShowInFtpPage = true, @@ -957,7 +965,7 @@ public static List GetBaseItemMenuItems(BaseLayo Text = "BaseLayoutItemContextFlyoutPinToFavorites/Text".GetLocalized(), Glyph = "\uE840", Command = commandsViewModel.SidebarPinItemCommand, - ShowItem = selectedItems.All(x => x.PrimaryItemAttribute == StorageItemTypes.Folder && !x.IsZipItem && !x.IsPinned) & App.AppSettings.ShowFavoritesSection, + ShowItem = selectedItems.All(x => x.PrimaryItemAttribute == StorageItemTypes.Folder && !x.IsZipItem && !x.IsPinned) & userSettingsService.SidebarSettingsService.ShowFavoritesSection, ShowInSearchPage = true, ShowInFtpPage = true, }, @@ -966,7 +974,7 @@ public static List GetBaseItemMenuItems(BaseLayo Text = "BaseLayoutContextFlyoutUnpinFromFavorites/Text".GetLocalized(), Glyph = "\uE77A", Command = commandsViewModel.SidebarUnpinItemCommand, - ShowItem = selectedItems.All(x => x.PrimaryItemAttribute == StorageItemTypes.Folder && !x.IsZipItem && x.IsPinned) & App.AppSettings.ShowFavoritesSection, + ShowItem = selectedItems.All(x => x.PrimaryItemAttribute == StorageItemTypes.Folder && !x.IsZipItem && x.IsPinned) & userSettingsService.SidebarSettingsService.ShowFavoritesSection, ShowInSearchPage = true, ShowInFtpPage = true, }, diff --git a/Files/Helpers/ItemListDisplayHelpers/SortingHelper.cs b/Files/Helpers/ItemListDisplayHelpers/SortingHelper.cs index a5a7d3c061ac..60035241e555 100644 --- a/Files/Helpers/ItemListDisplayHelpers/SortingHelper.cs +++ b/Files/Helpers/ItemListDisplayHelpers/SortingHelper.cs @@ -1,6 +1,7 @@ using Files.Enums; using Files.Filesystem; -using Microsoft.Toolkit.Uwp.UI; +using Files.Services; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using System; using System.Collections.Generic; using System.Linq; @@ -39,11 +40,13 @@ public static IEnumerable OrderFileList(List filesAndFol static bool folderThenFileAsync(ListedItem listedItem) => (listedItem.PrimaryItemAttribute == StorageItemTypes.File || listedItem.IsZipItem); IOrderedEnumerable ordered; + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + if (directorySortDirection == SortDirection.Ascending) { if (directorySortOption == SortOption.Name) { - if (App.AppSettings.ListAndSortDirectoriesAlongsideFiles) + if (userSettingsService.FilesAndFoldersSettingsService.ListAndSortDirectoriesAlongsideFiles) { ordered = filesAndFolders.OrderBy(orderFunc, naturalStringComparer); } @@ -54,7 +57,7 @@ public static IEnumerable OrderFileList(List filesAndFol } else if (directorySortOption == SortOption.FileTag) { - if (App.AppSettings.ListAndSortDirectoriesAlongsideFiles) + if (userSettingsService.FilesAndFoldersSettingsService.ListAndSortDirectoriesAlongsideFiles) { ordered = filesAndFolders.OrderBy(x => string.IsNullOrEmpty(orderFunc(x) as string)).ThenBy(orderFunc); } @@ -65,7 +68,7 @@ public static IEnumerable OrderFileList(List filesAndFol } else { - if (App.AppSettings.ListAndSortDirectoriesAlongsideFiles) + if (userSettingsService.FilesAndFoldersSettingsService.ListAndSortDirectoriesAlongsideFiles) { ordered = filesAndFolders.OrderBy(orderFunc); } @@ -79,7 +82,7 @@ public static IEnumerable OrderFileList(List filesAndFol { if (directorySortOption == SortOption.Name) { - if (App.AppSettings.ListAndSortDirectoriesAlongsideFiles) + if (userSettingsService.FilesAndFoldersSettingsService.ListAndSortDirectoriesAlongsideFiles) { ordered = filesAndFolders.OrderByDescending(orderFunc, naturalStringComparer); } @@ -90,7 +93,7 @@ public static IEnumerable OrderFileList(List filesAndFol } else if (directorySortOption == SortOption.FileTag) { - if (App.AppSettings.ListAndSortDirectoriesAlongsideFiles) + if (userSettingsService.FilesAndFoldersSettingsService.ListAndSortDirectoriesAlongsideFiles) { ordered = filesAndFolders.OrderBy(x => string.IsNullOrEmpty(orderFunc(x) as string)).ThenByDescending(orderFunc); } @@ -101,7 +104,7 @@ public static IEnumerable OrderFileList(List filesAndFol } else { - if (App.AppSettings.ListAndSortDirectoriesAlongsideFiles) + if (userSettingsService.FilesAndFoldersSettingsService.ListAndSortDirectoriesAlongsideFiles) { ordered = filesAndFolders.OrderByDescending(orderFunc); } diff --git a/Files/Helpers/JumpListManager.cs b/Files/Helpers/JumpListManager.cs index 6800c0e230d7..3ef86a9679cf 100644 --- a/Files/Helpers/JumpListManager.cs +++ b/Files/Helpers/JumpListManager.cs @@ -60,15 +60,15 @@ private void AddFolder(string path) if (instance != null && !JumpListItemPaths.Contains(path)) { string displayName; - if (path.Equals(App.AppSettings.DesktopPath, StringComparison.OrdinalIgnoreCase)) + if (path.Equals(CommonPaths.DesktopPath, StringComparison.OrdinalIgnoreCase)) { displayName = "ms-resource:///Resources/SidebarDesktop"; } - else if (path.Equals(App.AppSettings.DownloadsPath, StringComparison.OrdinalIgnoreCase)) + else if (path.Equals(CommonPaths.DownloadsPath, StringComparison.OrdinalIgnoreCase)) { displayName = "ms-resource:///Resources/SidebarDownloads"; } - else if (path.Equals(App.AppSettings.RecycleBinPath, StringComparison.OrdinalIgnoreCase)) + else if (path.Equals(CommonPaths.RecycleBinPath, StringComparison.OrdinalIgnoreCase)) { var localSettings = ApplicationData.Current.LocalSettings; displayName = localSettings.Values.Get("RecycleBin_Title", "Recycle Bin"); diff --git a/Files/Helpers/NavigationHelpers.cs b/Files/Helpers/NavigationHelpers.cs index d6460e82d115..0a0e4cfe1858 100644 --- a/Files/Helpers/NavigationHelpers.cs +++ b/Files/Helpers/NavigationHelpers.cs @@ -2,8 +2,10 @@ using Files.Enums; using Files.Filesystem; using Files.Filesystem.StorageItems; +using Files.Services; using Files.ViewModels; using Files.Views; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Generic; @@ -66,7 +68,7 @@ public static async Task OpenDirectoryInTerminal(string workingDir) public static async void OpenSelectedItems(IShellPage associatedInstance, bool openViaApplicationPicker = false) { - if (associatedInstance.FilesystemViewModel.WorkingDirectory.StartsWith(App.AppSettings.RecycleBinPath)) + if (associatedInstance.FilesystemViewModel.WorkingDirectory.StartsWith(CommonPaths.RecycleBinPath)) { // Do not open files and folders inside the recycle bin return; @@ -86,7 +88,7 @@ public static async void OpenSelectedItems(IShellPage associatedInstance, bool o public static async void OpenItemsWithExecutable(IShellPage associatedInstance, List items, string executable) { - if (associatedInstance.FilesystemViewModel.WorkingDirectory.StartsWith(App.AppSettings.RecycleBinPath)) + if (associatedInstance.FilesystemViewModel.WorkingDirectory.StartsWith(CommonPaths.RecycleBinPath)) { // Do not open files and folders inside the recycle bin return; @@ -196,11 +198,13 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio private static async Task OpenLibrary(string path, IShellPage associatedInstance, IEnumerable selectItems) { + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + var opened = (FilesystemResult)false; bool isHiddenItem = NativeFileOperationsHelper.HasFileAttribute(path, System.IO.FileAttributes.Hidden); if (isHiddenItem) { - if (App.AppSettings.OpenFoldersNewTab) + if (userSettingsService.PreferencesSettingsService.OpenFoldersInNewTab) { await OpenPathInNewTab(path); } @@ -220,7 +224,7 @@ private static async Task OpenLibrary(string path, IShellPage opened = (FilesystemResult)await library.CheckDefaultSaveFolderAccess(); if (opened) { - if (App.AppSettings.OpenFoldersNewTab) + if (userSettingsService.PreferencesSettingsService.OpenFoldersInNewTab) { await OpenPathInNewTab(library.Text); } @@ -241,9 +245,12 @@ private static async Task OpenLibrary(string path, IShellPage private static async Task OpenDirectory(string path, IShellPage associatedInstance, IEnumerable selectItems, ShortcutItem shortcutInfo) { + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + var opened = (FilesystemResult)false; bool isHiddenItem = NativeFileOperationsHelper.HasFileAttribute(path, System.IO.FileAttributes.Hidden); bool isShortcutItem = path.EndsWith(".lnk") || path.EndsWith(".url"); // Determine + if (isShortcutItem) { if (string.IsNullOrEmpty(shortcutInfo.TargetPath)) @@ -253,7 +260,7 @@ private static async Task OpenDirectory(string path, IShellPag } else { - if (App.AppSettings.OpenFoldersNewTab) + if (userSettingsService.PreferencesSettingsService.OpenFoldersInNewTab) { await OpenPathInNewTab(shortcutInfo.TargetPath); } @@ -273,7 +280,7 @@ private static async Task OpenDirectory(string path, IShellPag } else if (isHiddenItem) { - if (App.AppSettings.OpenFoldersNewTab) + if (userSettingsService.PreferencesSettingsService.OpenFoldersInNewTab) { await OpenPathInNewTab(path); } @@ -307,7 +314,7 @@ private static async Task OpenDirectory(string path, IShellPag } if (opened) { - if (App.AppSettings.OpenFoldersNewTab) + if (userSettingsService.PreferencesSettingsService.OpenFoldersInNewTab) { await OpenPathInNewTab(path); } @@ -409,7 +416,7 @@ await connection.SendMessageAsync(new ValueSet() //We can have many sort entries SortEntry sortEntry = new SortEntry() { - AscendingOrder = associatedInstance.InstanceViewModel.FolderSettings.DirectorySortDirection == Microsoft.Toolkit.Uwp.UI.SortDirection.Ascending + AscendingOrder = associatedInstance.InstanceViewModel.FolderSettings.DirectorySortDirection == SortDirection.Ascending }; //Basically we tell to the launched app to follow how we sorted the files in the directory. diff --git a/Files/Helpers/RecycleBinHelpers.cs b/Files/Helpers/RecycleBinHelpers.cs index 181b91246474..be2a2cabea73 100644 --- a/Files/Helpers/RecycleBinHelpers.cs +++ b/Files/Helpers/RecycleBinHelpers.cs @@ -32,7 +32,7 @@ public async Task> EnumerateRecycleBin() { { "Arguments", "ShellFolder" }, { "action", "Enumerate" }, - { "folder", App.AppSettings.RecycleBinPath } + { "folder", CommonPaths.RecycleBinPath } }; var (status, response) = await connection.SendMessageForResponseAsync(value); diff --git a/Files/Helpers/RegistryToJsonSettingsMerger.cs b/Files/Helpers/RegistryToJsonSettingsMerger.cs new file mode 100644 index 000000000000..4c2a67aca812 --- /dev/null +++ b/Files/Helpers/RegistryToJsonSettingsMerger.cs @@ -0,0 +1,101 @@ +using Files.Enums; +using Files.Services; +using Files.ViewModels; +using Microsoft.Toolkit.Mvvm.DependencyInjection; +using System; +using System.Diagnostics; +using System.Linq; + +namespace Files.Helpers +{ + // TODO: Please remove this class after V2 version next since most of users would have merged the settings by that time + public class RegistryToJsonSettingsMerger + { + public static void MergeSettings() + { + if (!App.AppSettings.AreRegistrySettingsMergedToJson) + { + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + SettingsViewModel appSettings = App.AppSettings; + + try + { + // Preview pane + userSettingsService.PreviewPaneSettingsService.PreviewPaneSizeHorizontalPx = appSettings.Get(300d, "PreviewPaneSizeHorizontal"); + userSettingsService.PreviewPaneSettingsService.PreviewPaneSizeVerticalPx = appSettings.Get(250d, "PreviewPaneSizeVertical"); + userSettingsService.PreviewPaneSettingsService.PreviewPaneEnabled = appSettings.Get(false, "PreviewPaneEnabled"); + userSettingsService.PreviewPaneSettingsService.ShowPreviewOnly = appSettings.Get(false, "ShowPreviewOnly"); + userSettingsService.PreviewPaneSettingsService.PreviewPaneMediaVolume = appSettings.Get(1.0d, "MediaVolume"); + + // Files and folders + userSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions = appSettings.Get(true, "ShowFileExtensions"); + userSettingsService.FilesAndFoldersSettingsService.AreHiddenItemsVisible = appSettings.Get(false, "AreHiddenItemsVisible"); + userSettingsService.FilesAndFoldersSettingsService.AreSystemItemsHidden = appSettings.Get(true, "AreSystemItemsHidden"); + userSettingsService.FilesAndFoldersSettingsService.ListAndSortDirectoriesAlongsideFiles = appSettings.Get(false, "ListAndSortDirectoriesAlongsideFiles"); + userSettingsService.FilesAndFoldersSettingsService.OpenItemsWithOneclick = appSettings.Get(false, "OpenItemsWithOneclick"); + userSettingsService.FilesAndFoldersSettingsService.SearchUnindexedItems = appSettings.Get(false, "SearchUnindexedItems"); + userSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder = appSettings.Get(true, "AreLayoutPreferencesPerFolder"); + userSettingsService.FilesAndFoldersSettingsService.AdaptiveLayoutEnabled = appSettings.Get(true, "AdaptiveLayoutEnabled"); + userSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled = appSettings.Get(false, "AreFileTagsEnabled"); + + // Multitasking + userSettingsService.MultitaskingSettingsService.IsVerticalTabFlyoutEnabled = appSettings.Get(true, "IsVerticalTabFlyoutEnabled"); + userSettingsService.MultitaskingSettingsService.IsDualPaneEnabled = appSettings.Get(false, "IsDualPaneEnabled"); + userSettingsService.MultitaskingSettingsService.AlwaysOpenDualPaneInNewTab = appSettings.Get(false, "AlwaysOpenDualPaneInNewTab"); + + // Widgets + userSettingsService.WidgetsSettingsService.ShowFoldersWidget = appSettings.Get(true, "ShowFolderWidgetWidget"); + userSettingsService.WidgetsSettingsService.ShowRecentFilesWidget = appSettings.Get(true, "ShowRecentFilesWidget"); + userSettingsService.WidgetsSettingsService.ShowDrivesWidget = appSettings.Get(true, "ShowDrivesWidget"); + userSettingsService.WidgetsSettingsService.ShowBundlesWidget = appSettings.Get(false, "ShowBundlesWidget"); + + // Sidebar + userSettingsService.SidebarSettingsService.SidebarWidth = appSettings.Get(255d, "SidebarWidth"); + userSettingsService.SidebarSettingsService.IsSidebarOpen = appSettings.Get(true, "IsSidebarOpen"); + userSettingsService.SidebarSettingsService.ShowFavoritesSection = appSettings.Get(true, "ShowFavoritesSection"); + userSettingsService.SidebarSettingsService.ShowLibrarySection = appSettings.Get(false, "ShowLibrarySection"); + userSettingsService.SidebarSettingsService.ShowDrivesSection = appSettings.Get(true, "ShowDrivesSection"); + userSettingsService.SidebarSettingsService.ShowCloudDrivesSection = appSettings.Get(true, "ShowCloudDrivesSection"); + userSettingsService.SidebarSettingsService.ShowNetworkDrivesSection = appSettings.Get(true, "ShowNetworkDrivesSection"); + userSettingsService.SidebarSettingsService.ShowWslSection = appSettings.Get(true, "ShowWslSection"); + userSettingsService.SidebarSettingsService.PinRecycleBinToSidebar = appSettings.Get(true, "PinRecycleBinToSideBar"); + + // Preferences + userSettingsService.PreferencesSettingsService.ShowConfirmDeleteDialog = appSettings.Get(true, "ShowConfirmDeleteDialog"); + userSettingsService.PreferencesSettingsService.OpenFoldersInNewTab = appSettings.Get(false, "OpenFoldersNewTab"); + + // Appearance + userSettingsService.AppearanceSettingsService.MoveOverflowMenuItemsToSubMenu = appSettings.Get(true, "MoveOverflowMenuItemsToSubMenu"); + + // Startup + userSettingsService.StartupSettingsService.OpenSpecificPageOnStartup = appSettings.Get(false, "OpenASpecificPageOnStartup"); + userSettingsService.StartupSettingsService.OpenSpecificPageOnStartupPath = appSettings.Get("", "OpenASpecificPageOnStartupPath"); + userSettingsService.StartupSettingsService.ContinueLastSessionOnStartUp = appSettings.Get(false, "ContinueLastSessionOnStartUp"); + userSettingsService.StartupSettingsService.OpenNewTabOnStartup = appSettings.Get(true, "OpenNewTabPageOnStartup"); + userSettingsService.StartupSettingsService.AlwaysOpenNewInstance = appSettings.Get(false, "AlwaysOpenANewInstance"); + userSettingsService.StartupSettingsService.TabsOnStartupList = appSettings.Get(null, "PagesOnStartupList")?.ToList(); + userSettingsService.StartupSettingsService.LastSessionTabList = appSettings.Get(null, "LastSessionPages")?.ToList(); + + // Layout settings + userSettingsService.LayoutSettingsService.ShowDateColumn = appSettings.Get(true, "ShowDateColumn"); + userSettingsService.LayoutSettingsService.ShowDateCreatedColumn = appSettings.Get(false, "ShowDateCreatedColumn"); + userSettingsService.LayoutSettingsService.ShowTypeColumn = appSettings.Get(true, "ShowTypeColumn"); + userSettingsService.LayoutSettingsService.ShowSizeColumn = appSettings.Get(true, "ShowSizeColumn"); + userSettingsService.LayoutSettingsService.ShowFileTagColumn = appSettings.Get(true, "ShowFileTagColumn"); + userSettingsService.LayoutSettingsService.DefaultGridViewSize = appSettings.Get(Constants.Browser.GridViewBrowser.GridViewSizeSmall, "DefaultGridViewSize"); + userSettingsService.LayoutSettingsService.DefaultLayoutMode = (FolderLayoutModes)appSettings.Get((byte)FolderLayoutModes.DetailsView, "DefaultLayoutMode"); + userSettingsService.LayoutSettingsService.DefaultDirectorySortDirection = (SortDirection)appSettings.Get((byte)Microsoft.Toolkit.Uwp.UI.SortDirection.Ascending, "DefaultDirectorySortDirection"); + userSettingsService.LayoutSettingsService.DefaultDirectorySortOption = (SortOption)appSettings.Get((byte)SortOption.Name, "DefaultDirectorySortOption"); + userSettingsService.LayoutSettingsService.DefaultDirectoryGroupOption = (GroupOption)appSettings.Get((byte)GroupOption.None, "DefaultDirectoryGroupOption"); + + App.AppSettings.AreRegistrySettingsMergedToJson = true; + } + catch (Exception ex) + { + App.Logger.Warn(ex, "Merging settings failed"); + Debugger.Break(); + } + } + } + } +} diff --git a/Files/Helpers/UIFilesystemHelpers.cs b/Files/Helpers/UIFilesystemHelpers.cs index c68aaede6630..b38236045cf1 100644 --- a/Files/Helpers/UIFilesystemHelpers.cs +++ b/Files/Helpers/UIFilesystemHelpers.cs @@ -4,6 +4,8 @@ using Files.Filesystem; using Files.Filesystem.StorageItems; using Files.Interacts; +using Files.Services; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Concurrent; @@ -237,6 +239,8 @@ public static async Task PasteItemAsync(string destinationPath, IShellPage assoc public static async Task RenameFileItemAsync(ListedItem item, string oldName, string newName, IShellPage associatedInstance) { + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + if (oldName == newName || string.IsNullOrEmpty(newName)) { return true; @@ -250,7 +254,7 @@ public static async Task RenameFileItemAsync(ListedItem item, string oldNa } else { - if (item.IsShortcutItem || !App.AppSettings.ShowFileExtensions) + if (item.IsShortcutItem || !userSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions) { newName += item.FileExtension; } diff --git a/Files/Helpers/WidgetsHelpers.cs b/Files/Helpers/WidgetsHelpers.cs index ef4e8c9adce3..ec2da9acc05d 100644 --- a/Files/Helpers/WidgetsHelpers.cs +++ b/Files/Helpers/WidgetsHelpers.cs @@ -1,4 +1,5 @@ -using Files.UserControls.Widgets; +using Files.Services; +using Files.UserControls.Widgets; using Files.ViewModels.Widgets; using System.Collections.Generic; @@ -6,10 +7,10 @@ namespace Files.Helpers { public static class WidgetsHelpers { - public static TWidget TryGetWidget(WidgetsListControlViewModel widgetsViewModel, out bool shouldReload, TWidget defaultValue = default) where TWidget : IWidgetItemModel, new() + public static TWidget TryGetWidget(IWidgetsSettingsService widgetsSettingsService, WidgetsListControlViewModel widgetsViewModel, out bool shouldReload, TWidget defaultValue = default) where TWidget : IWidgetItemModel, new() { bool canAddWidget = widgetsViewModel.CanAddWidget(typeof(TWidget).Name); - bool isWidgetSettingEnabled = TryGetIsWidgetSettingEnabled(); + bool isWidgetSettingEnabled = TryGetIsWidgetSettingEnabled(widgetsSettingsService); if (canAddWidget && isWidgetSettingEnabled) { @@ -34,23 +35,23 @@ public static class WidgetsHelpers return (defaultValue); } - public static bool TryGetIsWidgetSettingEnabled() where TWidget : IWidgetItemModel + public static bool TryGetIsWidgetSettingEnabled(IWidgetsSettingsService widgetsSettingsService) where TWidget : IWidgetItemModel { if (typeof(TWidget) == typeof(FolderWidget)) { - return App.AppSettings.ShowFolderWidgetWidget; + return widgetsSettingsService.ShowFoldersWidget; } if (typeof(TWidget) == typeof(DrivesWidget)) { - return App.AppSettings.ShowDrivesWidget; + return widgetsSettingsService.ShowDrivesWidget; } if (typeof(TWidget) == typeof(BundlesWidget)) { - return App.AppSettings.ShowBundlesWidget; + return widgetsSettingsService.ShowBundlesWidget; } if (typeof(TWidget) == typeof(RecentFilesWidget)) { - return App.AppSettings.ShowRecentFilesWidget; + return widgetsSettingsService.ShowRecentFilesWidget; } // A custom widget it is - TWidget implements ICustomWidgetItemModel if (typeof(ICustomWidgetItemModel).IsAssignableFrom(typeof(TWidget))) diff --git a/Files/Interacts/BaseLayoutCommandImplementationModel.cs b/Files/Interacts/BaseLayoutCommandImplementationModel.cs index 766f5c0d9a2e..0e7ef81f3a3a 100644 --- a/Files/Interacts/BaseLayoutCommandImplementationModel.cs +++ b/Files/Interacts/BaseLayoutCommandImplementationModel.cs @@ -546,7 +546,7 @@ public virtual async Task DragOver(DragEventArgs e) } else if (handledByFtp) { - if (pwd.StartsWith(App.AppSettings.RecycleBinPath)) + if (pwd.StartsWith(CommonPaths.RecycleBinPath)) { e.AcceptedOperation = DataPackageOperation.None; } @@ -564,7 +564,7 @@ public virtual async Task DragOver(DragEventArgs e) else { e.DragUIOverride.IsCaptionVisible = true; - if (pwd.StartsWith(App.AppSettings.RecycleBinPath)) + if (pwd.StartsWith(CommonPaths.RecycleBinPath)) { e.DragUIOverride.Caption = string.Format("MoveToFolderCaptionText".GetLocalized(), folderName); e.AcceptedOperation = DataPackageOperation.Move; diff --git a/Files/Models/JsonSettings/BaseJsonSettingsModel.cs b/Files/Models/JsonSettings/BaseJsonSettingsModel.cs new file mode 100644 index 000000000000..25e63cbbef5e --- /dev/null +++ b/Files/Models/JsonSettings/BaseJsonSettingsModel.cs @@ -0,0 +1,200 @@ +using Newtonsoft.Json.Linq; +using System.Runtime.CompilerServices; +using Files.Helpers; +using Files.Models.JsonSettings.Implementation; +using System; +using Files.EventArguments; +using System.IO; + +namespace Files.Models.JsonSettings +{ + /// + /// Clipboard Canvas + /// A base class to easily manage all application's settings. + /// + public abstract class BaseJsonSettingsModel : ISettingsSharingContext + { + #region Protected Members + + protected int registeredMembers = 0; + + protected ISettingsSharingContext settingsSharingContext; + + protected readonly IJsonSettingsSerializer jsonSettingsSerializer; + + protected readonly ISettingsSerializer settingsSerializer; + + #endregion Protected Members + + #region Properties + + private string _FilePath; + public string FilePath + { + get => settingsSharingContext?.FilePath ?? _FilePath; + protected set => _FilePath = value; + } + + private IJsonSettingsDatabase _JsonSettingsDatabase; + public IJsonSettingsDatabase JsonSettingsDatabase + { + get => settingsSharingContext?.JsonSettingsDatabase ?? _JsonSettingsDatabase; + protected set => _JsonSettingsDatabase = value; + } + + #endregion Properties + + #region Events + + public event EventHandler OnSettingChangedEvent; + + #endregion Events + + #region Constructor + + public BaseJsonSettingsModel() + { + } + + public BaseJsonSettingsModel(string filePath) + : this (filePath, null, null, null) + { + } + + public BaseJsonSettingsModel(ISettingsSharingContext settingsSharingContext) + { + RegisterSettingsContext(settingsSharingContext); + Initialize(); + } + + public BaseJsonSettingsModel(string filePath, bool isCachingEnabled, + IJsonSettingsSerializer jsonSettingsSerializer = null, + ISettingsSerializer settingsSerializer = null) + { + this.FilePath = filePath; + Initialize(); + + this.jsonSettingsSerializer = jsonSettingsSerializer; + this.settingsSerializer = settingsSerializer; + + // Fallback + this.jsonSettingsSerializer ??= new DefaultJsonSettingsSerializer(); + this.settingsSerializer ??= new DefaultSettingsSerializer(this.FilePath); + + if (isCachingEnabled) + { + this.JsonSettingsDatabase = new CachingJsonSettingsDatabase(this.jsonSettingsSerializer, this.settingsSerializer); + } + else + { + this.JsonSettingsDatabase = new DefaultJsonSettingsDatabase(this.jsonSettingsSerializer, this.settingsSerializer); + } + } + + public BaseJsonSettingsModel(string filePath, + IJsonSettingsSerializer jsonSettingsSerializer, + ISettingsSerializer settingsSerializer, + IJsonSettingsDatabase jsonSettingsDatabase) + { + this.FilePath = filePath; + Initialize(); + + this.jsonSettingsSerializer = jsonSettingsSerializer; + this.settingsSerializer = settingsSerializer; + this.JsonSettingsDatabase = jsonSettingsDatabase; + + // Fallback + this.jsonSettingsSerializer ??= new DefaultJsonSettingsSerializer(); + this.settingsSerializer ??= new DefaultSettingsSerializer(this.FilePath); + this.JsonSettingsDatabase ??= new DefaultJsonSettingsDatabase(this.jsonSettingsSerializer, this.settingsSerializer); + } + + #endregion Constructor + + #region Helpers + + protected virtual void Initialize() + { + // Create the file + NativeFileOperationsHelper.CreateDirectoryFromApp(Path.GetDirectoryName(FilePath), IntPtr.Zero); + NativeFileOperationsHelper.CreateFileForWrite(FilePath, false).Dispose(); + } + + public virtual bool FlushSettings() + { + return JsonSettingsDatabase.FlushSettings(); + } + + public virtual object ExportSettings() + { + return JsonSettingsDatabase.ExportSettings(); + } + + public virtual bool ImportSettings(object import) + { + return JsonSettingsDatabase.ImportSettings(import); + } + + public bool RegisterSettingsContext(ISettingsSharingContext settingsSharingContext) + { + if (this.settingsSharingContext == null) + { + // Can set only once + this.settingsSharingContext = settingsSharingContext; + return true; + } + + return false; + } + + public ISettingsSharingContext GetSharingContext() + { + registeredMembers++; + return settingsSharingContext ?? this; + } + + public virtual void RaiseOnSettingChangedEvent(object sender, SettingChangedEventArgs e) + { + if (settingsSharingContext != null) + { + settingsSharingContext.RaiseOnSettingChangedEvent(sender, e); + } + else + { + OnSettingChangedEvent?.Invoke(sender, e); + } + } + + #endregion Helpers + + #region Get, Set + + protected virtual TValue Get(TValue defaultValue, [CallerMemberName] string propertyName = "") + { + if (string.IsNullOrEmpty(propertyName)) + { + return defaultValue; + } + + return JsonSettingsDatabase.GetValue(propertyName, defaultValue); + } + + protected virtual bool Set(TValue value, [CallerMemberName] string propertyName = "") + { + if (string.IsNullOrEmpty(propertyName)) + { + return false; + } + + if (JsonSettingsDatabase.UpdateKey(propertyName, value)) + { + RaiseOnSettingChangedEvent(this, new SettingChangedEventArgs(propertyName, value)); + return true; + } + + return false; + } + + #endregion Get, Set + } +} \ No newline at end of file diff --git a/Files/Models/JsonSettings/IJsonSettingsDatabase.cs b/Files/Models/JsonSettings/IJsonSettingsDatabase.cs new file mode 100644 index 000000000000..2ab4731dec23 --- /dev/null +++ b/Files/Models/JsonSettings/IJsonSettingsDatabase.cs @@ -0,0 +1,19 @@ +namespace Files.Models.JsonSettings +{ + public interface IJsonSettingsDatabase + { + TValue GetValue(string key, TValue defaultValue = default); + + bool AddKey(string key, object value); + + bool RemoveKey(string key); + + bool UpdateKey(string key, object newValue); + + bool FlushSettings(); + + bool ImportSettings(object import); + + object ExportSettings(); + } +} diff --git a/Files/Models/JsonSettings/IJsonSettingsSerializer.cs b/Files/Models/JsonSettings/IJsonSettingsSerializer.cs new file mode 100644 index 000000000000..0979e72163e1 --- /dev/null +++ b/Files/Models/JsonSettings/IJsonSettingsSerializer.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Files.Models.JsonSettings +{ + public interface IJsonSettingsSerializer + { + + string SerializeToJson(object obj); + + T DeserializeFromJson(string json); + } +} diff --git a/Files/Models/JsonSettings/ISettingsSerializer.cs b/Files/Models/JsonSettings/ISettingsSerializer.cs new file mode 100644 index 000000000000..a3986c2f1745 --- /dev/null +++ b/Files/Models/JsonSettings/ISettingsSerializer.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Files.Models.JsonSettings +{ + public interface ISettingsSerializer + { + bool WriteToFile(string json); + + string ReadFromFile(); + } +} diff --git a/Files/Models/JsonSettings/ISettingsSharingContext.cs b/Files/Models/JsonSettings/ISettingsSharingContext.cs new file mode 100644 index 000000000000..d4f7f91ee3ac --- /dev/null +++ b/Files/Models/JsonSettings/ISettingsSharingContext.cs @@ -0,0 +1,15 @@ +using Files.EventArguments; + +namespace Files.Models.JsonSettings +{ + public interface ISettingsSharingContext + { + string FilePath { get; } + + IJsonSettingsDatabase JsonSettingsDatabase { get; } + + ISettingsSharingContext GetSharingContext(); + + void RaiseOnSettingChangedEvent(object sender, SettingChangedEventArgs e); + } +} diff --git a/Files/Models/JsonSettings/Implementation/CachingJsonSettingsDatabase.cs b/Files/Models/JsonSettings/Implementation/CachingJsonSettingsDatabase.cs new file mode 100644 index 000000000000..a95b96573cf1 --- /dev/null +++ b/Files/Models/JsonSettings/Implementation/CachingJsonSettingsDatabase.cs @@ -0,0 +1,93 @@ +using Files.Common; +using System.Collections; +using System.Linq; + +namespace Files.Models.JsonSettings.Implementation +{ + public sealed class CachingJsonSettingsDatabase : DefaultJsonSettingsDatabase + { + private int _cacheMisses = 0; + + public CachingJsonSettingsDatabase(IJsonSettingsSerializer jsonSettingsSerializer, ISettingsSerializer settingsSerializer) + : base(jsonSettingsSerializer, settingsSerializer) + { + } + + public override TValue GetValue(string key, TValue defaultValue = default) + { + if (settingsCache.ContainsKey(key)) + { + var value = settingsCache[key]; + if (value is Newtonsoft.Json.Linq.JToken jTokenValue) + { + var objValue = jTokenValue.ToObject(); + settingsCache[key] = objValue; + return objValue; + } + return (TValue)value; + } + else + { + _cacheMisses++; + return base.GetValue(key, defaultValue); + } + } + + public override bool AddKey(string key, object value) + { + if (settingsCache.ContainsKey(key)) + { + return false; + } + + _cacheMisses++; + return base.AddKey(key, value); + } + + public override bool RemoveKey(string key) + { + if (!settingsCache.ContainsKey(key)) + { + return false; + } + + _cacheMisses++; + return base.RemoveKey(key); + } + + public override bool UpdateKey(string key, object newValue) + { + if (!settingsCache.ContainsKey(key)) + { + // Doesn't contain setting, add it + return this.AddKey(key, newValue); + } + else + { + object value = settingsCache[key]; + + bool isDifferent; + if (newValue is IEnumerable enumerableNewValue && value is IEnumerable enumerableValue) + { + isDifferent = enumerableValue.Cast().SequenceEqual(enumerableNewValue.Cast()); + } + else + { + isDifferent = value != newValue; + } + + if (isDifferent) + { + // Values are different, update value and reload the cache + _cacheMisses++; + return base.UpdateKey(key, newValue); + } + else + { + // The cache does not need to be updated, continue + return false; + } + } + } + } +} diff --git a/Files/Models/JsonSettings/Implementation/DefaultJsonSettingsDatabase.cs b/Files/Models/JsonSettings/Implementation/DefaultJsonSettingsDatabase.cs new file mode 100644 index 000000000000..fd766ce2472d --- /dev/null +++ b/Files/Models/JsonSettings/Implementation/DefaultJsonSettingsDatabase.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using Files.Common; + +namespace Files.Models.JsonSettings.Implementation +{ + public class DefaultJsonSettingsDatabase : IJsonSettingsDatabase + { + protected Dictionary settingsCache; + + protected readonly IJsonSettingsSerializer jsonSettingsSerializer; + + protected readonly ISettingsSerializer settingsSerializer; + + public DefaultJsonSettingsDatabase(IJsonSettingsSerializer jsonSettingsSerializer, ISettingsSerializer settingsSerializer) + { + this.jsonSettingsSerializer = jsonSettingsSerializer; + this.settingsSerializer = settingsSerializer; + this.settingsCache = new Dictionary(); + } + + protected virtual Dictionary GetNewSettingsCache() + { + string settingsData = settingsSerializer.ReadFromFile(); + + return jsonSettingsSerializer.DeserializeFromJson>(settingsData) ?? new Dictionary(); + } + + protected virtual bool SaveSettingsCache() + { + string settingsData = jsonSettingsSerializer.SerializeToJson(this.settingsCache); + + return settingsSerializer.WriteToFile(settingsData); + } + + public virtual TValue GetValue(string key, TValue defaultValue = default) + { + var value = GetObjectValue(key, defaultValue); + if (value is Newtonsoft.Json.Linq.JToken jTokenValue) + { + return jTokenValue.ToObject(); + } + return (TValue)value; + } + + private object GetObjectValue(string key, object defaultValue = null) + { + this.settingsCache = GetNewSettingsCache(); + + if (settingsCache.ContainsKey(key)) + { + return settingsCache[key]; + } + else + { + AddKey(key, defaultValue); + return defaultValue; + } + } + + public virtual bool AddKey(string key, object value) + { + this.settingsCache = GetNewSettingsCache(); + + if (!this.settingsCache.ContainsKey(key)) + { + this.settingsCache.Add(key, value); + + return SaveSettingsCache(); + } + + return false; + } + + public virtual bool RemoveKey(string key) + { + this.settingsCache = GetNewSettingsCache(); + + if (this.settingsCache.ContainsKey(key)) + { + this.settingsCache.Remove(key); + + return SaveSettingsCache(); + } + + return false; + } + + public virtual bool UpdateKey(string key, object newValue) + { + this.settingsCache = GetNewSettingsCache(); + + if (!this.settingsCache.ContainsKey(key)) + { + return AddKey(key, newValue); + } + else + { + this.settingsCache[key] = newValue; + + return SaveSettingsCache(); + } + } + + public virtual bool ImportSettings(object import) + { + try + { + // Try convert + settingsCache = (Dictionary)import; + + // Serialize + string serialized = jsonSettingsSerializer.SerializeToJson(this.settingsCache); + + // Write to file + settingsSerializer.WriteToFile(serialized); + + return true; + } + catch (Exception ex) + { + Debug.WriteLine(ex); + Debugger.Break(); + + return false; + } + } + + public virtual bool FlushSettings() + { + try + { + // Serialize + string serialized = jsonSettingsSerializer.SerializeToJson(this.settingsCache); + + // Write to file + settingsSerializer.WriteToFile(serialized); + + return true; + } + catch (Exception ex) + { + Debug.WriteLine(ex); + Debugger.Break(); + + return false; + } + } + + public virtual object ExportSettings() + { + settingsCache = GetNewSettingsCache(); + + return settingsCache; + } + } +} diff --git a/Files/Models/JsonSettings/Implementation/DefaultJsonSettingsSerializer.cs b/Files/Models/JsonSettings/Implementation/DefaultJsonSettingsSerializer.cs new file mode 100644 index 000000000000..f5c85ebbcbce --- /dev/null +++ b/Files/Models/JsonSettings/Implementation/DefaultJsonSettingsSerializer.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json; + +namespace Files.Models.JsonSettings.Implementation +{ + public sealed class DefaultJsonSettingsSerializer : IJsonSettingsSerializer + { + public T DeserializeFromJson(string json) + { + return JsonConvert.DeserializeObject(json); + } + + public string SerializeToJson(object obj) + { + return JsonConvert.SerializeObject(obj, Formatting.Indented); + } + } +} diff --git a/Files/Models/JsonSettings/Implementation/DefaultSettingsSerializer.cs b/Files/Models/JsonSettings/Implementation/DefaultSettingsSerializer.cs new file mode 100644 index 000000000000..f45d01373640 --- /dev/null +++ b/Files/Models/JsonSettings/Implementation/DefaultSettingsSerializer.cs @@ -0,0 +1,24 @@ +using Files.Helpers; + +namespace Files.Models.JsonSettings.Implementation +{ + public class DefaultSettingsSerializer : ISettingsSerializer + { + private readonly string _filePath; + + public DefaultSettingsSerializer(string filePath) + { + this._filePath = filePath; + } + + public string ReadFromFile() + { + return NativeFileOperationsHelper.ReadStringFromFile(_filePath); + } + + public bool WriteToFile(string json) + { + return NativeFileOperationsHelper.WriteStringToFile(_filePath, json); + } + } +} diff --git a/Files/Models/Settings/BaseJsonSettingsModel.cs b/Files/Models/Settings/BaseJsonSettingsModel.cs deleted file mode 100644 index 248da0c8d46e..000000000000 --- a/Files/Models/Settings/BaseJsonSettingsModel.cs +++ /dev/null @@ -1,212 +0,0 @@ -using Files.Helpers; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace Files.Models.Settings -{ - /// - /// Clipboard Canvas - /// A base class to easily manage all application's settings. - /// - public abstract class BaseJsonSettingsModel - { - #region Protected Members - - protected readonly string settingsPath; - - protected readonly bool isCachingEnabled; - - protected Dictionary settingsCache; - - #endregion Protected Members - - #region Constructor - - /// - public BaseJsonSettingsModel(string settingsPath) - : this(settingsPath, false) - { - } - - /// - /// Initializes new instance of and calls function. - /// - /// The path to settings file. - /// Determines whether settings should be cached. - /// Use is recommended when settings are accessed frequently to improve performance. - ///
- ///
- /// If true, settings won't be flushed until value and value is different. - ///
- /// If false, settings are always accessed and flushed upon read, write. - public BaseJsonSettingsModel(string settingsPath, bool isCachingEnabled) - { - this.settingsPath = settingsPath; - this.isCachingEnabled = isCachingEnabled; - - // Create new instance of the cache - this.settingsCache = new Dictionary(); - - Initialize(); - } - - #endregion Constructor - - #region Helpers - - protected virtual void Initialize() - { - // Create the file - using var _ = NativeFileOperationsHelper.CreateFileForWrite(settingsPath, false); - } - - public virtual object ExportSettings() - { - return settingsCache; - } - - public virtual void ImportSettings(object import) - { - try - { - // Try convert - settingsCache = (Dictionary)import; - - // Serialize - string serialized = JsonConvert.SerializeObject(settingsCache, Formatting.Indented); - - // Write to file - NativeFileOperationsHelper.WriteStringToFile(settingsPath, serialized); - } - catch (Exception ex) - { - Debug.WriteLine(ex); - Debugger.Break(); - } - } - - #endregion Helpers - - #region Get, Set - - protected virtual TValue Get(TValue defaultValue, [CallerMemberName] string propertyName = "") - { - return Get(() => defaultValue, propertyName); - } - - protected virtual TValue Get(Func defaultValueFactory, [CallerMemberName] string propertyName = "") - { - try - { - // Check if caching is enabled - if (isCachingEnabled) - { - // If the cache contains the setting... - if (settingsCache.ContainsKey(propertyName)) - { - TValue settingValue; - - // Get the object - object settingObject = settingsCache[propertyName]; - - // Check if it's a JToken object - if (settingObject is JToken jtoken) - { - // Get the value from JToken - settingValue = jtoken.ToObject(); - settingsCache[propertyName] = settingValue; - } - else - { - // Otherwise, it is TValue, get the value - settingValue = (TValue)settingObject; - } - - // Return the setting and exit this function - return settingValue; - } - - // Cache miss, the cache doesn't contain the setting, continue, to update the cache - } - - // Read all settings from file - string settingsData = NativeFileOperationsHelper.ReadStringFromFile(settingsPath); - - // If there are existing settings... - if (!string.IsNullOrEmpty(settingsData)) - { - // Deserialize them and update the cache - settingsCache = JsonConvert.DeserializeObject>(settingsData); - } - - // If it doesn't have this setting... - if (!settingsCache.ContainsKey(propertyName)) - { - // Add it to cache - settingsCache.Add(propertyName, defaultValueFactory()); - - // Serialize with updated value - string serialized = JsonConvert.SerializeObject(settingsCache, Formatting.Indented); - - // Write to file - NativeFileOperationsHelper.WriteStringToFile(settingsPath, serialized); - } - - // Get the value object - object valueObject = settingsCache[propertyName]; - if (valueObject is JToken jtoken2) - { - var settingValue = jtoken2.ToObject(); - settingsCache[propertyName] = settingValue; - return settingValue; - } - - return (TValue)valueObject; - } - catch (Exception ex) - { - App.Logger.Warn(ex, $"Error loading json setting: {propertyName}"); - return defaultValueFactory(); - } - } - - protected virtual bool Set(TValue value, [CallerMemberName] string propertyName = "") - { - try - { - // If cache doesn't contain the setting... - if (!settingsCache.ContainsKey(propertyName)) - { - // Add the setting - settingsCache.Add(propertyName, value); - } - else - { - // Otherwise, update the setting's value - settingsCache[propertyName] = value; - } - - // Serialize - string serialized = JsonConvert.SerializeObject(settingsCache, Formatting.Indented); - - // Write to file - NativeFileOperationsHelper.WriteStringToFile(settingsPath, serialized); - - return true; - } - catch (Exception ex) - { - Debug.WriteLine(ex); - Debugger.Break(); - - return false; - } - } - - #endregion Get, Set - } -} \ No newline at end of file diff --git a/Files/Services/IAppearanceSettingsService.cs b/Files/Services/IAppearanceSettingsService.cs new file mode 100644 index 000000000000..3e2a2c65f659 --- /dev/null +++ b/Files/Services/IAppearanceSettingsService.cs @@ -0,0 +1,10 @@ +namespace Files.Services +{ + public interface IAppearanceSettingsService + { + /// + /// Gets or sets a value indicating whether or not to move overflow menu items into a sub menu. + /// + bool MoveOverflowMenuItemsToSubMenu { get; set; } + } +} diff --git a/Files/SettingsInterfaces/IBundlesSettings.cs b/Files/Services/IBundlesSettingsService.cs similarity index 51% rename from Files/SettingsInterfaces/IBundlesSettings.cs rename to Files/Services/IBundlesSettingsService.cs index 09f7285b43b8..3fb8dc0328d3 100644 --- a/Files/SettingsInterfaces/IBundlesSettings.cs +++ b/Files/Services/IBundlesSettingsService.cs @@ -1,13 +1,15 @@ using System.Collections.Generic; -namespace Files.SettingsInterfaces +namespace Files.Services { - public interface IBundlesSettings + public interface IBundlesSettingsService { - Dictionary> SavedBundles { get; set; } + bool FlushSettings(); object ExportSettings(); - void ImportSettings(object import); + bool ImportSettings(object import); + + Dictionary> SavedBundles { get; set; } } -} \ No newline at end of file +} diff --git a/Files/Services/IFileTagsSettingsService.cs b/Files/Services/IFileTagsSettingsService.cs new file mode 100644 index 000000000000..1b9840ffe381 --- /dev/null +++ b/Files/Services/IFileTagsSettingsService.cs @@ -0,0 +1,14 @@ +using Files.Filesystem; +using System.Collections.Generic; + +namespace Files.Services +{ + public interface IFileTagsSettingsService + { + IList FileTagList { get; set; } + + FileTag GetTagById(string uid); + + IEnumerable GetTagsByName(string tagName); + } +} diff --git a/Files/Services/IFilesAndFoldersSettingsService.cs b/Files/Services/IFilesAndFoldersSettingsService.cs new file mode 100644 index 000000000000..a2aa415b5e44 --- /dev/null +++ b/Files/Services/IFilesAndFoldersSettingsService.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Files.Services +{ + public interface IFilesAndFoldersSettingsService + { + /// + /// Gets or sets a value indicating whether or not file extensions should be visible. + /// + bool ShowFileExtensions { get; set; } + + /// + /// Gets or sets a value indicating whether or not hidden items should be visible. + /// + bool AreHiddenItemsVisible { get; set; } + + /// + /// Gets or sets a value indicating whether or not system items should be visible. + /// + bool AreSystemItemsHidden { get; set; } + + /// + /// Gets or sets a value indicating whether or not files should be sorted together with folders. + /// + bool ListAndSortDirectoriesAlongsideFiles { get; set; } + + /// + /// Gets or sets a value indicating whether or not items should open with one click. + /// + bool OpenItemsWithOneclick { get; set; } + + /// + /// Gets or sets a value indicating whether or not to search unindexed items. + /// + bool SearchUnindexedItems { get; set; } + + /// + /// Enables saving a unique layout mode, gridview size and sort direction per folder + /// + bool AreLayoutPreferencesPerFolder { get; set; } + + /// + /// Enables adaptive layout that adjusts layout mode based on the context of the directory + /// + bool AdaptiveLayoutEnabled { get; set; } + + /// + /// Gets or sets a value indicating whether or not to enable file tags feature. + /// + bool AreFileTagsEnabled { get; set; } + } +} diff --git a/Files/Services/ILayoutSettingsService.cs b/Files/Services/ILayoutSettingsService.cs new file mode 100644 index 000000000000..48a7e30761dc --- /dev/null +++ b/Files/Services/ILayoutSettingsService.cs @@ -0,0 +1,42 @@ +using Files.Enums; + +namespace Files.Services +{ + public interface ILayoutSettingsService + { + /// + /// Gets or sets a value indicating whether or not the date column should be visible. + /// + bool ShowDateColumn { get; set; } + + /// + /// Gets or sets a value indicating whether or not the date created column should be visible. + /// + bool ShowDateCreatedColumn { get; set; } + + /// + /// Gets or sets a value indicating whether or not the type column should be visible. + /// + bool ShowTypeColumn { get; set; } + + /// + /// Gets or sets a value indicating whether or not the size column should be visible. + /// + bool ShowSizeColumn { get; set; } + + /// + /// Gets or sets a value indicating whether or not the filetag column should be visible. + /// + bool ShowFileTagColumn { get; set; } + + int DefaultGridViewSize { get; set; } + + FolderLayoutModes DefaultLayoutMode { get; set; } + + SortDirection DefaultDirectorySortDirection { get; set; } + + SortOption DefaultDirectorySortOption { get; set; } + + GroupOption DefaultDirectoryGroupOption { get; set; } + } +} diff --git a/Files/Services/IMultitaskingSettingsService.cs b/Files/Services/IMultitaskingSettingsService.cs new file mode 100644 index 000000000000..e7cd77eea3d0 --- /dev/null +++ b/Files/Services/IMultitaskingSettingsService.cs @@ -0,0 +1,20 @@ +namespace Files.Services +{ + public interface IMultitaskingSettingsService + { + /// + /// Gets or sets a value indicating whether or not to enable the vertical tab flyout. + /// + bool IsVerticalTabFlyoutEnabled { get; set; } + + /// + /// Gets or sets a value indicating whether or not to enable dual pane feature. + /// + bool IsDualPaneEnabled { get; set; } + + /// + /// Gets or sets a value indicating whether or not to always open a second pane when opening a new tab. + /// + bool AlwaysOpenDualPaneInNewTab { get; set; } + } +} diff --git a/Files/Services/IPreferencesSettingsService.cs b/Files/Services/IPreferencesSettingsService.cs new file mode 100644 index 000000000000..96d989726d6f --- /dev/null +++ b/Files/Services/IPreferencesSettingsService.cs @@ -0,0 +1,15 @@ +namespace Files.Services +{ + public interface IPreferencesSettingsService + { + /// + /// Gets or sets a value indicating whether or not to show the delete confirmation dialog when deleting items. + /// + bool ShowConfirmDeleteDialog { get; set; } + + /// + /// Gets or sets a value indicating whether or not to open folders in new tab. + /// + bool OpenFoldersInNewTab { get; set; } + } +} diff --git a/Files/Services/IPreviewPaneSettingsService.cs b/Files/Services/IPreviewPaneSettingsService.cs new file mode 100644 index 000000000000..baa8baaff137 --- /dev/null +++ b/Files/Services/IPreviewPaneSettingsService.cs @@ -0,0 +1,30 @@ +namespace Files.Services +{ + public interface IPreviewPaneSettingsService + { + /// + /// Gets or sets a value indicating the default volume on media preview. + /// + double PreviewPaneMediaVolume { get; set; } + + /// + /// Gets or sets a value indicating the height of the preview pane in a horizontal layout. + /// + double PreviewPaneSizeHorizontalPx { get; set; } + + /// + /// Gets or sets a value indicating the width of the preview pane in a vertical layout. + /// + double PreviewPaneSizeVerticalPx { get; set; } + + /// + /// Gets or sets a value indicating if the preview pane should be open or closed. + /// + bool PreviewPaneEnabled { get; set; } + + /// + /// Gets or sets a value indicating if the preview pane should only show the item preview without the details section + /// + bool ShowPreviewOnly { get; set; } + } +} diff --git a/Files/Services/ISidebarSettingsService.cs b/Files/Services/ISidebarSettingsService.cs new file mode 100644 index 000000000000..da49d831cf7d --- /dev/null +++ b/Files/Services/ISidebarSettingsService.cs @@ -0,0 +1,54 @@ +namespace Files.Services +{ + public interface ISidebarSettingsService + { + #region Internal Settings + + /// + /// Gets or sets a value indicating the width of the sidebar pane when open. + /// + double SidebarWidth { get; set; } + + /// + /// Gets or sets a value indicating if the sidebar pane should be open or closed. + /// + bool IsSidebarOpen { get; set; } + + #endregion + + /// + /// Gets or sets a value indicating whether or not to show the Favorites section on the sidebar. + /// + bool ShowFavoritesSection { get; set; } + + /// + /// Gets or sets a value indicating whether or not to show the library section on the sidebar. + /// + bool ShowLibrarySection { get; set; } + + /// + /// Gets or sets a value indicating whether [show drives section]. + /// + bool ShowDrivesSection { get; set; } + + /// + /// Gets or sets a value indicating whether [show cloud drives section]. + /// + bool ShowCloudDrivesSection { get; set; } + + /// + /// Gets or sets a value indicating whether [show network drives section]. + /// + bool ShowNetworkDrivesSection { get; set; } + + /// + /// Gets or sets a value indicating whether [show wsl section]. + /// + bool ShowWslSection { get; set; } + + /// + /// Gets or sets a value indicating whether or not recycle bin should be pinned to the sidebar. + /// + bool PinRecycleBinToSidebar { get; set; } + } +} diff --git a/Files/Services/IStartupSettingsService.cs b/Files/Services/IStartupSettingsService.cs new file mode 100644 index 000000000000..85d2d7976552 --- /dev/null +++ b/Files/Services/IStartupSettingsService.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; + +namespace Files.Services +{ + public interface IStartupSettingsService + { + /// + /// Gets or sets a value indicating whether or not to navigate to a specific location when launching the app. + /// + bool OpenSpecificPageOnStartup { get; set; } + + /// + /// Gets or sets a value indicating the default startup location. + /// + string OpenSpecificPageOnStartupPath { get; set; } + + /// + /// Gets or sets a value indicating whether or not continue the last session whenever the app is launched. + /// + bool ContinueLastSessionOnStartUp { get; set; } + + /// + /// Gets or sets a value indicating whether or not to open a page when the app is launched. + /// + bool OpenNewTabOnStartup { get; set; } + + /// + /// Gets or sets a value indicating whether or not opening the app from the jumplist should open the directory in a new instance. + /// + bool AlwaysOpenNewInstance { get; set; } + + /// + /// A list containing all paths to open at startup. + /// + List TabsOnStartupList { get; set; } + + /// + /// A list containing all paths to tabs closed on last session. + /// + List LastSessionTabList { get; set; } + } +} diff --git a/Files/Services/IUserSettingsService.cs b/Files/Services/IUserSettingsService.cs new file mode 100644 index 000000000000..7f9981df409f --- /dev/null +++ b/Files/Services/IUserSettingsService.cs @@ -0,0 +1,31 @@ +using System; +using Files.EventArguments; +using Files.Models.JsonSettings; + +namespace Files.Services +{ + public interface IUserSettingsService + { + event EventHandler OnSettingChangedEvent; + + ISettingsSharingContext GetSharingContext(); + + IFilesAndFoldersSettingsService FilesAndFoldersSettingsService { get; } + + IMultitaskingSettingsService MultitaskingSettingsService { get; } + + IWidgetsSettingsService WidgetsSettingsService { get; } + + ISidebarSettingsService SidebarSettingsService { get; } + + IPreferencesSettingsService PreferencesSettingsService { get; } + + IAppearanceSettingsService AppearanceSettingsService { get; } + + IStartupSettingsService StartupSettingsService { get; } + + IPreviewPaneSettingsService PreviewPaneSettingsService { get; } + + ILayoutSettingsService LayoutSettingsService { get; } + } +} diff --git a/Files/Services/IWidgetsSettingsService.cs b/Files/Services/IWidgetsSettingsService.cs new file mode 100644 index 000000000000..dcb63aee4f0f --- /dev/null +++ b/Files/Services/IWidgetsSettingsService.cs @@ -0,0 +1,25 @@ +namespace Files.Services +{ + public interface IWidgetsSettingsService + { + /// + /// Gets or sets a value indicating whether or not the library cards widget should be visible. + /// + bool ShowFoldersWidget { get; set; } + + /// + /// Gets or sets a value indicating whether or not the recent files widget should be visible. + /// + bool ShowRecentFilesWidget { get; set; } + + /// + /// Gets or sets a value indicating whether or not the drives widget should be visible. + /// + bool ShowDrivesWidget { get; set; } + + /// + /// Gets or sets a value indicating whether or not the Bundles widget should be visible. + /// + bool ShowBundlesWidget { get; set; } + } +} diff --git a/Files/Services/Implementation/AppearanceSettingsService.cs b/Files/Services/Implementation/AppearanceSettingsService.cs new file mode 100644 index 000000000000..88ae8296aeee --- /dev/null +++ b/Files/Services/Implementation/AppearanceSettingsService.cs @@ -0,0 +1,31 @@ +using Files.Models.JsonSettings; + +namespace Files.Services.Implementation +{ + public class AppearanceSettingsService : BaseJsonSettingsModel, IAppearanceSettingsService + { + public AppearanceSettingsService(ISettingsSharingContext settingsSharingContext) + { + // Initialize settings + this.RegisterSettingsContext(settingsSharingContext); + } + + public override void RaiseOnSettingChangedEvent(object sender, EventArguments.SettingChangedEventArgs e) + { + switch (e.settingName) + { + case nameof(MoveOverflowMenuItemsToSubMenu): + Microsoft.AppCenter.Analytics.Analytics.TrackEvent($"{nameof(e.settingName)} {e.newValue}"); + break; + } + + base.RaiseOnSettingChangedEvent(sender, e); + } + + public bool MoveOverflowMenuItemsToSubMenu + { + get => Get(true); + set => Set(value); + } + } +} diff --git a/Files/Models/Settings/BundlesSettingsModel.cs b/Files/Services/Implementation/BundlesSettingsService.cs similarity index 51% rename from Files/Models/Settings/BundlesSettingsModel.cs rename to Files/Services/Implementation/BundlesSettingsService.cs index 278606db2579..7eb04e75ac21 100644 --- a/Files/Models/Settings/BundlesSettingsModel.cs +++ b/Files/Services/Implementation/BundlesSettingsService.cs @@ -1,49 +1,44 @@ -using Files.SettingsInterfaces; -using Newtonsoft.Json; +using Files.Models.JsonSettings; using System.Collections.Generic; using Windows.Storage; -namespace Files.Models.Settings +namespace Files.Services.Implementation { - public class BundlesSettingsModel : BaseJsonSettingsModel, IBundlesSettings + public sealed class BundlesSettingsService : BaseJsonSettingsModel, IBundlesSettingsService { - #region Constructor - - public BundlesSettingsModel() + public BundlesSettingsService() : base(System.IO.Path.Combine(ApplicationData.Current.LocalFolder.Path, Constants.LocalSettings.SettingsFolderName, Constants.LocalSettings.BundlesSettingsFileName), isCachingEnabled: true) { } - #endregion Constructor - - #region IBundlesSettings - public Dictionary> SavedBundles { - get => Get>>(() => null); + get => Get>>(null); set => Set(value); } - #endregion IBundlesSettings - - #region Override - - public override void ImportSettings(object import) + public override bool ImportSettings(object import) { try { SavedBundles = (Dictionary>)import; + + FlushSettings(); + + return true; + } + catch + { + // TODO: Display the error? + return false; } - catch { } } public override object ExportSettings() { // Return string in Json format - return JsonConvert.SerializeObject(SavedBundles, Formatting.Indented); + return jsonSettingsSerializer.SerializeToJson(SavedBundles); } - - #endregion Override } -} \ No newline at end of file +} diff --git a/Files/Services/Implementation/FileTagsSettingsService.cs b/Files/Services/Implementation/FileTagsSettingsService.cs new file mode 100644 index 000000000000..d4c7f71e1d63 --- /dev/null +++ b/Files/Services/Implementation/FileTagsSettingsService.cs @@ -0,0 +1,50 @@ +using Files.Filesystem; +using Files.Models.JsonSettings; +using Microsoft.Toolkit.Uwp; +using System; +using System.Collections.Generic; +using System.Linq; +using Windows.Storage; + +namespace Files.Services.Implementation +{ + public sealed class FileTagsSettingsService : BaseJsonSettingsModel, IFileTagsSettingsService + { + private static readonly List s_defaultFileTags = new List() + { + new FileTag("Blue", "#0072BD"), + new FileTag("Orange", "#D95319"), + new FileTag("Yellow", "#EDB120"), + new FileTag("Green", "#77AC30"), + new FileTag("Azure", "#4DBEEE") + }; + + public FileTagsSettingsService() + : base(System.IO.Path.Combine(ApplicationData.Current.LocalFolder.Path, Constants.LocalSettings.SettingsFolderName, Constants.LocalSettings.FileTagSettingsFileName), + isCachingEnabled: true) + { + } + + public IList FileTagList + { + get => Get>(s_defaultFileTags); + set => Set(value); + } + + public FileTag GetTagById(string uid) + { + var tag = FileTagList.SingleOrDefault(x => x.Uid == uid); + if (!string.IsNullOrEmpty(uid) && tag == null) + { + tag = new FileTag("FileTagUnknown".GetLocalized(), "#9ea3a1", uid); + FileTagList = FileTagList.Append(tag).ToList(); + } + return tag; + } + + public IEnumerable GetTagsByName(string tagName) + { + return FileTagList.Where(x => x.TagName.Equals(tagName, StringComparison.OrdinalIgnoreCase)); + } + } +} diff --git a/Files/Services/Implementation/FilesAndFoldersSettingsService.cs b/Files/Services/Implementation/FilesAndFoldersSettingsService.cs new file mode 100644 index 000000000000..a024482f16c0 --- /dev/null +++ b/Files/Services/Implementation/FilesAndFoldersSettingsService.cs @@ -0,0 +1,87 @@ +using Files.Models.JsonSettings; + +namespace Files.Services.Implementation +{ + public class FilesAndFoldersSettingsService : BaseJsonSettingsModel, IFilesAndFoldersSettingsService + { + public FilesAndFoldersSettingsService(ISettingsSharingContext settingsSharingContext) + { + // Initialize settings + this.RegisterSettingsContext(settingsSharingContext); + } + + public override void RaiseOnSettingChangedEvent(object sender, EventArguments.SettingChangedEventArgs e) + { + switch (e.settingName) + { + case nameof(ShowFileExtensions): + case nameof(AreHiddenItemsVisible): + case nameof(AreSystemItemsHidden): + case nameof(ListAndSortDirectoriesAlongsideFiles): + case nameof(OpenItemsWithOneclick): + case nameof(SearchUnindexedItems): + case nameof(AreLayoutPreferencesPerFolder): + case nameof(AdaptiveLayoutEnabled): + case nameof(AreFileTagsEnabled): + Microsoft.AppCenter.Analytics.Analytics.TrackEvent($"{nameof(e.settingName)} {e.newValue}"); + break; + } + + base.RaiseOnSettingChangedEvent(sender, e); + } + + public bool ShowFileExtensions + { + get => Get(true); + set => Set(value); + } + + public bool AreHiddenItemsVisible + { + get => Get(false); + set => Set(value); + } + + public bool AreSystemItemsHidden + { + get => Get(true); + set => Set(value); + } + + public bool ListAndSortDirectoriesAlongsideFiles + { + get => Get(false); + set => Set(value); + } + + public bool OpenItemsWithOneclick + { + get => Get(false); + set => Set(value); + } + + public bool SearchUnindexedItems + { + get => Get(false); + set => Set(value); + } + + public bool AreLayoutPreferencesPerFolder + { + get => Get(true); + set => Set(value); + } + + public bool AdaptiveLayoutEnabled + { + get => Get(true); + set => Set(value); + } + + public bool AreFileTagsEnabled + { + get => Get(false); + set => Set(value); + } + } +} diff --git a/Files/Services/Implementation/LayoutSettingsService.cs b/Files/Services/Implementation/LayoutSettingsService.cs new file mode 100644 index 000000000000..1c123c87022b --- /dev/null +++ b/Files/Services/Implementation/LayoutSettingsService.cs @@ -0,0 +1,79 @@ +using Files.Enums; +using Files.Models.JsonSettings; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Files.Services.Implementation +{ + public sealed class LayoutSettingsService : BaseJsonSettingsModel, ILayoutSettingsService + { + public LayoutSettingsService(ISettingsSharingContext settingsSharingContext) + { + // Initialize settings + this.RegisterSettingsContext(settingsSharingContext); + } + + public bool ShowDateColumn + { + get => Get(true); + set => Set(value); + } + + public bool ShowDateCreatedColumn + { + get => Get(false); + set => Set(value); + } + + public bool ShowTypeColumn + { + get => Get(true); + set => Set(value); + } + + public bool ShowSizeColumn + { + get => Get(true); + set => Set(value); + } + + public bool ShowFileTagColumn + { + get => Get(true); + set => Set(value); + } + + public int DefaultGridViewSize + { + get => (int)Get((long)Constants.Browser.GridViewBrowser.GridViewSizeSmall); + set => Set((long)value); + } + + public FolderLayoutModes DefaultLayoutMode + { + get => (FolderLayoutModes)Get((long)FolderLayoutModes.DetailsView); + set => Set((long)value); + } + + public SortDirection DefaultDirectorySortDirection + { + get => (SortDirection)Get((long)SortDirection.Ascending); + set => Set((long)value); + } + + public SortOption DefaultDirectorySortOption + { + get => (SortOption)Get((long)SortOption.Name); + set => Set((long)value); + } + + public GroupOption DefaultDirectoryGroupOption + { + get => (GroupOption)Get((long)GroupOption.None); + set => Set((long)value); + } + } +} diff --git a/Files/Services/Implementation/MultitaskingSettingsService.cs b/Files/Services/Implementation/MultitaskingSettingsService.cs new file mode 100644 index 000000000000..bbfc7cba4758 --- /dev/null +++ b/Files/Services/Implementation/MultitaskingSettingsService.cs @@ -0,0 +1,45 @@ +using Files.Models.JsonSettings; + +namespace Files.Services.Implementation +{ + public class MultitaskingSettingsService : BaseJsonSettingsModel, IMultitaskingSettingsService + { + public MultitaskingSettingsService(ISettingsSharingContext settingsSharingContext) + { + // Initialize settings + this.RegisterSettingsContext(settingsSharingContext); + } + + public override void RaiseOnSettingChangedEvent(object sender, EventArguments.SettingChangedEventArgs e) + { + switch (e.settingName) + { + case nameof(IsVerticalTabFlyoutEnabled): + case nameof(IsDualPaneEnabled): + case nameof(AlwaysOpenDualPaneInNewTab): + Microsoft.AppCenter.Analytics.Analytics.TrackEvent($"{nameof(e.settingName)} {e.newValue}"); + break; + } + + base.RaiseOnSettingChangedEvent(sender, e); + } + + public bool IsVerticalTabFlyoutEnabled + { + get => Get(true); + set => Set(value); + } + + public bool IsDualPaneEnabled + { + get => Get(false); + set => Set(value); + } + + public bool AlwaysOpenDualPaneInNewTab + { + get => Get(false); + set => Set(value); + } + } +} diff --git a/Files/Services/Implementation/PreferencesSettingsService.cs b/Files/Services/Implementation/PreferencesSettingsService.cs new file mode 100644 index 000000000000..09777c4cf891 --- /dev/null +++ b/Files/Services/Implementation/PreferencesSettingsService.cs @@ -0,0 +1,38 @@ +using Files.Models.JsonSettings; + +namespace Files.Services.Implementation +{ + public class PreferencesSettingsService : BaseJsonSettingsModel, IPreferencesSettingsService + { + public PreferencesSettingsService(ISettingsSharingContext settingsSharingContext) + { + // Initialize settings + this.RegisterSettingsContext(settingsSharingContext); + } + + public override void RaiseOnSettingChangedEvent(object sender, EventArguments.SettingChangedEventArgs e) + { + switch (e.settingName) + { + case nameof(ShowConfirmDeleteDialog): + case nameof(OpenFoldersInNewTab): + Microsoft.AppCenter.Analytics.Analytics.TrackEvent($"{nameof(e.settingName)} {e.newValue}"); + break; + } + + base.RaiseOnSettingChangedEvent(sender, e); + } + + public bool ShowConfirmDeleteDialog + { + get => Get(true); + set => Set(value); + } + + public bool OpenFoldersInNewTab + { + get => Get(false); + set => Set(value); + } + } +} diff --git a/Files/Services/Implementation/PreviewPaneSettingsService.cs b/Files/Services/Implementation/PreviewPaneSettingsService.cs new file mode 100644 index 000000000000..ca61a6c44ae1 --- /dev/null +++ b/Files/Services/Implementation/PreviewPaneSettingsService.cs @@ -0,0 +1,59 @@ +using System; +using Files.EventArguments; +using Files.Models.JsonSettings; + +namespace Files.Services.Implementation +{ + public class PreviewPaneSettingsService : BaseJsonSettingsModel, IPreviewPaneSettingsService + { + public PreviewPaneSettingsService(ISettingsSharingContext settingsSharingContext) + { + // Initialize settings + this.RegisterSettingsContext(settingsSharingContext); + } + + public override void RaiseOnSettingChangedEvent(object sender, SettingChangedEventArgs e) + { + switch (e.settingName) + { + case nameof(ShowPreviewOnly): + //case nameof(DisplayedTimeStyle): + //case nameof(ThemeHelper.RootTheme): + Microsoft.AppCenter.Analytics.Analytics.TrackEvent($"{nameof(e.settingName)} {e.newValue}"); + break; + } + + base.RaiseOnSettingChangedEvent(sender, e); + } + + public double PreviewPaneMediaVolume + { + get => Math.Min(Math.Max(Get(1.0d), 0.0d), 1.0d); + set => Set(value); + } + + public double PreviewPaneSizeHorizontalPx + { + get => Get(Math.Min(Math.Max(Get(300d), 50d), 600d)); + set => Set(value); + } + + public double PreviewPaneSizeVerticalPx + { + get => Get(Math.Min(Math.Max(Get(250d), 50d), 600d)); + set => Set(value); + } + + public bool PreviewPaneEnabled + { + get => Get(false); + set => Set(value); + } + + public bool ShowPreviewOnly + { + get => Get(false); + set => Set(value); + } + } +} diff --git a/Files/Services/Implementation/SidebarSettingsService.cs b/Files/Services/Implementation/SidebarSettingsService.cs new file mode 100644 index 000000000000..96aa2f8cd8f8 --- /dev/null +++ b/Files/Services/Implementation/SidebarSettingsService.cs @@ -0,0 +1,89 @@ +using System; +using Files.Models.JsonSettings; + +namespace Files.Services.Implementation +{ + public class SidebarSettingsService : BaseJsonSettingsModel, ISidebarSettingsService + { + public SidebarSettingsService(ISettingsSharingContext settingsSharingContext) + { + // Initialize settings + this.RegisterSettingsContext(settingsSharingContext); + } + + public override void RaiseOnSettingChangedEvent(object sender, EventArguments.SettingChangedEventArgs e) + { + switch (e.settingName) + { + case nameof(ShowFavoritesSection): + case nameof(ShowLibrarySection): + case nameof(ShowCloudDrivesSection): + case nameof(ShowNetworkDrivesSection): + case nameof(ShowWslSection): + case nameof(PinRecycleBinToSidebar): + Microsoft.AppCenter.Analytics.Analytics.TrackEvent($"{nameof(e.settingName)} {e.newValue}"); + break; + } + + base.RaiseOnSettingChangedEvent(sender, e); + } + + #region Internal Settings + + public double SidebarWidth + { + get => Get(Math.Min(Math.Max(Get(255d), Constants.UI.MinimumSidebarWidth), 500d)); + set => Set(value); + } + + public bool IsSidebarOpen + { + get => Get(true); + set => Set(value); + } + + #endregion + + public bool ShowFavoritesSection + { + get => Get(true); + set => Set(value); + } + + public bool ShowLibrarySection + { + get => Get(false); + set => Set(value); + } + + public bool ShowDrivesSection + { + get => Get(true); + set => Set(value); + } + + public bool ShowCloudDrivesSection + { + get => Get(true); + set => Set(value); + } + + public bool ShowNetworkDrivesSection + { + get => Get(true); + set => Set(value); + } + + public bool ShowWslSection + { + get => Get(true); + set => Set(value); + } + + public bool PinRecycleBinToSidebar + { + get => Get(true); + set => Set(value); + } + } +} diff --git a/Files/Services/Implementation/StartupSettingsService.cs b/Files/Services/Implementation/StartupSettingsService.cs new file mode 100644 index 000000000000..cf1ebaa6af5a --- /dev/null +++ b/Files/Services/Implementation/StartupSettingsService.cs @@ -0,0 +1,71 @@ +using Files.Models.JsonSettings; +using System.Collections.Generic; + +namespace Files.Services.Implementation +{ + public class StartupSettingsService : BaseJsonSettingsModel, IStartupSettingsService + { + public StartupSettingsService(ISettingsSharingContext settingsSharingContext) + { + // Initialize settings + this.RegisterSettingsContext(settingsSharingContext); + } + + public override void RaiseOnSettingChangedEvent(object sender, EventArguments.SettingChangedEventArgs e) + { + switch (e.settingName) + { + case nameof(OpenSpecificPageOnStartup): + case nameof(ContinueLastSessionOnStartUp): + case nameof(OpenNewTabOnStartup): + case nameof(AlwaysOpenNewInstance): + Microsoft.AppCenter.Analytics.Analytics.TrackEvent($"{nameof(e.settingName)} {e.newValue}"); + break; + } + + base.RaiseOnSettingChangedEvent(sender, e); + } + + public bool OpenSpecificPageOnStartup + { + get => Get(false); + set => Set(value); + } + + public string OpenSpecificPageOnStartupPath + { + get => Get(string.Empty); + set => Set(value); + } + + public bool ContinueLastSessionOnStartUp + { + get => Get(false); + set => Set(value); + } + + public bool OpenNewTabOnStartup + { + get => Get(true); + set => Set(value); + } + + public bool AlwaysOpenNewInstance + { + get => Get(false); + set => Set(value); + } + + public List TabsOnStartupList + { + get => Get>(null); + set => Set(value); + } + + public List LastSessionTabList + { + get => Get>(null); + set => Set(value); + } + } +} diff --git a/Files/Services/Implementation/UserSettingsService.cs b/Files/Services/Implementation/UserSettingsService.cs new file mode 100644 index 000000000000..a973ec4ae57e --- /dev/null +++ b/Files/Services/Implementation/UserSettingsService.cs @@ -0,0 +1,77 @@ +using Files.Models.JsonSettings; +using Microsoft.Toolkit.Mvvm.DependencyInjection; +using System.IO; +using Windows.Storage; + +namespace Files.Services.Implementation +{ + public class UserSettingsService : BaseJsonSettingsModel, IUserSettingsService + { + private IFilesAndFoldersSettingsService _FilesAndFoldersSettingsService; + public IFilesAndFoldersSettingsService FilesAndFoldersSettingsService + { + get => GetSettingsService(ref _FilesAndFoldersSettingsService); + } + + private IMultitaskingSettingsService _MultitaskingSettingsService; + public IMultitaskingSettingsService MultitaskingSettingsService + { + get => GetSettingsService(ref _MultitaskingSettingsService); + } + + private IWidgetsSettingsService _WidgetsSettingsService; + public IWidgetsSettingsService WidgetsSettingsService + { + get => GetSettingsService(ref _WidgetsSettingsService); + } + + private ISidebarSettingsService _SidebarSettingsService; + public ISidebarSettingsService SidebarSettingsService + { + get => GetSettingsService(ref _SidebarSettingsService); + } + + private IPreferencesSettingsService _PreferencesSettingsService; + public IPreferencesSettingsService PreferencesSettingsService + { + get => GetSettingsService(ref _PreferencesSettingsService); + } + + private IAppearanceSettingsService _AppearanceSettingsService; + public IAppearanceSettingsService AppearanceSettingsService + { + get => GetSettingsService(ref _AppearanceSettingsService); + } + + private IStartupSettingsService _StartupSettingsService; + public IStartupSettingsService StartupSettingsService + { + get => GetSettingsService(ref _StartupSettingsService); + } + + private IPreviewPaneSettingsService _PreviewPaneSettingsService; + public IPreviewPaneSettingsService PreviewPaneSettingsService + { + get => GetSettingsService(ref _PreviewPaneSettingsService); + } + + private ILayoutSettingsService _LayoutSettingsService; + public ILayoutSettingsService LayoutSettingsService + { + get => GetSettingsService(ref _LayoutSettingsService); + } + + public UserSettingsService() + : base(Path.Combine(ApplicationData.Current.LocalFolder.Path, Constants.LocalSettings.SettingsFolderName, Constants.LocalSettings.UserSettingsFileName), + isCachingEnabled: true) + { + } + + private TSettingsService GetSettingsService(ref TSettingsService settingsServiceMember) + where TSettingsService : class + { + settingsServiceMember ??= Ioc.Default.GetService(); + return settingsServiceMember; + } + } +} diff --git a/Files/Services/Implementation/WidgetsSettingsService.cs b/Files/Services/Implementation/WidgetsSettingsService.cs new file mode 100644 index 000000000000..9a00c7774fb2 --- /dev/null +++ b/Files/Services/Implementation/WidgetsSettingsService.cs @@ -0,0 +1,51 @@ +using Files.Models.JsonSettings; + +namespace Files.Services.Implementation +{ + public class WidgetsSettingsService : BaseJsonSettingsModel, IWidgetsSettingsService + { + public WidgetsSettingsService(ISettingsSharingContext settingsSharingContext) + { + // Initialize settings + this.RegisterSettingsContext(settingsSharingContext); + } + + public override void RaiseOnSettingChangedEvent(object sender, EventArguments.SettingChangedEventArgs e) + { + switch (e.settingName) + { + case nameof(ShowFoldersWidget): + case nameof(ShowRecentFilesWidget): + case nameof(ShowDrivesWidget): + case nameof(ShowBundlesWidget): + Microsoft.AppCenter.Analytics.Analytics.TrackEvent($"{nameof(e.settingName)} {e.newValue}"); + break; + } + base.RaiseOnSettingChangedEvent(sender, e); + } + + public bool ShowFoldersWidget + { + get => Get(true); + set => Set(value); + } + + public bool ShowRecentFilesWidget + { + get => Get(true); + set => Set(value); + } + + public bool ShowDrivesWidget + { + get => Get(true); + set => Set(value); + } + + public bool ShowBundlesWidget + { + get => Get(false); + set => Set(value); + } + } +} diff --git a/Files/UserControls/DataGridHeader.xaml.cs b/Files/UserControls/DataGridHeader.xaml.cs index 4e661e5190d1..0298552b1c44 100644 --- a/Files/UserControls/DataGridHeader.xaml.cs +++ b/Files/UserControls/DataGridHeader.xaml.cs @@ -1,4 +1,4 @@ -using Microsoft.Toolkit.Uwp.UI; +using Files.Enums; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows.Input; diff --git a/Files/UserControls/FilePreviews/MediaPreview.xaml.cs b/Files/UserControls/FilePreviews/MediaPreview.xaml.cs index 2e155dad2edd..d371a8169458 100644 --- a/Files/UserControls/FilePreviews/MediaPreview.xaml.cs +++ b/Files/UserControls/FilePreviews/MediaPreview.xaml.cs @@ -1,4 +1,6 @@ -using Files.ViewModels.Previews; +using Files.Services; +using Files.ViewModels.Previews; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Windows.Media.Playback; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -9,6 +11,8 @@ namespace Files.UserControls.FilePreviews { public sealed partial class MediaPreview : UserControl { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public MediaPreview(MediaPreviewViewModel model) { ViewModel = model; @@ -20,15 +24,15 @@ public MediaPreview(MediaPreviewViewModel model) private void PlayerContext_Loaded(object sender, RoutedEventArgs e) { - PlayerContext.MediaPlayer.Volume = App.AppSettings.MediaVolume; + PlayerContext.MediaPlayer.Volume = UserSettingsService.PreviewPaneSettingsService.PreviewPaneMediaVolume; PlayerContext.MediaPlayer.VolumeChanged += MediaPlayer_VolumeChanged; } private void MediaPlayer_VolumeChanged(MediaPlayer sender, object args) { - if (sender.Volume != App.AppSettings.MediaVolume) + if (sender.Volume != UserSettingsService.PreviewPaneSettingsService.PreviewPaneMediaVolume) { - App.AppSettings.MediaVolume = sender.Volume; + UserSettingsService.PreviewPaneSettingsService.PreviewPaneMediaVolume = sender.Volume; } } } diff --git a/Files/UserControls/InnerNavigationToolbar.xaml b/Files/UserControls/InnerNavigationToolbar.xaml index 49b9ea777b5b..4b84f3142896 100644 --- a/Files/UserControls/InnerNavigationToolbar.xaml +++ b/Files/UserControls/InnerNavigationToolbar.xaml @@ -343,7 +343,7 @@ x:Uid="NavToolbarArrangementOptionFileTag" IsChecked="{x:Bind ViewModel.IsSortedByFileTag, Mode=TwoWay}" Text="File tag" - Visibility="{x:Bind AppSettings.AreFileTagsEnabled, Mode=OneWay}" /> + Visibility="{x:Bind UserSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled, Mode=OneWay}" /> + Visibility="{x:Bind UserSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled, Mode=OneWay}" /> @@ -681,7 +681,7 @@ MinWidth="40" AccessKey="P" AutomationProperties.Name="Toggle preview pane" - IsChecked="{x:Bind AppSettings.PreviewPaneEnabled, Mode=TwoWay}" + IsChecked="{x:Bind UserSettingsService.PreviewPaneSettingsService.PreviewPaneEnabled, Mode=TwoWay}" IsEnabled="{x:Bind ShowPreviewPaneButton, Mode=OneWay}" Label="Preview" LabelPosition="Collapsed" diff --git a/Files/UserControls/InnerNavigationToolbar.xaml.cs b/Files/UserControls/InnerNavigationToolbar.xaml.cs index 19ceaffd89df..9c668ef1d470 100644 --- a/Files/UserControls/InnerNavigationToolbar.xaml.cs +++ b/Files/UserControls/InnerNavigationToolbar.xaml.cs @@ -1,6 +1,8 @@ using Files.DataModels; using Files.Helpers; +using Files.Services; using Files.ViewModels; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Generic; @@ -22,8 +24,10 @@ public InnerNavigationToolbar() this.InitializeComponent(); } + public IUserSettingsService UserSettingsService { get; } = + Ioc.Default.GetService(); + public MainViewModel MainViewModel => App.MainViewModel; - public SettingsViewModel AppSettings => App.AppSettings; public NavToolbarViewModel ViewModel { diff --git a/Files/UserControls/MenuFlyoutItemFileTag.xaml.cs b/Files/UserControls/MenuFlyoutItemFileTag.xaml.cs index 685f308ed436..7ba38d088a68 100644 --- a/Files/UserControls/MenuFlyoutItemFileTag.xaml.cs +++ b/Files/UserControls/MenuFlyoutItemFileTag.xaml.cs @@ -1,4 +1,6 @@ using Files.Filesystem; +using Files.Services; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using System; using System.Collections.Generic; using System.Linq; @@ -9,6 +11,8 @@ namespace Files.UserControls { public sealed partial class MenuFlyoutItemFileTag : UserControl { + private IFileTagsSettingsService FileTagsSettingsService { get; } = Ioc.Default.GetService(); + public List SelectedItems { get { return (List)GetValue(SelectedItemsProperty); } @@ -66,12 +70,12 @@ public FileTag GetFileTag(List selectedItems) } else if (selectedItems.Count == 1) { - return App.AppSettings.FileTagsSettings.GetTagByID(selectedItems.First().FileTag); + return FileTagsSettingsService.GetTagById(selectedItems.First().FileTag); } else { var tag = selectedItems.First().FileTag; - return selectedItems.All(x => x.FileTag == tag) ? App.AppSettings.FileTagsSettings.GetTagByID(tag) : null; + return selectedItems.All(x => x.FileTag == tag) ? FileTagsSettingsService.GetTagById(tag) : null; } } diff --git a/Files/UserControls/PreviewPane.xaml b/Files/UserControls/PreviewPane.xaml index a9498db50621..ea018c50c511 100644 --- a/Files/UserControls/PreviewPane.xaml +++ b/Files/UserControls/PreviewPane.xaml @@ -59,7 +59,7 @@ - + - + diff --git a/Files/UserControls/PreviewPane.xaml.cs b/Files/UserControls/PreviewPane.xaml.cs index 19e2dfc0831f..451eb1febc8e 100644 --- a/Files/UserControls/PreviewPane.xaml.cs +++ b/Files/UserControls/PreviewPane.xaml.cs @@ -1,4 +1,6 @@ -using Files.ViewModels; +using Files.Services; +using Files.ViewModels; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -10,7 +12,7 @@ namespace Files.UserControls { public sealed partial class PreviewPane : UserControl { - public SettingsViewModel AppSettings => App.AppSettings; + public IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); public PreviewPaneViewModel Model { diff --git a/Files/UserControls/SidebarControl.xaml b/Files/UserControls/SidebarControl.xaml index 9be22938da93..477aa6989536 100644 --- a/Files/UserControls/SidebarControl.xaml +++ b/Files/UserControls/SidebarControl.xaml @@ -16,7 +16,7 @@ IsTitleBarAutoPaddingEnabled="False" ItemInvoked="Sidebar_ItemInvoked" MenuItemsSource="{x:Bind local:SidebarControl.SideBarItems, Mode=OneWay}" - OpenPaneLength="{x:Bind AppSettings.SidebarWidth.Value, Mode=OneTime}" + OpenPaneLength="{x:Bind UserSettingsService.SidebarSettingsService.SidebarWidth, Mode=OneTime}" SelectedItem="{x:Bind SelectedSidebarItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" mc:Ignorable="d"> diff --git a/Files/UserControls/SidebarControl.xaml.cs b/Files/UserControls/SidebarControl.xaml.cs index 5c6510d969de..6d72334ae51d 100644 --- a/Files/UserControls/SidebarControl.xaml.cs +++ b/Files/UserControls/SidebarControl.xaml.cs @@ -5,7 +5,9 @@ using Files.Filesystem.StorageItems; using Files.Helpers; using Files.Helpers.ContextFlyouts; +using Files.Services; using Files.ViewModels; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using Microsoft.Toolkit.Uwp.UI; @@ -30,6 +32,8 @@ namespace Files.UserControls { public sealed partial class SidebarControl : Microsoft.UI.Xaml.Controls.NavigationView, INotifyPropertyChanged { + public IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public static SemaphoreSlim SideBarItemsSemaphore = new SemaphoreSlim(1, 1); public static BulkConcurrentObservableCollection SideBarItems { get; private set; } = new BulkConcurrentObservableCollection(); @@ -150,41 +154,41 @@ public void HideSection_Click(object sender, RoutedEventArgs e) { if ("SidebarFavorites".GetLocalized().Equals(RightClickedItem.Text)) { - AppSettings.ShowFavoritesSection = false; + UserSettingsService.SidebarSettingsService.ShowFavoritesSection = false; App.SidebarPinnedController.Model.UpdateFavoritesSectionVisibility(); } else if ("SidebarLibraries".GetLocalized().Equals(RightClickedItem.Text)) { - AppSettings.ShowLibrarySection = false; + UserSettingsService.SidebarSettingsService.ShowLibrarySection = false; App.LibraryManager.UpdateLibrariesSectionVisibility(); } else if ("SidebarCloudDrives".GetLocalized().Equals(RightClickedItem.Text)) { - AppSettings.ShowCloudDrivesSection = false; + UserSettingsService.SidebarSettingsService.ShowCloudDrivesSection = false; App.CloudDrivesManager.UpdateCloudDrivesSectionVisibility(); } else if ("SidebarDrives".GetLocalized().Equals(RightClickedItem.Text)) { - AppSettings.ShowDrivesSection = false; + UserSettingsService.SidebarSettingsService.ShowDrivesSection = false; App.DrivesManager.UpdateDrivesSectionVisibility(); } else if ("SidebarNetworkDrives".GetLocalized().Equals(RightClickedItem.Text)) { - AppSettings.ShowNetworkDrivesSection = false; + UserSettingsService.SidebarSettingsService.ShowNetworkDrivesSection = false; App.NetworkDrivesManager.UpdateNetworkDrivesSectionVisibility(); } else if ("WSL".GetLocalized().Equals(RightClickedItem.Text)) { - AppSettings.ShowWslSection = false; + UserSettingsService.SidebarSettingsService.ShowWslSection = false; App.WSLDistroManager.UpdateWslSectionVisibility(); } } public void UnpinItem_Click(object sender, RoutedEventArgs e) { - if (string.Equals(AppSettings.RecycleBinPath, RightClickedItem.Path, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(CommonPaths.RecycleBinPath, RightClickedItem.Path, StringComparison.OrdinalIgnoreCase)) { - AppSettings.PinRecycleBinToSideBar = false; + UserSettingsService.SidebarSettingsService.PinRecycleBinToSidebar = false; } else if (RightClickedItem.Section == SectionType.Favorites) { @@ -362,7 +366,7 @@ private void NavigationViewLocationItem_RightTapped(object sender, RightTappedRo ShowProperties = false; } - if (string.Equals(item.Path, AppSettings.RecycleBinPath, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(item.Path, CommonPaths.RecycleBinPath, StringComparison.OrdinalIgnoreCase)) { ShowEmptyRecycleBin = true; ShowUnpinItem = true; @@ -377,7 +381,7 @@ private void NavigationViewLocationItem_RightTapped(object sender, RightTappedRo var menuItems = GetLocationItemMenuItems(); var (_, secondaryElements) = ItemModelListToContextFlyoutHelper.GetAppBarItemsFromModel(menuItems); - if (!App.AppSettings.MoveOverflowMenuItemsToSubMenu) + if (!UserSettingsService.AppearanceSettingsService.MoveOverflowMenuItemsToSubMenu) { secondaryElements.OfType().ForEach(i => i.MinWidth = 250); // Set menu min width if the overflow menu setting is disabled } @@ -429,7 +433,7 @@ private void NavigationViewDriveItem_RightTapped(object sender, RightTappedRoute var menuItems = GetLocationItemMenuItems(); var (_, secondaryElements) = ItemModelListToContextFlyoutHelper.GetAppBarItemsFromModel(menuItems); - if (!App.AppSettings.MoveOverflowMenuItemsToSubMenu) + if (!UserSettingsService.AppearanceSettingsService.MoveOverflowMenuItemsToSubMenu) { secondaryElements.OfType().ForEach(i => i.MinWidth = 250); // Set menu min width if the overflow menu setting is disabled } @@ -611,7 +615,7 @@ private async void NavigationViewLocationItem_DragOver(object sender, DragEventA } else if (handledByFtp) { - if (locationItem.Path.StartsWith(App.AppSettings.RecycleBinPath)) + if (locationItem.Path.StartsWith(CommonPaths.RecycleBinPath)) { e.AcceptedOperation = DataPackageOperation.None; } @@ -629,7 +633,7 @@ private async void NavigationViewLocationItem_DragOver(object sender, DragEventA else { e.DragUIOverride.IsCaptionVisible = true; - if (locationItem.Path.StartsWith(App.AppSettings.RecycleBinPath)) + if (locationItem.Path.StartsWith(CommonPaths.RecycleBinPath)) { e.DragUIOverride.Caption = string.Format("MoveToFolderCaptionText".GetLocalized(), locationItem.Text); e.AcceptedOperation = DataPackageOperation.Move; @@ -858,7 +862,7 @@ private void Border_KeyDown(object sender, KeyRoutedEventArgs e) { var step = 1; var ctrl = Window.Current.CoreWindow.GetKeyState(VirtualKey.Control); - originalSize = IsPaneOpen ? AppSettings.SidebarWidth.Value : CompactPaneLength; + originalSize = IsPaneOpen ? UserSettingsService.SidebarSettingsService.SidebarWidth : CompactPaneLength; if (ctrl.HasFlag(CoreVirtualKeyStates.Down)) { @@ -890,7 +894,7 @@ private void Border_KeyDown(object sender, KeyRoutedEventArgs e) return; } - App.AppSettings.SidebarWidth = new GridLength(OpenPaneLength); + UserSettingsService.SidebarSettingsService.SidebarWidth = OpenPaneLength; } /// @@ -958,7 +962,7 @@ private void ResizeElementBorder_ManipulationCompleted(object sender, Manipulati { Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 0); VisualStateManager.GoToState((sender as Grid).FindAscendant(), "ResizerNormal", true); - App.AppSettings.SidebarWidth = new GridLength(OpenPaneLength); + UserSettingsService.SidebarSettingsService.SidebarWidth = OpenPaneLength; dragging = false; } @@ -980,7 +984,7 @@ private void ResizeElementBorder_ManipulationStarted(object sender, Manipulation { if (DisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded) { - originalSize = IsPaneOpen ? AppSettings.SidebarWidth.Value : CompactPaneLength; + originalSize = IsPaneOpen ? UserSettingsService.SidebarSettingsService.SidebarWidth : CompactPaneLength; Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.SizeWestEast, 0); VisualStateManager.GoToState((sender as Grid).FindAscendant(), "ResizerPressed", true); dragging = true; @@ -1023,7 +1027,7 @@ private async void LoadShellMenuItems(Microsoft.UI.Xaml.Controls.CommandBarFlyou var shiftPressed = Window.Current.CoreWindow.GetKeyState(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down); var shellMenuItems = await ContextFlyoutItemHelper.GetItemContextShellCommandsAsync(connection: await AppServiceConnectionHelper.Instance, currentInstanceViewModel: null, workingDir: null, new List() { new ListedItem(null) { ItemPath = RightClickedItem.Path } }, shiftPressed: shiftPressed, showOpenMenu: false); - if (!App.AppSettings.MoveOverflowMenuItemsToSubMenu) + if (!UserSettingsService.AppearanceSettingsService.MoveOverflowMenuItemsToSubMenu) { var (_, secondaryElements) = ItemModelListToContextFlyoutHelper.GetAppBarItemsFromModel(shellMenuItems); if (secondaryElements.Any()) diff --git a/Files/UserControls/Widgets/BundlesWidget.xaml.cs b/Files/UserControls/Widgets/BundlesWidget.xaml.cs index 9096d5a5bf95..1512045fba81 100644 --- a/Files/UserControls/Widgets/BundlesWidget.xaml.cs +++ b/Files/UserControls/Widgets/BundlesWidget.xaml.cs @@ -1,5 +1,7 @@ -using Files.ViewModels.Widgets; +using Files.Services; +using Files.ViewModels.Widgets; using Files.ViewModels.Widgets.Bundles; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using Windows.UI.Xaml.Controls; @@ -10,6 +12,8 @@ namespace Files.UserControls.Widgets { public sealed partial class BundlesWidget : UserControl, IWidgetItemModel, IDisposable { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public BundlesViewModel ViewModel { get => (BundlesViewModel)DataContext; @@ -20,7 +24,7 @@ public BundlesViewModel ViewModel public string AutomationProperties => "BundlesWidgetAutomationProperties/Name".GetLocalized(); - public bool IsWidgetSettingEnabled => App.AppSettings.ShowBundlesWidget; + public bool IsWidgetSettingEnabled => UserSettingsService.WidgetsSettingsService.ShowBundlesWidget; public BundlesWidget() { diff --git a/Files/UserControls/Widgets/DrivesWidget.xaml.cs b/Files/UserControls/Widgets/DrivesWidget.xaml.cs index c630ab786c24..c86e96d43f8b 100644 --- a/Files/UserControls/Widgets/DrivesWidget.xaml.cs +++ b/Files/UserControls/Widgets/DrivesWidget.xaml.cs @@ -1,8 +1,10 @@ using Files.DataModels.NavigationControlItems; using Files.Filesystem; using Files.Helpers; +using Files.Services; using Files.ViewModels; using Files.ViewModels.Widgets; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.ObjectModel; @@ -21,6 +23,8 @@ namespace Files.UserControls.Widgets { public sealed partial class DrivesWidget : UserControl, IWidgetItemModel, INotifyPropertyChanged { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public SettingsViewModel AppSettings => App.AppSettings; public delegate void DrivesWidgetInvokedEventHandler(object sender, DrivesWidgetInvokedEventArgs e); @@ -54,7 +58,7 @@ public IShellPage AppInstance public string AutomationProperties => "DrivesWidgetAutomationProperties/Name".GetLocalized(); - public bool IsWidgetSettingEnabled => App.AppSettings.ShowDrivesWidget; + public bool IsWidgetSettingEnabled => UserSettingsService.WidgetsSettingsService.ShowDrivesWidget; public DrivesWidget() { diff --git a/Files/UserControls/Widgets/FolderWidget.xaml.cs b/Files/UserControls/Widgets/FolderWidget.xaml.cs index 63ff6bd45414..bf5b6959546f 100644 --- a/Files/UserControls/Widgets/FolderWidget.xaml.cs +++ b/Files/UserControls/Widgets/FolderWidget.xaml.cs @@ -1,8 +1,10 @@ using Files.Filesystem; using Files.Helpers; +using Files.Services; using Files.ViewModels; using Files.ViewModels.Widgets; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using System; @@ -55,6 +57,8 @@ public BitmapImage Icon public sealed partial class FolderWidget : UserControl, IWidgetItemModel, INotifyPropertyChanged { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public BulkConcurrentObservableCollection ItemsAdded = new BulkConcurrentObservableCollection(); private bool showMultiPaneControls; @@ -82,9 +86,7 @@ public FolderWidget() public event PropertyChangedEventHandler PropertyChanged; - public SettingsViewModel AppSettings => App.AppSettings; - - public bool IsWidgetSettingEnabled => App.AppSettings.ShowFolderWidgetWidget; + public bool IsWidgetSettingEnabled => UserSettingsService.WidgetsSettingsService.ShowFoldersWidget; public RelayCommand LibraryCardClicked => new RelayCommand(async (item) => { diff --git a/Files/UserControls/Widgets/RecentFilesWidget.xaml.cs b/Files/UserControls/Widgets/RecentFilesWidget.xaml.cs index 9944bd84dca7..a9daef2a3d97 100644 --- a/Files/UserControls/Widgets/RecentFilesWidget.xaml.cs +++ b/Files/UserControls/Widgets/RecentFilesWidget.xaml.cs @@ -1,8 +1,10 @@ using Files.Enums; using Files.Filesystem; using Files.Filesystem.StorageItems; +using Files.Services; using Files.ViewModels; using Files.ViewModels.Widgets; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.ObjectModel; @@ -20,6 +22,8 @@ namespace Files.UserControls.Widgets { public sealed partial class RecentFilesWidget : UserControl, IWidgetItemModel { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public delegate void RecentFilesOpenLocationInvokedEventHandler(object sender, PathNavigationEventArgs e); public event RecentFilesOpenLocationInvokedEventHandler RecentFilesOpenLocationInvoked; @@ -36,7 +40,7 @@ public sealed partial class RecentFilesWidget : UserControl, IWidgetItemModel public string AutomationProperties => "RecentFilesWidgetAutomationProperties/Name".GetLocalized(); - public bool IsWidgetSettingEnabled => App.AppSettings.ShowRecentFilesWidget; + public bool IsWidgetSettingEnabled => UserSettingsService.WidgetsSettingsService.ShowRecentFilesWidget; public RecentFilesWidget() { diff --git a/Files/ViewModels/FolderSettingsViewModel.cs b/Files/ViewModels/FolderSettingsViewModel.cs index 3786181a99e0..1b563169713c 100644 --- a/Files/ViewModels/FolderSettingsViewModel.cs +++ b/Files/ViewModels/FolderSettingsViewModel.cs @@ -1,10 +1,11 @@ using Files.Enums; using Files.EventArguments; using Files.Helpers; +using Files.Services; using Files.Views.LayoutModes; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; -using Microsoft.Toolkit.Uwp.UI; using Newtonsoft.Json; using System; using System.Linq; @@ -19,6 +20,8 @@ public class FolderSettingsViewModel : ObservableObject public event EventHandler LayoutPreferencesUpdateRequired; + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public FolderSettingsViewModel() { this.LayoutPreference = new LayoutPreferences(); @@ -167,7 +170,7 @@ public void SwitchAdaptiveLayout(bool enable) public RelayCommand ToggleLayoutModeGridViewLarge => new RelayCommand((manuallySet) => { - if (App.AppSettings.AreLayoutPreferencesPerFolder && App.AppSettings.AdaptiveLayoutEnabled) + if (UserSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder && UserSettingsService.FilesAndFoldersSettingsService.AdaptiveLayoutEnabled) { if (LastLayoutModeSelected == FolderLayout.GridViewLarge && LayoutPreference.IsAdaptiveLayoutOverridden) { @@ -196,7 +199,7 @@ public void SwitchAdaptiveLayout(bool enable) public RelayCommand ToggleLayoutModeColumnView => new RelayCommand((manuallySet) => { - if (App.AppSettings.AreLayoutPreferencesPerFolder && App.AppSettings.AdaptiveLayoutEnabled) + if (UserSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder && UserSettingsService.FilesAndFoldersSettingsService.AdaptiveLayoutEnabled) { if (LastLayoutModeSelected == FolderLayout.ColumnView) { @@ -218,7 +221,7 @@ public void SwitchAdaptiveLayout(bool enable) public RelayCommand ToggleLayoutModeGridViewMedium => new RelayCommand((manuallySet) => { - if (App.AppSettings.AreLayoutPreferencesPerFolder && App.AppSettings.AdaptiveLayoutEnabled) + if (UserSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder && UserSettingsService.FilesAndFoldersSettingsService.AdaptiveLayoutEnabled) { if (LastLayoutModeSelected == FolderLayout.GridViewMedium && LayoutPreference.IsAdaptiveLayoutOverridden) { @@ -247,7 +250,7 @@ public void SwitchAdaptiveLayout(bool enable) public RelayCommand ToggleLayoutModeGridViewSmall => new RelayCommand((manuallySet) => { - if (App.AppSettings.AreLayoutPreferencesPerFolder && App.AppSettings.AdaptiveLayoutEnabled) + if (UserSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder && UserSettingsService.FilesAndFoldersSettingsService.AdaptiveLayoutEnabled) { if (LastLayoutModeSelected == FolderLayout.GridViewSmall && LayoutPreference.IsAdaptiveLayoutOverridden) { @@ -289,7 +292,7 @@ public void SwitchAdaptiveLayout(bool enable) public RelayCommand ToggleLayoutModeTiles => new RelayCommand((manuallySet) => { - if (App.AppSettings.AreLayoutPreferencesPerFolder && App.AppSettings.AdaptiveLayoutEnabled) + if (UserSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder && UserSettingsService.FilesAndFoldersSettingsService.AdaptiveLayoutEnabled) { if (LastLayoutModeSelected == FolderLayout.TilesView && LayoutPreference.IsAdaptiveLayoutOverridden) { @@ -312,7 +315,7 @@ public void SwitchAdaptiveLayout(bool enable) public RelayCommand ToggleLayoutModeDetailsView => new RelayCommand((manuallySet) => { - if (App.AppSettings.AreLayoutPreferencesPerFolder && App.AppSettings.AdaptiveLayoutEnabled) + if (UserSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder && UserSettingsService.FilesAndFoldersSettingsService.AdaptiveLayoutEnabled) { if (LastLayoutModeSelected == FolderLayout.DetailsView && LayoutPreference.IsAdaptiveLayoutOverridden) { @@ -484,7 +487,8 @@ public ColumnsViewModel ColumnsViewModel public static LayoutPreferences GetLayoutPreferencesForPath(string folderPath) { - if (App.AppSettings.AreLayoutPreferencesPerFolder) + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + if (userSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder) { var layoutPrefs = ReadLayoutPreferencesFromAds(folderPath.TrimEnd('\\')); return layoutPrefs ?? ReadLayoutPreferencesFromSettings(folderPath.TrimEnd('\\').Replace('\\', '_')); @@ -495,7 +499,8 @@ public static LayoutPreferences GetLayoutPreferencesForPath(string folderPath) public void UpdateLayoutPreferencesForPath(string folderPath, LayoutPreferences prefs) { - if (App.AppSettings.AreLayoutPreferencesPerFolder) + IUserSettingsService userSettingsService = Ioc.Default.GetService(); + if (userSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder) { // Sanitize the folderPath by removing the trailing '\\'. This has to be performed because paths to drives // include an '\\' at the end (unlike paths to folders) @@ -506,27 +511,27 @@ public void UpdateLayoutPreferencesForPath(string folderPath, LayoutPreferences } else { - App.AppSettings.DefaultLayoutMode = prefs.LayoutMode; - App.AppSettings.DefaultGridViewSize = prefs.GridViewSize; + UserSettingsService.LayoutSettingsService.DefaultLayoutMode = prefs.LayoutMode; + UserSettingsService.LayoutSettingsService.DefaultGridViewSize = prefs.GridViewSize; // Do not save OriginalPath as global sort option (only works in recycle bin) if (prefs.DirectorySortOption != SortOption.OriginalFolder && prefs.DirectorySortOption != SortOption.DateDeleted && prefs.DirectorySortOption != SortOption.SyncStatus) { - App.AppSettings.DefaultDirectorySortOption = prefs.DirectorySortOption; + UserSettingsService.LayoutSettingsService.DefaultDirectorySortOption = prefs.DirectorySortOption; } if (prefs.DirectoryGroupOption != GroupOption.OriginalFolder && prefs.DirectoryGroupOption != GroupOption.DateDeleted && prefs.DirectoryGroupOption != GroupOption.SyncStatus) { - App.AppSettings.DefaultDirectoryGroupOption = prefs.DirectoryGroupOption; + UserSettingsService.LayoutSettingsService.DefaultDirectoryGroupOption = prefs.DirectoryGroupOption; } - App.AppSettings.DefaultDirectorySortDirection = prefs.DirectorySortDirection; - App.AppSettings.ShowDateColumn = !prefs.ColumnsViewModel.DateModifiedColumn.UserCollapsed; - App.AppSettings.ShowDateCreatedColumn = !prefs.ColumnsViewModel.DateCreatedColumn.UserCollapsed; - App.AppSettings.ShowTypeColumn = !prefs.ColumnsViewModel.ItemTypeColumn.UserCollapsed; - App.AppSettings.ShowSizeColumn = !prefs.ColumnsViewModel.SizeColumn.UserCollapsed; - App.AppSettings.ShowFileTagColumn = !prefs.ColumnsViewModel.TagColumn.UserCollapsed; + UserSettingsService.LayoutSettingsService.DefaultDirectorySortDirection = prefs.DirectorySortDirection; + UserSettingsService.LayoutSettingsService.ShowDateColumn = !prefs.ColumnsViewModel.DateModifiedColumn.UserCollapsed; + UserSettingsService.LayoutSettingsService.ShowDateCreatedColumn = !prefs.ColumnsViewModel.DateCreatedColumn.UserCollapsed; + UserSettingsService.LayoutSettingsService.ShowTypeColumn = !prefs.ColumnsViewModel.ItemTypeColumn.UserCollapsed; + UserSettingsService.LayoutSettingsService.ShowSizeColumn = !prefs.ColumnsViewModel.SizeColumn.UserCollapsed; + UserSettingsService.LayoutSettingsService.ShowFileTagColumn = !prefs.ColumnsViewModel.TagColumn.UserCollapsed; } } @@ -559,6 +564,8 @@ private static LayoutPreferences ReadLayoutPreferencesFromSettings(string folder { return LayoutPreferences.DefaultLayoutPreferences; } + + IUserSettingsService userSettingsService = Ioc.Default.GetService(); ApplicationDataContainer dataContainer = localSettings.CreateContainer("LayoutModeContainer", ApplicationDataCreateDisposition.Always); folderPath = new string(folderPath.TakeLast(254).ToArray()); if (dataContainer.Values.ContainsKey(folderPath)) @@ -566,15 +573,15 @@ private static LayoutPreferences ReadLayoutPreferencesFromSettings(string folder ApplicationDataCompositeValue adcv = (ApplicationDataCompositeValue)dataContainer.Values[folderPath]; return LayoutPreferences.FromCompositeValue(adcv); } - else if (folderPath == App.AppSettings.DownloadsPath) + else if (folderPath == CommonPaths.DownloadsPath) { // Default for downloads folder is to group by date created return new LayoutPreferences { - LayoutMode = App.AppSettings.DefaultLayoutMode, - GridViewSize = App.AppSettings.DefaultGridViewSize, - DirectorySortOption = App.AppSettings.DefaultDirectorySortOption, - DirectorySortDirection = App.AppSettings.DefaultDirectorySortDirection, + LayoutMode = userSettingsService.LayoutSettingsService.DefaultLayoutMode, + GridViewSize = userSettingsService.LayoutSettingsService.DefaultGridViewSize, + DirectorySortOption = userSettingsService.LayoutSettingsService.DefaultDirectorySortOption, + DirectorySortDirection = userSettingsService.LayoutSettingsService.DefaultDirectorySortDirection, ColumnsViewModel = new ColumnsViewModel(), DirectoryGroupOption = GroupOption.DateCreated, }; @@ -621,6 +628,8 @@ private set public class LayoutPreferences { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public SortOption DirectorySortOption; public SortDirection DirectorySortDirection; public GroupOption DirectoryGroupOption; @@ -635,18 +644,18 @@ public class LayoutPreferences public LayoutPreferences() { - this.LayoutMode = App.AppSettings.DefaultLayoutMode; - this.GridViewSize = App.AppSettings.DefaultGridViewSize; - this.DirectorySortOption = App.AppSettings.DefaultDirectorySortOption; - this.DirectoryGroupOption = App.AppSettings.DefaultDirectoryGroupOption; - this.DirectorySortDirection = App.AppSettings.DefaultDirectorySortDirection; + this.LayoutMode = UserSettingsService.LayoutSettingsService.DefaultLayoutMode; + this.GridViewSize = UserSettingsService.LayoutSettingsService.DefaultGridViewSize; + this.DirectorySortOption = UserSettingsService.LayoutSettingsService.DefaultDirectorySortOption; + this.DirectoryGroupOption = UserSettingsService.LayoutSettingsService.DefaultDirectoryGroupOption; + this.DirectorySortDirection = UserSettingsService.LayoutSettingsService.DefaultDirectorySortDirection; this.ColumnsViewModel = new ColumnsViewModel(); - this.ColumnsViewModel.DateCreatedColumn.UserCollapsed = !App.AppSettings.ShowDateCreatedColumn; - this.ColumnsViewModel.DateModifiedColumn.UserCollapsed = !App.AppSettings.ShowDateColumn; - this.ColumnsViewModel.ItemTypeColumn.UserCollapsed = !App.AppSettings.ShowTypeColumn; - this.ColumnsViewModel.SizeColumn.UserCollapsed = !App.AppSettings.ShowSizeColumn; - this.ColumnsViewModel.TagColumn.UserCollapsed = !App.AppSettings.ShowFileTagColumn; + this.ColumnsViewModel.DateCreatedColumn.UserCollapsed = !UserSettingsService.LayoutSettingsService.ShowDateCreatedColumn; + this.ColumnsViewModel.DateModifiedColumn.UserCollapsed = !UserSettingsService.LayoutSettingsService.ShowDateColumn; + this.ColumnsViewModel.ItemTypeColumn.UserCollapsed = !UserSettingsService.LayoutSettingsService.ShowTypeColumn; + this.ColumnsViewModel.SizeColumn.UserCollapsed = !UserSettingsService.LayoutSettingsService.ShowSizeColumn; + this.ColumnsViewModel.TagColumn.UserCollapsed = !UserSettingsService.LayoutSettingsService.ShowFileTagColumn; this.IsAdaptiveLayoutOverridden = false; // Default is always turned on for every dir } diff --git a/Files/ViewModels/ItemViewModel.cs b/Files/ViewModels/ItemViewModel.cs index 8b034c32a1d4..f051175f7a7e 100644 --- a/Files/ViewModels/ItemViewModel.cs +++ b/Files/ViewModels/ItemViewModel.cs @@ -1,6 +1,7 @@ using Files.Common; using Files.Dialogs; using Files.Enums; +using Files.EventArguments; using Files.Extensions; using Files.Filesystem; using Files.Filesystem.Cloud; @@ -9,11 +10,12 @@ using Files.Filesystem.StorageItems; using Files.Helpers; using Files.Helpers.FileListCache; +using Files.Services; using Files.UserControls; using FluentFTP; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; -using Microsoft.Toolkit.Uwp.UI; using Newtonsoft.Json; using System; using System.Collections.Concurrent; @@ -54,6 +56,8 @@ public class ItemViewModel : ObservableObject, IDisposable // files and folders list for manipulating private List filesAndFolders; + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + // only used for Binding and ApplyFilesAndFoldersChangesAsync, don't manipulate on this! public BulkConcurrentObservableCollection FilesAndFolders { get; } @@ -352,20 +356,20 @@ public ItemViewModel(FolderSettingsViewModel folderSettingsViewModel) operationEvent = new AsyncManualResetEvent(); enumFolderSemaphore = new SemaphoreSlim(1, 1); itemLoadEvent = new AsyncManualResetEvent(); - shouldDisplayFileExtensions = App.AppSettings.ShowFileExtensions; + shouldDisplayFileExtensions = UserSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions; + UserSettingsService.OnSettingChangedEvent += UserSettingsService_OnSettingChangedEvent; AppServiceConnectionHelper.ConnectionChanged += AppServiceConnectionHelper_ConnectionChanged; - AppSettings.PropertyChanged += AppSettings_PropertyChanged; } - private async void AppSettings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + private async void UserSettingsService_OnSettingChangedEvent(object sender, SettingChangedEventArgs e) { - switch (e.PropertyName) + switch (e.settingName) { - case nameof(AppSettings.ShowFileExtensions): - case nameof(AppSettings.AreHiddenItemsVisible): - case nameof(AppSettings.AreSystemItemsHidden): - case nameof(AppSettings.AreFileTagsEnabled): + case nameof(UserSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions): + case nameof(UserSettingsService.FilesAndFoldersSettingsService.AreHiddenItemsVisible): + case nameof(UserSettingsService.FilesAndFoldersSettingsService.AreSystemItemsHidden): + case nameof(UserSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled): await CoreApplication.MainView.DispatcherQueue.EnqueueAsync(() => { if (WorkingDirectory != "Home".GetLocalized() && WorkingDirectory != "NewTab".GetLocalized()) @@ -1188,7 +1192,7 @@ private async void RapidAddItemsToCollectionAsync(string path, string previousDi AdaptiveLayoutHelpers.PredictLayoutMode(folderSettings, this); } - if (AppSettings.PreviewPaneEnabled) + if (UserSettingsService.PreviewPaneSettingsService.PreviewPaneEnabled) { // Find and select README file foreach (var item in filesAndFolders) @@ -1221,9 +1225,9 @@ private async Task RapidAddItemsToCollection(string path, LibraryItem library = Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - var isRecycleBin = path.StartsWith(AppSettings.RecycleBinPath); + var isRecycleBin = path.StartsWith(CommonPaths.RecycleBinPath); if (isRecycleBin || - path.StartsWith(AppSettings.NetworkFolderPath) || + path.StartsWith(CommonPaths.NetworkFolderPath) || FtpHelpers.IsFtpPath(path)) { // Recycle bin and network are enumerated by the fulltrust process @@ -1301,8 +1305,8 @@ public async Task EnumerateItemsFromSpecialFolderAsync(string path) { PrimaryItemAttribute = StorageItemTypes.Folder, ItemPropertiesInitialized = true, - ItemName = path.StartsWith(AppSettings.RecycleBinPath) ? ApplicationData.Current.LocalSettings.Values.Get("RecycleBin_Title", "Recycle Bin") : - path.StartsWith(AppSettings.NetworkFolderPath) ? "Network".GetLocalized() : isFtp ? "FTP" : "Unknown", + ItemName = path.StartsWith(CommonPaths.RecycleBinPath) ? ApplicationData.Current.LocalSettings.Values.Get("RecycleBin_Title", "Recycle Bin") : + path.StartsWith(CommonPaths.NetworkFolderPath) ? "Network".GetLocalized() : isFtp ? "FTP" : "Unknown", ItemDateModifiedReal = DateTimeOffset.Now, // Fake for now ItemDateCreatedReal = DateTimeOffset.Now, // Fake for now ItemType = "FileFolderListItem".GetLocalized(), @@ -1953,7 +1957,7 @@ public ListedItem AddFileOrFolderFromShellFile(ShellFileItem item, string dateRe { // File string itemName; - if (App.AppSettings.ShowFileExtensions && !item.FileName.EndsWith(".lnk") && !item.FileName.EndsWith(".url")) + if (UserSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions && !item.FileName.EndsWith(".lnk") && !item.FileName.EndsWith(".url")) { itemName = item.FileName; // never show extension for shortcuts } @@ -2035,7 +2039,7 @@ private async Task AddFileOrFolderAsync(string fileOrFolderPath, string dateRetu var isSystem = ((FileAttributes)findData.dwFileAttributes & FileAttributes.System) == FileAttributes.System; var isHidden = ((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) == FileAttributes.Hidden; - if (isHidden && (!AppSettings.AreHiddenItemsVisible || (isSystem && AppSettings.AreSystemItemsHidden))) + if (isHidden && (!UserSettingsService.FilesAndFoldersSettingsService.AreHiddenItemsVisible || (isSystem && UserSettingsService.FilesAndFoldersSettingsService.AreSystemItemsHidden))) { // Do not add to file list if hidden/system attribute is set and system/hidden file are not to be shown return; @@ -2221,8 +2225,8 @@ public void Dispose() { Connection.RequestReceived -= Connection_RequestReceived; } + UserSettingsService.OnSettingChangedEvent -= UserSettingsService_OnSettingChangedEvent; AppServiceConnectionHelper.ConnectionChanged -= AppServiceConnectionHelper_ConnectionChanged; - AppSettings.PropertyChanged -= AppSettings_PropertyChanged; } } diff --git a/Files/ViewModels/MainPageViewModel.cs b/Files/ViewModels/MainPageViewModel.cs index ad37cc9fd276..d17b21f865af 100644 --- a/Files/ViewModels/MainPageViewModel.cs +++ b/Files/ViewModels/MainPageViewModel.cs @@ -2,9 +2,11 @@ using Files.Filesystem; using Files.Filesystem.StorageItems; using Files.Helpers; +using Files.Services; using Files.UserControls.MultitaskingControl; using Files.Views; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using System; @@ -23,6 +25,8 @@ namespace Files.ViewModels { public class MainPageViewModel : ObservableObject { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public IMultitaskingControl MultitaskingControl { get; set; } public List MultitaskingControls { get; } = new List(); @@ -228,20 +232,20 @@ public static async Task UpdateTabInfo(TabItem tabItem, object navigationArg) tabLocationHeader = "NewTab".GetLocalized(); iconSource.ImageSource = new Windows.UI.Xaml.Media.Imaging.BitmapImage(new Uri("ms-appx:///Assets/FluentIcons/Home.png")); } - else if (currentPath.Equals(App.AppSettings.DesktopPath, StringComparison.OrdinalIgnoreCase)) + else if (currentPath.Equals(CommonPaths.DesktopPath, StringComparison.OrdinalIgnoreCase)) { tabLocationHeader = "SidebarDesktop".GetLocalized(); } - else if (currentPath.Equals(App.AppSettings.DownloadsPath, StringComparison.OrdinalIgnoreCase)) + else if (currentPath.Equals(CommonPaths.DownloadsPath, StringComparison.OrdinalIgnoreCase)) { tabLocationHeader = "SidebarDownloads".GetLocalized(); } - else if (currentPath.Equals(App.AppSettings.RecycleBinPath, StringComparison.OrdinalIgnoreCase)) + else if (currentPath.Equals(CommonPaths.RecycleBinPath, StringComparison.OrdinalIgnoreCase)) { var localSettings = ApplicationData.Current.LocalSettings; tabLocationHeader = localSettings.Values.Get("RecycleBin_Title", "Recycle Bin"); } - else if (currentPath.Equals(App.AppSettings.NetworkFolderPath, StringComparison.OrdinalIgnoreCase)) + else if (currentPath.Equals(CommonPaths.NetworkFolderPath, StringComparison.OrdinalIgnoreCase)) { tabLocationHeader = "SidebarNetworkDrives".GetLocalized(); } @@ -331,12 +335,12 @@ public async void OnNavigatedTo(NavigationEventArgs e) try { // add last session tabs to closed tabs stack if those tabs are not about to be opened - if(!App.AppSettings.ResumeAfterRestart && !App.AppSettings.ContinueLastSessionOnStartUp && App.AppSettings.LastSessionPages != null) + if(!App.AppSettings.ResumeAfterRestart && !UserSettingsService.StartupSettingsService.ContinueLastSessionOnStartUp && UserSettingsService.StartupSettingsService.LastSessionTabList != null) { - var items = new TabItemArguments[App.AppSettings.LastSessionPages.Length]; + var items = new TabItemArguments[UserSettingsService.StartupSettingsService.LastSessionTabList.Count]; for(int i = 0; i < items.Length; i++) { - var tabArgs = TabItemArguments.Deserialize(App.AppSettings.LastSessionPages[i]); + var tabArgs = TabItemArguments.Deserialize(UserSettingsService.StartupSettingsService.LastSessionTabList[i]); items[i] = tabArgs; } BaseMultitaskingControl.RecentlyClosedTabs.Add(items); @@ -346,22 +350,22 @@ public async void OnNavigatedTo(NavigationEventArgs e) { App.AppSettings.ResumeAfterRestart = false; - foreach (string tabArgsString in App.AppSettings.LastSessionPages) + foreach (string tabArgsString in UserSettingsService.StartupSettingsService.LastSessionTabList) { var tabArgs = TabItemArguments.Deserialize(tabArgsString); await AddNewTabByParam(tabArgs.InitialPageType, tabArgs.NavigationArg); } - if (!App.AppSettings.ContinueLastSessionOnStartUp) + if (!UserSettingsService.StartupSettingsService.ContinueLastSessionOnStartUp) { - App.AppSettings.LastSessionPages = null; + UserSettingsService.StartupSettingsService.LastSessionTabList = null; } } - else if (App.AppSettings.OpenASpecificPageOnStartup) + else if (UserSettingsService.StartupSettingsService.OpenSpecificPageOnStartup) { - if (App.AppSettings.PagesOnStartupList != null) + if (UserSettingsService.StartupSettingsService.TabsOnStartupList != null) { - foreach (string path in App.AppSettings.PagesOnStartupList) + foreach (string path in UserSettingsService.StartupSettingsService.TabsOnStartupList) { await AddNewTabByPathAsync(typeof(PaneHolderPage), path); } @@ -371,17 +375,17 @@ public async void OnNavigatedTo(NavigationEventArgs e) await AddNewTabAsync(); } } - else if (App.AppSettings.ContinueLastSessionOnStartUp) + else if (UserSettingsService.StartupSettingsService.ContinueLastSessionOnStartUp) { - if (App.AppSettings.LastSessionPages != null) + if (UserSettingsService.StartupSettingsService.LastSessionTabList != null) { - foreach (string tabArgsString in App.AppSettings.LastSessionPages) + foreach (string tabArgsString in UserSettingsService.StartupSettingsService.LastSessionTabList) { var tabArgs = TabItemArguments.Deserialize(tabArgsString); await AddNewTabByParam(tabArgs.InitialPageType, tabArgs.NavigationArg); } var defaultArg = new TabItemArguments() { InitialPageType = typeof(PaneHolderPage), NavigationArg = "NewTab".GetLocalized() }; - App.AppSettings.LastSessionPages = new string[] { defaultArg.Serialize() }; + UserSettingsService.StartupSettingsService.LastSessionTabList = new List { defaultArg.Serialize() }; } else { diff --git a/Files/ViewModels/NavToolbarViewModel.cs b/Files/ViewModels/NavToolbarViewModel.cs index 821ac33670a7..a51dbce5e327 100644 --- a/Files/ViewModels/NavToolbarViewModel.cs +++ b/Files/ViewModels/NavToolbarViewModel.cs @@ -3,9 +3,11 @@ using Files.Filesystem; using Files.Filesystem.StorageItems; using Files.Helpers; +using Files.Services; using Files.UserControls; using Files.Views; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using Microsoft.Toolkit.Uwp.UI; @@ -27,11 +29,14 @@ using Windows.UI.Xaml.Input; using static Files.UserControls.INavigationToolbar; using SearchBox = Files.UserControls.SearchBox; +using SortDirection = Files.Enums.SortDirection; namespace Files.ViewModels { public class NavToolbarViewModel : ObservableObject, INavigationToolbar, IDisposable { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public delegate void ToolbarPathItemInvokedEventHandler(object sender, PathNavigationEventArgs e); public delegate void ToolbarFlyoutOpenedEventHandler(object sender, ToolbarFlyoutOpenedEventArgs e); @@ -607,16 +612,16 @@ public void SwitchSearchBoxVisibility() private NavigationToolbar NavToolbar => (Window.Current.Content as Frame).FindDescendant(); - #region YourHome Widgets + #region WidgetsPage Widgets public bool ShowFolderWidgetWidget { - get => App.AppSettings.ShowFolderWidgetWidget; + get => UserSettingsService.WidgetsSettingsService.ShowFoldersWidget; set { - if (App.AppSettings.ShowFolderWidgetWidget != value) + if (value != UserSettingsService.WidgetsSettingsService.ShowFoldersWidget) { - App.AppSettings.ShowFolderWidgetWidget = value; + UserSettingsService.WidgetsSettingsService.ShowFoldersWidget = value; RefreshWidgetsRequested?.Invoke(this, EventArgs.Empty); } @@ -625,12 +630,12 @@ public bool ShowFolderWidgetWidget public bool ShowDrivesWidget { - get => App.AppSettings.ShowDrivesWidget; + get => UserSettingsService.WidgetsSettingsService.ShowDrivesWidget; set { - if (App.AppSettings.ShowDrivesWidget != value) + if (value != UserSettingsService.WidgetsSettingsService.ShowDrivesWidget) { - App.AppSettings.ShowDrivesWidget = value; + UserSettingsService.WidgetsSettingsService.ShowDrivesWidget = value; RefreshWidgetsRequested?.Invoke(this, EventArgs.Empty); } @@ -639,12 +644,12 @@ public bool ShowDrivesWidget public bool ShowBundlesWidget { - get => App.AppSettings.ShowBundlesWidget; + get => UserSettingsService.WidgetsSettingsService.ShowBundlesWidget; set { - if (App.AppSettings.ShowBundlesWidget != value) + if (value != UserSettingsService.WidgetsSettingsService.ShowBundlesWidget) { - App.AppSettings.ShowBundlesWidget = value; + UserSettingsService.WidgetsSettingsService.ShowBundlesWidget = value; RefreshWidgetsRequested?.Invoke(this, EventArgs.Empty); } @@ -653,12 +658,12 @@ public bool ShowBundlesWidget public bool ShowRecentFilesWidget { - get => App.AppSettings.ShowRecentFilesWidget; + get => UserSettingsService.WidgetsSettingsService.ShowRecentFilesWidget; set { - if (App.AppSettings.ShowRecentFilesWidget != value) + if (value != UserSettingsService.WidgetsSettingsService.ShowRecentFilesWidget) { - App.AppSettings.ShowRecentFilesWidget = value; + UserSettingsService.WidgetsSettingsService.ShowRecentFilesWidget = value; RefreshWidgetsRequested?.Invoke(this, EventArgs.Empty); } @@ -842,7 +847,7 @@ public async Task CheckPathInput(string currentInput, string currentSelectedPath { var workingDir = string.IsNullOrEmpty(shellPage.FilesystemViewModel.WorkingDirectory) || shellPage.CurrentPageType == typeof(WidgetsPage) - ? App.AppSettings.HomePath + ? CommonPaths.HomePath : shellPage.FilesystemViewModel.WorkingDirectory; // Launch terminal application if possible diff --git a/Files/ViewModels/PreviewPaneViewModel.cs b/Files/ViewModels/PreviewPaneViewModel.cs index 39882d0287f6..d4f1302e2fe7 100644 --- a/Files/ViewModels/PreviewPaneViewModel.cs +++ b/Files/ViewModels/PreviewPaneViewModel.cs @@ -1,8 +1,10 @@ using Files.Filesystem; +using Files.Services; using Files.UserControls.FilePreviews; using Files.ViewModels.Previews; using Files.ViewModels.Properties; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Newtonsoft.Json; using System; @@ -23,6 +25,8 @@ namespace Files.ViewModels { public class PreviewPaneViewModel : ObservableObject, IDisposable { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + private CancellationTokenSource loadCancellationTokenSource; private bool isItemSelected; @@ -67,7 +71,7 @@ public UIElement PreviewPaneContent public PreviewPaneViewModel() { - App.AppSettings.PropertyChanged += AppSettings_PropertyChanged; + UserSettingsService.OnSettingChangedEvent += UserSettingsService_OnSettingChangedEvent; } private async Task LoadPreviewControlAsync(CancellationToken token, bool downloadItem) @@ -283,11 +287,11 @@ public async void UpdateSelectedItemPreview(bool downloadItem = false) public ICommand ShowPreviewOnlyInvoked => new RelayCommand(() => UpdateSelectedItemPreview()); - private void AppSettings_PropertyChanged(object sender, PropertyChangedEventArgs e) + private void UserSettingsService_OnSettingChangedEvent(object sender, EventArguments.SettingChangedEventArgs e) { - switch (e.PropertyName) + switch (e.settingName) { - case nameof(App.AppSettings.ShowPreviewOnly): + case nameof(UserSettingsService.PreviewPaneSettingsService.ShowPreviewOnly): // the preview will need refreshing as the file details won't be accurate needsRefresh = true; break; @@ -312,7 +316,7 @@ public void TryRefresh() public void Dispose() { - App.AppSettings.PropertyChanged -= AppSettings_PropertyChanged; + UserSettingsService.OnSettingChangedEvent -= UserSettingsService_OnSettingChangedEvent; } } diff --git a/Files/ViewModels/Previews/BasePreviewModel.cs b/Files/ViewModels/Previews/BasePreviewModel.cs index 3f16557d3156..f1691dead874 100644 --- a/Files/ViewModels/Previews/BasePreviewModel.cs +++ b/Files/ViewModels/Previews/BasePreviewModel.cs @@ -1,8 +1,10 @@ using Files.Filesystem; using Files.Filesystem.StorageItems; using Files.Helpers; +using Files.Services; using Files.ViewModels.Properties; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using System; using System.Collections.Generic; using System.IO; @@ -18,6 +20,8 @@ namespace Files.ViewModels.Previews { public abstract class BasePreviewModel : ObservableObject { + protected IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public BasePreviewModel(ListedItem item) : base() { Item = item; @@ -86,7 +90,7 @@ private async Task> GetSystemFileProperties() (double?)list.Find(x => x.Property == "System.GPS.LongitudeDecimal").Value); // adds the value for the file tag - if (App.AppSettings.AreFileTagsEnabled) + if (UserSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled) { list.FirstOrDefault(x => x.ID == "filetag").Value = Item.FileTagUI?.TagName; } @@ -109,7 +113,7 @@ public virtual async Task LoadAsync() Item.ItemFile ??= await StorageFileExtensions.DangerousGetFileFromPathAsync(Item.ItemPath); DetailsFromPreview = await LoadPreviewAndDetails(); - if (!App.AppSettings.ShowPreviewOnly) + if (!UserSettingsService.PreviewPaneSettingsService.ShowPreviewOnly) { // Add the details from the preview function, then the system file properties DetailsFromPreview?.ForEach(i => detailsFull.Add(i)); diff --git a/Files/ViewModels/Previews/FolderPreviewViewModel.cs b/Files/ViewModels/Previews/FolderPreviewViewModel.cs index cfd11bc7f73b..47c14181f6a9 100644 --- a/Files/ViewModels/Previews/FolderPreviewViewModel.cs +++ b/Files/ViewModels/Previews/FolderPreviewViewModel.cs @@ -2,7 +2,9 @@ using Files.Filesystem; using Files.Filesystem.StorageItems; using Files.Helpers; +using Files.Services; using Files.ViewModels.Properties; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using System; using System.Collections.ObjectModel; using System.Threading.Tasks; @@ -14,6 +16,8 @@ namespace Files.ViewModels.Previews { public class FolderPreviewViewModel { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + private BaseStorageFolder Folder { get; set; } public ListedItem Item { get; set; } @@ -70,7 +74,7 @@ private async Task LoadPreviewAndDetailsAsync() } }; - if (App.AppSettings.AreFileTagsEnabled) + if (UserSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled) { Item.FileDetails.Add(new FileProperty() { diff --git a/Files/ViewModels/Properties/FolderProperties.cs b/Files/ViewModels/Properties/FolderProperties.cs index 1e7fec2a0eed..2a6976fb3f53 100644 --- a/Files/ViewModels/Properties/FolderProperties.cs +++ b/Files/ViewModels/Properties/FolderProperties.cs @@ -124,7 +124,7 @@ public async override void GetSpecialProperties() } GetFolderSize(storageFolder, TokenSource.Token); } - else if (Item.ItemPath.Equals(App.AppSettings.RecycleBinPath, StringComparison.OrdinalIgnoreCase)) + else if (Item.ItemPath.Equals(CommonPaths.RecycleBinPath, StringComparison.OrdinalIgnoreCase)) { // GetFolderFromPathAsync cannot access recyclebin folder var connection = await AppServiceConnectionHelper.Instance; diff --git a/Files/ViewModels/SettingsViewModel.cs b/Files/ViewModels/SettingsViewModel.cs index b8aa8592832f..f04551deea4b 100644 --- a/Files/ViewModels/SettingsViewModel.cs +++ b/Files/ViewModels/SettingsViewModel.cs @@ -4,14 +4,10 @@ using Files.Enums; using Files.Filesystem; using Files.Helpers; -using Microsoft.AppCenter; -using Microsoft.AppCenter.Analytics; -using Microsoft.AppCenter.Crashes; using Microsoft.Toolkit.Mvvm.ComponentModel; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using Microsoft.Toolkit.Uwp.UI; -using Newtonsoft.Json.Linq; using System; using System.Collections.ObjectModel; using System.Linq; @@ -24,10 +20,10 @@ using Windows.Globalization; using Windows.Storage; using Windows.System; -using Windows.UI.Xaml; namespace Files.ViewModels { + [Obsolete("Do not use this class as Settings store anymore, settings have been merged to IUserSettingsService.")] public class SettingsViewModel : ObservableObject { private readonly ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings; @@ -43,44 +39,6 @@ public SettingsViewModel() { DefaultLanguages.Add(new DefaultLanguageModel(lang)); } - - FileTagsSettings = new FileTagsSettings(); - - // Send analytics to AppCenter - StartAppCenter(); - } - - private async void StartAppCenter() - { - JObject obj; - try - { - StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(@"ms-appx:///Resources/AppCenterKey.txt")); - var lines = await FileIO.ReadTextAsync(file); - obj = JObject.Parse(lines); - } - catch - { - return; - } - - AppCenter.Start((string)obj.SelectToken("key"), typeof(Analytics), typeof(Crashes)); - - Analytics.TrackEvent($"{nameof(DisplayedTimeStyle)} {DisplayedTimeStyle}"); - Analytics.TrackEvent($"{nameof(ThemeHelper.RootTheme)} {ThemeHelper.RootTheme}"); - Analytics.TrackEvent($"{nameof(PinRecycleBinToSideBar)} {PinRecycleBinToSideBar}"); - Analytics.TrackEvent($"{nameof(ShowFileExtensions)} {ShowFileExtensions}"); - Analytics.TrackEvent($"{nameof(ShowConfirmDeleteDialog)} {ShowConfirmDeleteDialog}"); - Analytics.TrackEvent($"{nameof(IsVerticalTabFlyoutEnabled)} {IsVerticalTabFlyoutEnabled}"); - Analytics.TrackEvent($"{nameof(IsDualPaneEnabled)} {IsDualPaneEnabled}"); - Analytics.TrackEvent($"{nameof(AlwaysOpenDualPaneInNewTab)} {AlwaysOpenDualPaneInNewTab}"); - Analytics.TrackEvent($"{nameof(AreHiddenItemsVisible)} {AreHiddenItemsVisible}"); - Analytics.TrackEvent($"{nameof(AreLayoutPreferencesPerFolder)} {AreLayoutPreferencesPerFolder}"); - Analytics.TrackEvent($"{nameof(ShowDrivesWidget)} {ShowDrivesWidget}"); - Analytics.TrackEvent($"{nameof(ShowLibrarySection)} {ShowLibrarySection}"); - Analytics.TrackEvent($"{nameof(ShowBundlesWidget)} {ShowBundlesWidget}"); - Analytics.TrackEvent($"{nameof(ListAndSortDirectoriesAlongsideFiles)} {ListAndSortDirectoriesAlongsideFiles}"); - Analytics.TrackEvent($"{nameof(AreFileTagsEnabled)} {AreFileTagsEnabled}"); } public static async void OpenLogLocation() @@ -99,55 +57,7 @@ public static async void ReportIssueOnGitHub() await Launcher.LaunchUriAsync(new Uri(@"https://github.com/files-community/Files/issues/new/choose")); } - /// - /// Gets or sets a value indicating the width of the the sidebar pane when open. - /// - public GridLength SidebarWidth - { - get => new GridLength(Math.Min(Math.Max(Get(255d), Constants.UI.MinimumSidebarWidth), 500d), GridUnitType.Pixel); - set => Set(value.Value); - } - - /// - /// Gets or sets a value indicating if the sidebar pane should be open or closed. - /// - public bool IsSidebarOpen - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating the height of the preview pane in a horizontal layout. - /// - public GridLength PreviewPaneSizeHorizontal - { - get => new GridLength(Math.Min(Math.Max(Get(300d), 50d), 600d), GridUnitType.Pixel); - set => Set(value.Value); - } - - /// - /// Gets or sets a value indicating the width of the preview pane in a vertical layout. - /// - public GridLength PreviewPaneSizeVertical - { - get => new GridLength(Math.Min(Math.Max(Get(250d), 50d), 600d), GridUnitType.Pixel); - set => Set(value.Value); - } - - /// - /// Gets or sets a value indicating if the preview pane should be open or closed. - /// - public bool PreviewPaneEnabled - { - get => Get(false); - set => Set(value); - } - - /// - /// Gets or sets a value indicating if the preview pane should only show the item preview without the details section - /// - public bool ShowPreviewOnly + public bool AreRegistrySettingsMergedToJson { get => Get(false); set => Set(value); @@ -215,344 +125,8 @@ public TimeStyle DisplayedTimeStyle } } - #region DetailsView Column Settings - - /// - /// Gets or sets a value indicating whether or not the date column should be visible. - /// - public bool ShowDateColumn - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not the date created column should be visible. - /// - public bool ShowDateCreatedColumn - { - get => Get(false); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not the type column should be visible. - /// - public bool ShowTypeColumn - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not the size column should be visible. - /// - public bool ShowSizeColumn - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not the filetag column should be visible. - /// - public bool ShowFileTagColumn - { - get => Get(true); - set => Set(value); - } - - #endregion DetailsView Column Settings - - #region CommonPaths - - public string DesktopPath { get; set; } = UserDataPaths.GetDefault().Desktop; - public string DownloadsPath { get; set; } = UserDataPaths.GetDefault().Downloads; - - private string tempPath = (string)Microsoft.Win32.Registry.GetValue(@"HKEY_CURRENT_USER\Environment", "TEMP", null); - - public string TempPath - { - get => tempPath; - set => SetProperty(ref tempPath, value); - } - - private string localAppDataPath = UserDataPaths.GetDefault().LocalAppData; - - public string LocalAppDataPath - { - get => localAppDataPath; - set => SetProperty(ref localAppDataPath, value); - } - - private string homePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - - public string HomePath - { - get => homePath; - set => SetProperty(ref homePath, value); - } - - // Currently is the command to open the folder from cmd ("cmd /c start Shell:RecycleBinFolder") - public string RecycleBinPath { get; set; } = @"Shell:RecycleBinFolder"; - - public string NetworkFolderPath { get; set; } = @"Shell:NetworkPlacesFolder"; - - #endregion CommonPaths - - #region FilesAndFolder - - /// - /// Gets or sets a value indicating whether or not file extensions should be visible. - /// - public bool ShowFileExtensions - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not hidden items should be visible. - /// - public bool AreHiddenItemsVisible - { - get => Get(false); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not system items should be visible. - /// - public bool AreSystemItemsHidden - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not files should be sorted together with folders. - /// - public bool ListAndSortDirectoriesAlongsideFiles - { - get => Get(false); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not items should open with one click. - /// - public bool OpenItemsWithOneclick - { - get => Get(false); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not to search unindexed items. - /// - public bool SearchUnindexedItems - { - get => Get(false); - set => Set(value); - } - - /// - /// Enables saving a unique layout mode, gridview size and sort direction per folder - /// - public bool AreLayoutPreferencesPerFolder - { - get => Get(true); - set => Set(value); - } - - /// - /// Enables adaptive layout that adjusts layout mode based on the context of the directory - /// - public bool AdaptiveLayoutEnabled - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not to enable file tags feature. - /// - public bool AreFileTagsEnabled - { - get => Get(false); - set => Set(value); - } - - #endregion FilesAndFolder - - #region Multitasking - - /// - /// Gets or sets a value indicating whether or not to enable the vertical tab flyout. - /// - public bool IsVerticalTabFlyoutEnabled - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not to enable dual pane feature. - /// - public bool IsDualPaneEnabled - { - get => Get(false); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not to always open a second pane when opening a new tab. - /// - public bool AlwaysOpenDualPaneInNewTab - { - get => Get(false); - set => Set(value); - } - - #endregion Multitasking - - #region Widgets - - /// - /// Gets or sets a value indicating whether or not the library cards widget should be visible. - /// - public bool ShowFolderWidgetWidget - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not the recent files widget should be visible. - /// - public bool ShowRecentFilesWidget - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not the drives widget should be visible. - /// - public bool ShowDrivesWidget - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not the Bundles widget should be visible. - /// - public bool ShowBundlesWidget - { - get => Get(false); - set => Set(value); - } - - #endregion Widgets - - #region Sidebar - - /// - /// Gets or sets a value indicating whether or not to show the Favorites section on the sidebar. - /// - public bool ShowFavoritesSection - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not to show the library section on the sidebar. - /// - public bool ShowLibrarySection - { - get => Get(false); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether [show drives section]. - /// - public bool ShowDrivesSection - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether [show cloud drives section]. - /// - public bool ShowCloudDrivesSection - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether [show network drives section]. - /// - public bool ShowNetworkDrivesSection - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether [show wsl section]. - /// - public bool ShowWslSection - { - get => Get(true); - set => Set(value); - } - - //TODO: This shouldn't pin recycle bin to the sidebar, it should only hold the value whether it should or shouldn't be pinned - /// - /// Gets or sets a value indicating whether or not recycle bin should be pinned to the sidebar. - /// - public bool PinRecycleBinToSideBar - { - get => Get(true); - set - { - if (Set(value)) - { - _ = App.SidebarPinnedController.Model.ShowHideRecycleBinItemAsync(value); - } - } - } - - #endregion Sidebar - #region Preferences - /// - /// Gets or sets a value indicating whether or not the confirm delete dialog should show when deleting items. - /// - public bool ShowConfirmDeleteDialog - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether [open folders new tab]. - /// - /// - /// true if [open folders new tab]; otherwise, false. - /// - public bool OpenFoldersNewTab - { - get => Get(false); - set => Set(value); - } - /// /// Gets or sets a value indicating the application language. /// @@ -583,15 +157,6 @@ public DefaultLanguageModel DefaultLanguage #region Appearance - /// - /// Gets or sets a value indicating whether or not to move overflow menu items into a sub menu. - /// - public bool MoveOverflowMenuItemsToSubMenu - { - get => Get(true); - set => Set(value); - } - /// /// Gets or sets the user's current selected skin /// @@ -606,67 +171,6 @@ public AppTheme SelectedTheme #endregion Appearance - #region Startup - - /// - /// Gets or sets a value indicating whether or not to navigate to a specific location when launching the app. - /// - public bool OpenASpecificPageOnStartup - { - get => Get(false); - set => Set(value); - } - - /// - /// Gets or sets a value indicating the default startup location. - /// - public string OpenASpecificPageOnStartupPath - { - get => Get(""); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not continue the last session whenever the app is launched. - /// - public bool ContinueLastSessionOnStartUp - { - get => Get(false); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not to open a page when the app is launched. - /// - public bool OpenNewTabPageOnStartup - { - get => Get(true); - set => Set(value); - } - - /// - /// Gets or sets a value indicating whether or not opening the app from the jumplist should open the directory in a new instance. - /// - public bool AlwaysOpenANewInstance - { - get => Get(false); - set => Set(value); - } - - public string[] PagesOnStartupList - { - get => Get(null); - set => Set(value); - } - - public string[] LastSessionPages - { - get => Get(null); - set => Set(value); - } - - #endregion Startup - /// /// Gets or sets a value indicating whether or not to show a teaching tip informing the user about the status center. /// @@ -685,24 +189,6 @@ public bool ResumeAfterRestart set => Set(value); } - /// - /// Gets or sets a value indicating whether or not to show the confirm elevation dialog. - /// - public bool HideConfirmElevateDialog - { - get => Get(false); - set => Set(value); - } - - /// - /// Gets or sets a value indicating the default volume on media preview. - /// - public double MediaVolume - { - get => Math.Min(Math.Max(Get(1.0d), 0.0d), 1.0d); - set => Set(value); - } - public event EventHandler ThemeModeChanged; public RelayCommand UpdateThemeElements => new RelayCommand(() => @@ -712,38 +198,6 @@ public double MediaVolume public AcrylicTheme AcrylicTheme { get; set; } = new AcrylicTheme(); - public FolderLayoutModes DefaultLayoutMode - { - get => (FolderLayoutModes)Get((byte)FolderLayoutModes.DetailsView); // Details View - set => Set((byte)value); - } - - public int DefaultGridViewSize - { - get => Get(Constants.Browser.GridViewBrowser.GridViewSizeSmall); - set => Set(value); - } - - public SortDirection DefaultDirectorySortDirection - { - get => (SortDirection)Get((byte)SortDirection.Ascending); - set => Set((byte)value); - } - - public SortOption DefaultDirectorySortOption - { - get => (SortOption)Get((byte)SortOption.Name); - set => Set((byte)value); - } - - public GroupOption DefaultDirectoryGroupOption - { - get => (GroupOption)Get((byte)GroupOption.None); - set => Set((byte)value); - } - - public FileTagsSettings FileTagsSettings { get; private set; } - #region ReadAndSaveSettings public bool Set(TValue value, [CallerMemberName] string propertyName = null) diff --git a/Files/ViewModels/SettingsViewModels/AppearanceViewModel.cs b/Files/ViewModels/SettingsViewModels/AppearanceViewModel.cs index d56b1582f35c..9d6f235f714a 100644 --- a/Files/ViewModels/SettingsViewModels/AppearanceViewModel.cs +++ b/Files/ViewModels/SettingsViewModels/AppearanceViewModel.cs @@ -1,5 +1,7 @@ using Files.Helpers; +using Files.Services; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Generic; @@ -10,10 +12,10 @@ namespace Files.ViewModels.SettingsViewModels { public class AppearanceViewModel : ObservableObject { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + private int selectedThemeIndex = (int)Enum.Parse(typeof(ElementTheme), ThemeHelper.RootTheme.ToString()); - private bool moveOverflowMenuItemsToSubMenu = App.AppSettings.MoveOverflowMenuItemsToSubMenu; private AppTheme selectedTheme = App.AppSettings.SelectedTheme; - private bool showRestartControl = false; public AppearanceViewModel() { @@ -48,15 +50,13 @@ public ElementTheme SelectedElementTheme public bool MoveOverflowMenuItemsToSubMenu { - get - { - return moveOverflowMenuItemsToSubMenu; - } + get => UserSettingsService.AppearanceSettingsService.MoveOverflowMenuItemsToSubMenu; set { - if (SetProperty(ref moveOverflowMenuItemsToSubMenu, value)) + if (value != UserSettingsService.AppearanceSettingsService.MoveOverflowMenuItemsToSubMenu) { - App.AppSettings.MoveOverflowMenuItemsToSubMenu = value; + UserSettingsService.AppearanceSettingsService.MoveOverflowMenuItemsToSubMenu = value; + OnPropertyChanged(); } } } diff --git a/Files/ViewModels/SettingsViewModels/ExperimentalViewModel.cs b/Files/ViewModels/SettingsViewModels/ExperimentalViewModel.cs index daa9489cb51d..b4fb1ae92111 100644 --- a/Files/ViewModels/SettingsViewModels/ExperimentalViewModel.cs +++ b/Files/ViewModels/SettingsViewModels/ExperimentalViewModel.cs @@ -1,9 +1,12 @@ using Files.Helpers; +using Files.Services; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Win32; using System; using System.Threading.Tasks; +using System.Windows.Input; using Windows.Foundation.Collections; using Windows.Storage; using Windows.System; @@ -12,31 +15,37 @@ namespace Files.ViewModels.SettingsViewModels { public class ExperimentalViewModel : ObservableObject { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + + public ICommand EditFileTagsCommand { get; } + + public ICommand SetAsDefaultExplorerCommand { get; } + + public ICommand SetAsOpenFileDialogCommand { get; } + public ExperimentalViewModel() { IsSetAsDefaultFileManager = DetectIsSetAsDefaultFileManager(); IsSetAsOpenFileDialog = DetectIsSetAsOpenFileDialog(); - } - private bool areFileTagsEnabled = App.AppSettings.AreFileTagsEnabled; + EditFileTagsCommand = new AsyncRelayCommand(LaunchFileTagsConfigFile); + SetAsDefaultExplorerCommand = new AsyncRelayCommand(SetAsDefaultExplorer); + SetAsOpenFileDialogCommand = new AsyncRelayCommand(SetAsOpenFileDialog); + } public bool AreFileTagsEnabled { - get - { - return areFileTagsEnabled; - } + get => UserSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled; set { - if (SetProperty(ref areFileTagsEnabled, value)) + if (value != UserSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled) { - App.AppSettings.AreFileTagsEnabled = value; + UserSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled = value; + OnPropertyChanged(); } } } - public IRelayCommand EditFileTagsCommand => new AsyncRelayCommand(() => LaunchFileTagsConfigFile()); - private async Task LaunchFileTagsConfigFile() { var configFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appdata:///local/settings/filetags.json")); @@ -55,8 +64,6 @@ await connection.SendMessageAsync(new ValueSet() } } - public AsyncRelayCommand SetAsDefaultExplorerCommand => new AsyncRelayCommand(() => SetAsDefaultExplorer()); - private async Task SetAsDefaultExplorer() { if (IsSetAsDefaultFileManager == DetectIsSetAsDefaultFileManager()) @@ -80,8 +87,6 @@ private async Task SetAsDefaultExplorer() } } - public AsyncRelayCommand SetAsOpenFileDialogCommand => new AsyncRelayCommand(() => SetAsOpenFileDialog()); - private async Task SetAsOpenFileDialog() { if (IsSetAsOpenFileDialog == DetectIsSetAsOpenFileDialog()) @@ -103,13 +108,13 @@ private async Task SetAsOpenFileDialog() private bool DetectIsSetAsDefaultFileManager() { using var subkey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\Directory\shell"); - return subkey?.GetValue("") as string == "openinfiles"; + return subkey?.GetValue(string.Empty) as string == "openinfiles"; } private bool DetectIsSetAsOpenFileDialog() { using var subkey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\CLSID\{DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7}"); - return subkey?.GetValue("") as string == "FilesOpenDialog class"; + return subkey?.GetValue(string.Empty) as string == "FilesOpenDialog class"; } private bool isSetAsDefaultFileManager; diff --git a/Files/ViewModels/SettingsViewModels/FilesAndFoldersViewModel.cs b/Files/ViewModels/SettingsViewModels/FilesAndFoldersViewModel.cs index e4a16cca7a3d..8ba00ce29781 100644 --- a/Files/ViewModels/SettingsViewModels/FilesAndFoldersViewModel.cs +++ b/Files/ViewModels/SettingsViewModels/FilesAndFoldersViewModel.cs @@ -1,118 +1,100 @@ -using Microsoft.Toolkit.Mvvm.ComponentModel; +using Files.Services; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; namespace Files.ViewModels.SettingsViewModels { public class FilesAndFoldersViewModel : ObservableObject { - private bool areHiddenItemsVisible = App.AppSettings.AreHiddenItemsVisible; - private bool areSystemItemsHidden = App.AppSettings.AreSystemItemsHidden; - private bool showFileExtensions = App.AppSettings.ShowFileExtensions; - private bool openItemsWithOneclick = App.AppSettings.OpenItemsWithOneclick; - private bool listAndSortDirectoriesAlongsideFiles = App.AppSettings.ListAndSortDirectoriesAlongsideFiles; - private bool searchUnindexedItems = App.AppSettings.SearchUnindexedItems; - private bool areLayoutPreferencesPerFolder = App.AppSettings.AreLayoutPreferencesPerFolder; + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); public bool AreHiddenItemsVisible { - get - { - return areHiddenItemsVisible; - } + get => UserSettingsService.FilesAndFoldersSettingsService.AreHiddenItemsVisible; set { - if (SetProperty(ref areHiddenItemsVisible, value)) + if (value != UserSettingsService.FilesAndFoldersSettingsService.AreHiddenItemsVisible) { - App.AppSettings.AreHiddenItemsVisible = value; + UserSettingsService.FilesAndFoldersSettingsService.AreHiddenItemsVisible = value; + OnPropertyChanged(); } } } public bool AreSystemItemsHidden { - get - { - return areSystemItemsHidden; - } + get => UserSettingsService.FilesAndFoldersSettingsService.AreSystemItemsHidden; set { - if (SetProperty(ref areSystemItemsHidden, value)) + if (value != UserSettingsService.FilesAndFoldersSettingsService.AreSystemItemsHidden) { - App.AppSettings.AreSystemItemsHidden = value; + UserSettingsService.FilesAndFoldersSettingsService.AreSystemItemsHidden = value; + OnPropertyChanged(); } } } public bool ShowFileExtensions { - get - { - return showFileExtensions; - } + get => UserSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions; set { - if (SetProperty(ref showFileExtensions, value)) + if (value != UserSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions) { - App.AppSettings.ShowFileExtensions = value; + UserSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions = value; + OnPropertyChanged(); } } } public bool OpenItemsWithOneclick { - get - { - return openItemsWithOneclick; - } + get => UserSettingsService.FilesAndFoldersSettingsService.OpenItemsWithOneclick; set { - if (SetProperty(ref openItemsWithOneclick, value)) + if (value != UserSettingsService.FilesAndFoldersSettingsService.OpenItemsWithOneclick) { - App.AppSettings.OpenItemsWithOneclick = value; + UserSettingsService.FilesAndFoldersSettingsService.OpenItemsWithOneclick = value; + OnPropertyChanged(); } } } public bool ListAndSortDirectoriesAlongsideFiles { - get - { - return listAndSortDirectoriesAlongsideFiles; - } + get => UserSettingsService.FilesAndFoldersSettingsService.ListAndSortDirectoriesAlongsideFiles; set { - if (SetProperty(ref listAndSortDirectoriesAlongsideFiles, value)) + if (value != UserSettingsService.FilesAndFoldersSettingsService.ListAndSortDirectoriesAlongsideFiles) { - App.AppSettings.ListAndSortDirectoriesAlongsideFiles = value; + UserSettingsService.FilesAndFoldersSettingsService.ListAndSortDirectoriesAlongsideFiles = value; + OnPropertyChanged(); } } } public bool SearchUnindexedItems { - get - { - return searchUnindexedItems; - } + get => UserSettingsService.FilesAndFoldersSettingsService.SearchUnindexedItems; set { - if (SetProperty(ref searchUnindexedItems, value)) + if (value != UserSettingsService.FilesAndFoldersSettingsService.SearchUnindexedItems) { - App.AppSettings.SearchUnindexedItems = value; + UserSettingsService.FilesAndFoldersSettingsService.SearchUnindexedItems = value; + OnPropertyChanged(); } } } public bool AreLayoutPreferencesPerFolder { - get - { - return areLayoutPreferencesPerFolder; - } + get => UserSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder; set { - if (SetProperty(ref areLayoutPreferencesPerFolder, value)) + if (value != UserSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder) { - App.AppSettings.AreLayoutPreferencesPerFolder = value; + UserSettingsService.FilesAndFoldersSettingsService.AreLayoutPreferencesPerFolder = value; + OnPropertyChanged(); } } } diff --git a/Files/ViewModels/SettingsViewModels/MultitaskingViewModel.cs b/Files/ViewModels/SettingsViewModels/MultitaskingViewModel.cs index 685ff6208a89..9dc6886c74d8 100644 --- a/Files/ViewModels/SettingsViewModels/MultitaskingViewModel.cs +++ b/Files/ViewModels/SettingsViewModels/MultitaskingViewModel.cs @@ -1,55 +1,48 @@ -using Microsoft.Toolkit.Mvvm.ComponentModel; +using Files.Services; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; namespace Files.ViewModels.SettingsViewModels { public class MultitaskingViewModel : ObservableObject { - private bool isVerticalTabFlyoutEnabled = App.AppSettings.IsVerticalTabFlyoutEnabled; + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); public bool IsVerticalTabFlyoutEnabled { - get - { - return isVerticalTabFlyoutEnabled; - } + get => UserSettingsService.MultitaskingSettingsService.IsVerticalTabFlyoutEnabled; set { - if (SetProperty(ref isVerticalTabFlyoutEnabled, value)) + if (value != UserSettingsService.MultitaskingSettingsService.IsVerticalTabFlyoutEnabled) { - App.AppSettings.IsVerticalTabFlyoutEnabled = value; + UserSettingsService.MultitaskingSettingsService.IsVerticalTabFlyoutEnabled = value; + OnPropertyChanged(); } } } - private bool isDualPaneEnabled = App.AppSettings.IsDualPaneEnabled; - private bool alwaysOpenDualPaneInNewTab = App.AppSettings.AlwaysOpenDualPaneInNewTab; - public bool IsDualPaneEnabled { - get - { - return isDualPaneEnabled; - } + get => UserSettingsService.MultitaskingSettingsService.IsDualPaneEnabled; set { - if (SetProperty(ref isDualPaneEnabled, value)) + if (value != UserSettingsService.MultitaskingSettingsService.IsDualPaneEnabled) { - App.AppSettings.IsDualPaneEnabled = value; + UserSettingsService.MultitaskingSettingsService.IsDualPaneEnabled = value; + OnPropertyChanged(); } } } public bool AlwaysOpenDualPaneInNewTab { - get - { - return alwaysOpenDualPaneInNewTab; - } + get => UserSettingsService.MultitaskingSettingsService.AlwaysOpenDualPaneInNewTab; set { - if (SetProperty(ref alwaysOpenDualPaneInNewTab, value)) + if (value != UserSettingsService.MultitaskingSettingsService.AlwaysOpenDualPaneInNewTab) { - App.AppSettings.AlwaysOpenDualPaneInNewTab = value; + UserSettingsService.MultitaskingSettingsService.AlwaysOpenDualPaneInNewTab = value; + OnPropertyChanged(); } } } diff --git a/Files/ViewModels/SettingsViewModels/OnStartupViewModel.cs b/Files/ViewModels/SettingsViewModels/OnStartupViewModel.cs index 17004dba13e2..b732ad0b8d7a 100644 --- a/Files/ViewModels/SettingsViewModels/OnStartupViewModel.cs +++ b/Files/ViewModels/SettingsViewModels/OnStartupViewModel.cs @@ -1,7 +1,10 @@ using Files.Common; using Files.Enums; using Files.Filesystem; +using Files.Helpers; +using Files.Services; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using System; @@ -18,19 +21,17 @@ namespace Files.ViewModels.SettingsViewModels { public class OnStartupViewModel : ObservableObject { - private bool openNewTabPageOnStartup = App.AppSettings.OpenNewTabPageOnStartup; - private bool continueLastSessionOnStartUp = App.AppSettings.ContinueLastSessionOnStartUp; - private bool openASpecificPageOnStartup = App.AppSettings.OpenASpecificPageOnStartup; + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + private int selectedPageIndex = -1; private bool isPageListEditEnabled; - private bool alwaysOpenANewInstance = App.AppSettings.AlwaysOpenANewInstance; private ReadOnlyCollection addFlyoutItemsSource; public OnStartupViewModel() { - if (App.AppSettings.PagesOnStartupList != null) + if (UserSettingsService.StartupSettingsService.TabsOnStartupList != null) { - PagesOnStartupList = new ObservableCollection(App.AppSettings.PagesOnStartupList.Select((p) => new PageOnStartupViewModel(p))); + PagesOnStartupList = new ObservableCollection(UserSettingsService.StartupSettingsService.TabsOnStartupList.Select((p) => new PageOnStartupViewModel(p))); } else { @@ -107,46 +108,49 @@ private void PagesOnStartupList_CollectionChanged(object sender, NotifyCollectio { if (PagesOnStartupList.Count() > 0) { - App.AppSettings.PagesOnStartupList = PagesOnStartupList.Select((p) => p.Path).ToArray(); + UserSettingsService.StartupSettingsService.TabsOnStartupList = PagesOnStartupList.Select((p) => p.Path).ToList(); } else { - App.AppSettings.PagesOnStartupList = null; + UserSettingsService.StartupSettingsService.TabsOnStartupList = null; } } public bool OpenNewTabPageOnStartup { - get => openNewTabPageOnStartup; + get => UserSettingsService.StartupSettingsService.OpenNewTabOnStartup; set { - if (SetProperty(ref openNewTabPageOnStartup, value)) + if (value != UserSettingsService.StartupSettingsService.OpenNewTabOnStartup) { - App.AppSettings.OpenNewTabPageOnStartup = value; + UserSettingsService.StartupSettingsService.OpenNewTabOnStartup = value; + OnPropertyChanged(); } } } public bool ContinueLastSessionOnStartUp { - get => continueLastSessionOnStartUp; + get => UserSettingsService.StartupSettingsService.ContinueLastSessionOnStartUp; set { - if (SetProperty(ref continueLastSessionOnStartUp, value)) + if (value != UserSettingsService.StartupSettingsService.ContinueLastSessionOnStartUp) { - App.AppSettings.ContinueLastSessionOnStartUp = value; + UserSettingsService.StartupSettingsService.ContinueLastSessionOnStartUp = value; + OnPropertyChanged(); } } } public bool OpenASpecificPageOnStartup { - get => openASpecificPageOnStartup; + get => UserSettingsService.StartupSettingsService.OpenSpecificPageOnStartup; set { - if (SetProperty(ref openASpecificPageOnStartup, value)) + if (value != UserSettingsService.StartupSettingsService.OpenSpecificPageOnStartup) { - App.AppSettings.OpenASpecificPageOnStartup = value; + UserSettingsService.StartupSettingsService.OpenSpecificPageOnStartup = value; + OnPropertyChanged(); } } } @@ -183,12 +187,13 @@ public ReadOnlyCollection AddFlyoutItemsSource public bool AlwaysOpenANewInstance { - get => alwaysOpenANewInstance; + get => UserSettingsService.StartupSettingsService.AlwaysOpenNewInstance; set { - if (SetProperty(ref alwaysOpenANewInstance, value)) + if (value != UserSettingsService.StartupSettingsService.AlwaysOpenNewInstance) { - App.AppSettings.AlwaysOpenANewInstance = alwaysOpenANewInstance; + UserSettingsService.StartupSettingsService.AlwaysOpenNewInstance = value; + OnPropertyChanged(); } } } @@ -255,7 +260,7 @@ public string Text { return "SidebarHome".GetLocalized(); } - if (Path == App.AppSettings.RecycleBinPath) + if (Path == CommonPaths.RecycleBinPath) { return ApplicationData.Current.LocalSettings.Values.Get("RecycleBin_Title", "Recycle Bin"); } diff --git a/Files/ViewModels/SettingsViewModels/PreferencesViewModel.cs b/Files/ViewModels/SettingsViewModels/PreferencesViewModel.cs index 2e14f7b77051..127cbda852c0 100644 --- a/Files/ViewModels/SettingsViewModels/PreferencesViewModel.cs +++ b/Files/ViewModels/SettingsViewModels/PreferencesViewModel.cs @@ -1,13 +1,16 @@ using Files.DataModels; using Files.Enums; using Files.Helpers; +using Files.Services; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Threading.Tasks; +using System.Windows.Input; using Windows.Foundation.Collections; using Windows.Storage; using Windows.System; @@ -16,23 +19,26 @@ namespace Files.ViewModels.SettingsViewModels { public class PreferencesViewModel : ObservableObject { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + private int selectedLanguageIndex = App.AppSettings.DefaultLanguages.IndexOf(App.AppSettings.DefaultLanguage); private bool showRestartControl; private Terminal selectedTerminal = App.TerminalController.Model.GetDefaultTerminal(); - private bool showConfirmDeleteDialog = App.AppSettings.ShowConfirmDeleteDialog; - private bool openFoldersNewTab = App.AppSettings.OpenFoldersNewTab; private int selectedDateFormatIndex = (int)Enum.Parse(typeof(TimeStyle), App.AppSettings.DisplayedTimeStyle.ToString()); + public ICommand EditTerminalApplicationsCommand { get; } + public PreferencesViewModel() { DefaultLanguages = App.AppSettings.DefaultLanguages; Terminals = App.TerminalController.Model.Terminals; - DateFormats = new List { "ApplicationTimeStye".GetLocalized(), "SystemTimeStye".GetLocalized() }; + + EditTerminalApplicationsCommand = new AsyncRelayCommand(LaunchTerminalsConfigFile); } public List DateFormats { get; set; } @@ -96,34 +102,28 @@ public Terminal SelectedTerminal } } - public IRelayCommand EditTerminalApplicationsCommand => new AsyncRelayCommand(() => LaunchTerminalsConfigFile()); - public bool ShowConfirmDeleteDialog { - get - { - return showConfirmDeleteDialog; - } + get => UserSettingsService.PreferencesSettingsService.ShowConfirmDeleteDialog; set { - if (SetProperty(ref showConfirmDeleteDialog, value)) + if (value != UserSettingsService.PreferencesSettingsService.ShowConfirmDeleteDialog) { - App.AppSettings.ShowConfirmDeleteDialog = value; + UserSettingsService.PreferencesSettingsService.ShowConfirmDeleteDialog = value; + OnPropertyChanged(); } } } public bool OpenFoldersNewTab { - get - { - return openFoldersNewTab; - } + get => UserSettingsService.PreferencesSettingsService.OpenFoldersInNewTab; set { - if (SetProperty(ref openFoldersNewTab, value)) + if (value != UserSettingsService.PreferencesSettingsService.OpenFoldersInNewTab) { - App.AppSettings.OpenFoldersNewTab = value; + UserSettingsService.PreferencesSettingsService.OpenFoldersInNewTab = value; + OnPropertyChanged(); } } } diff --git a/Files/ViewModels/SettingsViewModels/SidebarViewModel.cs b/Files/ViewModels/SettingsViewModels/SidebarViewModel.cs index aba48a9da268..12a80e014568 100644 --- a/Files/ViewModels/SettingsViewModels/SidebarViewModel.cs +++ b/Files/ViewModels/SettingsViewModels/SidebarViewModel.cs @@ -1,128 +1,107 @@ -using Microsoft.Toolkit.Mvvm.ComponentModel; +using Files.Services; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; namespace Files.ViewModels.SettingsViewModels { public class SidebarViewModel : ObservableObject { - private bool showFavoritesSection = App.AppSettings.ShowFavoritesSection; - private bool pinRecycleBinToSideBar = App.AppSettings.PinRecycleBinToSideBar; - private bool showLibrarySection = App.AppSettings.ShowLibrarySection; - private bool showDrivesSection = App.AppSettings.ShowDrivesSection; - private bool showCloudDrivesSection = App.AppSettings.ShowCloudDrivesSection; - private bool showNetworkDrivesSection = App.AppSettings.ShowNetworkDrivesSection; - private bool showWslSection = App.AppSettings.ShowWslSection; - - public SidebarViewModel() - { - } + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); public bool ShowFavoritesSection { - get - { - return showFavoritesSection; - } + get => UserSettingsService.SidebarSettingsService.ShowFavoritesSection; set { - if (SetProperty(ref showFavoritesSection, value)) + if (value != UserSettingsService.SidebarSettingsService.ShowFavoritesSection) { - App.AppSettings.ShowFavoritesSection = value; + UserSettingsService.SidebarSettingsService.ShowFavoritesSection = value; App.SidebarPinnedController.Model.UpdateFavoritesSectionVisibility(); + OnPropertyChanged(); } } } public bool PinRecycleBinToSideBar { - get - { - return pinRecycleBinToSideBar; - } + get => UserSettingsService.SidebarSettingsService.PinRecycleBinToSidebar; set { - if (SetProperty(ref pinRecycleBinToSideBar, value)) + if (value != UserSettingsService.SidebarSettingsService.PinRecycleBinToSidebar) { - App.AppSettings.PinRecycleBinToSideBar = value; + UserSettingsService.SidebarSettingsService.PinRecycleBinToSidebar = value; + _= App.SidebarPinnedController.Model.ShowHideRecycleBinItemAsync(value); + OnPropertyChanged(); } } } public bool ShowLibrarySection { - get - { - return showLibrarySection; - } + get => UserSettingsService.SidebarSettingsService.ShowLibrarySection; set { - if (SetProperty(ref showLibrarySection, value)) + if (value != UserSettingsService.SidebarSettingsService.ShowLibrarySection) { - App.AppSettings.ShowLibrarySection = value; + UserSettingsService.SidebarSettingsService.ShowLibrarySection = value; App.LibraryManager.UpdateLibrariesSectionVisibility(); + OnPropertyChanged(); } } } public bool ShowDrivesSection { - get - { - return showDrivesSection; - } + get => UserSettingsService.SidebarSettingsService.ShowDrivesSection; set { - if (SetProperty(ref showDrivesSection, value)) + if (value != UserSettingsService.SidebarSettingsService.ShowDrivesSection) { - App.AppSettings.ShowDrivesSection = value; + UserSettingsService.SidebarSettingsService.ShowDrivesSection = value; App.DrivesManager.UpdateDrivesSectionVisibility(); + OnPropertyChanged(); } } } public bool ShowCloudDrivesSection { - get - { - return showCloudDrivesSection; - } + get => UserSettingsService.SidebarSettingsService.ShowCloudDrivesSection; set { - if (SetProperty(ref showCloudDrivesSection, value)) + if (value != UserSettingsService.SidebarSettingsService.ShowCloudDrivesSection) { - App.AppSettings.ShowCloudDrivesSection = value; + UserSettingsService.SidebarSettingsService.ShowCloudDrivesSection = value; App.CloudDrivesManager.UpdateCloudDrivesSectionVisibility(); + OnPropertyChanged(); } } } public bool ShowNetworkDrivesSection { - get - { - return showNetworkDrivesSection; - } + get => UserSettingsService.SidebarSettingsService.ShowNetworkDrivesSection; set { - if (SetProperty(ref showNetworkDrivesSection, value)) + if (value != UserSettingsService.SidebarSettingsService.ShowNetworkDrivesSection) { - App.AppSettings.ShowNetworkDrivesSection = value; + UserSettingsService.SidebarSettingsService.ShowNetworkDrivesSection = value; App.NetworkDrivesManager.UpdateNetworkDrivesSectionVisibility(); + OnPropertyChanged(); } } } public bool ShowWslSection { - get - { - return showWslSection; - } + get => UserSettingsService.SidebarSettingsService.ShowWslSection; set { - if (SetProperty(ref showWslSection, value)) + if (value != UserSettingsService.SidebarSettingsService.ShowWslSection) { - App.AppSettings.ShowWslSection = value; + UserSettingsService.SidebarSettingsService.ShowWslSection = value; App.WSLDistroManager.UpdateWslSectionVisibility(); + OnPropertyChanged(); } } } diff --git a/Files/ViewModels/SidebarViewModel.cs b/Files/ViewModels/SidebarViewModel.cs index 2ad8ee938ff9..da5719f7c508 100644 --- a/Files/ViewModels/SidebarViewModel.cs +++ b/Files/ViewModels/SidebarViewModel.cs @@ -2,8 +2,10 @@ using Files.DataModels.NavigationControlItems; using Files.Filesystem; using Files.Helpers; +using Files.Services; using Files.UserControls; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using Microsoft.UI.Xaml.Controls; @@ -19,6 +21,7 @@ namespace Files.ViewModels { public class SidebarViewModel : ObservableObject, IDisposable { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); public ICommand EmptyRecycleBinCommand { get; private set; } private IPaneHolder paneHolder; @@ -102,13 +105,13 @@ public void UpdateSidebarSelectedItemFromArgs(string arg) public bool IsSidebarOpen { - get => App.AppSettings.IsSidebarOpen; + get => UserSettingsService.SidebarSettingsService.IsSidebarOpen; set { - if (App.AppSettings.IsSidebarOpen != value) + if (value != UserSettingsService.SidebarSettingsService.IsSidebarOpen) { - App.AppSettings.IsSidebarOpen = value; - OnPropertyChanged(nameof(IsSidebarOpen)); + UserSettingsService.SidebarSettingsService.IsSidebarOpen = value; + OnPropertyChanged(); } } } @@ -124,7 +127,7 @@ public INavigationControlItem SidebarSelectedItem public SidebarViewModel() { EmptyRecycleBinCommand = new RelayCommand(EmptyRecycleBin); - App.AppSettings.PropertyChanged += AppSettings_PropertyChanged; + UserSettingsService.OnSettingChangedEvent += UserSettingsService_OnSettingChangedEvent; } public async void EmptyRecycleBin(RoutedEventArgs e) @@ -132,12 +135,12 @@ public async void EmptyRecycleBin(RoutedEventArgs e) await RecycleBinHelpers.S_EmptyRecycleBin(); } - private void AppSettings_PropertyChanged(object sender, PropertyChangedEventArgs e) + private void UserSettingsService_OnSettingChangedEvent(object sender, EventArguments.SettingChangedEventArgs e) { - switch (e.PropertyName) + switch (e.settingName) { - case nameof(App.AppSettings.IsSidebarOpen): - if (App.AppSettings.IsSidebarOpen != IsSidebarOpen) + case nameof(UserSettingsService.SidebarSettingsService.IsSidebarOpen): + if (UserSettingsService.SidebarSettingsService.IsSidebarOpen != IsSidebarOpen) { OnPropertyChanged(nameof(IsSidebarOpen)); } @@ -147,7 +150,7 @@ private void AppSettings_PropertyChanged(object sender, PropertyChangedEventArgs public void Dispose() { - App.AppSettings.PropertyChanged -= AppSettings_PropertyChanged; + UserSettingsService.OnSettingChangedEvent -= UserSettingsService_OnSettingChangedEvent; } public void SidebarControl_DisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args) diff --git a/Files/ViewModels/Widgets/Bundles/BundleContainerViewModel.cs b/Files/ViewModels/Widgets/Bundles/BundleContainerViewModel.cs index 70a5d79a3d95..f2c0b8dd0bc4 100644 --- a/Files/ViewModels/Widgets/Bundles/BundleContainerViewModel.cs +++ b/Files/ViewModels/Widgets/Bundles/BundleContainerViewModel.cs @@ -2,9 +2,10 @@ using Files.Enums; using Files.Filesystem; using Files.Helpers; -using Files.SettingsInterfaces; +using Files.Services; using Files.ViewModels.Dialogs; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using System; @@ -30,7 +31,7 @@ public class BundleContainerViewModel : ObservableObject, IDisposable { #region Singleton - private IBundlesSettings BundlesSettings => App.BundlesSettings; + private IBundlesSettingsService BundlesSettingsService { get; } = Ioc.Default.GetService(); #endregion Singleton @@ -162,11 +163,11 @@ private async Task AddFile() private void RemoveBundle() { - if (BundlesSettings.SavedBundles.ContainsKey(BundleName)) + if (BundlesSettingsService.SavedBundles.ContainsKey(BundleName)) { - Dictionary> allBundles = BundlesSettings.SavedBundles; + Dictionary> allBundles = BundlesSettingsService.SavedBundles; allBundles.Remove(BundleName); - BundlesSettings.SavedBundles = allBundles; + BundlesSettingsService.SavedBundles = allBundles; NotifyItemRemoved(this); } } @@ -256,9 +257,9 @@ private void RenameBundleConfirm(string bundleRenameText) { if (CanRenameBundle(bundleRenameText).result) { - if (BundlesSettings.SavedBundles.ContainsKey(BundleName)) + if (BundlesSettingsService.SavedBundles.ContainsKey(BundleName)) { - Dictionary> allBundles = BundlesSettings.SavedBundles; // We need to do it this way for Set() to be called + Dictionary> allBundles = BundlesSettingsService.SavedBundles; // We need to do it this way for Set() to be called Dictionary> newBundles = new Dictionary>(); foreach (var item in allBundles) @@ -279,7 +280,7 @@ private void RenameBundleConfirm(string bundleRenameText) } } - BundlesSettings.SavedBundles = newBundles; + BundlesSettingsService.SavedBundles = newBundles; BundleName = bundleRenameText; } } @@ -359,11 +360,11 @@ private async Task Drop(DragEventArgs e) if (itemsAdded && dragFromBundle) { // Also remove the item from the collection - if (BundlesSettings.SavedBundles.ContainsKey(BundleName)) + if (BundlesSettingsService.SavedBundles.ContainsKey(BundleName)) { - Dictionary> allBundles = BundlesSettings.SavedBundles; + Dictionary> allBundles = BundlesSettingsService.SavedBundles; allBundles[originBundle].Remove(itemPath); - BundlesSettings.SavedBundles = allBundles; + BundlesSettingsService.SavedBundles = allBundles; NotifyBundleItemRemoved(originBundle, itemPath); } @@ -427,12 +428,12 @@ private void Contents_CollectionChanged(object sender, NotifyCollectionChangedEv private bool SaveBundle() { - if (BundlesSettings.SavedBundles.ContainsKey(BundleName)) + if (BundlesSettingsService.SavedBundles.ContainsKey(BundleName)) { - Dictionary> allBundles = BundlesSettings.SavedBundles; + Dictionary> allBundles = BundlesSettingsService.SavedBundles; allBundles[BundleName] = Contents.Select((item) => item.Path).ToList(); - BundlesSettings.SavedBundles = allBundles; + BundlesSettingsService.SavedBundles = allBundles; return true; } @@ -535,7 +536,7 @@ public async Task SetBundleItems(IEnumerable item.Key == name)) + if (!BundlesSettingsService.SavedBundles.Any((item) => item.Key == name)) { return (true, string.Empty); } diff --git a/Files/ViewModels/Widgets/Bundles/BundleItemViewModel.cs b/Files/ViewModels/Widgets/Bundles/BundleItemViewModel.cs index 4cfc51921acb..c0cdd54a31d7 100644 --- a/Files/ViewModels/Widgets/Bundles/BundleItemViewModel.cs +++ b/Files/ViewModels/Widgets/Bundles/BundleItemViewModel.cs @@ -1,8 +1,10 @@ using Files.Extensions; using Files.Filesystem; using Files.Helpers; +using Files.Services; using Files.Views; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using System; using System.Collections.Generic; @@ -26,7 +28,11 @@ public class BundleItemViewModel : ObservableObject, IDisposable #endregion Actions - #region Public Properties + #region Properties + + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + + private IBundlesSettingsService BundlesSettingsService { get; } = Ioc.Default.GetService(); /// /// The name of a bundle this item is contained within @@ -74,10 +80,10 @@ public bool OpenInNewTabLoad public bool OpenInNewPaneLoad { - get => App.AppSettings.IsDualPaneEnabled && TargetType == FilesystemItemType.Directory; + get => UserSettingsService.MultitaskingSettingsService.IsDualPaneEnabled && TargetType == FilesystemItemType.Directory; } - #endregion Public Properties + #endregion Properties #region Commands @@ -152,11 +158,11 @@ public void OpenItem() public void RemoveItem() { - if (App.BundlesSettings.SavedBundles.ContainsKey(ParentBundleName)) + if (BundlesSettingsService.SavedBundles.ContainsKey(ParentBundleName)) { - Dictionary> allBundles = App.BundlesSettings.SavedBundles; + Dictionary> allBundles = BundlesSettingsService.SavedBundles; allBundles[ParentBundleName].Remove(Path); - App.BundlesSettings.SavedBundles = allBundles; + BundlesSettingsService.SavedBundles = allBundles; NotifyItemRemoved(this); } } diff --git a/Files/ViewModels/Widgets/Bundles/BundlesViewModel.cs b/Files/ViewModels/Widgets/Bundles/BundlesViewModel.cs index d5372c0bdf0e..7d4195686f6c 100644 --- a/Files/ViewModels/Widgets/Bundles/BundlesViewModel.cs +++ b/Files/ViewModels/Widgets/Bundles/BundlesViewModel.cs @@ -3,8 +3,10 @@ using Files.EventArguments.Bundles; using Files.Filesystem; using Files.Helpers; +using Files.Services; using Files.ViewModels.Dialogs; using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using Newtonsoft.Json; @@ -41,7 +43,9 @@ public class BundlesViewModel : ObservableObject, IDisposable public event EventHandler OpenPathInNewPaneEvent; - #region Public Properties + #region Properties + + private IBundlesSettingsService BundlesSettingsService { get; } = Ioc.Default.GetService(); /// /// Collection of all bundles @@ -72,7 +76,7 @@ public bool NoBundlesAddItemLoad set => SetProperty(ref noBundlesAddItemLoad, value); } - #endregion Public Properties + #endregion Properties #region Commands @@ -194,9 +198,9 @@ private void AddBundle(string name) string savedBundleNameTextInput = name; BundleNameTextInput = string.Empty; - if (App.BundlesSettings.SavedBundles == null || (App.BundlesSettings.SavedBundles?.ContainsKey(savedBundleNameTextInput) ?? false)) // Init + if (BundlesSettingsService.SavedBundles == null || (BundlesSettingsService.SavedBundles?.ContainsKey(savedBundleNameTextInput) ?? false)) // Init { - App.BundlesSettings.SavedBundles = new Dictionary>() + BundlesSettingsService.SavedBundles = new Dictionary>() { { savedBundleNameTextInput, new List() { null } } }; @@ -231,7 +235,7 @@ private async Task ImportBundles() { string data = NativeFileOperationsHelper.ReadStringFromFile(file.Path); var deserialized = JsonConvert.DeserializeObject>>(data); - App.BundlesSettings.ImportSettings(JsonConvert.DeserializeObject>>(data)); + BundlesSettingsService.ImportSettings(JsonConvert.DeserializeObject>>(data)); await Load(); // Update the collection } catch // Couldn't deserialize, data is corrupted @@ -249,7 +253,7 @@ private async Task ExportBundles() if (file != null) { - NativeFileOperationsHelper.WriteStringToFile(file.Path, (string)App.BundlesSettings.ExportSettings()); + NativeFileOperationsHelper.WriteStringToFile(file.Path, (string)BundlesSettingsService.ExportSettings()); } } @@ -330,7 +334,7 @@ private void Items_CollectionChanged(object sender, NotifyCollectionChangedEvent public void Save() { - if (App.BundlesSettings.SavedBundles != null) + if (BundlesSettingsService.SavedBundles != null) { Dictionary> bundles = new Dictionary>(); @@ -351,18 +355,18 @@ public void Save() bundles.Add(bundle.BundleName, bundleItems); } - App.BundlesSettings.SavedBundles = bundles; // Calls Set() + BundlesSettingsService.SavedBundles = bundles; // Calls Set() } } public async Task Load() { - if (App.BundlesSettings.SavedBundles != null) + if (BundlesSettingsService.SavedBundles != null) { Items.Clear(); // For every bundle in saved bundle collection: - foreach (var bundle in App.BundlesSettings.SavedBundles) + foreach (var bundle in BundlesSettingsService.SavedBundles) { List bundleItems = new List(); diff --git a/Files/Views/ColumnShellPage.xaml.cs b/Files/Views/ColumnShellPage.xaml.cs index 46cd0d654c8c..afffadad8156 100644 --- a/Files/Views/ColumnShellPage.xaml.cs +++ b/Files/Views/ColumnShellPage.xaml.cs @@ -6,10 +6,12 @@ using Files.Filesystem.FilesystemHistory; using Files.Filesystem.Search; using Files.Helpers; +using Files.Services; using Files.UserControls; using Files.UserControls.MultitaskingControl; using Files.ViewModels; using Files.Views.LayoutModes; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using Microsoft.Toolkit.Uwp.UI; @@ -34,6 +36,8 @@ using Windows.UI.Xaml.Media.Animation; using Windows.UI.Xaml.Navigation; +using SortDirection = Files.Enums.SortDirection; + // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 namespace Files.Views @@ -47,7 +51,6 @@ public sealed partial class ColumnShellPage : Page, IShellPage, INotifyPropertyC public IBaseLayout SlimContentPage => ContentPage; public IFilesystemHelpers FilesystemHelpers { get; private set; } private CancellationTokenSource cancellationTokenSource; - public SettingsViewModel AppSettings => App.AppSettings; public bool CanNavigateBackward => ItemDisplayFrame.CanGoBack; public bool CanNavigateForward => ItemDisplayFrame.CanGoForward; @@ -59,6 +62,8 @@ public sealed partial class ColumnShellPage : Page, IShellPage, INotifyPropertyC public bool IsColumnView { get; } = true; + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public bool IsCurrentInstance { get @@ -264,7 +269,7 @@ private async void ColumnShellPage_TextChanged(ISearchBox sender, SearchBoxTextC Query = sender.Query, Folder = FilesystemViewModel.WorkingDirectory, MaxItemCount = 10, - SearchUnindexedItems = App.AppSettings.SearchUnindexedItems + SearchUnindexedItems = UserSettingsService.FilesAndFoldersSettingsService.SearchUnindexedItems }; sender.SetSuggestions(await search.SearchAsync()); } @@ -296,7 +301,7 @@ private void ColumnShellPage_QuerySubmitted(ISearchBox sender, SearchBoxQuerySub { if (e.ChosenSuggestion == null && !string.IsNullOrWhiteSpace(sender.Query)) { - SubmitSearch(sender.Query, App.AppSettings.SearchUnindexedItems); + SubmitSearch(sender.Query, UserSettingsService.FilesAndFoldersSettingsService.SearchUnindexedItems); } } @@ -377,7 +382,7 @@ private void NavigationToolbar_EditModeEnabled(object sender, EventArgs e) NavToolbarViewModel.ManualEntryBoxLoaded = true; NavToolbarViewModel.ClickablePathLoaded = false; NavToolbarViewModel.PathText = string.IsNullOrEmpty(FilesystemViewModel?.WorkingDirectory) - ? AppSettings.HomePath + ? CommonPaths.HomePath : FilesystemViewModel.WorkingDirectory; } @@ -689,7 +694,7 @@ private async void KeyboardAccelerator_Invoked(KeyboardAccelerator sender, Keybo break; case (true, false, false, true, VirtualKey.P): - AppSettings.PreviewPaneEnabled = !AppSettings.PreviewPaneEnabled; + UserSettingsService.PreviewPaneSettingsService.PreviewPaneEnabled = !UserSettingsService.PreviewPaneSettingsService.PreviewPaneEnabled; break; case (true, false, false, true, VirtualKey.R): // ctrl + r, refresh diff --git a/Files/Views/LayoutModes/ColumnViewBase.xaml.cs b/Files/Views/LayoutModes/ColumnViewBase.xaml.cs index fb1cd41f544f..207db3a78554 100644 --- a/Files/Views/LayoutModes/ColumnViewBase.xaml.cs +++ b/Files/Views/LayoutModes/ColumnViewBase.xaml.cs @@ -221,7 +221,7 @@ override public void StartRenameItem() textBox.KeyDown += RenameTextBox_KeyDown; int selectedTextLength = SelectedItem.ItemName.Length; - if (!SelectedItem.IsShortcutItem && App.AppSettings.ShowFileExtensions) + if (!SelectedItem.IsShortcutItem && UserSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions) { selectedTextLength -= extensionLength; } @@ -405,7 +405,7 @@ private async void FileList_PreviewKeyDown(object sender, KeyRoutedEventArgs e) private void FileList_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) { - if ((e.OriginalSource as FrameworkElement)?.DataContext is ListedItem && !AppSettings.OpenItemsWithOneclick) + if ((e.OriginalSource as FrameworkElement)?.DataContext is ListedItem && !UserSettingsService.FilesAndFoldersSettingsService.OpenItemsWithOneclick) { if (listViewItem != null) { @@ -467,7 +467,7 @@ private async void FileList_ItemTapped(object sender, TappedRoutedEventArgs e) return; } // Check if the setting to open items with a single click is turned on - if (AppSettings.OpenItemsWithOneclick) + if (UserSettingsService.FilesAndFoldersSettingsService.OpenItemsWithOneclick) { ResetRenameDoubleClick(); await Task.Delay(200); // The delay gives time for the item to be selected diff --git a/Files/Views/LayoutModes/ColumnViewBrowser.xaml.cs b/Files/Views/LayoutModes/ColumnViewBrowser.xaml.cs index a5a2b050a9d0..41f97407965d 100644 --- a/Files/Views/LayoutModes/ColumnViewBrowser.xaml.cs +++ b/Files/Views/LayoutModes/ColumnViewBrowser.xaml.cs @@ -312,7 +312,7 @@ override public void StartRenameItem() textBox.KeyDown += RenameTextBox_KeyDown; int selectedTextLength = SelectedItem.ItemName.Length; - if (!SelectedItem.IsShortcutItem && App.AppSettings.ShowFileExtensions) + if (!SelectedItem.IsShortcutItem && UserSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions) { selectedTextLength -= extensionLength; } @@ -496,7 +496,7 @@ private async void FileList_PreviewKeyDown(object sender, KeyRoutedEventArgs e) private void FileList_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) { - if ((e.OriginalSource as FrameworkElement)?.DataContext is ListedItem && !AppSettings.OpenItemsWithOneclick) + if ((e.OriginalSource as FrameworkElement)?.DataContext is ListedItem && !UserSettingsService.FilesAndFoldersSettingsService.OpenItemsWithOneclick) { if (listViewItem != null) { @@ -605,7 +605,7 @@ private async void FileList_ItemTapped(object sender, TappedRoutedEventArgs e) return; } // Check if the setting to open items with a single click is turned on - if (AppSettings.OpenItemsWithOneclick) + if (UserSettingsService.FilesAndFoldersSettingsService.OpenItemsWithOneclick) { ResetRenameDoubleClick(); await Task.Delay(200); // The delay gives time for the item to be selected diff --git a/Files/Views/LayoutModes/DetailsLayoutBrowser.xaml.cs b/Files/Views/LayoutModes/DetailsLayoutBrowser.xaml.cs index 174b9fca33c2..436ee0b37077 100644 --- a/Files/Views/LayoutModes/DetailsLayoutBrowser.xaml.cs +++ b/Files/Views/LayoutModes/DetailsLayoutBrowser.xaml.cs @@ -22,6 +22,8 @@ using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; +using SortDirection = Files.Enums.SortDirection; + namespace Files.Views.LayoutModes { public sealed partial class DetailsLayoutBrowser : BaseLayout @@ -281,7 +283,7 @@ private void FilesystemViewModel_PageTypeUpdated(object sender, PageTypeUpdatedE ColumnsViewModel.StatusColumn.Show(); } - if (!App.AppSettings.AreFileTagsEnabled) + if (!UserSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled) { ColumnsViewModel.TagColumn.Hide(); } @@ -356,7 +358,7 @@ override public void StartRenameItem() textBox.KeyDown += RenameTextBox_KeyDown; int selectedTextLength = SelectedItem.ItemName.Length; - if (!SelectedItem.IsShortcutItem && App.AppSettings.ShowFileExtensions) + if (!SelectedItem.IsShortcutItem && UserSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions) { selectedTextLength -= extensionLength; } @@ -578,7 +580,7 @@ private async void FileList_ItemTapped(object sender, TappedRoutedEventArgs e) } // Check if the setting to open items with a single click is turned on - if (AppSettings.OpenItemsWithOneclick) + if (UserSettingsService.FilesAndFoldersSettingsService.OpenItemsWithOneclick) { ResetRenameDoubleClick(); await Task.Delay(200); // The delay gives time for the item to be selected @@ -606,7 +608,7 @@ private async void FileList_ItemTapped(object sender, TappedRoutedEventArgs e) private void FileList_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) { // Skip opening selected items if the double tap doesn't capture an item - if ((e.OriginalSource as FrameworkElement)?.DataContext is ListedItem && !AppSettings.OpenItemsWithOneclick) + if ((e.OriginalSource as FrameworkElement)?.DataContext is ListedItem && !UserSettingsService.FilesAndFoldersSettingsService.OpenItemsWithOneclick) { if (!MainViewModel.MultiselectEnabled) { @@ -748,7 +750,7 @@ private void ResizeColumnToFit(int columnToResize) }; if (columnToResize == 1) { - colunmSizeToFit += AppSettings.AreFileTagsEnabled ? 20 : 0; + colunmSizeToFit += UserSettingsService.FilesAndFoldersSettingsService.AreFileTagsEnabled ? 20 : 0; } column.UserLength = new GridLength(Math.Min(colunmSizeToFit + 30, column.NormalMaxLength), GridUnitType.Pixel); } diff --git a/Files/Views/LayoutModes/GridViewBrowser.xaml.cs b/Files/Views/LayoutModes/GridViewBrowser.xaml.cs index d7a29b578070..05594e5ac31e 100644 --- a/Files/Views/LayoutModes/GridViewBrowser.xaml.cs +++ b/Files/Views/LayoutModes/GridViewBrowser.xaml.cs @@ -269,7 +269,7 @@ override public void StartRenameItem() textBox.KeyDown += RenameTextBox_KeyDown; int selectedTextLength = SelectedItem.ItemName.Length; - if (!SelectedItem.IsShortcutItem && App.AppSettings.ShowFileExtensions) + if (!SelectedItem.IsShortcutItem && UserSettingsService.FilesAndFoldersSettingsService.ShowFileExtensions) { selectedTextLength -= extensionLength; } @@ -498,7 +498,7 @@ private async void FileList_ItemTapped(object sender, TappedRoutedEventArgs e) } // Check if the setting to open items with a single click is turned on - if (AppSettings.OpenItemsWithOneclick) + if (UserSettingsService.FilesAndFoldersSettingsService.OpenItemsWithOneclick) { ResetRenameDoubleClick(); await Task.Delay(200); // The delay gives time for the item to be selected @@ -507,14 +507,13 @@ private async void FileList_ItemTapped(object sender, TappedRoutedEventArgs e) else { var clickedItem = e.OriginalSource as FrameworkElement; - if (clickedItem is TextBlock && ((TextBlock)clickedItem).Name == "ItemName") + if (clickedItem is TextBlock textBlock && textBlock.Name == "ItemName") { CheckRenameDoubleClick(clickedItem?.DataContext); } else if (IsRenamingItem) { - GridViewItem gridViewItem = FileList.ContainerFromItem(RenamingItem) as GridViewItem; - if (gridViewItem != null) + if (FileList.ContainerFromItem(RenamingItem) is GridViewItem gridViewItem) { if (FolderSettings.LayoutMode == FolderLayoutModes.GridView) { @@ -535,7 +534,7 @@ private async void FileList_ItemTapped(object sender, TappedRoutedEventArgs e) private void FileList_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) { // Skip opening selected items if the double tap doesn't capture an item - if ((e.OriginalSource as FrameworkElement)?.DataContext is ListedItem && !AppSettings.OpenItemsWithOneclick) + if ((e.OriginalSource as FrameworkElement)?.DataContext is ListedItem && !UserSettingsService.FilesAndFoldersSettingsService.OpenItemsWithOneclick) { if (!MainViewModel.MultiselectEnabled) { diff --git a/Files/Views/MainPage.xaml b/Files/Views/MainPage.xaml index 5fb439c68fa6..15ca14ca8dd0 100644 --- a/Files/Views/MainPage.xaml +++ b/Files/Views/MainPage.xaml @@ -289,7 +289,7 @@ Height="32" Padding="8" HorizontalAlignment="Right" - x:Load="{x:Bind AppSettings.IsVerticalTabFlyoutEnabled, Mode=OneWay}" + x:Load="{x:Bind IsVerticalTabFlyoutEnabled, Mode=OneWay}" AccessKey="T" AllowDrop="True" AutomationProperties.Name="Vertical tab flyout" diff --git a/Files/Views/MainPage.xaml.cs b/Files/Views/MainPage.xaml.cs index cb01a53d6918..74b259e4332d 100644 --- a/Files/Views/MainPage.xaml.cs +++ b/Files/Views/MainPage.xaml.cs @@ -2,9 +2,11 @@ using Files.Extensions; using Files.Filesystem; using Files.Helpers; +using Files.Services; using Files.UserControls; using Files.UserControls.MultitaskingControl; using Files.ViewModels; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using System; @@ -28,7 +30,8 @@ namespace Files.Views /// public sealed partial class MainPage : Page, INotifyPropertyChanged { - public SettingsViewModel AppSettings => App.AppSettings; + public IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public MainViewModel MainViewModel => App.MainViewModel; public MainPageViewModel ViewModel @@ -46,6 +49,8 @@ public MainPageViewModel ViewModel private ICommand ToggleCompactOverlayCommand => new RelayCommand(x => ToggleCompactOverlay()); private ICommand SetCompactOverlayCommand => new RelayCommand(x => SetCompactOverlay(x)); + public bool IsVerticalTabFlyoutEnabled => UserSettingsService.MultitaskingSettingsService.IsVerticalTabFlyoutEnabled; + public MainPage() { this.InitializeComponent(); @@ -64,16 +69,20 @@ public MainPage() ToggleFullScreenAcceleratorCommand = new RelayCommand(ToggleFullScreenAccelerator); - App.AppSettings.PropertyChanged += AppSettings_PropertyChanged; + UserSettingsService.OnSettingChangedEvent += UserSettingsService_OnSettingChangedEvent; } - private void AppSettings_PropertyChanged(object sender, PropertyChangedEventArgs e) + private void UserSettingsService_OnSettingChangedEvent(object sender, EventArguments.SettingChangedEventArgs e) { - switch (e.PropertyName) + switch (e.settingName) { - case nameof(App.AppSettings.PreviewPaneEnabled): + case nameof(UserSettingsService.PreviewPaneSettingsService.PreviewPaneEnabled): LoadPreviewPaneChanged(); break; + + case nameof(UserSettingsService.MultitaskingSettingsService.IsVerticalTabFlyoutEnabled): + OnPropertyChanged(nameof(IsVerticalTabFlyoutEnabled)); + break; } } @@ -119,7 +128,7 @@ private void HorizontalMultitaskingControl_Loaded(object sender, RoutedEventArgs ViewModel.MultitaskingControls.Add(horizontalMultitaskingControl); ViewModel.MultitaskingControl.CurrentInstanceChanged += MultitaskingControl_CurrentInstanceChanged; } - if (AppSettings.IsVerticalTabFlyoutEnabled) + if (UserSettingsService.MultitaskingSettingsService.IsVerticalTabFlyoutEnabled) { FindName(nameof(VerticalTabStripInvokeButton)); } @@ -380,14 +389,14 @@ private void UpdatePositioning() PreviewPaneRow.MinHeight = 0; PreviewPaneRow.Height = new GridLength(0); PreviewPaneColumn.MinWidth = 150; - PreviewPaneColumn.Width = AppSettings.PreviewPaneSizeVertical; + PreviewPaneColumn.Width = new GridLength(UserSettingsService.PreviewPaneSettingsService.PreviewPaneSizeVerticalPx, GridUnitType.Pixel); PreviewPane.IsHorizontal = false; } else if (RootGrid.ActualWidth <= 700) { PreviewPaneRow.MinHeight = 140; - PreviewPaneRow.Height = AppSettings.PreviewPaneSizeHorizontal; + PreviewPaneRow.Height = new GridLength(UserSettingsService.PreviewPaneSettingsService.PreviewPaneSizeHorizontalPx, GridUnitType.Pixel); PreviewPaneColumn.MinWidth = 0; PreviewPaneColumn.Width = new GridLength(0); @@ -412,23 +421,23 @@ private void PreviewPaneGridSplitter_ManipulationCompleted(object sender, Manipu if (PreviewPane.IsHorizontal) { - AppSettings.PreviewPaneSizeHorizontal = new GridLength(PreviewPane.ActualHeight); + UserSettingsService.PreviewPaneSettingsService.PreviewPaneSizeHorizontalPx = Math.Max(50d, Math.Min(PreviewPane.ActualHeight, 600d)); } else { - AppSettings.PreviewPaneSizeVertical = new GridLength(PreviewPane.ActualWidth); + UserSettingsService.PreviewPaneSettingsService.PreviewPaneSizeVerticalPx = Math.Max(50d, Math.Min(PreviewPane.ActualWidth, 600d)); } } - public bool LoadPreviewPane => App.AppSettings.PreviewPaneEnabled && !IsPreviewPaneDisabled; + public bool LoadPreviewPane => UserSettingsService.PreviewPaneSettingsService.PreviewPaneEnabled && !IsPreviewPaneDisabled; public bool IsPreviewPaneDisabled => (!(SidebarAdaptiveViewModel.PaneHolder?.ActivePane.InstanceViewModel.IsPageTypeNotHome ?? false) && !(SidebarAdaptiveViewModel.PaneHolder?.IsMultiPaneActive ?? false)) // hide the preview pane when on home page unless multi pane is in use || Window.Current.Bounds.Width <= 450 || Window.Current.Bounds.Height <= 400; // Disable the preview pane for small windows as it won't function properly private void LoadPreviewPaneChanged() { - NotifyPropertyChanged(nameof(LoadPreviewPane)); - NotifyPropertyChanged(nameof(IsPreviewPaneDisabled)); + OnPropertyChanged(nameof(LoadPreviewPane)); + OnPropertyChanged(nameof(IsPreviewPaneDisabled)); UpdatePositioning(); } @@ -441,7 +450,7 @@ private void PreviewPane_Loading(FrameworkElement sender, object args) public event PropertyChangedEventHandler PropertyChanged; - private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") + private void OnPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } @@ -473,7 +482,7 @@ public bool IsCompactOverlay if (value != isCompactOverlay) { isCompactOverlay = value; - NotifyPropertyChanged(nameof(IsCompactOverlay)); + OnPropertyChanged(nameof(IsCompactOverlay)); } } } diff --git a/Files/Views/ModernShellPage.xaml.cs b/Files/Views/ModernShellPage.xaml.cs index cec56eb4bb41..233f777bd327 100644 --- a/Files/Views/ModernShellPage.xaml.cs +++ b/Files/Views/ModernShellPage.xaml.cs @@ -6,10 +6,12 @@ using Files.Filesystem.FilesystemHistory; using Files.Filesystem.Search; using Files.Helpers; +using Files.Services; using Files.UserControls; using Files.UserControls.MultitaskingControl; using Files.ViewModels; using Files.Views.LayoutModes; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using Microsoft.Toolkit.Uwp.UI; @@ -34,6 +36,8 @@ using Windows.UI.Xaml.Media.Animation; using Windows.UI.Xaml.Navigation; +using SortDirection = Files.Enums.SortDirection; + namespace Files.Views { public sealed partial class ModernShellPage : Page, IShellPage, INotifyPropertyChanged @@ -42,13 +46,14 @@ public sealed partial class ModernShellPage : Page, IShellPage, INotifyPropertyC public IBaseLayout SlimContentPage => ContentPage; public IFilesystemHelpers FilesystemHelpers { get; private set; } private CancellationTokenSource cancellationTokenSource; - public SettingsViewModel AppSettings => App.AppSettings; public bool CanNavigateBackward => ItemDisplayFrame.CanGoBack; public bool CanNavigateForward => ItemDisplayFrame.CanGoForward; public FolderSettingsViewModel FolderSettings => InstanceViewModel?.FolderSettings; public MainViewModel MainViewModel => App.MainViewModel; private bool isCurrentInstance { get; set; } = false; + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public bool IsCurrentInstance { get @@ -262,7 +267,7 @@ private async void ModernShellPage_TextChanged(ISearchBox sender, SearchBoxTextC Query = sender.Query, Folder = FilesystemViewModel.WorkingDirectory, MaxItemCount = 10, - SearchUnindexedItems = App.AppSettings.SearchUnindexedItems + SearchUnindexedItems = UserSettingsService.FilesAndFoldersSettingsService.SearchUnindexedItems }; sender.SetSuggestions(await search.SearchAsync()); } @@ -294,7 +299,7 @@ private void ModernShellPage_QuerySubmitted(ISearchBox sender, SearchBoxQuerySub { if (e.ChosenSuggestion == null && !string.IsNullOrWhiteSpace(sender.Query)) { - SubmitSearch(sender.Query, AppSettings.SearchUnindexedItems); + SubmitSearch(sender.Query, UserSettingsService.FilesAndFoldersSettingsService.SearchUnindexedItems); } } @@ -411,7 +416,7 @@ private void NavigationToolbar_EditModeEnabled(object sender, EventArgs e) NavToolbarViewModel.ManualEntryBoxLoaded = true; NavToolbarViewModel.ClickablePathLoaded = false; NavToolbarViewModel.PathText = string.IsNullOrEmpty(FilesystemViewModel?.WorkingDirectory) - ? AppSettings.HomePath + ? CommonPaths.HomePath : FilesystemViewModel.WorkingDirectory; } @@ -734,7 +739,7 @@ private async void KeyboardAccelerator_Invoked(KeyboardAccelerator sender, Keybo break; case (true, false, false, true, VirtualKey.P): - AppSettings.PreviewPaneEnabled = !AppSettings.PreviewPaneEnabled; + UserSettingsService.PreviewPaneSettingsService.PreviewPaneEnabled = !UserSettingsService.PreviewPaneSettingsService.PreviewPaneEnabled; break; case (true, false, false, true, VirtualKey.R): // ctrl + r, refresh diff --git a/Files/Views/PaneHolderPage.xaml.cs b/Files/Views/PaneHolderPage.xaml.cs index 01237bb79d63..e47fbaaa1f99 100644 --- a/Files/Views/PaneHolderPage.xaml.cs +++ b/Files/Views/PaneHolderPage.xaml.cs @@ -1,7 +1,9 @@ using Files.Filesystem; +using Files.Services; using Files.UserControls.MultitaskingControl; using Files.ViewModels; using Files.Views.LayoutModes; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.ComponentModel; @@ -18,6 +20,8 @@ namespace Files.Views { public sealed partial class PaneHolderPage : Page, IPaneHolder, ITabItemContent { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + public bool IsLeftPaneActive => ActivePane == PaneLeft; public bool IsRightPaneActive => ActivePane == PaneRight; @@ -25,7 +29,6 @@ public sealed partial class PaneHolderPage : Page, IPaneHolder, ITabItemContent public event PropertyChangedEventHandler PropertyChanged; - public SettingsViewModel AppSettings => App.AppSettings; public IFilesystemHelpers FilesystemHelpers => ActivePane?.FilesystemHelpers; private TabItemArguments tabItemArguments; @@ -77,7 +80,7 @@ private bool windowIsCompact public bool IsMultiPaneEnabled { - get => AppSettings.IsDualPaneEnabled && !(Window.Current.Bounds.Width <= 750); + get => UserSettingsService.MultitaskingSettingsService.IsDualPaneEnabled && !(Window.Current.Bounds.Width <= 750); } private string navParamsLeft; @@ -197,12 +200,22 @@ public PaneHolderPage() this.InitializeComponent(); Window.Current.SizeChanged += Current_SizeChanged; this.ActivePane = PaneLeft; - this.IsRightPaneVisible = IsMultiPaneEnabled && AppSettings.AlwaysOpenDualPaneInNewTab; - App.AppSettings.PropertyChanged += AppSettings_PropertyChanged; + this.IsRightPaneVisible = IsMultiPaneEnabled && UserSettingsService.MultitaskingSettingsService.AlwaysOpenDualPaneInNewTab; + UserSettingsService.OnSettingChangedEvent += UserSettingsService_OnSettingChangedEvent; // TODO: fallback / error when failed to get NavigationViewCompactPaneLength value? } + private void UserSettingsService_OnSettingChangedEvent(object sender, EventArguments.SettingChangedEventArgs e) + { + switch (e.settingName) + { + case nameof(UserSettingsService.MultitaskingSettingsService.IsDualPaneEnabled): + NotifyPropertyChanged(nameof(IsMultiPaneEnabled)); + break; + } + } + private void Current_SizeChanged(object sender, WindowSizeChangedEventArgs e) { windowIsCompact = Window.Current.Bounds.Width <= 750; @@ -235,16 +248,6 @@ protected override void OnNavigatedTo(NavigationEventArgs eventArgs) }; } - private void AppSettings_PropertyChanged(object sender, PropertyChangedEventArgs e) - { - switch (e.PropertyName) - { - case nameof(App.AppSettings.IsDualPaneEnabled): - NotifyPropertyChanged(nameof(IsMultiPaneEnabled)); - break; - } - } - private void PaneLeft_PointerPressed(object sender, PointerRoutedEventArgs e) { ActivePane = PaneLeft; @@ -298,14 +301,14 @@ private void KeyboardAccelerator_Invoked(KeyboardAccelerator sender, KeyboardAcc switch (c: ctrl, s: shift, m: menu, k: args.KeyboardAccelerator.Key) { case (true, true, false, VirtualKey.Left): // ctrl + shift + "<-" select left pane - if (AppSettings.IsDualPaneEnabled) + if (UserSettingsService.MultitaskingSettingsService.IsDualPaneEnabled) { ActivePane = PaneLeft; } break; case (true, true, false, VirtualKey.Right): // ctrl + shift + "->" select right pane - if (AppSettings.IsDualPaneEnabled) + if (UserSettingsService.MultitaskingSettingsService.IsDualPaneEnabled) { if (string.IsNullOrEmpty(NavParamsRight)) { @@ -321,7 +324,7 @@ private void KeyboardAccelerator_Invoked(KeyboardAccelerator sender, KeyboardAcc break; case (false, true, true, VirtualKey.Add): // alt + shift + "+" open pane - if (AppSettings.IsDualPaneEnabled) + if (UserSettingsService.MultitaskingSettingsService.IsDualPaneEnabled) { if (string.IsNullOrEmpty(NavParamsRight)) { @@ -338,14 +341,6 @@ private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } - public void Dispose() - { - App.AppSettings.PropertyChanged -= AppSettings_PropertyChanged; - Window.Current.SizeChanged -= Current_SizeChanged; - PaneLeft?.Dispose(); - PaneRight?.Dispose(); - } - public void CloseActivePane() { // Can only close right pane atm @@ -361,6 +356,14 @@ private void PaneRight_Loaded(object sender, RoutedEventArgs e) { (sender as UIElement).AddHandler(UIElement.PointerPressedEvent, new PointerEventHandler(PaneRight_PointerPressed), true); } + + public void Dispose() + { + UserSettingsService.OnSettingChangedEvent -= UserSettingsService_OnSettingChangedEvent; + Window.Current.SizeChanged -= Current_SizeChanged; + PaneLeft?.Dispose(); + PaneRight?.Dispose(); + } } public class PaneNavigationArguments diff --git a/Files/Views/WidgetsPage.xaml.cs b/Files/Views/WidgetsPage.xaml.cs index e68ac53e84b6..5b4532174d21 100644 --- a/Files/Views/WidgetsPage.xaml.cs +++ b/Files/Views/WidgetsPage.xaml.cs @@ -2,9 +2,11 @@ using Files.Dialogs; using Files.Filesystem; using Files.Helpers; +using Files.Services; using Files.UserControls.Widgets; using Files.ViewModels; using Files.ViewModels.Pages; +using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Uwp; using System; using System.IO; @@ -17,6 +19,8 @@ namespace Files.Views { public sealed partial class WidgetsPage : Page, IDisposable { + private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService(); + private IShellPage AppInstance = null; public FolderSettingsViewModel FolderSettings => AppInstance?.InstanceViewModel.FolderSettings; @@ -56,10 +60,10 @@ private void ViewModel_WidgetListRefreshRequestedInvoked(object sender, EventArg private void ReloadWidgets() { - folderWidget = WidgetsHelpers.TryGetWidget(Widgets.ViewModel, out bool shouldReloadFolderWidget, folderWidget); - drivesWidget = WidgetsHelpers.TryGetWidget(Widgets.ViewModel, out bool shouldReloadDrivesWidget, drivesWidget); - bundlesWidget = WidgetsHelpers.TryGetWidget(Widgets.ViewModel, out bool shouldReloadBundles, bundlesWidget); - recentFilesWidget = WidgetsHelpers.TryGetWidget(Widgets.ViewModel, out bool shouldReloadRecentFiles, recentFilesWidget); + folderWidget = WidgetsHelpers.TryGetWidget(UserSettingsService.WidgetsSettingsService, Widgets.ViewModel, out bool shouldReloadFolderWidget, folderWidget); + drivesWidget = WidgetsHelpers.TryGetWidget(UserSettingsService.WidgetsSettingsService, Widgets.ViewModel, out bool shouldReloadDrivesWidget, drivesWidget); + bundlesWidget = WidgetsHelpers.TryGetWidget(UserSettingsService.WidgetsSettingsService, Widgets.ViewModel, out bool shouldReloadBundles, bundlesWidget); + recentFilesWidget = WidgetsHelpers.TryGetWidget(UserSettingsService.WidgetsSettingsService, Widgets.ViewModel, out bool shouldReloadRecentFiles, recentFilesWidget); if (shouldReloadFolderWidget && folderWidget != null) {