Skip to content

Commit

Permalink
feat: Scan & device accounts - add account v2 (#8802)
Browse files Browse the repository at this point in the history
* feat: Scan & device accounts - add account v2
  • Loading branch information
themooneer authored Jan 15, 2025
1 parent 187d8c1 commit b447baf
Show file tree
Hide file tree
Showing 35 changed files with 1,387 additions and 664 deletions.
5 changes: 5 additions & 0 deletions .changeset/grumpy-rockets-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": minor
---

Add account v2 : Device selection & Scan account step
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
import { Account } from "@ledgerhq/types-live";
import { ScreenName } from "~/const";
import { NavigatorName, ScreenName } from "~/const";

export type AccountSettingsNavigatorParamList = {
[ScreenName.AccountSettingsMain]: {
Expand All @@ -26,4 +26,12 @@ export type AccountSettingsNavigatorParamList = {
currency: CryptoCurrency;
};
[ScreenName.Accounts]: { currency?: string; search?: string } | undefined;

[NavigatorName.AccountSettings]: {
screen: string;
params: {
account?: Account;
onAccountNameChange?: (name: string, changedAccount: Account) => void;
};
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const Item = ({ device, onPress }: Props) => {

const wording = wired ? "usb" : available ? "available" : "unavailable";
const color = wording === "unavailable" ? "neutral.c60" : "primary.c80";
const testID = `device-item-${device.deviceId}`;

const onItemContextPress = useCallback(() => {
setIsRemoveDeviceMenuOpen(true);
Expand All @@ -42,7 +43,8 @@ const Item = ({ device, onPress }: Props) => {
return (
<Touchable
onPress={() => onPress(device)}
touchableTestID={"device-item-" + device.deviceId}
touchableTestID={testID}
testID={testID}
accessibilityRole="button"
>
<Flex
Expand Down
205 changes: 155 additions & 50 deletions apps/ledger-live-mobile/src/components/SelectableAccountsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ import { FlexBoxProps } from "@ledgerhq/native-ui/components/Layout/Flex/index";
import { Flex, Text } from "@ledgerhq/native-ui";
import Swipeable from "react-native-gesture-handler/Swipeable";

import { StackNavigationProp } from "@react-navigation/stack";
import { ScreenName } from "~/const";
import { NavigatorName, ScreenName } from "~/const";
import { track } from "~/analytics";
import AccountCard from "./AccountCard";
import CheckBox from "./CheckBox";
Expand All @@ -27,7 +26,11 @@ import Button from "./Button";
import TouchHintCircle from "./TouchHintCircle";
import Touchable from "./Touchable";
import { AccountSettingsNavigatorParamList } from "./RootNavigator/types/AccountSettingsNavigator";
import { AddAccountsNavigatorParamList } from "./RootNavigator/types/AddAccountsNavigator";
import AccountItem from "LLM/features/Accounts/components/AccountsListView/components/AccountItem";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import { BaseComposite, StackNavigatorProps } from "./RootNavigator/types/helpers";

const ANIMATION_DURATION = 200;

const selectAllHitSlop = {
top: 16,
Expand All @@ -53,6 +56,10 @@ type Props = FlexBoxProps & {
useFullBalance?: boolean;
};

type NavigationProps = BaseComposite<
StackNavigatorProps<AccountSettingsNavigatorParamList, ScreenName.EditAccountName>
>["navigation"];

const SelectableAccountsList = ({
accounts,
onPressAccount,
Expand All @@ -69,10 +76,7 @@ const SelectableAccountsList = ({
useFullBalance,
...props
}: Props) => {
const navigation =
useNavigation<
StackNavigationProp<AccountSettingsNavigatorParamList | AddAccountsNavigatorParamList>
>();
const navigation = useNavigation<NavigationProps>();

const onSelectAll = useCallback(() => {
track("SelectAllAccounts");
Expand All @@ -85,6 +89,85 @@ const SelectableAccountsList = ({
}, [accounts, onUnselectAllProp]);

const areAllSelected = accounts.every(a => selectedIds.indexOf(a.id) > -1);
const translateY = useRef(new Animated.Value(50)).current;
const opacity = useRef(new Animated.Value(0)).current;
const scale = useRef(new Animated.Value(0.8)).current;
const llmNetworkBasedAddAccountFlow = useFeature("llmNetworkBasedAddAccountFlow");

useEffect(() => {
if (!llmNetworkBasedAddAccountFlow?.enabled) return;
Animated.parallel([
Animated.timing(translateY, {
toValue: 0,
duration: ANIMATION_DURATION,
useNativeDriver: true,
}),
Animated.timing(opacity, {
toValue: 1,
duration: ANIMATION_DURATION,
useNativeDriver: true,
}),
Animated.timing(scale, {
toValue: 1,
duration: ANIMATION_DURATION,
useNativeDriver: true,
}),
]).start();
}, [translateY, opacity, scale, llmNetworkBasedAddAccountFlow?.enabled]);

const animatedSelectableAccount = useMemo(
() => ({
transform: [{ translateY }, { scale }],
opacity,
}),
[translateY, scale, opacity],
);

const renderSelectableAccount = useCallback(
({ item, index }: { index: number; item: Account }) =>
llmNetworkBasedAddAccountFlow?.enabled ? (
<Animated.View style={[animatedSelectableAccount]}>
<SelectableAccount
navigation={navigation}
showHint={!index && showHint}
rowIndex={index}
listIndex={listIndex}
account={item}
onAccountNameChange={onAccountNameChange}
isSelected={forceSelected || selectedIds.indexOf(item.id) > -1}
isDisabled={isDisabled}
onPress={onPressAccount}
useFullBalance={useFullBalance}
/>
</Animated.View>
) : (
<SelectableAccount
navigation={navigation}
showHint={!index && showHint}
rowIndex={index}
listIndex={listIndex}
account={item}
onAccountNameChange={onAccountNameChange}
isSelected={forceSelected || selectedIds.indexOf(item.id) > -1}
isDisabled={isDisabled}
onPress={onPressAccount}
useFullBalance={useFullBalance}
/>
),
[
navigation,
showHint,
listIndex,
selectedIds,
forceSelected,
isDisabled,
onAccountNameChange,
onPressAccount,
useFullBalance,
animatedSelectableAccount,
llmNetworkBasedAddAccountFlow?.enabled,
],
);

return (
<Flex marginBottom={7} {...props}>
Expand All @@ -99,21 +182,12 @@ const SelectableAccountsList = ({
<FlatList
data={accounts}
keyExtractor={(item, index) => item.id + index}
renderItem={({ item, index }) => (
<SelectableAccount
navigation={navigation}
showHint={!index && showHint}
rowIndex={index}
listIndex={listIndex}
account={item}
onAccountNameChange={onAccountNameChange}
isSelected={forceSelected || selectedIds.indexOf(item.id) > -1}
isDisabled={isDisabled}
onPress={onPressAccount}
useFullBalance={useFullBalance}
/>
renderItem={renderSelectableAccount}
ListEmptyComponent={() => (
<Flex height="100%" flexDirection="row" justifyContent="center">
{emptyState || null}
</Flex>
)}
ListEmptyComponent={() => <>{emptyState || null}</>}
/>
</Flex>
);
Expand All @@ -127,9 +201,7 @@ type SelectableAccountProps = {
showHint: boolean;
rowIndex: number;
listIndex: number;
navigation: StackNavigationProp<
AccountSettingsNavigatorParamList | AddAccountsNavigatorParamList
>;
navigation: NavigationProps;
onAccountNameChange?: (name: string, changedAccount: Account) => void;
useFullBalance?: boolean;
};
Expand All @@ -147,6 +219,7 @@ const SelectableAccount = ({
useFullBalance,
}: SelectableAccountProps) => {
const [stopAnimation, setStopAnimation] = useState<boolean>(false);
const llmNetworkBasedAddAccountFlow = useFeature("llmNetworkBasedAddAccountFlow");

const swipeableRow = useRef<Swipeable>(null);

Expand Down Expand Up @@ -206,11 +279,21 @@ const SelectableAccount = ({
if (!onAccountNameChange) return;

swipedAccountSubject.next({ row: -1, list: -1 });
navigation.navigate(ScreenName.EditAccountName, {
onAccountNameChange,
account,
});
}, [account, navigation, onAccountNameChange]);
if (llmNetworkBasedAddAccountFlow?.enabled) {
navigation.navigate(NavigatorName.AccountSettings, {
screen: ScreenName.EditAccountName,
params: {
onAccountNameChange,
account,
},
});
} else {
navigation.navigate(ScreenName.EditAccountName, {
onAccountNameChange,
account,
});
}
}, [account, navigation, onAccountNameChange, llmNetworkBasedAddAccountFlow?.enabled]);

const renderLeftActions = useCallback(
(
Expand Down Expand Up @@ -259,25 +342,41 @@ const SelectableAccount = ({
opacity={isDisabled ? 0.4 : 1}
backgroundColor="neutral.c30"
>
<Flex flex={1}>
<AccountCard
useFullBalance={useFullBalance}
account={account}
AccountSubTitle={
subAccountCount && !isDisabled ? (
<Flex marginTop={2}>
<Text fontWeight="semiBold" variant="small" color="pillActiveForeground">
<Trans
i18nKey={`selectableAccountsList.${isToken ? "tokenCount" : "subaccountCount"}`}
count={subAccountCount}
values={{ count: subAccountCount }}
/>
</Text>
</Flex>
) : null
}
/>
</Flex>
{llmNetworkBasedAddAccountFlow?.enabled ? (
<Flex
flex={1}
flexDirection="row"
height={56}
alignItems="center"
backgroundColor="neutral.c30"
borderRadius="12px"
padding="8px"
columnGap={8}
>
<AccountItem account={account} balance={account.spendableBalance} />
</Flex>
) : (
<Flex flex={1}>
<AccountCard
useFullBalance={useFullBalance}
account={account}
AccountSubTitle={
subAccountCount && !isDisabled ? (
<Flex marginTop={2}>
<Text fontWeight="semiBold" variant="small" color="pillActiveForeground">
<Trans
i18nKey={`selectableAccountsList.${isToken ? "tokenCount" : "subaccountCount"}`}
count={subAccountCount}
values={{ count: subAccountCount }}
/>
</Text>
</Flex>
) : null
}
/>
</Flex>
)}

{!isDisabled && (
<Flex marginLeft={4}>
<CheckBox onChange={handlePress} isChecked={!!isSelected} />
Expand Down Expand Up @@ -317,14 +416,20 @@ type HeaderProps = {

const Header = ({ text, areAllSelected, onSelectAll, onUnselectAll }: HeaderProps) => {
const shouldDisplaySelectAll = !!onSelectAll && !!onUnselectAll;
const llmNetworkBasedAddAccountFlow = useFeature("llmNetworkBasedAddAccountFlow");

return (
<Flex paddingX={16} flexDirection="row" alignItems="center" paddingBottom={8}>
<Flex
paddingX={llmNetworkBasedAddAccountFlow?.enabled ? 16 : 22}
flexDirection="row"
alignItems="center"
paddingBottom={llmNetworkBasedAddAccountFlow?.enabled ? 16 : 8}
>
<Text
fontWeight="semiBold"
flexShrink={1}
variant="small"
textTransform="uppercase"
{...(!llmNetworkBasedAddAccountFlow?.enabled && { textTransform: "uppercase" })}
color="neutral.c70"
numberOfLines={1}
>
Expand Down
1 change: 1 addition & 0 deletions apps/ledger-live-mobile/src/const/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ export enum ScreenName {
SelectDevice = "SelectDevice",
SelectAccounts = "SelectAccounts",
ScanDeviceAccounts = "ScanDeviceAccounts",
AddAccountsWarning = "AddAccountsWarning",
}

export enum NavigatorName {
Expand Down
12 changes: 10 additions & 2 deletions apps/ledger-live-mobile/src/icons/Pause.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,18 @@ type Props = {
};
export default function Pause({ size = 16, color }: Props) {
return (
<Svg viewBox="0 0 16 16" width={size} height={size}>
<Svg viewBox="0 0 20 20" width={size} height={size}>
<Path
fillRule="evenodd"
clipRule="evenodd"
d="M13.4167 15C13.0027 15 12.6667 14.44 12.6667 13.75V6.25C12.6667 5.56 13.0027 5 13.4167 5C13.8307 5 14.1667 5.56 14.1667 6.25V13.75C14.1667 14.44 13.8307 15 13.4167 15Z"
fill={color}
/>
<Path
fillRule="evenodd"
clipRule="evenodd"
d="M6.75 15C6.336 15 6 14.44 6 13.75V6.25C6 5.56 6.336 5 6.75 5C7.164 5 7.5 5.56 7.5 6.25V13.75C7.5 14.44 7.164 15 6.75 15Z"
fill={color}
d="M8 14.3A6.3 6.3 0 1 0 8 1.7a6.3 6.3 0 0 0 0 12.6zm0 1.4A7.7 7.7 0 1 1 8 .3a7.7 7.7 0 0 1 0 15.4zm-2.1-5.6V5.9c0-.933 1.4-.933 1.4 0v4.2c0 .933-1.4.933-1.4 0zm2.8 0V5.9c0-.933 1.4-.933 1.4 0v4.2c0 .933-1.4.933-1.4 0z"
/>
</Svg>
);
Expand Down
17 changes: 17 additions & 0 deletions apps/ledger-live-mobile/src/icons/PauseCircle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from "react";
import Svg, { Path } from "react-native-svg";

type Props = {
size?: number;
color?: string;
};
export default function PauseCircle({ size = 16, color }: Props) {
return (
<Svg viewBox="0 0 16 16" width={size} height={size}>
<Path
fill={color}
d="M8 14.3A6.3 6.3 0 1 0 8 1.7a6.3 6.3 0 0 0 0 12.6zm0 1.4A7.7 7.7 0 1 1 8 .3a7.7 7.7 0 0 1 0 15.4zm-2.1-5.6V5.9c0-.933 1.4-.933 1.4 0v4.2c0 .933-1.4.933-1.4 0zm2.8 0V5.9c0-.933 1.4-.933 1.4 0v4.2c0 .933-1.4.933-1.4 0z"
/>
</Svg>
);
}
Loading

0 comments on commit b447baf

Please sign in to comment.