Allow selected local files for archive upload to be moved instead of copied

Fixes #413
This commit is contained in:
Pat Hartl 2026-06-21 23:00:56 -05:00
parent 6b2610a200
commit 2e8e4ae3ae
3 changed files with 30 additions and 5 deletions

View file

@ -189,7 +189,7 @@ namespace LANCommander.Server.Services
return File.Exists(path);
}
public async Task<Guid> CopyFromLocalFileAsync(string path, Guid storageLocationId)
public async Task<Guid> CopyFromLocalFileAsync(string path, Guid storageLocationId, bool move = false)
{
var storageLocation = await storageLocationService.GetAsync(storageLocationId);
@ -212,7 +212,23 @@ namespace LANCommander.Server.Services
if (!string.IsNullOrEmpty(archiveDirectory) && !Directory.Exists(archiveDirectory))
Directory.CreateDirectory(archiveDirectory);
File.Copy(path, archivePath, true);
if (move)
{
try
{
File.Move(path, archivePath, true);
}
catch (IOException ex)
{
_logger.LogInformation(ex, "Could not move local file from {SourcePath} to {DestinationPath}, falling back to copy", path, archivePath);
File.Copy(path, archivePath, true);
}
}
else
{
File.Copy(path, archivePath, true);
}
return Guid.Parse(archive.ObjectKey);
}

View file

@ -4,6 +4,7 @@
@using LANCommander.UI.Services
@using Microsoft.Extensions.Options
@inject ArchiveService ArchiveService
@inject StorageLocationService StorageLocationService
@inject IOptions<Settings.Settings> Settings
@inject IMessageService MessageService
@inject ConfirmService ConfirmService
@ -13,6 +14,9 @@
@{
RenderFragment Footer =
@<Template>
<Tooltip Title="Moves the selected local file instead of copy">
<Checkbox @bind-Checked="MoveLocalFile" Disabled="@(Status != "")">Move</Checkbox>
</Tooltip>
<FilePickerButton EntrySelectable="@(entry => !String.IsNullOrWhiteSpace(entry.Name) && entry.Name.ToLower().EndsWith(".zip"))"
OnSelected="OnLocalFileSelected"
Root="@RootPath"
@ -76,6 +80,8 @@
string Status = "";
bool MoveLocalFile = false;
private async Task Start()
{
Uploading = true;
@ -195,6 +201,9 @@
Archive.ToolId = ToolId;
}
if (Archive.StorageLocation == null)
Archive.StorageLocation = await StorageLocationService.DefaultAsync(StorageLocationType.Archive) ?? new StorageLocation();
Uploading = false;
Visible = true;
@ -216,7 +225,7 @@
{
try
{
var objectKey = await ArchiveService.CopyFromLocalFileAsync(path, Archive.StorageLocation.Id);
var objectKey = await ArchiveService.CopyFromLocalFileAsync(path, Archive.StorageLocation.Id, MoveLocalFile);
// For local files, run the completion logic directly.
var gameId = Archive.GameId;

View file

@ -20,7 +20,7 @@
Accept=".lcx"
@bind-File="File"
@bind-Status="Status"
StorageLocationId="StorageLocation.Id"
StorageLocationId="@(StorageLocation?.Id ?? Guid.Empty)"
UploadType="UploadType.Import"
OnUploadError="OnUploadError">
<Text>
@ -189,7 +189,7 @@ else if (_stage == ImportStage.Failed)
ImportContext.OnImportStatusUpdate.EventRaised += ImportStatusUpdate;
ImportContext.OnImportError.EventRaised += ImportError;
StorageLocation = await StorageLocationService.FirstAsync(l => l.Default && l.Type == StorageLocationType.Archive);
StorageLocation = await StorageLocationService.DefaultAsync(StorageLocationType.Archive) ?? StorageLocation;
// If a pre-uploaded object key was provided, skip the upload stage.
if (!string.IsNullOrWhiteSpace(Options.PreUploadedObjectKey))