|
1 | 1 | import sortBy from 'lodash/sortBy'; |
2 | 2 | import React, {useContext, useRef} from 'react'; |
3 | | -import {View} from 'react-native'; |
4 | | -import type {OnyxEntry} from 'react-native-onyx'; |
| 3 | +// eslint-disable-next-line no-restricted-imports |
| 4 | +import {InteractionManager, View} from 'react-native'; |
| 5 | +import {importEmojiLocale} from '@assets/emojis'; |
5 | 6 | import type {Emoji} from '@assets/emojis/types'; |
6 | 7 | import OfflineWithFeedback from '@components/OfflineWithFeedback'; |
7 | 8 | import Tooltip from '@components/Tooltip/PopoverAnchorTooltip'; |
8 | | -import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; |
9 | | -import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; |
| 9 | +import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; |
| 10 | +import useLocalize from '@hooks/useLocalize'; |
10 | 11 | import useOnyx from '@hooks/useOnyx'; |
11 | 12 | import useThemeStyles from '@hooks/useThemeStyles'; |
12 | | -import {getEmojiReactionDetails, getLocalizedEmojiName} from '@libs/EmojiUtils'; |
| 13 | +import {getEmojiReactionDetails} from '@libs/EmojiUtils'; |
| 14 | +import {hideContextMenu} from '@pages/inbox/report/ContextMenu/ReportActionContextMenu'; |
13 | 15 | import {ReactionListContext} from '@pages/inbox/ReportScreenContext'; |
14 | 16 | import type {ReactionListAnchor, ReactionListEvent} from '@pages/inbox/ReportScreenContext'; |
| 17 | +import {toggleEmojiReaction} from '@userActions/Report'; |
| 18 | +import {isAnonymousUser, signOutAndRedirectToSignIn} from '@userActions/Session'; |
15 | 19 | import CONST from '@src/CONST'; |
| 20 | +import {isFullySupportedLocale} from '@src/CONST/LOCALES'; |
16 | 21 | import ONYXKEYS from '@src/ONYXKEYS'; |
17 | | -import type {Locale, ReportAction, ReportActionReactions} from '@src/types/onyx'; |
| 22 | +import type {ReportAction, ReportActionReactions} from '@src/types/onyx'; |
18 | 23 | import type {PendingAction} from '@src/types/onyx/OnyxCommon'; |
| 24 | +import {getEmptyObject} from '@src/types/utils/EmptyObject'; |
19 | 25 | import AddReactionBubble from './AddReactionBubble'; |
20 | 26 | import EmojiReactionBubble from './EmojiReactionBubble'; |
21 | 27 | import ReactionTooltipContent from './ReactionTooltipContent'; |
22 | 28 |
|
23 | | -type ReportActionItemEmojiReactionsProps = WithCurrentUserPersonalDetailsProps & { |
24 | | - /** All the emoji reactions for the report action. */ |
25 | | - emojiReactions: OnyxEntry<ReportActionReactions>; |
26 | | - |
27 | | - /** The user's preferred locale. */ |
28 | | - preferredLocale?: OnyxEntry<Locale>; |
29 | | - |
| 29 | +type ReportActionItemEmojiReactionsProps = { |
30 | 30 | /** The report action that these reactions are for */ |
31 | 31 | reportAction: ReportAction; |
32 | 32 |
|
33 | | - /** |
34 | | - * Function to call when the user presses on an emoji. |
35 | | - * This can also be an emoji the user already reacted with, |
36 | | - * hence this function asks to toggle the reaction by emoji. |
37 | | - */ |
38 | | - toggleReaction: (emoji: Emoji, preferredSkinTone: number, ignoreSkinToneOnCompare?: boolean) => void; |
| 33 | + /** The ID of the chat report this action belongs to */ |
| 34 | + reportID: string | undefined; |
39 | 35 |
|
40 | 36 | /** We disable reacting with emojis on report actions that have errors */ |
41 | 37 | shouldBlockReactions?: boolean; |
@@ -77,30 +73,40 @@ type FormattedReaction = { |
77 | 73 | setIsEmojiPickerActive?: (state: boolean) => void; |
78 | 74 | }; |
79 | 75 |
|
80 | | -function ReportActionItemEmojiReactions({ |
81 | | - reportAction, |
82 | | - currentUserPersonalDetails, |
83 | | - toggleReaction, |
84 | | - emojiReactions = {}, |
85 | | - shouldBlockReactions = false, |
86 | | - preferredLocale = CONST.LOCALES.DEFAULT, |
87 | | - setIsEmojiPickerActive, |
88 | | -}: ReportActionItemEmojiReactionsProps) { |
| 76 | +function ReportActionItemEmojiReactions({reportAction, reportID, shouldBlockReactions = false, setIsEmojiPickerActive}: ReportActionItemEmojiReactionsProps) { |
89 | 77 | const styles = useThemeStyles(); |
| 78 | + const {preferredLocale} = useLocalize(); |
| 79 | + const {accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); |
90 | 80 | const reactionListRef = useContext(ReactionListContext); |
91 | 81 | const popoverReactionListAnchors = useRef<PopoverReactionListAnchors>({}); |
92 | 82 | const [preferredSkinTone = CONST.EMOJI_DEFAULT_SKIN_TONE] = useOnyx(ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE); |
93 | 83 |
|
94 | 84 | const reportActionID = reportAction.reportActionID; |
| 85 | + const [emojiReactions = getEmptyObject<ReportActionReactions>()] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${reportActionID}`); |
| 86 | + |
| 87 | + // Prime the locale emoji table when this action has reactions. |
| 88 | + // Skip the default locale since getLocalizedEmojiName never reads localeEmojis for it. |
| 89 | + if (preferredLocale && preferredLocale !== CONST.LOCALES.DEFAULT && emojiReactions !== CONST.EMPTY_OBJECT && isFullySupportedLocale(preferredLocale)) { |
| 90 | + importEmojiLocale(preferredLocale); |
| 91 | + } |
| 92 | + |
| 93 | + const toggleReaction = (emoji: Emoji, skinTone: number, ignoreSkinToneOnCompare?: boolean) => { |
| 94 | + if (isAnonymousUser()) { |
| 95 | + hideContextMenu(false); |
| 96 | + |
| 97 | + // eslint-disable-next-line @typescript-eslint/no-deprecated |
| 98 | + InteractionManager.runAfterInteractions(() => { |
| 99 | + signOutAndRedirectToSignIn(); |
| 100 | + }); |
| 101 | + return; |
| 102 | + } |
| 103 | + toggleEmojiReaction(reportID, reportAction, emoji, emojiReactions, skinTone, currentUserAccountID, ignoreSkinToneOnCompare); |
| 104 | + }; |
95 | 105 |
|
96 | 106 | // Each emoji is sorted by the oldest timestamp of user reactions so that they will always appear in the same order for everyone |
97 | 107 | const formattedReactions: Array<FormattedReaction | null> = sortBy( |
98 | 108 | Object.entries(emojiReactions ?? {}).map(([emojiName, emojiReaction]) => { |
99 | | - const {emoji, emojiCodes, reactionCount, hasUserReacted, userAccountIDs, oldestTimestamp} = getEmojiReactionDetails( |
100 | | - emojiName, |
101 | | - emojiReaction, |
102 | | - currentUserPersonalDetails.accountID, |
103 | | - ); |
| 109 | + const {emoji, emojiCodes, reactionCount, hasUserReacted, userAccountIDs, oldestTimestamp} = getEmojiReactionDetails(emojiName, emojiReaction, currentUserAccountID); |
104 | 110 |
|
105 | 111 | if (reactionCount === 0) { |
106 | 112 | return null; |
@@ -138,14 +144,15 @@ function ReportActionItemEmojiReactions({ |
138 | 144 | if (reaction === null) { |
139 | 145 | return; |
140 | 146 | } |
| 147 | + |
141 | 148 | return ( |
142 | 149 | <Tooltip |
143 | 150 | renderTooltipContent={() => ( |
144 | 151 | <ReactionTooltipContent |
145 | | - emojiName={getLocalizedEmojiName(reaction.reactionEmojiName, preferredLocale)} |
| 152 | + emojiName={reaction.reactionEmojiName} |
146 | 153 | emojiCodes={reaction.emojiCodes} |
147 | 154 | accountIDs={reaction.userAccountIDs} |
148 | | - currentUserPersonalDetails={currentUserPersonalDetails} |
| 155 | + currentUserAccountID={currentUserAccountID} |
149 | 156 | /> |
150 | 157 | )} |
151 | 158 | renderTooltipContentKey={[...reaction.userAccountIDs.map(String), ...reaction.emojiCodes]} |
@@ -184,4 +191,4 @@ function ReportActionItemEmojiReactions({ |
184 | 191 | ); |
185 | 192 | } |
186 | 193 |
|
187 | | -export default withCurrentUserPersonalDetails(ReportActionItemEmojiReactions); |
| 194 | +export default ReportActionItemEmojiReactions; |
0 commit comments