Skip to content

Commit

Permalink
feat(mobile): handle initial route, closes leather-io/issues#60
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranjamie committed Jun 25, 2024
1 parent 85240e1 commit 37c100b
Show file tree
Hide file tree
Showing 13 changed files with 96 additions and 66 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ dist
build
tsconfig.tsbuildinfo
.turbo/

# macOS
.DS_Store

leather-styles
**/.env
2 changes: 1 addition & 1 deletion .ls-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ls:
.ts: regex:[a-z0-9\-\._]+
.tsx: regex:[a-z0-9\-\._]+
.js: regex:[a-z0-9\-\._]+
.dir: regex:[a-z0-9\-\._]+
.dir: regex:[a-z0-9\(\)\-\._]+

ignore:
- .git
Expand Down
18 changes: 13 additions & 5 deletions apps/mobile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@ Leather is the most popular and trusted wallet for apps built on Bitcoin. And no

This app is an [Expo](https://expo.dev/) mobile application. So there are a few prerequisites to have installed on your computer before we can proceed.

You'll need to create a `.env` file to set which app mode the wallet runs in

```
# .env
# `prelaunch` or `live`
EXPO_PUBLIC_APP_START_MODE='prelaunch'
```

### Prerequisites

- [Node and NPM](https://nodejs.org/en/download)
- [Node and Pnpm](https://nodejs.org/en/download)
- [Watchman](https://facebook.github.io/watchman/docs/install#buildinstall) for MacOS and Linux users.
- `npm install` in the monorepo root folder.
- `pnpm i` in the monorepo root folder.

If you want to run this in an iOS simulator:

Expand All @@ -35,11 +43,11 @@ Running on Android device

### Running the application

- `npm run start` if you want to test the app on your personal Android or iOS device
- `pnpm run start` if you want to test the app on your personal Android or iOS device

- `npm run ios` if you want to run it on iOS simulator
- `pnpm run ios` if you want to run it on iOS simulator

- `npm run android` if you want to run it on Android emulator
- `pnpm run android` if you want to run it on Android emulator

## License

Expand Down
23 changes: 18 additions & 5 deletions apps/mobile/src/app/(home)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
import { SafeAreaView } from 'react-native';

import { router } from 'expo-router';
import { AppStartMode, whenAppStartMode } from '@/utils/when-app-start-mode';
import { Redirect, useRouter } from 'expo-router';

import { Button } from '@leather-wallet/ui/native';
import { Button } from '@leather.io/ui/native';

let hasRun = false;

const startRoute = whenAppStartMode(process.env.EXPO_PUBLIC_APP_START_MODE as AppStartMode)({
live: '/',
prelaunch: '/waiting-list',
});

export default function Home() {
const router = useRouter();

if (process.env.EXPO_PUBLIC_APP_START_MODE && !hasRun) {
hasRun = true;
return <Redirect href={startRoute} />;
}

return (
<SafeAreaView>
<Button
Expand All @@ -18,9 +33,7 @@ export default function Home() {
<Button
variant="solid"
label="Go to start page"
onPress={() => {
router.replace('/waiting-list');
}}
onPress={() => router.replace('/waiting-list')}
/>
</SafeAreaView>
);
Expand Down
36 changes: 8 additions & 28 deletions apps/mobile/src/app/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useState } from 'react';
import { StatusBar } from 'react-native';

import { LeatherSplash } from '@/components/animations/leather-splash';
import { SplashScreenGuard } from '@/components/splash-screen-guard/splash-screen-guard';
import { initiateI18n } from '@/i18n';
import { queryClient } from '@/queries/query';
import { usePersistedStore, useProtectedStore } from '@/state';
Expand All @@ -19,7 +18,7 @@ void SplashScreen.preventAutoHideAsync();
export { ErrorBoundary } from 'expo-router';

// Ensure that reloading on `/modal` keeps a back button present
export const unstable_settings = { initialRouteName: 'waiting-list/index' };
export const unstable_settings = { initialRouteName: '/' };

initiateI18n();

Expand All @@ -41,39 +40,20 @@ export default function RootLayout() {
<I18nProvider i18n={i18n}>
<QueryClientProvider client={queryClient}>
<ThemeProvider>
<AppWithNavigation />
<SplashScreenGuard>
<AppRouter />
</SplashScreenGuard>
</ThemeProvider>
</QueryClientProvider>
</I18nProvider>
);
}

// interface SplashScreenContainerProps {
// children: React.ReactNode;
// }
// function SplashScreenContainer({ children }: SplashScreenContainerProps) {

// }

function AppWithNavigation() {
const [animationFinished, setAnimationFinished] = useState(false);

if (!animationFinished) {
return (
<Box backgroundColor="base.ink.component-background-default" flex={1}>
<LeatherSplash onAnimationEnd={() => setAnimationFinished(true)} />
</Box>
);
}

const bg = !animationFinished
? 'base.ink.component-background-default'
: 'dark.ink.background-secondary';

function AppRouter() {
return (
<Box backgroundColor={bg} flex={1}>
<Box backgroundColor="dark.ink.background-secondary" flex={1}>
<StatusBar barStyle="light-content" />
<Slot initialRouteName="waiting-list/index" />
<Slot />
</Box>
);
}
2 changes: 1 addition & 1 deletion apps/mobile/src/app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Stack } from 'expo-router';

export function Root() {
return <Stack initialRouteName="waiting-list/index" />;
return <Stack />;
}
6 changes: 3 additions & 3 deletions apps/mobile/src/app/waiting-list/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useRouter } from 'expo-router';

import { WaitingList as WaitingListLayout } from './waiting-list-layout';
import { WaitingList } from './waiting-list';

export default function WaitingList() {
export default function WaitingListPage() {
const router = useRouter();
return <WaitingListLayout onHiddenPressAction={() => router.replace('/')} />;
return <WaitingList onHiddenPressAction={() => router.replace('/')} />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useState } from 'react';

import { Box } from '@leather.io/ui/native';

import { LeatherSplash } from '../animations/leather-splash';

interface SplashScreenGuardProps {
children: React.ReactNode;
}
export function SplashScreenGuard({ children }: SplashScreenGuardProps) {
const [animationFinished, setAnimationFinished] = useState(false);

if (!animationFinished) {
return (
<Box backgroundColor="base.ink.component-background-default" flex={1}>
<LeatherSplash onAnimationEnd={() => setAnimationFinished(true)} />
</Box>
);
}

return children;
}
16 changes: 8 additions & 8 deletions apps/mobile/src/locales/en/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,34 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"

#: src/components/welcome-screen/index.tsx:327
#: src/app/waiting-list/waiting-list.tsx:330
msgid "<0><1>Bitcoin for</1></0><2><3>the rest of us</3></2>"
msgstr "<0><1>Bitcoin for</1></0><2><3>the rest of us</3></2>"

#: src/components/welcome-screen/index.tsx:252
#: src/app/waiting-list/waiting-list.tsx:255
msgid "Done"
msgstr "Done"

#: src/components/welcome-screen/index.tsx:286
#: src/app/waiting-list/waiting-list.tsx:289
msgid "Email address"
msgstr "Email address"

#: src/components/welcome-screen/index.tsx:240
#: src/app/waiting-list/waiting-list.tsx:243
msgid "Follow us"
msgstr "Follow us"

#: src/components/welcome-screen/index.tsx:341
#: src/app/waiting-list/waiting-list.tsx:344
msgid "Leather is the only wallet you need to tap into the multilayered Bitcoin economy"
msgstr "Leather is the only wallet you need to tap into the multilayered Bitcoin economy"

#: src/components/welcome-screen/index.tsx:261
#: src/app/waiting-list/waiting-list.tsx:264
msgid "Stay in the loop and be the first one to hear about new developments"
msgstr "Stay in the loop and be the first one to hear about new developments"

#: src/components/welcome-screen/index.tsx:296
#: src/app/waiting-list/waiting-list.tsx:299
msgid "Submit"
msgstr "Submit"

#: src/components/welcome-screen/index.tsx:226
#: src/app/waiting-list/waiting-list.tsx:229
msgid "Thanks for subscribing! We'll notify you when Leather's mobile app launches. In the meantime, please <0>check out our browser extension.</0>"
msgstr "Thanks for subscribing! We'll notify you when Leather's mobile app launches. In the meantime, please <0>check out our browser extension.</0>"
16 changes: 8 additions & 8 deletions apps/mobile/src/locales/pseudo-locale/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,34 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"

#: src/components/welcome-screen/index.tsx:327
#: src/app/waiting-list/waiting-list.tsx:330
msgid "<0><1>Bitcoin for</1></0><2><3>the rest of us</3></2>"
msgstr ""

#: src/components/welcome-screen/index.tsx:252
#: src/app/waiting-list/waiting-list.tsx:255
msgid "Done"
msgstr ""

#: src/components/welcome-screen/index.tsx:286
#: src/app/waiting-list/waiting-list.tsx:289
msgid "Email address"
msgstr ""

#: src/components/welcome-screen/index.tsx:240
#: src/app/waiting-list/waiting-list.tsx:243
msgid "Follow us"
msgstr ""

#: src/components/welcome-screen/index.tsx:341
#: src/app/waiting-list/waiting-list.tsx:344
msgid "Leather is the only wallet you need to tap into the multilayered Bitcoin economy"
msgstr ""

#: src/components/welcome-screen/index.tsx:261
#: src/app/waiting-list/waiting-list.tsx:264
msgid "Stay in the loop and be the first one to hear about new developments"
msgstr ""

#: src/components/welcome-screen/index.tsx:296
#: src/app/waiting-list/waiting-list.tsx:299
msgid "Submit"
msgstr ""

#: src/components/welcome-screen/index.tsx:226
#: src/app/waiting-list/waiting-list.tsx:229
msgid "Thanks for subscribing! We'll notify you when Leather's mobile app launches. In the meantime, please <0>check out our browser extension.</0>"
msgstr ""
12 changes: 12 additions & 0 deletions apps/mobile/src/utils/when-app-start-mode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const appStartModes = ['prelaunch', 'live'] as const;

export type AppStartMode = (typeof appStartModes)[number];

type AppStartModeMap<T = any> = Record<AppStartMode, T>;

export function whenAppStartMode<K extends AppStartMode>(mode: K) {
if (!appStartModes.includes(mode))
throw new Error('App start mode must be one of: ' + appStartModes.join(', '));

return <M extends AppStartModeMap>(appStartModeMap: M): M[K] => appStartModeMap[mode];
}
6 changes: 1 addition & 5 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,7 @@
"typecheck": "tsc --noEmit --project ./tsconfig.json"
},
"exports": {
".": {
"types": "./dist-all/web.d.ts",
"import": "./dist-all/web.js",
"require": "./dist-all/web.js"
},
".": "./dist-all/web.js",
"./native": "./dist-native/native.js"
},
"dependencies": {
Expand Down

0 comments on commit 37c100b

Please sign in to comment.