diff --git a/navigation/ReorderWalletsStack.tsx b/navigation/ReorderWalletsStack.tsx index a88a5b7fb..0ff01e0eb 100644 --- a/navigation/ReorderWalletsStack.tsx +++ b/navigation/ReorderWalletsStack.tsx @@ -4,7 +4,7 @@ import React from 'react'; import navigationStyle from '../components/navigationStyle'; import { useTheme } from '../components/themes'; import loc from '../loc'; -import ReorderWallets from '../screen/wallets/reorderWallets'; +import ReorderWallets from '../screen/wallets/ReorderWallets'; const Stack = createNativeStackNavigator(); diff --git a/screen/wallets/ReorderWallets.tsx b/screen/wallets/ReorderWallets.tsx new file mode 100644 index 000000000..c08d51e8e --- /dev/null +++ b/screen/wallets/ReorderWallets.tsx @@ -0,0 +1,192 @@ +import React, { useEffect, useLayoutEffect, useRef, useReducer, useCallback } from 'react'; +import { Platform, StyleSheet, useColorScheme } from 'react-native'; +// @ts-ignore: fix later +import DraggableFlatList, { ScaleDecorator } from 'react-native-draggable-flatlist'; +import { GestureHandlerRootView } from 'react-native-gesture-handler'; +import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback'; +import { useTheme } from '../../components/themes'; +import { WalletCarouselItem } from '../../components/WalletsCarousel'; +import { useExtendedNavigation } from '../../hooks/useExtendedNavigation'; +import loc from '../../loc'; +import { useStorage } from '../../hooks/context/useStorage'; + +// Action Types +const SET_SEARCH_QUERY = 'SET_SEARCH_QUERY'; +const SET_IS_SEARCH_FOCUSED = 'SET_IS_SEARCH_FOCUSED'; +const SET_WALLET_DATA = 'SET_WALLET_DATA'; + +// Action Interfaces +interface SetSearchQueryAction { + type: typeof SET_SEARCH_QUERY; + payload: string; +} + +interface SetIsSearchFocusedAction { + type: typeof SET_IS_SEARCH_FOCUSED; + payload: boolean; +} + +interface SetWalletDataAction { + type: typeof SET_WALLET_DATA; + payload: any[]; +} + +type Action = SetSearchQueryAction | SetIsSearchFocusedAction | SetWalletDataAction; + +// State Interface +interface State { + searchQuery: string; + isSearchFocused: boolean; + walletData: any[]; +} + +// Initial State +const initialState: State = { + searchQuery: '', + isSearchFocused: false, + walletData: [], +}; + +// Reducer +const reducer = (state: State, action: Action): State => { + switch (action.type) { + case SET_SEARCH_QUERY: + return { ...state, searchQuery: action.payload }; + case SET_IS_SEARCH_FOCUSED: + return { ...state, isSearchFocused: action.payload }; + case SET_WALLET_DATA: + return { ...state, walletData: action.payload }; + default: + return state; + } +}; + +const ReorderWallets: React.FC = () => { + const sortableList = useRef(null); + const { colors } = useTheme(); + const { wallets, setWalletsWithNewOrder } = useStorage(); + const colorScheme = useColorScheme(); + const { navigate, setOptions } = useExtendedNavigation(); + const [state, dispatch] = useReducer(reducer, initialState); + + const stylesHook = { + root: { + backgroundColor: colors.elevated, + }, + tip: { + backgroundColor: colors.ballOutgoingExpired, + }, + }; + + useEffect(() => { + dispatch({ type: SET_WALLET_DATA, payload: wallets }); + }, [wallets]); + + useEffect(() => { + setOptions({ + statusBarStyle: Platform.select({ ios: 'light', default: colorScheme === 'dark' ? 'light' : 'dark' }), + }); + }, [colorScheme, setOptions]); + + useEffect(() => { + const filteredWallets = wallets.filter(wallet => wallet.getLabel().toLowerCase().includes(state.searchQuery.toLowerCase())); + dispatch({ type: SET_WALLET_DATA, payload: filteredWallets }); + }, [wallets, state.searchQuery]); + + useLayoutEffect(() => { + setOptions({ + headerSearchBarOptions: { + hideWhenScrolling: false, + onChangeText: (event: { nativeEvent: { text: any } }) => dispatch({ type: SET_SEARCH_QUERY, payload: event.nativeEvent.text }), + onClear: () => dispatch({ type: SET_SEARCH_QUERY, payload: '' }), + onFocus: () => dispatch({ type: SET_IS_SEARCH_FOCUSED, payload: true }), + onBlur: () => dispatch({ type: SET_IS_SEARCH_FOCUSED, payload: false }), + placeholder: loc.wallets.search_wallets, + }, + }); + }, [setOptions]); + + const navigateToWallet = useCallback( + (wallet: any) => { + const walletID = wallet.getID(); + navigate('WalletTransactions', { + walletID, + walletType: wallet.type, + }); + }, + [navigate], + ); + + const isDraggingDisabled = state.searchQuery.length > 0 || state.isSearchFocused; + + const renderItem = useCallback( + ({ item, drag, isActive }: any) => { + const itemOpacity = isActive ? 1 : 0.5; + + return ( + + + + ); + }, + [isDraggingDisabled, navigateToWallet], + ); + + const onChangeOrder = useCallback(() => { + triggerHapticFeedback(HapticFeedbackTypes.ImpactMedium); + }, []); + + const onDragBegin = useCallback(() => { + triggerHapticFeedback(HapticFeedbackTypes.Selection); + }, []); + + const onRelease = useCallback(() => { + triggerHapticFeedback(HapticFeedbackTypes.ImpactLight); + }, []); + + const onDragEnd = useCallback( + ({ data }: any) => { + setWalletsWithNewOrder(data); + dispatch({ type: SET_WALLET_DATA, payload: data }); + }, + [setWalletsWithNewOrder], + ); + + const _keyExtractor = useCallback((_item: any, index: number) => index.toString(), []); + + return ( + + + + ); +}; + +export default ReorderWallets; + +const styles = StyleSheet.create({ + root: { + flex: 1, + }, + padding16: { + padding: 16, + }, +}); diff --git a/screen/wallets/reorderWallets.js b/screen/wallets/reorderWallets.js deleted file mode 100644 index 28cb29c87..000000000 --- a/screen/wallets/reorderWallets.js +++ /dev/null @@ -1,135 +0,0 @@ -import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; -import { Platform, StyleSheet, useColorScheme } from 'react-native'; -import DraggableFlatList, { ScaleDecorator } from 'react-native-draggable-flatlist'; -import { GestureHandlerRootView } from 'react-native-gesture-handler'; -import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback'; -import { useTheme } from '../../components/themes'; -import { WalletCarouselItem } from '../../components/WalletsCarousel'; -import { useExtendedNavigation } from '../../hooks/useExtendedNavigation'; -import loc from '../../loc'; -import { useStorage } from '../../hooks/context/useStorage'; - -const styles = StyleSheet.create({ - root: { - flex: 1, - }, - padding16: { - padding: 16, - }, -}); - -const ReorderWallets = () => { - const sortableList = useRef(); - const { colors } = useTheme(); - const { wallets, setWalletsWithNewOrder } = useStorage(); - const colorScheme = useColorScheme(); - const { navigate, setOptions } = useExtendedNavigation(); - const [searchQuery, setSearchQuery] = useState(''); - const [isSearchFocused, setIsSearchFocused] = useState(false); - const [walletData, setWalletData] = useState([]); - - const stylesHook = { - root: { - backgroundColor: colors.elevated, - }, - tip: { - backgroundColor: colors.ballOutgoingExpired, - }, - }; - - useEffect(() => { - setWalletData(wallets); - }, [wallets]); - - useEffect(() => { - setOptions({ - statusBarStyle: Platform.select({ ios: 'light', default: colorScheme === 'dark' ? 'light' : 'dark' }), - }); - }, [colorScheme, setOptions]); - - useEffect(() => { - // Filter wallets based on search query - const filteredWallets = wallets.filter(wallet => wallet.getLabel().toLowerCase().includes(searchQuery.toLowerCase())); - setWalletData(filteredWallets); - }, [wallets, searchQuery]); - - useLayoutEffect(() => { - // Set navigation options dynamically - setOptions({ - headerSearchBarOptions: { - hideWhenScrolling: false, - onChangeText: event => setSearchQuery(event.nativeEvent.text), - onClear: () => setSearchQuery(''), - onFocus: () => setIsSearchFocused(true), - onBlur: () => setIsSearchFocused(false), - placeholder: loc.wallets.search_wallets, - }, - }); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const navigateToWallet = wallet => { - const walletID = wallet.getID(); - navigate('WalletTransactions', { - walletID, - walletType: wallet.type, - }); - }; - - const renderItem = ({ item, drag, isActive }) => { - const itemOpacity = isActive ? 1 : 0.5; // Set opacity to 0.5 if not active - - return ( - - - - ); - }; - - const onChangeOrder = () => { - triggerHapticFeedback(HapticFeedbackTypes.ImpactMedium); - }; - - const onDragBegin = () => { - triggerHapticFeedback(HapticFeedbackTypes.Selection); - }; - - const onRelease = () => { - triggerHapticFeedback(HapticFeedbackTypes.ImpactLight); - }; - - const onDragEnd = ({ data }) => { - setWalletsWithNewOrder(data); - setWalletData(data); - }; - - const _keyExtractor = (_item, index) => index.toString(); - - const isDraggingDisabled = searchQuery.length > 0 || isSearchFocused; - - return ( - - - - ); -}; - -export default ReorderWallets;