From d851e6fdded7101cac8dd6bedbadbdd88813616b Mon Sep 17 00:00:00 2001 From: Andrzej Zaborski Date: Sun, 4 Feb 2024 15:42:47 +0100 Subject: [PATCH 1/2] fix: infinite loop on category swipe, refactor logic for scrolling emoji list --- src/components/Categories.tsx | 13 +++++++++---- src/components/CategoryItem.tsx | 6 +++--- src/components/EmojiStaticKeyboard.tsx | 24 ++++++++++++++++-------- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/components/Categories.tsx b/src/components/Categories.tsx index 7b513479..f6f5df8b 100644 --- a/src/components/Categories.tsx +++ b/src/components/Categories.tsx @@ -6,12 +6,13 @@ import { CategoryItem } from './CategoryItem' import { exhaustiveTypeCheck } from '../utils/exhaustiveTypeCheck' import { defaultTheme } from '../contexts/KeyboardContext' -const CATEGORY_ELEMENT_WIDTH = 37 +export const CATEGORY_ELEMENT_WIDTH = 37 const Separator = () => type Props = { scrollNav?: Animated.Value + scrollEmojiCategoryListToIndex: (index: number) => void } export const Categories = (p: Props) => { @@ -27,9 +28,13 @@ export const Categories = (p: Props) => { } = React.useContext(KeyboardContext) const scrollNav = React.useRef(new Animated.Value(0)).current - const handleScrollToCategory = React.useCallback(() => { - setShouldAnimateScroll(enableCategoryChangeAnimation) - }, [setShouldAnimateScroll, enableCategoryChangeAnimation]) + const handleScrollToCategory = React.useCallback( + (index: number) => { + setShouldAnimateScroll(enableCategoryChangeAnimation) + p.scrollEmojiCategoryListToIndex(index) + }, + [setShouldAnimateScroll, enableCategoryChangeAnimation, p], + ) const renderItem = React.useCallback( ({ item, index }: { item: CategoryNavigationItem; index: number }) => ( diff --git a/src/components/CategoryItem.tsx b/src/components/CategoryItem.tsx index d46d865b..cfef1317 100644 --- a/src/components/CategoryItem.tsx +++ b/src/components/CategoryItem.tsx @@ -1,20 +1,20 @@ import * as React from 'react' import { View, StyleSheet, TouchableOpacity } from 'react-native' import { KeyboardContext } from '../contexts/KeyboardContext' -import type { CategoryNavigationItem, CategoryTypes } from '../types' +import type { CategoryNavigationItem } from '../types' import { Icon } from './Icon' type CategoryItemProps = { item: CategoryNavigationItem index: number - handleScrollToCategory: (category: CategoryTypes) => void + handleScrollToCategory: (index: number) => void } export const CategoryItem = ({ item, index, handleScrollToCategory }: CategoryItemProps) => { const { activeCategoryIndex, theme, setActiveCategoryIndex } = React.useContext(KeyboardContext) const handleSelect = () => { - handleScrollToCategory(item.category) + handleScrollToCategory(index) setActiveCategoryIndex(index) } diff --git a/src/components/EmojiStaticKeyboard.tsx b/src/components/EmojiStaticKeyboard.tsx index d1934c92..d80cb76b 100644 --- a/src/components/EmojiStaticKeyboard.tsx +++ b/src/components/EmojiStaticKeyboard.tsx @@ -13,13 +13,12 @@ import { import { type EmojisByCategory } from '../types' import { EmojiCategory } from './EmojiCategory' import { KeyboardContext } from '../contexts/KeyboardContext' -import { Categories } from './Categories' +import { Categories, CATEGORY_ELEMENT_WIDTH } from './Categories' import { SearchBar } from './SearchBar' import { useKeyboardStore } from '../store/useKeyboardStore' import { ConditionalContainer } from './ConditionalContainer' import { SkinTones } from './SkinTones' -const CATEGORY_ELEMENT_WIDTH = 37 const isAndroid = Platform.OS === 'android' export const EmojiStaticKeyboard = React.memo( @@ -85,13 +84,19 @@ export const EmojiStaticKeyboard = React.memo( [activeCategoryIndex], ) + const scrollEmojiCategoryListToIndex = React.useCallback( + (index: number) => { + flatListRef.current?.scrollToIndex({ + index, + animated: shouldAnimateScroll && enableCategoryChangeAnimation, + }) + }, + [enableCategoryChangeAnimation, shouldAnimateScroll], + ) + React.useEffect(() => { - flatListRef.current?.scrollToIndex({ - index: activeCategoryIndex, - animated: shouldAnimateScroll && enableCategoryChangeAnimation, - }) setKeyboardScrollOffsetY(0) - }, [activeCategoryIndex, enableCategoryChangeAnimation, shouldAnimateScroll]) + }, [activeCategoryIndex]) const keyExtractor = React.useCallback((item: EmojisByCategory) => item.title, []) const scrollNav = React.useRef(new Animated.Value(0)).current @@ -155,7 +160,10 @@ export const EmojiStaticKeyboard = React.memo( keyboardShouldPersistTaps="handled" onMomentumScrollEnd={onScrollEnd} /> - + From 946ff17a854af28ea58da42965bc6a25d2e3b4c7 Mon Sep 17 00:00:00 2001 From: Andrzej Zaborski Date: Wed, 7 Feb 2024 09:29:30 +0100 Subject: [PATCH 2/2] fix: refactor SearchBar to use scrollEmojiCategoryListToIndex method --- src/components/EmojiStaticKeyboard.tsx | 4 +++- src/components/SearchBar.tsx | 9 ++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/EmojiStaticKeyboard.tsx b/src/components/EmojiStaticKeyboard.tsx index d80cb76b..b8194e76 100644 --- a/src/components/EmojiStaticKeyboard.tsx +++ b/src/components/EmojiStaticKeyboard.tsx @@ -139,7 +139,9 @@ export const EmojiStaticKeyboard = React.memo( )} > <> - {enableSearchBar && } + {enableSearchBar && ( + + )} extraData={[keyboardState.recentlyUsed.length, searchPhrase]} data={renderList} diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index e52381cf..cf2cec21 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -3,7 +3,11 @@ import { View, StyleSheet, TextInput, TouchableOpacity } from 'react-native' import { KeyboardContext } from '../contexts/KeyboardContext' import { Icon } from './Icon' -export const SearchBar = () => { +type SearchBarProps = { + scrollEmojiCategoryListToIndex: (index: number) => void +} + +export const SearchBar = ({ scrollEmojiCategoryListToIndex }: SearchBarProps) => { const { searchPhrase, setSearchPhrase, @@ -24,6 +28,7 @@ export const SearchBar = () => { if (text === '') { await setActiveCategoryIndex(0) + scrollEmojiCategoryListToIndex(0) setShouldAnimateScroll(enableCategoryChangeAnimation) return @@ -32,6 +37,7 @@ export const SearchBar = () => { const searchIndex = renderList.findIndex((cat) => cat.title === 'search') if (searchIndex !== -1) { setActiveCategoryIndex(searchIndex) + scrollEmojiCategoryListToIndex(searchIndex) setShouldAnimateScroll(enableSearchAnimation) } } @@ -40,6 +46,7 @@ export const SearchBar = () => { clearEmojiTonesData() inputRef.current?.blur() setActiveCategoryIndex(0) + scrollEmojiCategoryListToIndex(0) } return (