Message: Allow empty typing drafts (#6954)

This commit is contained in:
zubiden 2026-06-01 01:15:41 +02:00 committed by Alexander Zinchuk
parent b7e10507e6
commit 6a8ca9b97b
5 changed files with 17 additions and 5 deletions

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 60" width="48" height="60" class="lottie-svg" preserveAspectRatio="xMidYMid meet" style="width: 100%; height: 100%; transform: translate3d(0px, 0px, 0px); content-visibility: visible;"><defs><clipPath id="__lottie_element_17"><rect width="48" height="60" x="0" y="0"></rect></clipPath><clipPath id="__lottie_element_19"><path d="M0,0 L512,0 L512,512 L0,512z"></path></clipPath></defs><g clip-path="url(#__lottie_element_17)"><g clip-path="url(#__lottie_element_19)" transform="matrix(0.0949999988079071,0,0,0.0949999988079071,-0.31999969482421875,18.68000030517578)" opacity="1" style="display: block;"><g transform="matrix(1,0,0,1,291,256)" opacity="1" style="display: block;"><g opacity="1" transform="matrix(1,0,0,1,0,0)"><path fill="rgb(0,0,0)" fill-opacity="1" d=" M102.4000015258789,-32 C120.072998046875,-32 134.39999389648438,-17.67300033569336 134.39999389648438,0 C134.39999389648438,17.67300033569336 120.072998046875,32 102.4000015258789,32 C84.72699737548828,32 70.4000015258789,17.67300033569336 70.4000015258789,0 C70.4000015258789,-17.67300033569336 84.72699737548828,-32 102.4000015258789,-32z"></path></g></g><g transform="matrix(1,0,0,1,256,256)" opacity="1" style="display: block;"><g opacity="1" transform="matrix(1,0,0,1,0,0)"><path fill="rgb(0,0,0)" fill-opacity="1" d=" M0,-32 C17.67300033569336,-32 32,-17.67300033569336 32,0 C32,17.67300033569336 17.67300033569336,32 0,32 C-17.67300033569336,32 -32,17.67300033569336 -32,0 C-32,-17.67300033569336 -17.67300033569336,-32 0,-32z"></path></g></g><g transform="matrix(1,0,0,1,221,256)" opacity="1" style="display: block;"><g opacity="1" transform="matrix(1,0,0,1,0,0)"><path fill="rgb(0,0,0)" fill-opacity="1" d=" M-102.4000015258789,-32 C-84.72699737548828,-32 -70.4000015258789,-17.67300033569336 -70.4000015258789,0 C-70.4000015258789,17.67300033569336 -84.72699737548828,32 -102.4000015258789,32 C-120.072998046875,32 -134.39999389648438,17.67300033569336 -134.39999389648438,0 C-134.39999389648438,-17.67300033569336 -120.072998046875,-32 -102.4000015258789,-32z"></path></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -20,6 +20,11 @@
} }
} }
.fullyRevealed {
--typing-draft-progress: 100%;
--typing-draft-spread: 0%;
}
.placeholder { .placeholder {
display: inline-block; display: inline-block;
width: 1.25rem; width: 1.25rem;

View File

@ -6,7 +6,8 @@ import {
import type { ApiFormattedText } from '../../api/types'; import type { ApiFormattedText } from '../../api/types';
import { requestMutation } from '../../lib/fasterdom/fasterdom'; import { requestMutation } from '../../lib/fasterdom/fasterdom';
import { LOCAL_TGS_URLS } from './helpers/animatedAssets'; import buildClassName from '../../util/buildClassName';
import { LOCAL_TGS_PREVIEW_URLS, LOCAL_TGS_URLS } from './helpers/animatedAssets';
import { REM } from './helpers/mediaDimensions'; import { REM } from './helpers/mediaDimensions';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
@ -57,9 +58,11 @@ const TypingWrapper = ({
renderText, renderText,
onCompleted, onCompleted,
}: OwnProps) => { }: OwnProps) => {
const fullText = formattedText.text;
const ref = useRef<HTMLSpanElement>(); const ref = useRef<HTMLSpanElement>();
const animationRef = useRef<Animation>(); const animationRef = useRef<Animation>();
const progressRef = useRef(0); const progressRef = useRef(fullText ? 0 : 100);
const prevRevealedRef = useRef(0); const prevRevealedRef = useRef(0);
const fullTextRef = useRef(''); const fullTextRef = useRef('');
@ -69,7 +72,6 @@ const TypingWrapper = ({
const completedKeyRef = useRef<string>(); const completedKeyRef = useRef<string>();
const prevFullTextRef = useRef(''); const prevFullTextRef = useRef('');
const fullText = formattedText.text;
fullTextRef.current = fullText; fullTextRef.current = fullText;
const stopAnimation = useLastCallback(() => { const stopAnimation = useLastCallback(() => {
@ -244,14 +246,16 @@ const TypingWrapper = ({
text: fullText.slice(0, revealedLength), text: fullText.slice(0, revealedLength),
entities: formattedText.entities, entities: formattedText.entities,
}), [fullText, formattedText.entities, revealedLength]); }), [fullText, formattedText.entities, revealedLength]);
const className = buildClassName(styles.root, !fullText && styles.fullyRevealed);
return ( return (
<span ref={ref} className={styles.root}> <span ref={ref} className={className}>
{renderText(truncatedText)} {renderText(truncatedText)}
{shouldRenderPlaceholder && ( {shouldRenderPlaceholder && (
<span key="typing-placeholder" className={styles.placeholder}> <span key="typing-placeholder" className={styles.placeholder}>
<AnimatedIconWithPreview <AnimatedIconWithPreview
tgsUrl={LOCAL_TGS_URLS.Writing} tgsUrl={LOCAL_TGS_URLS.Writing}
previewUrl={LOCAL_TGS_PREVIEW_URLS.Writing}
size={PLACEHOLDER_SIZE} size={PLACEHOLDER_SIZE}
play play
noLoop={false} noLoop={false}

View File

@ -45,6 +45,7 @@ import StarReaction from '../../../assets/tgs/stars/StarReaction.tgs';
import StarReactionEffect from '../../../assets/tgs/stars/StarReactionEffect.tgs'; import StarReactionEffect from '../../../assets/tgs/stars/StarReactionEffect.tgs';
import Unlock from '../../../assets/tgs/Unlock.tgs'; import Unlock from '../../../assets/tgs/Unlock.tgs';
import DuckNothingFoundPreview from '../../../assets/tgs-previews/DuckNothingFound.svg'; import DuckNothingFoundPreview from '../../../assets/tgs-previews/DuckNothingFound.svg';
import WritingPreview from '../../../assets/tgs-previews/message/Writing.svg';
import SearchPreview from '../../../assets/tgs-previews/Search.svg'; import SearchPreview from '../../../assets/tgs-previews/Search.svg';
import HandStopPreview from '../../../assets/tgs-previews/settings/HandStopPreview.png'; import HandStopPreview from '../../../assets/tgs-previews/settings/HandStopPreview.png';
import PasskeysPreview from '../../../assets/tgs-previews/settings/Passkeys.svg'; import PasskeysPreview from '../../../assets/tgs-previews/settings/Passkeys.svg';
@ -55,6 +56,7 @@ export const LOCAL_TGS_PREVIEW_URLS = {
DuckNothingFound: DuckNothingFoundPreview, DuckNothingFound: DuckNothingFoundPreview,
Search: SearchPreview, Search: SearchPreview,
Passkeys: PasskeysPreview, Passkeys: PasskeysPreview,
Writing: WritingPreview,
}; };
export const LOCAL_TGS_URLS = { export const LOCAL_TGS_URLS = {

View File

@ -1129,7 +1129,7 @@ const Message = ({
observeIntersectionForPlaying={observeIntersectionForPlaying} observeIntersectionForPlaying={observeIntersectionForPlaying}
withTranslucentThumbs={isCustomShape} withTranslucentThumbs={isCustomShape}
isInSelectMode={isInSelectMode} isInSelectMode={isInSelectMode}
canBeEmpty={hasFactCheck} canBeEmpty={hasFactCheck || isTypingDraft}
maxTimestamp={maxTimestamp} maxTimestamp={maxTimestamp}
threadId={threadId} threadId={threadId}
shouldAnimateTyping={isTypingDraft} shouldAnimateTyping={isTypingDraft}