Skip to content

Commit

Permalink
Feat/live 8375 fw update redesign (#4471)
Browse files Browse the repository at this point in the history
* feat(llm/fwupdatebanner): new design

* fix(llm/fwupdatebanner): loading state

* chore: changeset

* chore(llm): remove unimported code

* chore(llm): cleanup comments

* fix(llm/fwupdatebanner): loader color
  • Loading branch information
ofreyssinet-ledger authored Aug 28, 2023
1 parent 4901a78 commit f55c6e4
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 76 deletions.
5 changes: 5 additions & 0 deletions .changeset/eighty-hornets-suffer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": patch
---

New firmware update flow: redesign of fw update available banner
105 changes: 53 additions & 52 deletions apps/ledger-live-mobile/src/components/FirmwareUpdateBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import React, { useState, useCallback, useEffect } from "react";
import { Platform, Linking } from "react-native";
import { Platform, Pressable } from "react-native";
import { useNavigation, useRoute, useTheme } from "@react-navigation/native";
import { DeviceModelInfo } from "@ledgerhq/types-live";
import { useTranslation } from "react-i18next";
import { useSelector } from "react-redux";
import { Alert, Text, Flex, IconsLegacy, IconBadge, ProgressLoader } from "@ledgerhq/native-ui";
import {
Alert,
Text,
Flex,
IconsLegacy,
IconBadge,
Icons,
InfiniteLoader,
} from "@ledgerhq/native-ui";
import { DownloadMedium, UsbMedium } from "@ledgerhq/native-ui/assets/icons";
import { DeviceModelId, getDeviceModel } from "@ledgerhq/devices";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
Expand All @@ -24,8 +32,6 @@ import {
import { hasConnectedDeviceSelector } from "../reducers/appstate";
import Button from "./Button";
import QueuedDrawer from "./QueuedDrawer";
import InvertTheme from "./theme/InvertTheme";
import { urls } from "../config/urls";
import { renderConnectYourDevice } from "./DeviceAction/rendering";
import { DeviceActionError } from "./DeviceAction/common";
import { UpdateStep } from "../screens/FirmwareUpdate";
Expand All @@ -48,7 +54,7 @@ const FirmwareUpdateBanner = ({ onBackFromUpdate }: FirmwareUpdateBannerProps) =

const { dark } = useTheme();
const theme: "dark" | "light" = dark ? "dark" : "light";
const [disableUpdateButton, setDisableUpdateButton] = useState(false);
const [loading, setLoading] = useState(false);
const [showBatteryWarningDrawer, setShowBatteryWarningDrawer] = useState<boolean>(false);

const [showUnsupportedUpdateDrawer, setShowUnsupportedUpdateDrawer] = useState<boolean>(false);
Expand Down Expand Up @@ -124,7 +130,7 @@ const FirmwareUpdateBanner = ({ onBackFromUpdate }: FirmwareUpdateBannerProps) =
? setShowBatteryWarningDrawer(true)
: onExperimentalFirmwareUpdate();

setDisableUpdateButton(false);
setLoading(false);
}
}, [
batteryRequestCompleted,
Expand All @@ -140,12 +146,6 @@ const FirmwareUpdateBanner = ({ onBackFromUpdate }: FirmwareUpdateBannerProps) =
setShowUnsupportedUpdateDrawer(false);
}, []);

const onOpenReleaseNotes = useCallback(() => {
if (lastConnectedDevice) {
Linking.openURL(urls.fwUpdateReleaseNotes[lastConnectedDevice?.modelId]);
}
}, [lastConnectedDevice]);

const isUsbFwVersionUpdateSupported =
lastSeenDevice &&
isFirmwareUpdateVersionSupported(lastSeenDevice.deviceInfo, lastSeenDevice.modelId);
Expand All @@ -161,7 +161,7 @@ const FirmwareUpdateBanner = ({ onBackFromUpdate }: FirmwareUpdateBannerProps) =
if (lastConnectedDevice?.modelId === DeviceModelId.stax && newFwUpdateUxFeatureFlag?.enabled) {
// This leads to a check on the battery before triggering update, it is only necessary for Stax and on the new UX
// (because it's the only type of update that can happen via BLE)
setDisableUpdateButton(true);
setLoading(true);
triggerBatteryCheck();
}
// Path with any device model, wired and on android
Expand All @@ -179,50 +179,51 @@ const FirmwareUpdateBanner = ({ onBackFromUpdate }: FirmwareUpdateBannerProps) =
onExperimentalFirmwareUpdate,
]);

const deviceName = lastConnectedDevice
const productName = lastConnectedDevice
? getDeviceModel(lastConnectedDevice.modelId).productName
: "";
: undefined;

const deviceName = lastConnectedDevice?.deviceName;

return showBanner && hasCompletedOnboarding && hasConnectedDevice ? (
<>
{newFwUpdateUxFeatureFlag?.enabled ? (
<Flex backgroundColor="neutral.c100" borderRadius={8} px={5} py={6}>
<Flex flexDirection="row" alignItems="center" mb={5}>
<IconsLegacy.CloudDownloadMedium color="neutral.c00" size={32} />
<Text ml={5} flexShrink={1} flexGrow={1} color="neutral.c00" fontWeight="semiBold">
{t("FirmwareUpdate.newVersion", {
version,
deviceName,
})}
</Text>
</Flex>
<InvertTheme>
<Flex flexDirection="row">
<Button
flex={1}
outline
event="button_clicked"
eventProperties={{ button: "Learn more" }}
type="main"
title={t("common.learnMore")}
onPress={onOpenReleaseNotes}
/>
<Button
ml={3}
flex={1}
event="button_clicked"
eventProperties={{ button: "Update" }}
disabled={disableUpdateButton}
type="main"
title={!disableUpdateButton ? t("FirmwareUpdate.update") : null}
onPress={onClickUpdate}
outline={false}
>
{disableUpdateButton && <ProgressLoader infinite radius={10} strokeWidth={2} />}
</Button>
<Pressable onPress={onClickUpdate} disabled={loading}>
<Flex
flexDirection="row"
alignItems="flex-start"
backgroundColor="opacityDefault.c05"
borderRadius={12}
p={7}
pl={5}
>
<Flex flexDirection="row" alignItems="center" mb={5} mr={4}>
{loading ? (
<InfiniteLoader size={24} color="primary.c80" />
) : lastConnectedDevice?.modelId === DeviceModelId.stax ? (
<Icons.Stax color="primary.c80" size="M" />
) : (
<Icons.Nano color="primary.c80" size="M" />
)}
</Flex>
</InvertTheme>
</Flex>
<Flex flexDirection="column" alignItems={"flex-start"} flexShrink={1}>
<Text variant="h5" fontWeight="semiBold" pb={4}>
{t("FirmwareUpdate.banner.title")}
</Text>
<Text variant="paragraph" fontWeight="medium" color="opacityDefault.c70">
{deviceName
? t("FirmwareUpdate.banner.descriptionDeviceName", {
deviceName,
firmwareVersion: version,
})
: t("FirmwareUpdate.banner.descriptionProductName", {
productName,
firmwareVersion: version,
})}
</Text>
</Flex>
</Flex>
</Pressable>
) : (
<Flex mt={5}>
<Alert type="info" showIcon={false}>
Expand Down Expand Up @@ -294,7 +295,7 @@ const FirmwareUpdateBanner = ({ onBackFromUpdate }: FirmwareUpdateBannerProps) =
}
onClose={() => {
cancelBatteryCheck();
setDisableUpdateButton(false);
setLoading(false);
}}
>
{lastConnectedDevice && (
Expand Down
14 changes: 0 additions & 14 deletions apps/ledger-live-mobile/src/components/theme/InvertTheme.tsx

This file was deleted.

5 changes: 5 additions & 0 deletions apps/ledger-live-mobile/src/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -4116,6 +4116,11 @@
"action": "Update"
},
"FirmwareUpdate": {
"banner": {
"title": "OS update available",
"descriptionDeviceName": "Tap to update “{{deviceName}}” to OS version {{firmwareVersion}}.",
"descriptionProductName": "Tap to update your {{productName}} to OS version {{firmwareVersion}}."
},
"title": "Update firmware",
"beginUpdate": "Begin update",
"updateDevice": "{{deviceName}} OS Update",
Expand Down
13 changes: 7 additions & 6 deletions apps/ledger-live-mobile/src/screens/Manager/AppsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,6 @@ const AppsScreen = ({
data={items}
ListHeaderComponent={
<Flex mt={4}>
{showFwUpdateBanner && newFwUpdateUxFeatureFlag?.enabled ? (
<Flex mb={5}>
<FirmwareUpdateBanner onBackFromUpdate={onBackFromUpdate} />
</Flex>
) : null}
<DeviceCard
distribution={distribution}
state={state}
Expand All @@ -277,7 +272,13 @@ const AppsScreen = ({
device={device}
appList={deviceApps}
onLanguageChange={onLanguageChange}
/>
>
{showFwUpdateBanner && newFwUpdateUxFeatureFlag?.enabled ? (
<Flex p={6} pb={0}>
<FirmwareUpdateBanner onBackFromUpdate={onBackFromUpdate} />
</Flex>
) : null}
</DeviceCard>
<ProviderWarning />
<Benchmarking state={state} />
{showFwUpdateBanner && !newFwUpdateUxFeatureFlag?.enabled ? (
Expand Down
18 changes: 14 additions & 4 deletions apps/ledger-live-mobile/src/screens/Manager/Device/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import React, { useRef, useEffect, memo, useCallback, useMemo, useState } from "react";
import React, {
useRef,
useEffect,
memo,
useCallback,
useMemo,
useState,
PropsWithChildren,
} from "react";
import { useSelector } from "react-redux";
import { Trans } from "react-i18next";

Expand Down Expand Up @@ -33,7 +41,7 @@ const illustrations = {
stax: Stax,
};

type Props = {
type Props = PropsWithChildren<{
distribution: AppsDistribution;
state: State;
result: ListAppsResult;
Expand All @@ -46,12 +54,12 @@ type Props = {
dispatch: (action: Action) => void;
appList: App[];
onLanguageChange: () => void;
};
}>;

const BorderCard = styled.View`
flex-direction: column;
border: 1px solid ${p => p.theme.colors.neutral.c40};
border-radius: 4px;
border-radius: 8px;
`;

const DeviceCard = ({
Expand All @@ -65,6 +73,7 @@ const DeviceCard = ({
dispatch,
appList,
onLanguageChange,
children,
}: Props) => {
const { colors, theme } = useTheme();
const lastSeenCustomImage = useSelector(lastSeenCustomImageSelector);
Expand Down Expand Up @@ -110,6 +119,7 @@ const DeviceCard = ({

return (
<BorderCard>
{children}
<Flex flexDirection={"row"} mt={20} mx={4} mb={8} alignItems="center">
{illustration}
<Flex
Expand Down

1 comment on commit f55c6e4

@vercel
Copy link

@vercel vercel bot commented on f55c6e4 Aug 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.