Skip to content

Commit

Permalink
[FEAT] : Get members from trustchain (#7387)
Browse files Browse the repository at this point in the history
  • Loading branch information
mcayuelas-ledger authored Jul 29, 2024
1 parent 0a1011e commit fc0474e
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/funny-swans-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": patch
---

Add Banner when error throws
5 changes: 5 additions & 0 deletions .changeset/moody-socks-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": patch
---

Get members of trutchain
9 changes: 8 additions & 1 deletion apps/ledger-live-mobile/src/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -6733,7 +6733,14 @@
"synchronizedInstances": {
"cta": "Manage now",
"title": "{{count}} Synchronized Instance",
"title_plural": "{{count}} Synchronized Instances"
"title_plural": "{{count}} Synchronized Instances",
"error": "Instances"
},
"errors": {
"fetching": "Something went wrong while fetching your synchronized instances.",
"trustchain": "Unexpected falsy trustchain",
"memberCredentials": "Unexpected falsy member credentials",
"ledgerSyncUnavailable": "Ledger Sync is currently unavailable. This doesn’t have any impact on your assets."
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ const Stack = createStackNavigator<

export function WalletSyncSettingsNavigator() {
return (
<Stack.Navigator initialRouteName={ScreenName.GeneralSettings}>
<Stack.Screen name={ScreenName.GeneralSettings} component={GeneralSettings} />
<Stack.Screen
name={NavigatorName.WalletSync}
component={WalletSyncNavigator}
options={{ headerShown: false }}
/>
</Stack.Navigator>
<QueryClientProvider client={new QueryClient()}>
<Stack.Navigator initialRouteName={ScreenName.GeneralSettings}>
<Stack.Screen name={ScreenName.GeneralSettings} component={GeneralSettings} />
<Stack.Screen
name={NavigatorName.WalletSync}
component={WalletSyncNavigator}
options={{ headerShown: false }}
/>
</Stack.Navigator>
</QueryClientProvider>
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum QueryKey {
getMembers = "useGetMembers",
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { memberCredentialsSelector, trustchainSelector } from "@ledgerhq/trustchain/store";
import { useSelector } from "react-redux";
import { useTrustchainSdk } from "./useTrustchainSdk";
import { useQuery } from "@tanstack/react-query";
import { QueryKey } from "./type.hooks";
import { useTranslation } from "react-i18next";
import { createCustomErrorClass } from "@ledgerhq/errors";

export const TrustchainNotFound = createCustomErrorClass("TrustchainNotFound");
export const MemberCredentialsNotFound = createCustomErrorClass("MemberCredentialsNotFound");

export function useGetMembers() {
const sdk = useTrustchainSdk();
const trustchain = useSelector(trustchainSelector);
const memberCredentials = useSelector(memberCredentialsSelector);
const { t } = useTranslation();

function getMembers() {
if (!memberCredentials) {
throw new MemberCredentialsNotFound(
t("walletSync.walletSyncActivated.errors.memberCredentials"),
);
}

if (!trustchain) {
throw new TrustchainNotFound(t("walletSync.walletSyncActivated.errors.trustchain"));
}

try {
return sdk.getMembers(trustchain, memberCredentials);
} catch (e) {
throw e as Error;
}
}

return useQuery({
queryKey: [QueryKey.getMembers, trustchain],
queryFn: () => getMembers(),
refetchOnMount: true,
refetchOnReconnect: true,
refetchOnWindowFocus: true,
retry: false,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ import { Flex, Icons, Text } from "@ledgerhq/native-ui";
import React from "react";
import { TouchableOpacity } from "react-native";
import { Separator } from "../../components/Separator";
import styled from "styled-components/native";

export type OptionProps = {
label: string;
description: string;
onClick?: () => void;
testId: string;
disabled?: boolean;
id: string;
};

export const Option = ({ label, description, onClick, testId }: OptionProps) => (
<TouchableOpacity onPress={onClick} data-testid={testId}>
<Flex flexDirection="row" alignItems="center" justifyContent="center">
export const Option = ({ label, description, onClick, testId, disabled }: OptionProps) => (
<TouchableOpacity onPress={onClick} data-testid={testId} disabled={disabled}>
<Container flexDirection="row" alignItems="center" justifyContent="center" disabled={disabled}>
<Flex paddingY={24} width={304}>
<Text fontWeight="semiBold" variant="large" color="neutral.c100">
{label}
Expand All @@ -26,8 +29,12 @@ export const Option = ({ label, description, onClick, testId }: OptionProps) =>
<Flex flexGrow={1} alignItems={"center"} justifyContent={"end"}>
<Icons.ChevronRight size="M" color="neutral.c70" />
</Flex>
</Flex>
</Container>

<Separator />
</TouchableOpacity>
);

const Container = styled(Flex).attrs((p: { disabled?: boolean }) => ({
opacity: p.disabled ? 0.3 : 1,
}))<{ disabled?: boolean }>``;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Flex, Text, Icons } from "@ledgerhq/native-ui";
import { Box, Flex, Text, Icons, InfiniteLoader, Alert } from "@ledgerhq/native-ui";
import React from "react";
import { useTranslation } from "react-i18next";
import { Option, OptionProps } from "./Option";
Expand All @@ -10,13 +10,12 @@ import {
} from "../../hooks/useWalletSyncAnalytics";
import { Separator } from "../../components/Separator";
import { TouchableOpacity } from "react-native";
import { TrustchainNotFound, useGetMembers } from "../../hooks/useGetMembers";

const WalletSyncManage = () => {
const { t } = useTranslation();

//const { instances, isLoading, hasError } = useInstances();
const instances = ["instance1", "instance2", "instance3"];
const disabled = false;
const { data, isLoading, isError, error } = useGetMembers();

const { onClickTrack } = useWalletSyncAnalytics();

Expand All @@ -42,45 +41,70 @@ const WalletSyncManage = () => {
description: t("walletSync.walletSyncActivated.synchronize.description"),
onClick: goToSync,
testId: "walletSync-synchronize",
id: "synchronize",
},
{
label: t("walletSync.walletSyncActivated.manageKey.title"),
description: t("walletSync.walletSyncActivated.manageKey.description"),
onClick: goToManageBackup,
testId: "walletSync-manage-backup",
id: "manageKey",
},
];

function getError(error: Error) {
// if (error instanceof UnavailableServerError) { DO SOMETHING}

return <Alert type="error" title={error.message} />;
}

return (
<Box height="100%" paddingX="16px">
{/* <TrackPage category={AnalyticsPage.WalletSyncSettings} /> */}

<Separator />
{isError ? getError(error) : <Separator />}

{Options.map((props, index) => (
<Option {...props} key={index} />
<Option
{...props}
key={index}
disabled={
props.id === "manageKey"
? error instanceof TrustchainNotFound
? false
: isError
: isError
}
/>
))}

<InstancesRow disabled={disabled}>
<Flex
<InstancesRow disabled={isError}>
<Container
flexDirection="row"
justifyContent="space-between"
paddingTop={24}
alignItems="center"
disabled={isError}
>
<Text fontWeight="semiBold" variant="large" color="neutral.c100">
{t("walletSync.walletSyncActivated.synchronizedInstances.title", {
count: instances?.length,
})}
</Text>
{isLoading ? (
<InfiniteLoader size={16} />
) : (
<Text fontWeight="semiBold" variant="large" color="neutral.c100">
{isError
? t("walletSync.walletSyncActivated.synchronizedInstances.error")
: t("walletSync.walletSyncActivated.synchronizedInstances.title", {
count: data?.length,
})}
</Text>
)}

<Flex flexDirection="row" alignItems="center" justifyContent="center">
<Text variant="body" color="primary.c80" mr={2}>
{t("walletSync.walletSyncActivated.synchronizedInstances.cta")}
</Text>
<Icons.ChevronRight size="M" color="neutral.c70" />
</Flex>
</Flex>
</Container>
</InstancesRow>
</Box>
);
Expand All @@ -93,3 +117,7 @@ const InstancesRow = styled(TouchableOpacity)<{ disabled?: boolean }>`
cursor: ${p => (p.disabled ? "not-allowed" : "pointer")};
}
`;

const Container = styled(Flex).attrs((p: { disabled?: boolean }) => ({
opacity: p.disabled ? 0.3 : 1,
}))<{ disabled?: boolean }>``;

0 comments on commit fc0474e

Please sign in to comment.