Browse Source

Fix collapsed document file name after animation

master
Eduard Kuzmenko 3 years ago
parent
commit
c30aa30bd2
  1. 1
      src/components/audio.ts
  2. 4
      src/components/chat/bubbles.ts
  3. 74
      src/components/middleEllipsis.ts
  4. 16
      src/components/wrappers.ts
  5. 21
      src/helpers/canvas/getTextWidth.ts
  6. 11
      src/helpers/mediaSizes.ts

1
src/components/audio.ts

@ -295,6 +295,7 @@ function wrapAudio(audioEl: AudioElement) {
const middleEllipsisEl = new MiddleEllipsisElement(); const middleEllipsisEl = new MiddleEllipsisElement();
middleEllipsisEl.dataset.fontWeight = audioEl.dataset.fontWeight; middleEllipsisEl.dataset.fontWeight = audioEl.dataset.fontWeight;
middleEllipsisEl.dataset.sizeType = audioEl.dataset.sizeType;
if(isVoice) { if(isVoice) {
middleEllipsisEl.append(appMessagesManager.wrapSenderToPeer(message)); middleEllipsisEl.append(appMessagesManager.wrapSenderToPeer(message));
} else { } else {

4
src/components/chat/bubbles.ts

@ -3369,7 +3369,8 @@ export default class ChatBubbles {
message: message as Message.message, message: message as Message.message,
autoDownloadSize: this.chat.autoDownload.file, autoDownloadSize: this.chat.autoDownload.file,
lazyLoadQueue: this.lazyLoadQueue, lazyLoadQueue: this.lazyLoadQueue,
loadPromises loadPromises,
sizeType: 'documentName'
}); });
preview.append(docDiv); preview.append(docDiv);
preview.classList.add('preview-with-document'); preview.classList.add('preview-with-document');
@ -3578,6 +3579,7 @@ export default class ChatBubbles {
useSearch: !(message as Message.message).pFlags.is_scheduled, useSearch: !(message as Message.message).pFlags.is_scheduled,
isScheduled: (message as Message.message).pFlags.is_scheduled isScheduled: (message as Message.message).pFlags.is_scheduled
} : undefined, } : undefined,
sizeType: 'documentName'
}); });
if(newNameContainer) { if(newNameContainer) {

74
src/components/middleEllipsis.ts

@ -4,7 +4,10 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE * https://github.com/morethanwords/tweb/blob/master/LICENSE
*/ */
import getTextWidth from "../helpers/canvas/getTextWidth";
import mediaSizes, { MediaSize } from "../helpers/mediaSizes";
import clamp from "../helpers/number/clamp"; import clamp from "../helpers/number/clamp";
import { fastRaf } from "../helpers/schedulers";
// Thanks to https://stackoverflow.com/a/49349813 // Thanks to https://stackoverflow.com/a/49349813
@ -32,17 +35,24 @@ const map: Map<HTMLElement, {
const testQueue: Set<HTMLElement> = new Set(); const testQueue: Set<HTMLElement> = new Set();
export const fontFamily = 'Roboto, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif'; export const fontFamily = 'Roboto, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif';
const fontSize = '16px'; const fontSize = '16px';
let timeoutId: number; let pendingTest = false;
const setTestQueue = () => { function setTestQueue() {
cancelAnimationFrame(timeoutId); if(pendingTest) {
timeoutId = window.requestAnimationFrame(testQueueElements); return;
}; }
pendingTest = true;
fastRaf(() => {
pendingTest = false;
testQueueElements();
});
}
const testQueueElements = () => { function testQueueElements() {
testQueue.forEach(testElement); testQueue.forEach(testElement);
testQueue.clear(); testQueue.clear();
}; }
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
for(const [key] of map) { for(const [key] of map) {
@ -52,7 +62,19 @@ window.addEventListener('resize', () => {
setTestQueue(); setTestQueue();
}, {capture: true, passive: true}); }, {capture: true, passive: true});
const testElement = (element: HTMLElement) => { function getElementWidth(element: HTMLElement) {
const type = element.dataset.sizeType;
if(type) {
const mediaSize = mediaSizes.active;
// @ts-ignore
const size: MediaSize = mediaSize[type];
return size.width;
}
return element.getBoundingClientRect().width;
}
function testElement(element: HTMLElement) {
//const perf = performance.now(); //const perf = performance.now();
// do not recalculate variables a second time // do not recalculate variables a second time
let mapped = map.get(element); let mapped = map.get(element);
@ -75,7 +97,7 @@ const testElement = (element: HTMLElement) => {
textWidth = getTextWidth(text, font); textWidth = getTextWidth(text, font);
//const perf = performance.now(); //const perf = performance.now();
elementWidth = element.getBoundingClientRect().width; elementWidth = getElementWidth(element);
//console.log('testMiddleEllipsis get offsetWidth:', performance.now() - perf, font); //console.log('testMiddleEllipsis get offsetWidth:', performance.now() - perf, font);
mapped = {text, textLength, from, multiplier, font, textWidth, elementWidth}; mapped = {text, textLength, from, multiplier, font, textWidth, elementWidth};
map.set(element, mapped); map.set(element, mapped);
@ -83,7 +105,7 @@ const testElement = (element: HTMLElement) => {
//console.log('[MEE] testElement map set', element); //console.log('[MEE] testElement map set', element);
} }
const newElementWidth = element.getBoundingClientRect().width; const newElementWidth = getElementWidth(element);
const widthChanged = firstTime || elementWidth !== newElementWidth; const widthChanged = firstTime || elementWidth !== newElementWidth;
!firstTime && widthChanged && (mapped.elementWidth = elementWidth = newElementWidth); !firstTime && widthChanged && (mapped.elementWidth = elementWidth = newElementWidth);
@ -108,7 +130,7 @@ const testElement = (element: HTMLElement) => {
} }
// * set new width after cutting text // * set new width after cutting text
mapped.elementWidth = element.getBoundingClientRect().width; mapped.elementWidth = getElementWidth(element);
//mapped.textWidth = smallerWidth; //mapped.textWidth = smallerWidth;
} else { } else {
element.removeAttribute('title'); element.removeAttribute('title');
@ -116,40 +138,19 @@ const testElement = (element: HTMLElement) => {
} }
//console.log('testMiddleEllipsis for element:', elm, performance.now() - perf); //console.log('testMiddleEllipsis for element:', elm, performance.now() - perf);
};
let context: CanvasRenderingContext2D;
/**
* Get the text width
* @param {string} text
* @param {string} font
*/
function getTextWidth(text: string, font: string) {
//const perf = performance.now();
if(!context) {
const canvas = document.createElement('canvas');
context = canvas.getContext('2d');
context.font = font;
}
//context.font = font;
const metrics = context.measureText(text);
//console.log('getTextWidth perf:', performance.now() - perf);
return metrics.width;
//return Math.round(metrics.width);
} }
export class MiddleEllipsisElement extends HTMLElement { export class MiddleEllipsisElement extends HTMLElement {
constructor() {
super();
}
connectedCallback() { connectedCallback() {
//console.log('[MEE]: connectedCallback before', map.has(this), testQueue.has(this), map.size, this.textContent, map); //console.log('[MEE]: connectedCallback before', map.has(this), testQueue.has(this), map.size, this.textContent, map);
map.set(this, null); map.set(this, null);
if(this.dataset.sizeType) {
testElement(this);
} else {
testQueue.add(this); testQueue.add(this);
setTestQueue(); setTestQueue();
}
//testElement(this); //testElement(this);
//console.log('[MEE]: connectedCallback after', map.has(this), map.size, testQueue.has(this), testQueue.size); //console.log('[MEE]: connectedCallback after', map.has(this), map.size, testQueue.has(this), testQueue.size);
@ -157,6 +158,7 @@ export class MiddleEllipsisElement extends HTMLElement {
disconnectedCallback() { disconnectedCallback() {
const deleted = map.delete(this); const deleted = map.delete(this);
testQueue.delete(this);
//console.log('[MEE]: disconnectedCallback', deleted, map.has(this), map.size, this.textContent, map); //console.log('[MEE]: disconnectedCallback', deleted, map.has(this), map.size, this.textContent, map);
} }
} }

16
src/components/wrappers.ts

@ -8,7 +8,7 @@ import type Chat from './chat/chat';
import { getEmojiToneIndex } from '../vendor/emoji'; import { getEmojiToneIndex } from '../vendor/emoji';
import { deferredPromise } from '../helpers/cancellablePromise'; import { deferredPromise } from '../helpers/cancellablePromise';
import { formatFullSentTime } from '../helpers/date'; import { formatFullSentTime } from '../helpers/date';
import mediaSizes, { ScreenSize } from '../helpers/mediaSizes'; import mediaSizes, { MediaSizeType, ScreenSize } from '../helpers/mediaSizes';
import { IS_SAFARI } from '../environment/userAgent'; import { IS_SAFARI } from '../environment/userAgent';
import { Message, MessageMedia, PhotoSize, StickerSet, WebPage } from '../layer'; import { Message, MessageMedia, PhotoSize, StickerSet, WebPage } from '../layer';
import appDocsManager, { MyDocument } from "../lib/appManagers/appDocsManager"; import appDocsManager, { MyDocument } from "../lib/appManagers/appDocsManager";
@ -570,7 +570,7 @@ rootScope.addEventListener('download_start', (docId) => {
}); });
}); });
export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showSender, searchContext, loadPromises, autoDownloadSize, lazyLoadQueue}: { export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showSender, searchContext, loadPromises, autoDownloadSize, lazyLoadQueue, sizeType}: {
message: Message.message, message: Message.message,
withTime?: boolean, withTime?: boolean,
fontWeight?: number, fontWeight?: number,
@ -579,9 +579,11 @@ export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showS
searchContext?: MediaSearchContext, searchContext?: MediaSearchContext,
loadPromises?: Promise<any>[], loadPromises?: Promise<any>[],
autoDownloadSize?: number, autoDownloadSize?: number,
lazyLoadQueue?: LazyLoadQueue lazyLoadQueue?: LazyLoadQueue,
sizeType?: MediaSizeType
}): HTMLElement { }): HTMLElement {
if(!fontWeight) fontWeight = 500; if(!fontWeight) fontWeight = 500;
if(!sizeType) sizeType = '' as any;
const noAutoDownload = autoDownloadSize === 0; const noAutoDownload = autoDownloadSize === 0;
const doc = ((message.media as MessageMedia.messageMediaDocument).document || ((message.media as MessageMedia.messageMediaWebPage).webpage as WebPage.webPage).document) as MyDocument; const doc = ((message.media as MessageMedia.messageMediaDocument).document || ((message.media as MessageMedia.messageMediaWebPage).webpage as WebPage.webPage).document) as MyDocument;
@ -600,6 +602,7 @@ export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showS
if(uploading) audioElement.preloader = (message.media as any).preloader; if(uploading) audioElement.preloader = (message.media as any).preloader;
audioElement.dataset.fontWeight = '' + fontWeight; audioElement.dataset.fontWeight = '' + fontWeight;
audioElement.dataset.sizeType = sizeType;
audioElement.render(); audioElement.render();
return audioElement; return audioElement;
} }
@ -671,6 +674,7 @@ export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showS
const nameDiv = docDiv.querySelector('.document-name') as HTMLElement; const nameDiv = docDiv.querySelector('.document-name') as HTMLElement;
const middleEllipsisEl = new MiddleEllipsisElement(); const middleEllipsisEl = new MiddleEllipsisElement();
middleEllipsisEl.dataset.fontWeight = '' + fontWeight; middleEllipsisEl.dataset.fontWeight = '' + fontWeight;
middleEllipsisEl.dataset.sizeType = sizeType;
middleEllipsisEl.innerHTML = fileName; middleEllipsisEl.innerHTML = fileName;
nameDiv.append(middleEllipsisEl); nameDiv.append(middleEllipsisEl);
@ -2033,7 +2037,7 @@ export function wrapAlbum({groupId, attachmentDiv, middleware, uploading, lazyLo
}); });
} }
export function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble, messageDiv, chat, loadPromises, autoDownloadSize, lazyLoadQueue, searchContext, useSearch}: { export function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble, messageDiv, chat, loadPromises, autoDownloadSize, lazyLoadQueue, searchContext, useSearch, sizeType}: {
albumMustBeRenderedFull: boolean, albumMustBeRenderedFull: boolean,
message: any, message: any,
messageDiv: HTMLElement, messageDiv: HTMLElement,
@ -2045,6 +2049,7 @@ export function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble,
lazyLoadQueue?: LazyLoadQueue, lazyLoadQueue?: LazyLoadQueue,
searchContext?: MediaSearchContext, searchContext?: MediaSearchContext,
useSearch?: boolean, useSearch?: boolean,
sizeType?: MediaSizeType
}) { }) {
let nameContainer: HTMLElement; let nameContainer: HTMLElement;
const mids = albumMustBeRenderedFull ? chat.getMidsByMid(message.mid) : [message.mid]; const mids = albumMustBeRenderedFull ? chat.getMidsByMid(message.mid) : [message.mid];
@ -2059,7 +2064,8 @@ export function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble,
loadPromises, loadPromises,
autoDownloadSize, autoDownloadSize,
lazyLoadQueue, lazyLoadQueue,
searchContext searchContext,
sizeType
}); });
const container = document.createElement('div'); const container = document.createElement('div');

21
src/helpers/canvas/getTextWidth.ts

@ -0,0 +1,21 @@
let context: CanvasRenderingContext2D;
/**
* Get the text width
* @param {string} text
* @param {string} font
*/
export default function getTextWidth(text: string, font: string) {
//const perf = performance.now();
if(!context) {
const canvas = document.createElement('canvas');
context = canvas.getContext('2d');
context.font = font;
}
//context.font = font;
const metrics = context.measureText(text);
//console.log('getTextWidth perf:', performance.now() - perf);
return metrics.width;
//return Math.round(metrics.width);
}

11
src/helpers/mediaSizes.ts

@ -39,9 +39,12 @@ type MediaTypeSizes = {
staticSticker: MediaSize, staticSticker: MediaSize,
emojiSticker: MediaSize, emojiSticker: MediaSize,
poll: MediaSize, poll: MediaSize,
round: MediaSize round: MediaSize,
documentName: MediaSize
}; };
export type MediaSizeType = keyof MediaTypeSizes;
export enum ScreenSize { export enum ScreenSize {
mobile, mobile,
medium, medium,
@ -72,7 +75,8 @@ class MediaSizes extends EventListenerBase<{
staticSticker: makeMediaSize(180, 180), staticSticker: makeMediaSize(180, 180),
emojiSticker: makeMediaSize(112, 112), emojiSticker: makeMediaSize(112, 112),
poll: makeMediaSize(240, 0), poll: makeMediaSize(240, 0),
round: makeMediaSize(200, 200) round: makeMediaSize(200, 200),
documentName: makeMediaSize(200, 0)
}, },
desktop: { desktop: {
regular: makeMediaSize(420, 340), regular: makeMediaSize(420, 340),
@ -83,7 +87,8 @@ class MediaSizes extends EventListenerBase<{
staticSticker: makeMediaSize(200, 200), staticSticker: makeMediaSize(200, 200),
emojiSticker: makeMediaSize(112, 112), emojiSticker: makeMediaSize(112, 112),
poll: makeMediaSize(330, 0), poll: makeMediaSize(330, 0),
round: makeMediaSize(280, 280) round: makeMediaSize(280, 280),
documentName: makeMediaSize(240, 0)
} }
}; };

Loading…
Cancel
Save