Skip to content

Commit

Permalink
Merge 752d0a4 into 5f71360
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandremgo authored Nov 17, 2022
2 parents 5f71360 + 752d0a4 commit 24cf60b
Show file tree
Hide file tree
Showing 20 changed files with 299 additions and 120 deletions.
5 changes: 5 additions & 0 deletions .changeset/fifty-garlics-marry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": patch
---

Fix for locked device error
6 changes: 6 additions & 0 deletions .changeset/little-parrots-swim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@ledgerhq/live-common": patch
"@ledgerhq/errors": patch
---

Fix for locked device error
5 changes: 5 additions & 0 deletions .changeset/selfish-lobsters-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ledger-live-desktop": patch
---

Fix for locked device error
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ const CustomImageDeviceAction: React.FC<Props> = withRemountableWrapper(props =>
) : isError ? (
<Flex flexDirection="column" alignItems="center">
{renderError({
t,
error,
device: device ?? undefined,
...(isRefusedOnStaxError
? { Icon: Icons.CircledAlertMedium, iconColor: "warning.c100" }
: {}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
renderSecureTransferDeviceConfirmation,
renderAllowLanguageInstallation,
renderInstallingLanguage,
renderLockedDeviceError,
} from "./rendering";

type Props<R, H, P> = {
Expand Down Expand Up @@ -73,6 +74,7 @@ export const DeviceActionDefaultRendering = <R, H, P>({
appAndVersion,
device,
unresponsive,
isLocked,
error,
isLoading,
allowManagerRequestedWording,
Expand Down Expand Up @@ -241,6 +243,7 @@ export const DeviceActionDefaultRendering = <R, H, P>({

if (inWrongDeviceForAccount) {
return renderInWrongAppForAccount({
t,
onRetry,
accountName: inWrongDeviceForAccount.accountName,
});
Expand All @@ -253,13 +256,15 @@ export const DeviceActionDefaultRendering = <R, H, P>({
error instanceof UpdateYourApp
) {
return renderError({
t,
error,
managerAppName: error.managerAppName,
});
}

if (error instanceof LatestFirmwareVersionRequired) {
return renderError({
t,
error,
requireFirmwareUpdate: true,
});
Expand All @@ -272,6 +277,7 @@ export const DeviceActionDefaultRendering = <R, H, P>({
(error instanceof TransportStatusError && error.message.includes("0x6d06"))
) {
return renderError({
t,
error: new DeviceNotOnboarded(),
withOnboardingCTA: true,
info: true,
Expand All @@ -280,19 +286,27 @@ export const DeviceActionDefaultRendering = <R, H, P>({

if (error instanceof NoSuchAppOnProvider) {
return renderError({
t,
error,
withOpenManager: true,
withExportLogs: true,
});
}

return renderError({
t,
error,
onRetry,
withExportLogs: true,
device: device ?? undefined,
});
}

// Renders an error as long as LLD is using the "event" implementation of device actions
if (isLocked) {
return renderLockedDeviceError({ t, device, onRetry });
}

if ((!isLoading && !device) || unresponsive) {
return renderConnectYourDevice({
modelId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { TokenCurrency } from "@ledgerhq/types-cryptoassets";
import { Transaction, TransactionStatus } from "@ledgerhq/live-common/generated/types";
import { ExchangeRate, Exchange } from "@ledgerhq/live-common/exchange/swap/types";
import { getProviderName } from "@ledgerhq/live-common/exchange/swap/utils/index";
import { WrongDeviceForAccount, UpdateYourApp } from "@ledgerhq/errors";
import { WrongDeviceForAccount, UpdateYourApp, LockedDeviceError } from "@ledgerhq/errors";
import { LatestFirmwareVersionRequired } from "@ledgerhq/live-common/errors";
import { DeviceModelId, getDeviceModel } from "@ledgerhq/devices";
import { Device } from "@ledgerhq/live-common/hw/actions/types";
Expand Down Expand Up @@ -47,7 +47,8 @@ import { SWAP_VERSION } from "~/renderer/screens/exchange/Swap2/utils/index";
import { context } from "~/renderer/drawers/Provider";
import { track } from "~/renderer/analytics/segment";
import { DrawerFooter } from "~/renderer/screens/exchange/Swap2/Form/DrawerFooter";
import { Flex, Icons, Text as TextV3, Log, ProgressLoader } from "@ledgerhq/react-ui";
import { Flex, Icons, Text as TextV3, Log, ProgressLoader, BoxedIcon } from "@ledgerhq/react-ui";
import { LockAltMedium } from "@ledgerhq/react-ui/assets/icons";
import { withV3StyleProvider } from "~/renderer/styles/StyleProviderV3";
import FramedImage from "../CustomImage/FramedImage";

Expand Down Expand Up @@ -483,8 +484,49 @@ export const renderWarningOutdated = ({
</Wrapper>
);

// Quick fix: the error LockedDeviceError should be catched
// inside all the device actions and mapped to an event of type "lockedDevice".
// With this fix, we can catch all the device action error that were not catched upstream.
// If LockedDeviceError is thrown from outside a device action and renderError was not called
// it is still handled by GenericErrorView.
export const renderLockedDeviceError = ({
t,
device,
onRetry,
}: {
t: TFunction;
device?: Device;
onRetry?: () => void;
}) => {
const productName = device ? getDeviceModel(device.modelId).productName : null;

return (
<Wrapper id="error-locked-device">
<Flex mb={5}>
<BoxedIcon size={64} Icon={LockAltMedium} iconSize={24} iconColor="neutral.c100" />
</Flex>
<ErrorTitle>{t("errors.LockedDeviceError.title")}</ErrorTitle>
<ErrorDescription>
{productName
? t("errors.LockedDeviceError.descriptionWithProductName", {
productName,
})
: t("errors.LockedDeviceError.description")}
</ErrorDescription>
<ButtonContainer>
{onRetry ? (
<Button primary onClick={onRetry}>
{t("common.retry")}
</Button>
) : null}
</ButtonContainer>
</Wrapper>
);
};

export const renderError = ({
error,
t,
withOpenManager,
onRetry,
withExportLogs,
Expand All @@ -495,8 +537,10 @@ export const renderError = ({
managerAppName,
requireFirmwareUpdate,
withOnboardingCTA,
device,
}: {
error: Error;
t: TFunction;
withOpenManager?: boolean;
onRetry?: () => void;
withExportLogs?: boolean;
Expand All @@ -507,67 +551,79 @@ export const renderError = ({
managerAppName?: string;
requireFirmwareUpdate?: boolean;
withOnboardingCTA?: boolean;
}) => (
<Wrapper id={`error-${error.name}`}>
<Logo info={info} warning={warning}>
<ErrorIcon size={44} error={error} />
</Logo>
<ErrorTitle>
<TranslatedError error={error} />
</ErrorTitle>
<ErrorDescription>
<TranslatedError error={error} field="description" /> <SupportLinkError error={error} />
</ErrorDescription>
{list ? (
device?: Device;
}) => {
// Redirects from renderError and not from DeviceActionDefaultRendering because renderError
// can be used directly by other component
if (error instanceof LockedDeviceError) {
return renderLockedDeviceError({ t, onRetry, device });
}

return (
<Wrapper id={`error-${error.name}`}>
<Logo info={info} warning={warning}>
<ErrorIcon size={44} error={error} />
</Logo>
<ErrorTitle>
<TranslatedError error={error} />
</ErrorTitle>
<ErrorDescription>
<ol style={{ textAlign: "justify" }}>
<TranslatedError error={error} field="list" />
</ol>
<TranslatedError error={error} field="description" /> <SupportLinkError error={error} />
</ErrorDescription>
) : null}
<ButtonContainer>
{managerAppName || requireFirmwareUpdate ? (
<OpenManagerButton
appName={managerAppName}
updateApp={error instanceof UpdateYourApp}
firmwareUpdate={error instanceof LatestFirmwareVersionRequired}
/>
) : (
<>
{supportLink ? (
<ExternalLinkButton label={<Trans i18nKey="common.getSupport" />} url={supportLink} />
) : null}
{withExportLogs ? (
<ExportLogsButton
title={<Trans i18nKey="settings.exportLogs.title" />}
small={false}
primary={false}
outlineGrey
mx={1}
/>
) : null}
{withOpenManager ? (
<OpenManagerButton mt={0} ml={withExportLogs ? 4 : 0} />
) : onRetry ? (
<Button primary ml={withExportLogs ? 4 : 0} onClick={onRetry}>
<Trans i18nKey="common.retry" />
</Button>
) : null}
{withOnboardingCTA ? <OpenOnboardingBtn /> : null}
</>
)}
</ButtonContainer>
</Wrapper>
);
{list ? (
<ErrorDescription>
<ol style={{ textAlign: "justify" }}>
<TranslatedError error={error} field="list" />
</ol>
</ErrorDescription>
) : null}
<ButtonContainer>
{managerAppName || requireFirmwareUpdate ? (
<OpenManagerButton
appName={managerAppName}
updateApp={error instanceof UpdateYourApp}
firmwareUpdate={error instanceof LatestFirmwareVersionRequired}
/>
) : (
<>
{supportLink ? (
<ExternalLinkButton label={t("common.getSupport")} url={supportLink} />
) : null}
{withExportLogs ? (
<ExportLogsButton
title={t("settings.exportLogs.title")}
small={false}
primary={false}
outlineGrey
mx={1}
/>
) : null}
{withOpenManager ? (
<OpenManagerButton mt={0} ml={withExportLogs ? 4 : 0} />
) : onRetry ? (
<Button primary ml={withExportLogs ? 4 : 0} onClick={onRetry}>
{t("common.retry")}
</Button>
) : null}
{withOnboardingCTA ? <OpenOnboardingBtn /> : null}
</>
)}
</ButtonContainer>
</Wrapper>
);
};

export const renderInWrongAppForAccount = ({
t,
onRetry,
accountName,
}: {
t: TFunction;
onRetry: () => void;
accountName: string;
}) =>
renderError({
t,
error: new WrongDeviceForAccount(null, { accountName }),
withExportLogs: true,
onRetry,
Expand Down
23 changes: 0 additions & 23 deletions apps/ledger-live-desktop/src/renderer/components/ErrorDisplay.js

This file was deleted.

26 changes: 26 additions & 0 deletions apps/ledger-live-desktop/src/renderer/components/ErrorDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useTranslation } from "react-i18next";
import { renderError } from "~/renderer/components/DeviceAction/rendering";

export type ErrorDisplayProps = {
error: Error;
onRetry?: () => void;
withExportLogs?: boolean;
list?: boolean;
supportLink?: string;
warning?: boolean;
};

const ErrorDisplay = ({
error,
onRetry,
withExportLogs,
list,
supportLink,
warning,
}: ErrorDisplayProps) => {
const { t } = useTranslation();

return renderError({ t, error, onRetry, withExportLogs, list, supportLink, warning });
};

export default ErrorDisplay;
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ const Result = ({
const Root = ({ data, onClose }: Props) => {
const { account, parentAccount, getCoinifyContext, onResult, onCancel } = data;

const { t } = useTranslation();

const tokenCurrency = account && account.type === "TokenAccount" && account.token;

// state
Expand Down Expand Up @@ -138,6 +140,7 @@ const Root = ({ data, onClose }: Props) => {
return (
<Box alignItems={"center"} justifyContent={"center"} p={20}>
{renderError({
t,
error,
})}
</Box>
Expand Down
5 changes: 5 additions & 0 deletions apps/ledger-live-desktop/static/i18n/en/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -5309,6 +5309,11 @@
"ImageLoadRefusedOnDevice": {
"title": "Image load refused on device (TODO: final wording)",
"description": "If this image wasn't the right fit, you can try again with another image."
},
"LockedDeviceError": {
"title": "Your device is locked",
"description": "Unlock your device and try again.",
"descriptionWithProductName": "Unlock your {{ productName }} and try again."
}
},
"cryptoOrg": {
Expand Down
Loading

0 comments on commit 24cf60b

Please sign in to comment.