diff --git a/Moonlight/App/Services/FileDownloadService.cs b/Moonlight/App/Services/FileDownloadService.cs new file mode 100644 index 00000000..ad85c010 --- /dev/null +++ b/Moonlight/App/Services/FileDownloadService.cs @@ -0,0 +1,33 @@ +using System.Text; +using Microsoft.JSInterop; + +namespace Moonlight.App.Services; + +public class FileDownloadService +{ + private readonly IJSRuntime JSRuntime; + + public FileDownloadService(IJSRuntime jsRuntime) + { + JSRuntime = jsRuntime; + } + + public async Task DownloadStream(string fileName, Stream stream) + { + using var streamRef = new DotNetStreamReference(stream); + + await JSRuntime.InvokeVoidAsync("moonlight.downloads.downloadStream", fileName, streamRef); + } + + public async Task DownloadBytes(string fileName, byte[] bytes) + { + var ms = new MemoryStream(bytes); + + await DownloadStream(fileName, ms); + } + + public async Task DownloadString(string fileName, string content) + { + await DownloadBytes(fileName, Encoding.UTF8.GetBytes(content)); + } +} \ No newline at end of file diff --git a/Moonlight/Program.cs b/Moonlight/Program.cs index 8339cb49..33f4900d 100644 --- a/Moonlight/Program.cs +++ b/Moonlight/Program.cs @@ -105,6 +105,7 @@ namespace Moonlight builder.Services.AddScoped(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); + builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/Moonlight/Shared/Views/Admin/Servers/Images/Edit.razor b/Moonlight/Shared/Views/Admin/Servers/Images/Edit.razor index 0f2c76bf..cfb81c5c 100644 --- a/Moonlight/Shared/Views/Admin/Servers/Images/Edit.razor +++ b/Moonlight/Shared/Views/Admin/Servers/Images/Edit.razor @@ -10,6 +10,7 @@ @inject ImageRepository ImageRepository @inject SmartTranslateService SmartTranslateService @inject ToastService ToastService +@inject FileDownloadService FileDownloadService
@@ -230,6 +231,11 @@ Cancel + + ImageRepository @inject Repository ImageVariableRepository @inject Repository ServerRepository @inject SmartTranslateService SmartTranslateService +@inject ToastService ToastService +@inject NavigationManager NavigationManager
@@ -23,10 +28,28 @@
- + New image +
@@ -86,6 +109,9 @@ private LazyLoader LazyLoader; private Dictionary ServersCount = new(); + + private bool Uploading = false; + private int Percent = 0; private async Task Load(LazyLoader lazyLoader) { @@ -127,4 +153,66 @@ ImageRepository.Delete(image); await LazyLoader.Reload(); } + + private async Task OnFileChanged(InputFileChangeEventArgs arg) + { + await ToastService.CreateProcessToast("upload", SmartTranslateService.Translate("Uploading files")); + + Uploading = true; + await InvokeAsync(StateHasChanged); + + int i = 1; + foreach (var browserFile in arg.GetMultipleFiles()) + { + if (browserFile.Size < 1024 * 1024 * 100) + { + Percent = 0; + + try + { + var stream = browserFile.OpenReadStream(1024 * 1024 * 100); + var data = new byte[browserFile.Size]; + await stream.ReadAsync(data, 0, data.Length); + Percent = 50; + + var text = Encoding.UTF8.GetString(data); + + var image = JsonConvert.DeserializeObject(text); + foreach (var imageDockerImage in image.DockerImages) + { + imageDockerImage.Id = 0; + } + foreach (var imageVariable in image.Variables) + { + imageVariable.Id = 0; + } + image.Id = 0; + + image = ImageRepository.Add(image); + + NavigationManager.NavigateTo("/admin/servers/images/edit/" + image.Id); + } + catch (Exception e) + { + await ToastService.Error(SmartTranslateService.Translate("An unknown error occured while uploading and importing the image")); + Logger.Error("Error uploading file"); + Logger.Error(e); + } + + await ToastService.UpdateProcessToast("upload", $"{i}/{arg.GetMultipleFiles().Count} {SmartTranslateService.Translate("complete")}"); + } + else + { + await ToastService.Error(SmartTranslateService.Translate("The uploaded file should not be bigger than 100MB")); + } + + i++; + } + + Uploading = false; + await InvokeAsync(StateHasChanged); + + await ToastService.UpdateProcessToast("upload", SmartTranslateService.Translate("Upload complete")); + await ToastService.RemoveProcessToast("upload"); + } } \ No newline at end of file diff --git a/Moonlight/wwwroot/assets/js/moonlight.js b/Moonlight/wwwroot/assets/js/moonlight.js index a1675549..7e865926 100644 --- a/Moonlight/wwwroot/assets/js/moonlight.js +++ b/Moonlight/wwwroot/assets/js/moonlight.js @@ -334,5 +334,18 @@ light.style.animation = ""; light.style.opacity = "0"; } + }, + downloads:{ + downloadStream: async function (fileName, contentStreamReference){ + const arrayBuffer = await contentStreamReference.arrayBuffer(); + const blob = new Blob([arrayBuffer]); + const url = URL.createObjectURL(blob); + const anchorElement = document.createElement('a'); + anchorElement.href = url; + anchorElement.download = fileName ?? ''; + anchorElement.click(); + anchorElement.remove(); + URL.revokeObjectURL(url); + } } }; \ No newline at end of file