webpage title & file downloads & progress bars
This commit is contained in:
parent
b2ddf3dd0a
commit
427718d852
19
package-lock.json
generated
19
package-lock.json
generated
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 = `
|
||||
<div class="document-ico ext-${ext}">${ext2}</div>
|
||||
<div class="document-download"><div class="tgico-download"></div></div>
|
||||
<div class="document-name">${fileName}</div>
|
||||
<div class="document-size">${size}</div>
|
||||
`;
|
||||
|
||||
let downloadDiv = docDiv.querySelector('.document-download') as HTMLDivElement;
|
||||
let preloader: ProgressivePreloader;
|
||||
let promise: CancellablePromise<Blob>;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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<Blob> {
|
||||
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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<void> {
|
||||
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();
|
||||
let arr = new Uint8Array(arrayBuffer);
|
||||
|
||||
fileWriter.write(arr).then(resolve, reject);
|
||||
};
|
||||
|
||||
fileReader.readAsArrayBuffer(bytes);
|
||||
});
|
||||
} else {
|
||||
//var blob = blobConstruct([bytesToArrayBuffer(bytes)]);
|
||||
//return fileWriter.write(blob);
|
||||
return fileWriter.write(bytes);
|
||||
}
|
||||
var deferred = $q.defer()
|
||||
|
||||
chrome.fileSystem.chooseEntry({
|
||||
type: 'saveFile',
|
||||
suggestedName: fileName,
|
||||
accepts: [{
|
||||
mimeTypes: [mimeType],
|
||||
extensions: [ext]
|
||||
}]
|
||||
}, function (writableFileEntry) {
|
||||
deferred.resolve(writableFileEntry)
|
||||
})
|
||||
|
||||
return deferred.promise */
|
||||
}
|
||||
|
||||
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<Blob> = [];
|
||||
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();
|
||||
|
@ -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 {
|
||||
|
@ -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<Blob> {
|
||||
} = {}): CancellablePromise<Blob> {
|
||||
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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -6,5 +6,6 @@ module.exports = merge(common, {
|
||||
devtool: 'inline-source-map',
|
||||
devServer: {
|
||||
contentBase: './public',
|
||||
http2: true
|
||||
},
|
||||
});
|
||||
});
|
||||
|
@ -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) {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user