Consolidate JS for components
This commit is contained in:
parent
e4f81cd22f
commit
920c82002c
22 changed files with 37 additions and 6145 deletions
11
LANCommander.UI/Scripts/Chunk.ts
Normal file
11
LANCommander.UI/Scripts/Chunk.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
export class Chunk {
|
||||
Index: number;
|
||||
Start: number;
|
||||
End: number;
|
||||
|
||||
constructor(start: number, end: number, index: number) {
|
||||
this.Start = start;
|
||||
this.End = end;
|
||||
this.Index = index;
|
||||
}
|
||||
}
|
||||
29
LANCommander.UI/Scripts/SplitPane.ts
Normal file
29
LANCommander.UI/Scripts/SplitPane.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import Split from 'split.js'
|
||||
|
||||
export class SplitPane {
|
||||
SplitPanes: HTMLElement[] = [];
|
||||
|
||||
Init(paneId: string) {
|
||||
let splitPane = document.querySelector<HTMLElement>(`#split-pane-${paneId}`);
|
||||
|
||||
if (splitPane != null) {
|
||||
let panes = Array.from(splitPane.querySelectorAll<HTMLElement>('.pane'));
|
||||
let opts = new SplitPaneOptions();
|
||||
|
||||
for (let pane of panes) {
|
||||
let size = parseInt(pane.getAttribute('data-size'));
|
||||
|
||||
if (isNaN(size))
|
||||
opts.sizes.push(0);
|
||||
else
|
||||
opts.sizes.push(size);
|
||||
}
|
||||
|
||||
Split(panes, opts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SplitPaneOptions implements Split.Options {
|
||||
sizes: number[] = [];
|
||||
}
|
||||
3
LANCommander.UI/Scripts/UploadInitResponse.ts
Normal file
3
LANCommander.UI/Scripts/UploadInitResponse.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export class UploadInitResponse {
|
||||
key: string = "";
|
||||
}
|
||||
148
LANCommander.UI/Scripts/Uploader.ts
Normal file
148
LANCommander.UI/Scripts/Uploader.ts
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
import { Chunk } from './Chunk';
|
||||
import { UploadInitResponse } from './UploadInitResponse';
|
||||
import axios, { AxiosProgressEvent } from 'axios';
|
||||
|
||||
export class Uploader {
|
||||
FileInput: HTMLInputElement | undefined;
|
||||
UploadButton: HTMLButtonElement | undefined;
|
||||
ObjectKeyInput: HTMLInputElement | undefined;
|
||||
ProgressBar: HTMLElement | undefined;
|
||||
ProgressText: HTMLElement | undefined;
|
||||
ProgressRate: HTMLElement | undefined;
|
||||
|
||||
File: File | undefined;
|
||||
|
||||
InitRoute: string = "/Upload/Init";
|
||||
ChunkRoute: string = "/Upload/Chunk";
|
||||
|
||||
MaxChunkSize: number = 1024 * 1024 * 50;
|
||||
TotalChunks: number = 0;
|
||||
CurrentChunk: number = 0;
|
||||
Chunks: Chunk[] = [];
|
||||
|
||||
Key: string = "";
|
||||
Id: string = "";
|
||||
|
||||
async Init(fileInputId: string, objectKey: string) {
|
||||
this.FileInput = document.getElementById(fileInputId) as HTMLInputElement;
|
||||
this.ProgressBar = document.querySelector('.uploader-progress .ant-progress-circle-path');
|
||||
this.ProgressText = document.querySelector('.uploader-progress .ant-progress-text');
|
||||
this.ProgressRate = document.querySelector('.uploader-progress-rate');
|
||||
|
||||
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.TotalChunks = Math.ceil(this.File.size / this.MaxChunkSize);
|
||||
|
||||
try {
|
||||
this.GetChunks();
|
||||
|
||||
for (let chunk of this.Chunks) {
|
||||
await this.UploadChunk(chunk);
|
||||
}
|
||||
|
||||
dotNetObject.invokeMethodAsync('JSOnUploadComplete', this.Key);
|
||||
} catch (ex) {
|
||||
dotNetObject.invokeMethodAsync('JSOnUploadError', ex.message);
|
||||
console.error(`Could not chunk upload: ${ex}`);
|
||||
}
|
||||
}
|
||||
|
||||
async UploadChunk(chunk: Chunk) {
|
||||
let formData = new FormData();
|
||||
|
||||
formData.append('file', this.File.slice(chunk.Start, chunk.End + 1));
|
||||
formData.append('start', chunk.Start.toString());
|
||||
formData.append('end', chunk.End.toString());
|
||||
formData.append('key', this.Key);
|
||||
formData.append('total', this.File.size.toString());
|
||||
|
||||
console.info(`Uploading chunk ${chunk.Index}/${this.TotalChunks}...`);
|
||||
|
||||
try {
|
||||
let chunkResponse = await axios({
|
||||
method: "post",
|
||||
url: this.ChunkRoute,
|
||||
data: formData,
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
onUploadProgress: (progressEvent: AxiosProgressEvent) => {
|
||||
console.log(progressEvent);
|
||||
|
||||
this.UpdateProgressBar(chunk.Index, progressEvent);
|
||||
}
|
||||
});
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
throw `Error uploading chunk ${chunk.Index}/${this.TotalChunks}`;
|
||||
}
|
||||
}
|
||||
|
||||
GetChunks() {
|
||||
for (let currentChunk = 1; currentChunk <= this.TotalChunks; currentChunk++) {
|
||||
let start = (currentChunk - 1) * this.MaxChunkSize;
|
||||
let end = (currentChunk * this.MaxChunkSize) - 1;
|
||||
|
||||
if (currentChunk == this.TotalChunks)
|
||||
end = this.File.size;
|
||||
|
||||
this.Chunks.push(new Chunk(start, end, currentChunk));
|
||||
}
|
||||
}
|
||||
|
||||
UpdateProgressBar(chunkIndex: number, progressEvent: AxiosProgressEvent) {
|
||||
var percent = ((1 / this.TotalChunks) * progressEvent.progress) + ((chunkIndex - 1) / this.TotalChunks);
|
||||
|
||||
this.ProgressBar.style.strokeDasharray = percent * 295.31 + 'px, 295.31px';
|
||||
this.ProgressText.innerText = Math.ceil(percent * 100) + '%';
|
||||
|
||||
if (progressEvent.rate > 0)
|
||||
this.ProgressRate.innerText = this.GetHumanFileSize(progressEvent.rate, false, 1) + '/s';
|
||||
}
|
||||
|
||||
GetHumanFileSize(bytes: number, si: boolean, dp: number) {
|
||||
const thresh = si ? 1000 : 1024;
|
||||
|
||||
if (Math.abs(bytes) < thresh) {
|
||||
return bytes + ' B';
|
||||
}
|
||||
|
||||
const units = si
|
||||
? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
||||
: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
||||
let u = -1;
|
||||
const r = 10 ** dp;
|
||||
|
||||
do {
|
||||
bytes /= thresh;
|
||||
++u;
|
||||
} while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);
|
||||
|
||||
return bytes.toFixed(dp) + ' ' + units[u];
|
||||
}
|
||||
|
||||
Clear() {
|
||||
this.File = undefined;
|
||||
this.FileInput.value = "";
|
||||
}
|
||||
|
||||
OnStart: () => void;
|
||||
OnComplete: (id: string, key: string) => void;
|
||||
OnProgress: (percent: number) => void;
|
||||
OnError: () => void;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue