Skip to content

Commit

Permalink
Merge pull request #32929 from VickyStash/ts-migration/reactions-comp…
Browse files Browse the repository at this point in the history
…onent

[TS migration] Migrate 'Reactions' component to TypeScript
  • Loading branch information
AndrewGable authored Jan 4, 2024
2 parents 9b74851 + 1d4010e commit b03fe67
Show file tree
Hide file tree
Showing 23 changed files with 529 additions and 544 deletions.
9 changes: 6 additions & 3 deletions assets/emojis/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import type {Locale} from '@src/types/onyx';
import emojis from './common';
import enEmojis from './en';
import esEmojis from './es';
import type {Emoji} from './types';
import type {Emoji, EmojisList} from './types';

type EmojiTable = Record<string, Emoji>;

type LocaleEmojis = Partial<Record<Locale, EmojisList>>;

const emojiNameTable = emojis.reduce<EmojiTable>((prev, cur) => {
const newValue = prev;
if (!('header' in cur) && cur.name) {
Expand All @@ -26,10 +29,10 @@ const emojiCodeTableWithSkinTones = emojis.reduce<EmojiTable>((prev, cur) => {
return newValue;
}, {});

const localeEmojis = {
const localeEmojis: LocaleEmojis = {
en: enEmojis,
es: esEmojis,
} as const;
};

export default emojis;
export {emojiNameTable, emojiCodeTableWithSkinTones, localeEmojis};
Expand Down
8 changes: 5 additions & 3 deletions assets/emojis/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type IconAsset from '@src/types/utils/IconAsset';
type Emoji = {
code: string;
name: string;
types?: string[];
types?: readonly string[];
};

type HeaderEmoji = {
Expand All @@ -12,8 +12,10 @@ type HeaderEmoji = {
code: string;
};

type PickerEmojis = Array<Emoji | HeaderEmoji>;
type PickerEmoji = Emoji | HeaderEmoji;

type PickerEmojis = PickerEmoji[];

type EmojisList = Record<string, {keywords: string[]; name?: string}>;

export type {Emoji, HeaderEmoji, EmojisList, PickerEmojis};
export type {Emoji, HeaderEmoji, EmojisList, PickerEmojis, PickerEmoji};
8 changes: 4 additions & 4 deletions src/components/EmojiSuggestions.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type {ReactElement} from 'react';
import React, {useCallback} from 'react';
import {View} from 'react-native';
import type {Emoji} from '@assets/emojis/types';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import type {SimpleEmoji} from '@libs/EmojiTrie';
import * as EmojiUtils from '@libs/EmojiUtils';
import getStyledTextArray from '@libs/GetStyledTextArray';
import AutoCompleteSuggestions from './AutoCompleteSuggestions';
Expand All @@ -16,7 +16,7 @@ type EmojiSuggestionsProps = {
highlightedEmojiIndex?: number;

/** Array of suggested emoji */
emojis: SimpleEmoji[];
emojis: Emoji[];

/** Fired when the user selects an emoji */
onSelect: (index: number) => void;
Expand All @@ -40,7 +40,7 @@ type EmojiSuggestionsProps = {
/**
* Create unique keys for each emoji item
*/
const keyExtractor = (item: SimpleEmoji, index: number): string => `${item.name}+${index}}`;
const keyExtractor = (item: Emoji, index: number): string => `${item.name}+${index}}`;

function EmojiSuggestions({emojis, onSelect, prefix, isEmojiPickerLarge, preferredSkinToneIndex, highlightedEmojiIndex = 0, measureParentContainer = () => {}}: EmojiSuggestionsProps) {
const styles = useThemeStyles();
Expand All @@ -49,7 +49,7 @@ function EmojiSuggestions({emojis, onSelect, prefix, isEmojiPickerLarge, preferr
* Render an emoji suggestion menu item component.
*/
const renderSuggestionMenuItem = useCallback(
(item: SimpleEmoji): ReactElement => {
(item: Emoji): ReactElement => {
const styledTextArray = getStyledTextArray(item.name, prefix);

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,81 +1,75 @@
import PropTypes from 'prop-types';
import React, {useEffect, useRef} from 'react';
import {View} from 'react-native';
import type {Emoji} from '@assets/emojis/types';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
import Text from '@components/Text';
import Tooltip from '@components/Tooltip/PopoverAnchorTooltip';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import useLocalize from '@hooks/useLocalize';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import getButtonState from '@libs/getButtonState';
import variables from '@styles/variables';
import * as EmojiPickerAction from '@userActions/EmojiPickerAction';
import type {AnchorOrigin} from '@userActions/EmojiPickerAction';
import * as Session from '@userActions/Session';
import CONST from '@src/CONST';
import type {ReportAction} from '@src/types/onyx';
import type {CloseContextMenuCallback, OpenPickerCallback, PickerRefElement} from './QuickEmojiReactions/types';

const propTypes = {
type AddReactionBubbleProps = {
/** Whether it is for context menu so we can modify its style */
isContextMenu: PropTypes.bool,
isContextMenu?: boolean;

/**
* Called when the user presses on the icon button.
* Will have a function as parameter which you can call
* to open the picker.
*/
onPressOpenPicker: PropTypes.func,
onPressOpenPicker?: (openPicker: OpenPickerCallback) => void;

/**
* Will get called the moment before the picker opens.
*/
onWillShowPicker: PropTypes.func,
onWillShowPicker?: (callback: CloseContextMenuCallback) => void;

/**
* Called when the user selects an emoji.
*/
onSelectEmoji: PropTypes.func.isRequired,
onSelectEmoji: (emoji: Emoji) => void;

/**
* ReportAction for EmojiPicker.
*/
reportAction: PropTypes.shape({
reportActionID: PropTypes.string.isRequired,
}),

...withLocalizePropTypes,
};

const defaultProps = {
isContextMenu: false,
onWillShowPicker: () => {},
onPressOpenPicker: undefined,
reportAction: {},
reportAction: ReportAction;
};

function AddReactionBubble(props) {
function AddReactionBubble({onSelectEmoji, reportAction, onPressOpenPicker, onWillShowPicker = () => {}, isContextMenu = false}: AddReactionBubbleProps) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const ref = useRef();
const ref = useRef<View | HTMLDivElement>(null);
const {translate} = useLocalize();

useEffect(() => EmojiPickerAction.resetEmojiPopoverAnchor, []);

const onPress = () => {
const openPicker = (refParam, anchorOrigin) => {
const openPicker = (refParam?: PickerRefElement, anchorOrigin?: AnchorOrigin) => {
EmojiPickerAction.showEmojiPicker(
() => {},
(emojiCode, emojiObject) => {
props.onSelectEmoji(emojiObject);
onSelectEmoji(emojiObject);
},
refParam || ref,
refParam ?? ref,
anchorOrigin,
props.onWillShowPicker,
props.reportAction.reportActionID,
onWillShowPicker,
reportAction.reportActionID,
);
};

if (!EmojiPickerAction.emojiPickerRef.current.isEmojiPickerVisible) {
if (props.onPressOpenPicker) {
props.onPressOpenPicker(openPicker);
if (!EmojiPickerAction.emojiPickerRef.current?.isEmojiPickerVisible) {
if (onPressOpenPicker) {
onPressOpenPicker(openPicker);
} else {
openPicker();
}
Expand All @@ -85,21 +79,21 @@ function AddReactionBubble(props) {
};

return (
<Tooltip text={props.translate('emojiReactions.addReactionTooltip')}>
<Tooltip text={translate('emojiReactions.addReactionTooltip')}>
<PressableWithFeedback
ref={ref}
style={({hovered, pressed}) => [styles.emojiReactionBubble, styles.userSelectNone, StyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, false, props.isContextMenu)]}
style={({hovered, pressed}) => [styles.emojiReactionBubble, styles.userSelectNone, StyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, false, isContextMenu)]}
onPress={Session.checkIfActionIsAllowed(onPress)}
onMouseDown={(e) => {
onMouseDown={(event) => {
// Allow text input blur when Add reaction is right clicked
if (!e || e.button === 2) {
if (!event || event.button === 2) {
return;
}

// Prevent text input blur when Add reaction is left clicked
e.preventDefault();
event.preventDefault();
}}
accessibilityLabel={props.translate('emojiReactions.addReactionTooltip')}
accessibilityLabel={translate('emojiReactions.addReactionTooltip')}
role={CONST.ROLE.BUTTON}
// disable dimming
pressDimmingValue={1}
Expand All @@ -110,12 +104,12 @@ function AddReactionBubble(props) {
{/* This (invisible) text will make the view have the same size as a regular
emoji reaction. We make the text invisible and put the
icon on top of it. */}
<Text style={[styles.opacity0, StyleUtils.getEmojiReactionBubbleTextStyle(props.isContextMenu)]}>{'\u2800\u2800'}</Text>
<Text style={[styles.opacity0, StyleUtils.getEmojiReactionBubbleTextStyle(isContextMenu)]}>{'\u2800\u2800'}</Text>
<View style={styles.pAbsolute}>
<Icon
src={Expensicons.AddReaction}
width={props.isContextMenu ? variables.iconSizeNormal : variables.iconSizeSmall}
height={props.isContextMenu ? variables.iconSizeNormal : variables.iconSizeSmall}
width={isContextMenu ? variables.iconSizeNormal : variables.iconSizeSmall}
height={isContextMenu ? variables.iconSizeNormal : variables.iconSizeSmall}
fill={StyleUtils.getIconFillColor(getButtonState(hovered, pressed))}
/>
</View>
Expand All @@ -126,8 +120,6 @@ function AddReactionBubble(props) {
);
}

AddReactionBubble.propTypes = propTypes;
AddReactionBubble.defaultProps = defaultProps;
AddReactionBubble.displayName = 'AddReactionBubble';

export default withLocalize(AddReactionBubble);
export default AddReactionBubble;
110 changes: 0 additions & 110 deletions src/components/Reactions/EmojiReactionBubble.js

This file was deleted.

Loading

0 comments on commit b03fe67

Please sign in to comment.