Story: Fix long caption blinking (#4099)
This commit is contained in:
parent
78dac9bbaf
commit
a75fc9be51
@ -1,13 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
memo, useEffect, useRef, useState,
|
memo, useEffect, useLayoutEffect, useRef, useState,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
import { addExtraClass, removeExtraClass } from '../../lib/teact/teact-dom';
|
import { addExtraClass, removeExtraClass } from '../../lib/teact/teact-dom';
|
||||||
|
|
||||||
import type { ApiStory } from '../../api/types';
|
import type { ApiStory } from '../../api/types';
|
||||||
|
|
||||||
import { requestMutation } from '../../lib/fasterdom/fasterdom';
|
import { requestForcedReflow, requestMeasure, requestMutation } from '../../lib/fasterdom/fasterdom';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import { REM } from '../common/helpers/mediaDimensions';
|
|
||||||
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import usePrevDuringAnimation from '../../hooks/usePrevDuringAnimation';
|
import usePrevDuringAnimation from '../../hooks/usePrevDuringAnimation';
|
||||||
@ -27,7 +26,6 @@ interface OwnProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const EXPAND_ANIMATION_DURATION_MS = 400;
|
const EXPAND_ANIMATION_DURATION_MS = 400;
|
||||||
const OVERFLOW_THRESHOLD_PX = 5.75 * REM;
|
|
||||||
const LINES_TO_SHOW = 3;
|
const LINES_TO_SHOW = 3;
|
||||||
|
|
||||||
function StoryCaption({
|
function StoryCaption({
|
||||||
@ -49,15 +47,6 @@ function StoryCaption({
|
|||||||
const prevIsExpanded = usePrevDuringAnimation(isExpanded || undefined, EXPAND_ANIMATION_DURATION_MS);
|
const prevIsExpanded = usePrevDuringAnimation(isExpanded || undefined, EXPAND_ANIMATION_DURATION_MS);
|
||||||
const isInExpandedState = isExpanded || prevIsExpanded;
|
const isInExpandedState = isExpanded || prevIsExpanded;
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!ref.current) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { clientHeight } = ref.current;
|
|
||||||
setHasOverflow(clientHeight > OVERFLOW_THRESHOLD_PX);
|
|
||||||
}, [caption]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
requestMutation(() => {
|
requestMutation(() => {
|
||||||
if (!contentRef.current) {
|
if (!contentRef.current) {
|
||||||
@ -77,26 +66,46 @@ function StoryCaption({
|
|||||||
canExpand, undefined, true, 'slow', true,
|
canExpand, undefined, true, 'slow', true,
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (!showMoreButtonRef.current || !contentRef.current || !textRef.current) {
|
requestMeasure(() => {
|
||||||
return;
|
if (!showMoreButtonRef.current) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const container = contentRef.current;
|
const button = showMoreButtonRef.current;
|
||||||
const textContainer = textRef.current;
|
|
||||||
|
|
||||||
const textOffsetTop = textContainer.offsetTop;
|
const { offsetWidth } = button;
|
||||||
const lineHeight = parseInt(getComputedStyle(textContainer).lineHeight, 10);
|
|
||||||
const overflowShift = textOffsetTop + lineHeight * LINES_TO_SHOW;
|
|
||||||
|
|
||||||
const button = showMoreButtonRef.current;
|
requestMutation(() => {
|
||||||
|
button.style.setProperty('--expand-button-width', `${offsetWidth}px`);
|
||||||
const { offsetWidth } = button;
|
});
|
||||||
requestMutation(() => {
|
|
||||||
container.style.setProperty('--_overflow-shift', `${overflowShift}px`);
|
|
||||||
container.style.setProperty('--expand-button-width', `${offsetWidth}px`);
|
|
||||||
});
|
});
|
||||||
}, [canExpand]);
|
}, []);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
requestForcedReflow(() => {
|
||||||
|
if (!contentRef.current || !textRef.current) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const container = contentRef.current;
|
||||||
|
const textContainer = textRef.current;
|
||||||
|
|
||||||
|
const textOffsetTop = textContainer.offsetTop;
|
||||||
|
const lineHeight = parseInt(getComputedStyle(textContainer).lineHeight, 10);
|
||||||
|
const isOverflowing = textContainer.clientHeight > lineHeight * LINES_TO_SHOW;
|
||||||
|
const overflowShift = textOffsetTop + lineHeight * LINES_TO_SHOW;
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (isOverflowing) {
|
||||||
|
addExtraClass(container, styles.hasOverflow);
|
||||||
|
setHasOverflow(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
container.style.setProperty('--_overflow-shift', `${overflowShift}px`);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}, [caption]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isExpanded) {
|
if (!isExpanded) {
|
||||||
@ -106,7 +115,6 @@ function StoryCaption({
|
|||||||
|
|
||||||
const fullClassName = buildClassName(
|
const fullClassName = buildClassName(
|
||||||
styles.captionContent,
|
styles.captionContent,
|
||||||
hasOverflow && !isExpanded && styles.hasOverflow,
|
|
||||||
isInExpandedState && styles.expanded,
|
isInExpandedState && styles.expanded,
|
||||||
shouldRenderShowMore && styles.withShowMore,
|
shouldRenderShowMore && styles.withShowMore,
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user