diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 53d88f6..7334cb5 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -33,7 +33,7 @@ body: attributes: label: Panel Version description: Version number of your Panel (latest is not a version) - placeholder: 1.4.0 + placeholder: v2 EA validations: required: true @@ -42,16 +42,7 @@ body: attributes: label: Daemon Version description: Version number of your Daemon (latest is not a version) - placeholder: 1.4.2 - validations: - required: true - -- type: input - id: wings-version - attributes: - label: Wings Version - description: Version number of your Wings (latest is not a version) - placeholder: 1.4.2 + placeholder: v2 EA validations: required: true @@ -93,4 +84,4 @@ body: - label: I have provided all relevant details, including the specific game and Docker images I am using if this issue is related to running a server. required: true - label: I have checked in the Discord server and believe this is a bug with the software, and not a configuration issue with my specific system. - required: true \ No newline at end of file + required: true diff --git a/.gitignore b/.gitignore index 6cfd4f4..1cd56bb 100644 --- a/.gitignore +++ b/.gitignore @@ -400,4 +400,5 @@ FodyWeavers.xsd storage/ .idea/.idea.Moonlight/.idea/dataSources.xml Moonlight/wwwroot/css/theme.css -Moonlight/wwwroot/css/theme.css.map \ No newline at end of file +Moonlight/wwwroot/css/theme.css.map +.idea/.idea.Moonlight/.idea/discord.xml diff --git a/Moonlight/Core/UI/Components/Partials/SoftErrorHandler.razor b/Moonlight/Core/UI/Components/Partials/SoftErrorHandler.razor index 927e6d5..f6c4400 100644 --- a/Moonlight/Core/UI/Components/Partials/SoftErrorHandler.razor +++ b/Moonlight/Core/UI/Components/Partials/SoftErrorHandler.razor @@ -7,7 +7,7 @@ @inherits ErrorBoundaryBase -@if (Crashed || CurrentException != null) +@if (Crashed || Exception != null) { if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" || (IdentityService.IsLoggedIn && IdentityService.CurrentUser.Permissions >= 9000)) { diff --git a/Moonlight/Core/UI/Components/Partials/StatCard.razor b/Moonlight/Core/UI/Components/Partials/StatCard.razor index 3cf844d..dd5f143 100644 --- a/Moonlight/Core/UI/Components/Partials/StatCard.razor +++ b/Moonlight/Core/UI/Components/Partials/StatCard.razor @@ -11,14 +11,14 @@ else {
-
+
-
+
@Value
-
+
@Description
diff --git a/Moonlight/Core/UI/Views/Admin/Index.razor b/Moonlight/Core/UI/Views/Admin/Index.razor index 713a618..0b6399a 100644 --- a/Moonlight/Core/UI/Views/Admin/Index.razor +++ b/Moonlight/Core/UI/Views/Admin/Index.razor @@ -34,7 +34,7 @@ private async Task Load(LazyLoader arg) { - await arg.SetText("Loading Information..."); + await arg.SetText("Loading statistics..."); var componentImplementations = await PluginService.GetImplementations(); diff --git a/Moonlight/Features/FileManager/FileManagerFeature.cs b/Moonlight/Features/FileManager/FileManagerFeature.cs index c3171a6..eb80a64 100644 --- a/Moonlight/Features/FileManager/FileManagerFeature.cs +++ b/Moonlight/Features/FileManager/FileManagerFeature.cs @@ -54,9 +54,12 @@ public class FileManagerFeature : MoonlightFeature await pluginService.RegisterImplementation(new RenameContextAction()); await pluginService.RegisterImplementation(new MoveContextAction()); await pluginService.RegisterImplementation(new DownloadContextAction()); + await pluginService.RegisterImplementation(new ArchiveContextAction()); + await pluginService.RegisterImplementation(new ExtractContextAction()); await pluginService.RegisterImplementation(new DeleteContextAction()); await pluginService.RegisterImplementation(new MoveSelectionAction()); + await pluginService.RegisterImplementation(new ArchiveSelectionAction()); await pluginService.RegisterImplementation(new DeleteSelectionAction()); await pluginService.RegisterImplementation(new CreateFileAction()); diff --git a/Moonlight/Features/FileManager/Implementations/ArchiveContextAction.cs b/Moonlight/Features/FileManager/Implementations/ArchiveContextAction.cs new file mode 100644 index 0000000..f2045a7 --- /dev/null +++ b/Moonlight/Features/FileManager/Implementations/ArchiveContextAction.cs @@ -0,0 +1,59 @@ +using MoonCore.Exceptions; +using MoonCore.Helpers; +using MoonCoreUI.Services; +using Moonlight.Features.FileManager.Interfaces; +using Moonlight.Features.FileManager.Models.Abstractions.FileAccess; + +namespace Moonlight.Features.FileManager.Implementations; + +public class ArchiveContextAction : IFileManagerContextAction +{ + public string Name => "Archive"; + public string Icon => "bxs-archive-in"; + public string Color => "warning"; + public Func Filter => _ => true; + + public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry entry, + IServiceProvider provider) + { + var archiveAccess = access.Actions as IArchiveFileActions; + + if (archiveAccess == null) + throw new DisplayException("This file access does not support archiving"); + + var alertService = provider.GetRequiredService(); + + var fileName = await alertService.Text("Enter the archive file name", "", + Formatter.FormatDate(DateTime.UtcNow) + ".tar.gz"); + + if (string.IsNullOrEmpty(fileName) || fileName.Contains("..")) // => canceled + return; + + var toastService = provider.GetRequiredService(); + + await toastService.CreateProgress("fileManagerArchive", "Archiving... Please be patient"); + + try + { + await archiveAccess.Archive( + access.CurrentDirectory + fileName, + new[] { access.CurrentDirectory + entry.Name } + ); + + await toastService.Success("Successfully created archive"); + } + catch (Exception e) + { + Logger.Warn($"An error occured while archiving item ({entry.Name}):"); + Logger.Warn(e); + + await toastService.Danger("An unknown error occured while creating archive"); + } + finally + { + await toastService.RemoveProgress("fileManagerArchive"); + } + + await fileManager.View.Refresh(); + } +} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Implementations/ArchiveSelectionAction.cs b/Moonlight/Features/FileManager/Implementations/ArchiveSelectionAction.cs index 135823d..240372e 100644 --- a/Moonlight/Features/FileManager/Implementations/ArchiveSelectionAction.cs +++ b/Moonlight/Features/FileManager/Implementations/ArchiveSelectionAction.cs @@ -14,10 +14,7 @@ public class ArchiveSelectionAction : IFileManagerSelectionAction public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry[] entries, IServiceProvider provider) { - if (!access.Actions.GetType().IsAssignableFrom(typeof(IArchiveFileActions))) - throw new DisplayException("This file access does not support archiving"); - - var archiveAccess = access as IArchiveFileActions; + var archiveAccess = access.Actions as IArchiveFileActions; if (archiveAccess == null) throw new DisplayException("This file access does not support archiving"); @@ -29,10 +26,30 @@ public class ArchiveSelectionAction : IFileManagerSelectionAction if (string.IsNullOrEmpty(fileName) || fileName.Contains("..")) // => canceled return; + + var toastService = provider.GetRequiredService(); - await archiveAccess.Archive( - access.CurrentDirectory + fileName, - entries.Select(x => access.CurrentDirectory + x.Name).ToArray() - ); + await toastService.CreateProgress("fileManagerArchive", "Archiving... Please be patient"); + + try + { + await archiveAccess.Archive( + access.CurrentDirectory + fileName, + entries.Select(x => access.CurrentDirectory + x.Name).ToArray() + ); + + await toastService.Success("Successfully created archive"); + } + catch (Exception e) + { + Logger.Warn($"An error occured while archiving items ({entries.Length}):"); + Logger.Warn(e); + + await toastService.Danger("An unknown error occured while creating archive"); + } + finally + { + await toastService.RemoveProgress("fileManagerArchive"); + } } } \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Implementations/ExtractContextAction.cs b/Moonlight/Features/FileManager/Implementations/ExtractContextAction.cs new file mode 100644 index 0000000..2b8735f --- /dev/null +++ b/Moonlight/Features/FileManager/Implementations/ExtractContextAction.cs @@ -0,0 +1,52 @@ +using MoonCore.Exceptions; +using MoonCore.Helpers; +using MoonCoreUI.Services; +using Moonlight.Features.FileManager.Interfaces; +using Moonlight.Features.FileManager.Models.Abstractions.FileAccess; + +namespace Moonlight.Features.FileManager.Implementations; + +public class ExtractContextAction : IFileManagerContextAction +{ + public string Name => "Extract"; + public string Icon => "bxs-archive-out"; + public string Color => "warning"; + public Func Filter => entry => entry.IsFile && entry.Name.EndsWith(".tar.gz"); + public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry entry, IServiceProvider provider) + { + var archiveAccess = access.Actions as IArchiveFileActions; + + if (archiveAccess == null) + throw new DisplayException("This file access does not support archiving"); + + await fileManager.OpenFolderSelect("Select where you want to extract the content of the archive", async destination => + { + var toastService = provider.GetRequiredService(); + + await toastService.CreateProgress("fileManagerExtract", "Extracting... Please be patient"); + + try + { + await archiveAccess.Extract( + access.CurrentDirectory + entry.Name, + destination + ); + + await toastService.Success("Successfully extracted archive"); + } + catch (Exception e) + { + Logger.Warn($"An error occured while extracting archive ({entry.Name}):"); + Logger.Warn(e); + + await toastService.Danger("An unknown error occured while extracting archive"); + } + finally + { + await toastService.RemoveProgress("fileManagerExtract"); + } + + await fileManager.View.Refresh(); + }); + } +} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IArchiveFileActions.cs b/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IArchiveFileActions.cs index 988bd16..ed35594 100644 --- a/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IArchiveFileActions.cs +++ b/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IArchiveFileActions.cs @@ -3,4 +3,5 @@ namespace Moonlight.Features.FileManager.Models.Abstractions.FileAccess; public interface IArchiveFileActions { public Task Archive(string path, string[] files); + public Task Extract(string path, string destination); } \ No newline at end of file diff --git a/Moonlight/Features/FileManager/UI/Components/FileManager.razor b/Moonlight/Features/FileManager/UI/Components/FileManager.razor index 16e3701..e51c145 100644 --- a/Moonlight/Features/FileManager/UI/Components/FileManager.razor +++ b/Moonlight/Features/FileManager/UI/Components/FileManager.razor @@ -95,7 +95,8 @@ else OnEntryClicked="OnEntryClicked" OnNavigateUpClicked="OnNavigateUpClicked" OnSelectionChanged="OnSelectionChanged" - EnableContextMenu="true"> + EnableContextMenu="true" + ShowUploadPrompt="true"> @foreach (var action in ContextActions) { diff --git a/Moonlight/Features/FileManager/UI/Components/FileView.razor b/Moonlight/Features/FileManager/UI/Components/FileView.razor index 8970f4d..aabdae0 100644 --- a/Moonlight/Features/FileManager/UI/Components/FileView.razor +++ b/Moonlight/Features/FileManager/UI/Components/FileView.razor @@ -210,7 +210,7 @@ - @if (Entries.Length == 0) + @if (Entries.Length == 0 && ShowUploadPrompt) {
@@ -240,6 +240,7 @@ [Parameter] public bool ShowDate { get; set; } = true; [Parameter] public bool ShowSelect { get; set; } = true; [Parameter] public bool ShowNavigateUp { get; set; } = true; + [Parameter] public bool ShowUploadPrompt { get; set; } = false; [Parameter] public RenderFragment? ContextMenuTemplate { get; set; } [Parameter] public bool EnableContextMenu { get; set; } = false; diff --git a/Moonlight/Features/Servers/Helpers/ServerApiFileActions.cs b/Moonlight/Features/Servers/Helpers/ServerApiFileActions.cs index 21e4692..8f4c451 100644 --- a/Moonlight/Features/Servers/Helpers/ServerApiFileActions.cs +++ b/Moonlight/Features/Servers/Helpers/ServerApiFileActions.cs @@ -47,6 +47,11 @@ public class ServerApiFileActions : IFileActions, IArchiveFileActions { await ApiClient.Post($"archive?path={path}&provider=tar.gz", files); } + + public async Task Extract(string path, string destination) + { + await ApiClient.Post($"extract?path={path}&destination={destination}&provider=tar.gz"); + } public IFileActions Clone() => new ServerApiFileActions(Endpoint, Token, ServerId); diff --git a/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor b/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor index 43e08ff..64e6150 100644 --- a/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor +++ b/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor @@ -13,11 +13,13 @@ @using MoonCore.Exceptions @using Moonlight.Features.Servers.Configuration @using MoonCore.Services +@using Moonlight.Core.Services @inject Repository ServerRepository @inject ServerService ServerService @inject ToastService ToastService @inject AlertService AlertService +@inject IdentityService IdentityService @inject ConfigService ConfigService @implements IDisposable @@ -217,6 +219,12 @@ .Include(x => x.Owner) .First(x => x.Id == Id); + if (Server.Owner.Id != IdentityService.CurrentUser.Id && IdentityService.CurrentUser.Permissions < 5000) + { + Server = null!; + return; + } + await lazyLoader.SetText("Establishing a connection to the server"); // Create console wrapper