From 83f0edefcccbd730ea2a759a5d950db4b6bac826 Mon Sep 17 00:00:00 2001 From: Danish Date: Sat, 20 Aug 2022 20:02:13 +0530 Subject: [PATCH] Tweaks --- app/containers/EmojiPicker/EmojiCategory.tsx | 7 ++- app/containers/EmojiPicker/emojis.ts | 2 + app/containers/EmojiPicker/index.tsx | 32 ++++++------ app/containers/MessageActions/Header.tsx | 3 +- app/containers/MessageBox/EmojiKeyboard.tsx | 11 ++-- app/containers/MessageBox/EmojiSearchbar.tsx | 54 +++++++++++--------- app/containers/MessageBox/index.tsx | 15 +++--- app/definitions/IEmoji.ts | 6 +-- 8 files changed, 67 insertions(+), 63 deletions(-) diff --git a/app/containers/EmojiPicker/EmojiCategory.tsx b/app/containers/EmojiPicker/EmojiCategory.tsx index adee9d843..d2fe39703 100644 --- a/app/containers/EmojiPicker/EmojiCategory.tsx +++ b/app/containers/EmojiPicker/EmojiCategory.tsx @@ -35,12 +35,11 @@ const EmojiCategory = ({ baseUrl, onEmojiSelected, emojis, width, tabsCount }: I const numColumns = Math.trunc(width ? width / emojiSize : tabsCount); const { colors } = useTheme(); - const renderItem = (emoji: IEmoji) => ( + const renderItem = (emoji: IEmoji | string) => ( onEmojiSelected(emoji)} - testID={`reaction-picker-${emoji && emoji.isCustom ? emoji.content : emoji}`} + testID={`reaction-picker-${typeof emoji === 'string' ? emoji : emoji.content}`} android_ripple={{ color: colors.bannerBackground, borderless: true, radius: emojiSize / 2 }} style={({ pressed }: { pressed: boolean }) => ({ backgroundColor: isIOS && pressed ? colors.bannerBackground : 'transparent' diff --git a/app/containers/EmojiPicker/emojis.ts b/app/containers/EmojiPicker/emojis.ts index b5ed98f52..965343d2e 100644 --- a/app/containers/EmojiPicker/emojis.ts +++ b/app/containers/EmojiPicker/emojis.ts @@ -2813,3 +2813,5 @@ export const emojis = [ 'flag_tc', 'flag_mf' ]; + +export const DEFAULT_EMOJIS = ['clap', '+1', 'heart_eyes', 'grinning', 'thinking_face', 'smiley']; diff --git a/app/containers/EmojiPicker/index.tsx b/app/containers/EmojiPicker/index.tsx index 2d20c1c73..293363b90 100644 --- a/app/containers/EmojiPicker/index.tsx +++ b/app/containers/EmojiPicker/index.tsx @@ -2,6 +2,7 @@ import React, { useMemo, useState } from 'react'; import { View } from 'react-native'; import ScrollableTabView from 'react-native-scrollable-tab-view'; import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord'; +import { shallowEqual } from 'react-redux'; import TabBar from './TabBar'; import EmojiCategory from './EmojiCategory'; @@ -10,7 +11,6 @@ import styles from './styles'; import categories from './categories'; import database from '../../lib/database'; import { emojisByCategory } from './emojis'; -import protectedFunction from '../../lib/methods/helpers/protectedFunction'; import shortnameToUnicode from '../../lib/methods/helpers/shortnameToUnicode'; import log from '../../lib/methods/helpers/log'; import { useTheme } from '../../theme'; @@ -31,20 +31,21 @@ const EmojiPicker = ({ const { frequentlyUsed, loaded } = useFrequentlyUsedEmoji(); const baseUrl = useAppSelector(state => state.server?.server); - const allCustomEmojis: ICustomEmojis = useAppSelector(state => state.customEmojis); + const allCustomEmojis: ICustomEmojis = useAppSelector(state => state.customEmojis, shallowEqual); const customEmojis = useMemo( () => Object.keys(allCustomEmojis) .filter(item => item === allCustomEmojis[item].name) .map(item => ({ content: allCustomEmojis[item].name, + name: allCustomEmojis[item].name, extension: allCustomEmojis[item].extension, isCustom: true })), [allCustomEmojis] ); - const _addFrequentlyUsed = protectedFunction(async (emoji: IEmoji) => { + const addFrequentlyUsed = async (emoji: IEmoji) => { const db = database.active; const freqEmojiCollection = db.get('frequently_used_emojis'); let freqEmojiRecord: TFrequentlyUsedEmojiModel; @@ -69,21 +70,22 @@ const EmojiPicker = ({ }); } }); - }); + }; - const handleEmojiSelect = (emoji: IEmoji) => { + const handleEmojiSelect = (emoji: IEmoji | string) => { try { - if (emoji.isCustom) { - _addFrequentlyUsed({ + if (typeof emoji === 'string') { + addFrequentlyUsed({ content: emoji, name: emoji, isCustom: false }); + const shortname = `:${emoji}:`; + onItemClicked(EventTypes.EMOJI_PRESSED, shortnameToUnicode(shortname), shortname); + } else { + addFrequentlyUsed({ content: emoji.content, + name: emoji.content, extension: emoji.extension, isCustom: true }); onItemClicked(EventTypes.EMOJI_PRESSED, `:${emoji.content}:`); - } else { - _addFrequentlyUsed({ content: emoji, isCustom: false }); - const shortname = `:${emoji}:`; - onItemClicked(EventTypes.EMOJI_PRESSED, shortnameToUnicode(shortname), shortname); } } catch (e) { log(e); @@ -107,8 +109,8 @@ const EmojiPicker = ({ } return ( handleEmojiSelect(emoji)} + emojis={emojis} + onEmojiSelected={(emoji: IEmoji | string) => handleEmojiSelect(emoji)} style={styles.categoryContainer} width={width} baseUrl={baseUrl} @@ -128,8 +130,8 @@ const EmojiPicker = ({ {searching ? ( handleEmojiSelect(emoji)} + emojis={searchedEmojis} + onEmojiSelected={(emoji: IEmoji | string) => handleEmojiSelect(emoji)} style={styles.categoryContainer} width={width} baseUrl={baseUrl} diff --git a/app/containers/MessageActions/Header.tsx b/app/containers/MessageActions/Header.tsx index 1e573dc07..709aaf824 100644 --- a/app/containers/MessageActions/Header.tsx +++ b/app/containers/MessageActions/Header.tsx @@ -11,6 +11,7 @@ import { useDimensions } from '../../dimensions'; import sharedStyles from '../../views/Styles'; import { TAnyMessageModel, TFrequentlyUsedEmojiModel } from '../../definitions'; import Touch from '../Touch'; +import { DEFAULT_EMOJIS } from '../EmojiPicker/emojis'; type TItem = TFrequentlyUsedEmojiModel | string; @@ -69,8 +70,6 @@ const keyExtractor = (item: TItem) => { return (emojiModel.id ? emojiModel.content : item) as string; }; -const DEFAULT_EMOJIS = ['clap', '+1', 'heart_eyes', 'grinning', 'thinking_face', 'smiley']; - const HeaderItem = ({ item, onReaction, server, theme }: THeaderItem) => { const emojiModel = item as TFrequentlyUsedEmojiModel; const emoji = (emojiModel.id ? emojiModel.content : item) as string; diff --git a/app/containers/MessageBox/EmojiKeyboard.tsx b/app/containers/MessageBox/EmojiKeyboard.tsx index 4efbbf421..02d1a57f9 100644 --- a/app/containers/MessageBox/EmojiKeyboard.tsx +++ b/app/containers/MessageBox/EmojiKeyboard.tsx @@ -6,22 +6,19 @@ import { Provider } from 'react-redux'; import store from '../../lib/store'; import EmojiPicker from '../EmojiPicker'; import styles from './styles'; -import {useTheme} from '../../theme' +import { useTheme } from '../../theme'; import { EventTypes } from '../EmojiPicker/interfaces'; const EmojiKeyboard = () => { + const { colors } = useTheme(); + const onItemClicked = (eventType: EventTypes, emoji: string | undefined) => { KeyboardRegistry.onItemSelected('EmojiKeyboard', { eventType, emoji }); }; - const {colors} = useTheme() - return ( - + diff --git a/app/containers/MessageBox/EmojiSearchbar.tsx b/app/containers/MessageBox/EmojiSearchbar.tsx index 955be5316..98329bf96 100644 --- a/app/containers/MessageBox/EmojiSearchbar.tsx +++ b/app/containers/MessageBox/EmojiSearchbar.tsx @@ -10,40 +10,52 @@ import shortnameToUnicode from '../../lib/methods/helpers/shortnameToUnicode'; import CustomEmoji from '../EmojiPicker/CustomEmoji'; import styles from './styles'; import useFrequentlyUsedEmoji from '../EmojiPicker/frequentlyUsedEmojis'; +import { DEFAULT_EMOJIS } from '../EmojiPicker/emojis'; -const BUTTON_HIT_SLOP = { top: 15, right: 15, bottom: 15, left: 15 }; +const BUTTON_HIT_SLOP = { top: 4, right: 4, bottom: 4, left: 4 }; const EMOJI_SIZE = 30; -const DEFAULT_EMOJIS = ['clap', '+1', 'heart_eyes', 'grinning', 'thinking_face', 'smiley']; interface IEmojiSearchBarProps { openEmoji: () => void; onChangeText: (value: string) => void; - emojis: IEmoji[]; - onEmojiSelected: (emoji: IEmoji) => void; + emojis: (IEmoji | string)[]; + onEmojiSelected: (emoji: IEmoji | string) => void; baseUrl: string; } -interface ICustomEmoji { - name: string; - extension: string; +interface IListItem { + emoji: IEmoji | string; + onEmojiSelected: (emoji: IEmoji | string) => void; + baseUrl: string; } -const Emoji = React.memo(({ emoji, baseUrl }: { emoji: IEmoji; baseUrl: string }) => { +const Emoji = ({ emoji, baseUrl }: { emoji: IEmoji | string; baseUrl: string }): React.ReactElement => { const { colors } = useTheme(); - if (emoji.isCustom || emoji.name) { - return ; + if (typeof emoji === 'string') { + return ( + + {shortnameToUnicode(`:${emoji}:`)} + + ); } + return ; +}; + +const ListItem = ({ emoji, onEmojiSelected, baseUrl }: IListItem): React.ReactElement => { + const key = typeof emoji === 'string' ? emoji : emoji?.name || emoji?.content; return ( - - {shortnameToUnicode(`:${emoji}:`)} - + + onEmojiSelected(emoji)}> + + + ); -}); +}; const EmojiSearchBar = React.forwardRef( ({ openEmoji, onChangeText, emojis, onEmojiSelected, baseUrl }, ref) => { const { colors } = useTheme(); const [searchText, setSearchText] = useState(''); - const [frequentlyUsedEmojis, setFrequentlyUsed] = useState<(string | ICustomEmoji)[]>(); + const [frequentlyUsedEmojis, setFrequentlyUsed] = useState<(string | IEmoji)[]>(); const { frequentlyUsed, loaded } = useFrequentlyUsedEmoji(); useEffect(() => { @@ -63,20 +75,12 @@ const EmojiSearchBar = React.forwardRef( onChangeText(text); }; - const ListItem = React.memo(({ emoji }: { emoji: IEmoji }) => ( - - onEmojiSelected(emoji)}> - - - - )); - return ( } + renderItem={({ item }) => } showsHorizontalScrollIndicator={false} ListEmptyComponent={() => ( @@ -84,7 +88,7 @@ const EmojiSearchBar = React.forwardRef( )} // @ts-ignore - keyExtractor={item => item?.name || item} + keyExtractor={item => item?.content || item?.name || item} contentContainerStyle={styles.emojiListContainer} keyboardShouldPersistTaps='always' /> diff --git a/app/containers/MessageBox/index.tsx b/app/containers/MessageBox/index.tsx index 6a71d05e0..cd424c298 100644 --- a/app/containers/MessageBox/index.tsx +++ b/app/containers/MessageBox/index.tsx @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { Alert, Keyboard, NativeModules, Text, View, TextInput as RNTextInput, BackHandler } from 'react-native'; +import { Alert, Keyboard, NativeModules, Text, View, BackHandler } from 'react-native'; import { connect } from 'react-redux'; import { KeyboardAccessoryView } from 'react-native-ui-lib/keyboard'; import ImagePicker, { Image, ImageOrVideo, Options } from 'react-native-image-crop-picker'; @@ -166,7 +166,7 @@ class MessageBox extends Component { private typingTimeout: any; - private emojiSearchbarRef: React.RefObject; + private emojiSearchbarRef: any; static defaultProps = { message: { @@ -198,7 +198,6 @@ class MessageBox extends Component { this.text = ''; this.selection = { start: 0, end: 0 }; this.focused = false; - this.emojiSearchbarRef = React.createRef(); const libPickerLabels = { cropperChooseText: I18n.t('Choose'), @@ -630,7 +629,9 @@ class MessageBox extends Component { case EventTypes.SEARCH_PRESSED: this.setState({ showEmojiKeyboard: false, showEmojiSearchbar: true }); setTimeout(() => { - this.emojiSearchbarRef.current?.focus(); + if (this.emojiSearchbarRef && this.emojiSearchbarRef.focus) { + this.emojiSearchbarRef.focus(); + } }, 400); break; default: @@ -1161,8 +1162,8 @@ class MessageBox extends Component { const onEmojiSelected = (emoji: any) => { let selectedEmoji; - if (emoji.name) { - selectedEmoji = `:${emoji.name}:`; + if (emoji.name || emoji.content) { + selectedEmoji = `:${emoji.name || emoji.content}:`; } else { selectedEmoji = shortnameToUnicode(`:${emoji}:`); } @@ -1177,7 +1178,7 @@ class MessageBox extends Component { }; return showEmojiSearchbar ? ( (this.emojiSearchbarRef = ref)} openEmoji={this.openEmoji} onChangeText={onChangeText} emojis={searchedEmojis} diff --git a/app/definitions/IEmoji.ts b/app/definitions/IEmoji.ts index 0dcf298bf..b48fd9fe6 100644 --- a/app/definitions/IEmoji.ts +++ b/app/definitions/IEmoji.ts @@ -5,7 +5,7 @@ import { ImageStyle } from 'react-native-fast-image'; export interface IEmoji { content: string; name: string; - extension: string; + extension?: string; isCustom: boolean; count?: number; } @@ -30,8 +30,8 @@ export interface ICustomEmojiModel { export interface IEmojiCategory { baseUrl: string; - emojis: IEmoji[]; - onEmojiSelected: (emoji: IEmoji) => void; + emojis: (IEmoji | string)[]; + onEmojiSelected: (emoji: IEmoji | string) => void; width: number | null; style: StyleProp; tabLabel: string;