2020-11-07 05:48:07 +02:00
import { getEmojiToneIndex } from '../emoji' ;
2020-10-11 22:12:17 +03:00
import { readBlobAsText } from '../helpers/blob' ;
import { deferredPromise } from '../helpers/cancellablePromise' ;
import { months } from '../helpers/date' ;
import mediaSizes from '../helpers/mediaSizes' ;
2020-11-07 05:48:07 +02:00
import { formatBytes } from '../helpers/number' ;
2020-10-31 00:39:36 +02:00
import { isAppleMobile , isSafari } from '../helpers/userAgent' ;
2020-10-11 22:12:17 +03:00
import { PhotoSize } from '../layer' ;
2020-09-17 22:33:23 +03:00
import appDocsManager , { MyDocument } from "../lib/appManagers/appDocsManager" ;
2020-10-11 22:12:17 +03:00
import { DownloadBlob } from '../lib/appManagers/appDownloadManager' ;
import appMessagesManager from '../lib/appManagers/appMessagesManager' ;
import appPhotosManager , { MyPhoto } from '../lib/appManagers/appPhotosManager' ;
import LottieLoader from '../lib/lottieLoader' ;
import VideoPlayer from '../lib/mediaPlayer' ;
2020-12-12 18:30:01 +02:00
import { attachClickEvent , cancelEvent , isInDOM } from "../helpers/dom" ;
2020-10-11 22:12:17 +03:00
import webpWorkerController from '../lib/webp/webpWorkerController' ;
import animationIntersector from './animationIntersector' ;
import appMediaPlaybackController from './appMediaPlaybackController' ;
import AudioElement from './audio' ;
import ReplyContainer from './chat/replyContainer' ;
import { Layouter , RectPart } from './groupedLayout' ;
2020-02-11 22:35:57 +07:00
import LazyLoadQueue from './lazyLoadQueue' ;
2020-08-28 14:25:43 +03:00
import { renderImageFromUrl } from './misc' ;
2020-05-09 15:02:07 +03:00
import PollElement from './poll' ;
2020-10-11 22:12:17 +03:00
import ProgressivePreloader from './preloader' ;
2020-11-07 05:48:07 +02:00
import './middleEllipsis' ;
2020-12-08 21:48:44 +02:00
import { nextRandomInt } from '../helpers/random' ;
2020-12-10 01:58:20 +02:00
import RichTextProcessor from '../lib/richtextprocessor' ;
2020-12-13 01:29:12 +02:00
import appImManager from '../lib/appManagers/appImManager' ;
2020-12-16 05:22:58 +02:00
import Chat from './chat/chat' ;
2020-02-11 22:35:57 +07:00
2020-10-28 20:20:01 +02:00
const MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024 ; // 50 MB
2020-08-24 17:09:31 +03:00
export function wrapVideo ( { doc , container , message , boxWidth , boxHeight , withTail , isOut , middleware , lazyLoadQueue , noInfo , group } : {
2020-09-17 22:33:23 +03:00
doc : MyDocument ,
2020-11-12 00:43:09 +02:00
container? : HTMLElement ,
2020-08-24 17:09:31 +03:00
message? : any ,
boxWidth? : number ,
boxHeight? : number ,
2020-04-20 00:40:00 +03:00
withTail? : boolean ,
isOut? : boolean ,
2020-08-24 17:09:31 +03:00
middleware ? : ( ) = > boolean ,
lazyLoadQueue? : LazyLoadQueue ,
noInfo? : true ,
2020-12-11 04:06:16 +02:00
group? : string
2020-04-20 00:40:00 +03:00
} ) {
2020-10-28 20:20:01 +02:00
const isAlbumItem = ! ( boxWidth && boxHeight ) ;
const canAutoplay = doc . type != 'video' || ( doc . size <= MAX_VIDEO_AUTOPLAY_SIZE && ! isAlbumItem ) ;
let spanTime : HTMLElement ;
2020-08-24 17:09:31 +03:00
if ( ! noInfo ) {
if ( doc . type != 'round' ) {
2020-10-28 20:20:01 +02:00
spanTime = document . createElement ( 'span' ) ;
spanTime . classList . add ( 'video-time' ) ;
container . append ( spanTime ) ;
2020-08-24 17:09:31 +03:00
if ( doc . type != 'gif' ) {
2020-10-28 20:20:01 +02:00
spanTime . innerText = ( doc . duration + '' ) . toHHMMSS ( false ) ;
if ( canAutoplay ) {
spanTime . classList . add ( 'tgico' , 'can-autoplay' ) ;
} else {
const spanPlay = document . createElement ( 'span' ) ;
spanPlay . classList . add ( 'video-play' , 'tgico-largeplay' , 'btn-circle' , 'position-center' ) ;
container . append ( spanPlay ) ;
}
2020-08-24 17:09:31 +03:00
} else {
2020-10-28 20:20:01 +02:00
spanTime . innerText = 'GIF' ;
2020-08-24 17:09:31 +03:00
}
2020-06-16 23:48:08 +03:00
}
}
2020-08-25 19:26:49 +03:00
if ( doc . mime_type == 'image/gif' ) {
2020-12-11 04:06:16 +02:00
return wrapPhoto ( {
photo : doc ,
message ,
container ,
boxWidth ,
boxHeight ,
withTail ,
isOut ,
lazyLoadQueue ,
middleware
} ) ;
2020-08-25 19:26:49 +03:00
}
2020-08-29 14:45:37 +03:00
/ * c o n s t v i d e o = d o c . t y p e = = ' r o u n d ' ? a p p M e d i a P l a y b a c k C o n t r o l l e r . a d d M e d i a ( d o c , m e s s a g e . m i d ) a s H T M L V i d e o E l e m e n t : d o c u m e n t . c r e a t e E l e m e n t ( ' v i d e o ' ) ;
if ( video . parentElement ) {
video . remove ( ) ;
} * /
2020-08-24 17:09:31 +03:00
const video = document . createElement ( 'video' ) ;
2020-08-30 13:43:57 +03:00
video . muted = true ;
2020-10-31 00:39:36 +02:00
video . setAttribute ( 'playsinline' , 'true' ) ;
2020-08-29 14:45:37 +03:00
if ( doc . type == 'round' ) {
2020-08-30 13:43:57 +03:00
//video.muted = true;
2020-12-16 05:22:58 +02:00
const globalVideo = appMediaPlaybackController . addMedia ( message . peerId , doc , message . mid ) ;
2020-08-29 14:45:37 +03:00
video . addEventListener ( 'canplay' , ( ) = > {
if ( globalVideo . currentTime > 0 ) {
video . currentTime = globalVideo . currentTime ;
}
if ( ! globalVideo . paused ) {
// с закоментированными настройками - хром выключал видео при скролле, для этого нужно было включить видео - выйти из диалога, зайти заново и проскроллить вверх
/ * v i d e o . a u t o p l a y = t r u e ;
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 ) ;
2020-08-30 13:43:57 +03:00
} else {
video . autoplay = true ; // для safari
2020-08-29 14:45:37 +03:00
}
2020-08-24 17:09:31 +03:00
2020-05-23 08:31:18 +03:00
let img : HTMLImageElement ;
2020-08-24 17:09:31 +03:00
if ( message ) {
2020-10-31 04:10:44 +02:00
if ( ! canAutoplay ) {
2020-12-11 04:06:16 +02:00
return wrapPhoto ( {
photo : doc ,
message ,
container ,
boxWidth ,
boxHeight ,
withTail ,
isOut ,
lazyLoadQueue ,
middleware
} ) ;
2020-08-24 17:09:31 +03:00
}
if ( withTail ) {
img = wrapMediaWithTail ( doc , message , container , boxWidth , boxHeight , isOut ) ;
2020-05-23 08:31:18 +03:00
} else {
2020-08-25 19:26:49 +03:00
if ( boxWidth && boxHeight ) { // !album
appPhotosManager . setAttachmentSize ( doc , container , boxWidth , boxHeight , false , true ) ;
}
2020-09-17 22:33:23 +03:00
if ( doc . thumbs ? . length && 'bytes' in doc . thumbs [ 0 ] ) {
2020-08-25 19:26:49 +03:00
appPhotosManager . setAttachmentPreview ( doc . thumbs [ 0 ] . bytes , container , false ) ;
2020-08-24 17:09:31 +03:00
}
img = container . lastElementChild as HTMLImageElement ;
2020-08-25 19:26:49 +03:00
if ( img ? . tagName != 'IMG' ) {
2020-08-24 17:09:31 +03:00
container . append ( img = new Image ( ) ) ;
2020-05-23 08:31:18 +03:00
}
2020-04-08 18:46:43 +03:00
}
2020-08-24 17:09:31 +03:00
if ( img ) {
img . classList . add ( 'thumbnail' ) ;
}
2020-05-23 08:31:18 +03:00
2020-08-24 17:09:31 +03:00
if ( withTail ) {
const foreignObject = img . parentElement ;
video . width = + foreignObject . getAttributeNS ( null , 'width' ) ;
video . height = + foreignObject . getAttributeNS ( null , 'height' ) ;
foreignObject . append ( video ) ;
2020-04-08 18:46:43 +03:00
}
2020-06-06 23:38:48 +03:00
}
2020-04-08 18:46:43 +03:00
2020-08-24 17:09:31 +03:00
if ( ! img ? . parentElement ) {
2020-08-28 14:25:43 +03:00
const gotThumb = appDocsManager . getThumb ( doc , false ) ;
if ( gotThumb ) {
gotThumb . promise . then ( ( ) = > {
video . poster = gotThumb . thumb . url ;
} ) ;
2020-08-24 17:09:31 +03:00
}
2020-06-13 11:19:39 +03:00
}
2020-06-16 23:48:08 +03:00
2020-08-24 17:09:31 +03:00
if ( ! video . parentElement && container ) {
2020-05-23 08:31:18 +03:00
container . append ( video ) ;
2020-04-08 18:46:43 +03:00
}
2020-08-21 14:17:16 +03:00
const loadVideo = async ( ) = > {
2020-08-25 19:26:49 +03:00
if ( middleware && ! middleware ( ) ) {
return ;
}
let preloader : ProgressivePreloader ;
2020-08-24 17:09:31 +03:00
if ( message ? . media ? . preloader ) { // means upload
2020-08-25 19:26:49 +03:00
preloader = message . media . preloader as ProgressivePreloader ;
2020-10-16 13:08:28 +03:00
preloader . attach ( container , undefined , undefined ) ;
2020-08-25 19:26:49 +03:00
} else if ( ! doc . downloaded && ! doc . supportsStreaming ) {
2020-12-11 04:06:16 +02:00
const promise = appDocsManager . downloadDoc ( doc , undefined , lazyLoadQueue ? . queueId ) ;
2020-10-16 13:08:28 +03:00
preloader = new ProgressivePreloader ( null , true , false , 'prepend' ) ;
preloader . attach ( container , true , promise ) ;
2020-08-25 19:26:49 +03:00
/ * v i d e o . a d d E v e n t L i s t e n e r ( ' c a n p l a y ' , ( ) = > {
if ( preloader ) {
preloader . detach ( ) ;
}
} , { once : true } ) ; * /
2020-06-16 23:48:08 +03:00
2020-08-25 19:26:49 +03:00
await promise ;
2020-10-28 20:20:01 +02:00
if ( middleware && ! middleware ( ) ) {
return ;
}
2020-08-26 19:14:23 +03:00
} else if ( doc . supportsStreaming ) {
2020-10-16 13:08:28 +03:00
preloader = new ProgressivePreloader ( null , false , false , 'prepend' ) ;
preloader . attach ( container , false , null ) ;
2020-10-28 20:20:01 +02:00
video . addEventListener ( isSafari ? 'timeupdate' : 'canplay' , ( ) = > {
2020-08-26 19:14:23 +03:00
preloader . detach ( ) ;
} , { once : true } ) ;
2020-04-28 20:30:54 +03:00
}
2020-10-28 20:20:01 +02:00
2020-06-06 23:38:48 +03:00
//console.log('loaded doc:', doc, doc.url, container);
2020-06-16 23:48:08 +03:00
2020-09-21 20:34:19 +03:00
const deferred = deferredPromise < void > ( ) ;
2020-08-25 19:26:49 +03:00
//if(doc.type == 'gif'/* || true */) {
2020-10-31 00:39:36 +02:00
video . addEventListener ( isAppleMobile ? 'loadeddata' : 'canplay' , ( ) = > {
2020-08-25 19:26:49 +03:00
if ( img ? . parentElement ) {
2020-06-16 23:48:08 +03:00
img . remove ( ) ;
}
/ * i f ( ! v i d e o . p a u s e d ) {
video . pause ( ) ;
} * /
2020-10-28 20:20:01 +02:00
if ( doc . type != 'round' && group ) {
2020-08-24 17:09:31 +03:00
animationIntersector . addAnimation ( video , group ) ;
}
2020-09-21 20:34:19 +03:00
// test lazyLoadQueue
//setTimeout(() => {
deferred . resolve ( ) ;
//}, 5000);
2020-06-16 23:48:08 +03:00
} , { once : true } ) ;
2020-08-25 19:26:49 +03:00
//}
2020-10-28 20:20:01 +02:00
if ( doc . type == 'video' ) {
video . addEventListener ( 'timeupdate' , ( ) = > {
spanTime . innerText = ( video . duration - video . currentTime + '' ) . toHHMMSS ( false ) ;
} ) ;
}
2020-10-04 02:10:57 +03:00
video . addEventListener ( 'error' , ( e ) = > {
deferred . resolve ( ) ;
/ * c o n s o l e . e r r o r ( ' v i d e o e r r o r ' , e , v i d e o . s r c ) ;
if ( video . src ) { // if wasn't cleaned
deferred . reject ( e ) ;
} else {
deferred . resolve ( ) ;
} * /
} ) ;
2020-09-21 20:34:19 +03:00
2020-08-29 14:45:37 +03:00
//if(doc.type != 'round') {
renderImageFromUrl ( video , doc . url ) ;
//}
2020-06-16 23:48:08 +03:00
/ * i f ( ! c o n t a i n e r . p a r e n t E l e m e n t ) {
container . append ( video ) ;
} * /
2020-08-30 13:43:57 +03:00
2020-10-28 20:20:01 +02:00
if ( doc . type == 'round' ) {
video . dataset . ckin = 'circle' ;
video . dataset . overlay = '1' ;
new VideoPlayer ( video ) ;
} else {
2020-06-06 23:38:48 +03:00
video . muted = true ;
2020-05-18 04:21:58 +03:00
video . loop = true ;
2020-06-13 11:19:39 +03:00
//video.play();
video . autoplay = true ;
2020-05-18 04:21:58 +03:00
}
2020-09-21 20:34:19 +03:00
return deferred ;
2020-02-11 22:35:57 +07:00
} ;
2020-04-28 20:30:54 +03:00
2020-06-16 23:48:08 +03:00
/ * i f ( d o c . s i z e > = 2 0 e 6 & & ! d o c . d o w n l o a d e d ) {
2020-04-28 20:30:54 +03:00
let downloadDiv = document . createElement ( 'div' ) ;
downloadDiv . classList . add ( 'download' ) ;
let span = document . createElement ( 'span' ) ;
2020-05-06 04:03:31 +03:00
span . classList . add ( 'btn-circle' , 'tgico-download' ) ;
2020-04-28 20:30:54 +03:00
downloadDiv . append ( span ) ;
downloadDiv . addEventListener ( 'click' , ( ) = > {
downloadDiv . remove ( ) ;
loadVideo ( ) ;
2020-02-11 22:35:57 +07:00
} ) ;
2020-04-28 20:30:54 +03:00
2020-05-06 04:03:31 +03:00
container . prepend ( downloadDiv ) ;
2020-04-28 20:30:54 +03:00
return ;
2020-06-16 23:48:08 +03:00
} * /
2020-08-24 17:09:31 +03:00
2020-09-21 20:34:19 +03:00
return /* doc.downloaded || */ ! lazyLoadQueue /* && false */ ? loadVideo ( ) : ( lazyLoadQueue . push ( { div : container , load : loadVideo /* , wasSeen: true */ } ) , Promise . resolve ( ) ) ;
2020-02-11 22:35:57 +07:00
}
2020-06-13 11:19:39 +03:00
export const formatDate = ( timestamp : number , monthShort = false , withYear = true ) = > {
2020-04-28 20:30:54 +03:00
const date = new Date ( timestamp * 1000 ) ;
2020-06-13 11:19:39 +03:00
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 ) ;
2020-04-28 20:30:54 +03:00
} ;
2020-12-20 06:41:42 +02:00
export function wrapDocument ( { message , withTime , fontWeight } : {
2020-12-19 03:07:24 +02:00
message : any ,
withTime? : boolean ,
fontWeight? : number
} ) : HTMLElement {
if ( ! fontWeight ) fontWeight = 500 ;
2020-12-20 06:41:42 +02:00
const uploading = message . pFlags . is_outgoing ;
2020-12-20 05:54:35 +02:00
const doc = message . media . document || message . media . webpage . document ;
2020-06-13 11:19:39 +03:00
if ( doc . type == 'audio' || doc . type == 'voice' ) {
2020-12-19 03:07:24 +02:00
const audioElement = new AudioElement ( ) ;
audioElement . setAttribute ( 'message-id' , '' + message . mid ) ;
audioElement . setAttribute ( 'peer-id' , '' + message . peerId ) ;
audioElement . withTime = withTime ;
audioElement . message = message ;
2020-11-07 05:48:07 +02:00
audioElement . dataset . fontWeight = '' + fontWeight ;
return audioElement ;
2020-02-15 22:20:38 +07:00
}
2020-04-28 20:30:54 +03:00
2020-02-11 22:35:57 +07:00
let extSplitted = doc . file_name ? doc . file_name . split ( '.' ) : '' ;
let ext = '' ;
ext = extSplitted . length > 1 && Array . isArray ( extSplitted ) ? extSplitted . pop ( ) . toLowerCase ( ) : 'file' ;
2020-04-28 20:30:54 +03:00
let docDiv = document . createElement ( 'div' ) ;
docDiv . classList . add ( 'document' , ` ext- ${ ext } ` ) ;
2020-09-19 14:37:19 +03:00
const icoDiv = document . createElement ( 'div' ) ;
icoDiv . classList . add ( 'document-ico' ) ;
2020-12-10 01:58:20 +02:00
if ( doc . thumbs ? . length || ( uploading && doc . url && doc . type == 'photo' ) ) {
2020-10-16 15:35:44 +03:00
docDiv . classList . add ( 'document-with-thumb' ) ;
2020-09-19 14:37:19 +03:00
if ( uploading ) {
icoDiv . innerHTML = ` <img src=" ${ doc . url } "> ` ;
} else {
2020-12-11 04:06:16 +02:00
wrapPhoto ( {
photo : doc ,
message : null ,
container : icoDiv ,
boxWidth : 54 ,
boxHeight : 54
} ) ;
2020-09-19 14:37:19 +03:00
icoDiv . style . width = icoDiv . style . height = '' ;
}
const img = icoDiv . querySelector ( 'img' ) ;
if ( img ) img . classList . add ( 'document-thumb' ) ;
} else {
icoDiv . innerText = ext ;
2020-02-11 22:35:57 +07:00
}
2020-09-19 14:37:19 +03:00
2020-11-07 05:48:07 +02:00
//let fileName = stringMiddleOverflow(doc.file_name || 'Unknown.file', 26);
2020-02-11 22:35:57 +07:00
let fileName = doc . file_name || 'Unknown.file' ;
let size = formatBytes ( doc . size ) ;
if ( withTime ) {
2020-04-28 20:30:54 +03:00
size += ' · ' + formatDate ( doc . date ) ;
2020-02-11 22:35:57 +07:00
}
docDiv . innerHTML = `
2020-02-16 02:03:27 +07:00
$ { ! uploading ? ` <div class="document-download"><div class="tgico-download"></div></div> ` : '' }
2020-11-07 05:48:07 +02:00
< div class = "document-name" > < middle - ellipsis - element data-font-weight = "${fontWeight}" > $ { fileName } < / m i d d l e - e l l i p s i s - e l e m e n t > < / d i v >
2020-02-11 22:35:57 +07:00
< div class = "document-size" > $ { size } < / div >
` ;
2020-09-19 14:37:19 +03:00
docDiv . prepend ( icoDiv ) ;
2020-02-16 02:03:27 +07:00
if ( ! uploading ) {
let downloadDiv = docDiv . querySelector ( '.document-download' ) as HTMLDivElement ;
2020-08-25 12:39:39 +03:00
let preloader : ProgressivePreloader ;
2020-08-25 19:26:49 +03:00
let download : DownloadBlob ;
2020-02-16 02:03:27 +07:00
2020-12-12 18:30:01 +02:00
attachClickEvent ( docDiv , ( e ) = > {
2020-11-21 15:13:23 +02:00
cancelEvent ( e ) ;
2020-08-22 19:53:59 +03:00
if ( ! download ) {
2020-02-16 02:03:27 +07:00
if ( downloadDiv . classList . contains ( 'downloading' ) ) {
return ; // means not ready yet
}
2020-02-16 01:08:26 +07:00
2020-02-16 02:03:27 +07:00
if ( ! preloader ) {
2020-08-25 12:39:39 +03:00
preloader = new ProgressivePreloader ( null , true ) ;
2020-02-16 02:03:27 +07:00
}
2020-08-22 19:53:59 +03:00
2020-12-13 01:29:12 +02:00
//preloader.attach(downloadDiv, true);
download = appDocsManager . saveDocFile ( doc , appImManager . chat . bubbles . lazyLoadQueue . queueId ) ;
2020-08-25 12:39:39 +03:00
preloader . attach ( downloadDiv , true , download ) ;
2020-02-16 01:08:26 +07:00
2020-08-25 12:39:39 +03:00
download . then ( ( ) = > {
2020-08-22 19:53:59 +03:00
downloadDiv . remove ( ) ;
} ) . catch ( err = > {
if ( err . name === 'AbortError' ) {
download = null ;
}
} ) . finally ( ( ) = > {
downloadDiv . classList . remove ( 'downloading' ) ;
} ) ;
2020-02-16 02:03:27 +07:00
2020-12-13 01:29:12 +02:00
downloadDiv . classList . add ( 'downloading' ) ;
2020-02-16 02:03:27 +07:00
} else {
2020-08-25 12:39:39 +03:00
download . cancel ( ) ;
2020-02-16 02:03:27 +07:00
}
} ) ;
}
2020-02-11 22:35:57 +07:00
return docDiv ;
}
2020-11-12 00:43:09 +02:00
function wrapMediaWithTail ( photo : MyPhoto | MyDocument , message : { mid : number , message : string } , container : HTMLElement , boxWidth : number , boxHeight : number , isOut : boolean ) {
2020-08-25 19:26:49 +03:00
const svg = document . createElementNS ( "http://www.w3.org/2000/svg" , "svg" ) ;
2020-04-08 18:46:43 +03:00
svg . classList . add ( 'bubble__media-container' , isOut ? 'is-out' : 'is-in' ) ;
2020-02-11 22:35:57 +07:00
2020-08-25 19:26:49 +03:00
const foreignObject = document . createElementNS ( "http://www.w3.org/2000/svg" , 'foreignObject' ) ;
2020-04-08 18:46:43 +03:00
2020-08-25 19:26:49 +03:00
appPhotosManager . setAttachmentSize ( photo , foreignObject , boxWidth , boxHeight /* , false, true */ ) ;
2020-05-23 08:31:18 +03:00
2020-08-25 19:26:49 +03:00
const width = + foreignObject . getAttributeNS ( null , 'width' ) ;
const height = + foreignObject . getAttributeNS ( null , 'height' ) ;
2020-05-23 08:31:18 +03:00
svg . setAttributeNS ( null , 'width' , '' + width ) ;
svg . setAttributeNS ( null , 'height' , '' + height ) ;
2020-04-14 18:46:31 +03:00
2020-06-05 19:01:06 +03:00
svg . setAttributeNS ( null , 'viewBox' , '0 0 ' + width + ' ' + height ) ;
svg . setAttributeNS ( null , 'preserveAspectRatio' , 'none' ) ;
2020-12-11 04:06:16 +02:00
const clipId = 'clip' + message . mid + '_' + nextRandomInt ( 9999 ) ;
svg . dataset . clipId = clipId ;
2020-02-11 22:35:57 +07:00
2020-08-25 19:26:49 +03:00
const defs = document . createElementNS ( "http://www.w3.org/2000/svg" , 'defs' ) ;
2020-04-14 18:46:31 +03:00
let clipPathHTML : string = '' ;
2020-04-08 18:46:43 +03: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 18:46:31 +03:00
2020-12-11 04:06:16 +02:00
defs . innerHTML = ` <clipPath id=" ${ clipId } "> ${ clipPathHTML } </clipPath> ` ;
2020-04-08 18:46:43 +03:00
2020-05-23 08:31:18 +03:00
container . style . width = parseInt ( container . style . width ) - 9 + 'px' ;
2020-06-13 11:19:39 +03:00
container . classList . add ( 'with-tail' ) ;
2020-05-23 08:31:18 +03:00
svg . append ( defs , foreignObject ) ;
container . append ( svg ) ;
let img = foreignObject . firstElementChild as HTMLImageElement ;
if ( ! img ) {
foreignObject . append ( img = new Image ( ) ) ;
}
2020-04-08 18:46:43 +03:00
2020-05-23 08:31:18 +03:00
return img ;
2020-04-08 18:46:43 +03:00
}
2020-12-11 04:06:16 +02:00
export function wrapPhoto ( { photo , message , container , boxWidth , boxHeight , withTail , isOut , lazyLoadQueue , middleware , size } : {
photo : MyPhoto | MyDocument ,
message : any ,
container : HTMLElement ,
boxWidth? : number ,
boxHeight? : number ,
withTail? : boolean ,
isOut? : boolean ,
lazyLoadQueue? : LazyLoadQueue ,
middleware ? : ( ) = > boolean ,
size? : PhotoSize
} ) {
if ( boxWidth === undefined ) {
boxWidth = mediaSizes . active . regular . width ;
}
if ( boxHeight === undefined ) {
boxHeight = mediaSizes . active . regular . height ;
}
2020-05-23 08:31:18 +03:00
let image : HTMLImageElement ;
2020-04-08 18:46:43 +03:00
if ( withTail ) {
image = wrapMediaWithTail ( photo , message , container , boxWidth , boxHeight , isOut ) ;
2020-05-23 08:31:18 +03:00
} else {
2020-08-25 19:26:49 +03:00
if ( boxWidth && boxHeight ) { // !album
size = appPhotosManager . setAttachmentSize ( photo , container , boxWidth , boxHeight , false , true ) ;
}
if ( photo . _ == 'document' || ! photo . downloaded ) {
2020-09-17 22:33:23 +03:00
const thumbs = ( photo as MyPhoto ) . sizes || ( photo as MyDocument ) . thumbs ;
if ( thumbs ? . length && 'bytes' in thumbs [ 0 ] ) {
2020-08-25 19:26:49 +03:00
appPhotosManager . setAttachmentPreview ( thumbs [ 0 ] . bytes , container , false ) ;
2020-05-23 08:31:18 +03:00
}
2020-05-02 00:28:40 +03:00
}
2020-05-23 08:31:18 +03:00
image = container . lastElementChild as HTMLImageElement ;
if ( ! image || image . tagName != 'IMG' ) {
container . append ( image = new Image ( ) ) ;
2020-04-08 18:46:43 +03:00
}
}
2020-10-31 04:10:44 +02:00
if ( ! ( ( photo as MyPhoto ) . sizes || ( photo as MyDocument ) . thumbs ) ) {
return Promise . resolve ( ) ;
}
2020-04-14 18:46:31 +03:00
2020-05-06 04:03:31 +03:00
//console.log('wrapPhoto downloaded:', photo, photo.downloaded, container);
2020-04-14 18:46:31 +03:00
2020-08-25 12:39:39 +03:00
const cacheContext = appPhotosManager . getCacheContext ( photo ) ;
2020-04-26 04:45:07 +03:00
2020-04-14 18:46:31 +03:00
let preloader : ProgressivePreloader ;
2020-09-19 14:37:19 +03:00
if ( message ? . media ? . preloader ) { // means upload
2020-05-02 00:28:40 +03:00
message . media . preloader . attach ( container ) ;
2020-08-25 12:39:39 +03:00
} else if ( ! cacheContext . downloaded ) {
2020-12-21 02:38:21 +02:00
preloader = new ProgressivePreloader ( null , false , false , photo . _ == 'document' ? 'prepend' : 'append' ) ;
2020-05-02 00:28:40 +03:00
}
2020-08-25 12:39:39 +03:00
const load = ( ) = > {
2020-12-11 04:06:16 +02:00
const promise = photo . _ == 'document' && photo . animated ?
appDocsManager . downloadDoc ( photo , undefined , lazyLoadQueue ? . queueId ) :
appPhotosManager . preloadPhoto ( photo , size , lazyLoadQueue ? . queueId ) ;
2020-08-25 12:39:39 +03:00
2020-04-14 18:46:31 +03:00
if ( preloader ) {
preloader . attach ( container , true , promise ) ;
}
2020-08-28 14:25:43 +03:00
2020-04-15 23:55:08 +03:00
return promise . then ( ( ) = > {
2020-04-26 04:45:07 +03:00
if ( middleware && ! middleware ( ) ) return ;
2020-04-15 23:55:08 +03:00
2020-08-25 19:26:49 +03:00
renderImageFromUrl ( image || container , cacheContext . url || photo . url ) ;
2020-02-14 18:04:39 +07:00
} ) ;
} ;
2020-08-25 12:39:39 +03:00
2020-12-14 00:28:17 +02:00
return cacheContext . downloaded || ! lazyLoadQueue ? load ( ) : ( lazyLoadQueue . push ( { div : container , load /* : load, wasSeen: true */ } ) , Promise . resolve ( ) ) ;
2020-02-11 22:35:57 +07:00
}
2020-06-13 11:19:39 +03:00
export function wrapSticker ( { doc , div , middleware , lazyLoadQueue , group , play , onlyThumb , emoji , width , height , withThumb , loop } : {
2020-09-17 22:33:23 +03:00
doc : MyDocument ,
2020-11-25 21:36:18 +02:00
div : HTMLElement ,
2020-05-26 18:04:06 +03:00
middleware ? : ( ) = > boolean ,
lazyLoadQueue? : LazyLoadQueue ,
group? : string ,
play? : boolean ,
onlyThumb? : boolean ,
2020-06-13 11:19:39 +03:00
emoji? : string ,
width? : number ,
height? : number ,
withThumb? : boolean ,
loop? : boolean
2020-05-26 18:04:06 +03:00
} ) {
2020-08-28 14:25:43 +03:00
const stickerType = doc . sticker ;
2020-04-14 18:46:31 +03:00
2020-06-13 11:19:39 +03:00
if ( ! width ) {
width = ! emoji ? 200 : undefined ;
}
if ( ! height ) {
height = ! emoji ? 200 : undefined ;
}
2020-04-14 18:46:31 +03:00
if ( stickerType == 2 && ! LottieLoader . loaded ) {
2020-05-30 09:44:54 +03:00
//LottieLoader.loadLottie();
LottieLoader . loadLottieWorkers ( ) ;
2020-04-14 18:46:31 +03:00
}
2020-02-11 22:35:57 +07:00
if ( ! stickerType ) {
2020-05-09 15:02:07 +03:00
console . error ( 'wrong doc for wrapSticker!' , doc ) ;
2020-05-23 08:31:18 +03:00
throw new Error ( 'wrong doc for wrapSticker!' ) ;
2020-02-11 22:35:57 +07:00
}
2020-05-23 08:31:18 +03:00
2020-12-11 04:06:16 +02:00
div . dataset . docId = doc . id ;
2020-02-11 22:35:57 +07:00
2020-05-09 15:02:07 +03:00
//console.log('wrap sticker', doc, div, onlyThumb);
2020-05-26 18:04:06 +03:00
const toneIndex = emoji ? getEmojiToneIndex ( emoji ) : - 1 ;
2020-02-11 22:35:57 +07:00
2020-11-27 21:09:05 +02:00
if ( ( doc . thumbs ? . length || doc . stickerCachedThumbs ) && ! div . firstElementChild && ( ! doc . downloaded || stickerType == 2 || onlyThumb ) /* && doc.thumbs[0]._ != 'photoSizeEmpty' */ ) {
2020-11-28 17:56:28 +02:00
let thumb = doc . stickerCachedThumbs && doc . stickerCachedThumbs [ toneIndex ] || doc . thumbs [ 0 ] ;
2020-04-08 18:46:43 +03:00
2020-04-19 00:55:20 +03:00
//console.log('wrap sticker', thumb, div);
2020-08-23 15:12:08 +03:00
let img : HTMLImageElement ;
const afterRender = ( ) = > {
if ( ! div . childElementCount ) {
div . append ( img ) ;
}
} ;
2020-09-17 22:33:23 +03:00
if ( 'url' in thumb ) {
img = new Image ( ) ;
renderImageFromUrl ( img , thumb . url , afterRender ) ;
} else if ( 'bytes' in thumb ) {
2020-11-27 21:09:05 +02:00
if ( thumb . _ == 'photoPathSize' ) {
2020-11-28 17:56:28 +02:00
if ( thumb . bytes . length ) {
//if(!doc.w) console.error('no w', doc);
const d = appPhotosManager . getPathFromPhotoPathSize ( thumb ) ;
/ * i f ( d = = ' M z ' | | d . i n c l u d e s ( ' 1 5 1 , 4 8 , 3 4 9 , 3 3 z ' ) ) {
console . error ( 'no path' , doc ) ;
} * /
div . innerHTML = ` <svg class="rlottie-vector" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 ${ doc . w || 512 } ${ doc . h || 512 } " xml:space="preserve">
< path d = "${d}" / >
< / svg > ` ;
} else {
thumb = doc . thumbs . find ( t = > ( t as PhotoSize . photoStrippedSize ) . bytes ? . length ) || thumb ;
}
}
if ( thumb && thumb . _ != 'photoPathSize' && toneIndex <= 0 ) {
2020-11-27 21:09:05 +02:00
img = new Image ( ) ;
if ( ( webpWorkerController . isWebpSupported ( ) || doc . pFlags . stickerThumbConverted || thumb . url ) /* && false */ ) {
2020-11-28 17:56:28 +02:00
renderImageFromUrl ( img , appPhotosManager . getPreviewURLFromThumb ( thumb as PhotoSize . photoStrippedSize , true ) , afterRender ) ;
2020-11-27 21:09:05 +02:00
} else {
2020-11-28 17:56:28 +02:00
webpWorkerController . convert ( doc . id , ( thumb as PhotoSize . photoStrippedSize ) . bytes as Uint8Array ) . then ( bytes = > {
( thumb as PhotoSize . photoStrippedSize ) . bytes = bytes ;
2020-11-27 21:09:05 +02:00
doc . pFlags . stickerThumbConverted = true ;
if ( middleware && ! middleware ( ) ) return ;
if ( ! div . childElementCount ) {
2020-11-28 17:56:28 +02:00
renderImageFromUrl ( img , appPhotosManager . getPreviewURLFromThumb ( thumb as PhotoSize . photoStrippedSize , true ) , afterRender ) ;
2020-11-27 21:09:05 +02:00
}
} ) . catch ( ( ) = > { } ) ;
}
2020-05-23 08:31:18 +03:00
}
2020-11-27 21:09:05 +02:00
} else if ( stickerType == 2 && ( withThumb || onlyThumb ) && toneIndex <= 0 ) {
2020-08-23 15:12:08 +03:00
img = new Image ( ) ;
2020-08-28 14:25:43 +03:00
2020-08-24 17:09:31 +03:00
const load = ( ) = > {
2020-06-16 23:48:08 +03:00
if ( div . childElementCount || ( middleware && ! middleware ( ) ) ) return ;
2020-08-28 14:25:43 +03:00
const r = ( ) = > {
if ( div . childElementCount || ( middleware && ! middleware ( ) ) ) return ;
2020-11-28 17:56:28 +02:00
renderImageFromUrl ( img , ( thumb as PhotoSize . photoStrippedSize ) . url , afterRender ) ;
2020-08-28 14:25:43 +03:00
} ;
2020-11-28 17:56:28 +02:00
if ( ( thumb as PhotoSize . photoStrippedSize ) . url ) {
2020-08-28 14:25:43 +03:00
r ( ) ;
return Promise . resolve ( ) ;
} else {
2020-11-28 17:56:28 +02:00
return appDocsManager . getThumbURL ( doc , thumb as PhotoSize . photoStrippedSize ) . promise . then ( r ) ;
2020-08-28 14:25:43 +03:00
}
2020-08-24 17:09:31 +03:00
} ;
2020-04-08 18:46:43 +03:00
2020-08-28 14:25:43 +03:00
if ( lazyLoadQueue && onlyThumb ) {
lazyLoadQueue . push ( { div , load } ) ;
return Promise . resolve ( ) ;
} else {
load ( ) ;
}
2020-02-11 22:35:57 +07:00
}
}
2020-05-23 08:31:18 +03:00
2020-08-28 14:25:43 +03:00
if ( onlyThumb ) { // for sticker panel
return Promise . resolve ( ) ;
2020-02-27 00:52:59 +07:00
}
2020-02-11 22:35:57 +07:00
2020-05-06 04:03:31 +03:00
let downloaded = doc . downloaded ;
2020-08-23 15:12:08 +03:00
let load = async ( ) = > {
2020-02-11 22:35:57 +07:00
if ( middleware && ! middleware ( ) ) return ;
2020-05-23 08:31:18 +03:00
2020-02-11 22:35:57 +07:00
if ( stickerType == 2 ) {
2020-08-23 15:12:08 +03:00
/ * i f ( d o c . i d = = ' 1 8 6 0 7 4 9 7 6 3 0 0 8 2 6 6 3 0 1 ' ) {
console . log ( 'loaded sticker:' , doc , div ) ;
} * /
2020-04-14 18:46:31 +03:00
2020-11-27 21:09:05 +02:00
//await new Promise((resolve) => setTimeout(resolve, 500));
//return;
2020-08-23 15:12:08 +03:00
//console.time('download sticker' + doc.id);
2020-05-26 18:04:06 +03:00
2020-08-23 15:12:08 +03:00
//appDocsManager.downloadDocNew(doc.id).promise.then(res => res.json()).then(async(json) => {
2020-08-25 12:39:39 +03:00
//fetch(doc.url).then(res => res.json()).then(async(json) => {
2020-12-11 04:06:16 +02:00
/* return */ await appDocsManager . downloadDoc ( doc , undefined , lazyLoadQueue ? . queueId )
2020-08-28 14:25:43 +03:00
. then ( readBlobAsText )
2020-09-25 17:50:57 +03:00
//.then(JSON.parse)
2020-08-28 14:25:43 +03:00
. then ( async ( json ) = > {
2020-08-23 15:12:08 +03:00
//console.timeEnd('download sticker' + doc.id);
2020-09-20 01:38:00 +03:00
//console.log('loaded sticker:', doc, div/* , blob */);
2020-08-23 15:12:08 +03:00
if ( middleware && ! middleware ( ) ) return ;
2020-05-30 09:44:54 +03:00
2020-11-27 21:09:05 +02:00
let animation = await LottieLoader . loadAnimationWorker ( {
2020-02-11 22:35:57 +07:00
container : div ,
2020-06-13 11:19:39 +03:00
loop : loop && ! emoji ,
autoplay : play ,
2020-08-23 15:12:08 +03:00
animationData : json ,
2020-06-13 11:19:39 +03:00
width ,
height
2020-05-26 18:04:06 +03:00
} , group , toneIndex ) ;
2020-09-20 01:38:00 +03:00
//const deferred = deferredPromise<void>();
2020-08-28 14:25:43 +03:00
2020-06-13 11:19:39 +03:00
animation . addListener ( 'firstFrame' , ( ) = > {
2020-11-27 21:09:05 +02:00
const element = div . firstElementChild ;
const needFadeIn = ! element || element . tagName === 'svg' ;
const cb = ( ) = > {
if ( element && element != animation . canvas ) {
element . remove ( ) ;
}
} ;
if ( ! needFadeIn ) {
cb ( ) ;
2020-06-13 11:19:39 +03:00
} else {
animation . canvas . classList . add ( 'fade-in' ) ;
2020-11-27 21:09:05 +02:00
if ( element ) {
setTimeout ( ( ) = > {
cb ( ) ;
} , element . tagName === 'svg' ? 50 : 200 ) ;
}
2020-05-30 09:44:54 +03:00
}
2020-09-20 01:38:00 +03:00
2020-11-27 21:09:05 +02:00
appDocsManager . saveLottiePreview ( doc , animation . canvas , toneIndex ) ;
2020-09-20 01:38:00 +03:00
//deferred.resolve();
2020-06-13 11:19:39 +03:00
} , true ) ;
2020-08-28 14:25:43 +03:00
2020-06-13 11:19:39 +03:00
if ( emoji ) {
2020-12-12 18:30:01 +02:00
attachClickEvent ( div , ( e ) = > {
2020-11-21 15:13:23 +02:00
cancelEvent ( e ) ;
2020-06-13 11:19:39 +03:00
let animation = LottieLoader . getAnimation ( div ) ;
2020-08-28 14:25:43 +03:00
2020-06-13 11:19:39 +03:00
if ( animation . paused ) {
2020-11-18 22:07:31 +02:00
animation . autoplay = true ;
2020-06-13 11:19:39 +03:00
animation . restart ( ) ;
2020-02-11 22:35:57 +07:00
}
2020-06-13 11:19:39 +03:00
} ) ;
}
2020-09-20 01:38:00 +03:00
//return deferred;
2020-08-28 14:25:43 +03:00
//await new Promise((resolve) => setTimeout(resolve, 5e3));
2020-02-11 22:35:57 +07:00
} ) ;
2020-08-23 15:12:08 +03:00
//console.timeEnd('render sticker' + doc.id);
2020-02-11 22:35:57 +07:00
} else if ( stickerType == 1 ) {
let img = new Image ( ) ;
2020-04-16 03:48:41 +03:00
2020-05-06 04:03:31 +03:00
if ( ! downloaded && ( ! div . firstElementChild || div . firstElementChild . tagName != 'IMG' ) ) {
2020-06-13 11:19:39 +03:00
img . classList . add ( 'fade-in-transition' ) ;
img . style . opacity = '0' ;
2020-05-06 04:03:31 +03:00
2020-11-19 05:37:15 +02:00
/ * i f ( ! d i v . f i r s t E l e m e n t C h i l d ) {
2020-11-19 01:51:39 +02:00
div . append ( img ) ;
2020-11-19 05:37:15 +02:00
} * /
2020-11-19 01:51:39 +02:00
2020-05-18 04:21:58 +03:00
img . addEventListener ( 'load' , ( ) = > {
2020-08-23 15:12:08 +03:00
doc . downloaded = true ;
2020-05-06 04:03:31 +03:00
window . requestAnimationFrame ( ( ) = > {
img . style . opacity = '' ;
} ) ;
2020-05-18 04:21:58 +03:00
} ) ;
2020-05-06 04:03:31 +03:00
}
2020-08-28 14:25:43 +03:00
const r = ( ) = > {
if ( middleware && ! middleware ( ) ) return ;
2020-04-16 03:48:41 +03:00
2020-08-28 14:25:43 +03:00
renderImageFromUrl ( img , doc . url , ( ) = > {
if ( div . firstElementChild && div . firstElementChild != img ) {
div . firstElementChild . remove ( ) ;
}
div . append ( img ) ;
} ) ;
} ;
if ( doc . url ) r ( ) ;
else {
2020-12-11 04:06:16 +02:00
appDocsManager . downloadDoc ( doc , undefined , lazyLoadQueue ? . queueId ) . then ( r ) ;
2020-08-28 14:25:43 +03:00
}
2020-02-11 22:35:57 +07:00
}
2020-08-23 15:12:08 +03:00
} ;
2020-02-11 22:35:57 +07:00
2020-12-14 00:28:17 +02:00
return lazyLoadQueue && ( ! doc . downloaded || stickerType == 2 ) ? ( lazyLoadQueue . push ( { div , load /* , wasSeen: group == 'chat' && stickerType != 2 */ } ) , Promise . resolve ( ) ) : load ( ) ;
2020-02-11 22:35:57 +07:00
}
2020-02-16 01:08:26 +07:00
2020-10-11 22:12:17 +03:00
export function wrapReply ( title : string , subtitle : string , message? : any ) {
const replyContainer = new ReplyContainer ( 'reply' ) ;
replyContainer . fill ( title , subtitle , message ) ;
2020-02-17 19:18:06 +07:00
/////////console.log('wrapReply', title, subtitle, media);
2020-10-11 22:12:17 +03:00
return replyContainer . container ;
2020-02-16 01:08:26 +07:00
}
2020-05-02 00:28:40 +03:00
2020-11-12 00:43:09 +02:00
export function prepareAlbum ( options : {
container : HTMLElement ,
items : { w : number , h : number } [ ] ,
maxWidth : number ,
minWidth : number ,
spacing : number ,
maxHeight? : number ,
forMedia? : true
2020-05-02 00:28:40 +03:00
} ) {
2020-11-12 00:43:09 +02:00
const layouter = new Layouter ( options . items , options . maxWidth , options . minWidth , options . spacing , options . maxHeight ) ;
const layout = layouter . layout ( ) ;
2020-05-02 00:28:40 +03:00
2020-11-12 00:43:09 +02:00
const widthItem = layout . find ( item = > item . sides & RectPart . Right ) ;
const width = widthItem . geometry . width + widthItem . geometry . x ;
2020-05-02 00:28:40 +03:00
2020-11-12 00:43:09 +02:00
const heightItem = layout . find ( item = > item . sides & RectPart . Bottom ) ;
const height = heightItem . geometry . height + heightItem . geometry . y ;
2020-05-02 00:28:40 +03:00
2020-11-12 00:43:09 +02:00
const container = options . container ;
container . style . width = width + 'px' ;
container . style . height = height + 'px' ;
const children = container . children ;
2020-05-02 00:28:40 +03:00
2020-11-12 00:43:09 +02:00
layout . forEach ( ( { geometry , sides } , idx ) = > {
let div : HTMLElement ;
div = children [ idx ] as HTMLElement ;
if ( ! div ) {
div = document . createElement ( 'div' ) ;
container . append ( div ) ;
2020-05-09 15:02:07 +03:00
}
2020-12-08 21:48:44 +02:00
div . classList . add ( 'album-item' , 'grouped-item' ) ;
2020-05-02 00:28:40 +03:00
2020-11-12 00:43:09 +02:00
div . style . width = ( geometry . width / width * 100 ) + '%' ;
div . style . height = ( geometry . height / height * 100 ) + '%' ;
div . style . top = ( geometry . y / height * 100 ) + '%' ;
div . style . left = ( geometry . x / width * 100 ) + '%' ;
2020-05-02 00:28:40 +03:00
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' ;
}
2020-11-12 00:43:09 +02:00
if ( options . forMedia ) {
const mediaDiv = document . createElement ( 'div' ) ;
mediaDiv . classList . add ( 'album-item-media' ) ;
div . append ( mediaDiv ) ;
}
// @ts-ignore
//div.style.backgroundColor = '#' + Math.floor(Math.random() * (2 ** 24 - 1)).toString(16).padStart(6, '0');
} ) ;
/ * i f ( o p t i o n s . f o r M e d i a ) {
layout . forEach ( ( _ , i ) = > {
const mediaDiv = document . createElement ( 'div' ) ;
mediaDiv . classList . add ( 'album-item-media' ) ;
options . container . children [ i ] . append ( mediaDiv ) ;
} ) ;
} * /
}
2020-12-16 05:22:58 +02:00
export function wrapAlbum ( { groupId , attachmentDiv , middleware , uploading , lazyLoadQueue , isOut , chat } : {
2020-12-11 04:06:16 +02:00
groupId : string ,
2020-11-12 00:43:09 +02:00
attachmentDiv : HTMLElement ,
middleware ? : ( ) = > boolean ,
lazyLoadQueue? : LazyLoadQueue ,
uploading? : boolean ,
2020-12-16 05:22:58 +02:00
isOut : boolean ,
chat : Chat
2020-11-12 00:43:09 +02:00
} ) {
const items : { size : PhotoSize.photoSize , media : any , message : any } [ ] = [ ] ;
2020-11-09 22:57:06 +03:00
2020-12-10 01:58:20 +02:00
// !lowest msgID will be the FIRST in album
2020-12-11 04:06:16 +02:00
const storage = appMessagesManager . getMidsByAlbum ( groupId ) ;
2020-11-12 00:43:09 +02:00
for ( const mid of storage ) {
2020-12-16 05:22:58 +02:00
const m = chat . getMessage ( mid ) ;
2020-11-12 00:43:09 +02:00
const media = m . media . photo || m . media . document ;
const size : any = media . _ == 'photo' ? appPhotosManager . choosePhotoSize ( media , 480 , 480 ) : { w : media.w , h : media.h } ;
items . push ( { size , media , message : m } ) ;
}
2020-12-19 03:07:24 +02:00
/* / / * pending
2020-12-10 01:58:20 +02:00
if ( storage [ 0 ] < 0 ) {
items . reverse ( ) ;
2020-12-19 03:07:24 +02:00
} * /
2020-12-10 01:58:20 +02:00
2020-11-12 00:43:09 +02:00
prepareAlbum ( {
container : attachmentDiv ,
items : items.map ( i = > ( { w : i.size.w , h : i.size.h } ) ) ,
maxWidth : mediaSizes.active.album.width ,
minWidth : 100 ,
spacing : 2 ,
forMedia : true
} ) ;
items . forEach ( ( item , idx ) = > {
const { size , media , message } = item ;
const div = attachmentDiv . children [ idx ] as HTMLElement ;
div . dataset . mid = '' + message . mid ;
const mediaDiv = div . firstElementChild as HTMLElement ;
2020-05-02 00:28:40 +03:00
if ( media . _ == 'photo' ) {
2020-12-11 04:06:16 +02:00
wrapPhoto ( {
photo : media ,
2020-05-02 00:28:40 +03:00
message ,
2020-12-11 04:06:16 +02:00
container : mediaDiv ,
boxWidth : 0 ,
boxHeight : 0 ,
2020-05-02 00:28:40 +03:00
isOut ,
lazyLoadQueue ,
middleware ,
size
2020-12-11 04:06:16 +02:00
} ) ;
2020-05-02 00:28:40 +03:00
} else {
wrapVideo ( {
doc : message.media.document ,
2020-11-09 22:57:06 +03:00
container : mediaDiv ,
2020-05-02 00:28:40 +03:00
message ,
boxWidth : 0 ,
boxHeight : 0 ,
withTail : false ,
isOut ,
lazyLoadQueue ,
middleware
} ) ;
}
2020-11-12 00:43:09 +02:00
} ) ;
2020-05-02 00:28:40 +03:00
}
2020-05-09 15:02:07 +03:00
2020-12-16 05:22:58 +02:00
export function wrapGroupedDocuments ( { albumMustBeRenderedFull , message , bubble , messageDiv , chat } : {
2020-12-10 01:58:20 +02:00
albumMustBeRenderedFull : boolean ,
message : any ,
messageDiv : HTMLElement ,
bubble : HTMLElement ,
2020-12-16 05:22:58 +02:00
uploading? : boolean ,
chat : Chat
2020-12-10 01:58:20 +02:00
} ) {
let nameContainer : HTMLDivElement ;
2020-12-16 05:22:58 +02:00
const mids = albumMustBeRenderedFull ? chat . getMidsByMid ( message . mid ) : [ message . mid ] ;
2020-12-19 03:07:24 +02:00
const isPending = message . pFlags . is_outgoing ;
/ * i f ( i s P e n d i n g ) {
2020-12-10 01:58:20 +02:00
mids . reverse ( ) ;
2020-12-19 03:07:24 +02:00
} * /
2020-12-10 01:58:20 +02:00
mids . forEach ( ( mid , idx ) = > {
2020-12-16 05:22:58 +02:00
const message = chat . getMessage ( mid ) ;
2020-12-10 01:58:20 +02:00
const doc = message . media . document ;
2020-12-19 03:07:24 +02:00
const div = wrapDocument ( {
message
} ) ;
2020-12-10 01:58:20 +02:00
const container = document . createElement ( 'div' ) ;
container . classList . add ( 'document-container' ) ;
container . dataset . mid = '' + mid ;
const wrapper = document . createElement ( 'div' ) ;
wrapper . classList . add ( 'document-wrapper' ) ;
if ( message . message ) {
const messageDiv = document . createElement ( 'div' ) ;
messageDiv . classList . add ( 'document-message' ) ;
const richText = RichTextProcessor . wrapRichText ( message . message , {
entities : message.totalEntities
} ) ;
messageDiv . innerHTML = richText ;
wrapper . append ( messageDiv ) ;
}
if ( mids . length > 1 ) {
const selection = document . createElement ( 'div' ) ;
selection . classList . add ( 'document-selection' ) ;
container . append ( selection ) ;
container . classList . add ( 'grouped-item' ) ;
if ( idx === 0 ) {
nameContainer = wrapper ;
}
}
if ( isPending ) {
if ( doc . type == 'audio' || doc . type == 'voice' ) {
( div as AudioElement ) . preloader = message . media . preloader ;
} else {
const icoDiv = div . querySelector ( '.audio-download, .document-ico' ) ;
message . media . preloader . attach ( icoDiv , false ) ;
}
}
wrapper . append ( div ) ;
container . append ( wrapper ) ;
messageDiv . append ( container ) ;
} ) ;
if ( mids . length > 1 ) {
bubble . classList . add ( 'is-multiple-documents' , 'is-grouped' ) ;
}
return nameContainer ;
}
2020-12-18 05:07:32 +02:00
export function wrapPoll ( message : any ) {
2020-06-13 11:19:39 +03:00
const elem = new PollElement ( ) ;
2020-12-18 05:07:32 +02:00
elem . message = message ;
elem . setAttribute ( 'peer-id' , '' + message . peerId ) ;
elem . setAttribute ( 'poll-id' , message . media . poll . id ) ;
elem . setAttribute ( 'message-id' , '' + message . mid ) ;
2020-05-09 15:02:07 +03:00
return elem ;
}