Skip to content

Commit

Permalink
[native] introudce selectMultipleEmojis and alreadySelectedEmojis to …
Browse files Browse the repository at this point in the history
…EmojiKeyboard component

Summary:
This diff is the first part to highlight the already selected emojis to indicate on the emoji keyboard what emojis the user has already selected. This diff handles the case when `selectMultipleEmojis` is equal to `false` and the next diff will handle the case when `selectMultipleEmojis` is equal to `true`

The big obstacle I had to overcome to build this was that the `selectedEmojis ` prop needs to be [[ https://thewidlarzgroup.github.io/rn-emoji-keyboard/docs/api/modal#selectedemojis | an array of emoji names ]] and we only store the actual emoji in our database. To overcome this obstacle I index the `emojiData` by the `emoji` so that we can easily grab the correct emoji name and pass it into the `selectedEmojis` prop.

Here is a link to an example to the docs that helped me with this implementation:
https://thewidlarzgroup.github.io/rn-emoji-keyboard/docs/documentation/Examples/selected_emojis

Linear Task: https://linear.app/comm/issue/ENG-3794/mobile-emoji-keyboard-highlight-emojis-that-a-user-has-already

Depends on D8282

Test Plan:
Please watch the demo video below:

{F600937}

Reviewers: atul, kamil

Reviewed By: kamil

Subscribers: ashoat, tomek

Differential Revision: https://phab.comm.dev/D8284
  • Loading branch information
ginsueddy committed Jun 23, 2023
1 parent bb40eaf commit b400d0b
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 2 deletions.
7 changes: 7 additions & 0 deletions native/avatars/emoji-avatar-creation.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ function EmojiAvatarCreation(props: Props): React.Node {
);
}, [saveAvatarCallLoading, styles.loadingContainer]);

const alreadySelectedEmojis = React.useMemo(
() => [pendingEmoji],
[pendingEmoji],
);

return (
<View style={styles.container}>
<View style={styles.emojiAvatarCreationContainer}>
Expand Down Expand Up @@ -132,6 +137,8 @@ function EmojiAvatarCreation(props: Props): React.Node {
onEmojiSelected={onEmojiSelected}
emojiKeyboardOpen={emojiKeyboardOpen}
onEmojiKeyboardClose={onEmojiKeyboardClose}
selectMultipleEmojis={false}
alreadySelectedEmojis={alreadySelectedEmojis}
/>
</View>
);
Expand Down
3 changes: 3 additions & 0 deletions native/chat/multimedia-message-tooltip-button.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ function MultimediaMessageTooltipButton(props: Props): React.Node {
[sendReaction, dismissTooltip],
);

const alreadySelectedEmojis = React.useMemo(() => [], []);

return (
<>
<Animated.View style={messageContainerStyle}>
Expand All @@ -171,6 +173,7 @@ function MultimediaMessageTooltipButton(props: Props): React.Node {
onEmojiSelected={onEmojiSelected}
emojiKeyboardOpen={emojiPickerOpen}
onEmojiKeyboardClose={dismissTooltip}
alreadySelectedEmojis={alreadySelectedEmojis}
/>
</>
);
Expand Down
3 changes: 3 additions & 0 deletions native/chat/robotext-message-tooltip-button.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ function RobotextMessageTooltipButton(props: Props): React.Node {
[sendReaction, dismissTooltip],
);

const alreadySelectedEmojis = React.useMemo(() => [], []);

return (
<>
<Animated.View style={messageContainerStyle}>
Expand All @@ -153,6 +155,7 @@ function RobotextMessageTooltipButton(props: Props): React.Node {
onEmojiSelected={onEmojiSelected}
emojiKeyboardOpen={emojiPickerOpen}
onEmojiKeyboardClose={dismissTooltip}
alreadySelectedEmojis={alreadySelectedEmojis}
/>
</>
);
Expand Down
3 changes: 3 additions & 0 deletions native/chat/text-message-tooltip-button.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ function TextMessageTooltipButton(props: Props): React.Node {
[sendReaction, dismissTooltip],
);

const alreadySelectedEmojis = React.useMemo(() => [], []);

return (
<MessageListContextProvider threadInfo={threadInfo}>
<SidebarInputBarHeightMeasurer
Expand Down Expand Up @@ -177,6 +179,7 @@ function TextMessageTooltipButton(props: Props): React.Node {
onEmojiSelected={onEmojiSelected}
emojiKeyboardOpen={emojiPickerOpen}
onEmojiKeyboardClose={dismissTooltip}
alreadySelectedEmojis={alreadySelectedEmojis}
/>
</MessageListContextProvider>
);
Expand Down
32 changes: 30 additions & 2 deletions native/components/emoji-keyboard.react.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// @flow

import AsyncStorage from '@react-native-async-storage/async-storage';
import _flatMap from 'lodash/fp/flatMap.js';
import _flow from 'lodash/fp/flow.js';
import _keyBy from 'lodash/fp/keyBy.js';
import * as React from 'react';
import EmojiPicker, { useRecentPicksPersistence } from 'rn-emoji-keyboard';
import emojisData from 'rn-emoji-keyboard/src/assets/emojis.json';

const STORAGE_KEY = 'EMOJI_KEYBOARD_RECENT';

Expand Down Expand Up @@ -36,6 +40,7 @@ const useRecentPicksPersistenceArgs = {
initialization: initializationCallback,
onStateChange: onStateChangeCallback,
};
const keyedEmojiData = _flow(_flatMap('data'), _keyBy('emoji'))(emojisData);

export type EmojiSelection = {
+emoji: string,
Expand All @@ -50,22 +55,45 @@ type Props = {
+onEmojiSelected: (emoji: EmojiSelection) => mixed,
+emojiKeyboardOpen: boolean,
+onEmojiKeyboardClose: () => mixed,
+selectMultipleEmojis?: boolean,
+alreadySelectedEmojis: $ReadOnlyArray<string>,
};

function EmojiKeyboard(props: Props): React.Node {
const { onEmojiSelected, emojiKeyboardOpen, onEmojiKeyboardClose } = props;
const {
onEmojiSelected,
emojiKeyboardOpen,
onEmojiKeyboardClose,
selectMultipleEmojis,
alreadySelectedEmojis,
} = props;

const [currentlySelected, setCurrentlySelected] = React.useState<
$ReadOnlyArray<string>,
>(() => alreadySelectedEmojis.map(emoji => keyedEmojiData[emoji].name));

const handleOnEmojiSelected = React.useCallback(
(emoji: EmojiSelection) => {
if (!selectMultipleEmojis) {
setCurrentlySelected([emoji.name]);
}
onEmojiSelected(emoji);
},
[onEmojiSelected, setCurrentlySelected, selectMultipleEmojis],
);

useRecentPicksPersistence(useRecentPicksPersistenceArgs);

return (
<EmojiPicker
onEmojiSelected={onEmojiSelected}
onEmojiSelected={handleOnEmojiSelected}
open={emojiKeyboardOpen}
onClose={onEmojiKeyboardClose}
enableSearchBar
enableSearchAnimation={false}
enableRecentlyUsed
categoryOrder={categoryOrder}
selectedEmojis={currentlySelected}
/>
);
}
Expand Down

0 comments on commit b400d0b

Please sign in to comment.