Upload fix
Fixed upload preloader
This commit is contained in:
parent
2b498a5b2c
commit
8a5a91b3c4
@ -303,7 +303,7 @@ export default class AudioElement extends HTMLElement {
|
||||
downloadDiv.innerHTML = '<div class="tgico-download"></div>';
|
||||
}
|
||||
|
||||
if(doc.type != 'audio' && !uploading) {
|
||||
if(doc.type != 'audio' || uploading) {
|
||||
this.append(downloadDiv);
|
||||
}
|
||||
|
||||
|
@ -53,37 +53,41 @@ export default class ProgressivePreloader {
|
||||
}
|
||||
}
|
||||
|
||||
public attachPromise(promise: CancellablePromise<any>) {
|
||||
this.promise = promise;
|
||||
|
||||
const tempID = --this.tempID;
|
||||
|
||||
const onEnd = () => {
|
||||
promise.notify = null;
|
||||
|
||||
if(tempID == this.tempID) {
|
||||
this.detach();
|
||||
this.promise = promise = null;
|
||||
}
|
||||
};
|
||||
|
||||
//promise.catch(onEnd);
|
||||
promise.finally(onEnd);
|
||||
|
||||
if(promise.addNotifyListener) {
|
||||
promise.addNotifyListener((details: {done: number, total: number}) => {
|
||||
/* if(details.done >= details.total) {
|
||||
onEnd();
|
||||
} */
|
||||
|
||||
if(tempID != this.tempID) return;
|
||||
|
||||
//console.log('preloader download', promise, details);
|
||||
const percents = details.done / details.total * 100;
|
||||
this.setProgress(percents);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public attach(elem: Element, reset = true, promise?: CancellablePromise<any>, append = true) {
|
||||
if(promise/* && false */) {
|
||||
this.promise = promise;
|
||||
|
||||
const tempID = --this.tempID;
|
||||
|
||||
const onEnd = () => {
|
||||
promise.notify = null;
|
||||
|
||||
if(tempID == this.tempID) {
|
||||
this.detach();
|
||||
this.promise = promise = null;
|
||||
}
|
||||
};
|
||||
|
||||
//promise.catch(onEnd);
|
||||
promise.finally(onEnd);
|
||||
|
||||
if(promise.addNotifyListener) {
|
||||
promise.addNotifyListener((details: {done: number, total: number}) => {
|
||||
/* if(details.done >= details.total) {
|
||||
onEnd();
|
||||
} */
|
||||
|
||||
if(tempID != this.tempID) return;
|
||||
|
||||
//console.log('preloader download', promise, details);
|
||||
const percents = details.done / details.total * 100;
|
||||
this.setProgress(percents);
|
||||
});
|
||||
}
|
||||
this.attachPromise(promise);
|
||||
}
|
||||
|
||||
this.detached = false;
|
||||
|
@ -59,7 +59,7 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
|
||||
|
||||
let img: HTMLImageElement;
|
||||
if(message) {
|
||||
if(doc.type == 'video') {
|
||||
if(doc.type == 'video' && doc.thumbs?.length) {
|
||||
return wrapPhoto(doc, message, container, boxWidth, boxHeight, withTail, isOut, lazyLoadQueue, middleware);
|
||||
}
|
||||
|
||||
@ -390,7 +390,7 @@ export function wrapPhoto(photo: MTPhoto | MTDocument, message: any, container:
|
||||
});
|
||||
};
|
||||
|
||||
return cacheContext.downloaded ? load() : lazyLoadQueue.push({div: container, load: load, wasSeen: true});
|
||||
return cacheContext.downloaded || !lazyLoadQueue ? load() : lazyLoadQueue.push({div: container, load: load, wasSeen: true});
|
||||
}
|
||||
|
||||
export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, onlyThumb, emoji, width, height, withThumb, loop}: {
|
||||
|
@ -124,7 +124,10 @@ class AppDocsManager {
|
||||
|
||||
if((doc.type == 'gif' && doc.size > 8e6) || doc.type == 'audio' || doc.type == 'video') {
|
||||
doc.supportsStreaming = true;
|
||||
doc.url = this.getFileURL(doc);
|
||||
|
||||
if(!doc.url) {
|
||||
doc.url = this.getFileURL(doc);
|
||||
}
|
||||
}
|
||||
|
||||
if(!doc.file_name) {
|
||||
|
@ -3,6 +3,7 @@ import apiManager from "../mtproto/mtprotoworker";
|
||||
import { deferredPromise, CancellablePromise } from "../polyfill";
|
||||
import type { DownloadOptions } from "../mtproto/apiFileManager";
|
||||
import { getFileNameByLocation } from "../bin_utils";
|
||||
import { InputFile } from "../../types";
|
||||
|
||||
export type ResponseMethodBlob = 'blob';
|
||||
export type ResponseMethodJson = 'json';
|
||||
@ -23,6 +24,8 @@ export class AppDownloadManager {
|
||||
private progress: {[fileName: string]: Progress} = {};
|
||||
private progressCallbacks: {[fileName: string]: Array<ProgressCallback>} = {};
|
||||
|
||||
private uploadID = 0;
|
||||
|
||||
constructor() {
|
||||
$rootScope.$on('download_progress', (e) => {
|
||||
const details = e.detail as {done: number, fileName: string, total: number, offset: number};
|
||||
@ -40,39 +43,56 @@ export class AppDownloadManager {
|
||||
});
|
||||
}
|
||||
|
||||
public download(options: DownloadOptions, responseMethod?: ResponseMethodBlob): DownloadBlob;
|
||||
public download(options: DownloadOptions, responseMethod?: ResponseMethodJson): DownloadJson;
|
||||
public download(options: DownloadOptions, responseMethod: ResponseMethod = 'blob'): DownloadBlob {
|
||||
const fileName = getFileNameByLocation(options.location, {fileName: options.fileName});
|
||||
|
||||
if(this.downloads.hasOwnProperty(fileName)) return this.downloads[fileName];
|
||||
|
||||
private getNewDeferred(fileName: string) {
|
||||
const deferred = deferredPromise<Blob>();
|
||||
|
||||
apiManager.downloadFile(options)
|
||||
.then(deferred.resolve, deferred.reject)
|
||||
.finally(() => {
|
||||
delete this.progressCallbacks[fileName];
|
||||
});
|
||||
|
||||
//console.log('Will download file:', fileName, url);
|
||||
|
||||
deferred.cancel = () => {
|
||||
const error = new Error('Download canceled');
|
||||
error.name = 'AbortError';
|
||||
|
||||
apiManager.cancelDownload(fileName);
|
||||
delete this.downloads[fileName];
|
||||
delete this.progress[fileName];
|
||||
delete this.progressCallbacks[fileName];
|
||||
this.clearDownload(fileName);
|
||||
|
||||
deferred.reject(error);
|
||||
deferred.cancel = () => {};
|
||||
};
|
||||
|
||||
deferred.finally(() => {
|
||||
delete this.progress[fileName];
|
||||
delete this.progressCallbacks[fileName];
|
||||
});
|
||||
|
||||
return this.downloads[fileName] = deferred;
|
||||
}
|
||||
|
||||
private clearDownload(fileName: string) {
|
||||
delete this.downloads[fileName];
|
||||
}
|
||||
|
||||
public download(options: DownloadOptions): DownloadBlob {
|
||||
const fileName = getFileNameByLocation(options.location, {fileName: options.fileName});
|
||||
if(this.downloads.hasOwnProperty(fileName)) return this.downloads[fileName];
|
||||
|
||||
const deferred = this.getNewDeferred(fileName);
|
||||
apiManager.downloadFile(options).then(deferred.resolve, deferred.reject);
|
||||
|
||||
//console.log('Will download file:', fileName, url);
|
||||
return deferred;
|
||||
}
|
||||
|
||||
public upload(file: File | Blob) {
|
||||
const fileName = /* (file as File).name || */'upload-' + this.uploadID++;
|
||||
|
||||
const deferred = this.getNewDeferred(fileName);
|
||||
apiManager.uploadFile({file, fileName}).then(deferred.resolve, deferred.reject);
|
||||
|
||||
deferred.finally(() => {
|
||||
this.clearDownload(fileName);
|
||||
});
|
||||
|
||||
return deferred as any as CancellablePromise<InputFile>;
|
||||
}
|
||||
|
||||
public getDownload(fileName: string) {
|
||||
return this.downloads[fileName];
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import appAudio from '../../components/appAudio';
|
||||
import appPollsManager from './appPollsManager';
|
||||
import { ripple } from '../../components/ripple';
|
||||
import { horizontalMenu } from '../../components/horizontalMenu';
|
||||
import AudioElement from '../../components/audio';
|
||||
|
||||
//console.log('appImManager included33!');
|
||||
|
||||
@ -2251,15 +2252,14 @@ export class AppImManager {
|
||||
case 'audio':
|
||||
case 'voice':
|
||||
case 'document': {
|
||||
let doc = appDocsManager.getDoc(message.id);
|
||||
const doc = appDocsManager.getDoc(message.id);
|
||||
this.log('will wrap pending doc:', doc);
|
||||
let docDiv = wrapDocument(doc, false, true, message.id);
|
||||
const docDiv = wrapDocument(doc, false, true, message.id);
|
||||
|
||||
if(doc.type == 'audio' || doc.type == 'voice') {
|
||||
// @ts-ignore
|
||||
docDiv.preloader = preloader;
|
||||
(docDiv as AudioElement).preloader = preloader;
|
||||
} else {
|
||||
let icoDiv = docDiv.querySelector('.audio-download, .document-ico');
|
||||
const icoDiv = docDiv.querySelector('.audio-download, .document-ico');
|
||||
preloader.attach(icoDiv, false);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ import searchIndexManager from '../searchIndexManager';
|
||||
import { MTDocument, MTPhotoSize } from "../../types";
|
||||
import { logger, LogLevels } from "../logger";
|
||||
import type {ApiFileManager} from '../mtproto/apiFileManager';
|
||||
import appDownloadManager from "./appDownloadManager";
|
||||
|
||||
//console.trace('include');
|
||||
|
||||
@ -1121,9 +1122,9 @@ export class AppMessagesManager {
|
||||
flags |= 256;
|
||||
}
|
||||
|
||||
let preloader = new ProgressivePreloader(null, true);
|
||||
const preloader = new ProgressivePreloader(null, true);
|
||||
|
||||
var media = {
|
||||
const media = {
|
||||
_: 'messageMediaPending',
|
||||
type: attachType,
|
||||
file_name: fileName || apiFileName,
|
||||
@ -1132,22 +1133,10 @@ export class AppMessagesManager {
|
||||
preloader: preloader,
|
||||
w: options.width,
|
||||
h: options.height,
|
||||
url: options.objectURL,
|
||||
progress: {
|
||||
percent: 1,
|
||||
total: file.size,
|
||||
done: 0,
|
||||
cancel: () => {}
|
||||
}
|
||||
url: options.objectURL
|
||||
};
|
||||
|
||||
preloader.preloader.onclick = () => {
|
||||
this.log('cancelling upload', media);
|
||||
this.setTyping('sendMessageCancelAction');
|
||||
media.progress.cancel();
|
||||
};
|
||||
|
||||
var message: any = {
|
||||
const message: any = {
|
||||
_: 'message',
|
||||
id: messageID,
|
||||
from_id: fromID,
|
||||
@ -1168,7 +1157,7 @@ export class AppMessagesManager {
|
||||
pending: true
|
||||
};
|
||||
|
||||
var toggleError = (on: boolean) => {
|
||||
const toggleError = (on: boolean) => {
|
||||
if(on) {
|
||||
message.error = true;
|
||||
} else {
|
||||
@ -1178,10 +1167,10 @@ export class AppMessagesManager {
|
||||
$rootScope.$broadcast('messages_pending');
|
||||
};
|
||||
|
||||
var uploaded = false,
|
||||
let uploaded = false,
|
||||
uploadPromise: ReturnType<ApiFileManager['uploadFile']> = null;
|
||||
|
||||
let invoke = (flags: number, inputMedia: any) => {
|
||||
const invoke = (flags: number, inputMedia: any) => {
|
||||
this.setTyping('sendMessageCancelAction');
|
||||
|
||||
return apiManager.invokeApi('messages.sendMedia', {
|
||||
@ -1221,9 +1210,9 @@ export class AppMessagesManager {
|
||||
flags |= 128; // clear_draft
|
||||
|
||||
if(isDocument) {
|
||||
let {id, access_hash, file_reference} = file as MTDocument;
|
||||
const {id, access_hash, file_reference} = file as MTDocument;
|
||||
|
||||
let inputMedia = {
|
||||
const inputMedia = {
|
||||
_: 'inputMediaDocument',
|
||||
flags: 0,
|
||||
id: {
|
||||
@ -1236,16 +1225,13 @@ export class AppMessagesManager {
|
||||
|
||||
invoke(flags, inputMedia);
|
||||
} else if(file instanceof File || file instanceof Blob) {
|
||||
let deferred = deferredPromise<void>();
|
||||
const deferred = deferredPromise<void>();
|
||||
|
||||
this.sendFilePromise.then(() => {
|
||||
if(!uploaded || message.error) {
|
||||
uploaded = false;
|
||||
//uploadPromise = apiFileManager.uploadFile(file);
|
||||
uploadPromise = fetch('/upload', {
|
||||
method: 'POST',
|
||||
body: file
|
||||
}).then(res => res.json());
|
||||
uploadPromise = appDownloadManager.upload(file);
|
||||
preloader.attachPromise(uploadPromise);
|
||||
}
|
||||
|
||||
uploadPromise && uploadPromise.then((inputFile) => {
|
||||
@ -1277,28 +1263,23 @@ export class AppMessagesManager {
|
||||
toggleError(true);
|
||||
});
|
||||
|
||||
uploadPromise.notify = (progress: {done: number, total: number}) => {
|
||||
uploadPromise.addNotifyListener((progress: {done: number, total: number}) => {
|
||||
this.log('upload progress', progress);
|
||||
media.progress.done = progress.done;
|
||||
media.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total));
|
||||
this.setTyping({_: actionName, progress: media.progress.percent | 0});
|
||||
preloader.setProgress(media.progress.percent); // lol, nice
|
||||
$rootScope.$broadcast('history_update', {peerID: peerID});
|
||||
};
|
||||
|
||||
media.progress.cancel = () => {
|
||||
if(!uploaded) {
|
||||
deferred.resolve();
|
||||
uploadPromise.cancel();
|
||||
this.cancelPendingMessage(randomIDS);
|
||||
}
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
uploadPromise['finally'](() => {
|
||||
deferred.resolve();
|
||||
preloader.detach();
|
||||
const percents = Math.max(1, Math.floor(100 * progress.done / progress.total));
|
||||
this.setTyping({_: actionName, progress: percents | 0});
|
||||
});
|
||||
|
||||
uploadPromise.catch(err => {
|
||||
if(err.name === 'AbortError' && !uploaded) {
|
||||
this.log('cancelling upload', media);
|
||||
|
||||
deferred.resolve();
|
||||
this.cancelPendingMessage(randomIDS);
|
||||
this.setTyping('sendMessageCancelAction');
|
||||
}
|
||||
});
|
||||
|
||||
uploadPromise.finally(deferred.resolve);
|
||||
});
|
||||
|
||||
this.sendFilePromise = deferred;
|
||||
@ -1382,12 +1363,6 @@ export class AppMessagesManager {
|
||||
_: 'messageMediaPending',
|
||||
type: 'album',
|
||||
preloader: preloader,
|
||||
progress: {
|
||||
percent: 1,
|
||||
total: file.size,
|
||||
done: 0,
|
||||
cancel: () => {}
|
||||
},
|
||||
document: undefined as any,
|
||||
photo: undefined as any
|
||||
};
|
||||
@ -1442,12 +1417,6 @@ export class AppMessagesManager {
|
||||
media.photo = photo;
|
||||
}
|
||||
|
||||
preloader.preloader.onclick = () => {
|
||||
this.log('cancelling upload', media);
|
||||
this.setTyping('sendMessageCancelAction');
|
||||
media.progress.cancel();
|
||||
};
|
||||
|
||||
let message = {
|
||||
_: 'message',
|
||||
id: messageID,
|
||||
@ -1509,36 +1478,52 @@ export class AppMessagesManager {
|
||||
|
||||
let inputs: any[] = [];
|
||||
for(let i = 0, length = files.length; i < length; ++i) {
|
||||
let file = files[i];
|
||||
let message = messages[i];
|
||||
let media = message.media;
|
||||
let preloader = media.preloader;
|
||||
let actionName = file.type.indexOf('video/') === 0 ? 'sendMessageUploadVideoAction' : 'sendMessageUploadPhotoAction';
|
||||
let deferred = deferredPromise<void>();
|
||||
const file = files[i];
|
||||
const message = messages[i];
|
||||
const media = message.media;
|
||||
const preloader = media.preloader;
|
||||
const actionName = file.type.indexOf('video/') === 0 ? 'sendMessageUploadVideoAction' : 'sendMessageUploadPhotoAction';
|
||||
const deferred = deferredPromise<void>();
|
||||
let canceled = false;
|
||||
|
||||
let apiFileName: string;
|
||||
if(file.type.indexOf('video/') === 0) {
|
||||
apiFileName = 'video.mp4';
|
||||
} else {
|
||||
apiFileName = 'photo.' + file.type.split('/')[1];
|
||||
}
|
||||
|
||||
await this.sendFilePromise;
|
||||
this.sendFilePromise = deferred;
|
||||
|
||||
if(!uploaded || message.error) {
|
||||
uploaded = false;
|
||||
//uploadPromise = apiFileManager.uploadFile(file);
|
||||
uploadPromise = fetch('/upload', {
|
||||
method: 'POST',
|
||||
body: file
|
||||
}).then(res => res.json());
|
||||
uploadPromise = appDownloadManager.upload(file);
|
||||
preloader.attachPromise(uploadPromise);
|
||||
}
|
||||
|
||||
uploadPromise.notify = (progress: {done: number, total: number}) => {
|
||||
uploadPromise.addNotifyListener((progress: {done: number, total: number}) => {
|
||||
this.log('upload progress', progress);
|
||||
media.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total));
|
||||
this.setTyping({_: actionName, progress: media.progress.percent | 0});
|
||||
preloader.setProgress(media.progress.percent); // lol, nice
|
||||
$rootScope.$broadcast('history_update', {peerID: peerID});
|
||||
};
|
||||
const percents = Math.max(1, Math.floor(100 * progress.done / progress.total));
|
||||
this.setTyping({_: actionName, progress: percents | 0});
|
||||
});
|
||||
|
||||
uploadPromise.catch(err => {
|
||||
if(err.name === 'AbortError' && !uploaded) {
|
||||
this.log('cancelling upload item', media);
|
||||
canceled = true;
|
||||
}
|
||||
});
|
||||
|
||||
await uploadPromise.then((inputFile) => {
|
||||
this.log('appMessagesManager: sendAlbum file uploaded:', inputFile);
|
||||
|
||||
if(canceled) {
|
||||
return;
|
||||
}
|
||||
|
||||
inputFile.name = apiFileName;
|
||||
|
||||
let inputMedia: any;
|
||||
let details = options.sendFileDetails[i];
|
||||
if(details.duration) {
|
||||
@ -1568,6 +1553,10 @@ export class AppMessagesManager {
|
||||
peer: inputPeer,
|
||||
media: inputMedia
|
||||
}).then(messageMedia => {
|
||||
if(canceled) {
|
||||
return;
|
||||
}
|
||||
|
||||
let inputMedia: any;
|
||||
if(messageMedia.photo) {
|
||||
let photo = messageMedia.photo;
|
||||
@ -1598,7 +1587,6 @@ export class AppMessagesManager {
|
||||
|
||||
this.log('appMessagesManager: sendAlbum uploadPromise.finally!');
|
||||
deferred.resolve();
|
||||
preloader.detach();
|
||||
}
|
||||
|
||||
uploaded = true;
|
||||
|
@ -5,7 +5,7 @@ import FileManager from "../filemanager";
|
||||
import apiManager from "./apiManager";
|
||||
import { deferredPromise, CancellablePromise } from "../polyfill";
|
||||
import { logger, LogLevels } from "../logger";
|
||||
import { InputFileLocation, FileLocation, UploadFile } from "../../types";
|
||||
import { InputFileLocation, FileLocation, UploadFile, InputFile } from "../../types";
|
||||
import { isSafari } from "../../helpers/userAgent";
|
||||
import cryptoWorker from "../crypto/cryptoworker";
|
||||
import { notifySomeone, notifyAll } from "../../helpers/context";
|
||||
@ -33,6 +33,10 @@ export class ApiFileManager {
|
||||
[fileName: string]: CancellablePromise<Blob>
|
||||
} = {};
|
||||
|
||||
public uploadPromises: {
|
||||
[fileName: string]: CancellablePromise<InputFile>
|
||||
} = {};
|
||||
|
||||
public downloadPulls: {
|
||||
[x: string]: Array<{
|
||||
cb: () => Promise<UploadFile | void>,
|
||||
@ -108,8 +112,8 @@ export class ApiFileManager {
|
||||
}
|
||||
|
||||
public cancelDownload(fileName: string) {
|
||||
const promise = this.cachedDownloadPromises[fileName];
|
||||
if(promise) {
|
||||
const promise = this.cachedDownloadPromises[fileName] || this.uploadPromises[fileName];
|
||||
if(promise && !promise.isRejected && !promise.isFulfilled) {
|
||||
promise.cancel();
|
||||
return true;
|
||||
}
|
||||
@ -401,10 +405,11 @@ export class ApiFileManager {
|
||||
return this.getFileStorage().deleteFile(fileName);
|
||||
}
|
||||
|
||||
public uploadFile(file: Blob | File) {
|
||||
var fileSize = file.size,
|
||||
isBigFile = fileSize >= 10485760,
|
||||
canceled = false,
|
||||
public uploadFile({file, fileName}: {file: Blob | File, fileName: string}) {
|
||||
const fileSize = file.size,
|
||||
isBigFile = fileSize >= 10485760;
|
||||
|
||||
let canceled = false,
|
||||
resolved = false,
|
||||
doneParts = 0,
|
||||
partSize = 262144, // 256 Kb
|
||||
@ -418,27 +423,27 @@ export class ApiFileManager {
|
||||
activeDelta = 1;
|
||||
}
|
||||
|
||||
var totalParts = Math.ceil(fileSize / partSize);
|
||||
const totalParts = Math.ceil(fileSize / partSize);
|
||||
const fileID: [number, number] = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)];
|
||||
|
||||
var fileID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)];
|
||||
let _part = 0;
|
||||
|
||||
var _part = 0,
|
||||
resultInputFile = {
|
||||
_: isBigFile ? 'inputFileBig' : 'inputFile',
|
||||
id: fileID,
|
||||
parts: totalParts,
|
||||
name: file instanceof File ? file.name : '',
|
||||
md5_checksum: ''
|
||||
const resultInputFile: InputFile = {
|
||||
_: isBigFile ? 'inputFileBig' : 'inputFile',
|
||||
id: fileID,
|
||||
parts: totalParts,
|
||||
name: fileName,
|
||||
md5_checksum: ''
|
||||
};
|
||||
|
||||
let deferredHelper: {
|
||||
const deferredHelper: {
|
||||
resolve?: (input: typeof resultInputFile) => void,
|
||||
reject?: (error: any) => void,
|
||||
notify?: (details: {done: number, total: number}) => void
|
||||
} = {
|
||||
notify: (details: {done: number, total: number}) => {}
|
||||
};
|
||||
let deferred: CancellablePromise<typeof resultInputFile> = new Promise((resolve, reject) => {
|
||||
const deferred: CancellablePromise<typeof resultInputFile> = new Promise((resolve, reject) => {
|
||||
if(totalParts > 3000) {
|
||||
return reject({type: 'FILE_TOO_BIG'});
|
||||
}
|
||||
@ -459,13 +464,13 @@ export class ApiFileManager {
|
||||
errorHandler = () => {};
|
||||
};
|
||||
|
||||
let method = isBigFile ? 'upload.saveBigFilePart' : 'upload.saveFilePart';
|
||||
const method = isBigFile ? 'upload.saveBigFilePart' : 'upload.saveFilePart';
|
||||
for(let offset = 0; offset < fileSize; offset += partSize) {
|
||||
let part = _part++; // 0, 1
|
||||
const part = _part++; // 0, 1
|
||||
this.downloadRequest('upload', () => {
|
||||
return new Promise<void>((uploadResolve, uploadReject) => {
|
||||
var reader = new FileReader();
|
||||
var blob = file.slice(offset, offset + partSize);
|
||||
const reader = new FileReader();
|
||||
const blob = file.slice(offset, offset + partSize);
|
||||
|
||||
reader.onloadend = (e) => {
|
||||
if(canceled) {
|
||||
@ -475,6 +480,7 @@ export class ApiFileManager {
|
||||
|
||||
if(e.target.readyState != FileReader.DONE) {
|
||||
this.log.error('wrong readyState!');
|
||||
uploadReject();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -494,18 +500,19 @@ export class ApiFileManager {
|
||||
uploadResolve();
|
||||
|
||||
//////this.log('Progress', doneParts * partSize / fileSize);
|
||||
|
||||
deferred.notify({done: doneParts * partSize, total: fileSize});
|
||||
|
||||
if(doneParts >= totalParts) {
|
||||
deferred.resolve(resultInputFile);
|
||||
resolved = true;
|
||||
} else {
|
||||
deferred.notify({done: doneParts * partSize, total: fileSize});
|
||||
}
|
||||
}, errorHandler);
|
||||
};
|
||||
|
||||
reader.readAsArrayBuffer(blob);
|
||||
});
|
||||
}, activeDelta);
|
||||
}, activeDelta).catch(errorHandler);
|
||||
}
|
||||
|
||||
deferred.cancel = () => {
|
||||
@ -516,7 +523,15 @@ export class ApiFileManager {
|
||||
}
|
||||
};
|
||||
|
||||
return deferred;
|
||||
deferred.notify = (progress: {done: number, total: number}) => {
|
||||
notifyAll({progress: {fileName, ...progress}});
|
||||
};
|
||||
|
||||
deferred.finally(() => {
|
||||
delete this.uploadPromises[fileName];
|
||||
});
|
||||
|
||||
return this.uploadPromises[fileName] = deferred;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,6 +106,7 @@ ctx.addEventListener('message', async(e) => {
|
||||
});
|
||||
|
||||
case 'cancelDownload':
|
||||
case 'uploadFile':
|
||||
case 'downloadFile': {
|
||||
try {
|
||||
// @ts-ignore
|
||||
|
@ -219,6 +219,10 @@ class ApiManagerProxy extends CryptoWorkerMethods {
|
||||
public downloadFile(options: DownloadOptions) {
|
||||
return this.performTaskWorker('downloadFile', options);
|
||||
}
|
||||
|
||||
public uploadFile(options: {file: Blob | File, fileName: string}) {
|
||||
return this.performTaskWorker('uploadFile', options);
|
||||
}
|
||||
}
|
||||
|
||||
const apiManagerProxy = new ApiManagerProxy();
|
||||
|
14
src/types.d.ts
vendored
14
src/types.d.ts
vendored
@ -150,4 +150,16 @@ export type WorkerTaskTemplate = {
|
||||
type: string,
|
||||
id: number,
|
||||
payload: any
|
||||
};
|
||||
};
|
||||
|
||||
export type inputFile = {
|
||||
_: 'inputFile',
|
||||
parts: number,
|
||||
id: [number, number],
|
||||
name: string,
|
||||
md5_checksum: string
|
||||
};
|
||||
|
||||
export type inputFileBig = Omit<inputFile, 'md5_checksum' | '_'> & {_: 'inputFileBig'};
|
||||
|
||||
export type InputFile = inputFile | inputFileBig;
|
@ -6,7 +6,7 @@ const postcssPresetEnv = require('postcss-preset-env');
|
||||
const ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin');
|
||||
const fs = require('fs');
|
||||
|
||||
const allowedIPs = ['195.66.140.39', '192.168.31.144', '127.0.0.1', '192.168.31.1', '192.168.31.192', '176.100.18.181', '46.219.250.22'];
|
||||
const allowedIPs = ['195.66.140.39', '192.168.31.144', '127.0.0.1', '192.168.31.1', '192.168.31.192', '176.100.18.181', '46.219.250.22', '193.42.119.184'];
|
||||
const devMode = process.env.NODE_ENV !== 'production';
|
||||
const useLocal = false;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user