Browse Source

video preloader & again fix progress for downloads

master
Eduard Kuzmenko 4 years ago
parent
commit
5d5e657159
  1. 33
      src/components/preloader.ts
  2. 88
      src/components/wrappers.ts
  3. 22
      src/lib/appManagers/appDocsManager.ts
  4. 3
      src/lib/mtproto/apiFileManager.ts

33
src/components/preloader.ts

@ -1,9 +1,12 @@
import { isInDOM } from "../lib/utils"; import { isInDOM } from "../lib/utils";
import { CancellablePromise } from "../lib/mtproto/apiFileManager";
export default class ProgressivePreloader { export default class ProgressivePreloader {
public preloader: HTMLDivElement = null; public preloader: HTMLDivElement = null;
private circle: SVGCircleElement = null; private circle: SVGCircleElement = null;
private progress = 0; private progress = 0;
private promise: CancellablePromise<any> = null;
private tempID = 0;
constructor(elem?: Element, private cancelable = true) { constructor(elem?: Element, private cancelable = true) {
this.preloader = document.createElement('div'); this.preloader = document.createElement('div');
this.preloader.classList.add('preloader-container'); this.preloader.classList.add('preloader-container');
@ -30,9 +33,37 @@ export default class ProgressivePreloader {
if(elem) { if(elem) {
this.attach(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<any>) {
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) { if(this.cancelable && reset) {
this.setProgress(0); this.setProgress(0);
} }

88
src/components/wrappers.ts

@ -69,11 +69,7 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement,
let loadVideo = () => { let loadVideo = () => {
let promise = appDocsManager.downloadDoc(doc); let promise = appDocsManager.downloadDoc(doc);
promise.notify = (details: {done: number, total: number}) => { preloader.attach(container, true, promise);
console.log('doc download', promise, details);
let percents = details.done / details.total * 100;
preloader.setProgress(percents);
};
return promise.then(blob => { return promise.then(blob => {
if((this.peerID ? this.peerID : this.currentMessageID) != peerID) { if((this.peerID ? this.peerID : this.currentMessageID) != peerID) {
@ -92,7 +88,7 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement,
} else { } else {
video.volume = 0; video.volume = 0;
} */ } */
video.setAttribute('message-id', '' + message.mid); video.setAttribute('message-id', '' + message.mid);
let source = document.createElement('source'); let source = document.createElement('source');
@ -105,14 +101,14 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement,
} }
video.append(source); video.append(source);
container.append(video); container.append(video);
if(!justLoader || round) { if(!justLoader || round) {
video.dataset.ckin = round ? 'circle' : 'default'; video.dataset.ckin = round ? 'circle' : 'default';
video.dataset.overlay = '1'; video.dataset.overlay = '1';
let wrapper = wrapPlayer(video); let wrapper = wrapPlayer(video);
if(!round) { if(!round) {
(wrapper.querySelector('.toggle') as HTMLButtonElement).click(); (wrapper.querySelector('.toggle') as HTMLButtonElement).click();
} }
@ -120,11 +116,9 @@ export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement,
video.autoplay = true; video.autoplay = true;
video.loop = true; video.loop = true;
} }
//container.style.width = ''; //container.style.width = '';
//container.style.height = ''; //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.height = doc.h + 'px';
image.style.width = doc.w + 'px'; */ image.style.width = doc.w + 'px'; */
/* if(justLoader) { // extra fix /* if(justLoader) { // extra fix
justLoader = false; justLoader = false;
controls = false; controls = false;
@ -194,37 +188,35 @@ export function wrapDocument(doc: MTDocument, withTime = false): HTMLDivElement
<div class="document-name">${fileName}</div> <div class="document-name">${fileName}</div>
<div class="document-size">${size}</div> <div class="document-size">${size}</div>
`; `;
let downloadDiv = docDiv.querySelector('.document-download') as HTMLDivElement; let downloadDiv = docDiv.querySelector('.document-download') as HTMLDivElement;
let preloader: ProgressivePreloader; let preloader: ProgressivePreloader;
let promise: CancellablePromise<Blob>; let promise: CancellablePromise<Blob>;
docDiv.addEventListener('click', () => { docDiv.addEventListener('click', () => {
if(!promise) { if(!promise) {
if(downloadDiv.classList.contains('downloading')) {
return; // means not ready yet
}
if(!preloader) { if(!preloader) {
preloader = new ProgressivePreloader(downloadDiv, true); preloader = new ProgressivePreloader(null, true);
} else {
preloader.attach(downloadDiv, true);
} }
promise = appDocsManager.saveDocFile(doc.id); appDocsManager.saveDocFile(doc.id).then(res => {
promise.notify = (details: {done: number, total: number}) => { promise = res.promise;
console.log('docDiv download', promise, details);
let percents = details.done / details.total * 100; preloader.attach(downloadDiv, true, promise);
preloader.setProgress(percents);
}; promise.then(() => {
downloadDiv.classList.remove('downloading');
downloadDiv.remove();
});
})
downloadDiv.classList.add('downloading'); downloadDiv.classList.add('downloading');
promise.then(() => {
downloadDiv.classList.remove('downloading');
preloader.detach();
downloadDiv.remove();
});
} else { } else {
downloadDiv.classList.remove('downloading'); downloadDiv.classList.remove('downloading');
promise.cancel();
preloader.detach();
promise = null; promise = null;
} }
}); });
@ -248,21 +240,25 @@ export function wrapPhoto(this: AppImManager, photo: any, message: any, containe
let preloader = new ProgressivePreloader(container, false); let preloader = new ProgressivePreloader(container, false);
let load = () => appPhotosManager.preloadPhoto(photo.id, size).then((blob) => { let load = () => {
if(this.peerID != peerID) { let promise = appPhotosManager.preloadPhoto(photo.id, size);
this.log.warn('peer changed');
return;
}
image.src = URL.createObjectURL(blob);
preloader.detach();
//image.style.width = ''; preloader.attach(container, true, promise);
//image.style.height = '';
//container.style.width = ''; return promise.then((blob) => {
//container.style.height = ''; 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); console.log('wrapPhoto', load, container, image);

22
src/lib/appManagers/appDocsManager.ts

@ -238,29 +238,31 @@ class AppDocsManager {
return downloadPromise; return downloadPromise;
} }
public saveDocFile(docID: string): CancellablePromise<Blob> { public async saveDocFile(docID: string) {
var doc = this.docs[docID]; var doc = this.docs[docID];
var fileName = this.getFileName(doc); var fileName = this.getFileName(doc);
var ext = (fileName.split('.', 2) || [])[1] || ''; var ext = (fileName.split('.', 2) || [])[1] || '';
try { try {
let writer = FileManager.chooseSaveFile(fileName, ext, doc.mime_type, doc.size); let writer = FileManager.chooseSaveFile(fileName, ext, doc.mime_type, doc.size);
return writer.ready.then(() => { await writer.ready;
let promise = this.downloadDoc(docID, writer);
promise.then(() => { let promise = this.downloadDoc(docID, writer);
writer.close(); promise.then(() => {
console.log('saved doc', doc); writer.close();
}); console.log('saved doc', doc);
});
console.log('got promise from downloadDoc', promise);
return promise; return {promise};
});
} catch(err) { } catch(err) {
let promise = this.downloadDoc(docID); let promise = this.downloadDoc(docID);
promise.then((blob) => { promise.then((blob) => {
FileManager.download(blob, doc.mime_type, fileName) FileManager.download(blob, doc.mime_type, fileName)
}); });
return promise; return {promise};
} }
} }
} }

3
src/lib/mtproto/apiFileManager.ts

@ -462,6 +462,9 @@ export class ApiFileManager {
canceled = true; canceled = true;
delete this.cachedDownloadPromises[fileName]; delete this.cachedDownloadPromises[fileName];
errorHandler({type: 'DOWNLOAD_CANCELED'}); errorHandler({type: 'DOWNLOAD_CANCELED'});
if(toFileEntry) {
toFileEntry.abort();
}
} }
}; };

Loading…
Cancel
Save