New stickers preview (photoPathSize)
Caching thumb after sticker render (with toneIndex too)
This commit is contained in:
parent
cdf6c09ed5
commit
0f3c91ee2a
@ -42,7 +42,7 @@ export function wrapReplyDivAndCaption(options: {
|
|||||||
div: mediaEl,
|
div: mediaEl,
|
||||||
lazyLoadQueue: appImManager.lazyLoadQueue,
|
lazyLoadQueue: appImManager.lazyLoadQueue,
|
||||||
group: CHAT_ANIMATION_GROUP,
|
group: CHAT_ANIMATION_GROUP,
|
||||||
onlyThumb: media.document.sticker == 2,
|
//onlyThumb: media.document.sticker == 2,
|
||||||
width: 32,
|
width: 32,
|
||||||
height: 32
|
height: 32
|
||||||
});
|
});
|
||||||
|
@ -564,8 +564,8 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
|
|||||||
|
|
||||||
const toneIndex = emoji ? getEmojiToneIndex(emoji) : -1;
|
const toneIndex = emoji ? getEmojiToneIndex(emoji) : -1;
|
||||||
|
|
||||||
if(doc.thumbs?.length && !div.firstElementChild && (!doc.downloaded || stickerType == 2 || onlyThumb) && toneIndex <= 0/* && doc.thumbs[0]._ != 'photoSizeEmpty' */) {
|
if((doc.thumbs?.length || doc.stickerCachedThumbs) && !div.firstElementChild && (!doc.downloaded || stickerType == 2 || onlyThumb)/* && doc.thumbs[0]._ != 'photoSizeEmpty' */) {
|
||||||
const thumb = doc.thumbs[0];
|
const thumb = doc.stickerCachedThumbs && doc.stickerCachedThumbs[toneIndex] || doc.thumbs[0];
|
||||||
|
|
||||||
//console.log('wrap sticker', thumb, div);
|
//console.log('wrap sticker', thumb, div);
|
||||||
|
|
||||||
@ -580,23 +580,29 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
|
|||||||
img = new Image();
|
img = new Image();
|
||||||
renderImageFromUrl(img, thumb.url, afterRender);
|
renderImageFromUrl(img, thumb.url, afterRender);
|
||||||
} else if('bytes' in thumb) {
|
} else if('bytes' in thumb) {
|
||||||
img = new Image();
|
if(thumb._ == 'photoPathSize') {
|
||||||
|
//if(!doc.w) console.error('no w', doc);
|
||||||
if((webpWorkerController.isWebpSupported() || doc.pFlags.stickerThumbConverted || thumb.url)/* && false */) {
|
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">
|
||||||
renderImageFromUrl(img, appPhotosManager.getPreviewURLFromThumb(thumb, true), afterRender);
|
<path d="${appPhotosManager.getPathFromPhotoPathSize(thumb)}"/>
|
||||||
} else {
|
</svg>`;
|
||||||
webpWorkerController.convert(doc.id, thumb.bytes as Uint8Array).then(bytes => {
|
} else if(toneIndex <= 0) {
|
||||||
thumb.bytes = bytes;
|
img = new Image();
|
||||||
doc.pFlags.stickerThumbConverted = true;
|
if((webpWorkerController.isWebpSupported() || doc.pFlags.stickerThumbConverted || thumb.url)/* && false */) {
|
||||||
|
renderImageFromUrl(img, appPhotosManager.getPreviewURLFromThumb(thumb, true), afterRender);
|
||||||
if(middleware && !middleware()) return;
|
} else {
|
||||||
|
webpWorkerController.convert(doc.id, thumb.bytes as Uint8Array).then(bytes => {
|
||||||
if(!div.childElementCount) {
|
thumb.bytes = bytes;
|
||||||
renderImageFromUrl(img, appPhotosManager.getPreviewURLFromThumb(thumb, true), afterRender);
|
doc.pFlags.stickerThumbConverted = true;
|
||||||
}
|
|
||||||
}).catch(() => {});
|
if(middleware && !middleware()) return;
|
||||||
|
|
||||||
|
if(!div.childElementCount) {
|
||||||
|
renderImageFromUrl(img, appPhotosManager.getPreviewURLFromThumb(thumb, true), afterRender);
|
||||||
|
}
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if(stickerType == 2 && (withThumb || onlyThumb)) {
|
} else if(stickerType == 2 && (withThumb || onlyThumb) && toneIndex <= 0) {
|
||||||
img = new Image();
|
img = new Image();
|
||||||
|
|
||||||
const load = () => {
|
const load = () => {
|
||||||
@ -637,6 +643,9 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
|
|||||||
console.log('loaded sticker:', doc, div);
|
console.log('loaded sticker:', doc, div);
|
||||||
} */
|
} */
|
||||||
|
|
||||||
|
//await new Promise((resolve) => setTimeout(resolve, 500));
|
||||||
|
//return;
|
||||||
|
|
||||||
//console.time('download sticker' + doc.id);
|
//console.time('download sticker' + doc.id);
|
||||||
|
|
||||||
//appDocsManager.downloadDocNew(doc.id).promise.then(res => res.json()).then(async(json) => {
|
//appDocsManager.downloadDocNew(doc.id).promise.then(res => res.json()).then(async(json) => {
|
||||||
@ -649,7 +658,7 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
|
|||||||
//console.log('loaded sticker:', doc, div/* , blob */);
|
//console.log('loaded sticker:', doc, div/* , blob */);
|
||||||
if(middleware && !middleware()) return;
|
if(middleware && !middleware()) return;
|
||||||
|
|
||||||
let animation = await LottieLoader.loadAnimationWorker/* loadAnimation */({
|
let animation = await LottieLoader.loadAnimationWorker({
|
||||||
container: div,
|
container: div,
|
||||||
loop: loop && !emoji,
|
loop: loop && !emoji,
|
||||||
autoplay: play,
|
autoplay: play,
|
||||||
@ -661,12 +670,29 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
|
|||||||
//const deferred = deferredPromise<void>();
|
//const deferred = deferredPromise<void>();
|
||||||
|
|
||||||
animation.addListener('firstFrame', () => {
|
animation.addListener('firstFrame', () => {
|
||||||
if(div.firstElementChild && div.firstElementChild.tagName == 'IMG') {
|
const element = div.firstElementChild;
|
||||||
div.firstElementChild.remove();
|
const needFadeIn = !element || element.tagName === 'svg';
|
||||||
|
|
||||||
|
const cb = () => {
|
||||||
|
if(element && element != animation.canvas) {
|
||||||
|
element.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(!needFadeIn) {
|
||||||
|
cb();
|
||||||
} else {
|
} else {
|
||||||
animation.canvas.classList.add('fade-in');
|
animation.canvas.classList.add('fade-in');
|
||||||
|
|
||||||
|
if(element) {
|
||||||
|
setTimeout(() => {
|
||||||
|
cb();
|
||||||
|
}, element.tagName === 'svg' ? 50 : 200);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
appDocsManager.saveLottiePreview(doc, animation.canvas, toneIndex);
|
||||||
|
|
||||||
//deferred.resolve();
|
//deferred.resolve();
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
3
src/layer.d.ts
vendored
3
src/layer.d.ts
vendored
@ -2927,7 +2927,7 @@ export namespace Document {
|
|||||||
date: number,
|
date: number,
|
||||||
mime_type: string,
|
mime_type: string,
|
||||||
size: number,
|
size: number,
|
||||||
thumbs?: Array<PhotoSize.photoSize | PhotoSize.photoCachedSize | PhotoSize.photoStrippedSize>,
|
thumbs?: Array<PhotoSize.photoSize | PhotoSize.photoCachedSize | PhotoSize.photoStrippedSize | PhotoSize.photoPathSize>,
|
||||||
video_thumbs?: Array<VideoSize>,
|
video_thumbs?: Array<VideoSize>,
|
||||||
dc_id: number,
|
dc_id: number,
|
||||||
attributes: Array<DocumentAttribute>,
|
attributes: Array<DocumentAttribute>,
|
||||||
@ -2948,6 +2948,7 @@ export namespace Document {
|
|||||||
pFlags?: Partial<{
|
pFlags?: Partial<{
|
||||||
stickerThumbConverted?: true,
|
stickerThumbConverted?: true,
|
||||||
}>,
|
}>,
|
||||||
|
stickerCachedThumbs?: {[toneIndex: number]: {url: string, w: number, h: number}},
|
||||||
animated?: boolean,
|
animated?: boolean,
|
||||||
supportsStreaming?: boolean
|
supportsStreaming?: boolean
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { FileURLType, getFileNameByLocation, getFileURL } from '../../helpers/fileName';
|
import { FileURLType, getFileNameByLocation, getFileURL } from '../../helpers/fileName';
|
||||||
import { safeReplaceArrayInObject, defineNotNumerableProperties, isObject } from '../../helpers/object';
|
import { safeReplaceArrayInObject, defineNotNumerableProperties, isObject } from '../../helpers/object';
|
||||||
import { isSafari } from '../../helpers/userAgent';
|
|
||||||
import { Document, InputFileLocation, PhotoSize } from '../../layer';
|
import { Document, InputFileLocation, PhotoSize } from '../../layer';
|
||||||
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
|
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
|
||||||
import referenceDatabase, { ReferenceContext } from '../mtproto/referenceDatabase';
|
import referenceDatabase, { ReferenceContext } from '../mtproto/referenceDatabase';
|
||||||
@ -16,6 +15,7 @@ export type MyDocument = Document.document;
|
|||||||
|
|
||||||
class AppDocsManager {
|
class AppDocsManager {
|
||||||
private docs: {[docID: string]: MyDocument} = {};
|
private docs: {[docID: string]: MyDocument} = {};
|
||||||
|
private savingLottiePreview: {[docID: string]: true} = {};
|
||||||
|
|
||||||
public saveDoc(doc: Document, context?: ReferenceContext): MyDocument {
|
public saveDoc(doc: Document, context?: ReferenceContext): MyDocument {
|
||||||
if(doc._ == 'documentEmpty') {
|
if(doc._ == 'documentEmpty') {
|
||||||
@ -326,6 +326,66 @@ class AppDocsManager {
|
|||||||
return download;
|
return download;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public saveLottiePreview(doc: MyDocument, canvas: HTMLCanvasElement, toneIndex: number) {
|
||||||
|
const key = doc.id + '-' + toneIndex;
|
||||||
|
if(this.savingLottiePreview[key]/* || true */) return;
|
||||||
|
|
||||||
|
if(!doc.stickerCachedThumbs) {
|
||||||
|
defineNotNumerableProperties(doc, ['stickerCachedThumbs']);
|
||||||
|
doc.stickerCachedThumbs = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const thumb = doc.stickerCachedThumbs[toneIndex];
|
||||||
|
if(thumb && thumb.w >= canvas.width && thumb.h >= canvas.height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if(doc.thumbs.find(t => t._ == 'photoStrippedSize')
|
||||||
|
|| (doc.stickerCachedThumb || (doc.stickerSavedThumbWidth >= canvas.width && doc.stickerSavedThumbHeight >= canvas.height))) {
|
||||||
|
return;
|
||||||
|
} */
|
||||||
|
|
||||||
|
this.savingLottiePreview[key] = true;
|
||||||
|
canvas.toBlob((blob) => {
|
||||||
|
//console.log('got lottie preview', doc, blob, URL.createObjectURL(blob));
|
||||||
|
|
||||||
|
const thumb = {
|
||||||
|
url: URL.createObjectURL(blob),
|
||||||
|
w: canvas.width,
|
||||||
|
h: canvas.height
|
||||||
|
};
|
||||||
|
|
||||||
|
doc.stickerCachedThumbs[toneIndex] = thumb;
|
||||||
|
|
||||||
|
delete this.savingLottiePreview[key];
|
||||||
|
|
||||||
|
/* const reader = new FileReader();
|
||||||
|
reader.onloadend = (e) => {
|
||||||
|
const uint8 = new Uint8Array(e.target.result as ArrayBuffer);
|
||||||
|
const thumb: PhotoSize.photoStrippedSize = {
|
||||||
|
_: 'photoStrippedSize',
|
||||||
|
bytes: uint8,
|
||||||
|
type: 'i'
|
||||||
|
};
|
||||||
|
|
||||||
|
doc.stickerSavedThumbWidth = canvas.width;
|
||||||
|
doc.stickerSavedThumbHeight = canvas.width;
|
||||||
|
|
||||||
|
defineNotNumerableProperties(thumb, ['url']);
|
||||||
|
thumb.url = URL.createObjectURL(blob);
|
||||||
|
doc.thumbs.findAndSplice(t => t._ == thumb._);
|
||||||
|
doc.thumbs.unshift(thumb);
|
||||||
|
|
||||||
|
if(!webpWorkerController.isWebpSupported()) {
|
||||||
|
doc.pFlags.stickerThumbConverted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete this.savingLottiePreview[doc.id];
|
||||||
|
};
|
||||||
|
reader.readAsArrayBuffer(blob); */
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public saveDocFile(doc: MyDocument) {
|
public saveDocFile(doc: MyDocument) {
|
||||||
const options = this.getFileDownloadOptions(doc);
|
const options = this.getFileDownloadOptions(doc);
|
||||||
return appDownloadManager.downloadToDisc(options, doc.file_name);
|
return appDownloadManager.downloadToDisc(options, doc.file_name);
|
||||||
|
@ -158,6 +158,33 @@ export class AppPhotosManager {
|
|||||||
return URL.createObjectURL(blob);
|
return URL.createObjectURL(blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://core.telegram.org/api/files#vector-thumbnails
|
||||||
|
*/
|
||||||
|
public getPathFromPhotoPathSize(size: PhotoSize.photoPathSize) {
|
||||||
|
const bytes = size.bytes;
|
||||||
|
const lookup = "AACAAAAHAAALMAAAQASTAVAAAZaacaaaahaaalmaaaqastava.az0123456789-,";
|
||||||
|
|
||||||
|
let path = 'M';
|
||||||
|
for(let i = 0, length = bytes.length; i < length; ++i) {
|
||||||
|
const num = bytes[i];
|
||||||
|
|
||||||
|
if(num >= (128 + 64)) {
|
||||||
|
path += lookup[num - 128 - 64];
|
||||||
|
} else {
|
||||||
|
if(num >= 128) {
|
||||||
|
path += ',';
|
||||||
|
} else if(num >= 64) {
|
||||||
|
path += '-';
|
||||||
|
}
|
||||||
|
path += '' + (num & 63);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path += 'z';
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
public getPreviewURLFromThumb(thumb: PhotoSize.photoCachedSize | PhotoSize.photoStrippedSize, isSticker = false) {
|
public getPreviewURLFromThumb(thumb: PhotoSize.photoCachedSize | PhotoSize.photoStrippedSize, isSticker = false) {
|
||||||
return thumb.url ?? (defineNotNumerableProperties(thumb, ['url']), thumb.url = this.getPreviewURLFromBytes(thumb.bytes, isSticker));
|
return thumb.url ?? (defineNotNumerableProperties(thumb, ['url']), thumb.url = this.getPreviewURLFromBytes(thumb.bytes, isSticker));
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
|
||||||
import CryptoWorkerMethods from './crypto_methods';
|
import CryptoWorkerMethods from './crypto_methods';
|
||||||
|
|
||||||
type Task = {
|
type Task = {
|
||||||
@ -124,5 +125,6 @@ class CryptoWorker extends CryptoWorkerMethods {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cryptoWorker = new CryptoWorker();
|
const cryptoWorker = new CryptoWorker();
|
||||||
|
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.CryptoWorker = cryptoWorker);
|
||||||
//(window as any).CryptoWorker = cryptoWorker;
|
//(window as any).CryptoWorker = cryptoWorker;
|
||||||
export default cryptoWorker;
|
export default cryptoWorker;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[{
|
[{
|
||||||
"predicate": "document",
|
"predicate": "document",
|
||||||
"params": [
|
"params": [
|
||||||
{"name": "thumbs", "type": "Array<PhotoSize.photoSize | PhotoSize.photoCachedSize | PhotoSize.photoStrippedSize>"},
|
{"name": "thumbs", "type": "Array<PhotoSize.photoSize | PhotoSize.photoCachedSize | PhotoSize.photoStrippedSize | PhotoSize.photoPathSize>"},
|
||||||
{"name": "type", "type": "'gif' | 'sticker' | 'audio' | 'voice' | 'video' | 'round' | 'photo'"},
|
{"name": "type", "type": "'gif' | 'sticker' | 'audio' | 'voice' | 'video' | 'round' | 'photo'"},
|
||||||
{"name": "h", "type": "number"},
|
{"name": "h", "type": "number"},
|
||||||
{"name": "w", "type": "number"},
|
{"name": "w", "type": "number"},
|
||||||
@ -17,6 +17,7 @@
|
|||||||
{"name": "stickerEmojiRaw", "type": "string"},
|
{"name": "stickerEmojiRaw", "type": "string"},
|
||||||
{"name": "stickerSetInput", "type": "InputStickerSet.inputStickerSetID"},
|
{"name": "stickerSetInput", "type": "InputStickerSet.inputStickerSetID"},
|
||||||
{"name": "stickerThumbConverted", "type": "true"},
|
{"name": "stickerThumbConverted", "type": "true"},
|
||||||
|
{"name": "stickerCachedThumbs", "type": "{[toneIndex: number]: {url: string, w: number, h: number}}"},
|
||||||
{"name": "animated", "type": "boolean"},
|
{"name": "animated", "type": "boolean"},
|
||||||
{"name": "supportsStreaming", "type": "boolean"}
|
{"name": "supportsStreaming", "type": "boolean"}
|
||||||
]
|
]
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
justify-self: center;
|
justify-self: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
@ -78,6 +79,8 @@
|
|||||||
img {
|
img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -699,15 +699,21 @@ img.emoji {
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rlottie {
|
.rlottie, .rlottie-vector {
|
||||||
|
position: absolute;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
&.fade-in {
|
.rlottie.fade-in {
|
||||||
animation: fade-in-opacity .2s ease forwards;
|
animation: fade-in-opacity .2s ease forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rlottie-vector {
|
||||||
|
fill: rgba(0, 0, 0, .08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-in-transition {
|
.fade-in-transition {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user