|
|
|
/*
|
|
|
|
* https://github.com/morethanwords/tweb
|
|
|
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
|
|
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
|
|
|
*/
|
|
|
|
|
|
|
|
import MEDIA_MIME_TYPES_SUPPORTED from "../../environment/mediaMimeTypesSupport";
|
|
|
|
import { clearBadCharsAndTrim } from "../../helpers/cleanSearchText";
|
|
|
|
import { formatFullSentTime } from "../../helpers/date";
|
|
|
|
import { simulateClickEvent, attachClickEvent } from "../../helpers/dom/clickEvent";
|
|
|
|
import formatBytes from "../../helpers/formatBytes";
|
|
|
|
import { MediaSizeType } from "../../helpers/mediaSizes";
|
|
|
|
import noop from "../../helpers/noop";
|
|
|
|
import { Message, MessageMedia, WebPage } from "../../layer";
|
|
|
|
import { MyDocument } from "../../lib/appManagers/appDocsManager";
|
|
|
|
import appDownloadManager from "../../lib/appManagers/appDownloadManager";
|
|
|
|
import appImManager from "../../lib/appManagers/appImManager";
|
|
|
|
import { AppManagers } from "../../lib/appManagers/managers";
|
|
|
|
import getDownloadMediaDetails from "../../lib/appManagers/utils/download/getDownloadMediaDetails";
|
|
|
|
import choosePhotoSize from "../../lib/appManagers/utils/photos/choosePhotoSize";
|
|
|
|
import { joinElementsWith } from "../../lib/langPack";
|
|
|
|
import wrapPlainText from "../../lib/richTextProcessor/wrapPlainText";
|
|
|
|
import rootScope from "../../lib/rootScope";
|
|
|
|
import type { ThumbCache } from "../../lib/storages/thumbs";
|
|
|
|
import { MediaSearchContext } from "../appMediaPlaybackController";
|
|
|
|
import AudioElement from "../audio";
|
|
|
|
import LazyLoadQueue from "../lazyLoadQueue";
|
|
|
|
import { MiddleEllipsisElement } from "../middleEllipsis";
|
|
|
|
import ProgressivePreloader from "../preloader";
|
|
|
|
import wrapPhoto from './photo';
|
|
|
|
import wrapSenderToPeer from "./senderToPeer";
|
|
|
|
import wrapSentTime from "./sentTime";
|
|
|
|
|
|
|
|
rootScope.addEventListener('document_downloading', (docId) => {
|
|
|
|
const elements = Array.from(document.querySelectorAll(`.document[data-doc-id="${docId}"]`)) as HTMLElement[];
|
|
|
|
elements.forEach((element) => {
|
|
|
|
if(element.querySelector('.preloader-container.manual')) {
|
|
|
|
simulateClickEvent(element);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
export default async function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showSender, searchContext, loadPromises, autoDownloadSize, lazyLoadQueue, sizeType, managers = rootScope.managers, cacheContext}: {
|
|
|
|
message: Message.message,
|
|
|
|
withTime?: boolean,
|
|
|
|
fontWeight?: number,
|
|
|
|
voiceAsMusic?: boolean,
|
|
|
|
showSender?: boolean,
|
|
|
|
searchContext?: MediaSearchContext,
|
|
|
|
loadPromises?: Promise<any>[],
|
|
|
|
autoDownloadSize?: number,
|
|
|
|
lazyLoadQueue?: LazyLoadQueue,
|
|
|
|
sizeType?: MediaSizeType,
|
|
|
|
managers?: AppManagers,
|
|
|
|
cacheContext?: ThumbCache
|
|
|
|
}): Promise<HTMLElement> {
|
|
|
|
if(!fontWeight) fontWeight = 500;
|
|
|
|
if(!sizeType) sizeType = '' as any;
|
|
|
|
const noAutoDownload = autoDownloadSize === 0;
|
|
|
|
|
|
|
|
const doc = ((message.media as MessageMedia.messageMediaDocument).document || ((message.media as MessageMedia.messageMediaWebPage).webpage as WebPage.webPage).document) as MyDocument;
|
|
|
|
const uploadFileName = message?.uploadingFileName;
|
|
|
|
if(doc.type === 'audio' || doc.type === 'voice' || doc.type === 'round') {
|
|
|
|
const audioElement = new AudioElement();
|
|
|
|
audioElement.withTime = withTime;
|
|
|
|
audioElement.message = message;
|
|
|
|
audioElement.noAutoDownload = noAutoDownload;
|
|
|
|
audioElement.lazyLoadQueue = lazyLoadQueue;
|
|
|
|
audioElement.loadPromises = loadPromises;
|
|
|
|
|
|
|
|
if(voiceAsMusic) audioElement.voiceAsMusic = voiceAsMusic;
|
|
|
|
if(searchContext) audioElement.searchContext = searchContext;
|
|
|
|
if(showSender) audioElement.showSender = showSender;
|
|
|
|
|
|
|
|
audioElement.dataset.fontWeight = '' + fontWeight;
|
|
|
|
audioElement.dataset.sizeType = sizeType;
|
|
|
|
await audioElement.render();
|
|
|
|
return audioElement;
|
|
|
|
}
|
|
|
|
|
|
|
|
let extSplitted = doc.file_name ? doc.file_name.split('.') : '';
|
|
|
|
let ext = '';
|
|
|
|
ext = extSplitted.length > 1 && Array.isArray(extSplitted) ?
|
|
|
|
clearBadCharsAndTrim(extSplitted.pop().split(' ', 1)[0].toLowerCase()) :
|
|
|
|
'file';
|
|
|
|
|
|
|
|
let docDiv = document.createElement('div');
|
|
|
|
docDiv.classList.add('document', `ext-${ext}`);
|
|
|
|
docDiv.dataset.docId = '' + doc.id;
|
|
|
|
|
|
|
|
// return docDiv;
|
|
|
|
|
|
|
|
const icoDiv = document.createElement('div');
|
|
|
|
icoDiv.classList.add('document-ico');
|
|
|
|
|
|
|
|
const hadContext = !!cacheContext;
|
|
|
|
const getCacheContext = () => {
|
|
|
|
return hadContext ? cacheContext : managers.thumbsStorage.getCacheContext(doc);
|
|
|
|
};
|
|
|
|
|
|
|
|
cacheContext = await getCacheContext();
|
|
|
|
if((doc.thumbs?.length || (message.pFlags.is_outgoing && cacheContext.url && doc.type === 'photo'))/* && doc.mime_type !== 'image/gif' */) {
|
|
|
|
docDiv.classList.add('document-with-thumb');
|
|
|
|
|
|
|
|
let imgs: (HTMLImageElement | HTMLCanvasElement)[] = [];
|
|
|
|
// ! WARNING, use thumbs for check when thumb will be generated for media
|
|
|
|
if(message.pFlags.is_outgoing && ['photo', 'video'].includes(doc.type)) {
|
|
|
|
icoDiv.innerHTML = `<img src="${cacheContext.url}">`;
|
|
|
|
imgs.push(icoDiv.firstElementChild as HTMLImageElement);
|
|
|
|
} else {
|
|
|
|
const perf = performance.now();
|
|
|
|
const wrapped = await wrapPhoto({
|
|
|
|
photo: doc,
|
|
|
|
message: null,
|
|
|
|
container: icoDiv,
|
|
|
|
boxWidth: 54,
|
|
|
|
boxHeight: 54,
|
|
|
|
loadPromises,
|
|
|
|
withoutPreloader: true,
|
|
|
|
lazyLoadQueue,
|
|
|
|
size: choosePhotoSize(doc, 54, 54, true),
|
|
|
|
managers
|
|
|
|
});
|
|
|
|
// console.log('was wrapping photo', performance.now() - perf);
|
|
|
|
icoDiv.style.width = icoDiv.style.height = '';
|
|
|
|
if(wrapped.images.thumb) imgs.push(wrapped.images.thumb);
|
|
|
|
if(wrapped.images.full) imgs.push(wrapped.images.full);
|
|
|
|
}
|
|
|
|
|
|
|
|
imgs.forEach((img) => img.classList.add('document-thumb'));
|
|
|
|
} else {
|
|
|
|
icoDiv.innerText = ext;
|
|
|
|
}
|
|
|
|
|
|
|
|
//let fileName = stringMiddleOverflow(doc.file_name || 'Unknown.file', 26);
|
|
|
|
let fileName = doc.file_name ? wrapPlainText(doc.file_name) : 'Unknown.file';
|
|
|
|
const descriptionEl = document.createElement('div');
|
|
|
|
descriptionEl.classList.add('document-description');
|
|
|
|
const descriptionParts: (HTMLElement | string | DocumentFragment)[] = [formatBytes(doc.size)];
|
|
|
|
|
|
|
|
if(withTime) {
|
|
|
|
descriptionParts.push(formatFullSentTime(message.date));
|
|
|
|
}
|
|
|
|
|
|
|
|
if(showSender) {
|
|
|
|
descriptionParts.push(await wrapSenderToPeer(message));
|
|
|
|
}
|
|
|
|
|
|
|
|
docDiv.innerHTML = `
|
|
|
|
${(cacheContext.downloaded && !uploadFileName) || !message.mid ? '' : `<div class="document-download"></div>`}
|
|
|
|
<div class="document-name"></div>
|
|
|
|
<div class="document-size"></div>
|
|
|
|
`;
|
|
|
|
|
|
|
|
const nameDiv = docDiv.querySelector('.document-name') as HTMLElement;
|
|
|
|
const middleEllipsisEl = new MiddleEllipsisElement();
|
|
|
|
middleEllipsisEl.dataset.fontWeight = '' + fontWeight;
|
|
|
|
middleEllipsisEl.dataset.sizeType = sizeType;
|
|
|
|
middleEllipsisEl.textContent = fileName;
|
|
|
|
// setInnerHTML(middleEllipsisEl, fileName);
|
|
|
|
|
|
|
|
nameDiv.append(middleEllipsisEl);
|
|
|
|
|
|
|
|
if(showSender) {
|
|
|
|
nameDiv.append(wrapSentTime(message));
|
|
|
|
}
|
|
|
|
|
|
|
|
const sizeDiv = docDiv.querySelector('.document-size') as HTMLElement;
|
|
|
|
sizeDiv.append(...joinElementsWith(descriptionParts, ' · '));
|
|
|
|
|
|
|
|
docDiv.prepend(icoDiv);
|
|
|
|
|
|
|
|
if(!uploadFileName && message.pFlags.is_outgoing && !message.mid) {
|
|
|
|
return docDiv;
|
|
|
|
}
|
|
|
|
|
|
|
|
let downloadDiv: HTMLElement, preloader: ProgressivePreloader = null;
|
|
|
|
const onLoad = () => {
|
|
|
|
if(downloadDiv) {
|
|
|
|
downloadDiv.classList.add('downloaded');
|
|
|
|
const _downloadDiv = downloadDiv;
|
|
|
|
setTimeout(() => {
|
|
|
|
_downloadDiv.remove();
|
|
|
|
}, 200);
|
|
|
|
downloadDiv = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(preloader) {
|
|
|
|
preloader = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const load = async(e?: Event) => {
|
|
|
|
const save = !e || e.isTrusted;
|
|
|
|
const doc = await managers.appDocsManager.getDoc(docDiv.dataset.docId);
|
|
|
|
let download: Promise<any>;
|
|
|
|
const queueId = appImManager.chat.bubbles ? appImManager.chat.bubbles.lazyLoadQueue.queueId : undefined;
|
|
|
|
if(!save) {
|
|
|
|
download = appDownloadManager.downloadMediaVoid({media: doc, queueId});
|
|
|
|
} else if(doc.type === 'pdf') {
|
|
|
|
const canOpenAfter = /* managers.appDocsManager.downloading.has(doc.id) || */!preloader || preloader.detached;
|
|
|
|
download = appDownloadManager.downloadMediaURL({media: doc, queueId});
|
|
|
|
if(canOpenAfter) {
|
|
|
|
download.then(() => {
|
|
|
|
setTimeout(async() => { // wait for preloader animation end
|
|
|
|
const url = (await getCacheContext()).url;
|
|
|
|
window.open(url);
|
|
|
|
}, rootScope.settings.animationsEnabled ? 250 : 0);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} else if(MEDIA_MIME_TYPES_SUPPORTED.has(doc.mime_type) && doc.thumbs?.length) {
|
|
|
|
download = appDownloadManager.downloadMediaURL({media: doc, queueId});
|
|
|
|
} else {
|
|
|
|
download = appDownloadManager.downloadToDisc({media: doc, queueId});
|
|
|
|
}
|
|
|
|
|
|
|
|
if(downloadDiv) {
|
|
|
|
download.then(onLoad, noop);
|
|
|
|
preloader.attach(downloadDiv, true, download);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const {fileName: downloadFileName} = getDownloadMediaDetails({media: doc});
|
|
|
|
if(await managers.apiFileManager.isDownloading(downloadFileName)) {
|
|
|
|
downloadDiv = docDiv.querySelector('.document-download');
|
|
|
|
const promise = appDownloadManager.downloadMediaVoid({media: doc});
|
|
|
|
|
|
|
|
preloader = new ProgressivePreloader();
|
|
|
|
preloader.attach(downloadDiv, false, promise);
|
|
|
|
preloader.setDownloadFunction(load);
|
|
|
|
} else if(!cacheContext.downloaded || uploadFileName) {
|
|
|
|
downloadDiv = docDiv.querySelector('.document-download');
|
|
|
|
preloader = new ProgressivePreloader({
|
|
|
|
isUpload: !!uploadFileName
|
|
|
|
});
|
|
|
|
|
|
|
|
if(!uploadFileName) {
|
|
|
|
preloader.construct();
|
|
|
|
preloader.setManual();
|
|
|
|
preloader.attach(downloadDiv);
|
|
|
|
preloader.setDownloadFunction(load);
|
|
|
|
|
|
|
|
if(autoDownloadSize !== undefined && autoDownloadSize >= doc.size) {
|
|
|
|
simulateClickEvent(preloader.preloader);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const uploadPromise = appDownloadManager.getUpload(uploadFileName);
|
|
|
|
preloader.attachPromise(uploadPromise);
|
|
|
|
preloader.attach(downloadDiv);
|
|
|
|
uploadPromise.then(onLoad, noop);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
attachClickEvent(docDiv, (e) => {
|
|
|
|
if(preloader) {
|
|
|
|
preloader.onClick(e);
|
|
|
|
} else {
|
|
|
|
load(e);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return docDiv;
|
|
|
|
}
|