Skip to content

Commit aa5be02

Browse files
committed
Ability to expand quote in translations
1 parent 3eb8528 commit aa5be02

File tree

4 files changed

+94
-52
lines changed

4 files changed

+94
-52
lines changed

src/components/appMediaViewer.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {i18n} from '@lib/langPack';
3838
import wrapEmojiText from '@richTextProcessor/wrapEmojiText';
3939
import wrapWebPageDescription from '@components/wrappers/webPageDescription';
4040
import Button from '@components/button';
41+
import onQuoteClick from '@helpers/dom/onQuoteClick';
4142

4243
type AppMediaViewerTargetType = {
4344
element: HTMLElement,
@@ -49,12 +50,20 @@ type AppMediaViewerTargetType = {
4950

5051
export const onMediaCaptionClick = (caption: HTMLElement, e: MouseEvent) => {
5152
const a = findUpTag(e.target, 'A');
53+
const spoiler = findUpClassName(e.target, 'spoiler');
54+
const quoteDiv = findUpClassName(e.target, 'quote-like-collapsable');
55+
const isSpoilerVisible = caption.classList.contains('is-spoiler-visible');
56+
if(quoteDiv && !a && (!spoiler || isSpoilerVisible)) {
57+
if(onQuoteClick(e, quoteDiv)) {
58+
return;
59+
}
60+
}
61+
5262
if(!a || a.classList.contains('timestamp')) {
5363
return;
5464
}
5565

56-
const spoiler = findUpClassName(e.target, 'spoiler');
57-
if(a instanceof HTMLAnchorElement && (!spoiler || caption.classList.contains('is-spoiler-visible'))) { // close viewer if it's t.me/ redirect
66+
if(a instanceof HTMLAnchorElement && (!spoiler || isSpoilerVisible)) { // close viewer if it's t.me/ redirect
5867
const onclick = a.getAttribute('onclick');
5968
if(!onclick || onclick.includes('showMaskedAlert')) {
6069
return;

src/components/chat/bubbles.ts

Lines changed: 5 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ import {setPeerColorToElement} from '@components/peerColors';
218218
import {showStarGiftOfferButtons, StarGiftOfferBubble, StarGiftOfferReplyMarkup} from '@components/chat/bubbles/starGiftOffer';
219219
import {wrapSolidComponent} from '@helpers/solid/wrapSolidComponent';
220220
import wrapDice from '@components/chat/bubbleParts/dice';
221+
import animateSomethingWithScroll from '@helpers/animateSomethingWithScroll';
222+
import onQuoteClick from '@helpers/dom/onQuoteClick';
221223

222224
export type BubbleContext = {
223225
bubble: HTMLElement,
@@ -2715,41 +2717,8 @@ export default class ChatBubbles {
27152717

27162718
const quoteDiv: HTMLElement = findUpClassName(target, 'quote-like-collapsable');
27172719
if(quoteDiv) {
2718-
const isTruncated = quoteDiv.classList.contains('is-truncated');
2719-
const isExpanded = quoteDiv.classList.contains('is-expanded');
2720-
const isGood = isTruncated || isExpanded;
2721-
if(isGood && window.getSelection().isCollapsed) {
2722-
cancelEvent(e);
2723-
2724-
const hasAnimations = liteMode.isAvailable('animations');
2725-
if(hasAnimations) {
2726-
(quoteDiv as any).ignoreQuoteResize = Infinity;
2727-
}
2728-
2729-
const scrollSaver = this.createScrollSaver(true);
2730-
scrollSaver.save();
2731-
2732-
let onTransitionEnd: (e: TransitionEvent) => void;
2733-
2734-
const animationPromise = hasAnimations ? Promise.race([
2735-
pause(1000).then(() => {
2736-
quoteDiv.removeEventListener('transitionend', onTransitionEnd);
2737-
}),
2738-
new Promise<void>((resolve) => {
2739-
onTransitionEnd = (e: TransitionEvent) => {
2740-
if(e.target === quoteDiv) {
2741-
resolve();
2742-
delete (quoteDiv as any).ignoreQuoteResize;
2743-
}
2744-
};
2745-
2746-
quoteDiv.addEventListener('transitionend', onTransitionEnd, {once: true});
2747-
})
2748-
]) : Promise.resolve();
2749-
2750-
this.animateSomethingWithScroll(animationPromise, scrollSaver);
2751-
quoteDiv.classList.toggle('is-expanded');
2752-
quoteDiv.classList.toggle('is-truncated', isExpanded);
2720+
const isGood = onQuoteClick(e, quoteDiv, this.scrollable, () => this.createScrollSaver(true));
2721+
if(isGood) {
27532722
return;
27542723
}
27552724
}
@@ -3800,21 +3769,7 @@ export default class ChatBubbles {
38003769
scrollSaver.save();
38013770
}
38023771

3803-
let finished = false;
3804-
promise.then(() => {
3805-
finished = true;
3806-
});
3807-
3808-
dispatchHeavyAnimationEvent(promise);
3809-
3810-
scrollSaver && animateSingle(() => {
3811-
if(finished) {
3812-
return false;
3813-
}
3814-
3815-
scrollSaver.restore();
3816-
return true;
3817-
}, this.scrollable.container);
3772+
animateSomethingWithScroll(promise, this.scrollable, scrollSaver);
38183773
}
38193774

38203775
public deleteMessagesByIds(fullMids: FullMid[], permanent = true, ignoreOnScroll?: boolean) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Scrollable from '@components/scrollable';
2+
import {animateSingle} from '@helpers/animation';
3+
import ScrollSaver from '@helpers/scrollSaver';
4+
import {dispatchHeavyAnimationEvent} from '@hooks/useHeavyAnimationCheck';
5+
6+
export default function animateSomethingWithScroll(promise: Promise<any>, scrollable: Scrollable, scrollSaver: ScrollSaver) {
7+
let finished = false;
8+
promise.then(() => {
9+
finished = true;
10+
});
11+
12+
dispatchHeavyAnimationEvent(promise);
13+
14+
animateSingle(() => {
15+
if(finished) {
16+
return false;
17+
}
18+
19+
scrollSaver.restore();
20+
return true;
21+
}, scrollable.container);
22+
}

src/helpers/dom/onQuoteClick.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import Scrollable from '@components/scrollable';
2+
import animateSomethingWithScroll from '@helpers/animateSomethingWithScroll';
3+
import cancelEvent from '@helpers/dom/cancelEvent';
4+
import liteMode from '@helpers/liteMode';
5+
import pause from '@helpers/schedulers/pause';
6+
import ScrollSaver from '@helpers/scrollSaver';
7+
8+
export default function onQuoteClick(
9+
e: Event,
10+
quoteDiv: HTMLElement,
11+
scrollable?: Scrollable,
12+
createScrollSaver?: () => ScrollSaver
13+
) {
14+
const isTruncated = quoteDiv.classList.contains('is-truncated');
15+
const isExpanded = quoteDiv.classList.contains('is-expanded');
16+
const isGood = isTruncated || isExpanded;
17+
if(isGood && window.getSelection().isCollapsed) {
18+
cancelEvent(e);
19+
20+
if(createScrollSaver) {
21+
const hasAnimations = liteMode.isAvailable('animations');
22+
if(hasAnimations) {
23+
(quoteDiv as any).ignoreQuoteResize = Infinity;
24+
}
25+
26+
const scrollSaver = createScrollSaver();
27+
scrollSaver.save();
28+
29+
let onTransitionEnd: (e: TransitionEvent) => void;
30+
31+
const animationPromise = hasAnimations ? Promise.race([
32+
pause(1000).then(() => {
33+
quoteDiv.removeEventListener('transitionend', onTransitionEnd);
34+
}),
35+
new Promise<void>((resolve) => {
36+
onTransitionEnd = (e: TransitionEvent) => {
37+
if(e.target === quoteDiv) {
38+
resolve();
39+
delete (quoteDiv as any).ignoreQuoteResize;
40+
}
41+
};
42+
43+
quoteDiv.addEventListener('transitionend', onTransitionEnd, {once: true});
44+
})
45+
]) : Promise.resolve();
46+
47+
animateSomethingWithScroll(animationPromise, scrollable, scrollSaver);
48+
}
49+
50+
quoteDiv.classList.toggle('is-expanded');
51+
quoteDiv.classList.toggle('is-truncated', isExpanded);
52+
return true;
53+
}
54+
55+
return false;
56+
}

0 commit comments

Comments
 (0)