Message: Fix parallel emoji interactions (#1678)
This commit is contained in:
parent
e33e22c982
commit
74d348b00a
@ -27,7 +27,7 @@ type OwnProps = {
|
||||
forceLoadPreview?: boolean;
|
||||
messageId?: number;
|
||||
chatId?: string;
|
||||
activeEmojiInteraction?: ActiveEmojiInteraction;
|
||||
activeEmojiInteractions?: ActiveEmojiInteraction[];
|
||||
};
|
||||
|
||||
const QUALITY = 1;
|
||||
@ -43,7 +43,7 @@ const AnimatedEmoji: FC<OwnProps> = ({
|
||||
forceLoadPreview,
|
||||
messageId,
|
||||
chatId,
|
||||
activeEmojiInteraction,
|
||||
activeEmojiInteractions,
|
||||
}) => {
|
||||
const {
|
||||
markAnimationLoaded,
|
||||
@ -53,7 +53,7 @@ const AnimatedEmoji: FC<OwnProps> = ({
|
||||
style,
|
||||
handleClick,
|
||||
playKey,
|
||||
} = useAnimatedEmoji(size, chatId, messageId, soundId, activeEmojiInteraction, isOwn, undefined, effect?.emoji);
|
||||
} = useAnimatedEmoji(size, chatId, messageId, soundId, activeEmojiInteractions, isOwn, undefined, effect?.emoji);
|
||||
|
||||
const localMediaHash = `sticker${sticker.id}`;
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ type OwnProps = {
|
||||
forceLoadPreview?: boolean;
|
||||
messageId?: number;
|
||||
chatId?: string;
|
||||
activeEmojiInteraction?: ActiveEmojiInteraction;
|
||||
activeEmojiInteractions?: ActiveEmojiInteraction[];
|
||||
};
|
||||
|
||||
const LocalAnimatedEmoji: FC<OwnProps> = ({
|
||||
@ -35,7 +35,7 @@ const LocalAnimatedEmoji: FC<OwnProps> = ({
|
||||
observeIntersection,
|
||||
messageId,
|
||||
chatId,
|
||||
activeEmojiInteraction,
|
||||
activeEmojiInteractions,
|
||||
}) => {
|
||||
const {
|
||||
playKey,
|
||||
@ -44,7 +44,7 @@ const LocalAnimatedEmoji: FC<OwnProps> = ({
|
||||
width,
|
||||
handleClick,
|
||||
markAnimationLoaded,
|
||||
} = useAnimatedEmoji(size, chatId, messageId, soundId, activeEmojiInteraction, isOwn, localEffect);
|
||||
} = useAnimatedEmoji(size, chatId, messageId, soundId, activeEmojiInteractions, isOwn, localEffect);
|
||||
const id = `local_emoji_${localSticker}`;
|
||||
|
||||
const isIntersecting = useIsIntersecting(ref, observeIntersection);
|
||||
|
||||
@ -22,7 +22,7 @@ export default function useAnimatedEmoji(
|
||||
chatId?: string,
|
||||
messageId?: number,
|
||||
soundId?: string,
|
||||
activeEmojiInteraction?: ActiveEmojiInteraction,
|
||||
activeEmojiInteractions?: ActiveEmojiInteraction[],
|
||||
isOwn?: boolean,
|
||||
localEffect?: string,
|
||||
emoji?: string,
|
||||
@ -120,16 +120,21 @@ export default function useAnimatedEmoji(
|
||||
useEffect(() => {
|
||||
const container = ref.current;
|
||||
|
||||
if (!container || !activeEmojiInteraction) return;
|
||||
if (!container || !activeEmojiInteractions) return;
|
||||
|
||||
const {
|
||||
messageId: selectedMessageId, endX, endY,
|
||||
} = activeEmojiInteraction;
|
||||
activeEmojiInteractions.forEach(({
|
||||
id,
|
||||
startSize,
|
||||
messageId: interactionMessageId,
|
||||
}) => {
|
||||
if (startSize || messageId !== interactionMessageId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!endX && !endY && selectedMessageId === messageId) {
|
||||
const { x, y } = container.getBoundingClientRect();
|
||||
|
||||
sendWatchingEmojiInteraction({
|
||||
id,
|
||||
chatId,
|
||||
emoticon: localEffect ? selectLocalAnimatedEmojiEffectByName(localEffect) : emoji,
|
||||
startSize: width,
|
||||
@ -138,9 +143,9 @@ export default function useAnimatedEmoji(
|
||||
isReversed: !isOwn,
|
||||
});
|
||||
play();
|
||||
}
|
||||
});
|
||||
}, [
|
||||
activeEmojiInteraction, chatId, emoji, isOwn, localEffect, messageId, play, sendWatchingEmojiInteraction, width,
|
||||
activeEmojiInteractions, chatId, emoji, isOwn, localEffect, messageId, play, sendWatchingEmojiInteraction, width,
|
||||
]);
|
||||
|
||||
return {
|
||||
|
||||
@ -5,8 +5,9 @@ import { Bundles } from '../../util/moduleLoader';
|
||||
import useModuleLoader from '../../hooks/useModuleLoader';
|
||||
|
||||
const EmojiInteractionAnimationAsync: FC<OwnProps> = (props) => {
|
||||
const { emojiInteraction } = props;
|
||||
const EmojiInteractionAnimation = useModuleLoader(Bundles.Extra, 'EmojiInteractionAnimation', !emojiInteraction);
|
||||
const { activeEmojiInteraction } = props;
|
||||
const EmojiInteractionAnimation = useModuleLoader(Bundles.Extra, 'EmojiInteractionAnimation',
|
||||
!activeEmojiInteraction);
|
||||
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
return EmojiInteractionAnimation ? <EmojiInteractionAnimation {...props} /> : undefined;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React, {
|
||||
FC, memo, useCallback, useEffect, useLayoutEffect, useState,
|
||||
FC, memo, useCallback, useEffect, useLayoutEffect, useRef, useState,
|
||||
} from '../../lib/teact/teact';
|
||||
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
|
||||
|
||||
@ -21,13 +21,12 @@ import AnimatedSticker from '../common/AnimatedSticker';
|
||||
import './EmojiInteractionAnimation.scss';
|
||||
|
||||
export type OwnProps = {
|
||||
emojiInteraction: ActiveEmojiInteraction;
|
||||
activeEmojiInteraction: ActiveEmojiInteraction;
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
effectAnimationId?: string;
|
||||
localEffectAnimation?: string;
|
||||
isReversed?: boolean;
|
||||
};
|
||||
|
||||
const HIDE_ANIMATION_DURATION = 250;
|
||||
@ -35,41 +34,50 @@ const PLAYING_DURATION = 3000;
|
||||
const EFFECT_SIZE = 240;
|
||||
|
||||
const EmojiInteractionAnimation: FC<OwnProps & StateProps> = ({
|
||||
emojiInteraction,
|
||||
effectAnimationId,
|
||||
localEffectAnimation,
|
||||
isReversed,
|
||||
activeEmojiInteraction,
|
||||
}) => {
|
||||
const { stopActiveEmojiInteraction } = getDispatch();
|
||||
|
||||
const [isHiding, startHiding] = useFlag(false);
|
||||
const [isPlaying, startPlaying] = useFlag(false);
|
||||
const timeoutRef = useRef<NodeJS.Timeout>();
|
||||
|
||||
const stop = useCallback(() => {
|
||||
startHiding();
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
}
|
||||
setTimeout(() => {
|
||||
stopActiveEmojiInteraction();
|
||||
stopActiveEmojiInteraction({ id: activeEmojiInteraction.id });
|
||||
}, HIDE_ANIMATION_DURATION);
|
||||
}, [startHiding, stopActiveEmojiInteraction]);
|
||||
}, [activeEmojiInteraction.id, startHiding, stopActiveEmojiInteraction]);
|
||||
|
||||
const handleCancelAnimation = useCallback((e: UIEvent) => {
|
||||
if (!(e.target as HTMLElement)?.closest('.AnimatedEmoji')) {
|
||||
stop();
|
||||
}
|
||||
}, [stop]);
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener('touchstart', stop);
|
||||
document.addEventListener('touchmove', stop);
|
||||
document.addEventListener('mousedown', stop);
|
||||
document.addEventListener('wheel', stop);
|
||||
document.addEventListener('touchstart', handleCancelAnimation);
|
||||
document.addEventListener('touchmove', handleCancelAnimation);
|
||||
document.addEventListener('mousedown', handleCancelAnimation);
|
||||
document.addEventListener('wheel', handleCancelAnimation);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('touchstart', stop);
|
||||
document.removeEventListener('touchmove', stop);
|
||||
document.removeEventListener('mousedown', stop);
|
||||
document.removeEventListener('wheel', stop);
|
||||
document.removeEventListener('touchstart', handleCancelAnimation);
|
||||
document.removeEventListener('touchmove', handleCancelAnimation);
|
||||
document.removeEventListener('mousedown', handleCancelAnimation);
|
||||
document.removeEventListener('wheel', handleCancelAnimation);
|
||||
};
|
||||
}, [stop]);
|
||||
}, [handleCancelAnimation]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent();
|
||||
|
||||
setTimeout(() => {
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
stop();
|
||||
dispatchHeavyAnimationStop();
|
||||
}, PLAYING_DURATION);
|
||||
@ -86,16 +94,24 @@ const EmojiInteractionAnimation: FC<OwnProps & StateProps> = ({
|
||||
}
|
||||
}, [localEffectAnimation]);
|
||||
|
||||
const scale = (emojiInteraction.startSize || 0) / EFFECT_SIZE;
|
||||
if (!activeEmojiInteraction.startSize) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const scale = (activeEmojiInteraction.startSize || 0) / EFFECT_SIZE;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={buildClassName(
|
||||
'EmojiInteractionAnimation', isHiding && 'hiding', isPlaying && 'playing', isReversed && 'reversed',
|
||||
'EmojiInteractionAnimation',
|
||||
isHiding && 'hiding',
|
||||
isPlaying && 'playing',
|
||||
activeEmojiInteraction.isReversed && 'reversed',
|
||||
)}
|
||||
style={`--scale: ${scale}; --start-x: ${emojiInteraction.x}px; --start-y: ${emojiInteraction.y}px;`}
|
||||
style={`--scale: ${scale}; --start-x: ${activeEmojiInteraction.x}px; --start-y: ${activeEmojiInteraction.y}px;`}
|
||||
>
|
||||
<AnimatedSticker
|
||||
key={`effect_${effectAnimationId}`}
|
||||
id={`effect_${effectAnimationId}`}
|
||||
size={EFFECT_SIZE}
|
||||
animationData={localEffectAnimationData || effectAnimationData}
|
||||
@ -110,15 +126,14 @@ const EmojiInteractionAnimation: FC<OwnProps & StateProps> = ({
|
||||
};
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { emojiInteraction }): StateProps => {
|
||||
const animatedEffect = emojiInteraction.animatedEffect !== undefined
|
||||
&& selectAnimatedEmojiEffect(global, emojiInteraction.animatedEffect);
|
||||
(global, { activeEmojiInteraction }): StateProps => {
|
||||
const animatedEffect = activeEmojiInteraction.animatedEffect !== undefined
|
||||
&& selectAnimatedEmojiEffect(global, activeEmojiInteraction.animatedEffect);
|
||||
return {
|
||||
effectAnimationId: animatedEffect ? animatedEffect.id : undefined,
|
||||
localEffectAnimation: !animatedEffect && emojiInteraction.animatedEffect
|
||||
&& Object.keys(ANIMATED_STICKERS_PATHS).includes(emojiInteraction.animatedEffect)
|
||||
? emojiInteraction.animatedEffect : undefined,
|
||||
isReversed: emojiInteraction.isReversed,
|
||||
localEffectAnimation: !animatedEffect && activeEmojiInteraction.animatedEffect
|
||||
&& Object.keys(ANIMATED_STICKERS_PATHS).includes(activeEmojiInteraction.animatedEffect)
|
||||
? activeEmojiInteraction.animatedEffect : undefined,
|
||||
};
|
||||
},
|
||||
)(EmojiInteractionAnimation));
|
||||
|
||||
@ -109,7 +109,7 @@ type StateProps = {
|
||||
canSubscribe?: boolean;
|
||||
canStartBot?: boolean;
|
||||
canRestartBot?: boolean;
|
||||
activeEmojiInteraction?: ActiveEmojiInteraction;
|
||||
activeEmojiInteractions?: ActiveEmojiInteraction[];
|
||||
};
|
||||
|
||||
const CLOSE_ANIMATION_DURATION = IS_SINGLE_COLUMN_LAYOUT ? 450 + ANIMATION_END_DELAY : undefined;
|
||||
@ -150,7 +150,7 @@ const MiddleColumn: FC<StateProps> = ({
|
||||
canSubscribe,
|
||||
canStartBot,
|
||||
canRestartBot,
|
||||
activeEmojiInteraction,
|
||||
activeEmojiInteractions,
|
||||
}) => {
|
||||
const {
|
||||
openChat,
|
||||
@ -522,9 +522,15 @@ const MiddleColumn: FC<StateProps> = ({
|
||||
onUnpin={handleUnpinAllMessages}
|
||||
/>
|
||||
)}
|
||||
{activeEmojiInteraction && (
|
||||
<EmojiInteractionAnimation emojiInteraction={activeEmojiInteraction} />
|
||||
)}
|
||||
<div teactFastList>
|
||||
{activeEmojiInteractions?.map((activeEmojiInteraction, i) => (
|
||||
<EmojiInteractionAnimation
|
||||
teactOrderKey={i}
|
||||
key={activeEmojiInteraction.id}
|
||||
activeEmojiInteraction={activeEmojiInteraction}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -538,7 +544,7 @@ export default memo(withGlobal(
|
||||
|
||||
const { messageLists } = global.messages;
|
||||
const currentMessageList = selectCurrentMessageList(global);
|
||||
const { isLeftColumnShown, chats: { listIds }, activeEmojiInteraction } = global;
|
||||
const { isLeftColumnShown, chats: { listIds }, activeEmojiInteractions } = global;
|
||||
|
||||
const state: StateProps = {
|
||||
theme,
|
||||
@ -556,7 +562,7 @@ export default memo(withGlobal(
|
||||
isReactorListModalOpen: Boolean(global.reactorModal),
|
||||
animationLevel: global.settings.byKey.animationLevel,
|
||||
currentTransitionKey: Math.max(0, global.messages.messageLists.length - 1),
|
||||
activeEmojiInteraction,
|
||||
activeEmojiInteractions,
|
||||
};
|
||||
|
||||
if (!currentMessageList || !listIds.active) {
|
||||
|
||||
@ -185,7 +185,7 @@ type StateProps = {
|
||||
availableReactions?: ApiAvailableReaction[];
|
||||
defaultReaction?: string;
|
||||
activeReaction?: ActiveReaction;
|
||||
activeEmojiInteraction?: ActiveEmojiInteraction;
|
||||
activeEmojiInteractions?: ActiveEmojiInteraction[];
|
||||
};
|
||||
|
||||
type MetaPosition =
|
||||
@ -261,7 +261,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
availableReactions,
|
||||
defaultReaction,
|
||||
activeReaction,
|
||||
activeEmojiInteraction,
|
||||
activeEmojiInteractions,
|
||||
messageListType,
|
||||
isPinnedList,
|
||||
isDownloading,
|
||||
@ -637,7 +637,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
forceLoadPreview={isLocal}
|
||||
messageId={messageId}
|
||||
chatId={chatId}
|
||||
activeEmojiInteraction={activeEmojiInteraction}
|
||||
activeEmojiInteractions={activeEmojiInteractions}
|
||||
/>
|
||||
)}
|
||||
{localSticker && (
|
||||
@ -652,7 +652,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
forceLoadPreview={isLocal}
|
||||
messageId={messageId}
|
||||
chatId={chatId}
|
||||
activeEmojiInteraction={activeEmojiInteraction}
|
||||
activeEmojiInteractions={activeEmojiInteractions}
|
||||
/>
|
||||
)}
|
||||
{isAlbum && (
|
||||
@ -1055,7 +1055,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
availableReactions: global.availableReactions,
|
||||
defaultReaction: isMessageLocal(message) ? undefined : selectDefaultReaction(global, chatId),
|
||||
activeReaction: reactionMessage && global.activeReactions[reactionMessage.id],
|
||||
activeEmojiInteraction: global.activeEmojiInteraction,
|
||||
activeEmojiInteractions: global.activeEmojiInteractions,
|
||||
...(isOutgoing && { outgoingStatus: selectOutgoingStatus(global, message, messageListType === 'scheduled') }),
|
||||
...(typeof uploadProgress === 'number' && { uploadProgress }),
|
||||
...(isFocused && { focusDirection, noFocusHighlight, isResizingContainer }),
|
||||
|
||||
@ -65,13 +65,11 @@ export interface MessageList {
|
||||
}
|
||||
|
||||
export interface ActiveEmojiInteraction {
|
||||
id: number;
|
||||
x: number;
|
||||
y: number;
|
||||
messageId?: number;
|
||||
endX?: number;
|
||||
endY?: number;
|
||||
startSize?: number;
|
||||
reaction?: string;
|
||||
animatedEffect?: string;
|
||||
isReversed?: boolean;
|
||||
}
|
||||
@ -332,7 +330,7 @@ export type GlobalState = {
|
||||
};
|
||||
|
||||
availableReactions?: ApiAvailableReaction[];
|
||||
activeEmojiInteraction?: ActiveEmojiInteraction;
|
||||
activeEmojiInteractions?: ActiveEmojiInteraction[];
|
||||
activeReactions: Record<number, ActiveReaction>;
|
||||
|
||||
localTextSearch: {
|
||||
|
||||
@ -15,6 +15,10 @@ import { buildCollectionByKey, omit } from '../../../util/iteratees';
|
||||
import { ANIMATION_LEVEL_MAX } from '../../../config';
|
||||
import { isMessageLocal } from '../../helpers';
|
||||
|
||||
const INTERACTION_RANDOM_OFFSET = 40;
|
||||
|
||||
let interactionLocalId = 0;
|
||||
|
||||
addReducer('loadAvailableReactions', () => {
|
||||
(async () => {
|
||||
const result = await callApi('getAvailableReactions');
|
||||
@ -45,28 +49,31 @@ addReducer('interactWithAnimatedEmoji', (global, actions, payload) => {
|
||||
emoji, x, y, localEffect, startSize, isReversed,
|
||||
} = payload!;
|
||||
|
||||
const activeEmojiInteraction = {
|
||||
id: interactionLocalId++,
|
||||
animatedEffect: emoji || localEffect,
|
||||
x: subtractXForEmojiInteraction(global, x) + Math.random()
|
||||
* INTERACTION_RANDOM_OFFSET - INTERACTION_RANDOM_OFFSET / 2,
|
||||
y: y + Math.random() * INTERACTION_RANDOM_OFFSET - INTERACTION_RANDOM_OFFSET / 2,
|
||||
startSize,
|
||||
isReversed,
|
||||
};
|
||||
|
||||
return {
|
||||
...global,
|
||||
activeEmojiInteraction: {
|
||||
animatedEffect: emoji || localEffect,
|
||||
x: subtractXForEmojiInteraction(global, x),
|
||||
y,
|
||||
startSize,
|
||||
isReversed,
|
||||
},
|
||||
activeEmojiInteractions: [...(global.activeEmojiInteractions || []), activeEmojiInteraction],
|
||||
};
|
||||
});
|
||||
|
||||
addReducer('sendEmojiInteraction', (global, actions, payload) => {
|
||||
const {
|
||||
messageId, chatId, emoji, interactions, localEffect,
|
||||
x, y, startX, startY, startSize,
|
||||
} = payload!;
|
||||
|
||||
const chat = selectChat(global, chatId);
|
||||
|
||||
if (!chat || (!emoji && !localEffect) || chatId === global.currentUserId) {
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
void callApi('sendEmojiInteraction', {
|
||||
@ -75,20 +82,6 @@ addReducer('sendEmojiInteraction', (global, actions, payload) => {
|
||||
emoticon: emoji || selectLocalAnimatedEmojiEffectByName(localEffect),
|
||||
timestamps: interactions,
|
||||
});
|
||||
|
||||
if (!global.activeEmojiInteraction) return undefined;
|
||||
|
||||
return {
|
||||
...global,
|
||||
activeEmojiInteraction: {
|
||||
...global.activeEmojiInteraction,
|
||||
endX: subtractXForEmojiInteraction(global, x),
|
||||
endY: y,
|
||||
...(startX && { x: subtractXForEmojiInteraction(global, startX) }),
|
||||
...(startY && { y: startY }),
|
||||
...(startSize && { startSize }),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
addReducer('sendDefaultReaction', (global, actions, payload) => {
|
||||
@ -224,10 +217,12 @@ addReducer('setDefaultReaction', (global, actions, payload) => {
|
||||
})();
|
||||
});
|
||||
|
||||
addReducer('stopActiveEmojiInteraction', (global) => {
|
||||
addReducer('stopActiveEmojiInteraction', (global, actions, payload) => {
|
||||
const { id } = payload;
|
||||
|
||||
return {
|
||||
...global,
|
||||
activeEmojiInteraction: undefined,
|
||||
activeEmojiInteractions: global.activeEmojiInteractions?.filter((l) => l.id !== id),
|
||||
};
|
||||
});
|
||||
|
||||
@ -287,12 +282,12 @@ addReducer('loadMessageReactions', (global, actions, payload) => {
|
||||
|
||||
addReducer('sendWatchingEmojiInteraction', (global, actions, payload) => {
|
||||
const {
|
||||
chatId, emoticon, x, y, startSize, isReversed,
|
||||
chatId, emoticon, x, y, startSize, isReversed, id,
|
||||
} = payload;
|
||||
|
||||
const chat = selectChat(global, chatId);
|
||||
|
||||
if (!chat || !global.activeEmojiInteraction || chatId === global.currentUserId) {
|
||||
if (!chat || !global.activeEmojiInteractions?.some((l) => l.id === id) || chatId === global.currentUserId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@ -300,12 +295,17 @@ addReducer('sendWatchingEmojiInteraction', (global, actions, payload) => {
|
||||
|
||||
return {
|
||||
...global,
|
||||
activeEmojiInteraction: {
|
||||
...global.activeEmojiInteraction,
|
||||
x: subtractXForEmojiInteraction(global, x),
|
||||
y,
|
||||
startSize,
|
||||
isReversed,
|
||||
},
|
||||
activeEmojiInteractions: global.activeEmojiInteractions.map((activeEmojiInteraction) => {
|
||||
if (activeEmojiInteraction.id === id) {
|
||||
return {
|
||||
...activeEmojiInteraction,
|
||||
x: subtractXForEmojiInteraction(global, x),
|
||||
y,
|
||||
startSize,
|
||||
isReversed,
|
||||
};
|
||||
}
|
||||
return activeEmojiInteraction;
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
@ -118,7 +118,7 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate) => {
|
||||
case 'updateStartEmojiInteraction': {
|
||||
const { chatId: currentChatId } = selectCurrentMessageList(global) || {};
|
||||
|
||||
if (global.activeEmojiInteraction || currentChatId !== update.id) return;
|
||||
if (currentChatId !== update.id) return;
|
||||
const message = selectChatMessage(global, currentChatId, update.messageId);
|
||||
|
||||
if (!message) return;
|
||||
@ -130,10 +130,11 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate) => {
|
||||
|
||||
global = {
|
||||
...global,
|
||||
activeEmojiInteraction: {
|
||||
activeEmojiInteractions: [...(global.activeEmojiInteractions || []), {
|
||||
id: global.activeEmojiInteractions?.length || 0,
|
||||
animatedEffect: localEmoji ? selectLocalAnimatedEmojiEffect(localEmoji) : update.emoji,
|
||||
messageId: update.messageId,
|
||||
} as ActiveEmojiInteraction,
|
||||
} as ActiveEmojiInteraction],
|
||||
};
|
||||
|
||||
setGlobal(global);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user