diff --git a/src/components/wrappers.ts b/src/components/wrappers.ts index b73a1c34..7eb56ff4 100644 --- a/src/components/wrappers.ts +++ b/src/components/wrappers.ts @@ -651,7 +651,7 @@ export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showS return img; } */ -export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withTail, isOut, lazyLoadQueue, middleware, size, withoutPreloader, loadPromises, noAutoDownload, noBlur}: { +export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withTail, isOut, lazyLoadQueue, middleware, size, withoutPreloader, loadPromises, noAutoDownload, noBlur, noThumb, noFadeIn}: { photo: MyPhoto | MyDocument, message: any, container: HTMLElement, @@ -666,6 +666,8 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT loadPromises?: Promise[], noAutoDownload?: boolean, noBlur?: boolean, + noThumb?: boolean, + noFadeIn?: boolean, }) { if(!((photo as MyPhoto).sizes || (photo as MyDocument).thumbs)) { if(boxWidth && boxHeight && !size && photo._ === 'document') { @@ -722,6 +724,28 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT const thumbImage = gotThumb.image; // local scope thumbImage.classList.add('media-photo'); container.append(thumbImage); + } else { + const res = wrapPhoto({ + container, + message, + photo, + boxWidth: 0, + boxHeight: 0, + size, + lazyLoadQueue, + isOut, + loadPromises, + middleware, + withoutPreloader, + withTail, + noAutoDownload, + noBlur, + noThumb: true, + //noFadeIn: true + }); + const thumbImage = res.images.full; + thumbImage.classList.add('media-photo', 'thumbnail'); + //container.append(thumbImage); } container.classList.add('media-container-fitted'); @@ -735,12 +759,14 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT cacheContext = appDownloadManager.getCacheContext(photo, size?.type); } - const gotThumb = appPhotosManager.getStrippedThumbIfNeeded(photo, cacheContext, !noBlur); - if(gotThumb) { - loadThumbPromise = Promise.all([loadThumbPromise, gotThumb.loadPromise]); - thumbImage = gotThumb.image; - thumbImage.classList.add('media-photo'); - aspecter.append(thumbImage); + if(!noThumb) { + const gotThumb = appPhotosManager.getStrippedThumbIfNeeded(photo, cacheContext, !noBlur); + if(gotThumb) { + loadThumbPromise = Promise.all([loadThumbPromise, gotThumb.loadPromise]); + thumbImage = gotThumb.image; + thumbImage.classList.add('media-photo'); + aspecter.append(thumbImage); + } } // } @@ -748,7 +774,7 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT //console.log('wrapPhoto downloaded:', photo, photo.downloaded, container); - const needFadeIn = (thumbImage || !cacheContext.downloaded) && rootScope.settings.animationsEnabled; + const needFadeIn = (thumbImage || !cacheContext.downloaded) && rootScope.settings.animationsEnabled && !noFadeIn; if(needFadeIn) { image.classList.add('fade-in'); } diff --git a/src/lib/appManagers/appMessagesManager.ts b/src/lib/appManagers/appMessagesManager.ts index ae62f4ad..973bff12 100644 --- a/src/lib/appManagers/appMessagesManager.ts +++ b/src/lib/appManagers/appMessagesManager.ts @@ -109,21 +109,21 @@ export type MessagesStorage = { export type MyMessageActionType = Message.messageService['action']['_']; export class AppMessagesManager { - public static MESSAGE_ID_INCREMENT = 0x10000; - public static MESSAGE_ID_OFFSET = 0xFFFFFFFF; + private static MESSAGE_ID_INCREMENT = 0x10000; + private static MESSAGE_ID_OFFSET = 0xFFFFFFFF; - public messagesStorageByPeerId: {[peerId: string]: MessagesStorage} = {}; + private messagesStorageByPeerId: {[peerId: string]: MessagesStorage} = {}; public groupedMessagesStorage: {[groupId: string]: MessagesStorage} = {}; // will be used for albums - public scheduledMessagesStorage: {[peerId: string]: MessagesStorage} = {}; - public historiesStorage: { + private scheduledMessagesStorage: {[peerId: string]: MessagesStorage} = {}; + private historiesStorage: { [peerId: string]: HistoryStorage } = {}; - public threadsStorage: { + private threadsStorage: { [peerId: string]: { [threadId: string]: HistoryStorage } } = {}; - public searchesStorage: { + private searchesStorage: { [peerId: string]: Partial<{ [inputFilter in MyInputMessagesFilter]: { count?: number, @@ -134,11 +134,11 @@ export class AppMessagesManager { public pinnedMessages: {[peerId: string]: PinnedStorage} = {}; public threadsServiceMessagesIdsStorage: {[peerId_threadId: string]: number} = {}; - public threadsToReplies: { + private threadsToReplies: { [peerId_threadId: string]: string; } = {}; - public pendingByRandomId: { + private pendingByRandomId: { [randomId: string]: { peerId: number, tempId: number, @@ -146,12 +146,11 @@ export class AppMessagesManager { storage: MessagesStorage } } = {}; - public pendingByMessageId: {[mid: string]: string} = {}; - public pendingAfterMsgs: any = {}; + private pendingByMessageId: {[mid: string]: string} = {}; + private pendingAfterMsgs: any = {}; public pendingTopMsgs: {[peerId: string]: number} = {}; - public sendFilePromise: CancellablePromise = Promise.resolve(); - public tempNum = 0; - public tempFinalizeCallbacks: { + private tempNum = 0; + private tempFinalizeCallbacks: { [tempId: string]: { [callbackName: string]: Partial<{ deferred: CancellablePromise, @@ -160,20 +159,20 @@ export class AppMessagesManager { } } = {}; - public sendSmthLazyLoadQueue = new LazyLoadQueueBase(1); + private sendSmthLazyLoadQueue = new LazyLoadQueueBase(1); - public needSingleMessages: {[peerId: string]: number[]} = {}; + private needSingleMessages: {[peerId: string]: number[]} = {}; private fetchSingleMessagesPromise: Promise = null; - public maxSeenId = 0; + private maxSeenId = 0; public migratedFromTo: {[peerId: number]: number} = {}; public migratedToFrom: {[peerId: number]: number} = {}; - public newMessagesHandleTimeout = 0; - public newMessagesToHandle: {[peerId: string]: Set} = {}; - public newDialogsHandlePromise: Promise; - public newDialogsToHandle: {[peerId: string]: Dialog} = {}; + private newMessagesHandleTimeout = 0; + private newMessagesToHandle: {[peerId: string]: Set} = {}; + private newDialogsHandlePromise: Promise; + private newDialogsToHandle: {[peerId: string]: Dialog} = {}; public newUpdatesAfterReloadToHandle: {[peerId: string]: Set} = {}; private notificationsHandlePromise = 0; @@ -4371,7 +4370,8 @@ export class AppMessagesManager { const photo = appPhotosManager.getPhoto('' + tempId); if(/* photo._ !== 'photoEmpty' */photo) { const newPhoto = message.media.photo as MyPhoto; - const cacheContext = appDownloadManager.getCacheContext(newPhoto); + const newPhotoSize = newPhoto.sizes[newPhoto.sizes.length - 1]; + const cacheContext = appDownloadManager.getCacheContext(newPhoto, newPhotoSize.type); const oldCacheContext = appDownloadManager.getCacheContext(photo, 'full'); Object.assign(cacheContext, oldCacheContext); diff --git a/src/lib/appManagers/appPhotosManager.ts b/src/lib/appManagers/appPhotosManager.ts index 28909a66..6d2a23ff 100644 --- a/src/lib/appManagers/appPhotosManager.ts +++ b/src/lib/appManagers/appPhotosManager.ts @@ -279,7 +279,7 @@ export class AppPhotosManager { const sizes = (photo as MyPhoto).sizes || (photo as MyDocument).thumbs; const thumb = sizes?.length ? sizes.find(size => size._ === 'photoStrippedSize') : null; if(thumb && ('bytes' in thumb)) { - return appPhotosManager.getImageFromStrippedThumb(photo, thumb as any, useBlur); + return this.getImageFromStrippedThumb(photo, thumb as any, useBlur); } } @@ -407,5 +407,5 @@ export class AppPhotosManager { } const appPhotosManager = new AppPhotosManager(); -MOUNT_CLASS_TO.appPhotosManager = appPhotosManager; +MOUNT_CLASS_TO && (MOUNT_CLASS_TO.appPhotosManager = appPhotosManager); export default appPhotosManager; diff --git a/src/scss/partials/_chatBubble.scss b/src/scss/partials/_chatBubble.scss index 2b63e051..c7c80fa0 100644 --- a/src/scss/partials/_chatBubble.scss +++ b/src/scss/partials/_chatBubble.scss @@ -608,6 +608,7 @@ $bubble-margin: .25rem; &-aspecter { position: relative; margin: 0 auto; + z-index: 1; } &-fitted { diff --git a/src/scss/style.scss b/src/scss/style.scss index b1512591..91cf267a 100644 --- a/src/scss/style.scss +++ b/src/scss/style.scss @@ -582,6 +582,16 @@ input:-webkit-autofill:active { } } +@keyframes thumbnail-fade-in-opacity { + 0% { + opacity: 0; + } + + to { + opacity: .8; + } +} + @keyframes fade-in-opacity { 0% { opacity: 0; @@ -1143,6 +1153,14 @@ middle-ellipsis-element { } } +.media-photo.thumbnail { + @include animation-level(2) { + &.fade-in { + animation: thumbnail-fade-in-opacity .2s ease-in-out forwards; + } + } +} + .media-video { z-index: 1; // * overflow media-photo }