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

Fix: Fixed issue where opening and closing modals quickly may lead to a crash #11928

Merged
Merged
Show file tree
Hide file tree
Changes from 4 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
22 changes: 22 additions & 0 deletions src/Files.App/Actions/BaseUIAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Files.App.Helpers;
using System.ComponentModel;

namespace Files.App.Actions
{
internal abstract class BaseUIAction : ObservableObject
yaira2 marked this conversation as resolved.
Show resolved Hide resolved
{
public virtual bool IsExecutable => UIHelpers.CanShowDialog;

public BaseUIAction()
{
UIHelpers.PropertyChanged += UIHelpers_PropertyChanged;
}

private void UIHelpers_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName is nameof(UIHelpers.CanShowDialog))
OnPropertyChanged(nameof(IsExecutable));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.App.Contexts;
using Files.App.Dialogs;
using Files.App.Extensions;
using Files.App.Filesystem.Archive;
using Files.App.Helpers;
using Microsoft.UI.Xaml.Controls;
using System.ComponentModel;
using System.Threading.Tasks;

namespace Files.App.Actions
{
internal class CompressIntoArchiveAction : ObservableObject, IAction
internal class CompressIntoArchiveAction : BaseUIAction, IAction
{
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();

public string Label => "CreateArchive".GetLocalizedResource();

public string Description => "TODO: Need to be described.";

public bool IsExecutable => IsContextPageTypeAdaptedToCommand()
&& ArchiveHelpers.CanCompress(context.SelectedItems);
public override bool IsExecutable =>
IsContextPageTypeAdaptedToCommand() &&
ArchiveHelpers.CanCompress(context.SelectedItems) &&
UIHelpers.CanShowDialog;

public CompressIntoArchiveAction()
{
Expand All @@ -34,9 +36,9 @@ public async Task ExecuteAsync()
{
FileName = fileName,
};
await dialog.ShowAsync();
var result = await dialog.TryShowAsync();

if (!dialog.CanCreate)
if (!dialog.CanCreate || result != ContentDialogResult.Primary)
return;

IArchiveCreator creator = new ArchiveCreator
Expand Down
11 changes: 6 additions & 5 deletions src/Files.App/Actions/Content/Archives/DecompressArchive.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.App.Commands;
using Files.App.Contexts;
using Files.App.Extensions;
Expand All @@ -10,7 +9,7 @@

namespace Files.App.Actions
{
internal class DecompressArchive : ObservableObject, IAction
internal class DecompressArchive : BaseUIAction, IAction
{
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();

Expand All @@ -20,8 +19,10 @@ internal class DecompressArchive : ObservableObject, IAction

public HotKey HotKey { get; } = new(VirtualKey.E, VirtualKeyModifiers.Control);

public bool IsExecutable => IsContextPageTypeAdaptedToCommand()
&& ArchiveHelpers.CanDecompress(context.SelectedItems);
public override bool IsExecutable =>
IsContextPageTypeAdaptedToCommand() &&
ArchiveHelpers.CanDecompress(context.SelectedItems) &&
UIHelpers.CanShowDialog;

public DecompressArchive()
{
Expand Down
11 changes: 6 additions & 5 deletions src/Files.App/Actions/Content/Archives/DecompressArchiveHere.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.App.Contexts;
using Files.App.Extensions;
using Files.App.Helpers;
Expand All @@ -8,16 +7,18 @@

namespace Files.App.Actions
{
internal class DecompressArchiveHere : ObservableObject, IAction
internal class DecompressArchiveHere : BaseUIAction, IAction
{
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();

public string Label => "ExtractHere".GetLocalizedResource();

public string Description => "TODO: Need to be described.";

public bool IsExecutable => IsContextPageTypeAdaptedToCommand()
&& ArchiveHelpers.CanDecompress(context.SelectedItems);
public override bool IsExecutable =>
IsContextPageTypeAdaptedToCommand() &&
ArchiveHelpers.CanDecompress(context.SelectedItems) &&
UIHelpers.CanShowDialog;

public DecompressArchiveHere()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.App.Contexts;
using Files.App.Extensions;
using Files.App.Helpers;
Expand All @@ -10,16 +9,18 @@

namespace Files.App.Actions
{
internal class DecompressArchiveToChildFolderAction : ObservableObject, IAction
internal class DecompressArchiveToChildFolderAction : BaseUIAction, IAction
{
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();

public string Label => ComputeLabel();

public string Description => "TODO: Need to be described.";

public bool IsExecutable => IsContextPageTypeAdaptedToCommand()
&& ArchiveHelpers.CanDecompress(context.SelectedItems);
public override bool IsExecutable =>
IsContextPageTypeAdaptedToCommand() &&
ArchiveHelpers.CanDecompress(context.SelectedItems) &&
UIHelpers.CanShowDialog;

public DecompressArchiveToChildFolderAction()
{
Expand Down
7 changes: 3 additions & 4 deletions src/Files.App/Actions/FileSystem/CreateFolderAction.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.App.Commands;
using Files.App.Contexts;
using Files.App.Extensions;
Expand All @@ -10,7 +9,7 @@

namespace Files.App.Actions
{
internal class CreateFolderAction : ObservableObject, IAction
internal class CreateFolderAction : BaseUIAction, IAction
{
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();

Expand All @@ -20,7 +19,7 @@ internal class CreateFolderAction : ObservableObject, IAction

public RichGlyph Glyph { get; } = new RichGlyph(baseGlyph: "\uE8B7");

public bool IsExecutable => context.ShellPage is not null;
public override bool IsExecutable => context.ShellPage is not null && UIHelpers.CanShowDialog;

public CreateFolderAction()
{
Expand Down
7 changes: 3 additions & 4 deletions src/Files.App/Actions/FileSystem/CreateShortcutAction.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.App.Commands;
using Files.App.Contexts;
using Files.App.Extensions;
Expand All @@ -11,7 +10,7 @@

namespace Files.App.Actions
{
internal class CreateShortcutAction : ObservableObject, IAction
internal class CreateShortcutAction : BaseUIAction, IAction
{
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();

Expand All @@ -21,7 +20,7 @@ internal class CreateShortcutAction : ObservableObject, IAction

public RichGlyph Glyph { get; } = new RichGlyph(opacityStyle: "ColorIconShortcut");

public bool IsExecutable => context.HasSelection;
public override bool IsExecutable => context.HasSelection && UIHelpers.CanShowDialog;

public CreateShortcutAction()
{
Expand Down
22 changes: 17 additions & 5 deletions src/Files.App/Actions/FileSystem/CreateShortcutFromDialogAction.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.App.Commands;
using Files.App.Contexts;
using Files.App.Extensions;
using Files.App.Helpers;
using System.ComponentModel;
using System.Threading.Tasks;

namespace Files.App.Actions
{
internal class CreateShortcutFromDialogAction : ObservableObject, IAction
internal class CreateShortcutFromDialogAction : BaseUIAction, IAction
{
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();

Expand All @@ -18,10 +18,22 @@ internal class CreateShortcutFromDialogAction : ObservableObject, IAction

public RichGlyph Glyph { get; } = new RichGlyph(opacityStyle: "ColorIconShortcut");

public override bool IsExecutable => context.ShellPage is not null && UIHelpers.CanShowDialog;

public CreateShortcutFromDialogAction()
{
context.PropertyChanged += Context_PropertyChanged;
}

public async Task ExecuteAsync()
{
if (context.ShellPage is not null)
await UIFilesystemHelpers.CreateShortcutFromDialogAsync(context.ShellPage);
await UIFilesystemHelpers.CreateShortcutFromDialogAsync(context.ShellPage);
}

private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName is nameof(IContentPageContext.ShellPage))
OnPropertyChanged(nameof(IsExecutable));
}
}
}
7 changes: 4 additions & 3 deletions src/Files.App/Actions/FileSystem/DeleteItemAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

namespace Files.App.Actions
{
internal class DeleteItemAction : ObservableObject, IAction
internal class DeleteItemAction : BaseUIAction, IAction
{
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();
private readonly IFoldersSettingsService settings = Ioc.Default.GetRequiredService<IFoldersSettingsService>();
Expand All @@ -27,9 +27,10 @@ internal class DeleteItemAction : ObservableObject, IAction

public HotKey HotKey { get; } = new(VirtualKey.Delete);

public bool IsExecutable =>
public override bool IsExecutable =>
context.HasSelection &&
(!context.ShellPage?.SlimContentPage?.IsRenamingItem ?? false);
(!context.ShellPage?.SlimContentPage?.IsRenamingItem ?? false) &&
UIHelpers.CanShowDialog;

public DeleteItemAction()
{
Expand Down
21 changes: 7 additions & 14 deletions src/Files.App/Actions/FileSystem/EmptyRecycleBinAction.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.App.Commands;
using Files.App.Contexts;
using Files.App.Extensions;
Expand All @@ -9,7 +8,7 @@

namespace Files.App.Actions
{
internal class EmptyRecycleBinAction : ObservableObject, IAction
internal class EmptyRecycleBinAction : BaseUIAction, IAction
{
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();

Expand All @@ -19,15 +18,10 @@ internal class EmptyRecycleBinAction : ObservableObject, IAction

public RichGlyph Glyph { get; } = new RichGlyph(opacityStyle: "ColorIconDelete");

public bool IsExecutable
{
get
{
if (context.PageType is ContentPageTypes.RecycleBin)
return context.HasItem;
return RecycleBinHelpers.RecycleBinHasItems();
}
}
public override bool IsExecutable =>
UIHelpers.CanShowDialog &&
((context.PageType is ContentPageTypes.RecycleBin && context.HasItem) ||
RecycleBinHelpers.RecycleBinHasItems());

public EmptyRecycleBinAction()
{
Expand All @@ -45,8 +39,7 @@ private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
case nameof(IContentPageContext.PageType):
case nameof(IContentPageContext.HasItem):
if (context.PageType is ContentPageTypes.RecycleBin)
OnPropertyChanged(nameof(IsExecutable));
OnPropertyChanged(nameof(IsExecutable));
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.App.Commands;
using Files.App.Contexts;
using Files.App.DataModels;
Expand All @@ -12,7 +11,7 @@

namespace Files.App.Actions
{
internal class PasteItemToSelectionAction : ObservableObject, IAction
internal class PasteItemToSelectionAction : BaseUIAction, IAction
{
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();

Expand All @@ -25,7 +24,7 @@ internal class PasteItemToSelectionAction : ObservableObject, IAction
public HotKey HotKey { get; } = new(VirtualKey.V, VirtualKeyModifiers.Control | VirtualKeyModifiers.Shift);

private bool isExecutable;
public bool IsExecutable => isExecutable;
public override bool IsExecutable => isExecutable;

public PasteItemToSelectionAction()
{
Expand Down Expand Up @@ -55,7 +54,7 @@ public bool GetIsExecutable()
return false;
if (!context.HasSelection)
return true;
return context.SelectedItem?.PrimaryItemAttribute is Windows.Storage.StorageItemTypes.Folder;
return context.SelectedItem?.PrimaryItemAttribute is Windows.Storage.StorageItemTypes.Folder && UIHelpers.CanShowDialog;
}

private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
Expand Down
19 changes: 7 additions & 12 deletions src/Files.App/Actions/FileSystem/RestoreAllRecycleBinAction.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.App.Commands;
using Files.App.Contexts;
using Files.App.Extensions;
Expand All @@ -9,7 +8,7 @@

namespace Files.App.Actions
{
internal class RestoreAllRecycleBinAction : ObservableObject, IAction
internal class RestoreAllRecycleBinAction : BaseUIAction, IAction
{
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();

Expand All @@ -19,15 +18,11 @@ internal class RestoreAllRecycleBinAction : ObservableObject, IAction

public RichGlyph Glyph { get; } = new RichGlyph(opacityStyle: "ColorIconRestoreItem");

public bool IsExecutable
{
get
{
if (context.PageType is ContentPageTypes.RecycleBin)
return context.HasItem;
return RecycleBinHelpers.RecycleBinHasItems();
}
}
public override bool IsExecutable =>
context.ShellPage is not null &&
UIHelpers.CanShowDialog &&
((context.PageType is ContentPageTypes.RecycleBin && context.HasItem) ||
RecycleBinHelpers.RecycleBinHasItems());

public RestoreAllRecycleBinAction()
{
Expand Down
Loading