Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code Quality: Refactor LayoutPages & ShellPages #11929

Merged
merged 19 commits into from
Apr 2, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/Files.App/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

<Application.Resources>
<ResourceDictionary>

<!-- Default list view item height -->
<x:Double x:Key="ListItemHeight">36</x:Double>

Expand Down Expand Up @@ -75,6 +76,7 @@
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>

</ResourceDictionary>
</Application.Resources>
</Application>
</Application>
60 changes: 40 additions & 20 deletions src/Files.App/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,8 @@
using Windows.Storage;
using Windows.UI.Notifications;


namespace Files.App
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public partial class App : Application
{
private static bool ShowErrorNotification = false;
Expand Down Expand Up @@ -140,10 +136,12 @@ await Task.WhenAll(
OptionalTask(FileTagsManager.UpdateFileTagsAsync(), preferencesSettingsService.ShowFileTagsSection),
QuickAccessManager.InitializeAsync()
);

await Task.WhenAll(
JumpListHelper.InitializeUpdatesAsync(),
addItemService.GetNewEntriesAsync()
);

FileTagsHelper.UpdateTagsDb();
});

Expand Down Expand Up @@ -233,10 +231,12 @@ protected override void OnLaunched(LaunchActivatedEventArgs e)
.AddSingleton<AppearanceViewModel>()
)
.Build();

Logger = host.Services.GetRequiredService<ILogger<App>>();
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);
Expand Down Expand Up @@ -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));
}
Expand All @@ -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();

Expand All @@ -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();
Expand All @@ -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
/// <summary>
/// Enumerates through all tabs and gets the Path property and saves it to AppSettings.LastSessionPages.
/// </summary>
public static void SaveSessionTabs()
{
IUserSettingsService userSettingsService = Ioc.Default.GetRequiredService<IUserSettingsService>();
IBundlesSettingsService bundlesSettingsService = Ioc.Default.GetRequiredService<IBundlesSettingsService>();
Expand All @@ -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);
/// <summary>
/// Occurs when an exception is not handled on the UI thread.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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);
/// <summary>
/// Occurs when an exception is not handled on a background thread.
/// i.e. A task is fired and forgotten Task.Run(() => {...})
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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");
Expand Down Expand Up @@ -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);
Expand All @@ -399,7 +421,7 @@ private static void AppUnhandledException(Exception ex, bool shouldShowNotificat

var toastContent = new ToastContent()
{
Visual = new ToastVisual()
Visual = new()
{
BindingGeneric = new ToastBindingGeneric()
{
Expand All @@ -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"
}
Expand All @@ -440,9 +462,7 @@ private static void AppUnhandledException(Exception ex, bool shouldShowNotificat
}

public static void CloseApp()
{
Window.Close();
}
=> Window.Close();
yaira2 marked this conversation as resolved.
Show resolved Hide resolved

public static AppWindow GetAppWindow(Window w)
{
Expand Down
73 changes: 37 additions & 36 deletions src/Files.App/BaseLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -515,9 +515,7 @@ navigationArguments.SelectItems is not null &&
ItemManipulationModel.FocusFileList();
}
}
catch (Exception)
{
}
catch (Exception) { }
}

private CancellationTokenSource? groupingCancellationToken;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -747,7 +749,7 @@ private async Task AddShellMenuItemsAsync(List<ContextMenuFlyoutItemViewModel> 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)));

Expand Down Expand Up @@ -854,34 +856,31 @@ private async Task AddShellMenuItemsAsync(List<ContextMenuFlyoutItemViewModel> s
ShellContextmenuHelper.AddItemsToOverflowMenu(overflowItem, x);
});

if (itemsControl is not null)
itemsControl?.Items.OfType<FrameworkElement>().ForEach(item =>
{
itemsControl.Items.OfType<FrameworkElement>().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<IList<MenuFlyoutItemBase>> clickAction = null!;
clickAction = (items) =>
{
Action<IList<MenuFlyoutItemBase>> clickAction = null!;
clickAction = (items) =>
items.OfType<MenuFlyoutItem>().ForEach(i =>
{
items.OfType<MenuFlyoutItem>().ForEach(i =>
{
i.Click += new RoutedEventHandler((s, e) => contextMenuFlyout.Hide());
});
items.OfType<MenuFlyoutSubItem>().ForEach(i =>
{
clickAction(i.Items);
});
};
i.Click += new RoutedEventHandler((s, e) => contextMenuFlyout.Hide());
});
items.OfType<MenuFlyoutSubItem>().ForEach(i =>
{
clickAction(i.Items);
});
};

clickAction(flyout.Items);
}
});
}
clickAction(flyout.Items);
}
});
}

private void RemoveOverflow(CommandBarFlyout contextMenuFlyout)
Expand Down Expand Up @@ -913,6 +912,7 @@ protected void FileList_DragItemsStarting(object sender, DragItemsStartingEventA
{
var iddo = shellItemList[0].Parent.GetChildrenUIObjects<IDataObject>(HWND.NULL, shellItemList);
shellItemList.ForEach(x => x.Dispose());

var format = System.Windows.Forms.DataFormats.GetFormat("Shell IDList Array");
if (iddo.TryGetData<byte[]>((uint)format.Id, out var data))
{
Expand Down Expand Up @@ -951,6 +951,7 @@ protected async void Item_DragOver(object sender, DragEventArgs e)
return;

DragOperationDeferral? deferral = null;

try
{
deferral = e.GetDeferral();
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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())
Expand All @@ -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);
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1239,15 +1240,15 @@ private void UpdateCollectionViewSource()

if (ParentShellPageInstance.FilesystemViewModel.FilesAndFolders.IsGrouped)
{
CollectionViewSource = new CollectionViewSource()
CollectionViewSource = new()
{
IsSourceGrouped = true,
Source = ParentShellPageInstance.FilesystemViewModel.FilesAndFolders.GroupedCollection
};
}
else
{
CollectionViewSource = new CollectionViewSource()
CollectionViewSource = new()
{
IsSourceGrouped = false,
Source = ParentShellPageInstance.FilesystemViewModel.FilesAndFolders
Expand Down
3 changes: 3 additions & 0 deletions src/Files.App/Files.App.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,7 @@
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
</Page>
</ItemGroup>
<ItemGroup>
<Folder Include="ViewModels\Pages\" />
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions src/Files.App/IShellPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
}
}
}
Loading