Sticker: Fix looping behavior (#4279)
This commit is contained in:
parent
ae9d09c762
commit
95f98442fc
@ -78,7 +78,7 @@ const CustomEmoji: FC<OwnProps> = ({
|
||||
const { customEmoji, canPlay } = useCustomEmoji(documentId);
|
||||
|
||||
const loopCountRef = useRef(0);
|
||||
const [shouldLoop, setShouldLoop] = useState(true);
|
||||
const [shouldPlay, setShouldPlay] = useState(true);
|
||||
|
||||
const hasCustomColor = customEmoji?.shouldUseTextColor;
|
||||
const customColor = useDynamicColorListener(containerRef, !hasCustomColor);
|
||||
@ -89,7 +89,7 @@ const CustomEmoji: FC<OwnProps> = ({
|
||||
loopCountRef.current += 1;
|
||||
|
||||
if (loopCountRef.current >= loopLimit) {
|
||||
setShouldLoop(false);
|
||||
setShouldPlay(false);
|
||||
e.currentTarget.currentTime = 0;
|
||||
} else {
|
||||
// Loop manually
|
||||
@ -102,9 +102,8 @@ const CustomEmoji: FC<OwnProps> = ({
|
||||
|
||||
loopCountRef.current += 1;
|
||||
|
||||
// Sticker plays 1 more time after disabling loop
|
||||
if (loopCountRef.current >= loopLimit - 1) {
|
||||
setShouldLoop(false);
|
||||
if (loopCountRef.current >= loopLimit) {
|
||||
setShouldPlay(false);
|
||||
}
|
||||
});
|
||||
|
||||
@ -143,10 +142,10 @@ const CustomEmoji: FC<OwnProps> = ({
|
||||
sticker={customEmoji}
|
||||
isSmall={!isBig}
|
||||
size={size}
|
||||
noPlay={noPlay || !canPlay}
|
||||
noPlay={noPlay || !(shouldPlay && canPlay)}
|
||||
thumbClassName={styles.thumb}
|
||||
fullMediaClassName={styles.media}
|
||||
shouldLoop={shouldLoop}
|
||||
shouldLoop
|
||||
loopLimit={loopLimit}
|
||||
shouldPreloadPreview={shouldPreloadPreview || noPlay || !canPlay}
|
||||
forceOnHeavyAnimation={forceOnHeavyAnimation}
|
||||
|
||||
@ -180,12 +180,12 @@ const StickerView: FC<OwnProps> = ({
|
||||
/>
|
||||
) : isVideo ? (
|
||||
<OptimizedVideo
|
||||
canPlay={shouldPlay && shouldLoop}
|
||||
canPlay={shouldPlay}
|
||||
className={buildClassName(styles.media, fullMediaClassName, fullMediaClassNames, 'sticker-media')}
|
||||
src={fullMediaData}
|
||||
playsInline
|
||||
muted
|
||||
loop={!loopLimit}
|
||||
loop={shouldLoop && !loopLimit}
|
||||
isPriority={forceAlways}
|
||||
disablePictureInPicture
|
||||
onReady={markPlayerReady}
|
||||
|
||||
@ -35,6 +35,7 @@ type OwnProps = {
|
||||
withEffectOnly?: boolean;
|
||||
shouldPause?: boolean;
|
||||
shouldLoop?: boolean;
|
||||
loopLimit?: number;
|
||||
observeIntersection?: ObserveFn;
|
||||
};
|
||||
|
||||
@ -64,6 +65,7 @@ const ReactionAnimatedEmoji = ({
|
||||
withEffectOnly,
|
||||
shouldPause,
|
||||
shouldLoop,
|
||||
loopLimit,
|
||||
observeIntersection,
|
||||
}: OwnProps & StateProps) => {
|
||||
const { stopActiveReaction } = getActions();
|
||||
@ -164,6 +166,7 @@ const ReactionAnimatedEmoji = ({
|
||||
className={styles.customEmoji}
|
||||
size={size}
|
||||
noPlay={shouldPause}
|
||||
loopLimit={loopLimit}
|
||||
forceAlways
|
||||
observeIntersectionForPlaying={observeIntersection}
|
||||
/>
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import type { FC } from '../../lib/teact/teact';
|
||||
import React, { memo, useEffect, useRef } from '../../lib/teact/teact';
|
||||
import React, {
|
||||
memo, useEffect, useMemo, useRef,
|
||||
} from '../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../global';
|
||||
|
||||
import type { ApiSticker, ApiUpdateConnectionStateType } from '../../api/types';
|
||||
import type { MessageList } from '../../global/types';
|
||||
|
||||
import { getPeerIdDividend } from '../../global/helpers';
|
||||
import { selectChat, selectChatLastMessage, selectCurrentMessageList } from '../../global/selectors';
|
||||
|
||||
import useLang from '../../hooks/useLang';
|
||||
@ -20,14 +21,14 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
sticker?: ApiSticker;
|
||||
stickers?: ApiSticker[];
|
||||
lastUnreadMessageId?: number;
|
||||
connectionState?: ApiUpdateConnectionStateType;
|
||||
currentMessageList?: MessageList;
|
||||
};
|
||||
|
||||
const ContactGreeting: FC<OwnProps & StateProps> = ({
|
||||
sticker,
|
||||
stickers,
|
||||
connectionState,
|
||||
lastUnreadMessageId,
|
||||
currentMessageList,
|
||||
@ -43,13 +44,20 @@ const ContactGreeting: FC<OwnProps & StateProps> = ({
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const sticker = useMemo(() => {
|
||||
if (!stickers?.length) return undefined;
|
||||
|
||||
const randomIndex = Math.floor(Math.random() * stickers.length);
|
||||
return stickers[randomIndex];
|
||||
}, [stickers]);
|
||||
|
||||
useEffect(() => {
|
||||
if (sticker || connectionState !== 'connectionStateReady') {
|
||||
if (stickers?.length || connectionState !== 'connectionStateReady') {
|
||||
return;
|
||||
}
|
||||
|
||||
loadGreetingStickers();
|
||||
}, [connectionState, loadGreetingStickers, sticker]);
|
||||
}, [connectionState, loadGreetingStickers, stickers]);
|
||||
|
||||
useEffect(() => {
|
||||
if (connectionState === 'connectionStateReady' && lastUnreadMessageId) {
|
||||
@ -94,8 +102,6 @@ const ContactGreeting: FC<OwnProps & StateProps> = ({
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { userId }): StateProps => {
|
||||
const { stickers } = global.stickers.greeting;
|
||||
const dividend = getPeerIdDividend(userId) + getPeerIdDividend(global.currentUserId!);
|
||||
const sticker = stickers?.length ? stickers[dividend % stickers.length] : undefined;
|
||||
const chat = selectChat(global, userId);
|
||||
if (!chat) {
|
||||
return {};
|
||||
@ -104,7 +110,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
const lastMessage = selectChatLastMessage(global, chat.id);
|
||||
|
||||
return {
|
||||
sticker,
|
||||
stickers,
|
||||
lastUnreadMessageId: lastMessage && lastMessage.id !== chat.lastReadInboxMessageId
|
||||
? lastMessage.id
|
||||
: undefined,
|
||||
|
||||
@ -607,7 +607,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
||||
) : isBot && !hasMessages ? (
|
||||
<MessageListBotInfo chatId={chatId} />
|
||||
) : shouldRenderGreeting ? (
|
||||
<ContactGreeting userId={chatId} />
|
||||
<ContactGreeting key={chatId} userId={chatId} />
|
||||
) : messageIds && (!messageGroups || isGroupChatJustCreated || isEmptyTopic) ? (
|
||||
<NoMessages
|
||||
chatId={chatId}
|
||||
|
||||
@ -26,6 +26,7 @@ import styles from './ReactionButton.module.scss';
|
||||
|
||||
const REACTION_SIZE = 1.25 * REM;
|
||||
const TITLE_MAX_LENGTH = 15;
|
||||
const LOOP_LIMIT = 1;
|
||||
|
||||
const SavedTagButton: FC<{
|
||||
reaction: ApiReaction;
|
||||
@ -134,6 +135,7 @@ const SavedTagButton: FC<{
|
||||
className={styles.animatedEmoji}
|
||||
containerId={containerId}
|
||||
reaction={reaction}
|
||||
loopLimit={LOOP_LIMIT}
|
||||
size={REACTION_SIZE}
|
||||
observeIntersection={observeIntersection}
|
||||
/>
|
||||
@ -151,16 +153,18 @@ const SavedTagButton: FC<{
|
||||
>
|
||||
<path className={styles.tailFill} d="m 0,30 c 3.1855,0 6.1803,-1.5176 8.0641,-4.0864 l 5.835,-7.9568 c 1.2906,-1.7599 1.2906,-4.1537 0,-5.9136 L 8.0641,4.08636 C 6.1803,1.51761 3.1855,0 0,0" />
|
||||
</svg>
|
||||
<PromptDialog
|
||||
isOpen={isRenamePromptOpen}
|
||||
maxLength={TITLE_MAX_LENGTH}
|
||||
title={lang(tag?.title ? 'SavedTagRenameTag' : 'SavedTagLabelTag')}
|
||||
subtitle={lang('SavedTagLabelTagText')}
|
||||
placeholder={lang('SavedTagLabelPlaceholder')}
|
||||
initialValue={tag?.title}
|
||||
onClose={closeRenamePrompt}
|
||||
onSubmit={handleRenameTag}
|
||||
/>
|
||||
{withContextMenu && (
|
||||
<PromptDialog
|
||||
isOpen={isRenamePromptOpen}
|
||||
maxLength={TITLE_MAX_LENGTH}
|
||||
title={lang(tag?.title ? 'SavedTagRenameTag' : 'SavedTagLabelTag')}
|
||||
subtitle={lang('SavedTagLabelTagText')}
|
||||
placeholder={lang('SavedTagLabelPlaceholder')}
|
||||
initialValue={tag?.title}
|
||||
onClose={closeRenamePrompt}
|
||||
onSubmit={handleRenameTag}
|
||||
/>
|
||||
)}
|
||||
{withContextMenu && contextMenuPosition && (
|
||||
<Menu
|
||||
ref={menuRef}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user