From 427718d852fddc12d5b269489a378ff14fb68e0d Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Fri, 14 Feb 2020 16:30:06 +0700 Subject: [PATCH] webpage title & file downloads & progress bars --- package-lock.json | 19 ++- package.json | 4 +- src/components/pageSignUp.ts | 22 +-- src/components/wrappers.ts | 37 ++++- src/lib/appManagers/appDocsManager.ts | 42 ++++-- src/lib/appManagers/appImManager.ts | 4 +- src/lib/appManagers/appMediaViewer.ts | 5 + src/lib/appManagers/appPhotosManager.ts | 68 +++------ src/lib/filemanager.ts | 192 +++++++++++++----------- src/lib/lottieLoader.ts | 5 +- src/lib/mtproto/apiFileManager.ts | 42 ++++-- src/scss/partials/_sidebar.scss | 8 +- src/scss/style.scss | 42 +++++- webpack.dev.js | 3 +- webpack.prod.js | 2 + 15 files changed, 300 insertions(+), 195 deletions(-) diff --git a/package-lock.json b/package-lock.json index b44d6a2a..9dc923b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6521,9 +6521,10 @@ } }, "lottie-web": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.6.3.tgz", - "integrity": "sha512-cSG6kSA2m5ppxV/QMVHRVGop/R+oXgO4vVMvDcZR015Cy0PGml5hHP+XG21yB2qV6cYZy+X3ChTogSALgch7CA==" + "version": "5.6.4", + "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.6.4.tgz", + "integrity": "sha512-eU+21Wo/RSi4i260S7fDUxfhNJ9PhfzUJMVQpip0yZd19oJ18jrNCoSQKVUzjC2TzOjqumlLZXR636ezKoWNQg==", + "dev": true }, "loud-rejection": { "version": "1.6.0", @@ -12816,6 +12817,12 @@ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", "dev": true }, + "streamsaver": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/streamsaver/-/streamsaver-2.0.3.tgz", + "integrity": "sha512-IpXeZ67YxcsrfZHe3yg/IyZ5KPfRSn1teDy5mRX2e8M6K410NcJNcR+SFQ2Z92DO36VBUArQP4Vy3Qu33MwIOQ==", + "dev": true + }, "string-length": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", @@ -13761,6 +13768,12 @@ "minimalistic-assert": "^1.0.0" } }, + "web-streams-polyfill": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-2.0.6.tgz", + "integrity": "sha512-nXOi4fBykO4LzyQhZX3MAGib635KGZBoNTkNXrNIkz0zthEf2QokEWxRb0H632xNLDWtHFb1R6dFGzksjYMSDw==", + "dev": true + }, "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", diff --git a/package.json b/package.json index 5ebb55f2..0b35c076 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,6 @@ "license": "ISC", "dependencies": { "jsbn": "^1.1.0", - "lottie-web": "^5.6.3", "materialize-css": "^1.0.0", "roboto-fontface": "^0.10.0", "rusha": "^0.8.13", @@ -41,6 +40,7 @@ "install": "^0.13.0", "jest": "^24.9.0", "leemon": "^6.2.0", + "lottie-web": "^5.6.4", "node-sass": "^4.13.0", "npm": "^6.13.4", "offscreen-canvas": "^0.1.1", @@ -49,11 +49,13 @@ "pako": "^1.0.10", "resolve-url-loader": "^3.1.1", "sass-loader": "^8.0.0", + "streamsaver": "^2.0.3", "style-loader": "^1.0.0", "ts-jest": "^24.3.0", "ts-loader": "^6.2.1", "typescript": "^3.7.2", "url-loader": "^2.2.0", + "web-streams-polyfill": "^2.0.6", "webp-hero": "0.0.0-dev.24", "webpack": "^4.41.2", "webpack-cli": "^3.3.10", diff --git a/src/components/pageSignUp.ts b/src/components/pageSignUp.ts index afcd4c20..deab03f0 100644 --- a/src/components/pageSignUp.ts +++ b/src/components/pageSignUp.ts @@ -9,6 +9,7 @@ let authCode: { import resizeableImage from '../lib/cropper'; import pageIm from './pageIm'; import apiManager from '../lib/mtproto/apiManager'; +import apiFileManager from '../lib/mtproto/apiFileManager'; export default (_authCode: typeof authCode) => { authCode = _authCode; @@ -71,19 +72,6 @@ export default (_authCode: typeof authCode) => { if(!file) { return; } - - /* console.log(file, typeof(file)); */ - - // @ts-ignore - /* apiFileManager.uploadFile(file).then(function(inputFile) { - console.log('uploaded smthn', inputFile); - - apiManager.invokeApi('photos.uploadProfilePhoto', { - file: inputFile - }).then(function (updateResult) { - console.log('updated photo!'); - }); - }); */ var reader = new FileReader(); reader.onload = (e) => { @@ -94,18 +82,11 @@ export default (_authCode: typeof authCode) => { avatarImage.src = contents; avatarImage.onload = () => { - /* avatarPreviewCtx.drawImage(avatarImage, - 70, 20, // Start at 70/20 pixels from the left and the top of the image (crop), - 50, 50, // "Get" a `50 * 50` (w * h) area from the source image (crop), - 0, 0, // Place the result at 0, 0 in the canvas, - 100, 100); // With as width / height: 100 * 100 (scale) */ - cropper = resizeableImage(avatarImage, avatarPreview); avatarInput.value = ''; }; avatarPopup.classList.add('active'); - //console.log(contents); }; reader.readAsDataURL(file); @@ -136,7 +117,6 @@ export default (_authCode: typeof authCode) => { } console.log('invoking uploadFile...'); - // @ts-ignore apiFileManager.uploadFile(avatarBlob).then((inputFile: any) => { console.log('uploaded smthn', inputFile); diff --git a/src/components/wrappers.ts b/src/components/wrappers.ts index 4027b3f1..b661dd39 100644 --- a/src/components/wrappers.ts +++ b/src/components/wrappers.ts @@ -7,7 +7,7 @@ import {AppImManager} from "../lib/appManagers/appImManager"; import { formatBytes } from "../lib/utils"; import ProgressivePreloader from './preloader'; import LazyLoadQueue from './lazyLoadQueue'; -import apiFileManager from '../lib/mtproto/apiFileManager'; +import apiFileManager, { CancellablePromise } from '../lib/mtproto/apiFileManager'; import appWebpManager from '../lib/appManagers/appWebpManager'; import {wrapPlayer} from '../lib/ckin'; @@ -190,9 +190,44 @@ export function wrapDocument(doc: MTDocument, withTime = false): HTMLDivElement docDiv.innerHTML = `
${ext2}
+
${fileName}
${size}
`; + + let downloadDiv = docDiv.querySelector('.document-download') as HTMLDivElement; + let preloader: ProgressivePreloader; + let promise: CancellablePromise; + + docDiv.addEventListener('click', () => { + if(!promise) { + if(!preloader) { + preloader = new ProgressivePreloader(downloadDiv, true); + } else { + preloader.attach(downloadDiv, 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); + }; + + 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; + } + }); return docDiv; } diff --git a/src/lib/appManagers/appDocsManager.ts b/src/lib/appManagers/appDocsManager.ts index d84113a8..028eb758 100644 --- a/src/lib/appManagers/appDocsManager.ts +++ b/src/lib/appManagers/appDocsManager.ts @@ -232,27 +232,37 @@ class AppDocsManager { }; */ //historyDoc.progress.cancel = downloadPromise.cancel; + + console.log('return downloadPromise:', downloadPromise); return downloadPromise; } - /* public saveDocFile(docID: string) { - var doc = this.docs[docID] - var historyDoc = this.docsForHistory[docID] || doc || {} - var mimeType = doc.mime_type - var fileName = this.getFileName(doc) - var ext = (fileName.split('.', 2) || [])[1] || '' - - FileManager.chooseSave(this.getFileName(doc), ext, doc.mime_type).then((writableFileEntry) => { - if (writableFileEntry) { - this.downloadDoc(docID, writableFileEntry) - } - }, () => { - this.downloadDoc(docID).then((blob) => { + public saveDocFile(docID: string): CancellablePromise { + 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); + }); + + return promise; + }); + } catch(err) { + let promise = this.downloadDoc(docID); + promise.then((blob) => { FileManager.download(blob, doc.mime_type, fileName) - }) - }) - } */ + }); + + return promise; + } + } } export default new AppDocsManager(); diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts index 5db55e0f..f0bbe174 100644 --- a/src/lib/appManagers/appImManager.ts +++ b/src/lib/appManagers/appImManager.ts @@ -1726,7 +1726,9 @@ export class AppImManager { textDiv.innerHTML = RichTextProcessor.wrapRichText(webpage.description); } - //textDiv.innerText = webpage.description || ''; + if(webpage.title) { + titleDiv.innerHTML = RichTextProcessor.wrapRichText(webpage.title); + } quote.append(nameEl, titleDiv, textDiv); box.append(quote); diff --git a/src/lib/appManagers/appMediaViewer.ts b/src/lib/appManagers/appMediaViewer.ts index 80afc642..d8e08286 100644 --- a/src/lib/appManagers/appMediaViewer.ts +++ b/src/lib/appManagers/appMediaViewer.ts @@ -66,6 +66,11 @@ export class AppMediaViewer { this.buttons.next.style.display = 'none'; } }); + + this.buttons.download.addEventListener('click', () => { + let message = appMessagesManager.getMessage(this.currentMessageID); + appPhotosManager.downloadPhoto(message.media.photo.id); + }); /* this.buttons.prev.onclick = (e) => { let history = appSidebarRight.historiesStorage[$rootScope.selectedPeerID]['inputMessagesFilterPhotoVideo'].slice(); diff --git a/src/lib/appManagers/appPhotosManager.ts b/src/lib/appManagers/appPhotosManager.ts index 7ab0e465..1a3d22c2 100644 --- a/src/lib/appManagers/appPhotosManager.ts +++ b/src/lib/appManagers/appPhotosManager.ts @@ -283,7 +283,7 @@ export class AppPhotosManager { return photo; } - public wrapForFull(photoID: string) { + /* public wrapForFull(photoID: string) { var photo = this.wrapForHistory(photoID); var fullWidth = document.body.scrollWidth - (Config.Mobile ? 0 : 32); var fullHeight = document.body.scrollHeight - (Config.Mobile ? 0 : 116); @@ -310,38 +310,6 @@ export class AppPhotosManager { photo.full = full; return photo; - } - - /* public openPhoto(photoID: number, list: any) { - if(!photoID || photoID === '0') { - return false; - } - - var scope = $rootScope.$new(true); - - scope.photoID = photoID; - - var controller = 'PhotoModalController'; - if (list && list.p > 0) { - controller = 'UserpicModalController'; - scope.userID = list.p; - } else if (list && list.p < 0) { - controller = 'ChatpicModalController'; - scope.chatID = -list.p; - } else if (list && list.m > 0) { - scope.messageID = list.m; - if (list.w) { - scope.webpageID = list.w; - } - } - - var modalInstance = $modal.open({ - templateUrl: templateUrl('photo_modal'), - windowTemplateUrl: templateUrl('media_modal_layout'), - controller: controller, - scope: scope, - windowClass: 'photo_modal_window' - }); } */ public downloadPhoto(photoID: string) { @@ -349,28 +317,36 @@ export class AppPhotosManager { var ext = 'jpg'; var mimeType = 'image/jpeg'; var fileName = 'photo' + photoID + '.' + ext; - var fullWidth = Math.max(screen.width || 0, document.body.scrollWidth - 36, 800); - var fullHeight = Math.max(screen.height || 0, document.body.scrollHeight - 150, 800); + var fullWidth = this.windowW; + var fullHeight = this.windowH; var fullPhotoSize = this.choosePhotoSize(photo, fullWidth, fullHeight); var inputFileLocation = { - _: 'inputFileLocation', - volume_id: fullPhotoSize.location.volume_id, - local_id: fullPhotoSize.location.local_id, - secret: fullPhotoSize.location.secret + // @ts-ignore + _: photo._ == 'document' ? 'inputDocumentFileLocation' : 'inputPhotoFileLocation', + id: photo.id, + access_hash: photo.access_hash, + file_reference: photo.file_reference, + thumb_size: fullPhotoSize.type }; - fileManager.chooseSaveFile(fileName, ext, mimeType).then((writableFileEntry) => { - if(writableFileEntry) { + try { // photo.dc_id, location, photoSize.size + let writer = fileManager.chooseSaveFile(fileName, ext, mimeType, fullPhotoSize.size); + writer.ready.then(() => { + console.log('ready'); apiFileManager.downloadFile(photo.dc_id, inputFileLocation, fullPhotoSize.size, { mimeType: mimeType, - toFileEntry: writableFileEntry + toFileEntry: writer }).then(() => { - // console.log('file save done') + writer.close(); + //writer.abort(); + console.log('file save done', fileName, ext, mimeType, writer); }, (e: any) => { console.log('photo download failed', e); }); - } - }, () => { + }); + } catch(err) { + console.error('err', err); + var cachedBlob = apiFileManager.getCachedFile(inputFileLocation) if (cachedBlob) { return fileManager.download(cachedBlob, mimeType, fileName); @@ -382,7 +358,7 @@ export class AppPhotosManager { }, (e: any) => { console.log('photo download failed', e); }); - }); + } } } diff --git a/src/lib/filemanager.ts b/src/lib/filemanager.ts index 456fdc9b..4d5de899 100644 --- a/src/lib/filemanager.ts +++ b/src/lib/filemanager.ts @@ -1,16 +1,20 @@ import {bytesToArrayBuffer, blobSafeMimeType, blobConstruct, bytesToBase64} from './bin_utils'; -class FileManager { - /* $window.URL = $window.URL || $window.webkitURL - $window.BlobBuilder = $window.BlobBuilder || $window.WebKitBlobBuilder || $window.MozBlobBuilder */ +import 'web-streams-polyfill/ponyfill'; +// @ts-ignore +import streamSaver from 'streamsaver'; +if(window.location.href.indexOf('localhost') === -1) { + streamSaver.mitm = 'mitm.html'; +} +class FileManager { public isSafari = 'safari' in window; public safariVersion = parseFloat(this.isSafari && (navigator.userAgent.match(/Version\/(\d+\.\d+).* Safari/) || [])[1]); public safariWithDownload = this.isSafari && this.safariVersion >= 11.0; public buggyUnknownBlob = this.isSafari && !this.safariWithDownload; - + public blobSupported = true; - + constructor() { try { blobConstruct([], ''); @@ -18,12 +22,12 @@ class FileManager { this.blobSupported = false; } } - + public isAvailable() { return this.blobSupported; } - - public copy(fromFileEntry: any, toFileEntry: any) { + + /* public copy(fromFileEntry: any, toFileEntry: any) { return this.getFileWriter(toFileEntry).then((fileWriter) => { return this.write(fileWriter, fromFileEntry).then(() => { return fileWriter; @@ -32,13 +36,28 @@ class FileManager { // @ts-ignore fileWriter.truncate(0); } catch (e) {} - + return Promise.reject(error); }); }); + } */ + public copy(fromFileEntry: any, toFileEntry: any) { + return this.write(toFileEntry, fromFileEntry).then(() => { + console.log('copy success'); + return toFileEntry; + }, (error: any) => { + console.error('copy error 1:', error); + try { + toFileEntry.truncate(0); + } catch(e) { + console.error('copy error', e); + } + + return Promise.reject(error); + }); } - - public write(fileWriter: any, bytes: any) { + + /* public write(fileWriter: any, bytes: any) { return new Promise((resolve, reject) => { fileWriter.onwriteend = function(e: any) { resolve(); @@ -46,7 +65,7 @@ class FileManager { fileWriter.onerror = function(e: any) { reject(e); }; - + if(bytes.file) { bytes.file((file: any) => { fileWriter.write(file); @@ -62,54 +81,52 @@ class FileManager { } } }); - } + } */ + + public write(fileWriter: any, bytes: any): Promise { + if(bytes.file) { + return bytes.file((file: any) => { + return fileWriter.write(file); + }); + } else if(bytes instanceof Blob) { // is file bytes + return new Promise((resolve, reject) => { + let fileReader = new FileReader(); + fileReader.onload = function(event) { + let arrayBuffer = event.target.result as ArrayBuffer; - public chooseSaveFile(fileName: string, ext: string, mimeType: string) { - return Promise.reject(); - /* if(!window.chrome || !chrome.fileSystem || !chrome.fileSystem.chooseEntry) { - //return qSync.reject() - return Promise.reject(); - } - var deferred = $q.defer() + let arr = new Uint8Array(arrayBuffer); - chrome.fileSystem.chooseEntry({ - type: 'saveFile', - suggestedName: fileName, - accepts: [{ - mimeTypes: [mimeType], - extensions: [ext] - }] - }, function (writableFileEntry) { - deferred.resolve(writableFileEntry) - }) + fileWriter.write(arr).then(resolve, reject); + }; - return deferred.promise */ + fileReader.readAsArrayBuffer(bytes); + }); + } else { + //var blob = blobConstruct([bytesToArrayBuffer(bytes)]); + //return fileWriter.write(blob); + return fileWriter.write(bytes); + } } - - public getFileWriter(fileEntry: any) { - return new Promise((resolve, reject) => { - fileEntry.createWriter(resolve, reject); + + public chooseSaveFile(fileName: string, ext: string, mimeType: string, size?: number): any { + let fileStream = streamSaver.createWriteStream(fileName, { + size: size, + writableStrategy: undefined, + readableStrategy: undefined }); + let writer = fileStream.getWriter(); + return writer; } public getFakeFileWriter(mimeType: string, saveFileCallback: any) { var blobParts: Array = []; - var fakeFileWriter: any = { - write: (blob: Blob) => { + var fakeFileWriter = { + write: async(blob: Blob) => { if(!this.blobSupported) { - if(fakeFileWriter.onerror) { - fakeFileWriter.onerror(new Error('Blob not supported by browser')); - } - - return false; + throw false; } - + blobParts.push(blob); - setTimeout(() => { - if(fakeFileWriter.onwriteend) { - fakeFileWriter.onwriteend(); - } - }, 0); }, truncate: () => { blobParts = []; @@ -119,14 +136,14 @@ class FileManager { if(saveFileCallback) { saveFileCallback(blob); } - + return blob; } }; - + return fakeFileWriter; } - + public getUrl(fileData: any, mimeType: string) { var safeMimeType = blobSafeMimeType(mimeType); // console.log(dT(), 'get url', fileData, mimeType, fileData.toURL !== undefined, fileData instanceof Blob) @@ -138,7 +155,7 @@ class FileManager { } return 'data:' + safeMimeType + ';base64,' + bytesToBase64(fileData); } - + public getByteArray(fileData: any) { if(fileData instanceof Blob) { return new Promise((resolve, reject) => { @@ -146,7 +163,7 @@ class FileManager { var reader = new FileReader(); reader.onloadend = (e) => { // @ts-ignore - resolve(new Uint8Array(e.target.result)); + resolve(new Uint8Array(e.target.result)); }; reader.onerror = (e) => { reject(e); @@ -163,11 +180,11 @@ class FileManager { }, reject); }); } - + return Promise.resolve(fileData); //return $q.when(fileData); } - + public getDataUrl(blob: any) { return new Promise((resolve, reject) => { try { @@ -181,7 +198,7 @@ class FileManager { } }); } - + public getFileCorrectUrl(blob: any, mimeType: string) { if(this.buggyUnknownBlob && blob instanceof Blob) { // @ts-ignore @@ -190,48 +207,48 @@ class FileManager { return this.getDataUrl(blob); } } - + return Promise.resolve(this.getUrl(blob, mimeType)); } - + // downloadFile public download(blob: any, mimeType: string, fileName: string) { if(window.navigator && navigator.msSaveBlob !== undefined) { window.navigator.msSaveBlob(blob, fileName); return false; } - + if(window.navigator && 'getDeviceStorage' in navigator) { var storageName = 'sdcard'; var subdir = 'telegram/'; switch(mimeType.split('/')[0]) { case 'video': - storageName = 'videos'; - break; + storageName = 'videos'; + break; case 'audio': - storageName = 'music'; - break; + storageName = 'music'; + break; case 'image': - storageName = 'pictures'; - break; + storageName = 'pictures'; + break; } - + // @ts-ignore var deviceStorage = navigator.getDeviceStorage(storageName); var request = deviceStorage.addNamed(blob, subdir + fileName); - + request.onsuccess = function () { console.log('Device storage save result', this.result); }; request.onerror = () => {}; return; } - + var popup: Window; if(this.isSafari && !this.safariWithDownload) { popup = window.open(); } - + this.getFileCorrectUrl(blob, mimeType).then((url) => { if(popup) { try { @@ -240,7 +257,7 @@ class FileManager { return; } catch (e) {} } - + var anchor = document.createElementNS('http://www.w3.org/1999/xhtml', 'a') as HTMLAnchorElement; anchor.href = url as string; if(!this.safariWithDownload) { @@ -254,29 +271,30 @@ class FileManager { anchor.style.position = 'absolute'; anchor.style.top = '1px'; anchor.style.left = '1px'; - + document.body.append(anchor); - + try { var clickEvent = document.createEvent('MouseEvents'); clickEvent.initMouseEvent( 'click', true, false, window, 0, 0, 0, 0, 0 , false, false, false, false, 0, null - ) - anchor.dispatchEvent(clickEvent); - } catch (e) { - console.error('Download click error', e); - try { - anchor.click(); + ) + anchor.dispatchEvent(clickEvent); } catch (e) { - window.open(url as string, '_blank'); + console.error('Download click error', e); + try { + anchor.click(); + } catch (e) { + window.open(url as string, '_blank'); + } } - } - setTimeout(() => { - anchor.remove(); - }, 100); - }) + setTimeout(() => { + anchor.remove(); + }, 100); + }) + } } -} - -export default new FileManager(); + + export default new FileManager(); + \ No newline at end of file diff --git a/src/lib/lottieLoader.ts b/src/lib/lottieLoader.ts index e9d288f8..52fdec4e 100644 --- a/src/lib/lottieLoader.ts +++ b/src/lib/lottieLoader.ts @@ -1,4 +1,7 @@ -import LottiePlayer, { AnimationConfigWithPath, AnimationConfigWithData, AnimationItem } from "lottie-web"; +//import LottiePlayer, { AnimationConfigWithPath, AnimationConfigWithData, AnimationItem } from "lottie-web"; +// @ts-ignore +import LottiePlayer, { AnimationConfigWithPath, AnimationConfigWithData, AnimationItem } from "lottie-web/build/player/lottie_canvas.min.js"; +//import LottiePlayer, { AnimationConfigWithPath, AnimationConfigWithData, AnimationItem } from "lottie-web/build/player/lottie_light.min.js"; import { isElementInViewport, isInDOM } from "./utils"; class LottieLoader { diff --git a/src/lib/mtproto/apiFileManager.ts b/src/lib/mtproto/apiFileManager.ts index 7025ad7d..68d4219a 100644 --- a/src/lib/mtproto/apiFileManager.ts +++ b/src/lib/mtproto/apiFileManager.ts @@ -248,12 +248,12 @@ export class ApiFileManager { return fileStorage.getFile(fileName, size); } - public async downloadFile(dcID: number, location: any, size: number, options: { + public downloadFile(dcID: number, location: any, size: number, options: { mimeType?: string, dcID?: number, toFileEntry?: any, limitPart?: number - } = {}): Promise { + } = {}): CancellablePromise { if(!FileManager.isAvailable()) { return Promise.reject({type: 'BROWSER_BLOB_NOT_SUPPORTED'}); } @@ -288,19 +288,33 @@ export class ApiFileManager { //this.log('downloadFile cachedPromise'); if(size) { - let blob = await cachedPromise; + /* let blob = await cachedPromise; if(blob.size < size) { this.log('downloadFile need to deleteFile, wrong size:', blob.size, size); await this.deleteFile(location); } else { return cachedPromise; - } + } */ + return cachedPromise.then((blob: Blob) => { + if(blob.size < size) { + this.log('downloadFile need to deleteFile, wrong size:', blob.size, size); + + return this.deleteFile(location).then(() => { + return this.downloadFile(dcID, location, size, options); + }).catch(() => { + return this.downloadFile(dcID, location, size, options); + }); + } else { + //return cachedPromise; + return blob; + } + }); } else { return cachedPromise; } } - //this.log('arriba'); + this.log('arriba'); //var deferred = $q.defer() let deferredHelper: any = {notify: () => {}}; @@ -310,16 +324,17 @@ export class ApiFileManager { }); Object.assign(deferred, deferredHelper); + //return; + var canceled = false; var resolved = false; var mimeType = options.mimeType || 'image/jpeg', cacheFileWriter: any; var errorHandler = (error: any) => { - deferred.reject(error) + deferred.reject(error); errorHandler = () => {}; - if(cacheFileWriter && - (!error || error.type != 'DOWNLOAD_CANCELED')) { + if(cacheFileWriter && (!error || error.type != 'DOWNLOAD_CANCELED')) { cacheFileWriter.truncate(0); } }; @@ -336,14 +351,15 @@ export class ApiFileManager { if(toFileEntry) { FileManager.copy(blob, toFileEntry).then(() => { deferred.resolve(); - }, errorHandler) + }, errorHandler); } else { deferred.resolve(this.cachedDownloads[fileName] = blob); } //}, () => { }).catch(() => { //this.log('not i wanted'); - var fileWriterPromise = toFileEntry ? FileManager.getFileWriter(toFileEntry) : fileStorage.getFileWriter(fileName, mimeType); + //var fileWriterPromise = toFileEntry ? FileManager.getFileWriter(toFileEntry) : fileStorage.getFileWriter(fileName, mimeType); + var fileWriterPromise = toFileEntry ? Promise.resolve(toFileEntry) : fileStorage.getFileWriter(fileName, mimeType); var processDownloaded = (bytes: any) => { return Promise.resolve(bytes); @@ -414,7 +430,7 @@ export class ApiFileManager { return Promise.resolve(); } - return processDownloaded(result.bytes).then((processedResult) => { + return processDownloaded(result.bytes).then((processedResult: Uint8Array) => { return FileManager.write(fileWriter, processedResult).then(() => { writeFileDeferred.resolve(); }, errorHandler).then(() => { @@ -427,7 +443,7 @@ export class ApiFileManager { deferred.resolve(this.cachedDownloads[fileName] = fileWriter.finalize()); } } else { - this.log('deferred notify 2:', {done: offset + limit, total: size}); + this.log('deferred notify 2:', {done: offset + limit, total: size}, deferred); deferred.notify({done: offset + limit, total: size}); } }); @@ -449,6 +465,8 @@ export class ApiFileManager { } }; + console.log(deferred, deferred.notify, deferred.cancel); + if(!toFileEntry) { this.cachedDownloadPromises[fileName] = deferred; } diff --git a/src/scss/partials/_sidebar.scss b/src/scss/partials/_sidebar.scss index 19be8798..0fe03652 100644 --- a/src/scss/partials/_sidebar.scss +++ b/src/scss/partials/_sidebar.scss @@ -163,15 +163,17 @@ #content-docs { padding: 15px; + padding-top: 3px; .document { padding-left: 5rem; padding-right: 1rem; - height: 54px; + //height: 54px; + height: calc(54px + 1.5rem); - & + .document { + /* & + .document { margin-top: 1.5rem; - } + } */ } .document-name { diff --git a/src/scss/style.scss b/src/scss/style.scss index f82cc5b9..b0841fdd 100644 --- a/src/scss/style.scss +++ b/src/scss/style.scss @@ -61,11 +61,21 @@ button, input, optgroup, select, textarea, html { min-width: 100%; } +.container { + margin: 0 auto; +} + h1, h2, h3, h4, h5, h6 { letter-spacing: -.66px; font-weight: 500; } +h4 { + font-size: 2.28rem; + margin: 1.52rem 0 .912rem 0; + line-height: 110%; +} + input { caret-color: $button-primary-background; } @@ -388,7 +398,7 @@ input { cursor: pointer; position: relative; - .document-ico { + .document-ico, .document-download { position: absolute; left: 0; width: 54px; @@ -404,6 +414,28 @@ input { text-overflow: ellipsis; } + .document-download { + z-index: 3; + background-color: rgb(101, 161, 227); + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + font-size: 24px; + cursor: pointer; + + .tgico-download { + transform: scale(1); + transition: .2s scale; + } + + &.downloading { + .tgico-download { + transform: scale(0); + } + } + } + &:not(.photo) { .document-ico { padding-top: 1.5rem; @@ -692,7 +724,7 @@ input { text-align: left; display: grid; - grid-template-columns: 15% 65% 20%; + grid-template-columns: 15% 60% 25%; &:hover { background-color: rgba(112, 117, 121, .08); @@ -1059,6 +1091,7 @@ span.popup-close { justify-content: space-between; */ display: flex; margin-bottom: 2rem; + align-items: center; } .popup-avatar { @@ -1074,12 +1107,17 @@ span.popup-close { right: 15px; } } + + .popup-close { + font-size: 1.5rem; + } h6 { font-size: 1.1rem; text-align: left; margin: 0; margin-left: 1.5rem; + font-weight: 400; } .crop { diff --git a/webpack.dev.js b/webpack.dev.js index 72b8aa88..4d6bb453 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -6,5 +6,6 @@ module.exports = merge(common, { devtool: 'inline-source-map', devServer: { contentBase: './public', + http2: true }, -}); \ No newline at end of file +}); diff --git a/webpack.prod.js b/webpack.prod.js index 389ac391..ce8716f5 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -59,6 +59,8 @@ module.exports = merge(common, { files.forEach(file => { //console.log('to unlink 1:', file); + if(file.includes('mitm.') || file.includes('sw.js')) return; + let p = path.resolve(buildDir + file); if(!newlyCreatedAssets[file] && ['.gz', '.js'].find(ext => file.endsWith(ext)) !== undefined) {