Split uploader into separate component from table editor. Allow specification of object key on uploader for allowing replacement uploads.
parent
1e98412b17
commit
2e4a31b136
|
@ -19,6 +19,8 @@ namespace LANCommander.Controllers
|
||||||
|
|
||||||
if (!System.IO.File.Exists(Path.Combine(UploadDirectory, key)))
|
if (!System.IO.File.Exists(Path.Combine(UploadDirectory, key)))
|
||||||
System.IO.File.Create(Path.Combine(UploadDirectory, key)).Close();
|
System.IO.File.Create(Path.Combine(UploadDirectory, key)).Close();
|
||||||
|
else
|
||||||
|
System.IO.File.Delete(Path.Combine(UploadDirectory, key));
|
||||||
|
|
||||||
return Json(new
|
return Json(new
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
@using System.Net;
|
||||||
|
@using System.Diagnostics;
|
||||||
|
@using Hangfire;
|
||||||
|
@using LANCommander.Jobs.Background;
|
||||||
|
@using Microsoft.EntityFrameworkCore;
|
||||||
|
@inject HttpClient HttpClient
|
||||||
|
@inject NavigationManager Navigator
|
||||||
|
@inject ArchiveService ArchiveService
|
||||||
|
@inject IMessageService MessageService
|
||||||
|
@inject IJSRuntime JS
|
||||||
|
|
||||||
|
<Space Direction="DirectionVHType.Vertical" Style="width: 100%">
|
||||||
|
<SpaceItem>
|
||||||
|
<Table TItem="Archive" DataSource="@Game.Archives.OrderByDescending(a => a.CreatedOn)" HidePagination="true">
|
||||||
|
<PropertyColumn Property="a => a.Version" />
|
||||||
|
<PropertyColumn Property="a => a.CompressedSize">
|
||||||
|
@ByteSizeLib.ByteSize.FromBytes(context.CompressedSize)
|
||||||
|
</PropertyColumn>
|
||||||
|
<PropertyColumn Property="a => a.CreatedBy">
|
||||||
|
@context.CreatedBy?.UserName
|
||||||
|
</PropertyColumn>
|
||||||
|
<PropertyColumn Property="a => a.CreatedOn" Format="MM/dd/yyyy hh:mm tt" />
|
||||||
|
<ActionColumn Title="">
|
||||||
|
<Space Style="display: flex; justify-content: end">
|
||||||
|
<SpaceItem>
|
||||||
|
<Button OnClick="() => Download(context)" Icon="@IconType.Outline.Download" Type="@ButtonType.Text" />
|
||||||
|
</SpaceItem>
|
||||||
|
<SpaceItem>
|
||||||
|
<Popconfirm Title="Are you sure you want to delete this archive?" OnConfirm="() => Delete(context)">
|
||||||
|
<Button Icon="@IconType.Outline.Close" Type="@ButtonType.Text" Danger />
|
||||||
|
</Popconfirm>
|
||||||
|
</SpaceItem>
|
||||||
|
</Space>
|
||||||
|
</ActionColumn>
|
||||||
|
</Table>
|
||||||
|
</SpaceItem>
|
||||||
|
|
||||||
|
<SpaceItem>
|
||||||
|
<GridRow Justify="end">
|
||||||
|
<GridCol>
|
||||||
|
<Button OnClick="UploadArchive" Type="@ButtonType.Primary">Upload Archive</Button>
|
||||||
|
</GridCol>
|
||||||
|
</GridRow>
|
||||||
|
</SpaceItem>
|
||||||
|
</Space>
|
||||||
|
|
||||||
|
<ArchiveUploader @ref="Uploader" OnArchiveUploaded="AddArchive" />
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter] public Game Game { get; set; }
|
||||||
|
|
||||||
|
Archive Archive;
|
||||||
|
ArchiveUploader Uploader;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
await LoadData();
|
||||||
|
|
||||||
|
HttpClient.BaseAddress = new Uri(Navigator.BaseUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadData()
|
||||||
|
{
|
||||||
|
Game.Archives = await ArchiveService.Get(a => a.GameId == Game.Id).OrderByDescending(a => a.CreatedOn).ToListAsync();
|
||||||
|
|
||||||
|
if (Game.Archives == null)
|
||||||
|
Game.Archives = new List<Archive>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Download(Archive archive)
|
||||||
|
{
|
||||||
|
string url = $"/Download/Game/{archive.Id}";
|
||||||
|
|
||||||
|
await JS.InvokeAsync<object>("open", url, "_blank");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UploadArchive()
|
||||||
|
{
|
||||||
|
Archive = new Archive()
|
||||||
|
{
|
||||||
|
GameId = Game.Id,
|
||||||
|
Id = Guid.NewGuid()
|
||||||
|
};
|
||||||
|
|
||||||
|
await Uploader.Open(Archive);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task AddArchive(Archive archive)
|
||||||
|
{
|
||||||
|
var lastArchive = Game.Archives.OrderByDescending(a => a.CreatedOn).FirstOrDefault();
|
||||||
|
|
||||||
|
Archive = await ArchiveService.Add(archive);
|
||||||
|
|
||||||
|
await LoadData();
|
||||||
|
|
||||||
|
if (lastArchive != null)
|
||||||
|
BackgroundJob.Enqueue<PatchArchiveBackgroundJob>(x => x.Execute(lastArchive.Id, Archive.Id));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Delete(Archive archive)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await ArchiveService.Delete(archive);
|
||||||
|
|
||||||
|
await MessageService.Success("Archive deleted!");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await MessageService.Error("Archive could not be deleted.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,41 +8,6 @@
|
||||||
@inject IMessageService MessageService
|
@inject IMessageService MessageService
|
||||||
@inject IJSRuntime JS
|
@inject IJSRuntime JS
|
||||||
|
|
||||||
<Space Direction="DirectionVHType.Vertical" Style="width: 100%">
|
|
||||||
<SpaceItem>
|
|
||||||
<Table TItem="Archive" DataSource="@Game.Archives.OrderByDescending(a => a.CreatedOn)" HidePagination="true">
|
|
||||||
<PropertyColumn Property="a => a.Version" />
|
|
||||||
<PropertyColumn Property="a => a.CompressedSize">
|
|
||||||
@ByteSizeLib.ByteSize.FromBytes(context.CompressedSize)
|
|
||||||
</PropertyColumn>
|
|
||||||
<PropertyColumn Property="a => a.CreatedBy">
|
|
||||||
@context.CreatedBy?.UserName
|
|
||||||
</PropertyColumn>
|
|
||||||
<PropertyColumn Property="a => a.CreatedOn" Format="MM/dd/yyyy hh:mm tt" />
|
|
||||||
<ActionColumn Title="">
|
|
||||||
<Space Style="display: flex; justify-content: end">
|
|
||||||
<SpaceItem>
|
|
||||||
<Button OnClick="() => Download(context)" Icon="@IconType.Outline.Download" Type="@ButtonType.Text" />
|
|
||||||
</SpaceItem>
|
|
||||||
<SpaceItem>
|
|
||||||
<Popconfirm Title="Are you sure you want to delete this archive?" OnConfirm="() => Delete(context)">
|
|
||||||
<Button Icon="@IconType.Outline.Close" Type="@ButtonType.Text" Danger />
|
|
||||||
</Popconfirm>
|
|
||||||
</SpaceItem>
|
|
||||||
</Space>
|
|
||||||
</ActionColumn>
|
|
||||||
</Table>
|
|
||||||
</SpaceItem>
|
|
||||||
|
|
||||||
<SpaceItem>
|
|
||||||
<GridRow Justify="end">
|
|
||||||
<GridCol>
|
|
||||||
<Button OnClick="AddArchive" Type="@ButtonType.Primary">Upload Archive</Button>
|
|
||||||
</GridCol>
|
|
||||||
</GridRow>
|
|
||||||
</SpaceItem>
|
|
||||||
</Space>
|
|
||||||
|
|
||||||
@{
|
@{
|
||||||
RenderFragment Footer =
|
RenderFragment Footer =
|
||||||
@<Template>
|
@<Template>
|
||||||
|
@ -52,7 +17,7 @@
|
||||||
</Template>;
|
</Template>;
|
||||||
}
|
}
|
||||||
|
|
||||||
<Modal Visible="@ModalVisible" Title="Upload Archive" OnOk="UploadArchiveJS" OnCancel="Cancel" Footer="@Footer">
|
<Modal Visible="@Visible" Title="Upload Archive" OnOk="UploadArchiveJS" OnCancel="Cancel" Footer="@Footer">
|
||||||
<Form Model="@Archive" Layout="@FormLayout.Vertical">
|
<Form Model="@Archive" Layout="@FormLayout.Vertical">
|
||||||
<FormItem Label="Version">
|
<FormItem Label="Version">
|
||||||
<Input @bind-Value="@context.Version" />
|
<Input @bind-Value="@context.Version" />
|
||||||
|
@ -96,8 +61,8 @@
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter] public Game Game { get; set; }
|
[Parameter] public EventCallback<Archive> OnArchiveUploaded { get; set; }
|
||||||
|
|
||||||
Archive Archive;
|
Archive Archive;
|
||||||
|
|
||||||
|
@ -105,21 +70,13 @@
|
||||||
List<UploadFileItem> FileList = new List<UploadFileItem>();
|
List<UploadFileItem> FileList = new List<UploadFileItem>();
|
||||||
|
|
||||||
bool IsValid = false;
|
bool IsValid = false;
|
||||||
bool ModalVisible = false;
|
bool Visible = false;
|
||||||
|
|
||||||
private static string DefaultDragClass = "relative rounded-lg border-2 border-dashed pa-4 mt-4 mud-width-full mud-height-full z-10";
|
|
||||||
private string DragClass = DefaultDragClass;
|
|
||||||
|
|
||||||
const int ChunkSize = 1024 * 1024 * 10;
|
|
||||||
|
|
||||||
int Progress = 0;
|
int Progress = 0;
|
||||||
bool Uploading = false;
|
bool Uploading = false;
|
||||||
bool Finished = false;
|
bool Finished = false;
|
||||||
double Speed = 0;
|
double Speed = 0;
|
||||||
|
|
||||||
Stopwatch Watch;
|
|
||||||
long WatchBytesTransferred = 0;
|
|
||||||
|
|
||||||
string Filename;
|
string Filename;
|
||||||
|
|
||||||
ProgressStatus CurrentProgressStatus {
|
ProgressStatus CurrentProgressStatus {
|
||||||
|
@ -136,48 +93,7 @@
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
if (Game.Archives == null)
|
|
||||||
Game.Archives = new List<Archive>();
|
|
||||||
|
|
||||||
HttpClient.BaseAddress = new Uri(Navigator.BaseUri);
|
HttpClient.BaseAddress = new Uri(Navigator.BaseUri);
|
||||||
|
|
||||||
Archive = new Archive()
|
|
||||||
{
|
|
||||||
GameId = Game.Id,
|
|
||||||
Id = Guid.NewGuid()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Download(Archive archive)
|
|
||||||
{
|
|
||||||
string url = $"/Download/Game/{archive.Id}";
|
|
||||||
|
|
||||||
await JS.InvokeAsync<object>("open", url, "_blank");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddArchive()
|
|
||||||
{
|
|
||||||
Archive = new Archive()
|
|
||||||
{
|
|
||||||
GameId = Game.Id,
|
|
||||||
Id = Guid.NewGuid()
|
|
||||||
};
|
|
||||||
|
|
||||||
ModalVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Delete(Archive archive)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await ArchiveService.Delete(archive);
|
|
||||||
|
|
||||||
await MessageService.Success("Archive deleted!");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await MessageService.Error("Archive could not be deleted.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Clear()
|
private void Clear()
|
||||||
|
@ -188,7 +104,7 @@
|
||||||
private void Cancel()
|
private void Cancel()
|
||||||
{
|
{
|
||||||
File = null;
|
File = null;
|
||||||
ModalVisible = false;
|
Visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void FileSelected(InputFileChangeEventArgs args)
|
private async void FileSelected(InputFileChangeEventArgs args)
|
||||||
|
@ -196,13 +112,31 @@
|
||||||
File = args.File;
|
File = args.File;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task Open(Archive archive)
|
||||||
|
{
|
||||||
|
Archive = archive;
|
||||||
|
|
||||||
|
Visible = true;
|
||||||
|
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
|
||||||
|
await Task.Delay(500);
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(archive.ObjectKey) && archive.ObjectKey != Guid.Empty.ToString())
|
||||||
|
await JS.InvokeVoidAsync("Uploader.Init", "FileInput", archive.ObjectKey.ToString());
|
||||||
|
else
|
||||||
|
await JS.InvokeVoidAsync("Uploader.Init", "FileInput", "");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private async Task UploadArchiveJS()
|
private async Task UploadArchiveJS()
|
||||||
{
|
{
|
||||||
Uploading = true;
|
Uploading = true;
|
||||||
|
|
||||||
var dotNetReference = DotNetObjectReference.Create(this);
|
var dotNetReference = DotNetObjectReference.Create(this);
|
||||||
|
|
||||||
await JS.InvokeVoidAsync("Uploader.Upload", "FileInput", dotNetReference);
|
await JS.InvokeVoidAsync("Uploader.Upload", dotNetReference);
|
||||||
|
|
||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
}
|
}
|
||||||
|
@ -218,22 +152,18 @@
|
||||||
Archive.ObjectKey = objectKey.ToString();
|
Archive.ObjectKey = objectKey.ToString();
|
||||||
Archive.CompressedSize = File.Size;
|
Archive.CompressedSize = File.Size;
|
||||||
|
|
||||||
var originalArchive = Game.Archives.OrderByDescending(a => a.CreatedOn).FirstOrDefault();
|
Visible = false;
|
||||||
|
|
||||||
Archive = await ArchiveService.Add(Archive);
|
|
||||||
|
|
||||||
ModalVisible = false;
|
|
||||||
|
|
||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
|
|
||||||
await MessageService.Success("Archive uploaded!");
|
if (OnArchiveUploaded.HasDelegate)
|
||||||
|
await OnArchiveUploaded.InvokeAsync(Archive);
|
||||||
|
|
||||||
if (originalArchive != null)
|
await MessageService.Success("Archive uploaded!");
|
||||||
BackgroundJob.Enqueue<PatchArchiveBackgroundJob>(x => x.Execute(originalArchive.Id, Archive.Id));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ModalVisible = false;
|
Visible = false;
|
||||||
|
|
||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-panel="Archives">
|
<div data-panel="Archives">
|
||||||
<ArchiveUploader Game="Game" />
|
<ArchiveEditor Game="Game" />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,29 +23,34 @@ export default class Uploader {
|
||||||
Key: string = "";
|
Key: string = "";
|
||||||
Id: string = "";
|
Id: string = "";
|
||||||
|
|
||||||
Init(fileInputId: string, uploadButtonId: string, objectKeyInputId: string) {
|
async Init(fileInputId: string, objectKey: string) {
|
||||||
this.FileInput = document.getElementById(fileInputId) as HTMLInputElement;
|
|
||||||
this.UploadButton = document.getElementById(uploadButtonId) as HTMLButtonElement;
|
|
||||||
this.ObjectKeyInput = document.getElementById(objectKeyInputId) as HTMLInputElement;
|
|
||||||
|
|
||||||
this.Chunks = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
async Upload(fileInputId: string, dotNetObject: any) {
|
|
||||||
this.FileInput = document.getElementById(fileInputId) as HTMLInputElement;
|
this.FileInput = document.getElementById(fileInputId) as HTMLInputElement;
|
||||||
this.ProgressBar = document.querySelector('.uploader-progress .ant-progress-bg');
|
this.ProgressBar = document.querySelector('.uploader-progress .ant-progress-bg');
|
||||||
this.ProgressText = document.querySelector('.uploader-progress .ant-progress-text');
|
this.ProgressText = document.querySelector('.uploader-progress .ant-progress-text');
|
||||||
this.ProgressRate = document.querySelector('.uploader-progress-rate');
|
this.ProgressRate = document.querySelector('.uploader-progress-rate');
|
||||||
this.Chunks = [];
|
|
||||||
|
|
||||||
|
if (objectKey == undefined || objectKey == "") {
|
||||||
|
try {
|
||||||
|
var response = await axios.post<UploadInitResponse>(this.InitRoute);
|
||||||
|
|
||||||
|
this.Key = response.data.key;
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
this.Key = null;
|
||||||
|
console.error(`Could not init upload: ${ex}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.Key = objectKey;
|
||||||
|
|
||||||
|
this.Chunks = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async Upload(dotNetObject: any) {
|
||||||
this.File = this.FileInput.files.item(0);
|
this.File = this.FileInput.files.item(0);
|
||||||
this.TotalChunks = Math.ceil(this.File.size / this.MaxChunkSize);
|
this.TotalChunks = Math.ceil(this.File.size / this.MaxChunkSize);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var resp = await axios.post<UploadInitResponse>(this.InitRoute);
|
|
||||||
|
|
||||||
this.Key = resp.data.key;
|
|
||||||
|
|
||||||
this.GetChunks();
|
this.GetChunks();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -58,8 +63,7 @@ export default class Uploader {
|
||||||
this.OnError();
|
this.OnError();
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
this.Key = null;
|
console.error(`Could not chunk upload: ${ex}`);
|
||||||
console.error(`Could not init upload: ${ex}`);
|
|
||||||
} finally {
|
} finally {
|
||||||
dotNetObject.invokeMethodAsync('OnUploadComplete', this.Key);
|
dotNetObject.invokeMethodAsync('OnUploadComplete', this.Key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,24 +57,32 @@ class Uploader {
|
||||||
this.Key = "";
|
this.Key = "";
|
||||||
this.Id = "";
|
this.Id = "";
|
||||||
}
|
}
|
||||||
Init(fileInputId, uploadButtonId, objectKeyInputId) {
|
Init(fileInputId, objectKey) {
|
||||||
this.FileInput = document.getElementById(fileInputId);
|
|
||||||
this.UploadButton = document.getElementById(uploadButtonId);
|
|
||||||
this.ObjectKeyInput = document.getElementById(objectKeyInputId);
|
|
||||||
this.Chunks = [];
|
|
||||||
}
|
|
||||||
Upload(fileInputId, dotNetObject) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
this.FileInput = document.getElementById(fileInputId);
|
this.FileInput = document.getElementById(fileInputId);
|
||||||
this.ProgressBar = document.querySelector('.uploader-progress .ant-progress-bg');
|
this.ProgressBar = document.querySelector('.uploader-progress .ant-progress-bg');
|
||||||
this.ProgressText = document.querySelector('.uploader-progress .ant-progress-text');
|
this.ProgressText = document.querySelector('.uploader-progress .ant-progress-text');
|
||||||
this.ProgressRate = document.querySelector('.uploader-progress-rate');
|
this.ProgressRate = document.querySelector('.uploader-progress-rate');
|
||||||
|
if (objectKey == undefined || objectKey == "") {
|
||||||
|
try {
|
||||||
|
var response = yield axios__WEBPACK_IMPORTED_MODULE_1__["default"].post(this.InitRoute);
|
||||||
|
this.Key = response.data.key;
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
this.Key = null;
|
||||||
|
console.error(`Could not init upload: ${ex}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.Key = objectKey;
|
||||||
this.Chunks = [];
|
this.Chunks = [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Upload(dotNetObject) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
this.File = this.FileInput.files.item(0);
|
this.File = this.FileInput.files.item(0);
|
||||||
this.TotalChunks = Math.ceil(this.File.size / this.MaxChunkSize);
|
this.TotalChunks = Math.ceil(this.File.size / this.MaxChunkSize);
|
||||||
try {
|
try {
|
||||||
var resp = yield axios__WEBPACK_IMPORTED_MODULE_1__["default"].post(this.InitRoute);
|
|
||||||
this.Key = resp.data.key;
|
|
||||||
this.GetChunks();
|
this.GetChunks();
|
||||||
try {
|
try {
|
||||||
for (let chunk of this.Chunks) {
|
for (let chunk of this.Chunks) {
|
||||||
|
@ -87,8 +95,7 @@ class Uploader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
this.Key = null;
|
console.error(`Could not chunk upload: ${ex}`);
|
||||||
console.error(`Could not init upload: ${ex}`);
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
dotNetObject.invokeMethodAsync('OnUploadComplete', this.Key);
|
dotNetObject.invokeMethodAsync('OnUploadComplete', this.Key);
|
||||||
|
@ -120,12 +127,6 @@ class Uploader {
|
||||||
console.error(ex);
|
console.error(ex);
|
||||||
throw `Error uploading chunk ${chunk.Index}/${this.TotalChunks}`;
|
throw `Error uploading chunk ${chunk.Index}/${this.TotalChunks}`;
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
console.log("Updating progress bar");
|
|
||||||
var percent = Math.ceil((chunk.Index / this.TotalChunks) * 100);
|
|
||||||
this.ProgressBar.style.width = percent + '%';
|
|
||||||
this.ProgressText.innerText = percent + '%';
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
GetChunks() {
|
GetChunks() {
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue