diff --git a/src/components/audio.ts b/src/components/audio.ts index 224ee4484..c49e61f19 100644 --- a/src/components/audio.ts +++ b/src/components/audio.ts @@ -209,7 +209,7 @@ async function wrapVoiceMessage(audioEl: AudioElement) { mousedown = false; } mousemove = false; - }) + }); progress.addEventListener('mousemove', (e) => { mousemove = true; if(mousedown) scrub(e); @@ -301,6 +301,7 @@ async function wrapAudio(audioEl: AudioElement) { const middleEllipsisEl = new MiddleEllipsisElement(); middleEllipsisEl.dataset.fontWeight = audioEl.dataset.fontWeight; + middleEllipsisEl.dataset.fontSize = audioEl.dataset.fontSize; middleEllipsisEl.dataset.sizeType = audioEl.dataset.sizeType; if(isVoice) { middleEllipsisEl.append(await wrapSenderToPeer(message)); diff --git a/src/components/chat/bubbles.ts b/src/components/chat/bubbles.ts index a958c5fa7..4fe04bbd8 100644 --- a/src/components/chat/bubbles.ts +++ b/src/components/chat/bubbles.ts @@ -528,7 +528,7 @@ export default class ChatBubbles { if(!tempMessage.media?.document?.thumbs?.length && doc.thumbs?.length) { getHeavyAnimationPromise().then(async() => { const timeSpan = div.querySelector('.time'); - const newDiv = await wrapDocument({message}); + const newDiv = await wrapDocument({message, fontSize: rootScope.settings.messagesTextSize}); div.replaceWith(newDiv); if(timeSpan) { @@ -3622,6 +3622,8 @@ export default class ChatBubbles { } } + customEmojiSize ??= this.chat.appImManager.customEmojiSize; + const richText = wrapRichText(messageMessage, { entities: totalEntities, passEntities: this.passEntities, @@ -4012,7 +4014,8 @@ export default class ChatBubbles { inputFilter: { _: 'inputMessagesFilterEmpty' } - } + }, + fontSize: rootScope.settings.messagesTextSize }); preview.append(docDiv); preview.classList.add('preview-with-document'); @@ -4227,7 +4230,8 @@ export default class ChatBubbles { useSearch: !(message as Message.message).pFlags.is_scheduled, isScheduled: (message as Message.message).pFlags.is_scheduled } : undefined, - sizeType: 'documentName' + sizeType: 'documentName', + fontSize: rootScope.settings.messagesTextSize }); if(newNameContainer) { diff --git a/src/components/middleEllipsis.ts b/src/components/middleEllipsis.ts index 47714d798..cf8db3783 100644 --- a/src/components/middleEllipsis.ts +++ b/src/components/middleEllipsis.ts @@ -89,8 +89,10 @@ function testElement(element: HTMLElement) { from = /* parseFloat(element.getAttribute(attributeName)) || */50; multiplier = from > 0 && from / 100; + let fontSize = element.dataset.fontSize; + if(fontSize) fontSize += 'px'; // const perf = performance.now(); - font = `${element.dataset.fontWeight || FontWeight} ${FontSize} ${FontFamily}`; + font = `${element.dataset.fontWeight || FontWeight} ${fontSize || FontSize} ${FontFamily}`; /* const computedStyle = window.getComputedStyle(elm, null); font = `${computedStyle.getPropertyValue('font-weight')} ${computedStyle.getPropertyValue('font-size')} ${computedStyle.getPropertyValue('font-family')}`; */ // console.log('testMiddleEllipsis get computed style:', performance.now() - perf, font); diff --git a/src/components/wrappers/document.ts b/src/components/wrappers/document.ts index 91910d23a..9d1c3d8b8 100644 --- a/src/components/wrappers/document.ts +++ b/src/components/wrappers/document.ts @@ -9,7 +9,6 @@ import {CancellablePromise} from '../../helpers/cancellablePromise'; import {clearBadCharsAndTrim} from '../../helpers/cleanSearchText'; import {formatFullSentTime} from '../../helpers/date'; import {simulateClickEvent, attachClickEvent} from '../../helpers/dom/clickEvent'; -import replaceContent from '../../helpers/dom/replaceContent'; import formatBytes from '../../helpers/formatBytes'; import {MediaSizeType} from '../../helpers/mediaSizes'; import noop from '../../helpers/noop'; @@ -43,7 +42,7 @@ rootScope.addEventListener('document_downloading', (docId) => { }); }); -export default async function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showSender, searchContext, loadPromises, autoDownloadSize, lazyLoadQueue, sizeType, managers = rootScope.managers, cacheContext}: { +export default async function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showSender, searchContext, loadPromises, autoDownloadSize, lazyLoadQueue, sizeType, managers = rootScope.managers, cacheContext, fontSize}: { message: Message.message, withTime?: boolean, fontWeight?: number, @@ -55,10 +54,11 @@ export default async function wrapDocument({message, withTime, fontWeight, voice lazyLoadQueue?: LazyLoadQueue, sizeType?: MediaSizeType, managers?: AppManagers, - cacheContext?: ThumbCache + cacheContext?: ThumbCache, + fontSize?: number }): Promise { - if(!fontWeight) fontWeight = 500; - if(!sizeType) sizeType = '' as any; + fontWeight ??= 500; + sizeType ??= '' as any; const noAutoDownload = autoDownloadSize === 0; const doc = ((message.media as MessageMedia.messageMediaDocument).document || ((message.media as MessageMedia.messageMediaWebPage).webpage as WebPage.webPage).document) as MyDocument; @@ -76,6 +76,7 @@ export default async function wrapDocument({message, withTime, fontWeight, voice if(showSender) audioElement.showSender = showSender; audioElement.dataset.fontWeight = '' + fontWeight; + audioElement.dataset.fontSize = '' + fontSize; audioElement.dataset.sizeType = sizeType; await audioElement.render(); return audioElement; @@ -177,6 +178,7 @@ export default async function wrapDocument({message, withTime, fontWeight, voice const nameDiv = docDiv.querySelector('.document-name') as HTMLElement; const middleEllipsisEl = new MiddleEllipsisElement(); middleEllipsisEl.dataset.fontWeight = '' + fontWeight; + middleEllipsisEl.dataset.fontSize = '' + fontSize; middleEllipsisEl.dataset.sizeType = sizeType; middleEllipsisEl.textContent = fileName; // setInnerHTML(middleEllipsisEl, fileName); diff --git a/src/components/wrappers/groupedDocuments.ts b/src/components/wrappers/groupedDocuments.ts index 4f69863b0..7239a7482 100644 --- a/src/components/wrappers/groupedDocuments.ts +++ b/src/components/wrappers/groupedDocuments.ts @@ -14,7 +14,7 @@ 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}: { +export default async function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble, messageDiv, chat, loadPromises, autoDownloadSize, lazyLoadQueue, searchContext, useSearch, sizeType, managers, fontWeight, fontSize}: { albumMustBeRenderedFull: boolean, message: any, messageDiv: HTMLElement, @@ -27,7 +27,9 @@ export default async function wrapGroupedDocuments({albumMustBeRenderedFull, mes searchContext?: MediaSearchContext, useSearch?: boolean, sizeType?: MediaSizeType, - managers?: AppManagers + managers?: AppManagers, + fontWeight?: number, + fontSize?: number }) { let nameContainer: HTMLElement; const mids = albumMustBeRenderedFull ? await chat.getMidsByMid(message.mid) : [message.mid]; @@ -44,7 +46,9 @@ export default async function wrapGroupedDocuments({albumMustBeRenderedFull, mes lazyLoadQueue, searchContext, sizeType, - managers + managers, + fontWeight, + fontSize }); const container = document.createElement('div'); diff --git a/src/helpers/canvas/getTextWidth.ts b/src/helpers/canvas/getTextWidth.ts index f91718f17..522d31b70 100644 --- a/src/helpers/canvas/getTextWidth.ts +++ b/src/helpers/canvas/getTextWidth.ts @@ -17,6 +17,9 @@ export default function getTextWidth(text: string, font: string) { if(!context) { const canvas = document.createElement('canvas'); context = canvas.getContext('2d', {alpha: false}); + } + + if(context.font !== font) { context.font = font; } diff --git a/src/helpers/mediaSizes.ts b/src/helpers/mediaSizes.ts index c4fd278e1..0d3ac171f 100644 --- a/src/helpers/mediaSizes.ts +++ b/src/helpers/mediaSizes.ts @@ -39,7 +39,7 @@ const MOBILE_SIZE = 600; const MEDIUM_SIZE = 1275; const LARGE_SIZE = 1680; -const CUSTOM_EMOJI_SIZE = makeMediaSize(18, 18); +const CUSTOM_EMOJI_SIZE = makeMediaSize(20, 20); const ESG_CUSTOM_EMOJI_SIZE = makeMediaSize(36, 36); const EMOJI_STATUS_SIZE = makeMediaSize(18, 18); diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts index b37a37db9..f043d8038 100644 --- a/src/lib/appManagers/appImManager.ts +++ b/src/lib/appManagers/appImManager.ts @@ -69,7 +69,7 @@ import uiNotificationsManager from './uiNotificationsManager'; import appMediaPlaybackController from '../../components/appMediaPlaybackController'; import {PHONE_NUMBER_REG_EXP} from '../richTextProcessor'; import wrapEmojiText from '../richTextProcessor/wrapEmojiText'; -import wrapRichText from '../richTextProcessor/wrapRichText'; +import wrapRichText, {CustomEmojiRendererElement, renderEmojis} from '../richTextProcessor/wrapRichText'; import wrapUrl from '../richTextProcessor/wrapUrl'; import generateMessageId from './utils/messageId/generateMessageId'; import getUserStatusString from '../../components/wrappers/getUserStatusString'; @@ -93,6 +93,8 @@ import {CLICK_EVENT_NAME} from '../../helpers/dom/clickEvent'; import PopupPayment from '../../components/popups/payment'; import wrapPeerTitle from '../../components/wrappers/peerTitle'; import NBSP from '../../helpers/string/nbsp'; +import {makeMediaSize, MediaSize} from '../../helpers/mediaSize'; +import {MiddleEllipsisElement} from '../../components/middleEllipsis'; export type ChatSavedPosition = { mids: number[], @@ -144,6 +146,7 @@ export class AppImManager extends EventListenerBase<{ public managers: AppManagers; public cacheStorage = new CacheStorageController('cachedFiles'); + public customEmojiSize: MediaSize; get myId() { return rootScope.myId; @@ -1365,7 +1368,26 @@ export class AppImManager extends EventListenerBase<{ } private setSettings = () => { - document.documentElement.style.setProperty('--messages-text-size', rootScope.settings.messagesTextSize + 'px'); + const {messagesTextSize} = rootScope.settings; + + this.customEmojiSize = makeMediaSize(messagesTextSize + 4, messagesTextSize + 4); + document.documentElement.style.setProperty('--messages-text-size', messagesTextSize + 'px'); + + const firstTime = !this.customEmojiSize; + if(!firstTime) { + const ellipsisElements = document.querySelectorAll('middle-ellipsis-element'); + ellipsisElements.forEach((element) => { + element.disconnectedCallback(); + element.dataset.fontSize = '' + messagesTextSize; + if(element.title) element.textContent = element.title; + element.connectedCallback(); + }); + + const renderers = document.querySelectorAll('.chat custom-emoji-renderer-element'); + renderers.forEach((renderer) => { + renderer.forceRenderAfterSize = true; + }); + } document.body.classList.toggle('animation-level-0', !rootScope.settings.animationsEnabled); document.body.classList.toggle('animation-level-1', false); diff --git a/src/lib/richTextProcessor/wrapRichText.ts b/src/lib/richTextProcessor/wrapRichText.ts index 15bb22d6a..2ef19c38c 100644 --- a/src/lib/richTextProcessor/wrapRichText.ts +++ b/src/lib/richTextProcessor/wrapRichText.ts @@ -225,6 +225,8 @@ export class CustomEmojiRendererElement extends HTMLElement { public ignoreSettingDimensions: boolean; + public forceRenderAfterSize: boolean; + constructor() { super(); @@ -278,7 +280,7 @@ export class CustomEmojiRendererElement extends HTMLElement { undefined; } - public getOffsets(offsetsMap: Map = new Map()) { + public getOffsets(offsetsMap: Map = new Map()) { if(!this.playersSynced.size) { return offsetsMap; } @@ -304,7 +306,7 @@ export class CustomEmojiRendererElement extends HTMLElement { const offsets = visible.map(({rect: elementRect}) => { const top = elementRect.top - rect.top; const left = elementRect.left - rect.left; - return {top, left}; + return {top, left, width: elementRect.width}; }); if(offsets.length) { @@ -368,6 +370,17 @@ export class CustomEmojiRendererElement extends HTMLElement { frameHeight = frame.height; } + // ! check performance of scaling + const elementWidth = Math.round(offsets[0].width * dpr); + if(elementWidth !== frameWidth) { + // if(this.size.width === 36) { + // console.warn('different width', elementWidth, frameWidth, this); + // } + + frameWidth = elementWidth; + frameHeight = elementWidth; + } + const maxTop = height - frameHeight; const maxLeft = width - frameWidth; @@ -388,7 +401,7 @@ export class CustomEmojiRendererElement extends HTMLElement { offsets.forEach(({top, left}) => { top = Math.round(top * dpr), left = Math.round(left * dpr); - if(/* top > maxTop || */left > maxLeft) { + if(left < 0 ||/* top > maxTop || */left > maxLeft) { return; } @@ -456,7 +469,8 @@ export class CustomEmojiRendererElement extends HTMLElement { this.isDimensionsSet = true; this.isCanvasClean = true; - if(this.isSelectable && forceRenderAfter) { + if(this.forceRenderAfterSize || (this.isSelectable && forceRenderAfter)) { + this.forceRenderAfterSize = undefined; this.forceRender(); } } diff --git a/src/scss/partials/_chat.scss b/src/scss/partials/_chat.scss index d80876673..eba20547a 100644 --- a/src/scss/partials/_chat.scss +++ b/src/scss/partials/_chat.scss @@ -178,6 +178,7 @@ $chat-input-border-radius: 1rem; } .input-message-input { + --custom-emoji-size: var(--messages-custom-emoji-size); background: none; border: none; width: 100%; diff --git a/src/scss/partials/_chatBubble.scss b/src/scss/partials/_chatBubble.scss index f3e981d95..20d5d7514 100644 --- a/src/scss/partials/_chatBubble.scss +++ b/src/scss/partials/_chatBubble.scss @@ -1143,7 +1143,17 @@ $bubble-beside-button-width: 38px; } .reply { - font-size: var(--messages-secondary-text-size); + --font-size: var(--messages-secondary-text-size); + } + + .document { + &-name { + font-size: var(--messages-text-size); + } + + &-size { + font-size: var(--messages-secondary-text-size); + } } &.is-square-photo { @@ -1291,6 +1301,7 @@ $bubble-beside-button-width: 38px; } .message { + --custom-emoji-size: var(--messages-custom-emoji-size); font-size: var(--messages-text-size); padding: 0 .5rem .375rem .625rem; max-width: 100%; @@ -1743,7 +1754,7 @@ $bubble-beside-button-width: 38px; background-color: var(--message-time-background); padding: 0 .3125rem; z-index: 2; - + .time { margin-left: 0; display: flex; @@ -1751,7 +1762,7 @@ $bubble-beside-button-width: 38px; padding: 0; margin: 0; white-space: nowrap; - height: 18px; + height: calc(var(--messages-time-text-size) + .375rem); .inner { right: unset; @@ -1811,7 +1822,8 @@ $bubble-beside-button-width: 38px; .time { visibility: hidden; // * can't use color transparent here, because in name can be emoji - font-size: 12px; + font-size: var(--messages-time-text-size); + height: var(--messages-time-text-size); user-select: none; line-height: 1; vertical-align: middle; @@ -1820,7 +1832,6 @@ $bubble-beside-button-width: 38px; z-index: 1; /* display: inline-flex; align-items: center; */ - height: 12px; direction: ltr; float: right; // * rtl fix cursor: pointer; @@ -1853,7 +1864,7 @@ $bubble-beside-button-width: 38px; line-height: 1; padding: inherit; white-space: nowrap; - height: 12px; // * as font-size + height: var(--messages-time-text-size); // * as font-size visibility: visible; } @@ -1884,12 +1895,12 @@ $bubble-beside-button-width: 38px; background-color: var(--message-time-background); padding: 0px 6px 0px 6px; z-index: 2; - font-size: 12px; + font-size: var(--messages-time-text-size); color: white; display: flex; align-items: center; user-select: none; - height: 1.125rem; + height: calc(var(--messages-time-text-size) + .375rem); line-height: 1; &.can-autoplay:after { @@ -1971,8 +1982,8 @@ $bubble-beside-button-width: 38px; font-weight: var(--font-weight-bold) !important; /* padding-bottom: 4px; */ color: var(--primary-color); - font-size: .875rem; - line-height: 1.25rem; + font-size: var(--messages-secondary-text-size); + line-height: calc(var(--messages-secondary-text-size) + .25rem); max-width: 100%; overflow: hidden; text-overflow: ellipsis; @@ -2284,10 +2295,10 @@ $bubble-beside-button-width: 38px; color: #fff; //background-color: rgba(0, 0, 0, .24); background-color: var(--message-highlightning-color); - font-size: .9375rem; + font-size: var(--messages-service-text-size); padding: .28125rem .625rem; // line-height: var(--line-height); - line-height: 1.25rem; + line-height: calc(var(--messages-service-text-size) + 5px); border-radius: inherit; user-select: none; display: flex; @@ -2579,10 +2590,10 @@ $bubble-beside-button-width: 38px; &:after, .inner:after { - font-size: 19px; + font-size: calc(var(--messages-text-size) + 3px); //vertical-align: middle; margin-left: 1px; - line-height: 16px; // of message + line-height: var(--messages-time-text-size); // of message color: var(--message-out-primary-color); } } diff --git a/src/scss/partials/_chatPinned.scss b/src/scss/partials/_chatPinned.scss index b5ad24228..1401bd41e 100644 --- a/src/scss/partials/_chatPinned.scss +++ b/src/scss/partials/_chatPinned.scss @@ -5,6 +5,8 @@ */ .pinned-message { + --custom-emoji-size: calc(var(--font-size) + 2px) !important; + &-border { position: relative; height: 2rem; @@ -123,6 +125,9 @@ .pinned-message, .reply { + --font-size: var(--font-size-14); + --custom-emoji-size: calc(var(--font-size) + 4px); + --line-height: calc(var(--font-size) + 4px); cursor: pointer; display: flex; align-items: center; @@ -143,6 +148,9 @@ pointer-events: none; position: relative; margin-left: .5rem; + display: flex; + flex-direction: column; + justify-content: center; } &-title { @@ -151,8 +159,8 @@ &-title, &-subtitle { - font-size: var(--font-size-14); - line-height: var(--line-height-14); + font-size: var(--font-size); + line-height: var(--line-height); position: relative; // ! WARNING (for custom emoji) @include text-overflow(); @@ -214,7 +222,7 @@ } */ &-border { - height: 2rem; + height: calc(var(--font-size) * 2 + .25rem); border-radius: 1px; min-width: 2px; background: var(--primary-color); @@ -480,7 +488,7 @@ } &-title { - margin-top: -.125rem; + // margin-top: -.125rem; margin-bottom: .25rem; } diff --git a/src/scss/partials/_customEmoji.scss b/src/scss/partials/_customEmoji.scss index 7d15b9d1c..56014eb66 100644 --- a/src/scss/partials/_customEmoji.scss +++ b/src/scss/partials/_customEmoji.scss @@ -55,8 +55,8 @@ &-placeholder { display: inline; - width: 18px; - height: 18px; + width: var(--messages-custom-emoji-size); + height: var(--messages-custom-emoji-size); vertical-align: middle; margin-top: -.125rem; } diff --git a/src/scss/style.scss b/src/scss/style.scss index 06aac67b6..3e583fca5 100644 --- a/src/scss/style.scss +++ b/src/scss/style.scss @@ -88,6 +88,9 @@ $chat-input-inner-padding-handhelds: .25rem; --messages-text-size: 16px; --messages-secondary-text-size: calc(var(--messages-text-size) - 2px); --messages-secondary-line-height: calc(var(--messages-secondary-text-size) + 4px); + --messages-time-text-size: calc(var(--messages-text-size) - 4px); + --messages-service-text-size: calc(var(--messages-text-size) - 1px); + --messages-custom-emoji-size: calc(var(--messages-text-size) + 4px); --bubble-transition-in: transform var(--transition-standard-in), opacity var(--transition-standard-in); --bubble-transition-out: transform var(--transition-standard-out), opacity var(--transition-standard-out); --line-height: 1.3125; @@ -118,7 +121,7 @@ $chat-input-inner-padding-handhelds: .25rem; --call-button-size: 3.375rem; --call-button-margin: 2rem; - --custom-emoji-size: 1.125rem; + --custom-emoji-size: 1.25rem; // https://github.com/overtake/TelegramSwift/blob/5cc7d2475fe4738a6aa0486c23eaf80a89d33b97/submodules/TGUIKit/TGUIKit/PresentationTheme.swift#L2054 --peer-avatar-red-top: #ff885e;