@page "/"
MeowStash
MeowStash
A meowmeow host for stashing random files~
@if (_uploadData.Any())
{
@foreach (var item in _uploadData)
{
@item.Key.Name
@item.Value.Item1%
@item.Value.Item2
}
}
@code {
private string GetUploadProgressClassesFor(float percent)
{
return percent switch
{
(< 5f) => "upload-progress-low",
(> 5f) and (< 50f) => "upload-progress-submedial",
(> 50f) and (< 95f) => "upload-progress-supermedial",
(> 95f) and (< 100f) => "upload-progress-nearly-done",
100f or (> 100f) => "upload-progress-done",
_ => "upload-progress-invalid"
};
}
private System.Collections.Concurrent.ConcurrentDictionary _uploadData = new();
private CancellationTokenSource _cancel = null!;
private async Task SendFiles(InputFileChangeEventArgs e)
{
if (_cancel != null)
{
_cancel.Cancel();
_cancel.Dispose();
}
_cancel = new();
var files = e.GetMultipleFiles(e.FileCount);
_uploadData = new(files.Count, files.ToDictionary(f => f, _ => (0f, 0L)), null);
if (!System.IO.Directory.Exists("/tmp/uploads"))
{
System.IO.Directory.CreateDirectory("/tmp/uploads");
}
var tasks = new List();
foreach (var file in files)
{
tasks.Add(Task.Run(async () =>
{
await using var fos = System.IO.File.OpenWrite($"/tmp/uploads/{file.Name}");
var stream = file.OpenReadStream(1024 * 1024 * 1024, _cancel.Token);
int read;
byte[] buffer = new byte[16 * 1024];
while ((read = await stream.ReadAsync(buffer, 0, buffer.Length, _cancel.Token)) > 0)
{
if (_cancel.IsCancellationRequested)
{
stream.Close();
return;
}
await fos.WriteAsync(buffer, 0, read);
long totalRead = _uploadData[file].Item2;
totalRead += read;
float percent = float.Round(((float)totalRead / (float)file.Size * 100f), 2);
_uploadData[file] = (percent, totalRead);
await InvokeAsync(StateHasChanged);
await Task.Delay(500, _cancel.Token);
}
stream.Close();
Console.WriteLine($"File: /tmp/uploads/{file.Name} written...");
await InvokeAsync(StateHasChanged);
}));
}
await Task.WhenAll(tasks);
StateHasChanged();
}
}