tweb/src/components/wrappers.ts

865 lines
26 KiB
TypeScript
Raw Normal View History

import appPhotosManager, {MyPhoto} from '../lib/appManagers/appPhotosManager';
import LottieLoader from '../lib/lottieLoader';
import appDocsManager, { MyDocument } from "../lib/appManagers/appDocsManager";
import { formatBytes, getEmojiToneIndex, isInDOM } from "../lib/utils";
import ProgressivePreloader from './preloader';
import LazyLoadQueue from './lazyLoadQueue';
import VideoPlayer from '../lib/mediaPlayer';
2020-02-15 19:08:26 +01:00
import { RichTextProcessor } from '../lib/richtextprocessor';
import { renderImageFromUrl } from './misc';
2020-05-01 23:28:40 +02:00
import appMessagesManager from '../lib/appManagers/appMessagesManager';
import { Layouter, RectPart } from './groupedLayout';
2020-05-09 14:02:07 +02:00
import PollElement from './poll';
import animationIntersector from './animationIntersector';
import AudioElement from './audio';
import { DownloadBlob } from '../lib/appManagers/appDownloadManager';
import webpWorkerController from '../lib/webp/webpWorkerController';
import { readBlobAsText } from '../helpers/blob';
import appMediaPlaybackController from './appMediaPlaybackController';
import { PhotoSize } from '../layer';
import { deferredPromise } from '../helpers/cancellablePromise';
import mediaSizes from '../helpers/mediaSizes';
import { isSafari } from '../helpers/userAgent';
export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTail, isOut, middleware, lazyLoadQueue, noInfo, group}: {
doc: MyDocument,
container?: HTMLDivElement,
message?: any,
boxWidth?: number,
boxHeight?: number,
withTail?: boolean,
isOut?: boolean,
middleware?: () => boolean,
lazyLoadQueue?: LazyLoadQueue,
noInfo?: true,
group?: string,
}) {
if(!noInfo) {
if(doc.type != 'round') {
let span: HTMLSpanElement, spanPlay: HTMLSpanElement;
span = document.createElement('span');
span.classList.add('video-time');
container.append(span);
if(doc.type != 'gif') {
span.innerText = (doc.duration + '').toHHMMSS(false);
spanPlay = document.createElement('span');
spanPlay.classList.add('video-play', 'tgico-largeplay', 'btn-circle', 'position-center');
container.append(spanPlay);
} else {
span.innerText = 'GIF';
}
2020-06-16 22:48:08 +02:00
}
}
if(doc.mime_type == 'image/gif') {
return wrapPhoto(doc, message, container, boxWidth, boxHeight, withTail, isOut, lazyLoadQueue, middleware);
}
/* const video = doc.type == 'round' ? appMediaPlaybackController.addMedia(doc, message.mid) as HTMLVideoElement : document.createElement('video');
if(video.parentElement) {
video.remove();
} */
const video = document.createElement('video');
video.muted = true;
video.setAttribute('playsinline', '');
if(doc.type == 'round') {
//video.muted = true;
const globalVideo = appMediaPlaybackController.addMedia(doc, message.mid);
video.addEventListener('canplay', () => {
if(globalVideo.currentTime > 0) {
video.currentTime = globalVideo.currentTime;
}
if(!globalVideo.paused) {
// с закоментированными настройками - хром выключал видео при скролле, для этого нужно было включить видео - выйти из диалога, зайти заново и проскроллить вверх
/* video.autoplay = true;
video.loop = false; */
video.play();
}
}, {once: true});
const clear = () => {
//console.log('clearing video');
globalVideo.removeEventListener('timeupdate', onTimeUpdate);
globalVideo.removeEventListener('play', onGlobalPlay);
globalVideo.removeEventListener('pause', onGlobalPause);
video.removeEventListener('play', onVideoPlay);
video.removeEventListener('pause', onVideoPause);
};
const onTimeUpdate = () => {
if(!isInDOM(video)) {
clear();
}
};
const onGlobalPlay = () => {
video.play();
};
const onGlobalPause = () => {
video.pause();
};
const onVideoPlay = () => {
globalVideo.play();
};
const onVideoPause = () => {
//console.log('video pause event');
if(isInDOM(video)) {
globalVideo.pause();
} else {
clear();
}
};
globalVideo.addEventListener('timeupdate', onTimeUpdate);
globalVideo.addEventListener('play', onGlobalPlay);
globalVideo.addEventListener('pause', onGlobalPause);
video.addEventListener('play', onVideoPlay);
video.addEventListener('pause', onVideoPause);
} else {
video.autoplay = true; // для safari
}
let img: HTMLImageElement;
if(message) {
2020-08-28 17:11:25 +02:00
if(doc.type == 'video' && doc.thumbs?.length) {
return wrapPhoto(doc, message, container, boxWidth, boxHeight, withTail, isOut, lazyLoadQueue, middleware);
}
if(withTail) {
img = wrapMediaWithTail(doc, message, container, boxWidth, boxHeight, isOut);
} else {
if(boxWidth && boxHeight) { // !album
appPhotosManager.setAttachmentSize(doc, container, boxWidth, boxHeight, false, true);
}
if(doc.thumbs?.length && 'bytes' in doc.thumbs[0]) {
appPhotosManager.setAttachmentPreview(doc.thumbs[0].bytes, container, false);
}
img = container.lastElementChild as HTMLImageElement;
if(img?.tagName != 'IMG') {
container.append(img = new Image());
}
2020-04-08 17:46:43 +02:00
}
if(img) {
img.classList.add('thumbnail');
}
if(withTail) {
const foreignObject = img.parentElement;
video.width = +foreignObject.getAttributeNS(null, 'width');
video.height = +foreignObject.getAttributeNS(null, 'height');
foreignObject.append(video);
2020-04-08 17:46:43 +02:00
}
}
2020-04-08 17:46:43 +02:00
if(!img?.parentElement) {
const gotThumb = appDocsManager.getThumb(doc, false);
if(gotThumb) {
gotThumb.promise.then(() => {
video.poster = gotThumb.thumb.url;
});
}
}
2020-06-16 22:48:08 +02:00
if(!video.parentElement && container) {
container.append(video);
2020-04-08 17:46:43 +02:00
}
const loadVideo = async() => {
if(middleware && !middleware()) {
return;
}
let preloader: ProgressivePreloader;
if(message?.media?.preloader) { // means upload
preloader = message.media.preloader as ProgressivePreloader;
preloader.attach(container, undefined, undefined, true);
} else if(!doc.downloaded && !doc.supportsStreaming) {
const promise = appDocsManager.downloadDocNew(doc);
preloader = new ProgressivePreloader(container, true);
preloader.attach(container, true, promise, true);
/* video.addEventListener('canplay', () => {
if(preloader) {
preloader.detach();
}
}, {once: true}); */
2020-06-16 22:48:08 +02:00
await promise;
2020-08-26 18:14:23 +02:00
} else if(doc.supportsStreaming) {
preloader = new ProgressivePreloader(container, false);
video.addEventListener('canplay', () => {
preloader.detach();
}, {once: true});
}
2020-04-08 17:46:43 +02:00
if(middleware && !middleware()) {
return;
}
2020-04-08 17:46:43 +02:00
//console.log('loaded doc:', doc, doc.url, container);
2020-06-16 22:48:08 +02:00
const deferred = deferredPromise<void>();
//if(doc.type == 'gif'/* || true */) {
2020-06-16 22:48:08 +02:00
video.addEventListener('canplay', () => {
if(img?.parentElement) {
2020-06-16 22:48:08 +02:00
img.remove();
}
/* if(!video.paused) {
video.pause();
} */
if(doc.type == 'gif' && group) {
animationIntersector.addAnimation(video, group);
}
// test lazyLoadQueue
//setTimeout(() => {
deferred.resolve();
//}, 5000);
2020-06-16 22:48:08 +02:00
}, {once: true});
//}
video.addEventListener('error', deferred.reject);
//if(doc.type != 'round') {
renderImageFromUrl(video, doc.url);
//}
2020-06-16 22:48:08 +02:00
/* if(!container.parentElement) {
container.append(video);
} */
2020-06-16 22:48:08 +02:00
if(doc.type == 'gif'/* || true */) {
video.muted = true;
video.loop = true;
//video.play();
video.autoplay = true;
} else if(doc.type == 'round') {
video.dataset.ckin = 'circle';
video.dataset.overlay = '1';
new VideoPlayer(video);
}
return deferred;
};
2020-06-16 22:48:08 +02:00
/* if(doc.size >= 20e6 && !doc.downloaded) {
let downloadDiv = document.createElement('div');
downloadDiv.classList.add('download');
let span = document.createElement('span');
span.classList.add('btn-circle', 'tgico-download');
downloadDiv.append(span);
downloadDiv.addEventListener('click', () => {
downloadDiv.remove();
loadVideo();
});
container.prepend(downloadDiv);
return;
2020-06-16 22:48:08 +02:00
} */
return /* doc.downloaded || */!lazyLoadQueue/* && false */ ? loadVideo() : (lazyLoadQueue.push({div: container, load: loadVideo/* , wasSeen: true */}), Promise.resolve());
}
export const formatDate = (timestamp: number, monthShort = false, withYear = true) => {
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'Octomber', 'November', 'December'];
const date = new Date(timestamp * 1000);
let month = months[date.getMonth()];
if(monthShort) month = month.slice(0, 3);
let str = month + ' ' + date.getDate();
if(withYear) {
str += ', ' + date.getFullYear();
}
return str + ' at ' + date.getHours() + ':' + ('0' + date.getMinutes()).slice(-2);
};
export function wrapDocument(doc: MyDocument, withTime = false, uploading = false, mid?: number): HTMLElement {
if(doc.type == 'audio' || doc.type == 'voice') {
return wrapAudio(doc, withTime, mid);
}
let extSplitted = doc.file_name ? doc.file_name.split('.') : '';
let ext = '';
ext = extSplitted.length > 1 && Array.isArray(extSplitted) ? extSplitted.pop().toLowerCase() : 'file';
let docDiv = document.createElement('div');
docDiv.classList.add('document', `ext-${ext}`);
const icoDiv = document.createElement('div');
icoDiv.classList.add('document-ico');
if(doc.type == 'photo') {
docDiv.classList.add('photo');
if(uploading) {
icoDiv.innerHTML = `<img src="${doc.url}">`;
} else {
wrapPhoto(doc, null, icoDiv, 54, 54, false, null, null, null);
icoDiv.style.width = icoDiv.style.height = '';
}
const img = icoDiv.querySelector('img');
if(img) img.classList.add('document-thumb');
} else {
icoDiv.innerText = ext;
}
let fileName = doc.file_name || 'Unknown.file';
let size = formatBytes(doc.size);
if(withTime) {
size += ' · ' + formatDate(doc.date);
}
docDiv.innerHTML = `
2020-02-15 20:03:27 +01:00
${!uploading ? `<div class="document-download"><div class="tgico-download"></div></div>` : ''}
<div class="document-name">${fileName}</div>
<div class="document-size">${size}</div>
`;
docDiv.prepend(icoDiv);
2020-02-15 20:03:27 +01:00
if(!uploading) {
let downloadDiv = docDiv.querySelector('.document-download') as HTMLDivElement;
let preloader: ProgressivePreloader;
let download: DownloadBlob;
2020-02-15 20:03:27 +01:00
docDiv.addEventListener('click', () => {
if(!download) {
2020-02-15 20:03:27 +01:00
if(downloadDiv.classList.contains('downloading')) {
return; // means not ready yet
}
2020-02-15 19:08:26 +01:00
2020-02-15 20:03:27 +01:00
if(!preloader) {
preloader = new ProgressivePreloader(null, true);
2020-02-15 20:03:27 +01:00
}
download = appDocsManager.saveDocFile(doc);
preloader.attach(downloadDiv, true, download);
2020-02-15 19:08:26 +01:00
download.then(() => {
downloadDiv.remove();
}).catch(err => {
if(err.name === 'AbortError') {
download = null;
}
}).finally(() => {
downloadDiv.classList.remove('downloading');
});
2020-02-15 20:03:27 +01:00
downloadDiv.classList.add('downloading');
} else {
download.cancel();
2020-02-15 20:03:27 +01:00
}
});
}
return docDiv;
}
export function wrapAudio(doc: MyDocument, withTime = false, mid?: number): HTMLElement {
let elem = new AudioElement();
elem.setAttribute('doc-id', doc.id);
elem.setAttribute('with-time', '' + +withTime);
elem.setAttribute('message-id', '' + mid);
return elem;
}
function wrapMediaWithTail(photo: MyPhoto | MyDocument, message: {mid: number, message: string}, container: HTMLDivElement, boxWidth: number, boxHeight: number, isOut: boolean) {
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
2020-04-08 17:46:43 +02:00
svg.classList.add('bubble__media-container', isOut ? 'is-out' : 'is-in');
const foreignObject = document.createElementNS("http://www.w3.org/2000/svg", 'foreignObject');
2020-04-08 17:46:43 +02:00
appPhotosManager.setAttachmentSize(photo, foreignObject, boxWidth, boxHeight/* , false, true */);
const width = +foreignObject.getAttributeNS(null, 'width');
const height = +foreignObject.getAttributeNS(null, 'height');
svg.setAttributeNS(null, 'width', '' + width);
svg.setAttributeNS(null, 'height', '' + height);
2020-04-14 17:46:31 +02:00
svg.setAttributeNS(null, 'viewBox', '0 0 ' + width + ' ' + height);
svg.setAttributeNS(null, 'preserveAspectRatio', 'none');
const clipID = 'clip' + message.mid;
2020-04-08 17:46:43 +02:00
svg.dataset.clipID = clipID;
const defs = document.createElementNS("http://www.w3.org/2000/svg", 'defs');
2020-04-14 17:46:31 +02:00
let clipPathHTML: string = '';
2020-04-08 17:46:43 +02:00
if(message.message) {
//clipPathHTML += `<rect width="${width}" height="${height}"></rect>`;
} else {
if(isOut) {
clipPathHTML += `
<use href="#message-tail" transform="translate(${width - 2}, ${height}) scale(-1, -1)"></use>
<path />
`;
} else {
clipPathHTML += `
<use href="#message-tail" transform="translate(2, ${height}) scale(1, -1)"></use>
<path />
`;
}
}
2020-04-14 17:46:31 +02:00
2020-04-08 17:46:43 +02:00
defs.innerHTML = `<clipPath id="${clipID}">${clipPathHTML}</clipPath>`;
container.style.width = parseInt(container.style.width) - 9 + 'px';
container.classList.add('with-tail');
svg.append(defs, foreignObject);
container.append(svg);
let img = foreignObject.firstElementChild as HTMLImageElement;
if(!img) {
foreignObject.append(img = new Image());
}
2020-04-08 17:46:43 +02:00
return img;
2020-04-08 17:46:43 +02:00
}
export function wrapPhoto(photo: MyPhoto | MyDocument, message: any, container: HTMLDivElement, boxWidth = mediaSizes.active.regular.width, boxHeight = mediaSizes.active.regular.height, withTail: boolean, isOut: boolean, lazyLoadQueue: LazyLoadQueue, middleware: () => boolean, size: PhotoSize = null) {
let image: HTMLImageElement;
2020-04-08 17:46:43 +02:00
if(withTail) {
image = wrapMediaWithTail(photo, message, container, boxWidth, boxHeight, isOut);
} else {
if(boxWidth && boxHeight) { // !album
size = appPhotosManager.setAttachmentSize(photo, container, boxWidth, boxHeight, false, true);
}
if(photo._ == 'document' || !photo.downloaded) {
const thumbs = (photo as MyPhoto).sizes || (photo as MyDocument).thumbs;
if(thumbs?.length && 'bytes' in thumbs[0]) {
appPhotosManager.setAttachmentPreview(thumbs[0].bytes, container, false);
}
2020-05-01 23:28:40 +02:00
}
image = container.lastElementChild as HTMLImageElement;
if(!image || image.tagName != 'IMG') {
container.append(image = new Image());
2020-04-08 17:46:43 +02:00
}
}
2020-04-14 17:46:31 +02:00
//console.log('wrapPhoto downloaded:', photo, photo.downloaded, container);
2020-04-14 17:46:31 +02:00
const cacheContext = appPhotosManager.getCacheContext(photo);
2020-04-14 17:46:31 +02:00
let preloader: ProgressivePreloader;
if(message?.media?.preloader) { // means upload
2020-05-01 23:28:40 +02:00
message.media.preloader.attach(container);
} else if(!cacheContext.downloaded) {
2020-05-01 23:28:40 +02:00
preloader = new ProgressivePreloader(container, false);
}
const load = () => {
const promise = photo._ == 'document' && photo.animated ? appDocsManager.downloadDocNew(photo) : appPhotosManager.preloadPhoto(photo, size);
2020-04-14 17:46:31 +02:00
if(preloader) {
preloader.attach(container, true, promise);
}
return promise.then(() => {
if(middleware && !middleware()) return;
renderImageFromUrl(image || container, cacheContext.url || photo.url);
});
};
return cacheContext.downloaded || !lazyLoadQueue ? load() : (lazyLoadQueue.push({div: container, load: load, wasSeen: true}), Promise.resolve());
}
export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, onlyThumb, emoji, width, height, withThumb, loop}: {
doc: MyDocument,
div: HTMLDivElement,
middleware?: () => boolean,
lazyLoadQueue?: LazyLoadQueue,
group?: string,
play?: boolean,
onlyThumb?: boolean,
emoji?: string,
width?: number,
height?: number,
withThumb?: boolean,
loop?: boolean
}) {
const stickerType = doc.sticker;
2020-04-14 17:46:31 +02:00
if(!width) {
width = !emoji ? 200 : undefined;
}
if(!height) {
height = !emoji ? 200 : undefined;
}
2020-04-14 17:46:31 +02:00
if(stickerType == 2 && !LottieLoader.loaded) {
//LottieLoader.loadLottie();
LottieLoader.loadLottieWorkers();
2020-04-14 17:46:31 +02:00
}
if(!stickerType) {
2020-05-09 14:02:07 +02:00
console.error('wrong doc for wrapSticker!', doc);
throw new Error('wrong doc for wrapSticker!');
}
div.dataset.docID = doc.id;
2020-05-09 14:02:07 +02:00
//console.log('wrap sticker', doc, div, onlyThumb);
const toneIndex = emoji ? getEmojiToneIndex(emoji) : -1;
if(doc.thumbs?.length && !div.firstElementChild && (!doc.downloaded || stickerType == 2 || onlyThumb) && toneIndex <= 0/* && doc.thumbs[0]._ != 'photoSizeEmpty' */) {
const thumb = doc.thumbs[0];
2020-04-08 17:46:43 +02:00
//console.log('wrap sticker', thumb, div);
let img: HTMLImageElement;
const afterRender = () => {
if(!div.childElementCount) {
div.append(img);
}
};
if('url' in thumb) {
img = new Image();
renderImageFromUrl(img, thumb.url, afterRender);
} else if('bytes' in thumb) {
img = new Image();
if((!isSafari || doc.pFlags.stickerThumbConverted || thumb.url)/* && false */) {
renderImageFromUrl(img, appPhotosManager.getPreviewURLFromThumb(thumb, true), afterRender);
} else {
webpWorkerController.convert(doc.id, thumb.bytes as Uint8Array).then(bytes => {
thumb.bytes = bytes;
doc.pFlags.stickerThumbConverted = true;
if(middleware && !middleware()) return;
if(!div.childElementCount) {
renderImageFromUrl(img, appPhotosManager.getPreviewURLFromThumb(thumb, true), afterRender);
}
}).catch(() => {});
}
} else if(stickerType == 2 && (withThumb || onlyThumb)) {
img = new Image();
const load = () => {
2020-06-16 22:48:08 +02:00
if(div.childElementCount || (middleware && !middleware())) return;
const r = () => {
if(div.childElementCount || (middleware && !middleware())) return;
renderImageFromUrl(img, thumb.url, afterRender);
};
if(thumb.url) {
r();
return Promise.resolve();
} else {
return appDocsManager.getThumbURL(doc, thumb).promise.then(r);
}
};
2020-04-08 17:46:43 +02:00
if(lazyLoadQueue && onlyThumb) {
lazyLoadQueue.push({div, load});
return Promise.resolve();
} else {
load();
}
}
}
if(onlyThumb) { // for sticker panel
return Promise.resolve();
2020-02-26 18:52:59 +01:00
}
let downloaded = doc.downloaded;
let load = async() => {
if(middleware && !middleware()) return;
if(stickerType == 2) {
/* if(doc.id == '1860749763008266301') {
console.log('loaded sticker:', doc, div);
} */
2020-04-14 17:46:31 +02:00
//console.time('download sticker' + doc.id);
//appDocsManager.downloadDocNew(doc.id).promise.then(res => res.json()).then(async(json) => {
//fetch(doc.url).then(res => res.json()).then(async(json) => {
2020-09-20 00:38:00 +02:00
/* return */ await appDocsManager.downloadDocNew(doc)
.then(readBlobAsText)
.then(JSON.parse)
.then(async(json) => {
//console.timeEnd('download sticker' + doc.id);
2020-09-20 00:38:00 +02:00
//console.log('loaded sticker:', doc, div/* , blob */);
if(middleware && !middleware()) return;
let animation = await LottieLoader.loadAnimationWorker/* loadAnimation */({
container: div,
loop: loop && !emoji,
autoplay: play,
animationData: json,
width,
height
}, group, toneIndex);
2020-09-20 00:38:00 +02:00
//const deferred = deferredPromise<void>();
animation.addListener('firstFrame', () => {
if(div.firstElementChild && div.firstElementChild.tagName == 'IMG') {
div.firstElementChild.remove();
} else {
animation.canvas.classList.add('fade-in');
}
2020-09-20 00:38:00 +02:00
//deferred.resolve();
}, true);
if(emoji) {
div.addEventListener('click', () => {
let animation = LottieLoader.getAnimation(div);
if(animation.paused) {
animation.restart();
}
});
}
2020-09-20 00:38:00 +02:00
//return deferred;
//await new Promise((resolve) => setTimeout(resolve, 5e3));
});
//console.timeEnd('render sticker' + doc.id);
} else if(stickerType == 1) {
let img = new Image();
2020-04-16 02:48:41 +02:00
if(!downloaded && (!div.firstElementChild || div.firstElementChild.tagName != 'IMG')) {
img.classList.add('fade-in-transition');
img.style.opacity = '0';
img.addEventListener('load', () => {
doc.downloaded = true;
window.requestAnimationFrame(() => {
img.style.opacity = '';
});
});
}
const r = () => {
if(middleware && !middleware()) return;
2020-04-16 02:48:41 +02:00
renderImageFromUrl(img, doc.url, () => {
if(div.firstElementChild && div.firstElementChild != img) {
div.firstElementChild.remove();
}
div.append(img);
});
};
if(doc.url) r();
else {
appDocsManager.downloadDocNew(doc).then(r);
}
}
};
return lazyLoadQueue && (!doc.downloaded || stickerType == 2) ? (lazyLoadQueue.push({div, load, wasSeen: group == 'chat' && stickerType != 2}), Promise.resolve()) : load();
}
2020-02-15 19:08:26 +01:00
export function wrapReply(title: string, subtitle: string, message?: any, isPinned?: boolean) {
const prefix = isPinned ? 'pinned-message' : 'reply';
const div = document.createElement('div');
div.classList.add(prefix);
2020-02-15 19:08:26 +01:00
const replyBorder = document.createElement('div');
replyBorder.classList.add(prefix + '-border');
2020-02-15 19:08:26 +01:00
const replyContent = document.createElement('div');
replyContent.classList.add(prefix + '-content');
2020-02-15 19:08:26 +01:00
const replyTitle = document.createElement('div');
replyTitle.classList.add(prefix + '-title');
2020-02-15 19:08:26 +01:00
const replySubtitle = document.createElement('div');
replySubtitle.classList.add(prefix + '-subtitle');
if(title.length > 150) {
title = title.substr(0, 140) + '...';
}
if(subtitle.length > 150) {
subtitle = subtitle.substr(0, 140) + '...';
}
2020-02-15 19:08:26 +01:00
replyTitle.innerHTML = title ? RichTextProcessor.wrapEmojiText(title) : '';
const media = message && message.media;
2020-02-15 19:08:26 +01:00
if(media) {
replySubtitle.innerHTML = message.rReply;
//console.log('wrap reply', media);
2020-04-08 17:46:43 +02:00
2020-02-15 19:08:26 +01:00
if(media.photo || (media.document && ['video'].indexOf(media.document.type) !== -1)) {
let replyMedia = document.createElement('div');
replyMedia.classList.add(prefix + '-media');
2020-04-08 17:46:43 +02:00
2020-02-15 19:08:26 +01:00
let photo = media.photo || media.document;
let sizes = photo.sizes || photo.thumbs;
if(sizes && sizes[0].bytes) {
appPhotosManager.setAttachmentPreview(sizes[0].bytes, replyMedia, false, true);
}
appPhotosManager.preloadPhoto(photo, appPhotosManager.choosePhotoSize(photo, 32, 32))
.then(() => {
renderImageFromUrl(replyMedia, photo._ == 'photo' ? photo.url : appPhotosManager.getDocumentCachedThumb(photo.id).url);
2020-02-15 19:08:26 +01:00
});
2020-04-08 17:46:43 +02:00
2020-02-15 19:08:26 +01:00
replyContent.append(replyMedia);
div.classList.add('is-media');
2020-02-15 19:08:26 +01:00
}
} else {
replySubtitle.innerHTML = subtitle ? RichTextProcessor.wrapEmojiText(subtitle) : '';
}
replyContent.append(replyTitle, replySubtitle);
div.append(replyBorder, replyContent);
2020-02-17 13:18:06 +01:00
/////////console.log('wrapReply', title, subtitle, media);
2020-02-15 19:08:26 +01:00
return div;
}
2020-05-01 23:28:40 +02:00
export function wrapAlbum({groupID, attachmentDiv, middleware, uploading, lazyLoadQueue, isOut}: {
groupID: string,
attachmentDiv: HTMLElement,
middleware?: () => boolean,
lazyLoadQueue?: LazyLoadQueue,
uploading?: boolean,
isOut: boolean
}) {
const items: {size: PhotoSize.photoSize, media: any, message: any}[] = [];
2020-05-01 23:28:40 +02:00
2020-09-01 21:59:49 +02:00
// !higher msgID will be the FIRST in album
const storage = Object.keys(appMessagesManager.groupedMessagesStorage[groupID]).map(id => +id).sort((a, b) => a - b);
for(const mid of storage) {
const m = appMessagesManager.getMessage(mid);
const media = m.media.photo || m.media.document;
2020-05-01 23:28:40 +02:00
2020-09-01 21:59:49 +02:00
const size: any = media._ == 'photo' ? appPhotosManager.choosePhotoSize(media, 480, 480) : {w: media.w, h: media.h};
2020-05-01 23:28:40 +02:00
items.push({size, media, message: m});
}
2020-09-01 21:59:49 +02:00
const spacing = 2;
const layouter = new Layouter(items.map(i => ({w: i.size.w, h: i.size.h})), mediaSizes.active.album.width, 100, spacing);
const layout = layouter.layout();
//console.log('layout:', layout, items.map(i => ({w: i.size.w, h: i.size.h})));
2020-05-01 23:28:40 +02:00
/* let borderRadius = window.getComputedStyle(realParent).getPropertyValue('border-radius');
let brSplitted = fillPropertyValue(borderRadius); */
2020-09-01 21:59:49 +02:00
for(const {geometry, sides} of layout) {
const item = items.shift();
2020-05-09 14:02:07 +02:00
if(!item) {
console.error('no item for layout!');
continue;
}
2020-09-01 21:59:49 +02:00
const {size, media, message} = item;
const div = document.createElement('div');
2020-05-01 23:28:40 +02:00
div.classList.add('album-item');
div.dataset.mid = message.mid;
div.style.width = geometry.width + 'px';
div.style.height = geometry.height + 'px';
div.style.top = geometry.y + 'px';
div.style.left = geometry.x + 'px';
if(sides & RectPart.Right) {
attachmentDiv.style.width = geometry.width + geometry.x + 'px';
}
if(sides & RectPart.Bottom) {
attachmentDiv.style.height = geometry.height + geometry.y + 'px';
}
if(sides & RectPart.Left && sides & RectPart.Top) {
div.style.borderTopLeftRadius = 'inherit';
}
if(sides & RectPart.Left && sides & RectPart.Bottom) {
div.style.borderBottomLeftRadius = 'inherit';
}
if(sides & RectPart.Right && sides & RectPart.Top) {
div.style.borderTopRightRadius = 'inherit';
}
if(sides & RectPart.Right && sides & RectPart.Bottom) {
div.style.borderBottomRightRadius = 'inherit';
}
if(media._ == 'photo') {
wrapPhoto(
media,
2020-05-01 23:28:40 +02:00
message,
div,
0,
0,
false,
isOut,
lazyLoadQueue,
middleware,
size
);
} else {
wrapVideo({
doc: message.media.document,
container: div,
message,
boxWidth: 0,
boxHeight: 0,
withTail: false,
isOut,
lazyLoadQueue,
middleware
});
}
// @ts-ignore
//div.style.backgroundColor = '#' + Math.floor(Math.random() * (2 ** 24 - 1)).toString(16).padStart(6, '0');
attachmentDiv.append(div);
}
}
2020-05-09 14:02:07 +02:00
export function wrapPoll(pollID: string, mid: number) {
const elem = new PollElement();
elem.setAttribute('poll-id', pollID);
elem.setAttribute('message-id', '' + mid);
2020-05-09 14:02:07 +02:00
return elem;
}