diff --git a/src/Files.App/Assets/FilesOpenDialog/Files.App.Launcher.exe b/src/Files.App/Assets/FilesOpenDialog/Files.App.Launcher.exe index f64cd5fa0c42..e5765b6216f8 100644 Binary files a/src/Files.App/Assets/FilesOpenDialog/Files.App.Launcher.exe and b/src/Files.App/Assets/FilesOpenDialog/Files.App.Launcher.exe differ diff --git a/src/Files.App/Assets/FilesOpenDialog/Files.App.Launcher.exe.sha256 b/src/Files.App/Assets/FilesOpenDialog/Files.App.Launcher.exe.sha256 index 61dd73294393..ade8fe992695 100644 --- a/src/Files.App/Assets/FilesOpenDialog/Files.App.Launcher.exe.sha256 +++ b/src/Files.App/Assets/FilesOpenDialog/Files.App.Launcher.exe.sha256 @@ -1 +1 @@ -7219ea9bd5832c77f1d6c8e57f97e6504a33f07bdef61122a171061f0dcb3509 +cc957911eb0abac03d457a70f1c6ff03eeabd0d05548806ff801998d7218b48d diff --git a/src/Files.App/Data/EventArguments/ToolbarFlyoutOpenedEventArgs.cs b/src/Files.App/Data/EventArguments/ToolbarFlyoutOpenedEventArgs.cs deleted file mode 100644 index da2c17d6445a..000000000000 --- a/src/Files.App/Data/EventArguments/ToolbarFlyoutOpenedEventArgs.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Files Community -// Licensed under the MIT License. - -using Files.App.Views; -using Microsoft.UI.Xaml.Controls; -using Windows.ApplicationModel.DataTransfer; - -namespace Files.App.Data.EventArguments -{ - public sealed class ToolbarFlyoutOpenedEventArgs - { - public MenuFlyout OpenedFlyout { get; set; } - } -} diff --git a/src/Files.App/Data/EventArguments/ToolbarFlyoutOpeningEventArgs.cs b/src/Files.App/Data/EventArguments/ToolbarFlyoutOpeningEventArgs.cs new file mode 100644 index 000000000000..7e3d0f32ccd4 --- /dev/null +++ b/src/Files.App/Data/EventArguments/ToolbarFlyoutOpeningEventArgs.cs @@ -0,0 +1,17 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +using Microsoft.UI.Xaml.Controls; + +namespace Files.App.Data.EventArguments +{ + public sealed class ToolbarFlyoutOpeningEventArgs + { + public MenuFlyout OpeningFlyout { get; } + + public ToolbarFlyoutOpeningEventArgs(MenuFlyout openingFlyout) + { + OpeningFlyout = openingFlyout; + } + } +} diff --git a/src/Files.App/UserControls/AddressToolbar.xaml b/src/Files.App/UserControls/AddressToolbar.xaml index 637c45be2efd..f24e9101c231 100644 --- a/src/Files.App/UserControls/AddressToolbar.xaml +++ b/src/Files.App/UserControls/AddressToolbar.xaml @@ -277,6 +277,7 @@ items, IList destination, bool isBackMode) + private async Task AddHistoryItemsAsync(IEnumerable items, IList flyoutItems, bool isBackMode) { // This may not seem performant, however it's the most viable trade-off to make. // Instead of constantly keeping track of back/forward stack and performing lookups @@ -169,29 +169,41 @@ private async Task AddHistoryItemsAsync(IEnumerable items, IList // There's also a high chance the user might not use the feature at all in which case // the former approach would just waste extra performance gain - destination.Clear(); + flyoutItems.Clear(); foreach (var item in items.Reverse()) { if (item.Parameter is not NavigationArguments args || args.NavPathParam is null) continue; - var imageSource = await NavigationHelpers.GetIconForPathAsync(args.NavPathParam); var fileName = SystemIO.Path.GetFileName(args.NavPathParam); // The fileName is empty if the path is (root) drive path if (string.IsNullOrEmpty(fileName)) fileName = args.NavPathParam; - destination.Add(new MenuFlyoutItem() + var flyoutItem = new MenuFlyoutItem { - Icon = new ImageIcon() { Source = imageSource }, + Icon = new FontIcon { Glyph = "\uE8B7" }, // Use font icon as placeholder Text = fileName, Command = historyItemClickedCommand, CommandParameter = new ToolbarHistoryItemModel(item, isBackMode) - }); + }; + + flyoutItems?.Add(flyoutItem); + + // Start loading the thumbnail in the background + _ = LoadFlyoutItemIconAsync(flyoutItem, args.NavPathParam); } } + private async Task LoadFlyoutItemIconAsync(MenuFlyoutItem flyoutItem, string path) + { + var imageSource = await NavigationHelpers.GetIconForPathAsync(path); + + if (imageSource is not null) + flyoutItem.Icon = new ImageIcon { Source = imageSource }; + } + private void HistoryItemClicked(ToolbarHistoryItemModel? itemModel) { if (itemModel is null) diff --git a/src/Files.App/UserControls/PathBreadcrumb.xaml b/src/Files.App/UserControls/PathBreadcrumb.xaml index 1ccda718b72e..a145c34c41d4 100644 --- a/src/Files.App/UserControls/PathBreadcrumb.xaml +++ b/src/Files.App/UserControls/PathBreadcrumb.xaml @@ -94,8 +94,9 @@ diff --git a/src/Files.App/UserControls/PathBreadcrumb.xaml.cs b/src/Files.App/UserControls/PathBreadcrumb.xaml.cs index 11aaf0ac7182..0ff28ca67331 100644 --- a/src/Files.App/UserControls/PathBreadcrumb.xaml.cs +++ b/src/Files.App/UserControls/PathBreadcrumb.xaml.cs @@ -20,9 +20,9 @@ private void PathItemSeparator_DataContextChanged(FrameworkElement sender, DataC ViewModel.PathItemSeparator_DataContextChanged(sender, args); } - private void PathBoxItemFlyout_Opened(object sender, object e) + private void PathBoxItemFlyout_Opening(object sender, object e) { - ViewModel.PathboxItemFlyout_Opened(sender, e); + ViewModel.PathboxItemFlyout_Opening(sender, e); } private void PathBoxItemFlyout_Closed(object sender, object e) diff --git a/src/Files.App/ViewModels/UserControls/AddressToolbarViewModel.cs b/src/Files.App/ViewModels/UserControls/AddressToolbarViewModel.cs index 905255f092e5..cbd2944e25c9 100644 --- a/src/Files.App/ViewModels/UserControls/AddressToolbarViewModel.cs +++ b/src/Files.App/ViewModels/UserControls/AddressToolbarViewModel.cs @@ -33,7 +33,7 @@ public sealed class AddressToolbarViewModel : ObservableObject, IAddressToolbarV public delegate void ToolbarPathItemInvokedEventHandler(object sender, PathNavigationEventArgs e); - public delegate void ToolbarFlyoutOpenedEventHandler(object sender, ToolbarFlyoutOpenedEventArgs e); + public delegate void ToolbarFlyoutOpeningEventHandler(object sender, ToolbarFlyoutOpeningEventArgs e); public delegate void ToolbarPathItemLoadedEventHandler(object sender, ToolbarPathItemLoadedEventArgs e); @@ -43,7 +43,7 @@ public sealed class AddressToolbarViewModel : ObservableObject, IAddressToolbarV public event ToolbarPathItemInvokedEventHandler? ToolbarPathItemInvoked; - public event ToolbarFlyoutOpenedEventHandler? ToolbarFlyoutOpened; + public event ToolbarFlyoutOpeningEventHandler? ToolbarFlyoutOpening; public event ToolbarPathItemLoadedEventHandler? ToolbarPathItemLoaded; @@ -456,9 +456,9 @@ public void PathItemSeparator_DataContextChanged(FrameworkElement sender, DataCo }); } - public void PathboxItemFlyout_Opened(object sender, object e) + public void PathboxItemFlyout_Opening(object sender, object e) { - ToolbarFlyoutOpened?.Invoke(this, new ToolbarFlyoutOpenedEventArgs() { OpenedFlyout = (MenuFlyout)sender }); + ToolbarFlyoutOpening?.Invoke(this, new ToolbarFlyoutOpeningEventArgs((MenuFlyout)sender)); } public void PathBoxItemFlyout_Closed(object sender, object e) @@ -651,11 +651,9 @@ public async Task SetPathBoxDropDownFlyoutAsync(MenuFlyout flyout, PathBoxItem p foreach (var childFolder in childFolders) { - var imageSource = await NavigationHelpers.GetIconForPathAsync(childFolder.Path); - var flyoutItem = new MenuFlyoutItem { - Icon = new ImageIcon() { Source = imageSource }, + Icon = new FontIcon { Glyph = "\uE8B7" }, // Use font icon as placeholder Text = childFolder.Item.Name, FontSize = 12, }; @@ -670,9 +668,21 @@ public async Task SetPathBoxDropDownFlyoutAsync(MenuFlyout flyout, PathBoxItem p } flyout.Items?.Add(flyoutItem); + + // Start loading the thumbnail in the background + _ = LoadFlyoutItemIconAsync(flyoutItem, childFolder.Path); } } + private async Task LoadFlyoutItemIconAsync(MenuFlyoutItem flyoutItem, string path) + { + var imageSource = await NavigationHelpers.GetIconForPathAsync(path); + + if (imageSource is not null) + flyoutItem.Icon = new ImageIcon { Source = imageSource }; + } + + private static string NormalizePathInput(string currentInput, bool isFtp) { if (currentInput.Contains('/') && !isFtp) diff --git a/src/Files.App/Views/Shells/BaseShellPage.cs b/src/Files.App/Views/Shells/BaseShellPage.cs index b6eed5384111..305c8d211aa4 100644 --- a/src/Files.App/Views/Shells/BaseShellPage.cs +++ b/src/Files.App/Views/Shells/BaseShellPage.cs @@ -180,7 +180,7 @@ public BaseShellPage(CurrentInstanceViewModel instanceViewModel) FlowDirection = FlowDirection.RightToLeft; ToolbarViewModel.ToolbarPathItemInvoked += ShellPage_NavigationRequested; - ToolbarViewModel.ToolbarFlyoutOpened += ShellPage_ToolbarFlyoutOpened; + ToolbarViewModel.ToolbarFlyoutOpening += ShellPage_ToolbarFlyoutOpening; ToolbarViewModel.ToolbarPathItemLoaded += ShellPage_ToolbarPathItemLoaded; ToolbarViewModel.AddressBarTextEntered += ShellPage_AddressBarTextEntered; ToolbarViewModel.PathBoxItemDropped += ShellPage_PathBoxItemDropped; @@ -431,12 +431,12 @@ protected async void ShellPage_ToolbarPathItemLoaded(object sender, ToolbarPathI await ToolbarViewModel.SetPathBoxDropDownFlyoutAsync(e.OpenedFlyout, e.Item, this); } - protected async void ShellPage_ToolbarFlyoutOpened(object sender, ToolbarFlyoutOpenedEventArgs e) + protected async void ShellPage_ToolbarFlyoutOpening(object sender, ToolbarFlyoutOpeningEventArgs e) { - var pathBoxItem = ((Button)e.OpenedFlyout.Target).DataContext as PathBoxItem; + var pathBoxItem = ((Button)e.OpeningFlyout.Target).DataContext as PathBoxItem; if (pathBoxItem is not null) - await ToolbarViewModel.SetPathBoxDropDownFlyoutAsync(e.OpenedFlyout, pathBoxItem, this); + await ToolbarViewModel.SetPathBoxDropDownFlyoutAsync(e.OpeningFlyout, pathBoxItem, this); } protected async void NavigationToolbar_QuerySubmitted(object sender, ToolbarQuerySubmittedEventArgs e) @@ -828,7 +828,7 @@ public virtual void Dispose() drivesViewModel.PropertyChanged -= DrivesManager_PropertyChanged; ToolbarViewModel.ToolbarPathItemInvoked -= ShellPage_NavigationRequested; - ToolbarViewModel.ToolbarFlyoutOpened -= ShellPage_ToolbarFlyoutOpened; + ToolbarViewModel.ToolbarFlyoutOpening -= ShellPage_ToolbarFlyoutOpening; ToolbarViewModel.ToolbarPathItemLoaded -= ShellPage_ToolbarPathItemLoaded; ToolbarViewModel.AddressBarTextEntered -= ShellPage_AddressBarTextEntered; ToolbarViewModel.PathBoxItemDropped -= ShellPage_PathBoxItemDropped;