refactor: fix context
This commit is contained in:
parent
e165a829b7
commit
4b72f5ec5b
|
@ -8,7 +8,6 @@ import {
|
||||||
Animated,
|
Animated,
|
||||||
NativeSyntheticEvent,
|
NativeSyntheticEvent,
|
||||||
NativeScrollEvent,
|
NativeScrollEvent,
|
||||||
ViewToken,
|
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { CATEGORIES, CategoryTypes } from './types';
|
import { CATEGORIES, CategoryTypes } from './types';
|
||||||
import { EmojiCategory } from './components/EmojiCategory';
|
import { EmojiCategory } from './components/EmojiCategory';
|
||||||
|
@ -24,17 +23,6 @@ export const EmojiKeyboard = () => {
|
||||||
const scrollX = React.useRef(new Animated.Value(0)).current;
|
const scrollX = React.useRef(new Animated.Value(0)).current;
|
||||||
const scrollNav = React.useRef(new Animated.Value(0)).current;
|
const scrollNav = React.useRef(new Animated.Value(0)).current;
|
||||||
|
|
||||||
const onViewableItemsChanged = React.useRef(
|
|
||||||
({ viewableItems }: { viewableItems: Array<ViewToken> }) => {
|
|
||||||
if (viewableItems.length > 0 && viewableItems[0].index !== null) {
|
|
||||||
ctx?.setActiveCategoryIndex(viewableItems[0].index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const viewabilityConfig = React.useRef({
|
|
||||||
viewAreaCoveragePercentThreshold: 60,
|
|
||||||
});
|
|
||||||
|
|
||||||
const getItemLayout = (
|
const getItemLayout = (
|
||||||
_: CategoryTypes[] | null | undefined,
|
_: CategoryTypes[] | null | undefined,
|
||||||
index: number
|
index: number
|
||||||
|
@ -66,7 +54,7 @@ export const EmojiKeyboard = () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[styles.container, ctx?.containerStyles]}>
|
<View style={[styles.container, ctx.containerStyles]}>
|
||||||
<FlatList
|
<FlatList
|
||||||
data={CATEGORIES}
|
data={CATEGORIES}
|
||||||
keyExtractor={(item) => item}
|
keyExtractor={(item) => item}
|
||||||
|
@ -81,8 +69,6 @@ export const EmojiKeyboard = () => {
|
||||||
decelerationRate="fast"
|
decelerationRate="fast"
|
||||||
getItemLayout={getItemLayout}
|
getItemLayout={getItemLayout}
|
||||||
onScroll={onScroll}
|
onScroll={onScroll}
|
||||||
onViewableItemsChanged={onViewableItemsChanged.current}
|
|
||||||
viewabilityConfig={viewabilityConfig.current}
|
|
||||||
/>
|
/>
|
||||||
<Categories flatListRef={flatListRef} scrollNav={scrollNav} />
|
<Categories flatListRef={flatListRef} scrollNav={scrollNav} />
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -1,18 +1,25 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import type { ViewStyle } from 'react-native';
|
import type { ViewStyle } from 'react-native';
|
||||||
|
import {
|
||||||
|
defaultKeyboardContext,
|
||||||
|
defaultKeyboardValues,
|
||||||
|
} from './KeyboardProvider';
|
||||||
import type { EmojiType } from './types';
|
import type { EmojiType } from './types';
|
||||||
|
|
||||||
export type KeyboardProps = {
|
export type KeyboardProps = {
|
||||||
onEmojiSelected: (emoji: EmojiType) => void;
|
onEmojiSelected: (emoji: EmojiType) => void;
|
||||||
numberOfColumns?: number;
|
|
||||||
emojiSize?: number;
|
emojiSize?: number;
|
||||||
containerStyles?: ViewStyle;
|
containerStyles?: ViewStyle;
|
||||||
};
|
};
|
||||||
export type ContextValues = {
|
export type ContextValues = {
|
||||||
activeCategoryIndex: number;
|
activeCategoryIndex: number;
|
||||||
setActiveCategoryIndex: (index: number) => void;
|
setActiveCategoryIndex: (index: number) => void;
|
||||||
|
numberOfColumns: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const KeyboardContext = React.createContext<
|
export const KeyboardContext = React.createContext<
|
||||||
(KeyboardProps & ContextValues) | null
|
Required<KeyboardProps> & ContextValues
|
||||||
>(null);
|
>({
|
||||||
|
...defaultKeyboardContext,
|
||||||
|
...defaultKeyboardValues,
|
||||||
|
});
|
||||||
|
|
|
@ -10,20 +10,26 @@ type ProviderProps = KeyboardProps & {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultKeyboardContext: KeyboardProps = {
|
export const defaultKeyboardContext: Required<KeyboardProps> = {
|
||||||
onEmojiSelected: (_emoji: EmojiType) => {},
|
onEmojiSelected: (_emoji: EmojiType) => {},
|
||||||
numberOfColumns: 7,
|
|
||||||
emojiSize: 24,
|
emojiSize: 24,
|
||||||
|
containerStyles: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultKeyboardValues: Partial<ContextValues> = {
|
export const defaultKeyboardValues: ContextValues = {
|
||||||
// activeCategoryIndex: 0,
|
activeCategoryIndex: 0,
|
||||||
|
setActiveCategoryIndex: () => {},
|
||||||
|
numberOfColumns: 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const KeyboardProvider: React.FC<ProviderProps> = React.memo((props) => {
|
export const KeyboardProvider: React.FC<ProviderProps> = React.memo((props) => {
|
||||||
const [activeCategoryIndex, setActiveCategoryIndex] = React.useState(0);
|
const [activeCategoryIndex, setActive] = React.useState(0);
|
||||||
|
|
||||||
const value: KeyboardProps & ContextValues = {
|
const setActiveCategoryIndex = React.useCallback((index: number) => {
|
||||||
|
setActive(index);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const value: Required<KeyboardProps> & ContextValues = {
|
||||||
...defaultKeyboardContext,
|
...defaultKeyboardContext,
|
||||||
...defaultKeyboardValues,
|
...defaultKeyboardValues,
|
||||||
...props,
|
...props,
|
||||||
|
|
|
@ -11,35 +11,45 @@ type CategoriesProps = {
|
||||||
|
|
||||||
export const Categories = ({ flatListRef, scrollNav }: CategoriesProps) => {
|
export const Categories = ({ flatListRef, scrollNav }: CategoriesProps) => {
|
||||||
const ctx = React.useContext(KeyboardContext);
|
const ctx = React.useContext(KeyboardContext);
|
||||||
const handleScrollToCategory = (category: CategoryTypes) => {
|
const handleScrollToCategory = React.useCallback(
|
||||||
|
(category: CategoryTypes) => {
|
||||||
flatListRef?.current?.scrollToIndex({
|
flatListRef?.current?.scrollToIndex({
|
||||||
index: CATEGORIES.indexOf(category),
|
index: CATEGORIES.indexOf(category),
|
||||||
});
|
});
|
||||||
};
|
},
|
||||||
|
[flatListRef]
|
||||||
|
);
|
||||||
|
|
||||||
|
const rendarItem = React.useCallback(
|
||||||
|
({ item, index }) => (
|
||||||
|
<CategoryItem
|
||||||
|
item={item}
|
||||||
|
index={index}
|
||||||
|
handleScrollToCategory={handleScrollToCategory}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
[handleScrollToCategory]
|
||||||
|
);
|
||||||
|
|
||||||
|
const activeIndicator = React.useCallback(
|
||||||
|
() => (
|
||||||
|
<Animated.View style={[styles.activeIndicator, { left: scrollNav }]} />
|
||||||
|
),
|
||||||
|
[scrollNav]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.bottomBar}>
|
<View style={styles.bottomBar}>
|
||||||
<View style={styles.navigation}>
|
<View style={styles.navigation}>
|
||||||
<FlatList
|
<FlatList
|
||||||
data={CATEGORIES_NAVIGATION}
|
data={CATEGORIES_NAVIGATION}
|
||||||
keyExtractor={(item) => item.category}
|
keyExtractor={(item) => item.category}
|
||||||
renderItem={({ item, index }) => (
|
renderItem={rendarItem}
|
||||||
<CategoryItem
|
|
||||||
item={item}
|
|
||||||
index={index}
|
|
||||||
handleScrollToCategory={handleScrollToCategory}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
ItemSeparatorComponent={() => <View style={styles.separator} />}
|
ItemSeparatorComponent={() => <View style={styles.separator} />}
|
||||||
scrollEnabled={false}
|
scrollEnabled={false}
|
||||||
horizontal={true}
|
horizontal={true}
|
||||||
onScrollToIndexFailed={(e) => console.log(e)}
|
onScrollToIndexFailed={(e) => console.log(e)}
|
||||||
ListHeaderComponent={() => {
|
ListHeaderComponent={activeIndicator}
|
||||||
return (
|
|
||||||
<Animated.View
|
|
||||||
style={[styles.activeIndicator, { left: scrollNav }]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
extraData={ctx?.activeCategoryIndex}
|
extraData={ctx?.activeCategoryIndex}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -16,10 +16,9 @@ export const EmojiCategory = ({ item }: { item: CategoryTypes }) => {
|
||||||
const { width } = useWindowDimensions();
|
const { width } = useWindowDimensions();
|
||||||
const ctx = React.useContext(KeyboardContext);
|
const ctx = React.useContext(KeyboardContext);
|
||||||
const numberOfColumns = React.useRef<number>(
|
const numberOfColumns = React.useRef<number>(
|
||||||
Math.floor(width / (ctx?.emojiSize ? ctx?.emojiSize : 0 + 16))
|
Math.floor(width / (ctx.emojiSize + 16))
|
||||||
);
|
);
|
||||||
const [data, setData] = React.useState<EmojiType[]>([]);
|
const [data, setData] = React.useState<EmojiType[]>([]);
|
||||||
// console.log(width);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const newData = emojisByGroup[item];
|
const newData = emojisByGroup[item];
|
||||||
|
@ -63,11 +62,11 @@ const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
marginTop: 12,
|
marginTop: 6,
|
||||||
},
|
},
|
||||||
sectionTitle: {
|
sectionTitle: {
|
||||||
opacity: 0.6,
|
opacity: 0.6,
|
||||||
marginBottom: 12,
|
marginBottom: 6,
|
||||||
marginLeft: 12,
|
marginLeft: 12,
|
||||||
},
|
},
|
||||||
footer: { height: 70 },
|
footer: { height: 70 },
|
||||||
|
|
Loading…
Reference in New Issue