mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-01-19 05:45:15 +01:00
FIX: Testing memos was broken
This commit is contained in:
parent
fde4bc4f4b
commit
85cf3ee10f
@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import { Linking, View, Text, StyleSheet, Animated, ViewStyle } from 'react-native';
|
||||
import { Linking, View, ViewStyle } from 'react-native';
|
||||
import Lnurl from '../class/lnurl';
|
||||
import { LightningTransaction, Transaction } from '../class/wallets/types';
|
||||
import TransactionExpiredIcon from '../components/icons/TransactionExpiredIcon';
|
||||
@ -23,7 +23,7 @@ import { DetailViewStackParamList } from '../navigation/DetailViewStackParamList
|
||||
import { useStorage } from '../hooks/context/useStorage';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
import { CommonToolTipActions } from '../typings/CommonToolTipActions';
|
||||
import useBounceAnimation from '../hooks/useBounceAnimation';
|
||||
import { pop } from '../NavigationService';
|
||||
|
||||
interface TransactionListItemProps {
|
||||
itemPriceUnit: BitcoinUnit;
|
||||
@ -31,12 +31,13 @@ interface TransactionListItemProps {
|
||||
item: Transaction & LightningTransaction; // using type intersection to have less issues with ts
|
||||
searchQuery?: string;
|
||||
style?: ViewStyle;
|
||||
renderHighlightedText?: (text: string, query: string) => JSX.Element;
|
||||
}
|
||||
|
||||
type NavigationProps = NativeStackNavigationProp<DetailViewStackParamList>;
|
||||
|
||||
export const TransactionListItem: React.FC<TransactionListItemProps> = React.memo(
|
||||
({ item, itemPriceUnit = BitcoinUnit.BTC, walletID, searchQuery, style }) => {
|
||||
({ item, itemPriceUnit = BitcoinUnit.BTC, walletID, searchQuery, style, renderHighlightedText }) => {
|
||||
const [subtitleNumberOfLines, setSubtitleNumberOfLines] = useState(1);
|
||||
const { colors } = useTheme();
|
||||
const { navigate } = useExtendedNavigation<NavigationProps>();
|
||||
@ -202,6 +203,7 @@ export const TransactionListItem: React.FC<TransactionListItemProps> = React.mem
|
||||
const onPress = useCallback(async () => {
|
||||
menuRef?.current?.dismissMenu?.();
|
||||
if (item.hash) {
|
||||
pop();
|
||||
navigate('TransactionStatus', { hash: item.hash, walletID });
|
||||
} else if (item.type === 'user_invoice' || item.type === 'payment_request' || item.type === 'paid_invoice') {
|
||||
const lightningWallet = wallets.filter(wallet => wallet?.getID() === item.walletID);
|
||||
@ -226,7 +228,7 @@ export const TransactionListItem: React.FC<TransactionListItemProps> = React.mem
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
console.debug(e);
|
||||
}
|
||||
|
||||
navigate('LNDViewInvoice', {
|
||||
@ -311,25 +313,6 @@ export const TransactionListItem: React.FC<TransactionListItemProps> = React.mem
|
||||
};
|
||||
}, [subtitleNumberOfLines]);
|
||||
|
||||
const bounceAnim = useBounceAnimation(searchQuery ?? '');
|
||||
|
||||
const renderHighlightedText = (text: string, query: string) => {
|
||||
const parts = text.split(new RegExp(`(${query})`, 'gi'));
|
||||
return (
|
||||
<Text>
|
||||
{parts.map((part, index) =>
|
||||
part.toLowerCase() === query.toLowerCase() ? (
|
||||
<Animated.View key={index} style={[styles.highlightedContainer, { transform: [{ scale: bounceAnim }] }]}>
|
||||
<Text style={[styles.highlighted, styles.defaultText]}>{part}</Text>
|
||||
</Animated.View>
|
||||
) : (
|
||||
<Text key={index} style={query ? styles.dimmedText : {}}>{part}</Text>
|
||||
),
|
||||
)}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<ToolTipMenu
|
||||
isButton
|
||||
@ -344,7 +327,7 @@ export const TransactionListItem: React.FC<TransactionListItemProps> = React.mem
|
||||
leftAvatar={avatar}
|
||||
title={title}
|
||||
subtitleNumberOfLines={subtitleNumberOfLines}
|
||||
subtitle={subtitle ? renderHighlightedText(subtitle, searchQuery ?? '') : undefined}
|
||||
subtitle={subtitle ? (renderHighlightedText ? renderHighlightedText(subtitle, searchQuery ?? '') : subtitle) : undefined}
|
||||
Component={View}
|
||||
subtitleProps={subtitleProps}
|
||||
chevron={false}
|
||||
@ -356,26 +339,3 @@ export const TransactionListItem: React.FC<TransactionListItemProps> = React.mem
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
highlightedContainer: {
|
||||
backgroundColor: 'white',
|
||||
borderColor: 'black',
|
||||
borderWidth: 1,
|
||||
borderRadius: 5,
|
||||
padding: 2,
|
||||
alignSelf: 'flex-start',
|
||||
},
|
||||
highlighted: {
|
||||
color: 'black',
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
},
|
||||
defaultText: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
},
|
||||
dimmedText: {
|
||||
opacity: 0.5,
|
||||
},
|
||||
});
|
||||
|
@ -8,7 +8,6 @@ import {
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
useWindowDimensions,
|
||||
View,
|
||||
FlatListProps,
|
||||
@ -73,12 +72,7 @@ const NewWalletPanel: React.FC<NewWalletPanelProps> = ({ onPress }) => {
|
||||
});
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
testID="CreateAWallet"
|
||||
onPress={onPress}
|
||||
style={isLargeScreen ? {} : { width: itemWidth * 1.2 }}
|
||||
>
|
||||
<Pressable accessibilityRole="button" testID="CreateAWallet" onPress={onPress} style={isLargeScreen ? {} : { width: itemWidth * 1.2 }}>
|
||||
<View
|
||||
style={[
|
||||
nStyles.container,
|
||||
@ -93,7 +87,7 @@ const NewWalletPanel: React.FC<NewWalletPanelProps> = ({ onPress }) => {
|
||||
<Text style={[nStyles.buttonText, { color: colors.brandingColor }]}>{loc.wallets.list_create_a_button}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</Pressable>
|
||||
);
|
||||
};
|
||||
|
||||
@ -105,7 +99,8 @@ interface WalletCarouselItemProps {
|
||||
customStyle?: ViewStyle;
|
||||
horizontal?: boolean;
|
||||
isActive?: boolean;
|
||||
allowOnPressAnimation?: boolean;
|
||||
searchQuery?: string;
|
||||
renderHighlightedText?: (text: string, query: string) => JSX.Element;
|
||||
}
|
||||
|
||||
const iStyles = StyleSheet.create({
|
||||
@ -168,7 +163,7 @@ const iStyles = StyleSheet.create({
|
||||
});
|
||||
|
||||
export const WalletCarouselItem: React.FC<WalletCarouselItemProps> = React.memo(
|
||||
({ item, onPress, handleLongPress, isSelectedWallet, customStyle, horizontal, allowOnPressAnimation = true }) => {
|
||||
({ item, onPress, handleLongPress, isSelectedWallet, customStyle, horizontal, searchQuery, renderHighlightedText }) => {
|
||||
const scaleValue = useRef(new Animated.Value(1.0)).current;
|
||||
const { colors } = useTheme();
|
||||
const { walletTransactionUpdateStatus } = useStorage();
|
||||
@ -234,8 +229,8 @@ export const WalletCarouselItem: React.FC<WalletCarouselItemProps> = React.memo(
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
testID={item.getLabel()}
|
||||
onPressIn={allowOnPressAnimation ? onPressedIn : undefined}
|
||||
onPressOut={allowOnPressAnimation ? onPressedOut : undefined}
|
||||
onPressIn={onPressedIn}
|
||||
onPressOut={onPressedOut}
|
||||
onLongPress={() => {
|
||||
if (handleLongPress) handleLongPress();
|
||||
}}
|
||||
@ -246,7 +241,7 @@ export const WalletCarouselItem: React.FC<WalletCarouselItemProps> = React.memo(
|
||||
<Image source={image} style={iStyles.image} />
|
||||
<Text style={iStyles.br} />
|
||||
<Text numberOfLines={1} style={[iStyles.label, { color: colors.inverseForegroundColor }]}>
|
||||
{item.getLabel()}
|
||||
{renderHighlightedText && searchQuery ? renderHighlightedText(item.getLabel(), searchQuery) : item.getLabel()}
|
||||
</Text>
|
||||
<View style={iStyles.balanceContainer}>
|
||||
{item.hideBalance ? (
|
||||
@ -288,6 +283,8 @@ interface WalletsCarouselProps extends Partial<FlatListProps<any>> {
|
||||
handleLongPress?: () => void;
|
||||
data: TWallet[];
|
||||
scrollEnabled?: boolean;
|
||||
searchQuery?: string;
|
||||
renderHighlightedText?: (text: string, query: string) => JSX.Element;
|
||||
}
|
||||
|
||||
type FlatListRefType = FlatList<any> & {
|
||||
@ -316,7 +313,17 @@ const cStyles = StyleSheet.create({
|
||||
const ListHeaderComponent: React.FC = () => <View style={cStyles.separatorStyle} />;
|
||||
|
||||
const WalletsCarousel = forwardRef<FlatListRefType, WalletsCarouselProps>((props, ref) => {
|
||||
const { horizontal, data, handleLongPress, onPress, selectedWallet, scrollEnabled, onNewWalletPress } = props;
|
||||
const {
|
||||
horizontal,
|
||||
data,
|
||||
handleLongPress,
|
||||
onPress,
|
||||
selectedWallet,
|
||||
scrollEnabled,
|
||||
onNewWalletPress,
|
||||
searchQuery,
|
||||
renderHighlightedText,
|
||||
} = props;
|
||||
const renderItem = useCallback(
|
||||
({ item, index }: ListRenderItemInfo<TWallet>) =>
|
||||
item ? (
|
||||
@ -326,9 +333,11 @@ const WalletsCarousel = forwardRef<FlatListRefType, WalletsCarouselProps>((props
|
||||
handleLongPress={handleLongPress}
|
||||
onPress={onPress}
|
||||
horizontal={horizontal}
|
||||
searchQuery={searchQuery}
|
||||
renderHighlightedText={renderHighlightedText}
|
||||
/>
|
||||
) : null,
|
||||
[horizontal, selectedWallet, handleLongPress, onPress],
|
||||
[horizontal, selectedWallet, handleLongPress, onPress, searchQuery, renderHighlightedText],
|
||||
);
|
||||
|
||||
const flatListRef = useRef<FlatList<any>>(null);
|
||||
@ -402,6 +411,8 @@ const WalletsCarousel = forwardRef<FlatListRefType, WalletsCarouselProps>((props
|
||||
handleLongPress={handleLongPress}
|
||||
onPress={onPress}
|
||||
key={index}
|
||||
searchQuery={props.searchQuery}
|
||||
renderHighlightedText={props.renderHighlightedText}
|
||||
/>
|
||||
) : null,
|
||||
)}
|
||||
|
@ -65,7 +65,7 @@ import WalletXpubStackRoot from './WalletXpubStack';
|
||||
import PlusIcon from '../components/icons/PlusIcon';
|
||||
import SettingsButton from '../components/icons/SettingsButton';
|
||||
import ExportMultisigCoordinationSetupStack from './ExportMultisigCoordinationSetupStack';
|
||||
import ManageWalletsStackRoot from './ManageWalletsStack';
|
||||
import ManageWallets from '../screen/wallets/ManageWallets';
|
||||
|
||||
const DetailViewStackScreensStack = () => {
|
||||
const theme = useTheme();
|
||||
@ -379,13 +379,15 @@ const DetailViewStackScreensStack = () => {
|
||||
}}
|
||||
/>
|
||||
<DetailViewStack.Screen
|
||||
name="ManageWalletsRoot"
|
||||
component={ManageWalletsStackRoot}
|
||||
options={{
|
||||
headerShown: false,
|
||||
name="ManageWallets"
|
||||
component={ManageWallets}
|
||||
options={navigationStyle({
|
||||
headerBackVisible: false,
|
||||
headerLargeTitle: true,
|
||||
gestureEnabled: false,
|
||||
presentation: 'modal',
|
||||
}}
|
||||
title: loc.wallets.manage_title,
|
||||
})(theme)}
|
||||
/>
|
||||
</DetailViewStack.Navigator>
|
||||
);
|
||||
|
@ -103,5 +103,5 @@ export type DetailViewStackParamList = {
|
||||
paymentCode: string;
|
||||
walletID: string;
|
||||
};
|
||||
ManageWalletsRoot: undefined;
|
||||
ManageWallets: undefined;
|
||||
};
|
||||
|
@ -1,30 +0,0 @@
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
import React from 'react';
|
||||
|
||||
import navigationStyle from '../components/navigationStyle';
|
||||
import { useTheme } from '../components/themes';
|
||||
import loc from '../loc';
|
||||
import ManageWallets from '../screen/wallets/ManageWallets';
|
||||
|
||||
const Stack = createNativeStackNavigator();
|
||||
|
||||
const ManageWalletsStackRoot = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Stack.Navigator screenOptions={{ headerShadowVisible: false }}>
|
||||
<Stack.Screen
|
||||
name="ManageWallets"
|
||||
component={ManageWallets}
|
||||
options={navigationStyle({
|
||||
headerBackVisible: false,
|
||||
headerLargeTitle: true,
|
||||
|
||||
headerTitle: loc.wallets.manage_title,
|
||||
})(theme)}
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
);
|
||||
};
|
||||
|
||||
export default ManageWalletsStackRoot;
|
@ -124,7 +124,7 @@ const DrawerList: React.FC<DrawerListProps> = memo(({ navigation }) => {
|
||||
|
||||
const handleLongPress = useCallback(() => {
|
||||
if (state.wallets.length > 1) {
|
||||
navigation.navigate('ManageWalletsRoot');
|
||||
navigation.navigate('ManageWallets');
|
||||
} else {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useLayoutEffect, useRef, useReducer, useCallback, useMemo } from 'react';
|
||||
import { Platform, StyleSheet, useColorScheme, TouchableOpacity, Image, Animated, Text, I18nManager, View } from 'react-native';
|
||||
import { Platform, StyleSheet, useColorScheme, TouchableOpacity, Image, Animated, Text, I18nManager } from 'react-native';
|
||||
// @ts-ignore: no declaration file
|
||||
import DraggableFlatList, { ScaleDecorator } from 'react-native-draggable-flatlist';
|
||||
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
||||
@ -199,7 +199,7 @@ const ManageWallets: React.FC = () => {
|
||||
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.manage_wallets_search_placeholder, // New placeholder text
|
||||
placeholder: loc.wallets.manage_wallets_search_placeholder,
|
||||
},
|
||||
});
|
||||
}, [setOptions]);
|
||||
@ -226,12 +226,12 @@ const ManageWallets: React.FC = () => {
|
||||
return (
|
||||
<Text>
|
||||
{parts.map((part, index) =>
|
||||
part.toLowerCase() === query.toLowerCase() ? (
|
||||
<Animated.View key={index} style={[iStyles.highlightedContainer, { transform: [{ scale: bounceAnim }] }]}>
|
||||
<Text style={[iStyles.highlighted, iStyles.defaultText]}>{part}</Text>
|
||||
query && part.toLowerCase().includes(query.toLowerCase()) ? (
|
||||
<Animated.View key={`${index}-${query}`} style={[iStyles.highlightedContainer, { transform: [{ scale: bounceAnim }] }]}>
|
||||
<Text style={iStyles.highlighted}>{part}</Text>
|
||||
</Animated.View>
|
||||
) : (
|
||||
<Text key={index} style={[iStyles.defaultText, query ? iStyles.dimmedText : {}]}>
|
||||
<Text key={`${index}-${query}`} style={query ? iStyles.dimmedText : iStyles.defaultText}>
|
||||
{part}
|
||||
</Text>
|
||||
),
|
||||
@ -241,22 +241,20 @@ const ManageWallets: React.FC = () => {
|
||||
},
|
||||
[bounceAnim],
|
||||
);
|
||||
|
||||
const renderItem = useCallback(
|
||||
// eslint-disable-next-line react/no-unused-prop-types
|
||||
({ item, drag, isActive }: { item: Item; drag: () => void; isActive: boolean }) => {
|
||||
const itemOpacity = isActive ? 1 : state.searchQuery ? 0.5 : 1;
|
||||
|
||||
if (item.type === ItemType.TransactionSection && item.data) {
|
||||
const w = wallets.find(wallet => wallet.getTransactions().some((tx: ExtendedTransaction) => tx.hash === item.data.hash));
|
||||
const walletID = w ? w.getID() : '';
|
||||
return (
|
||||
<View style={StyleSheet.flatten([styles.padding16, { opacity: itemOpacity }])}>
|
||||
<TransactionListItem
|
||||
item={item.data}
|
||||
itemPriceUnit={BitcoinUnit.BTC}
|
||||
walletID={item.data.walletID}
|
||||
searchQuery={state.searchQuery}
|
||||
style={{ opacity: itemOpacity }}
|
||||
/>
|
||||
</View>
|
||||
<TransactionListItem
|
||||
item={item.data}
|
||||
itemPriceUnit={item.data.walletPreferredBalanceUnit || BitcoinUnit.BTC}
|
||||
walletID={walletID}
|
||||
searchQuery={state.searchQuery}
|
||||
renderHighlightedText={renderHighlightedText}
|
||||
/>
|
||||
);
|
||||
} else if (item.type === ItemType.WalletSection) {
|
||||
return (
|
||||
@ -266,16 +264,16 @@ const ManageWallets: React.FC = () => {
|
||||
handleLongPress={isDraggingDisabled ? undefined : drag}
|
||||
isActive={isActive}
|
||||
onPress={() => navigateToWallet(item.data)}
|
||||
customStyle={StyleSheet.flatten([styles.padding16, { opacity: itemOpacity }])}
|
||||
customStyle={styles.padding16}
|
||||
searchQuery={state.searchQuery}
|
||||
renderHighlightedText={state.searchQuery ? renderHighlightedText : undefined}
|
||||
renderHighlightedText={renderHighlightedText}
|
||||
/>
|
||||
</ScaleDecorator>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
[isDraggingDisabled, navigateToWallet, state.searchQuery, renderHighlightedText],
|
||||
[wallets, isDraggingDisabled, navigateToWallet, state.searchQuery, renderHighlightedText],
|
||||
);
|
||||
|
||||
const onChangeOrder = useCallback(() => {
|
||||
@ -299,7 +297,10 @@ const ManageWallets: React.FC = () => {
|
||||
const renderHeader = useMemo(() => {
|
||||
if (!state.searchQuery) return null;
|
||||
const hasWallets = state.walletData.length > 0;
|
||||
const hasTransactions = Object.keys(state.txMetadata).length > 0;
|
||||
const filteredTxMetadata = Object.entries(state.txMetadata).filter(([_, tx]) =>
|
||||
tx.memo?.toLowerCase().includes(state.searchQuery.toLowerCase()),
|
||||
);
|
||||
const hasTransactions = filteredTxMetadata.length > 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -361,18 +362,22 @@ const iStyles = StyleSheet.create({
|
||||
borderWidth: 1,
|
||||
borderRadius: 5,
|
||||
padding: 2,
|
||||
alignSelf: 'flex-start', // ensure the container resizes based on its content
|
||||
alignSelf: 'flex-start',
|
||||
textDecorationLine: 'underline',
|
||||
textDecorationStyle: 'double',
|
||||
textShadowColor: '#000',
|
||||
textShadowOffset: { width: 1, height: 1 },
|
||||
textShadowRadius: 1,
|
||||
},
|
||||
highlighted: {
|
||||
color: 'black',
|
||||
fontSize: 14,
|
||||
fontSize: 19,
|
||||
fontWeight: '600',
|
||||
},
|
||||
defaultText: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
fontSize: 19,
|
||||
},
|
||||
dimmedText: {
|
||||
opacity: 0.5,
|
||||
opacity: 0.8,
|
||||
},
|
||||
});
|
||||
|
@ -239,7 +239,7 @@ const WalletsList: React.FC = () => {
|
||||
|
||||
const handleLongPress = useCallback(() => {
|
||||
if (wallets.length > 1) {
|
||||
navigate('ManageWalletsRoot');
|
||||
navigate('ManageWallets');
|
||||
} else {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user