Skip to content

Commit

Permalink
Feat/FAT 156 - LLM Post onboarding (#943)
Browse files Browse the repository at this point in the history
* feat: post onboarding

author Olivier Freyssinet <[email protected]> 1660815558 +0200
committer Olivier F <[email protected]> 1661187186 +0200

feat: post onboarding

PostOnboardingHub screen ground work + debug settings + screen for mocking features with "done" button

Use correct typo for title & subtitle of hub screen

Add largeLineHeight variant to native-ui text

Use correct typographic styles & colors in post onboarding hub

Move post onboarding types to LLC

Add POST_ONBOARDING_CLEAR_LAST_ACTION_COMPLETED action

fix bracketSizes type

Rename & document hooks

Fix PostOnboardingMockActionScreen

Move post onboarding to own navigator

Clear last action completed when leaving closing hub screen

feat(native-ui): new variant "plain" for Notification component

Implement logic for closing popup in PostOnboardingHub

Fix bad style in native-ui getTextStyle (missing unit in styled component)

Remove "all done" state confettis in hub

Reword "setActionDone" to "setActionCompleted"

Fix import of postOnboardingState (don't add to store if value is falsy)

Add post onboarding entry point on portfolio/wallet screen

Implement new tag variants from figma

Change icons & shorten text of mock post onboarding actions

Use new tag styling

Set logic for mocking post onboarding actions

Add animated success screen

Improve placeholder text

Cleanup (rename mock actions as such, cleanup documentation, remove useless hook)

Improve wording of debug settings

Fix warning in PostOnboardingHub

Fix post rebase

Fix color of placeholder img in entry point card

Fix feature flagging of post onboarding actions

lint

Tag component changesets

Add guides for implementation of post onboarding action for each device model

Add startPostOnboarding at the end of existing onboarding

Fix useStartPostOnboardingCallback not always overriding state

Improve navigation to main screen

lint

changeset

Migrate postOnboarding types to types-live

Add tracking of post onboarding action start

docs & rename ActionState type

Remove placeholder type

Better use of design system spacing & radii scales

Rename `icon` > `Icon` to follow component naming convention

Use deep comparison of post onboarding state before saving it in db

Cleanup some types & comments

Fix potential crash on falsy value

lint

Use Divider from design system

Add todos

Try moving state logic to LLC (not working for now bc of react-redux)

pnpm i

remove /lib/postOnboarding imports

remove /lib imports in postOnboarding/hooks

Revert change on portfolio index

Force react-redux dep in LLM metro config (thank you Julien you saved the day 🙏)

chore: remove react-native from react-redux peer deps

Slightly more elegant way of fixing LLM/LLC react-redux duplicate package issues

live-common changesets

Fix bad use of importPostOnboardingState action creator

lint

install deps post rebase

fix bad merge

fix reducer missing post rebase

Fix ts (post rebase)

Force react-redux dep in LLM metro config

chore: remove react-dom from react-redux peer deps

Fix typing of PostOnboardingProvider props

Move hooks to their own file

rename hooks.tsx to useNavigateToPostOnboardingHubCallback.ts

no import from "."

Remove log

some unit tests, more coming tomorrow

this is boring to death

Add tests for usePostOnboardingHubState

Unit test postOnboarding reducer & actions creators

give this code some room to breathe

fix PostOnboarding routes typing

improve test clarity

fix post rebase

fix doc

remove @ts-expect-error

lint

lint again

lint

Fix post rebase


Fix post rebase


Fix remove bad comment on portfolio


Remove useless hooks


Rename onStartEvent->startEvent, onStartEventProperties->startEventProperties


File apps/ledger-live-mobile/src/locales/en/common.json was updated on ru-RU locale

File apps/ledger-live-mobile/src/locales/en/common.json was updated on de-DE locale

File apps/ledger-live-mobile/src/locales/en/common.json was updated on ko-KR locale

File apps/ledger-live-mobile/src/locales/en/common.json was updated on pt-BR locale

File apps/ledger-live-mobile/src/locales/en/common.json was updated on es-ES locale

File apps/ledger-live-mobile/src/locales/en/common.json was updated on tr-TR locale

File apps/ledger-live-mobile/src/locales/en/common.json was updated on ar-AE locale

File apps/ledger-live-mobile/src/locales/en/common.json was updated on fr-FR locale

File apps/ledger-live-mobile/src/locales/en/common.json was updated on zh-CN locale

File apps/ledger-live-mobile/src/locales/en/common.json was updated on ja-JP locale

Prevent closing the onboarding hub during the end animation


Add delay prop to Transitions.Fade


Fade out the notification at the bottom


doc:ljs


Remove usePostOnboardingDeviceModelId, useSetActionCompletedCallback


lint


fix post rebase

* Improve cleanup of triggerEndAnimation

* Smartling translations are updated for PR#943 from feat/FAT-156-post-onboarding (#1251)

* File apps/ledger-live-mobile/src/locales/en/common.json was updated on ru-RU locale

* File apps/ledger-live-mobile/src/locales/en/common.json was updated on de-DE locale

* File apps/ledger-live-mobile/src/locales/en/common.json was updated on ko-KR locale

* File apps/ledger-live-mobile/src/locales/en/common.json was updated on pt-BR locale

* File apps/ledger-live-mobile/src/locales/en/common.json was updated on es-ES locale

* File apps/ledger-live-mobile/src/locales/en/common.json was updated on tr-TR locale

* File apps/ledger-live-mobile/src/locales/en/common.json was updated on ar-AE locale

* File apps/ledger-live-mobile/src/locales/en/common.json was updated on fr-FR locale

* File apps/ledger-live-mobile/src/locales/en/common.json was updated on zh-CN locale

* File apps/ledger-live-mobile/src/locales/en/common.json was updated on ja-JP locale

* update pods

Co-authored-by: Ledger Live <[email protected]>
  • Loading branch information
ofreyssinet-ledger and ledgerlive committed Sep 13, 2022
1 parent 4d2149c commit 8465b5e
Show file tree
Hide file tree
Showing 66 changed files with 3,542 additions and 525 deletions.
5 changes: 5 additions & 0 deletions .changeset/chilled-hornets-press.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/live-common": patch
---

Add react-redux and redux-actions peer dependencies
5 changes: 5 additions & 0 deletions .changeset/cool-wombats-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": patch
---

Add post-onboarding hub (not used for any device model so far)
5 changes: 5 additions & 0 deletions .changeset/dry-games-approve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/types-live": patch
---

Add postOnboarding types
5 changes: 5 additions & 0 deletions .changeset/healthy-birds-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/live-common": patch
---

Add post onboarding actions, reducers, hooks and provider logic
5 changes: 5 additions & 0 deletions .changeset/lazy-doors-pretend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/native-ui": patch
---

Add "delay" prop to Transitions.Fade
5 changes: 5 additions & 0 deletions .changeset/silver-penguins-walk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/native-ui": patch
---

Add largeLineHeight text variant
7 changes: 7 additions & 0 deletions .pnpmfile.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ function readPackage(pkg, context) {
So we are going to patch these until the maintainers fix their own stuff…
Feel free to make PRs if you feel like it :).
*/
/*
Remove react-native/react-dom from react-redux optional peer dependencies.
Without this, using react-redux code in LLM from LLC will fail because the package will get duplicated.
*/
removeDependencies("react-redux", ["react-native", "react-dom"], {
kind: "peerDependencies",
}),
/* Storybook packages */
addDependencies("@storybook/webpack-config", { "resolve-from": "*" }),
addDependencies("@storybook/addon-knobs", {
Expand Down
128 changes: 64 additions & 64 deletions apps/ledger-live-mobile/ios/Podfile.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React, { useCallback } from "react";
import { Flex, Icons, Tag, Text } from "@ledgerhq/native-ui";
import { useTranslation } from "react-i18next";
import { useNavigation } from "@react-navigation/native";
import {
PostOnboardingActionState,
PostOnboardingAction,
} from "@ledgerhq/types-live";
import Touchable from "../Touchable";
import { track } from "../../analytics";

export type Props = PostOnboardingAction & PostOnboardingActionState;

const PostOnboardingActionRow: React.FC<Props> = props => {
const {
navigationParams,
Icon,
title,
description,
tagLabel,
startEvent,
startEventProperties,
completed,
} = props;
const { t } = useTranslation();
const navigation = useNavigation();

const handlePress = useCallback(() => {
if (navigationParams) {
navigation.navigate(...navigationParams);
startEvent && track(startEvent, startEventProperties);
}
}, [navigationParams, navigation, startEvent, startEventProperties]);

return (
<Touchable onPress={completed ? null : handlePress}>
<Flex
flexDirection="row"
alignItems="center"
py={6}
justifyContent="space-between"
>
<Flex flexDirection="row" alignItems="center" flexShrink={1}>
<Icon size={24} color={completed ? "neutral.c70" : "primary.c80"} />
<Flex ml={6} flexDirection="column" justifyContent="center" flex={1}>
<Text
variant="largeLineHeight"
fontWeight="medium"
color={completed ? "neutral.c70" : "neutral.c100"}
>
{t(title)}
</Text>
<Text variant="body" fontWeight="medium" color="neutral.c70">
{t(description)}
</Text>
</Flex>
</Flex>
<Flex
flexDirection="row"
alignItems="center"
flexShrink={0}
flexGrow={1}
pl={6}
>
{tagLabel ? (
<Tag mr={6} size="medium" type="color" uppercase={false}>
{tagLabel}
</Tag>
) : null}
{completed ? (
<Icons.CheckAloneMedium color="success.c100" size={16} />
) : (
<Icons.ChevronRightMedium color="primary.c80" size={16} />
)}
</Flex>
</Flex>
</Touchable>
);
};

export default PostOnboardingActionRow;
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useCallback } from "react";
import { Flex, Icons, Text } from "@ledgerhq/native-ui";
import { useTranslation } from "react-i18next";
import { getDeviceModel } from "@ledgerhq/devices/lib/index";
import styled from "styled-components/native";
import { useDispatch, useSelector } from "react-redux";
import { usePostOnboardingEntryPointVisibleOnWallet } from "@ledgerhq/live-common/postOnboarding/hooks/index";
import { hidePostOnboardingWalletEntryPoint } from "@ledgerhq/live-common/postOnboarding/actions";
import { postOnboardingDeviceModelIdSelector } from "@ledgerhq/live-common/lib/postOnboarding/reducer";
import { useNavigateToPostOnboardingHubCallback } from "../../logic/postOnboarding/useNavigateToPostOnboardingHubCallback";
import Touchable from "../Touchable";
import darkPlaceholderImage from "../../images/illustration/Dark/_000_PLACEHOLDER.png";
import lightPlaceholderImage from "../../images/illustration/Light/_000_PLACEHOLDER.png";

const PlaceholderImage = styled.Image.attrs(p => ({
source:
p.theme.colors.type === "dark"
? darkPlaceholderImage
: lightPlaceholderImage,
resizeMode: "contain",
}))`
height: 100px;
width: 100px;
margin: 7px;
`;

const PostOnboardingEntryPointCard: React.FC<Record<string, never>> = () => {
const { t } = useTranslation();
const deviceModelId = useSelector(postOnboardingDeviceModelIdSelector);
const productName = deviceModelId
? getDeviceModel(deviceModelId)?.productName
: null;
const dispatch = useDispatch();
const openHub = useNavigateToPostOnboardingHubCallback();
const dismissCard = useCallback(() => {
dispatch(hidePostOnboardingWalletEntryPoint());
}, [dispatch]);
const visible = usePostOnboardingEntryPointVisibleOnWallet();
if (!visible) return null;
return (
<Touchable onPress={openHub}>
<Flex
flexDirection="row"
backgroundColor="neutral.c30" // TODO: when new wallet design is implemented, change to c20
borderRadius={2}
>
<Flex flexDirection="column" mx={6} my={7} flex={1}>
<Text
variant="subtitle"
fontWeight="semiBold"
color="neutral.c70"
mb={3}
flexShrink={1}
>
{t("postOnboarding.walletCard.title")}
</Text>
<Text variant="body" fontWeight="medium" flexShrink={1}>
{t("postOnboarding.walletCard.description", { productName })}
</Text>
</Flex>
<PlaceholderImage />
<Flex position="absolute" top={3} right={7}>
<Touchable onPress={dismissCard}>
<Flex borderRadius={20} p={2} backgroundColor="neutral.c40">
<Icons.CloseMedium />
</Flex>
</Touchable>
</Flex>
</Flex>
</Touchable>
);
};

export default PostOnboardingEntryPointCard;
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import PostBuyDeviceSetupNanoWallScreen from "../../screens/PostBuyDeviceSetupNa
import WalletConnectNavigator from "./WalletConnectNavigator";
import WalletConnectLiveAppNavigator from "./WalletConnectLiveAppNavigator";
import CustomImageNavigator from "./CustomImageNavigator";
import PostOnboardingNavigator from "./PostOnboardingNavigator";

import {
BleDevicePairingFlow,
Expand Down Expand Up @@ -630,6 +631,11 @@ export default function BaseNavigator() {
title: "",
}}
/>
<Stack.Screen
name={NavigatorName.PostOnboarding}
options={{ headerShown: false }}
component={PostOnboardingNavigator}
/>
</Stack.Navigator>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React, { useMemo } from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { useTheme } from "styled-components/native";

import { ScreenName } from "../../const";
import { getStackNavigatorConfig } from "../../navigation/navigatorConfig";

import { ParamList } from "../../screens/PostOnboarding/types";
import PostOnboardingDebugScreen from "../../screens/PostOnboarding/PostOnboardingDebugScreen";
import PostOnboardingHub from "../../screens/PostOnboarding/PostOnboardingHub";
import PostOnboardingMockActionScreen from "../../screens/PostOnboarding/PostOnboardingMockActionScreen";

const Stack = createStackNavigator<ParamList>();

const screenOptions = { headerShown: true, title: "", headerLeft: () => null };

const PostOnboardingNavigator = () => {
const { colors } = useTheme();
const stackNavigationConfig = useMemo(
() => getStackNavigatorConfig(colors, true),
[colors],
);

return (
<Stack.Navigator
screenOptions={{
...stackNavigationConfig,
headerShown: false,
}}
>
<Stack.Screen
name={ScreenName.PostOnboardingHub as "PostOnboardingHub"}
component={PostOnboardingHub}
options={screenOptions}
/>
<Stack.Screen
name={
ScreenName.PostOnboardingDebugScreen as "PostOnboardingDebugScreen"
}
component={PostOnboardingDebugScreen}
/>
<Stack.Screen
name={
ScreenName.PostOnboardingMockActionScreen as "PostOnboardingMockActionScreen"
}
component={PostOnboardingMockActionScreen}
options={screenOptions}
/>
</Stack.Navigator>
);
};

export default PostOnboardingNavigator;
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import { GenerateMockAccountSelectScreen } from "../../screens/Settings/Debug/Ge
import HiddenNftCollections from "../../screens/Settings/Accounts/HiddenNftCollections";
import { track } from "../../analytics";
import { useCurrentRouteName } from "../../helpers/routeHooks";
import PostOnboardingDebugScreen from "../../screens/PostOnboarding/PostOnboardingDebugScreen";

// TODO: types for each screens and navigators need to be set
export type SettingsNavigatorStackParamList = {
Expand Down Expand Up @@ -351,6 +352,10 @@ export default function SettingsNavigator() {
headerTitle: t("onboarding.stepLanguage.title"),
}}
/>
<Stack.Screen
name={ScreenName.PostOnboardingDebugScreen}
component={PostOnboardingDebugScreen}
/>
</Stack.Navigator>
);
}
6 changes: 6 additions & 0 deletions apps/ledger-live-mobile/src/const/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,10 @@ export const ScreenName = {
CustomImageStep2Preview: "CustomImageStep2Preview",
CustomImageStep3Transfer: "CustomImageStep3Transfer",
CustomImageErrorScreen: "CustomImageErrorScreen",

PostOnboardingHub: "PostOnboardingHub",
PostOnboardingDebugScreen: "PostOnboardingDebugScreen",
PostOnboardingMockActionScreen: "PostOnboardingMockActionScreen",
};
export const NavigatorName = {
// Stack
Expand Down Expand Up @@ -472,4 +476,6 @@ export const NavigatorName = {
CustomImage: "CustomImage",

WalletConnect: "WalletConnect",

PostOnboarding: "PostOnboarding",
};
17 changes: 16 additions & 1 deletion apps/ledger-live-mobile/src/context/LedgerStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ import React, { Component } from "react";
import { Provider } from "react-redux";
import thunk from "redux-thunk";
import { createStore, applyMiddleware, compose } from "redux";
import { getAccounts, getCountervalues, getSettings, getBle } from "../db";
import { importPostOnboardingState } from "@ledgerhq/live-common/postOnboarding/actions";
import {
getAccounts,
getCountervalues,
getSettings,
getBle,
getPostOnboardingState,
} from "../db";
import reducers from "../reducers";
import { importSettings } from "../actions/settings";
import { importStore as importAccounts } from "../actions/accounts";
Expand Down Expand Up @@ -61,6 +68,14 @@ export default class LedgerStoreProvider extends Component<
store.dispatch(importSettings(settingsData));
const accountsData = await getAccounts();
store.dispatch(importAccounts(accountsData));

const postOnboardingState = await getPostOnboardingState();
if (postOnboardingState) {
store.dispatch(
importPostOnboardingState({ newState: postOnboardingState }),
);
}

const initialCountervalues = await getCountervalues();
this.setState(
{
Expand Down
12 changes: 11 additions & 1 deletion apps/ledger-live-mobile/src/db.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { log } from "@ledgerhq/logs";
import { atomicQueue } from "@ledgerhq/live-common/promise";
import type { AccountRaw } from "@ledgerhq/types-live";
import type { AccountRaw, PostOnboardingState } from "@ledgerhq/types-live";
import type { CounterValuesStateRaw } from "@ledgerhq/live-common/countervalues/types";
import store from "./logic/storeWrapper";

Expand Down Expand Up @@ -243,3 +243,13 @@ async function migrateAccountsIfNecessary(): Promise<void> {
log("db", "done migrateAccountsIfNecessary");
}
}

export async function getPostOnboardingState(): Promise<any> {
return store.get("postOnboarding");
}

export async function savePostOnboardingState(
obj: PostOnboardingState,
): Promise<void> {
await store.save("postOnboarding", obj);
}
Loading

0 comments on commit 8465b5e

Please sign in to comment.