From 5d5e6571598e4d67cc5f70d568820f925013f82f Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Fri, 14 Feb 2020 18:04:39 +0700 Subject: [PATCH] video preloader & again fix progress for downloads --- src/components/preloader.ts | 33 +++++++++- src/components/wrappers.ts | 88 +++++++++++++-------------- src/lib/appManagers/appDocsManager.ts | 22 ++++--- src/lib/mtproto/apiFileManager.ts | 3 + 4 files changed, 89 insertions(+), 57 deletions(-) diff --git a/src/components/preloader.ts b/src/components/preloader.ts index d48ad018..f186f8f3 100644 --- a/src/components/preloader.ts +++ b/src/components/preloader.ts @@ -1,9 +1,12 @@ import { isInDOM } from "../lib/utils"; +import { CancellablePromise } from "../lib/mtproto/apiFileManager"; export default class ProgressivePreloader { public preloader: HTMLDivElement = null; private circle: SVGCircleElement = null; private progress = 0; + private promise: CancellablePromise = null; + private tempID = 0; constructor(elem?: Element, private cancelable = true) { this.preloader = document.createElement('div'); this.preloader.classList.add('preloader-container'); @@ -30,9 +33,37 @@ export default class ProgressivePreloader { if(elem) { this.attach(elem); } + + if(this.cancelable) { + this.preloader.addEventListener('click', () => { + if(this.promise && this.promise.cancel) { + this.promise.cancel(); + this.detach(); + } + }); + } } - public attach(elem: Element, reset = true) { + public attach(elem: Element, reset = true, promise?: CancellablePromise) { + if(promise) { + this.promise = promise; + + let tempID = --this.tempID; + promise.then(() => { + if(tempID == this.tempID) { + this.detach(); + } + }); + + promise.notify = (details: {done: number, total: number}) => { + if(tempID != this.tempID) return; + + console.log('preloader download', promise, details); + let percents = details.done / details.total * 100; + this.setProgress(percents); + }; + } + if(this.cancelable && reset) { this.setProgress(0); } diff --git a/src/components/wrappers.ts b/src/components/wrappers.ts index b661dd39..c75d0c79 100644 --- a/src/components/wrappers.ts +++ b/src/components/wrappers.ts @@ -69,11 +69,7 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement, let loadVideo = () => { let promise = appDocsManager.downloadDoc(doc); - promise.notify = (details: {done: number, total: number}) => { - console.log('doc download', promise, details); - let percents = details.done / details.total * 100; - preloader.setProgress(percents); - }; + preloader.attach(container, true, promise); return promise.then(blob => { if((this.peerID ? this.peerID : this.currentMessageID) != peerID) { @@ -92,7 +88,7 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement, } else { video.volume = 0; } */ - + video.setAttribute('message-id', '' + message.mid); let source = document.createElement('source'); @@ -105,14 +101,14 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement, } video.append(source); - + container.append(video); - + if(!justLoader || round) { video.dataset.ckin = round ? 'circle' : 'default'; video.dataset.overlay = '1'; let wrapper = wrapPlayer(video); - + if(!round) { (wrapper.querySelector('.toggle') as HTMLButtonElement).click(); } @@ -120,11 +116,9 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement, video.autoplay = true; video.loop = true; } - + //container.style.width = ''; //container.style.height = ''; - - preloader.detach(); }); }; @@ -141,7 +135,7 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement, /* image.style.height = doc.h + 'px'; image.style.width = doc.w + 'px'; */ - + /* if(justLoader) { // extra fix justLoader = false; controls = false; @@ -194,37 +188,35 @@ export function wrapDocument(doc: MTDocument, withTime = false): HTMLDivElement
${fileName}
${size}
`; - + let downloadDiv = docDiv.querySelector('.document-download') as HTMLDivElement; let preloader: ProgressivePreloader; let promise: CancellablePromise; - + docDiv.addEventListener('click', () => { if(!promise) { + if(downloadDiv.classList.contains('downloading')) { + return; // means not ready yet + } + if(!preloader) { - preloader = new ProgressivePreloader(downloadDiv, true); - } else { - preloader.attach(downloadDiv, true); + preloader = new ProgressivePreloader(null, true); } - promise = appDocsManager.saveDocFile(doc.id); - promise.notify = (details: {done: number, total: number}) => { - console.log('docDiv download', promise, details); - let percents = details.done / details.total * 100; - preloader.setProgress(percents); - }; + appDocsManager.saveDocFile(doc.id).then(res => { + promise = res.promise; + + preloader.attach(downloadDiv, true, promise); + + promise.then(() => { + downloadDiv.classList.remove('downloading'); + downloadDiv.remove(); + }); + }) downloadDiv.classList.add('downloading'); - - promise.then(() => { - downloadDiv.classList.remove('downloading'); - preloader.detach(); - downloadDiv.remove(); - }); } else { downloadDiv.classList.remove('downloading'); - promise.cancel(); - preloader.detach(); promise = null; } }); @@ -248,21 +240,25 @@ export function wrapPhoto(this: AppImManager, photo: any, message: any, containe let preloader = new ProgressivePreloader(container, false); - let load = () => appPhotosManager.preloadPhoto(photo.id, size).then((blob) => { - if(this.peerID != peerID) { - this.log.warn('peer changed'); - return; - } - - image.src = URL.createObjectURL(blob); - - preloader.detach(); + let load = () => { + let promise = appPhotosManager.preloadPhoto(photo.id, size); - //image.style.width = ''; - //image.style.height = ''; - //container.style.width = ''; - //container.style.height = ''; - }); + preloader.attach(container, true, promise); + + return promise.then((blob) => { + if(this.peerID != peerID) { + this.log.warn('peer changed'); + return; + } + + image.src = URL.createObjectURL(blob); + + //image.style.width = ''; + //image.style.height = ''; + //container.style.width = ''; + //container.style.height = ''; + }); + }; console.log('wrapPhoto', load, container, image); diff --git a/src/lib/appManagers/appDocsManager.ts b/src/lib/appManagers/appDocsManager.ts index 028eb758..1cb036b9 100644 --- a/src/lib/appManagers/appDocsManager.ts +++ b/src/lib/appManagers/appDocsManager.ts @@ -238,29 +238,31 @@ class AppDocsManager { return downloadPromise; } - public saveDocFile(docID: string): CancellablePromise { + public async saveDocFile(docID: string) { var doc = this.docs[docID]; var fileName = this.getFileName(doc); var ext = (fileName.split('.', 2) || [])[1] || ''; try { let writer = FileManager.chooseSaveFile(fileName, ext, doc.mime_type, doc.size); - return writer.ready.then(() => { - let promise = this.downloadDoc(docID, writer); - promise.then(() => { - writer.close(); - console.log('saved doc', doc); - }); + await writer.ready; + + let promise = this.downloadDoc(docID, writer); + promise.then(() => { + writer.close(); + console.log('saved doc', doc); + }); + + console.log('got promise from downloadDoc', promise); - return promise; - }); + return {promise}; } catch(err) { let promise = this.downloadDoc(docID); promise.then((blob) => { FileManager.download(blob, doc.mime_type, fileName) }); - return promise; + return {promise}; } } } diff --git a/src/lib/mtproto/apiFileManager.ts b/src/lib/mtproto/apiFileManager.ts index 68d4219a..6944fffa 100644 --- a/src/lib/mtproto/apiFileManager.ts +++ b/src/lib/mtproto/apiFileManager.ts @@ -462,6 +462,9 @@ export class ApiFileManager { canceled = true; delete this.cachedDownloadPromises[fileName]; errorHandler({type: 'DOWNLOAD_CANCELED'}); + if(toFileEntry) { + toFileEntry.abort(); + } } };