Telegram Web K with changes to work inside I2P https://web.telegram.i2p/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

282 lines
8.0 KiB

import apiFileManager from '../mtproto/apiFileManager';
5 years ago
import FileManager from '../filemanager';
import {RichTextProcessor} from '../richtextprocessor';
import { CancellablePromise } from '../polyfill';
import { MTDocument } from '../../components/wrappers';
5 years ago
class AppDocsManager {
private docs: {[docID: string]: MTDocument} = {};
5 years ago
public saveDoc(apiDoc: MTDocument/* any */, context?: any) {
5 years ago
console.log('saveDoc', apiDoc, this.docs[apiDoc.id]);
if(this.docs[apiDoc.id]) {
let d = this.docs[apiDoc.id];
5 years ago
if(apiDoc.thumbs) {
if(!d.thumbs) d.thumbs = apiDoc.thumbs;
else if(apiDoc.thumbs[0].bytes && !d.thumbs[0].bytes) {
d.thumbs.unshift(apiDoc.thumbs[0]);
}
}
return context ? Object.assign(d, context) : d;
}
5 years ago
if(context) {
5 years ago
Object.assign(apiDoc, context);
}
this.docs[apiDoc.id] = apiDoc;
5 years ago
if(apiDoc.thumb && apiDoc.thumb._ == 'photoCachedSize') {
console.warn('this will happen!!!');
5 years ago
apiFileManager.saveSmallFile(apiDoc.thumb.location, apiDoc.thumb.bytes);
// Memory
apiDoc.thumb.size = apiDoc.thumb.bytes.length;
delete apiDoc.thumb.bytes;
apiDoc.thumb._ = 'photoSize';
}
if(apiDoc.thumb && apiDoc.thumb._ == 'photoSizeEmpty') {
delete apiDoc.thumb;
}
apiDoc.attributes.forEach((attribute: any) => {
switch(attribute._) {
case 'documentAttributeFilename':
apiDoc.file_name = RichTextProcessor.wrapPlainText(attribute.file_name);
5 years ago
break;
case 'documentAttributeAudio':
apiDoc.duration = attribute.duration;
apiDoc.audioTitle = attribute.title;
apiDoc.audioPerformer = attribute.performer;
apiDoc.type = attribute.pFlags.voice ? 'voice' : 'audio';
5 years ago
break;
case 'documentAttributeVideo':
apiDoc.duration = attribute.duration;
apiDoc.w = attribute.w;
apiDoc.h = attribute.h;
if(apiDoc.thumbs && attribute.pFlags.round_message) {
apiDoc.type = 'round';
} else /* if(apiDoc.thumbs) */ {
5 years ago
apiDoc.type = 'video';
}
break;
case 'documentAttributeSticker':
apiDoc.sticker = true;
if(attribute.alt !== undefined) {
apiDoc.stickerEmojiRaw = attribute.alt;
apiDoc.stickerEmoji = RichTextProcessor.wrapRichText(apiDoc.stickerEmojiRaw, {noLinks: true, noLinebreaks: true});
}
if(attribute.stickerset) {
if(attribute.stickerset._ == 'inputStickerSetEmpty') {
delete attribute.stickerset;
5 years ago
} else if(attribute.stickerset._ == 'inputStickerSetID') {
apiDoc.stickerSetInput = attribute.stickerset;
5 years ago
}
}
if(apiDoc.thumbs && apiDoc.mime_type == 'image/webp') {
apiDoc.type = 'sticker';
5 years ago
} else if(apiDoc.mime_type == 'application/x-tgsticker') {
apiDoc.type = 'sticker';
apiDoc.animated = true;
}
break;
case 'documentAttributeImageSize':
apiDoc.w = attribute.w;
apiDoc.h = attribute.h;
break;
case 'documentAttributeAnimated':
if((apiDoc.mime_type == 'image/gif' || apiDoc.mime_type == 'video/mp4') && apiDoc.thumbs) {
apiDoc.type = 'gif';
}
apiDoc.animated = true;
break;
}
});
if(!apiDoc.mime_type) {
switch(apiDoc.type) {
case 'gif':
apiDoc.mime_type = 'video/mp4';
break;
case 'video':
case 'round':
apiDoc.mime_type = 'video/mp4';
break;
case 'sticker':
apiDoc.mime_type = 'image/webp';
break;
5 years ago
case 'audio':
apiDoc.mime_type = 'audio/mpeg';
break;
5 years ago
case 'voice':
apiDoc.mime_type = 'audio/ogg';
break;
5 years ago
default:
apiDoc.mime_type = 'application/octet-stream';
break;
5 years ago
}
}
if(!apiDoc.file_name) {
apiDoc.file_name = '';
5 years ago
}
if(apiDoc._ == 'documentEmpty') {
apiDoc.size = 0;
}
5 years ago
return apiDoc;
5 years ago
}
public getDoc(docID: string) {
return this.docs[docID] || {_: 'documentEmpty'};
}
public getFileName(doc: MTDocument) {
if(doc.file_name) {
return doc.file_name;
5 years ago
}
var fileExt = '.' + doc.mime_type.split('/')[1];
if(fileExt == '.octet-stream') {
fileExt = '';
5 years ago
}
return 't_' + (doc.type || 'file') + doc.id + fileExt;
5 years ago
}
public updateDocDownloaded(docID: string) {
var doc = this.docs[docID];
var inputFileLocation = {
_: 'inputDocumentFileLocation',
id: docID,
access_hash: doc.access_hash,
version: doc.version,
file_name: this.getFileName(doc)
};
if(doc.downloaded === undefined) {
apiFileManager.getDownloadedFile(inputFileLocation, doc.size).then(() => {
doc.downloaded = true;
}, () => {
doc.downloaded = false;
});
}
}
public downloadDoc(docID: string | MTDocument, toFileEntry?: any): CancellablePromise<Blob> {
let doc: MTDocument;
5 years ago
if(typeof(docID) === 'string') {
doc = this.docs[docID];
} else {
doc = docID;
}
var inputFileLocation = {
_: 'inputDocumentFileLocation',
id: doc.id,
access_hash: doc.access_hash,
file_reference: doc.file_reference,
thumb_size: '',
version: doc.version,
file_name: this.getFileName(doc)
};
if(doc._ == 'documentEmpty') {
return Promise.reject();
}
if(doc.downloaded && !toFileEntry) {
var cachedBlob = apiFileManager.getCachedFile(inputFileLocation);
if(cachedBlob) {
return Promise.resolve(cachedBlob);
}
}
//historyDoc.progress = {enabled: !historyDoc.downloaded, percent: 1, total: doc.size};
// нет смысла делать объект с выполняющимися промисами, нижняя строка и так вернёт загружающийся
var downloadPromise: CancellablePromise<Blob> = apiFileManager.downloadFile(doc.dc_id, inputFileLocation, doc.size, {
mimeType: doc.mime_type || 'application/octet-stream',
toFileEntry: toFileEntry
});
downloadPromise.then((blob) => {
if(blob) {
doc.downloaded = true;
if(/* !doc.animated || */doc.type != 'sticker') {
doc.url = FileManager.getFileCorrectUrl(blob, doc.mime_type);
}
5 years ago
}
/* doc.progress.percent = 100;
setTimeout(() => {
delete doc.progress;
}, 0); */
// console.log('file save done')
return blob;
}, (e) => {
console.log('document download failed', e);
//historyDoc.progress.enabled = false;
});
/* downloadPromise.notify = (progress) => {
console.log('dl progress', progress);
historyDoc.progress.enabled = true;
historyDoc.progress.done = progress.done;
historyDoc.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total));
$rootScope.$broadcast('history_update');
}; */
//historyDoc.progress.cancel = downloadPromise.cancel;
//console.log('return downloadPromise:', downloadPromise);
5 years ago
return downloadPromise;
}
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);
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};
} catch(err) {
let promise = this.downloadDoc(docID);
promise.then((blob) => {
5 years ago
FileManager.download(blob, doc.mime_type, fileName)
});
return {promise};
}
}
5 years ago
}
export default new AppDocsManager();