Added modular selection actions

This commit is contained in:
Marcel Baumgartner 2024-03-30 22:06:33 +01:00
parent 49077e7023
commit b2929fe211
7 changed files with 107 additions and 34 deletions

View file

@ -52,9 +52,11 @@ public class FileManagerFeature : MoonlightFeature
// Register default file manager actions in plugin service // Register default file manager actions in plugin service
var pluginService = context.Application.Services.GetRequiredService<PluginService>(); var pluginService = context.Application.Services.GetRequiredService<PluginService>();
await pluginService.RegisterImplementation<IFileManagerAction>(new RenameFileManagerAction()); await pluginService.RegisterImplementation<IFileManagerAction>(new RenameAction());
await pluginService.RegisterImplementation<IFileManagerAction>(new DownloadFileManagerAction()); await pluginService.RegisterImplementation<IFileManagerAction>(new DownloadAction());
await pluginService.RegisterImplementation<IFileManagerAction>(new DeleteFileManagerAction()); await pluginService.RegisterImplementation<IFileManagerAction>(new DeleteAction());
await pluginService.RegisterImplementation<IFileManagerSelectionAction>(new DeleteSelectionAction());
} }
public override async Task OnSessionInitialized(SessionInitContext context) public override async Task OnSessionInitialized(SessionInitContext context)

View file

@ -5,7 +5,7 @@ using Moonlight.Features.FileManager.UI.NewFileManager;
namespace Moonlight.Features.FileManager.Implementations; namespace Moonlight.Features.FileManager.Implementations;
public class DeleteFileManagerAction : IFileManagerAction public class DeleteAction : IFileManagerAction
{ {
public string Name => "Delete"; public string Name => "Delete";
public string Icon => "bxs-trash"; public string Icon => "bxs-trash";

View file

@ -0,0 +1,34 @@
using MoonCoreUI.Services;
using Moonlight.Features.FileManager.Interfaces;
using Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
using Moonlight.Features.FileManager.UI.NewFileManager;
namespace Moonlight.Features.FileManager.Implementations;
public class DeleteSelectionAction : IFileManagerSelectionAction
{
public string Name => "Delete";
public string Color => "danger";
public async Task Execute(BaseFileAccess access, FileView view, FileEntry[] entries, IServiceProvider provider)
{
var alertService = provider.GetRequiredService<AlertService>();
var toastService = provider.GetRequiredService<ToastService>();
if(!await alertService.YesNo($"Do you really want to delete {entries.Length} item(s)?"))
return;
await toastService.CreateProgress("fileManagerSelectionDelete", "Deleting items");
foreach (var entry in entries)
{
await toastService.ModifyProgress("fileManagerSelectionDelete", $"Deleting '{entry.Name}'");
await access.Delete(entry);
}
await toastService.RemoveProgress("fileManagerSelectionDelete");
await toastService.Success($"Successfully deleted selection");
}
}

View file

@ -8,7 +8,7 @@ using Moonlight.Features.FileManager.UI.NewFileManager;
namespace Moonlight.Features.FileManager.Implementations; namespace Moonlight.Features.FileManager.Implementations;
public class DownloadFileManagerAction : IFileManagerAction public class DownloadAction : IFileManagerAction
{ {
public string Name => "Download"; public string Name => "Download";
public string Icon => "bxs-cloud-download"; public string Icon => "bxs-cloud-download";

View file

@ -5,7 +5,7 @@ using Moonlight.Features.FileManager.UI.NewFileManager;
namespace Moonlight.Features.FileManager.Implementations; namespace Moonlight.Features.FileManager.Implementations;
public class RenameFileManagerAction : IFileManagerAction public class RenameAction : IFileManagerAction
{ {
public string Name => "Rename"; public string Name => "Rename";
public string Icon => "bxs-rename"; public string Icon => "bxs-rename";

View file

@ -0,0 +1,12 @@
using Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
using Moonlight.Features.FileManager.UI.NewFileManager;
namespace Moonlight.Features.FileManager.Interfaces;
public interface IFileManagerSelectionAction
{
public string Name { get; }
public string Color { get; }
public Task Execute(BaseFileAccess access, FileView view, FileEntry[] entries, IServiceProvider provider);
}

View file

@ -45,30 +45,42 @@
</div> </div>
</div> </div>
<div class="d-flex justify-content-center justify-content-md-end align-items-center"> <div class="d-flex justify-content-center justify-content-md-end align-items-center">
<WButton OnClick="ManualRefresh" CssClasses="btn btn-icon btn-light-info"> @if (View != null && View.Selection.Any())
<i class="bx bx-sm bx-refresh"></i> {
</WButton> foreach (var action in SelectionActions)
<label for="fileManagerSelect" class="btn btn-light-primary mx-2">Upload</label> {
<input id="fileManagerSelect" type="file" hidden="hidden" multiple/> var cssClass = $"btn btn-{action.Color} mx-2";
<div class="dropdown">
<a class="btn btn-primary dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false"> <WButton Text="@action.Name" CssClasses="@cssClass" OnClick="() => InvokeSelectionAction(action)" />
New }
</a> }
<ul class="dropdown-menu" aria-labelledby="dropdownMenuLink" style=""> else
<li> {
<a href="#" class="dropdown-item" @onclick:preventDefault @onclick="CreateFile"> <WButton OnClick="ManualRefresh" CssClasses="btn btn-icon btn-light-info">
<i class="bx bx-sm bx-file text-primary me-2 align-middle"></i> <i class="bx bx-sm bx-refresh"></i>
<span class="align-middle fs-6">File</span> </WButton>
</a> <label for="fileManagerSelect" class="btn btn-light-primary mx-2">Upload</label>
</li> <input id="fileManagerSelect" type="file" hidden="hidden" multiple/>
<li> <div class="dropdown">
<a href="#" class="dropdown-item" @onclick:preventDefault @onclick="CreateDirectory"> <a class="btn btn-primary dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bx bx-sm bx-folder text-primary me-2 align-middle"></i> New
<span class="align-middle fs-6">Folder</span> </a>
</a> <ul class="dropdown-menu" aria-labelledby="dropdownMenuLink" style="">
</li> <li>
</ul> <a href="#" class="dropdown-item" @onclick:preventDefault @onclick="CreateFile">
</div> <i class="bx bx-sm bx-file text-primary me-2 align-middle"></i>
<span class="align-middle fs-6">File</span>
</a>
</li>
<li>
<a href="#" class="dropdown-item" @onclick:preventDefault @onclick="CreateDirectory">
<i class="bx bx-sm bx-folder text-primary me-2 align-middle"></i>
<span class="align-middle fs-6">Folder</span>
</a>
</li>
</ul>
</div>
}
</div> </div>
</div> </div>
</div> </div>
@ -86,6 +98,7 @@ else
FileAccess="FileAccess" FileAccess="FileAccess"
OnEntryClicked="OnEntryClicked" OnEntryClicked="OnEntryClicked"
OnNavigateUpClicked="OnNavigateUpClicked" OnNavigateUpClicked="OnNavigateUpClicked"
OnSelectionChanged="OnSelectionChanged"
EnableContextMenu="true"> EnableContextMenu="true">
<ContextMenuTemplate> <ContextMenuTemplate>
@foreach (var action in Actions) @foreach (var action in Actions)
@ -138,6 +151,7 @@ else
private string Path = "/"; private string Path = "/";
private IFileManagerAction[] Actions; private IFileManagerAction[] Actions;
private IFileManagerSelectionAction[] SelectionActions;
// Editor // Editor
private FileEditor Editor; private FileEditor Editor;
@ -156,8 +170,12 @@ else
private Timer? UploadTokenTimer; private Timer? UploadTokenTimer;
protected override void OnInitialized() protected override async Task OnInitializedAsync()
{ {
// Load plugin ui and options
Actions = await PluginService.GetImplementations<IFileManagerAction>();
SelectionActions = await PluginService.GetImplementations<IFileManagerSelectionAction>();
OnFolderClicked = async entry => OnFolderClicked = async entry =>
{ {
await MoveAccess.ChangeDirectory(entry.Name); await MoveAccess.ChangeDirectory(entry.Name);
@ -175,9 +193,6 @@ else
if (!firstRender) if (!firstRender)
return; return;
// Load plugin ui and options
Actions = await PluginService.GetImplementations<IFileManagerAction>();
// Setup upload url update timer // Setup upload url update timer
UploadTokenTimer = new(async _ => UploadTokenTimer = new(async _ =>
@ -233,6 +248,16 @@ else
await action.Execute(FileAccess, View, entry, ServiceProvider); await action.Execute(FileAccess, View, entry, ServiceProvider);
} }
private async Task InvokeSelectionAction(IFileManagerSelectionAction action)
{
await action.Execute(FileAccess, View, View.Selection, ServiceProvider);
// Refresh resets the selection
await View.Refresh();
}
private async Task OnSelectionChanged(FileEntry[] _) => await InvokeAsync(StateHasChanged);
#region Navigation & Refreshing #region Navigation & Refreshing
private async Task OnNavigateUpClicked() private async Task OnNavigateUpClicked()