LANCommander/LANCommander.Server/UI/Components/ArchiveUploader.razor
2024-08-04 18:44:33 -05:00

189 lines
5.9 KiB
Text

@using System.Net;
@using System.Diagnostics;
@using Hangfire;
@using LANCommander.Server.Jobs.Background;
@using Microsoft.EntityFrameworkCore;
@inject HttpClient HttpClient
@inject NavigationManager Navigator
@inject ArchiveService ArchiveService
@inject IMessageService MessageService
@inject IJSRuntime JS
@inject ILogger<ArchiveUploader> Logger
@{
RenderFragment Footer =
@<Template>
<FilePickerButton EntrySelectable="@(entry => !String.IsNullOrWhiteSpace(entry.Name) && entry.Name.ToLower().EndsWith(".zip"))"
OnSelected="OnLocalFileSelected"
Root="@RootPath"
Disabled="@(Status != "" || String.IsNullOrWhiteSpace(Archive.Version))">
Use Local File
</FilePickerButton>
<Button OnClick="Start" Disabled="@(File == null || Status != "" || String.IsNullOrWhiteSpace(Archive.Version))" Type="@ButtonType.Primary">Upload</Button>
<Button OnClick="Cancel">Cancel</Button>
</Template>;
}
<Modal Visible="@Visible" Title="Upload Archive" OnOk="Start" OnCancel="Cancel" Footer="@Footer" Closable="@(!Uploading)" MaskClosable="@(!Uploading)">
<Form Model="@Archive" Layout="@FormLayout.Vertical">
<FormItem Label="Version">
<Input @bind-Value="@context.Version" />
</FormItem>
<FormItem Label="Changelog">
<TextArea @bind-Value="@context.Changelog" MaxLength=500 ShowCount />
</FormItem>
<FormItem>
<ChunkUploader @ref="ChunkUploader" Accept=".zip" @bind-File="File" @bind-Status="Status" OnUploadCompleted="OnUploadCompleted" OnUploadError="OnUploadError">
<Text>
<p>Drag and Drop</p>
<p>or</p>
<p>
<Button Type="@ButtonType.Primary" Style="margin-top: 8px;">Browse</Button>
</p>
</Text>
<Hint>Only ZIP files are supported as game archives</Hint>
</ChunkUploader>
</FormItem>
</Form>
</Modal>
@code {
[Parameter] public Guid GameId { get; set; }
[Parameter] public Guid RedistributableId { get; set; }
[Parameter] public EventCallback<Guid> OnArchiveUploaded { get; set; }
Archive Archive;
string RootPath = Path.GetPathRoot(Directory.GetCurrentDirectory());
IBrowserFile File;
ChunkUploader ChunkUploader;
bool IsValid = false;
bool Visible = false;
bool Uploading = false;
string Filename;
string Status;
private async Task Start()
{
Uploading = true;
await ChunkUploader.Start();
}
private async Task Clear()
{
await ChunkUploader.Clear();
}
private async Task Cancel()
{
await ChunkUploader.Clear();
Visible = false;
}
public async Task Open(Guid? archiveId = null)
{
if (archiveId.HasValue && archiveId != Guid.Empty)
{
Archive = await ArchiveService.Get(archiveId.Value);
}
else
{
Archive = new Archive();
if (GameId != Guid.Empty)
Archive.GameId = GameId;
else if (RedistributableId != Guid.Empty)
Archive.RedistributableId = RedistributableId;
}
Visible = true;
await InvokeAsync(StateHasChanged);
}
public async Task OnUploadCompleted(string data)
{
Uploading = false;
if (Guid.TryParse(data, out var objectKey))
{
Archive.ObjectKey = objectKey.ToString();
var archivePath = ArchiveService.GetArchiveFileLocation(Archive.ObjectKey);
Archive.CompressedSize = new System.IO.FileInfo(archivePath).Length;
if (Archive.Id != Guid.Empty)
Archive = await ArchiveService.Update(Archive);
else
Archive = await ArchiveService.Add(Archive);
Visible = false;
await InvokeAsync(StateHasChanged);
Archive? lastArchive = null;
var settings = SettingService.GetSettings();
if (settings.Archives.EnablePatching)
{
if (Archive.GameId != Guid.Empty)
lastArchive = await ArchiveService.Get(a => a.Id != Archive.Id && a.GameId == Archive.GameId).OrderByDescending(a => a.CreatedOn).FirstOrDefaultAsync();
else if (Archive.RedistributableId != Guid.Empty)
lastArchive = await ArchiveService.Get(a => a.Id != Archive.Id && a.RedistributableId == Archive.RedistributableId).OrderByDescending(a => a.CreatedOn).FirstOrDefaultAsync();
if (lastArchive != null && settings.Archives.EnablePatching)
BackgroundJob.Enqueue<PatchArchiveBackgroundJob>(x => x.Execute(lastArchive.Id, Archive.Id));
}
if (OnArchiveUploaded.HasDelegate)
await OnArchiveUploaded.InvokeAsync(Archive.Id);
MessageService.Success("Archive uploaded!");
}
else
{
Visible = false;
await InvokeAsync(StateHasChanged);
MessageService.Error("Archive failed to upload!");
Logger.LogError("Archive failed to upload!");
}
await ChunkUploader.Clear();
}
public async Task OnUploadError(string message)
{
Uploading = false;
Visible = false;
await InvokeAsync(StateHasChanged);
MessageService.Error("Archive failed to upload!");
Logger.LogError($"Archive failed to upload: {message}");
}
public async Task OnLocalFileSelected(string path)
{
try
{
var objectKey = await ArchiveService.CopyFromLocalFile(path);
await OnUploadCompleted(objectKey.ToString());
}
catch (Exception ex)
{
MessageService.Error("An unknown error occurred while trying to use a local file");
Logger.LogError(ex, "An unknown error occurred while trying to use a local file");
}
}
}