Skip to content

Commit

Permalink
Merge pull request #35140 from wildan-m/wildan/fix/33679-highlight-ac…
Browse files Browse the repository at this point in the history
…tive-emoji

Feature to highlight active emoji
  • Loading branch information
Hayata Suenaga authored Feb 6, 2024
2 parents 82c2444 + b85a6f9 commit d7f87c5
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 12 deletions.
2 changes: 2 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,8 @@ const CONST = {
EMOJI: /[\p{Extended_Pictographic}\u200d\u{1f1e6}-\u{1f1ff}\u{1f3fb}-\u{1f3ff}\u{e0020}-\u{e007f}\u20E3\uFE0F]|[#*0-9]\uFE0F?\u20E3/gu,
// eslint-disable-next-line max-len, no-misleading-character-class
EMOJIS: /[\p{Extended_Pictographic}](\u200D[\p{Extended_Pictographic}]|[\u{1F3FB}-\u{1F3FF}]|[\u{E0020}-\u{E007F}]|\uFE0F|\u20E3)*|[\u{1F1E6}-\u{1F1FF}]{2}|[#*0-9]\uFE0F?\u20E3/gu,
// eslint-disable-next-line max-len, no-misleading-character-class
EMOJI_SKIN_TONES: /[\u{1f3fb}-\u{1f3ff}]/gu,

TAX_ID: /^\d{9}$/,
NON_NUMERIC: /\D/g,
Expand Down
6 changes: 5 additions & 1 deletion src/components/EmojiPicker/EmojiPicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const EmojiPicker = forwardRef((props, ref) => {
const emojiPopoverAnchorRef = useRef(null);
const onModalHide = useRef(() => {});
const onEmojiSelected = useRef(() => {});
const activeEmoji = useRef();
const emojiSearchInput = useRef();
const {isSmallScreenWidth, windowHeight} = useWindowDimensions();

Expand All @@ -55,10 +56,12 @@ const EmojiPicker = forwardRef((props, ref) => {
* @param {Object} [anchorOrigin=DEFAULT_ANCHOR_ORIGIN] - Anchor origin for Popover
* @param {Function} [onWillShow=() => {}] - Run a callback when Popover will show
* @param {String} id - Unique id for EmojiPicker
* @param {String} activeEmojiValue - Selected emoji to be highlighted
*/
const showEmojiPicker = (onModalHideValue, onEmojiSelectedValue, emojiPopoverAnchorValue, anchorOrigin, onWillShow = () => {}, id) => {
const showEmojiPicker = (onModalHideValue, onEmojiSelectedValue, emojiPopoverAnchorValue, anchorOrigin, onWillShow = () => {}, id, activeEmojiValue) => {
onModalHide.current = onModalHideValue;
onEmojiSelected.current = onEmojiSelectedValue;
activeEmoji.current = activeEmojiValue;
emojiPopoverAnchorRef.current = emojiPopoverAnchorValue;
const emojiPopoverAnchor = getEmojiPopoverAnchor();
if (emojiPopoverAnchor.current && emojiPopoverAnchor.current.blur) {
Expand Down Expand Up @@ -190,6 +193,7 @@ const EmojiPicker = forwardRef((props, ref) => {
>
<EmojiPickerMenu
onEmojiSelected={selectEmoji}
activeEmoji={activeEmoji.current}
ref={(el) => (emojiSearchInput.current = el)}
/>
</PopoverWithMeasuredContent>
Expand Down
19 changes: 13 additions & 6 deletions src/components/EmojiPicker/EmojiPickerButtonDropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,25 @@ function EmojiPickerButtonDropdown(props) {
const StyleUtils = useStyleUtils();
const emojiPopoverAnchor = useRef(null);
useEffect(() => EmojiPickerAction.resetEmojiPopoverAnchor, []);

const onPress = () => {
if (EmojiPickerAction.isEmojiPickerVisible()) {
EmojiPickerAction.hideEmojiPicker();
return;
}

EmojiPickerAction.showEmojiPicker(props.onModalHide, (emoji) => props.onInputChange(emoji), emojiPopoverAnchor, {
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP,
shiftVertical: 4,
});
EmojiPickerAction.showEmojiPicker(
props.onModalHide,
(emoji) => props.onInputChange(emoji),
emojiPopoverAnchor,
{
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP,
shiftVertical: 4,
},
() => {},
undefined,
props.value,
);
};

return (
Expand Down
7 changes: 5 additions & 2 deletions src/components/EmojiPicker/EmojiPickerMenu/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as Browser from '@libs/Browser';
import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus';
import * as EmojiUtils from '@libs/EmojiUtils';
import isEnterWhileComposition from '@libs/KeyboardShortcut/isEnterWhileComposition';
import * as ReportUtils from '@libs/ReportUtils';
import CONST from '@src/CONST';
Expand All @@ -34,7 +35,7 @@ const defaultProps = {

const throttleTime = Browser.isMobile() ? 200 : 50;

function EmojiPickerMenu({forwardedRef, onEmojiSelected}) {
function EmojiPickerMenu({forwardedRef, onEmojiSelected, activeEmoji}) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const {isSmallScreenWidth, windowWidth} = useWindowDimensions();
Expand Down Expand Up @@ -259,7 +260,8 @@ function EmojiPickerMenu({forwardedRef, onEmojiSelected}) {
const emojiCode = types && types[preferredSkinTone] ? types[preferredSkinTone] : code;

const isEmojiFocused = index === focusedIndex && isUsingKeyboardMovement;
const shouldEmojiBeHighlighted = index === focusedIndex && highlightEmoji;
const shouldEmojiBeHighlighted =
(index === focusedIndex && highlightEmoji) || (Boolean(activeEmoji) && EmojiUtils.getRemovedSkinToneEmoji(emojiCode) === EmojiUtils.getRemovedSkinToneEmoji(activeEmoji));
const shouldFirstEmojiBeHighlighted = index === 0 && highlightFirstEmoji;

return (
Expand Down Expand Up @@ -293,6 +295,7 @@ function EmojiPickerMenu({forwardedRef, onEmojiSelected}) {
translate,
onEmojiSelected,
setFocusedIndex,
activeEmoji,
],
);

Expand Down
7 changes: 5 additions & 2 deletions src/components/EmojiPicker/EmojiPickerMenu/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import useSingleExecution from '@hooks/useSingleExecution';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as EmojiUtils from '@libs/EmojiUtils';
import CONST from '@src/CONST';
import BaseEmojiPickerMenu from './BaseEmojiPickerMenu';
import emojiPickerMenuPropTypes from './emojiPickerMenuPropTypes';
import useEmojiPickerMenu from './useEmojiPickerMenu';

const propTypes = emojiPickerMenuPropTypes;

function EmojiPickerMenu({onEmojiSelected}) {
function EmojiPickerMenu({onEmojiSelected, activeEmoji}) {
const styles = useThemeStyles();
const {windowWidth, isSmallScreenWidth} = useWindowDimensions();
const {translate} = useLocalize();
Expand Down Expand Up @@ -94,15 +95,17 @@ function EmojiPickerMenu({onEmojiSelected}) {
}

const emojiCode = types && types[preferredSkinTone] ? types[preferredSkinTone] : code;
const shouldEmojiBeHighlighted = Boolean(activeEmoji) && EmojiUtils.getRemovedSkinToneEmoji(emojiCode) === EmojiUtils.getRemovedSkinToneEmoji(activeEmoji);

return (
<EmojiPickerMenuItem
onPress={singleExecution((emoji) => onEmojiSelected(emoji, item))}
emoji={emojiCode}
isHighlighted={shouldEmojiBeHighlighted}
/>
);
},
[styles, windowWidth, preferredSkinTone, singleExecution, onEmojiSelected, translate],
[styles, windowWidth, preferredSkinTone, singleExecution, onEmojiSelected, translate, activeEmoji],
);

return (
Expand Down
6 changes: 6 additions & 0 deletions src/libs/EmojiUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,11 @@ const getEmojiReactionDetails = (emojiName: string, reaction: ReportActionReacti
};
};

/**
* Given an emoji code, returns an base emoji code without skin tone
*/
const getRemovedSkinToneEmoji = (emoji: string) => emoji.replace(CONST.REGEX.EMOJI_SKIN_TONES, '');

function getSpacersIndexes(allEmojis: EmojiPickerList): number[] {
const spacersIndexes: number[] = [];
allEmojis.forEach((emoji, index) => {
Expand Down Expand Up @@ -582,5 +587,6 @@ export {
getAddedEmojis,
isFirstLetterEmoji,
hasAccountIDEmojiReacted,
getRemovedSkinToneEmoji,
getSpacersIndexes,
};
4 changes: 3 additions & 1 deletion src/libs/actions/EmojiPickerAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type EmojiPickerRef = {
anchorOrigin?: AnchorOrigin,
onWillShow?: OnWillShowPicker,
id?: string,
activeEmoji?: string,
) => void;
isActive: (id: string) => boolean;
clearActive: () => void;
Expand Down Expand Up @@ -55,12 +56,13 @@ function showEmojiPicker(
anchorOrigin?: AnchorOrigin,
onWillShow: OnWillShowPicker = () => {},
id?: string,
activeEmoji?: string,
) {
if (!emojiPickerRef.current) {
return;
}

emojiPickerRef.current.showEmojiPicker(onModalHide, onEmojiSelected, emojiPopoverAnchor, anchorOrigin, onWillShow, id);
emojiPickerRef.current.showEmojiPicker(onModalHide, onEmojiSelected, emojiPopoverAnchor, anchorOrigin, onWillShow, id, activeEmoji);
}

/**
Expand Down

0 comments on commit d7f87c5

Please sign in to comment.