mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-22 15:04:50 +01:00
REF: ReorderWallets to TSX
This commit is contained in:
parent
34fc84cbdc
commit
845a2c4db8
3 changed files with 193 additions and 136 deletions
|
@ -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();
|
||||
|
||||
|
|
192
screen/wallets/ReorderWallets.tsx
Normal file
192
screen/wallets/ReorderWallets.tsx
Normal file
|
@ -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 (
|
||||
<ScaleDecorator>
|
||||
<WalletCarouselItem
|
||||
// @ts-ignore: fix later
|
||||
item={item}
|
||||
handleLongPress={isDraggingDisabled ? null : drag}
|
||||
isActive={isActive}
|
||||
onPress={navigateToWallet}
|
||||
customStyle={[styles.padding16, { opacity: itemOpacity }]}
|
||||
/>
|
||||
</ScaleDecorator>
|
||||
);
|
||||
},
|
||||
[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 (
|
||||
<GestureHandlerRootView style={[styles.root, stylesHook.root]}>
|
||||
<DraggableFlatList
|
||||
ref={sortableList}
|
||||
contentInsetAdjustmentBehavior="automatic"
|
||||
automaticallyAdjustContentInsets
|
||||
data={state.walletData}
|
||||
keyExtractor={_keyExtractor}
|
||||
renderItem={renderItem}
|
||||
onChangeOrder={onChangeOrder}
|
||||
onDragBegin={onDragBegin}
|
||||
onRelease={onRelease}
|
||||
onDragEnd={onDragEnd}
|
||||
containerStyle={styles.root}
|
||||
/>
|
||||
</GestureHandlerRootView>
|
||||
);
|
||||
};
|
||||
|
||||
export default ReorderWallets;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
flex: 1,
|
||||
},
|
||||
padding16: {
|
||||
padding: 16,
|
||||
},
|
||||
});
|
|
@ -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 (
|
||||
<ScaleDecorator>
|
||||
<WalletCarouselItem
|
||||
item={item}
|
||||
handleLongPress={isDraggingDisabled ? null : drag}
|
||||
isActive={isActive}
|
||||
onPress={navigateToWallet}
|
||||
customStyle={[styles.padding16, { opacity: itemOpacity }]} // Apply opacity style
|
||||
/>
|
||||
</ScaleDecorator>
|
||||
);
|
||||
};
|
||||
|
||||
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 (
|
||||
<GestureHandlerRootView style={[styles.root, stylesHook.root]}>
|
||||
<DraggableFlatList
|
||||
ref={sortableList}
|
||||
contentInsetAdjustmentBehavior="automatic"
|
||||
automaticallyAdjustContentInsets
|
||||
data={walletData}
|
||||
keyExtractor={_keyExtractor}
|
||||
renderItem={renderItem}
|
||||
onChangeOrder={onChangeOrder}
|
||||
onDragBegin={onDragBegin}
|
||||
onRelease={onRelease}
|
||||
onDragEnd={onDragEnd}
|
||||
containerStyle={styles.root}
|
||||
/>
|
||||
</GestureHandlerRootView>
|
||||
);
|
||||
};
|
||||
|
||||
export default ReorderWallets;
|
Loading…
Add table
Reference in a new issue