From a6364eba574f1a331b6d01df48231414610229d8 Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Sun, 5 Mar 2023 15:08:16 +0400 Subject: [PATCH] Fix playing timestamp on album item Fix wrapping message in grouped documents --- src/components/chat/bubbles.ts | 37 +++++++++++++------ src/components/wrappers/groupedDocuments.ts | 35 +++++++++++++++++- src/lib/appManagers/appImManager.ts | 2 +- .../messages/getMediaDurationFromMessage.ts | 7 ++++ 4 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 src/lib/appManagers/utils/messages/getMediaDurationFromMessage.ts diff --git a/src/components/chat/bubbles.ts b/src/components/chat/bubbles.ts index 15d90c51..99c7d284 100644 --- a/src/components/chat/bubbles.ts +++ b/src/components/chat/bubbles.ts @@ -133,6 +133,7 @@ import {PopupPeerCheckboxOptions} from '../popups/peer'; import toggleDisability from '../../helpers/dom/toggleDisability'; import {copyTextToClipboard} from '../../helpers/clipboard'; import liteMode from '../../helpers/liteMode'; +import getMediaDurationFromMessage from '../../lib/appManagers/utils/messages/getMediaDurationFromMessage'; export const USER_REACTIONS_INLINE = false; const USE_MEDIA_TAILS = false; @@ -735,7 +736,8 @@ export default class ChatBubbles { return; } - return {bubble: result.bubble, message, changedResults}; + // can be .document-container + return {bubble: findUpClassName(result.bubble, 'bubble'), message, changedResults}; }); let top: number; @@ -3303,15 +3305,22 @@ export default class ChatBubbles { return {cached, promise: setPeerPromise}; } - public playMediaWithTimestamp(bubble: HTMLElement, timestamp: number) { - const attachment = bubble.querySelector('.attachment'); + public playMediaWithTimestamp(element: HTMLElement, timestamp: number) { + const bubble = findUpClassName(element, 'bubble'); + const groupedItem = findUpClassName(element, 'grouped-item'); + const albumItemMid = groupedItem ? +groupedItem.dataset.mid : +bubble.dataset.textMid; + let attachment = bubble.querySelector('.attachment'); if(attachment) { + if(albumItemMid) { + attachment = attachment.querySelector(`[data-mid="${albumItemMid}"]`); + } + const media = attachment.querySelector('img, video, canvas'); this.checkTargetForMediaViewer(media, undefined, timestamp); return; } - const audio = bubble.querySelector('.audio'); + const audio = (groupedItem || bubble).querySelector('.audio'); if(audio) { audio.playWithTimestamp(timestamp); return; @@ -3874,10 +3883,10 @@ export default class ChatBubbles { let messageMedia: MessageMedia = isMessage && message.media; let needToSetHTML = true; - let messageMessage: string, totalEntities: MessageEntity[]; + let messageMessage: string, totalEntities: MessageEntity[], albumTextMessage: Message.message; if(isMessage) { if(groupedId && albumMustBeRenderedFull) { - const t = getAlbumText(albumMessages); + const t = albumTextMessage = getAlbumText(albumMessages); messageMessage = t?.message || ''; // totalEntities = t.entities; totalEntities = t?.totalEntities || []; @@ -3925,9 +3934,12 @@ export default class ChatBubbles { customEmojiSize ??= this.chat.appImManager.customEmojiSize; - const doc = (messageMedia as MessageMedia.messageMediaDocument)?.document as MyDocument; + const maxMediaTimestamp = needToSetHTML && getMediaDurationFromMessage(albumTextMessage || message as Message.message); + if(albumTextMessage && needToSetHTML) { + bubble.dataset.textMid = '' + albumTextMessage.mid; + } - const richText = wrapRichText(messageMessage, { + const richTextOptions: Parameters[1] = { entities: totalEntities, passEntities: this.passEntities, loadPromises, @@ -3935,8 +3947,10 @@ export default class ChatBubbles { customEmojiSize, middleware, animationGroup: this.chat.animationGroup, - maxMediaTimestamp: ((['voice', 'audio', 'video'] as MyDocument['type'][]).includes(doc?.type) && doc.duration) || undefined - }); + maxMediaTimestamp + }; + + const richText = messageMessage ? wrapRichText(messageMessage, richTextOptions) : ''; let canHaveTail = true; let isStandaloneMedia = false; @@ -4621,7 +4635,8 @@ export default class ChatBubbles { } : undefined, sizeType: 'documentName', fontSize: rootScope.settings.messagesTextSize, - richTextFragment: richText, + richTextFragment: typeof(richText) === 'string' ? undefined : richText, + richTextOptions, canTranscribeVoice: true }); diff --git a/src/components/wrappers/groupedDocuments.ts b/src/components/wrappers/groupedDocuments.ts index 2cae4af1..5686af37 100644 --- a/src/components/wrappers/groupedDocuments.ts +++ b/src/components/wrappers/groupedDocuments.ts @@ -8,12 +8,32 @@ import setInnerHTML from '../../helpers/dom/setInnerHTML'; import {MediaSizeType} from '../../helpers/mediaSizes'; import {Message} from '../../layer'; import {AppManagers} from '../../lib/appManagers/managers'; +import getMediaDurationFromMessage from '../../lib/appManagers/utils/messages/getMediaDurationFromMessage'; +import wrapRichText from '../../lib/richTextProcessor/wrapRichText'; import {MediaSearchContext} from '../appMediaPlaybackController'; import Chat from '../chat/chat'; import LazyLoadQueue from '../lazyLoadQueue'; import wrapDocument from './document'; -export default async function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble, messageDiv, chat, loadPromises, autoDownloadSize, lazyLoadQueue, searchContext, useSearch, sizeType, managers, fontWeight, fontSize, richTextFragment, canTranscribeVoice}: { +export default async function wrapGroupedDocuments({ + albumMustBeRenderedFull, + message, + bubble, + messageDiv, + chat, + loadPromises, + autoDownloadSize, + lazyLoadQueue, + searchContext, + useSearch, + sizeType, + managers, + fontWeight, + fontSize, + richTextFragment, + richTextOptions, + canTranscribeVoice +}: { albumMustBeRenderedFull: boolean, message: any, messageDiv: HTMLElement, @@ -30,6 +50,7 @@ export default async function wrapGroupedDocuments({albumMustBeRenderedFull, mes fontWeight?: number, fontSize?: number, richTextFragment?: DocumentFragment, + richTextOptions?: Parameters[1] canTranscribeVoice?: boolean }) { let nameContainer: HTMLElement; @@ -65,7 +86,17 @@ export default async function wrapGroupedDocuments({albumMustBeRenderedFull, mes const messageDiv = document.createElement('div'); messageDiv.classList.add('document-message'); - setInnerHTML(messageDiv, richTextFragment); + let fragment = richTextFragment; + if(!fragment) { + fragment = wrapRichText(message.message, { + ...richTextOptions, + entities: message.totalEntities, + maxMediaTimestamp: getMediaDurationFromMessage(message) + }); + } + + setInnerHTML(messageDiv, fragment); + wrapper.append(messageDiv); } diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts index f89df9aa..fff99305 100644 --- a/src/lib/appManagers/appImManager.ts +++ b/src/lib/appManagers/appImManager.ts @@ -630,7 +630,7 @@ export class AppImManager extends EventListenerBase<{ const timestamp = +element.dataset.timestamp; const bubble = findUpClassName(element, 'bubble'); if(bubble) { - this.chat.bubbles.playMediaWithTimestamp(bubble, timestamp); + this.chat.bubbles.playMediaWithTimestamp(element, timestamp); return; } diff --git a/src/lib/appManagers/utils/messages/getMediaDurationFromMessage.ts b/src/lib/appManagers/utils/messages/getMediaDurationFromMessage.ts new file mode 100644 index 00000000..e786bec9 --- /dev/null +++ b/src/lib/appManagers/utils/messages/getMediaDurationFromMessage.ts @@ -0,0 +1,7 @@ +import {Document, Message, MessageMedia} from '../../../../layer'; + +export default function getMediaDurationFromMessage(message: Message.message) { + const doc = (message.media as MessageMedia.messageMediaDocument)?.document as Document.document; + const duration = ((['voice', 'audio', 'video'] as Document.document['type'][]).includes(doc?.type) && doc.duration) || undefined; + return duration; +}