diff --git a/src/Files.App/App.xaml b/src/Files.App/App.xaml
index aa4e10a5ea79..4b46b5bb8077 100644
--- a/src/Files.App/App.xaml
+++ b/src/Files.App/App.xaml
@@ -5,6 +5,7 @@
+
36
@@ -75,6 +76,7 @@
+
-
\ No newline at end of file
+
diff --git a/src/Files.App/App.xaml.cs b/src/Files.App/App.xaml.cs
index 75248cba6c3e..1eef42a97d81 100644
--- a/src/Files.App/App.xaml.cs
+++ b/src/Files.App/App.xaml.cs
@@ -48,12 +48,8 @@
using Windows.Storage;
using Windows.UI.Notifications;
-
namespace Files.App
{
- ///
- /// Provides application-specific behavior to supplement the default Application class.
- ///
public partial class App : Application
{
private static bool ShowErrorNotification = false;
@@ -140,10 +136,12 @@ await Task.WhenAll(
OptionalTask(FileTagsManager.UpdateFileTagsAsync(), preferencesSettingsService.ShowFileTagsSection),
QuickAccessManager.InitializeAsync()
);
+
await Task.WhenAll(
JumpListHelper.InitializeUpdatesAsync(),
addItemService.GetNewEntriesAsync()
);
+
FileTagsHelper.UpdateTagsDb();
});
@@ -233,10 +231,12 @@ protected override void OnLaunched(LaunchActivatedEventArgs e)
.AddSingleton()
)
.Build();
+
Logger = host.Services.GetRequiredService>();
App.Logger.LogInformation($"App launched. Launch args type: {activatedEventArgs.Data.GetType().Name}");
Ioc.Default.ConfigureServices(host.Services);
+
EnsureSettingsAndConfigurationAreBootstrapped();
_ = InitializeAppComponentsAsync().ContinueWith(t => Logger.LogWarning(t.Exception, "Error during InitializeAppComponentsAsync()"), TaskContinuationOptions.OnlyOnFaulted);
@@ -266,6 +266,7 @@ public void OnActivated(AppActivationArguments activatedEventArgs)
{
App.Logger.LogInformation($"App activated. Activated args type: {activatedEventArgs.Data.GetType().Name}");
var data = activatedEventArgs.Data;
+
// InitializeApplication accesses UI, needs to be called on UI thread
_ = Window.DispatcherQueue.EnqueueAsync(() => Window.InitializeApplication(data));
}
@@ -288,7 +289,8 @@ private async void Window_Closed(object sender, WindowEventArgs args)
return;
}
- await Task.Yield(); // Method can take a long time, make sure the window is hidden
+ // Method can take a long time, make sure the window is hidden
+ await Task.Yield();
SaveSessionTabs();
@@ -299,11 +301,14 @@ await SafetyExtensions.IgnoreExceptions(async () =>
var instance = MainPageViewModel.AppInstances.FirstOrDefault(x => x.Control.TabItemContent.IsCurrentInstance);
if (instance is null)
return;
+
var items = (instance.Control.TabItemContent as PaneHolderPage)?.ActivePane?.SlimContentPage?.SelectedItems;
if (items is null)
return;
+
await FileIO.WriteLinesAsync(await StorageFile.GetFileFromPathAsync(OutputPath), items.Select(x => x.ItemPath));
- }, Logger);
+ },
+ Logger);
}
DrivesManager?.Dispose();
@@ -317,13 +322,17 @@ await SafetyExtensions.IgnoreExceptions(async () =>
if (dataPackage.Contains(StandardDataFormats.StorageItems))
Clipboard.Flush();
}
- }, Logger);
+ },
+ Logger);
// Wait for ongoing file operations
FileOperationsHelpers.WaitForCompletion();
}
- public static void SaveSessionTabs() // Enumerates through all tabs and gets the Path property and saves it to AppSettings.LastSessionPages
+ ///
+ /// Enumerates through all tabs and gets the Path property and saves it to AppSettings.LastSessionPages.
+ ///
+ public static void SaveSessionTabs()
{
IUserSettingsService userSettingsService = Ioc.Default.GetRequiredService();
IBundlesSettingsService bundlesSettingsService = Ioc.Default.GetRequiredService();
@@ -341,21 +350,33 @@ public static void SaveSessionTabs() // Enumerates through all tabs and gets the
var defaultArg = new TabItemArguments() { InitialPageType = typeof(PaneHolderPage), NavigationArg = "Home" };
return defaultArg.Serialize();
}
- }).ToList();
+ })
+ .ToList();
}
- // Occurs when an exception is not handled on the UI thread.
- private static void OnUnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e) => AppUnhandledException(e.Exception, true);
+ ///
+ /// Occurs when an exception is not handled on the UI thread.
+ ///
+ ///
+ ///
+ private static void OnUnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
+ => AppUnhandledException(e.Exception, true);
- // Occurs when an exception is not handled on a background thread.
- // ie. A task is fired and forgotten Task.Run(() => {...})
- private static void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e) => AppUnhandledException(e.Exception, false);
+ ///
+ /// Occurs when an exception is not handled on a background thread.
+ /// i.e. A task is fired and forgotten Task.Run(() => {...})
+ ///
+ ///
+ ///
+ private static void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)
+ => AppUnhandledException(e.Exception, false);
private static void AppUnhandledException(Exception ex, bool shouldShowNotification)
{
StringBuilder formattedException = new StringBuilder() { Capacity = 200 };
formattedException.Append("--------- UNHANDLED EXCEPTION ---------");
+
if (ex is not null)
{
formattedException.Append($"\n>>>> HRESULT: {ex.HResult}\n");
@@ -389,7 +410,8 @@ private static void AppUnhandledException(Exception ex, bool shouldShowNotificat
Debug.WriteLine(formattedException.ToString());
- Debugger.Break(); // Please check "Output Window" for exception details (View -> Output Window) (CTRL + ALT + O)
+ // Please check "Output Window" for exception details (View -> Output Window) (CTRL + ALT + O)
+ Debugger.Break();
SaveSessionTabs();
App.Logger.LogError(ex, ex.Message);
@@ -399,7 +421,7 @@ private static void AppUnhandledException(Exception ex, bool shouldShowNotificat
var toastContent = new ToastContent()
{
- Visual = new ToastVisual()
+ Visual = new()
{
BindingGeneric = new ToastBindingGeneric()
{
@@ -414,7 +436,7 @@ private static void AppUnhandledException(Exception ex, bool shouldShowNotificat
Text = "ExceptionNotificationBody".GetLocalizedResource()
}
},
- AppLogoOverride = new ToastGenericAppLogo()
+ AppLogoOverride = new()
{
Source = "ms-appx:///Assets/error.png"
}
@@ -440,9 +462,7 @@ private static void AppUnhandledException(Exception ex, bool shouldShowNotificat
}
public static void CloseApp()
- {
- Window.Close();
- }
+ => Window.Close();
public static AppWindow GetAppWindow(Window w)
{
diff --git a/src/Files.App/BaseLayout.cs b/src/Files.App/BaseLayout.cs
index c40906ede46b..fbde2c345616 100644
--- a/src/Files.App/BaseLayout.cs
+++ b/src/Files.App/BaseLayout.cs
@@ -515,9 +515,7 @@ navigationArguments.SelectItems is not null &&
ItemManipulationModel.FocusFileList();
}
}
- catch (Exception)
- {
- }
+ catch (Exception) { }
}
private CancellationTokenSource? groupingCancellationToken;
@@ -565,7 +563,8 @@ public async void ItemContextFlyout_Opening(object? sender, object e)
try
{
- if (!IsItemSelected && ((sender as CommandBarFlyout)?.Target as ListViewItem)?.Content is ListedItem li) // Workaround for item sometimes not getting selected
+ // Workaround for item sometimes not getting selected
+ if (!IsItemSelected && (sender as CommandBarFlyout)?.Target is ListViewItem { Content: ListedItem li })
ItemManipulationModel.SetSelectedItem(li);
if (IsItemSelected)
@@ -654,10 +653,13 @@ private async Task LoadMenuItemsAsync()
shellContextMenuItemCancellationToken?.Cancel();
shellContextMenuItemCancellationToken = new CancellationTokenSource();
SelectedItemsPropertiesViewModel.CheckAllFileExtensions(SelectedItems!.Select(selectedItem => selectedItem?.FileExtension).ToList()!);
+
var shiftPressed = Microsoft.UI.Input.InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(Windows.UI.Core.CoreVirtualKeyStates.Down);
var items = ContextFlyoutItemHelper.GetItemContextCommandsWithoutShellItems(currentInstanceViewModel: InstanceViewModel!, selectedItems: SelectedItems!, selectedItemsPropertiesViewModel: SelectedItemsPropertiesViewModel, commandsViewModel: CommandsViewModel!, shiftPressed: shiftPressed, itemViewModel: null);
+
ItemContextMenuFlyout.PrimaryCommands.Clear();
ItemContextMenuFlyout.SecondaryCommands.Clear();
+
var (primaryElements, secondaryElements) = ItemModelListToContextFlyoutHelper.GetAppBarItemsFromModel(items);
AddCloseHandler(ItemContextMenuFlyout, primaryElements, secondaryElements);
primaryElements.ForEach(ItemContextMenuFlyout.PrimaryCommands.Add);
@@ -747,7 +749,7 @@ private async Task AddShellMenuItemsAsync(List s
var requiredHeight = contextMenuFlyout.SecondaryCommands.Concat(mainItems).Where(x => x is not AppBarSeparator).Count() * Constants.UI.ContextMenuSecondaryItemsHeight;
var availableHeight = App.Window.Bounds.Height - cMenuPos.Y - Constants.UI.ContextMenuPrimaryItemsHeight;
- // Set menu max height to current height (avoids menu repositioning)
+ // Set menu max height to current height (Avoid menu repositioning)
if (requiredHeight > availableHeight)
itemsControl.MaxHeight = Math.Min(Constants.UI.ContextMenuMaxHeight, Math.Max(itemsControl.ActualHeight, Math.Min(availableHeight, requiredHeight)));
@@ -854,34 +856,31 @@ private async Task AddShellMenuItemsAsync(List s
ShellContextmenuHelper.AddItemsToOverflowMenu(overflowItem, x);
});
- if (itemsControl is not null)
+ itemsControl?.Items.OfType().ForEach(item =>
{
- itemsControl.Items.OfType().ForEach(item =>
- {
- // Enable CharacterEllipsis text trimming for menu items
- if (item.FindDescendant("OverflowTextLabel") is TextBlock label)
- label.TextTrimming = TextTrimming.CharacterEllipsis;
+ // Enable CharacterEllipsis text trimming for menu items
+ if (item.FindDescendant("OverflowTextLabel") is TextBlock label)
+ label.TextTrimming = TextTrimming.CharacterEllipsis;
- // Close main menu when clicking on subitems (#5508)
- if ((item as AppBarButton)?.Flyout as MenuFlyout is MenuFlyout flyout)
+ // Close main menu when clicking on subitems (#5508)
+ if ((item as AppBarButton)?.Flyout as MenuFlyout is MenuFlyout flyout)
+ {
+ Action> clickAction = null!;
+ clickAction = (items) =>
{
- Action> clickAction = null!;
- clickAction = (items) =>
+ items.OfType().ForEach(i =>
{
- items.OfType().ForEach(i =>
- {
- i.Click += new RoutedEventHandler((s, e) => contextMenuFlyout.Hide());
- });
- items.OfType().ForEach(i =>
- {
- clickAction(i.Items);
- });
- };
+ i.Click += new RoutedEventHandler((s, e) => contextMenuFlyout.Hide());
+ });
+ items.OfType().ForEach(i =>
+ {
+ clickAction(i.Items);
+ });
+ };
- clickAction(flyout.Items);
- }
- });
- }
+ clickAction(flyout.Items);
+ }
+ });
}
private void RemoveOverflow(CommandBarFlyout contextMenuFlyout)
@@ -913,6 +912,7 @@ protected void FileList_DragItemsStarting(object sender, DragItemsStartingEventA
{
var iddo = shellItemList[0].Parent.GetChildrenUIObjects(HWND.NULL, shellItemList);
shellItemList.ForEach(x => x.Dispose());
+
var format = System.Windows.Forms.DataFormats.GetFormat("Shell IDList Array");
if (iddo.TryGetData((uint)format.Id, out var data))
{
@@ -951,6 +951,7 @@ protected async void Item_DragOver(object sender, DragEventArgs e)
return;
DragOperationDeferral? deferral = null;
+
try
{
deferral = e.GetDeferral();
@@ -1048,6 +1049,7 @@ protected async void Item_Drop(object sender, DragEventArgs e)
var item = GetItemFromElement(sender);
if (item is not null)
await ParentShellPageInstance!.FilesystemHelpers.PerformOperationTypeAsync(e.AcceptedOperation, e.DataView, (item as ShortcutItem)?.TargetPath ?? item.ItemPath, false, true, item.IsExecutable);
+
deferral.Complete();
}
@@ -1139,13 +1141,13 @@ protected internal void FileListItem_PointerEntered(object sender, PointerRouted
hoverTimer.Stop();
- // selection of multiple individual items with control
+ // Selection of multiple individual items with control
if (e.KeyModifiers == VirtualKeyModifiers.Control &&
selectedItems is not null)
{
ItemManipulationModel.AddSelectedItem(hoveredItem);
}
- // selection of a range of items with shift
+ // Selection of a range of items with shift
else if (e.KeyModifiers == VirtualKeyModifiers.Shift &&
selectedItems is not null &&
selectedItems.Any())
@@ -1161,9 +1163,8 @@ selectedItems is not null &&
ItemManipulationModel.AddSelectedItem((ListedItem)ItemsControl.Items[i]);
}
}
- // avoid resetting the selection if multiple items are selected
- else if (SelectedItems is null ||
- SelectedItems.Count <= 1)
+ // Avoid resetting the selection if multiple items are selected
+ else if (SelectedItems is null || SelectedItems.Count <= 1)
{
ItemManipulationModel.SetSelectedItem(hoveredItem);
}
@@ -1211,7 +1212,7 @@ protected void UninitializeDrag(UIElement element)
element.Drop -= Item_Drop;
}
- // VirtualKey doesn't support / accept plus and minus by default.
+ // VirtualKey doesn't support or accept plus and minus by default.
public readonly VirtualKey PlusKey = (VirtualKey)187;
public readonly VirtualKey MinusKey = (VirtualKey)189;
@@ -1239,7 +1240,7 @@ private void UpdateCollectionViewSource()
if (ParentShellPageInstance.FilesystemViewModel.FilesAndFolders.IsGrouped)
{
- CollectionViewSource = new CollectionViewSource()
+ CollectionViewSource = new()
{
IsSourceGrouped = true,
Source = ParentShellPageInstance.FilesystemViewModel.FilesAndFolders.GroupedCollection
@@ -1247,7 +1248,7 @@ private void UpdateCollectionViewSource()
}
else
{
- CollectionViewSource = new CollectionViewSource()
+ CollectionViewSource = new()
{
IsSourceGrouped = false,
Source = ParentShellPageInstance.FilesystemViewModel.FilesAndFolders
diff --git a/src/Files.App/IShellPage.cs b/src/Files.App/IShellPage.cs
index 6808ba6072ab..9ce7570cc118 100644
--- a/src/Files.App/IShellPage.cs
+++ b/src/Files.App/IShellPage.cs
@@ -94,9 +94,9 @@ public interface IPaneHolder : IDisposable, INotifyPropertyChanged
public interface IMultiPaneInfo
{
- // The instance is the left (or only) pane
+ // The instance is the left or only pane
public bool IsPageMainPane { get; }
public IPaneHolder PaneHolder { get; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Files.App/MainWindow.xaml b/src/Files.App/MainWindow.xaml
index 895167b16cba..74eda8b9d29a 100644
--- a/src/Files.App/MainWindow.xaml
+++ b/src/Files.App/MainWindow.xaml
@@ -7,9 +7,9 @@
xmlns:winuiex="using:WinUIEx"
mc:Ignorable="d">
+
-
-
\ No newline at end of file
+
diff --git a/src/Files.App/MainWindow.xaml.cs b/src/Files.App/MainWindow.xaml.cs
index e555bdcdd51a..c66dcfe3185c 100644
--- a/src/Files.App/MainWindow.xaml.cs
+++ b/src/Files.App/MainWindow.xaml.cs
@@ -22,14 +22,8 @@
using WinUIEx;
using IO = System.IO;
-// To learn more about WinUI, the WinUI project structure,
-// and more about our project templates, see: http://aka.ms/winui-project-info.
-
namespace Files.App
{
- ///
- /// An empty window that can be used on its own or navigated to within a Frame.
- ///
public sealed partial class MainWindow : WindowEx
{
public MainWindow()
@@ -56,7 +50,7 @@ private void EnsureEarlyWindow()
AppWindow.TitleBar.ButtonBackgroundColor = Colors.Transparent;
AppWindow.TitleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
- // Set min size
+ // Set minimum sizes
base.MinHeight = 328;
base.MinWidth = 516;
}
@@ -66,13 +60,12 @@ public async Task InitializeApplication(object activatedEventArgs)
var rootFrame = EnsureWindowIsInitialized();
Activate();
- // WINUI3: port activation args from App.xaml.cs.old: OnActivated, OnFileActivated
switch (activatedEventArgs)
{
case ILaunchActivatedEventArgs launchArgs:
if (launchArgs.Arguments is not null && launchArgs.Arguments.Contains($"files.exe", StringComparison.OrdinalIgnoreCase))
{
- // WINUI3 bug: when launching from commandline the argument is not ICommandLineActivatedEventArgs (#10370)
+ // WINUI3: When launching from commandline the argument is not ICommandLineActivatedEventArgs (#10370)
var ppm = CommandLineParser.ParseUntrustedCommands(launchArgs.Arguments);
if (ppm.IsEmpty())
rootFrame.Navigate(typeof(MainPage), null, new SuppressNavigationTransitionInfo());
@@ -82,8 +75,7 @@ public async Task InitializeApplication(object activatedEventArgs)
else if (rootFrame.Content is null)
{
// When the navigation stack isn't restored navigate to the first page,
- // configuring the new page by passing required information as a navigation
- // parameter
+ // configuring the new page by passing required information as a navigation parameter
rootFrame.Navigate(typeof(MainPage), launchArgs.Arguments, new SuppressNavigationTransitionInfo());
}
else
@@ -107,7 +99,8 @@ public async Task InitializeApplication(object activatedEventArgs)
var folder = (StorageFolder)await FilesystemTasks.Wrap(() => StorageFolder.GetFolderFromPathAsync(unescapedValue).AsTask());
if (folder is not null && !string.IsNullOrEmpty(folder.Path))
{
- unescapedValue = folder.Path; // Convert short name to long name (#6190)
+ // Convert short name to long name (#6190)
+ unescapedValue = folder.Path;
}
switch (parsedArgs[0])
{
@@ -157,8 +150,7 @@ public async Task InitializeApplication(object activatedEventArgs)
if (rootFrame.Content is null)
{
// When the navigation stack isn't restored navigate to the first page,
- // configuring the new page by passing required information as a navigation
- // parameter
+ // configuring the new page by passing required information as a navigation parameter
rootFrame.Navigate(typeof(MainPage), fileArgs.Files.First().Path, new SuppressNavigationTransitionInfo());
index = 1;
}
@@ -170,15 +162,14 @@ public async Task InitializeApplication(object activatedEventArgs)
}
if (rootFrame.Content is null)
- {
rootFrame.Navigate(typeof(MainPage), null, new SuppressNavigationTransitionInfo());
- }
}
private Frame EnsureWindowIsInitialized()
{
- // Do not repeat app initialization when the Window already has content,
- // just ensure that the window is active
+ // NOTE:
+ // Do not repeat app initialization when the Window already has content,
+ // just ensure that the window is active
if (!(App.Window.Content is Frame rootFrame))
{
// Create a Frame to act as the navigation context and navigate to the first page
@@ -199,9 +190,7 @@ private Frame EnsureWindowIsInitialized()
/// The Frame which failed navigation
/// Details about the navigation failure
private void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
- {
- throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
- }
+ => throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
private async Task InitializeFromCmdLineArgs(Frame rootFrame, ParsedCommands parsedCommands, string activationPath = "")
{
@@ -212,23 +201,19 @@ async Task PerformNavigation(string payload, string selectItem = null)
payload = CommonPaths.ShellPlaces.Get(payload.ToUpperInvariant(), payload);
var folder = (StorageFolder)await FilesystemTasks.Wrap(() => StorageFolder.GetFolderFromPathAsync(payload).AsTask());
if (folder is not null && !string.IsNullOrEmpty(folder.Path))
- {
payload = folder.Path; // Convert short name to long name (#6190)
- }
}
+
var paneNavigationArgs = new PaneNavigationArguments
{
LeftPaneNavPathParam = payload,
LeftPaneSelectItemParam = selectItem,
};
+
if (rootFrame.Content is not null)
- {
await MainPageViewModel.AddNewTabByParam(typeof(PaneHolderPage), paneNavigationArgs);
- }
else
- {
rootFrame.Navigate(typeof(MainPage), paneNavigationArgs, new SuppressNavigationTransitionInfo());
- }
}
foreach (var command in parsedCommands)
{
@@ -243,9 +228,7 @@ async Task PerformNavigation(string payload, string selectItem = null)
case ParsedCommandType.SelectItem:
if (IO.Path.IsPathRooted(command.Payload))
- {
await PerformNavigation(IO.Path.GetDirectoryName(command.Payload), IO.Path.GetFileName(command.Payload));
- }
break;
case ParsedCommandType.TagFiles:
diff --git a/src/Files.App/Program.cs b/src/Files.App/Program.cs
index 5eac555409f7..468395b53a77 100644
--- a/src/Files.App/Program.cs
+++ b/src/Files.App/Program.cs
@@ -20,10 +20,11 @@ namespace Files.App
{
internal class Program
{
- // Note: We can't declare Main to be async because in a WinUI app
- // This prevents Narrator from reading XAML elements
- // https://github.com/microsoft/WindowsAppSDK-Samples/blob/main/Samples/AppLifecycle/Instancing/cs-winui-packaged/CsWinUiDesktopInstancing/CsWinUiDesktopInstancing/Program.cs
- // STAThread has no effect if main is async, needed for Clipboard
+ // Note:
+ // We can't declare Main to be async because in a WinUI app
+ // This prevents Narrator from reading XAML elements
+ // https://github.com/microsoft/WindowsAppSDK-Samples/blob/main/Samples/AppLifecycle/Instancing/cs-winui-packaged/CsWinUiDesktopInstancing/CsWinUiDesktopInstancing/Program.cs
+ // STAThread has no effect if main is async, needed for Clipboard
[STAThread]
private static void Main()
{
@@ -76,8 +77,7 @@ private static void Main()
}
}
}
-
- if (activatedArgs.Data is ILaunchActivatedEventArgs tileArgs)
+ else if (activatedArgs.Data is ILaunchActivatedEventArgs tileArgs)
{
if (tileArgs.Arguments is not null &&
!tileArgs.Arguments.Contains($"files.exe", StringComparison.OrdinalIgnoreCase) &&
@@ -134,6 +134,7 @@ private static void Main()
{
currentInstance.Activated += OnActivated;
}
+
ApplicationData.Current.LocalSettings.Values["INSTANCE_ACTIVE"] = -proc.Id;
Application.Start((p) =>
diff --git a/src/Files.App/ViewModels/Pages/YourHomeViewModel.cs b/src/Files.App/ViewModels/HomeViewModel.cs
similarity index 86%
rename from src/Files.App/ViewModels/Pages/YourHomeViewModel.cs
rename to src/Files.App/ViewModels/HomeViewModel.cs
index 1fd7f4d8c74d..281ce28bc96c 100644
--- a/src/Files.App/ViewModels/Pages/YourHomeViewModel.cs
+++ b/src/Files.App/ViewModels/HomeViewModel.cs
@@ -6,12 +6,11 @@
using Files.App.ViewModels.Widgets.Bundles;
using Microsoft.UI.Xaml;
using System;
-using System.Text.Json;
using System.Windows.Input;
-namespace Files.App.ViewModels.Pages
+namespace Files.App.ViewModels
{
- public class YourHomeViewModel : ObservableObject, IDisposable
+ public class HomeViewModel : ObservableObject, IDisposable
{
private BundlesViewModel bundlesViewModel;
@@ -19,15 +18,13 @@ public class YourHomeViewModel : ObservableObject, IDisposable
private IShellPage associatedInstance;
- private readonly JsonElement defaultJson = JsonSerializer.SerializeToElement("{}");
-
public event EventHandler YourHomeLoadedInvoked;
public ICommand YourHomeLoadedCommand { get; private set; }
public ICommand LoadBundlesCommand { get; private set; }
- public YourHomeViewModel(WidgetsListControlViewModel widgetsViewModel, IShellPage associatedInstance)
+ public HomeViewModel(WidgetsListControlViewModel widgetsViewModel, IShellPage associatedInstance)
{
this.widgetsViewModel = widgetsViewModel;
this.associatedInstance = associatedInstance;
@@ -69,8 +66,6 @@ private async void BundlesViewModel_OpenPathEvent(object sender, BundlesOpenPath
await NavigationHelpers.OpenPath(e.path, associatedInstance, e.itemType, e.openSilent, e.openViaApplicationPicker, e.selectItems);
}
- #region IDisposable
-
public void Dispose()
{
if (bundlesViewModel is not null)
@@ -81,7 +76,5 @@ public void Dispose()
widgetsViewModel?.Dispose();
}
-
- #endregion IDisposable
}
}
diff --git a/src/Files.App/ViewModels/ToolbarViewModel.cs b/src/Files.App/ViewModels/ToolbarViewModel.cs
index d3cb782af1ff..97952cc8c9ef 100644
--- a/src/Files.App/ViewModels/ToolbarViewModel.cs
+++ b/src/Files.App/ViewModels/ToolbarViewModel.cs
@@ -660,7 +660,7 @@ public async Task CheckPathInput(string currentInput, string currentSelectedPath
if (currentSelectedPath == currentInput || string.IsNullOrWhiteSpace(currentInput))
return;
- if (currentInput != shellPage.FilesystemViewModel.WorkingDirectory || shellPage.CurrentPageType == typeof(WidgetsPage))
+ if (currentInput != shellPage.FilesystemViewModel.WorkingDirectory || shellPage.CurrentPageType == typeof(HomePage))
{
if (currentInput.Equals("Home", StringComparison.OrdinalIgnoreCase) || currentInput.Equals("Home".GetLocalizedResource(), StringComparison.OrdinalIgnoreCase))
{
@@ -707,7 +707,7 @@ public async Task CheckPathInput(string currentInput, string currentSelectedPath
{
var workingDir =
string.IsNullOrEmpty(shellPage.FilesystemViewModel.WorkingDirectory) ||
- shellPage.CurrentPageType == typeof(WidgetsPage) ?
+ shellPage.CurrentPageType == typeof(HomePage) ?
CommonPaths.HomePath :
shellPage.FilesystemViewModel.WorkingDirectory;
diff --git a/src/Files.App/Views/BaseShellPage.cs b/src/Files.App/Views/BaseShellPage.cs
index 0e983e9a0d30..3a9f9d9db6c8 100644
--- a/src/Files.App/Views/BaseShellPage.cs
+++ b/src/Files.App/Views/BaseShellPage.cs
@@ -88,6 +88,7 @@ public BaseLayout ContentPage
if (value != contentPage)
{
contentPage = value;
+
NotifyPropertyChanged(nameof(ContentPage));
NotifyPropertyChanged(nameof(SlimContentPage));
}
@@ -103,6 +104,7 @@ public bool IsPageMainPane
if (value != isPageMainPane)
{
isPageMainPane = value;
+
NotifyPropertyChanged(nameof(IsPageMainPane));
}
}
@@ -117,6 +119,7 @@ public IPaneHolder PaneHolder
if (value != paneHolder)
{
paneHolder = value;
+
NotifyPropertyChanged(nameof(PaneHolder));
}
}
@@ -145,10 +148,12 @@ public bool IsCurrentInstance
if (isCurrentInstance != value)
{
isCurrentInstance = value;
+
if (isCurrentInstance)
ContentPage?.ItemManipulationModel.FocusFileList();
else if (SlimContentPage is not ColumnViewBrowser)
ToolbarViewModel.IsEditModeEnabled = false;
+
NotifyPropertyChanged(nameof(IsCurrentInstance));
}
}
@@ -156,8 +161,8 @@ public bool IsCurrentInstance
public SolidColorBrush CurrentInstanceBorderBrush
{
- get { return (SolidColorBrush)GetValue(CurrentInstanceBorderBrushProperty); }
- set { SetValue(CurrentInstanceBorderBrushProperty, value); }
+ get => (SolidColorBrush)GetValue(CurrentInstanceBorderBrushProperty);
+ set => SetValue(CurrentInstanceBorderBrushProperty, value);
}
public static readonly DependencyProperty CurrentInstanceBorderBrushProperty =
@@ -181,13 +186,12 @@ public BaseShellPage(CurrentInstanceViewModel instanceViewModel)
DisplayFilesystemConsentDialog();
- /*TODO ResourceContext.GetForCurrentView and ResourceContext.GetForViewIndependentUse do not exist in Windows App SDK
- Use your ResourceManager instance to create a ResourceContext as below.If you already have a ResourceManager instance,
- replace the new instance created below with correct instance.
- Read: https://learn.microsoft.com/windows/apps/windows-app-sdk/migrate-to-windows-app-sdk/guides/mrtcore
- */
+ // TODO:
+ // ResourceContext.GetForCurrentView and ResourceContext.GetForViewIndependentUse do not exist in Windows App SDK
+ // Use your ResourceManager instance to create a ResourceContext as below.If you already have a ResourceManager instance,
+ // replace the new instance created below with correct instance.
+ // Read: https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/migrate-to-windows-app-sdk/guides/mrtcore
var flowDirectionSetting = new Microsoft.Windows.ApplicationModel.Resources.ResourceManager().CreateResourceContext().QualifierValues["LayoutDirection"];
-
if (flowDirectionSetting == "RTL")
FlowDirection = FlowDirection.RightToLeft;
@@ -208,14 +212,7 @@ public BaseShellPage(CurrentInstanceViewModel instanceViewModel)
InstanceViewModel.FolderSettings.SortOptionPreferenceUpdated += AppSettings_SortOptionPreferenceUpdated;
InstanceViewModel.FolderSettings.SortDirectoriesAlongsideFilesPreferenceUpdated += AppSettings_SortDirectoriesAlongsideFilesPreferenceUpdated;
- this.PointerPressed += CoreWindow_PointerPressed;
-
- /*
- TODO UA307 Default back button in the title bar does not exist in WinUI3 apps.
- The tool has generated a custom back button in the MainWindow.xaml.cs file.
- Feel free to edit its position, behavior and use the custom back button instead.
- Read: https://learn.microsoft.com/windows/apps/windows-app-sdk/migrate-to-windows-app-sdk/case-study-1#restoring-back-button-functionality
- */
+ PointerPressed += CoreWindow_PointerPressed;
App.DrivesManager.PropertyChanged += DrivesManager_PropertyChanged;
@@ -234,7 +231,7 @@ protected void FilesystemViewModel_PageTypeUpdated(object sender, PageTypeUpdate
protected void FilesystemViewModel_OnSelectionRequestedEvent(object sender, List e)
{
- // set focus since selection might occur before the UI finishes updating
+ // Set focus since selection might occur before the UI finishes updating
ContentPage.ItemManipulationModel.FocusFileList();
ContentPage.ItemManipulationModel.SetSelectedItems(e);
}
@@ -258,31 +255,28 @@ protected virtual void Page_Loaded(object sender, RoutedEventArgs e)
this.Loaded -= Page_Loaded;
}
- /**
- * Some keys are overridden by control built-in defaults (e.g. 'Space').
- * They must be handled here since they're not propagated to KeyboardAccelerator.
- */
+ // Some keys are overridden by control built-in defaults(e.g. 'Space').
+ // They must be handled here since they're not propagated to KeyboardAccelerator.
protected void ShellPage_PreviewKeyDown(object sender, KeyRoutedEventArgs args)
{
var ctrl = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down);
var shift = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down);
var alt = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Menu).HasFlag(CoreVirtualKeyStates.Down);
- var tabInstance = CurrentPageType == typeof(DetailsLayoutBrowser) ||
- CurrentPageType == typeof(GridViewBrowser) ||
- CurrentPageType == typeof(ColumnViewBrowser) ||
- CurrentPageType == typeof(ColumnViewBase);
+ var tabInstance =
+ CurrentPageType == typeof(DetailsLayoutBrowser) ||
+ CurrentPageType == typeof(GridViewBrowser) ||
+ CurrentPageType == typeof(ColumnViewBrowser) ||
+ CurrentPageType == typeof(ColumnViewBase);
switch (c: ctrl, s: shift, a: alt, t: tabInstance, k: args.Key)
{
- // Ctrl + space, toggle media playback
+ // Ctrl + Space, toggle media playback
case (true, false, false, true, VirtualKey.Space):
-
if (Ioc.Default.GetRequiredService().PreviewPaneContent is UserControls.FilePreviews.MediaPreview mediaPreviewContent)
{
mediaPreviewContent.ViewModel.TogglePlayback();
args.Handled = true;
}
-
break;
}
}
@@ -299,6 +293,7 @@ protected async void ShellPage_TextChanged(ISearchBox sender, SearchBoxTextChang
{
if (e.Reason != SearchBoxTextChangeReason.UserInput)
return;
+
if (!string.IsNullOrWhiteSpace(sender.Query))
{
var search = new FolderSearch
@@ -308,6 +303,7 @@ protected async void ShellPage_TextChanged(ISearchBox sender, SearchBoxTextChang
MaxItemCount = 10,
SearchUnindexedItems = userSettingsService.PreferencesSettingsService.SearchUnindexedItems
};
+
sender.SetSuggestions((await search.SearchAsync()).Select(suggestion => new SuggestionModel(suggestion)));
}
else
@@ -340,6 +336,7 @@ protected void CoreWindow_PointerPressed(object sender, PointerRoutedEventArgs a
{
if (!IsCurrentInstance)
return;
+
if (args.GetCurrentPoint(this).Properties.IsXButton1Pressed)
Back_Click();
else if (args.GetCurrentPoint(this).Properties.IsXButton2Pressed)
@@ -387,11 +384,9 @@ protected void DrivesManager_PropertyChanged(object sender, PropertyChangedEvent
DisplayFilesystemConsentDialog();
}
- /*
- * Ensure that the path bar gets updated for user interaction
- * whenever the path changes. We will get the individual directories from
- * the updated, most-current path and add them to the UI.
- */
+ // Ensure that the path bar gets updated for user interaction
+ // whenever the path changes.We will get the individual directories from
+ // the updated, most-current path and add them to the UI.
public void UpdatePathUIToWorkingDirectory(string newWorkingDir, string singleItemOverride = null)
{
if (string.IsNullOrWhiteSpace(singleItemOverride))
@@ -447,6 +442,7 @@ public void NavigateToPath(string navigationPath, NavigationArguments? navArgs =
var layout = navigationPath.StartsWith("tag:")
? typeof(DetailsLayoutBrowser)
: FolderSettings.GetLayoutType(navigationPath);
+
NavigateToPath(navigationPath, layout, navArgs);
}
@@ -472,9 +468,10 @@ public async void Refresh_Click()
ThumbnailSize = InstanceViewModel.FolderSettings.GetIconSize(),
SearchUnindexedItems = InstanceViewModel.SearchedUnindexedItems
};
+
await FilesystemViewModel.SearchAsync(searchInstance);
}
- else if (CurrentPageType != typeof(WidgetsPage))
+ else if (CurrentPageType != typeof(HomePage))
{
ToolbarViewModel.CanRefresh = false;
FilesystemViewModel?.RefreshItems(null);
@@ -486,7 +483,7 @@ public virtual void Back_Click()
var previousPageContent = ItemDisplay.BackStack[ItemDisplay.BackStack.Count - 1];
HandleBackForwardRequest(previousPageContent);
- if (previousPageContent.SourcePageType == typeof(WidgetsPage))
+ if (previousPageContent.SourcePageType == typeof(HomePage))
ItemDisplay.GoBack(new EntranceNavigationTransitionInfo());
else
ItemDisplay.GoBack();
@@ -496,6 +493,7 @@ public virtual void Forward_Click()
{
var incomingPageContent = ItemDisplay.ForwardStack[ItemDisplay.ForwardStack.Count - 1];
HandleBackForwardRequest(incomingPageContent);
+
ItemDisplay.GoForward();
}
@@ -550,7 +548,6 @@ protected void FilesystemViewModel_ItemLoadStatusChanged(object sender, ItemLoad
ToolbarViewModel.CanRefresh = false;
SetLoadingIndicatorForTabs(true);
break;
-
case ItemLoadStatusChangedEventArgs.ItemLoadStatus.InProgress:
var columnCanNavigateBackward = false;
var columnCanNavigateForward = false;
@@ -563,13 +560,13 @@ protected void FilesystemViewModel_ItemLoadStatusChanged(object sender, ItemLoad
ToolbarViewModel.CanGoForward = ItemDisplay.CanGoForward || columnCanNavigateForward;
SetLoadingIndicatorForTabs(true);
break;
-
case ItemLoadStatusChangedEventArgs.ItemLoadStatus.Complete:
SetLoadingIndicatorForTabs(false);
ToolbarViewModel.CanRefresh = true;
// Select previous directory
if (!string.IsNullOrWhiteSpace(e.PreviousDirectory) &&
- e.PreviousDirectory.Contains(e.Path, StringComparison.Ordinal) && !e.PreviousDirectory.Contains(CommonPaths.RecycleBinPath, StringComparison.Ordinal))
+ e.PreviousDirectory.Contains(e.Path, StringComparison.Ordinal) &&
+ !e.PreviousDirectory.Contains(CommonPaths.RecycleBinPath, StringComparison.Ordinal))
{
// Remove the WorkingDir from previous dir
e.PreviousDirectory = e.PreviousDirectory.Replace(e.Path, string.Empty, StringComparison.Ordinal);
@@ -631,12 +628,13 @@ protected void InitToolbarCommands()
protected async Task GetContentOrNullAsync()
{
- // WINUI3: make sure not to run this synchronously, do not use EnqueueAsync
+ // WINUI3: Make sure not to run this synchronously, do not use EnqueueAsync
var tcs = new TaskCompletionSource