2023-03-09 20:17:20 +00:00
|
|
|
import React, { useState } from 'react';
|
2022-10-21 18:27:55 +00:00
|
|
|
import { View } from 'react-native';
|
2018-01-16 18:48:05 +00:00
|
|
|
import ScrollableTabView from 'react-native-scrollable-tab-view';
|
2018-12-21 10:55:35 +00:00
|
|
|
|
2018-01-16 18:48:05 +00:00
|
|
|
import TabBar from './TabBar';
|
|
|
|
import EmojiCategory from './EmojiCategory';
|
2022-10-21 18:27:55 +00:00
|
|
|
import Footer from './Footer';
|
2018-01-16 18:48:05 +00:00
|
|
|
import styles from './styles';
|
2022-10-21 18:27:55 +00:00
|
|
|
import { categories, emojisByCategory } from '../../lib/constants';
|
|
|
|
import { useTheme } from '../../theme';
|
|
|
|
import { IEmoji, ICustomEmojis } from '../../definitions';
|
|
|
|
import { useAppSelector, useFrequentlyUsedEmoji } from '../../lib/hooks';
|
|
|
|
import { addFrequentlyUsed } from '../../lib/methods';
|
|
|
|
import { IEmojiPickerProps, EventTypes } from './interfaces';
|
|
|
|
|
|
|
|
const EmojiPicker = ({
|
|
|
|
onItemClicked,
|
|
|
|
isEmojiKeyboard = false,
|
|
|
|
searching = false,
|
|
|
|
searchedEmojis = []
|
|
|
|
}: IEmojiPickerProps): React.ReactElement | null => {
|
|
|
|
const { colors } = useTheme();
|
2023-03-09 20:17:20 +00:00
|
|
|
const [parentWidth, setParentWidth] = useState(0);
|
|
|
|
|
2022-10-21 18:27:55 +00:00
|
|
|
const { frequentlyUsed, loaded } = useFrequentlyUsedEmoji();
|
|
|
|
|
|
|
|
const allCustomEmojis: ICustomEmojis = useAppSelector(
|
|
|
|
state => state.customEmojis,
|
|
|
|
() => true
|
|
|
|
);
|
|
|
|
const customEmojis = Object.keys(allCustomEmojis)
|
|
|
|
.filter(item => item === allCustomEmojis[item].name)
|
|
|
|
.map(item => ({
|
|
|
|
name: allCustomEmojis[item].name,
|
|
|
|
extension: allCustomEmojis[item].extension
|
|
|
|
}));
|
|
|
|
|
|
|
|
const handleEmojiSelect = (emoji: IEmoji) => {
|
|
|
|
onItemClicked(EventTypes.EMOJI_PRESSED, emoji);
|
|
|
|
addFrequentlyUsed(emoji);
|
2021-09-13 20:41:05 +00:00
|
|
|
};
|
2018-01-16 18:48:05 +00:00
|
|
|
|
2022-10-21 18:27:55 +00:00
|
|
|
const renderCategory = (category: keyof typeof emojisByCategory, i: number, label: string) => {
|
2018-01-16 18:48:05 +00:00
|
|
|
let emojis = [];
|
|
|
|
if (i === 0) {
|
2018-09-25 19:28:42 +00:00
|
|
|
emojis = frequentlyUsed;
|
2018-01-16 18:48:05 +00:00
|
|
|
} else if (i === 1) {
|
2018-09-25 19:28:42 +00:00
|
|
|
emojis = customEmojis;
|
2018-01-16 18:48:05 +00:00
|
|
|
} else {
|
|
|
|
emojis = emojisByCategory[category];
|
|
|
|
}
|
2022-10-21 18:27:55 +00:00
|
|
|
if (!emojis.length) {
|
2018-01-30 19:48:26 +00:00
|
|
|
return null;
|
|
|
|
}
|
2023-03-09 20:17:20 +00:00
|
|
|
return (
|
|
|
|
<EmojiCategory
|
|
|
|
parentWidth={parentWidth}
|
|
|
|
emojis={emojis}
|
|
|
|
onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)}
|
|
|
|
tabLabel={label}
|
|
|
|
/>
|
|
|
|
);
|
2022-10-21 18:27:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if (!loaded) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2023-03-09 20:17:20 +00:00
|
|
|
<View style={styles.emojiPickerContainer} onLayout={e => setParentWidth(e.nativeEvent.layout.width)}>
|
2022-10-21 18:27:55 +00:00
|
|
|
{searching ? (
|
2023-03-09 20:17:20 +00:00
|
|
|
<EmojiCategory
|
|
|
|
emojis={searchedEmojis}
|
|
|
|
onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)}
|
|
|
|
parentWidth={parentWidth}
|
|
|
|
/>
|
2022-10-21 18:27:55 +00:00
|
|
|
) : (
|
2019-11-25 20:01:17 +00:00
|
|
|
<ScrollableTabView
|
2022-10-21 18:27:55 +00:00
|
|
|
renderTabBar={() => <TabBar />}
|
2022-05-07 01:06:08 +00:00
|
|
|
contentProps={{
|
|
|
|
keyboardShouldPersistTaps: 'always',
|
|
|
|
keyboardDismissMode: 'none'
|
|
|
|
}}
|
2024-01-25 14:11:07 +00:00
|
|
|
style={{ backgroundColor: colors.surfaceLight }}
|
2022-08-08 21:02:08 +00:00
|
|
|
>
|
2022-10-21 18:27:55 +00:00
|
|
|
{categories.tabs.map((tab: any, i) => renderCategory(tab.category, i, tab.tabLabel))}
|
2019-11-25 20:01:17 +00:00
|
|
|
</ScrollableTabView>
|
2022-10-21 18:27:55 +00:00
|
|
|
)}
|
|
|
|
{isEmojiKeyboard && (
|
|
|
|
<Footer
|
|
|
|
onSearchPressed={() => onItemClicked(EventTypes.SEARCH_PRESSED)}
|
|
|
|
onBackspacePressed={() => onItemClicked(EventTypes.BACKSPACE_PRESSED)}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</View>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default EmojiPicker;
|