-
Notifications
You must be signed in to change notification settings - Fork 356
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat 💄(llm): update LNX drawer in Reborn
- Loading branch information
1 parent
38f7d5d
commit 27fce69
Showing
14 changed files
with
308 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"live-mobile": minor | ||
--- | ||
|
||
Create flex upsell drawer under ff to switch from the old LNX upsell drawer |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
186 changes: 186 additions & 0 deletions
186
apps/ledger-live-mobile/src/newArch/features/Reborn/screens/UpsellFlex/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
import React from "react"; | ||
import useUpsellFlexModel from "./useUpsellFlexModel"; | ||
import { | ||
Box, | ||
Button, | ||
Flex, | ||
IconBoxList, | ||
Icons, | ||
ScrollListContainer, | ||
Text, | ||
} from "@ledgerhq/native-ui"; | ||
import { TouchableOpacity } from "react-native"; | ||
import styled from "styled-components/native"; | ||
import videoSources from "../../../../../../assets/videos"; | ||
import Video from "react-native-video"; | ||
import GradientContainer from "~/components/GradientContainer"; | ||
import { TrackScreen } from "~/analytics"; | ||
|
||
const videoSource = videoSources.flex; | ||
|
||
const hitSlop = { | ||
bottom: 10, | ||
left: 24, | ||
right: 24, | ||
top: 10, | ||
}; | ||
|
||
const StyledSafeAreaView = styled(Box)` | ||
flex: 1; | ||
background-color: ${p => p.theme.colors.background.default}; | ||
padding-top: ${p => p.theme.space[10]}px; | ||
`; | ||
|
||
const CloseButton = styled(TouchableOpacity)` | ||
background-color: ${p => p.theme.colors.neutral.c30}; | ||
padding: 8px; | ||
border-radius: 32px; | ||
`; | ||
|
||
const items = [ | ||
{ | ||
title: "buyDevice.0.title", | ||
desc: "buyDevice.0.desc", | ||
Icon: Icons.Coins, | ||
}, | ||
{ | ||
title: "buyDevice.1.title", | ||
desc: "buyDevice.1.desc", | ||
Icon: Icons.GraphAsc, | ||
}, | ||
{ | ||
title: "buyDevice.2.title", | ||
desc: "buyDevice.2.desc", | ||
Icon: Icons.Globe, | ||
}, | ||
{ | ||
title: "buyDevice.3.title", | ||
desc: "buyDevice.3.desc", | ||
Icon: Icons.Flex, | ||
}, | ||
]; | ||
|
||
const videoStyle = { | ||
height: "100%", | ||
}; | ||
|
||
type ViewProps = ReturnType<typeof useUpsellFlexModel>; | ||
|
||
function View({ | ||
t, | ||
handleBack, | ||
setupDevice, | ||
buyLedger, | ||
colors, | ||
readOnlyModeEnabled, | ||
videoMounted, | ||
}: ViewProps) { | ||
return ( | ||
<StyledSafeAreaView> | ||
{readOnlyModeEnabled ? <TrackScreen category="ReadOnly" name="Upsell Flex" /> : null} | ||
<Flex | ||
flexDirection="row" | ||
alignItems="center" | ||
justifyContent="flex-end" | ||
width="100%" | ||
position="absolute" | ||
zIndex={10} | ||
p={6} | ||
top={50} | ||
> | ||
<CloseButton onPress={handleBack} hitSlop={hitSlop}> | ||
<Icons.Close size="S" /> | ||
</CloseButton> | ||
</Flex> | ||
<ScrollListContainer> | ||
<Flex | ||
height={320} | ||
borderTopLeftRadius={32} | ||
borderTopRightRadius={32} | ||
width="100%" | ||
overflow="hidden" | ||
opacity={videoMounted ? 0.8 : 0} | ||
> | ||
{videoMounted && ( | ||
<Video | ||
disableFocus | ||
source={videoSource} | ||
style={{ | ||
backgroundColor: colors.background.main, | ||
transform: [{ scale: 1.4 }], | ||
...(videoStyle as object), | ||
}} | ||
muted | ||
repeat={true} | ||
/> | ||
)} | ||
<GradientContainer | ||
color={colors.background.drawer} | ||
startOpacity={0} | ||
endOpacity={1} | ||
direction="top-to-bottom" | ||
containerStyle={{ | ||
position: "absolute", | ||
borderRadius: 0, | ||
left: 0, | ||
bottom: 0, | ||
width: "100%", | ||
height: "30%", | ||
}} | ||
/> | ||
</Flex> | ||
<Flex p={6}> | ||
<Text variant="h4" textAlign="center" lineHeight="32.4px"> | ||
{t("buyDevice.title")} | ||
</Text> | ||
<Flex mt={6} mb={8} justifyContent="center" alignItems="stretch"> | ||
<Text px={6} textAlign="center" variant="body" color="neutral.c70"> | ||
{t("buyDevice.desc")} | ||
</Text> | ||
</Flex> | ||
<IconBoxList | ||
iconShapes="circle" | ||
itemContainerProps={{ pr: 6 }} | ||
items={items.map(item => ({ | ||
Icon: <item.Icon size="S" />, | ||
title: t(item.title), | ||
description: ( | ||
<Text variant="paragraphLineHeight" color="neutral.c70"> | ||
{t(item.desc)} | ||
</Text> | ||
), | ||
}))} | ||
/> | ||
</Flex> | ||
</ScrollListContainer> | ||
<Flex> | ||
<Button | ||
mx={6} | ||
my={6} | ||
type="main" | ||
outline={false} | ||
testID="getDevice-buy-button" | ||
onPress={buyLedger} | ||
size="large" | ||
> | ||
{t("buyDevice.cta")} | ||
</Button> | ||
<Flex px={6} pt={0} mb={8}> | ||
<Button | ||
type="default" | ||
border={1} | ||
borderColor="neutral.c50" | ||
onPress={setupDevice} | ||
size="large" | ||
> | ||
{t("buyDevice.footer")} | ||
</Button> | ||
</Flex> | ||
</Flex> | ||
</StyledSafeAreaView> | ||
); | ||
} | ||
|
||
const UpsellFlex = () => <View {...useUpsellFlexModel()} />; | ||
|
||
export default UpsellFlex; |
96 changes: 96 additions & 0 deletions
96
apps/ledger-live-mobile/src/newArch/features/Reborn/screens/UpsellFlex/useUpsellFlexModel.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import { useFeature } from "@ledgerhq/live-common/featureFlags/index"; | ||
import { useNavigation } from "@react-navigation/native"; | ||
import { useCallback } from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
import { Linking } from "react-native"; | ||
import { useSelector, useDispatch } from "react-redux"; | ||
import { useTheme } from "styled-components/native"; | ||
import { setOnboardingHasDevice } from "~/actions/settings"; | ||
import { track } from "~/analytics"; | ||
import { BuyDeviceNavigatorParamList } from "~/components/RootNavigator/types/BuyDeviceNavigator"; | ||
import { | ||
BaseNavigationComposite, | ||
StackNavigatorNavigation, | ||
} from "~/components/RootNavigator/types/helpers"; | ||
import { OnboardingNavigatorParamList } from "~/components/RootNavigator/types/OnboardingNavigator"; | ||
import useIsAppInBackground from "~/components/useIsAppInBackground"; | ||
import { ScreenName, NavigatorName } from "~/const"; | ||
import { readOnlyModeEnabledSelector } from "~/reducers/settings"; | ||
import { useNavigationInterceptor } from "~/screens/Onboarding/onboardingContext"; | ||
import { urls } from "~/utils/urls"; | ||
|
||
type NavigationProp = BaseNavigationComposite< | ||
| StackNavigatorNavigation<BuyDeviceNavigatorParamList, ScreenName.GetDevice> | ||
| StackNavigatorNavigation<OnboardingNavigatorParamList, ScreenName.GetDevice> | ||
>; | ||
|
||
const useUpsellFlexModel = () => { | ||
const { t } = useTranslation(); | ||
const navigation = useNavigation<NavigationProp>(); | ||
const { colors } = useTheme(); | ||
const { setShowWelcome, setFirstTimeOnboarding } = useNavigationInterceptor(); | ||
const buyDeviceFromLive = useFeature("buyDeviceFromLive"); | ||
const readOnlyModeEnabled = useSelector(readOnlyModeEnabledSelector); | ||
const dispatch = useDispatch(); | ||
const currentNavigation = navigation.getParent()?.getParent()?.getState().routes[0].name; | ||
const isInOnboarding = currentNavigation === NavigatorName.BaseOnboarding; | ||
|
||
const handleBack = useCallback(() => { | ||
navigation.goBack(); | ||
if (readOnlyModeEnabled) { | ||
track("button_clicked", { | ||
button: "close", | ||
page: "Upsell Flex", | ||
}); | ||
} | ||
}, [readOnlyModeEnabled, navigation]); | ||
|
||
const setupDevice = useCallback(() => { | ||
setShowWelcome(false); | ||
setFirstTimeOnboarding(false); | ||
if (isInOnboarding) dispatch(setOnboardingHasDevice(true)); | ||
navigation.navigate(NavigatorName.BaseOnboarding, { | ||
screen: NavigatorName.Onboarding, | ||
params: { | ||
screen: ScreenName.OnboardingDeviceSelection, | ||
}, | ||
}); | ||
if (readOnlyModeEnabled) { | ||
track("message_clicked", { | ||
message: "I already have a device, set it up now", | ||
page: "Upsell Flex", | ||
}); | ||
} | ||
}, [ | ||
setShowWelcome, | ||
setFirstTimeOnboarding, | ||
isInOnboarding, | ||
dispatch, | ||
navigation, | ||
readOnlyModeEnabled, | ||
]); | ||
|
||
const buyLedger = useCallback(() => { | ||
if (buyDeviceFromLive?.enabled) { | ||
// FIXME: ScreenName.PurchaseDevice does not exist when coming from the Onboarding navigator | ||
// @ts-expect-error This seem very impossible to type because ts is right… | ||
navigation.navigate(ScreenName.PurchaseDevice); | ||
} else { | ||
Linking.openURL(urls.buyFlex); | ||
} | ||
}, [buyDeviceFromLive?.enabled, navigation]); | ||
|
||
const videoMounted = !useIsAppInBackground(); | ||
|
||
return { | ||
t, | ||
handleBack, | ||
setupDevice, | ||
buyLedger, | ||
colors, | ||
readOnlyModeEnabled, | ||
videoMounted, | ||
}; | ||
}; | ||
|
||
export default useUpsellFlexModel; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.