@using LANCommander.UI.Providers @using Microsoft.AspNetCore.Components.Forms @using Microsoft.JSInterop @inject HttpClient HttpClient @inject NavigationManager Navigator @inject ScriptProvider ScriptProvider @inject IMessageService MessageService @implements IAsyncDisposable @namespace LANCommander.UI.Components
@if (File != null) {
@File.Name ()
} @code { [Parameter] public RenderFragment? Text { get; set; } [Parameter] public RenderFragment? Hint { get; set; } [Parameter] public string? Accept { get; set; } [Parameter] public string? ObjectKey { get; set; } [Parameter] public EventCallback OnUploadCompleted { get; set; } [Parameter] public EventCallback OnUploadError { get; set; } [Parameter] public string? Status { get; set; } [Parameter] public EventCallback StatusChanged { get; set; } [Parameter] public IBrowserFile? File { get; set; } [Parameter] public EventCallback FileChanged { get; set; } [Parameter] public Guid StorageLocationId { get; set; } [Parameter] public EventCallback StorageLocationIdChanged { get; set; } readonly Guid _uploaderId = Guid.NewGuid(); InputFile? _fileInput; int _progress = 0; bool _uploading = false; bool _finished = false; bool _clearInput = false; double _speed = 0; IJSObjectReference? _uploaderInterop; ProgressStatus CurrentProgressStatus { get { switch (Status) { case "Complete": return ProgressStatus.Success; case "Uploading": return ProgressStatus.Active; default: return ProgressStatus.Normal; } } } protected override void OnInitialized() { HttpClient.BaseAddress = new Uri(Navigator.BaseUri); } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) _uploaderInterop ??= await ScriptProvider.ImportModuleAsync(); } public async Task Start() { if (_uploaderInterop is null) return; _uploading = true; await ChangeStatus("Uploading"); ushort i = 0; while (i < 20) { if (_fileInput != null) { if (!String.IsNullOrWhiteSpace(ObjectKey) && ObjectKey != Guid.Empty.ToString()) await _uploaderInterop.InvokeVoidAsync("Init", $"ChunkFileInput-{_uploaderId}", StorageLocationId, ObjectKey); else await _uploaderInterop.InvokeVoidAsync("Init", $"ChunkFileInput-{_uploaderId}", StorageLocationId, ""); break; } i++; await Task.Delay(500); } var dotNetReference = DotNetObjectReference.Create(this); await _uploaderInterop.InvokeVoidAsync("Upload", dotNetReference); await InvokeAsync(StateHasChanged); } public async Task Clear() { if (_uploaderInterop is null) return; await _uploaderInterop.InvokeVoidAsync("Clear"); File = null; if (FileChanged.HasDelegate) await FileChanged.InvokeAsync(null); Status = ""; if (StatusChanged.HasDelegate) await StatusChanged.InvokeAsync(Status); StateHasChanged(); } async void OnFileSelected(InputFileChangeEventArgs args) { var file = args.File; if (!String.IsNullOrWhiteSpace(Accept)) { var acceptedFileExtensions = Accept.Split(',').Select(x => x.Trim()).ToArray(); if (!acceptedFileExtensions.Any(x => file.Name.ToLower().EndsWith(x.ToLower()))) { MessageService.Error($"Only {String.Join(", ", acceptedFileExtensions)} can be selected!"); return; } } File = file; if (FileChanged.HasDelegate) await FileChanged.InvokeAsync(File); await ChangeStatus(""); } async Task ChangeStatus(string status) { Status = status; if (StatusChanged.HasDelegate) await StatusChanged.InvokeAsync(Status); } [JSInvokable] public async Task JSOnUploadComplete(string objectKey) { _uploading = false; _finished = true; await ChangeStatus("Complete"); if (OnUploadCompleted.HasDelegate) await OnUploadCompleted.InvokeAsync(objectKey); } [JSInvokable] public async Task JSOnUploadError(string message) { if (OnUploadError.HasDelegate) await OnUploadError.InvokeAsync(message); } public async ValueTask DisposeAsync() { if (_fileInput is not null) await CastAndDispose(_fileInput); if (_uploaderInterop is not null) await _uploaderInterop.DisposeAsync(); if (HttpClient is not null) await CastAndDispose(HttpClient); return; static async ValueTask CastAndDispose(IDisposable resource) { if (resource is IAsyncDisposable resourceAsyncDisposable) await resourceAsyncDisposable.DisposeAsync(); else resource.Dispose(); } } }