Reaction Picker: Show current reactions (#4822)
This commit is contained in:
parent
eddce446de
commit
a03db12474
@ -38,7 +38,7 @@ export type OwnProps = {
|
||||
};
|
||||
|
||||
interface StateProps {
|
||||
withCustomReactions?: boolean;
|
||||
shouldUseFullPicker?: boolean;
|
||||
message?: ApiMessage;
|
||||
story?: ApiStory | ApiStorySkipped;
|
||||
isCurrentUserPremium?: boolean;
|
||||
@ -61,7 +61,7 @@ const ReactionPicker: FC<OwnProps & StateProps> = ({
|
||||
position,
|
||||
isTranslucent,
|
||||
isCurrentUserPremium,
|
||||
withCustomReactions,
|
||||
shouldUseFullPicker,
|
||||
sendAsMessage,
|
||||
chatId,
|
||||
isForEffects,
|
||||
@ -91,10 +91,10 @@ const ReactionPicker: FC<OwnProps & StateProps> = ({
|
||||
}
|
||||
|
||||
return {
|
||||
x: storedPosition.x + (withCustomReactions ? FULL_PICKER_SHIFT_DELTA.x : LIMITED_PICKER_SHIFT_DELTA.x),
|
||||
y: storedPosition.y + (withCustomReactions ? FULL_PICKER_SHIFT_DELTA.y : LIMITED_PICKER_SHIFT_DELTA.y),
|
||||
x: storedPosition.x + (shouldUseFullPicker ? FULL_PICKER_SHIFT_DELTA.x : LIMITED_PICKER_SHIFT_DELTA.x),
|
||||
y: storedPosition.y + (shouldUseFullPicker ? FULL_PICKER_SHIFT_DELTA.y : LIMITED_PICKER_SHIFT_DELTA.y),
|
||||
};
|
||||
}, [renderedStoryId, storedPosition, withCustomReactions]);
|
||||
}, [renderedStoryId, storedPosition, shouldUseFullPicker]);
|
||||
|
||||
const getMenuElement = useLastCallback(() => menuRef.current);
|
||||
const getLayout = useLastCallback(() => ({
|
||||
@ -208,7 +208,7 @@ const ReactionPicker: FC<OwnProps & StateProps> = ({
|
||||
className={buildClassName(styles.menu, 'ReactionPicker')}
|
||||
bubbleClassName={buildClassName(
|
||||
styles.menuContent,
|
||||
!withCustomReactions && !renderedStoryId && styles.onlyReactions,
|
||||
!shouldUseFullPicker && !renderedStoryId && styles.onlyReactions,
|
||||
renderedStoryId && styles.storyMenu,
|
||||
)}
|
||||
withPortal
|
||||
@ -225,7 +225,7 @@ const ReactionPicker: FC<OwnProps & StateProps> = ({
|
||||
<StickerPicker
|
||||
className=""
|
||||
isHidden={!isOpen}
|
||||
loadAndPlay={Boolean(isOpen && withCustomReactions)}
|
||||
loadAndPlay={Boolean(isOpen && shouldUseFullPicker)}
|
||||
idPrefix="message-effect"
|
||||
canSendStickers={false}
|
||||
noContextMenus={false}
|
||||
@ -239,21 +239,22 @@ const ReactionPicker: FC<OwnProps & StateProps> = ({
|
||||
<CustomEmojiPicker
|
||||
chatId={renderedChatId}
|
||||
idPrefix="message-emoji-set-"
|
||||
isHidden={!isOpen || !(withCustomReactions || renderedStoryId)}
|
||||
loadAndPlay={Boolean(isOpen && withCustomReactions)}
|
||||
isHidden={!isOpen || !(shouldUseFullPicker || renderedStoryId)}
|
||||
loadAndPlay={Boolean(isOpen && shouldUseFullPicker)}
|
||||
isReactionPicker
|
||||
className={!withCustomReactions && !renderedStoryId ? styles.hidden : undefined}
|
||||
className={!shouldUseFullPicker && !renderedStoryId ? styles.hidden : undefined}
|
||||
selectedReactionIds={selectedReactionIds}
|
||||
isTranslucent={isTranslucent}
|
||||
onCustomEmojiSelect={renderedStoryId ? handleStoryReactionSelect : handleToggleCustomReaction}
|
||||
onReactionSelect={renderedStoryId ? handleStoryReactionSelect : handleToggleReaction}
|
||||
/>
|
||||
{!withCustomReactions && Boolean(renderedChatId) && (
|
||||
{!shouldUseFullPicker && Boolean(renderedChatId) && (
|
||||
<ReactionPickerLimited
|
||||
chatId={renderedChatId}
|
||||
loadAndPlay={isOpen}
|
||||
onReactionSelect={renderedStoryId ? handleStoryReactionSelect : handleToggleReaction}
|
||||
selectedReactionIds={selectedReactionIds}
|
||||
message={message}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
@ -276,16 +277,20 @@ export default memo(withGlobal<OwnProps>((global): StateProps => {
|
||||
const message = chatId && messageId ? selectChatMessage(global, chatId, messageId) : undefined;
|
||||
const isPrivateChat = isUserId(chatId || storyPeerId || '');
|
||||
const areSomeReactionsAllowed = chatFullInfo?.enabledReactions?.type === 'some';
|
||||
const areCustomReactionsAllowed = chatFullInfo?.enabledReactions?.type === 'all'
|
||||
&& chatFullInfo?.enabledReactions?.areCustomAllowed;
|
||||
const { maxUniqueReactions } = global.appConfig || {};
|
||||
const areAllReactionsAllowed = chatFullInfo?.enabledReactions?.type === 'all'
|
||||
&& chatFullInfo?.enabledReactions?.areCustomAllowed;
|
||||
|
||||
const currentReactions = message?.reactions?.results;
|
||||
const shouldUseCurrentReactions = Boolean(maxUniqueReactions && currentReactions
|
||||
&& currentReactions.length >= maxUniqueReactions);
|
||||
|
||||
return {
|
||||
message,
|
||||
story,
|
||||
position,
|
||||
withCustomReactions: chat?.isForbidden || areSomeReactionsAllowed
|
||||
? false
|
||||
: areCustomReactionsAllowed || isPrivateChat,
|
||||
shouldUseFullPicker: (chat?.isForbidden || areSomeReactionsAllowed || shouldUseCurrentReactions) ? false
|
||||
: (areAllReactionsAllowed || isPrivateChat),
|
||||
isTranslucent: selectIsContextMenuTranslucent(global),
|
||||
isCurrentUserPremium: selectIsCurrentUserPremium(global),
|
||||
sendAsMessage,
|
||||
|
||||
@ -1,10 +1,18 @@
|
||||
import type { FC } from '../../../../lib/teact/teact';
|
||||
import React, { memo, useMemo, useRef } from '../../../../lib/teact/teact';
|
||||
import React, {
|
||||
memo,
|
||||
useMemo, useRef,
|
||||
} from '../../../../lib/teact/teact';
|
||||
import { withGlobal } from '../../../../global';
|
||||
|
||||
import type { ApiAvailableReaction, ApiChatReactions, ApiReaction } from '../../../../api/types';
|
||||
import type {
|
||||
ApiAvailableReaction, ApiChatReactions, ApiMessage,
|
||||
ApiReaction,
|
||||
} from '../../../../api/types';
|
||||
|
||||
import { getReactionKey, sortReactions } from '../../../../global/helpers';
|
||||
import {
|
||||
getReactionKey, sortReactions,
|
||||
} from '../../../../global/helpers';
|
||||
import { selectChatFullInfo } from '../../../../global/selectors';
|
||||
import buildClassName from '../../../../util/buildClassName';
|
||||
import { REM } from '../../../common/helpers/mediaDimensions';
|
||||
@ -21,6 +29,7 @@ type OwnProps = {
|
||||
loadAndPlay: boolean;
|
||||
onReactionSelect?: (reaction: ApiReaction) => void;
|
||||
selectedReactionIds?: string[];
|
||||
message?: ApiMessage;
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
@ -29,6 +38,7 @@ type StateProps = {
|
||||
topReactions: ApiReaction[];
|
||||
canAnimate?: boolean;
|
||||
isSavedMessages?: boolean;
|
||||
reactionsLimit?: number;
|
||||
isCurrentUserPremium?: boolean;
|
||||
};
|
||||
|
||||
@ -47,6 +57,8 @@ const ReactionPickerLimited: FC<OwnProps & StateProps> = ({
|
||||
topReactions,
|
||||
selectedReactionIds,
|
||||
onReactionSelect,
|
||||
message,
|
||||
reactionsLimit,
|
||||
}) => {
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
const sharedCanvasRef = useRef<HTMLCanvasElement>(null);
|
||||
@ -55,7 +67,15 @@ const ReactionPickerLimited: FC<OwnProps & StateProps> = ({
|
||||
const { width: windowWidth } = useWindowSize();
|
||||
const { isTouchScreen } = useAppLayout();
|
||||
|
||||
const currentReactions = message?.reactions?.results;
|
||||
|
||||
const shouldUseCurrentReactions = reactionsLimit && currentReactions
|
||||
&& currentReactions.length >= reactionsLimit;
|
||||
|
||||
const allAvailableReactions = useMemo(() => {
|
||||
if (shouldUseCurrentReactions) {
|
||||
return currentReactions.map(({ reaction }) => reaction);
|
||||
}
|
||||
if (!enabledReactions) {
|
||||
return [];
|
||||
}
|
||||
@ -65,7 +85,7 @@ const ReactionPickerLimited: FC<OwnProps & StateProps> = ({
|
||||
}
|
||||
|
||||
return sortReactions(enabledReactions.allowed, topReactions);
|
||||
}, [availableReactions, enabledReactions, topReactions]);
|
||||
}, [availableReactions, enabledReactions, topReactions, shouldUseCurrentReactions, currentReactions]);
|
||||
|
||||
const pickerHeight = useMemo(() => {
|
||||
const pickerWidth = Math.min(MODAL_MAX_WIDTH_REM * REM, windowWidth);
|
||||
@ -112,12 +132,15 @@ const ReactionPickerLimited: FC<OwnProps & StateProps> = ({
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { chatId }): StateProps => {
|
||||
const { availableReactions, topReactions } = global.reactions;
|
||||
|
||||
const { maxUniqueReactions } = global.appConfig || {};
|
||||
const { enabledReactions } = selectChatFullInfo(global, chatId) || {};
|
||||
|
||||
return {
|
||||
enabledReactions,
|
||||
availableReactions,
|
||||
topReactions,
|
||||
reactionsLimit: maxUniqueReactions,
|
||||
};
|
||||
},
|
||||
)(ReactionPickerLimited));
|
||||
|
||||
@ -75,10 +75,17 @@ const ReactionSelector: FC<OwnProps> = ({
|
||||
|
||||
const areReactionsLocked = isInSavedMessages && !isCurrentUserPremium && !isInStoryViewer;
|
||||
|
||||
const shouldUseCurrentReactions = Boolean(maxUniqueReactions
|
||||
&& currentReactions && currentReactions.length >= maxUniqueReactions);
|
||||
|
||||
const availableReactions = useMemo(() => {
|
||||
const reactions = isForEffects ? effectReactions : isInSavedMessages ? defaultTagReactions
|
||||
: (enabledReactions?.type === 'some' ? enabledReactions.allowed
|
||||
: allAvailableReactions?.map((reaction) => reaction.reaction));
|
||||
const reactions = (() => {
|
||||
if (shouldUseCurrentReactions) return currentReactions?.map((reaction) => reaction.reaction);
|
||||
if (isForEffects) return effectReactions;
|
||||
if (isInSavedMessages) return defaultTagReactions;
|
||||
if (enabledReactions?.type === 'some') return enabledReactions.allowed;
|
||||
return allAvailableReactions?.map((reaction) => reaction.reaction);
|
||||
})();
|
||||
const filteredReactions = reactions?.map((reaction) => {
|
||||
const isCustomReaction = 'documentId' in reaction;
|
||||
const availableReaction = allAvailableReactions?.find((r) => isSameReaction(r.reaction, reaction));
|
||||
@ -87,12 +94,8 @@ const ReactionSelector: FC<OwnProps> = ({
|
||||
|
||||
if ((!isCustomReaction && !availableReaction) || availableReaction?.isInactive) return undefined;
|
||||
|
||||
if (!isPrivate && (!enabledReactions || !canSendReaction(reaction, enabledReactions))) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (maxUniqueReactions && currentReactions && currentReactions.length >= maxUniqueReactions
|
||||
&& !currentReactions.some(({ reaction: currentReaction }) => isSameReaction(reaction, currentReaction))) {
|
||||
if (!isPrivate && !shouldUseCurrentReactions
|
||||
&& (!enabledReactions || !canSendReaction(reaction, enabledReactions))) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@ -102,7 +105,7 @@ const ReactionSelector: FC<OwnProps> = ({
|
||||
return sortReactions(filteredReactions, topReactions);
|
||||
}, [
|
||||
allAvailableReactions, currentReactions, defaultTagReactions, enabledReactions, isInSavedMessages, isPrivate,
|
||||
maxUniqueReactions, topReactions, isForEffects, effectReactions,
|
||||
topReactions, isForEffects, effectReactions, shouldUseCurrentReactions,
|
||||
]);
|
||||
|
||||
const reactionsToRender = useMemo(() => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user