Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onboarding: revive ready login #4340

Merged
merged 38 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
76133c1
basic wait screen redirect for logging into paused/suspended node
latter-bolden Jan 8, 2025
7e8c0f8
move analytics events to domain logic
latter-bolden Jan 9, 2025
4f2c14b
Merge branch 'develop' into lb/robust-login
latter-bolden Jan 9, 2025
63492d2
more spots
latter-bolden Jan 9, 2025
a85ea95
move hosting key values over to new system
latter-bolden Jan 9, 2025
df6c9ed
move hosting api to shared, types to domain
latter-bolden Jan 9, 2025
955e07d
Merge branch 'develop' into lb/robust-login
latter-bolden Jan 13, 2025
b24d857
fix import
latter-bolden Jan 13, 2025
f600967
stash
latter-bolden Jan 13, 2025
db1cca8
finish refactoring, use extracted methods across OTP, Legacy, and Get…
latter-bolden Jan 13, 2025
36b0a20
remove dead code
latter-bolden Jan 13, 2025
c324012
Merge branch 'develop' into lb/robust-login
latter-bolden Jan 13, 2025
90ff0b1
cleanup
latter-bolden Jan 13, 2025
f91cfe3
move more logic over to hostingActions, better analytic sevent capture
latter-bolden Jan 14, 2025
3176a04
handle maintenance conditions
latter-bolden Jan 14, 2025
55441f0
fix up RequestPhoneVerify & CheckVerify
latter-bolden Jan 14, 2025
ec50759
fix detecting needs phone verification from hosting user
latter-bolden Jan 15, 2025
8f2e9de
new initial onboarding CheckState screen + check for stopped node whi…
latter-bolden Jan 15, 2025
d9f9cc4
polish visuals for GettingNodeReady screen
latter-bolden Jan 15, 2025
25e8e9e
remove dev logs
latter-bolden Jan 15, 2025
0bf946d
cleanup comments & dead code
latter-bolden Jan 15, 2025
4dd49a0
hide benefits sheet bricking app for now
latter-bolden Jan 15, 2025
4b6a576
little more cleanup
latter-bolden Jan 15, 2025
421966d
fix signup param name
latter-bolden Jan 15, 2025
fe3f8d6
smuggle
latter-bolden Jan 16, 2025
1e0f965
disable onboarding session revival for now, less essential now that w…
latter-bolden Jan 17, 2025
5cf6350
Merge branch 'develop' into lb/robust-login
latter-bolden Jan 17, 2025
294b503
actually avoiding key wipe and explicitly setting cookie works
latter-bolden Jan 17, 2025
dd982f1
logging adjustments
latter-bolden Jan 17, 2025
3aadded
Merge branch 'develop' into lb/robust-login
latter-bolden Jan 17, 2025
1495d10
fix fixture types
latter-bolden Jan 17, 2025
a6129e1
fix has signup session revive
latter-bolden Jan 17, 2025
1bd20a4
remove stored native cookie
latter-bolden Jan 17, 2025
316da0c
show benefits sheet, issue was not related to this branch
latter-bolden Jan 17, 2025
74768e6
Merge branch 'develop' into lb/robust-login
latter-bolden Jan 17, 2025
de8d726
Merge branch 'develop' into lb/robust-login
latter-bolden Jan 17, 2025
46f3ea2
address Hunter feedback
latter-bolden Jan 17, 2025
7f6135b
always show logout button on wait screen
latter-bolden Jan 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/tlon-mobile/ios/Landscape/Supporting/Expo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<key>EXUpdatesLaunchWaitMs</key>
<integer>0</integer>
<key>EXUpdatesRuntimeVersion</key>
<string>4.0.1</string>
<string>4.0.2</string>
<key>EXUpdatesURL</key>
<string>https://u.expo.dev/617bb643-5bf6-4c40-8af6-c6e9dd7e3bd0</string>
</dict>
Expand Down
2 changes: 1 addition & 1 deletion apps/tlon-mobile/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1889,7 +1889,7 @@ SPEC CHECKSUMS:
sqlite3: f163dbbb7aa3339ad8fc622782c2d9d7b72f7e9c
tentap: 2cf2e387dd284bf867010eb7d0f91618fb35b673
UMAppLoader: 5df85360d65cabaef544be5424ac64672e648482
Yoga: 4dbfeceb9bb0f62899d0a53d37a1ddd58898d3f2
Yoga: fb61b2337c7688c81a137e5560b3cbb515289f91

PODFILE CHECKSUM: 0cb7a78e5777e69c86c1bf4bb5135fd660376dbe

Expand Down
28 changes: 22 additions & 6 deletions apps/tlon-mobile/src/App.main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { useAsyncStorageDevTools } from '@dev-plugins/async-storage';
import { useReactNavigationDevTools } from '@dev-plugins/react-navigation';
import { useReactQueryDevTools } from '@dev-plugins/react-query';
import NetInfo from '@react-native-community/netinfo';
import crashlytics from '@react-native-firebase/crashlytics';
import {
DarkTheme,
DefaultTheme,
Expand All @@ -15,12 +14,11 @@ import { BranchProvider } from '@tloncorp/app/contexts/branch';
import { ShipProvider, useShip } from '@tloncorp/app/contexts/ship';
import { useIsDarkMode } from '@tloncorp/app/hooks/useIsDarkMode';
import { useMigrations } from '@tloncorp/app/lib/nativeDb';
import { PlatformState } from '@tloncorp/app/lib/platformHelpers';
import { Provider as TamaguiProvider } from '@tloncorp/app/provider';
import { FeatureFlagConnectedInstrumentationProvider } from '@tloncorp/app/utils/perf';
import { posthogAsync } from '@tloncorp/app/utils/posthog';
import { QueryClientProvider, queryClient } from '@tloncorp/shared/api';
import { finishingSelfHostedLogin as selfHostedLoginStatus } from '@tloncorp/shared/db';
import * as db from '@tloncorp/shared/db';
import {
LoadingSpinner,
PortalProvider,
Expand All @@ -46,7 +44,11 @@ const App = () => {
const { isLoading, isAuthenticated } = useShip();
const [connected, setConnected] = useState(true);
const signupContext = useSignupContext();
const finishingSelfHostedLogin = selfHostedLoginStatus.useValue();

const finishingSelfHostedLogin = db.finishingSelfHostedLogin.useValue();
const haveHostedLogin = db.haveHostedLogin.useValue();
const hostedAccountInitialized = db.hostedAccountIsInitialized.useValue();
const hostedNodeRunning = db.hostedNodeIsRunning.useValue();

const currentlyOnboarding = useMemo(() => {
return signupContext.email || signupContext.phoneNumber;
Expand All @@ -67,10 +69,24 @@ const App = () => {
}, []);

const showAuthenticatedApp = useMemo(() => {
const blockedOnSignup = currentlyOnboarding;
const blockedOnLoginHosted =
haveHostedLogin && (!hostedAccountInitialized || !hostedNodeRunning);
const blockedOnLoginSelfHosted = finishingSelfHostedLogin;
latter-bolden marked this conversation as resolved.
Show resolved Hide resolved
return (
isAuthenticated && !(currentlyOnboarding || finishingSelfHostedLogin)
isAuthenticated &&
!blockedOnSignup &&
!blockedOnLoginHosted &&
!blockedOnLoginSelfHosted
);
}, [isAuthenticated, currentlyOnboarding, finishingSelfHostedLogin]);
}, [
currentlyOnboarding,
haveHostedLogin,
hostedAccountInitialized,
hostedNodeRunning,
finishingSelfHostedLogin,
isAuthenticated,
]);

return (
<View height={'100%'} width={'100%'} backgroundColor="$background">
Expand Down
21 changes: 17 additions & 4 deletions apps/tlon-mobile/src/OnboardingStack.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { useScreenOptions } from '@tloncorp/app/hooks/useScreenOptions';

import { useReviveSavedOnboarding } from './hooks/useReviveSavedOnboarding';
import { CheckOTPScreen } from './screens/Onboarding/CheckOTPScreen';
import { CheckVerifyScreen } from './screens/Onboarding/CheckVerifyScreen';
import { EULAScreen } from './screens/Onboarding/EULAScreen';
import { GettingNodeReadyScreen } from './screens/Onboarding/GettingNodeReadyScreen';
import { InitialStateCheckScreen } from './screens/Onboarding/InitialStateCheckScreen';
import { InventoryCheckScreen } from './screens/Onboarding/InventoryCheckScreen';
import { JoinWaitListScreen } from './screens/Onboarding/JoinWaitListScreen';
import { PasteInviteLinkScreen } from './screens/Onboarding/PasteInviteLinkScreen';
Expand All @@ -17,6 +18,7 @@ import { ShipLoginScreen } from './screens/Onboarding/ShipLoginScreen';
import { SignupScreen } from './screens/Onboarding/SignupScreen';
import { TlonLoginScreen } from './screens/Onboarding/TlonLogin';
import { TlonLoginLegacy } from './screens/Onboarding/TlonLoginLegacy';
import { UnderMaintenanceScreen } from './screens/Onboarding/UnderMaintenance';
import { WelcomeScreen } from './screens/Onboarding/WelcomeScreen';
import type { OnboardingStackParamList } from './types';

Expand All @@ -31,16 +33,19 @@ export function OnboardingStack() {
headerShown: false,
};

useReviveSavedOnboarding();

return (
<OnboardingStackNavigator.Navigator
initialRouteName="Welcome"
initialRouteName="InitialStateCheck"
screenOptions={onboardingScreenOptions}
>
<OnboardingStackNavigator.Screen
name="InitialStateCheck"
component={InitialStateCheckScreen}
/>
<OnboardingStackNavigator.Screen
name="Welcome"
component={WelcomeScreen}
options={{ animation: 'none', gestureEnabled: false }}
/>
<OnboardingStackNavigator.Screen name="Signup" component={SignupScreen} />
<OnboardingStackNavigator.Screen
Expand Down Expand Up @@ -97,6 +102,14 @@ export function OnboardingStack() {
name="ResetPassword"
component={ResetPasswordScreen}
/>
<OnboardingStackNavigator.Screen
name="GettingNodeReadyScreen"
component={GettingNodeReadyScreen}
/>
<OnboardingStackNavigator.Screen
name="UnderMaintenance"
component={UnderMaintenanceScreen}
/>
</OnboardingStackNavigator.Navigator>
);
}
11 changes: 10 additions & 1 deletion apps/tlon-mobile/src/components/AuthenticatedApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ import { useUpdatePresentedNotifications } from '@tloncorp/app/lib/notifications
import { RootStack } from '@tloncorp/app/navigation/RootStack';
import { AppDataProvider } from '@tloncorp/app/provider/AppDataProvider';
import { sync } from '@tloncorp/shared';
import * as db from '@tloncorp/shared/db';
import { PortalProvider, ZStack } from '@tloncorp/ui';
import { useCallback, useEffect, useState } from 'react';
import { AppStateStatus } from 'react-native';

import { useCheckAppUpdated } from '../hooks/analytics';
import { useCheckNodeStopped } from '../hooks/useCheckNodeStopped';
import { useDeepLinkListener } from '../hooks/useDeepLinkListener';
import useNotificationListener from '../hooks/useNotificationListener';

function AuthenticatedApp() {
const telemetry = useTelemetry();
const checkNodeStopped = useCheckNodeStopped();
useNotificationListener();
useUpdatePresentedNotifications();
useDeepLinkListener();
Expand All @@ -34,13 +37,19 @@ function AuthenticatedApp() {
sync.syncUnreads({ priority: sync.SyncPriority.High });
sync.syncPinnedItems({ priority: sync.SyncPriority.High });
telemetry.captureAppActive();
checkNodeStopped();
}
},
[telemetry]
[checkNodeStopped, telemetry]
);

useAppStatusChange(handleAppStatusChange);

useEffect(() => {
// reset this anytime we get back into the authenticated app
db.nodeStoppedWhileLoggedIn.setValue(false);
}, []);

return (
<ZStack flex={1}>
<RootStack />
Expand Down
20 changes: 9 additions & 11 deletions apps/tlon-mobile/src/fixtures/Onboarding.fixture.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NavigationContainer } from '@react-navigation/native';
import { Context as BranchContext } from '@tloncorp/app/contexts/branch';
import { exampleContacts } from '@tloncorp/app/fixtures/contentHelpers';
import { group } from '@tloncorp/app/fixtures/fakeData';
import { Context as BranchContext } from '@tloncorp/app/contexts/branch';
import { AppInvite, QueryClientProvider, queryClient } from '@tloncorp/shared';
import { Theme } from '@tloncorp/ui';
import { PropsWithChildren, useState } from 'react';
Expand All @@ -12,6 +12,7 @@ import { OnboardingProvider } from '../lib/OnboardingContext';
import { CheckOTPScreen } from '../screens/Onboarding/CheckOTPScreen';
import { CheckVerifyScreen } from '../screens/Onboarding/CheckVerifyScreen';
import { EULAScreen } from '../screens/Onboarding/EULAScreen';
import { GettingNodeReadyScreen } from '../screens/Onboarding/GettingNodeReadyScreen';
import { InventoryCheckScreen } from '../screens/Onboarding/InventoryCheckScreen';
import { JoinWaitListScreen } from '../screens/Onboarding/JoinWaitListScreen';
import { PasteInviteLinkScreen } from '../screens/Onboarding/PasteInviteLinkScreen';
Expand Down Expand Up @@ -81,11 +82,6 @@ function OnboardingFixture({
]),
getShipAccessCode: async () => Promise.resolve({ code: 'xyz' }),
allocateReservedShip: async () => Promise.resolve({}),
getShipsWithStatus: async () =>
Promise.resolve({
shipId: '~solfer-magfed',
status: 'Ready',
}),
reserveShip: async () =>
Promise.resolve({
id: '~solfer-magfed',
Expand Down Expand Up @@ -156,7 +152,6 @@ export default {
Nickname: (
<SingleScreenFixture
routeName="SetNickname"
params={{ user: sampleUser }}
Component={SetNicknameScreen}
/>
),
Expand All @@ -171,28 +166,24 @@ export default {
<SingleScreenFixture
routeName="RequestPhoneVerify"
Component={RequestPhoneVerifyScreen}
params={{ user: sampleUser }}
/>
),
CheckVerify: (
<SingleScreenFixture
routeName="CheckVerify"
Component={CheckVerifyScreen}
params={{ user: sampleUser }}
/>
),
ReserveShip: (
<SingleScreenFixture
routeName="ReserveShip"
Component={ReserveShipScreen}
params={{ user: sampleUser }}
/>
),
SetNickname: (
<SingleScreenFixture
routeName="SetNickname"
Component={SetNicknameScreen}
params={{ user: sampleUser }}
/>
),
SetTelemetry: (
Expand Down Expand Up @@ -239,4 +230,11 @@ export default {
ShipLogin: (
<SingleScreenFixture routeName={'ShipLogin'} Component={ShipLoginScreen} />
),
GettingNodeReady: (
<SingleScreenFixture
routeName={'GettingNodeReadyScreen'}
Component={GettingNodeReadyScreen}
params={{ waitType: 'Paused', wasLoggedIn: true }}
/>
),
};
42 changes: 42 additions & 0 deletions apps/tlon-mobile/src/hooks/useCheckNodeStopped.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useShip } from '@tloncorp/app/contexts/ship';
import { HostedNodeStatus } from '@tloncorp/shared';
import * as db from '@tloncorp/shared/db';
import { useStore } from '@tloncorp/ui';
import { useCallback } from 'react';

export function useCheckNodeStopped() {
const store = useStore();
const { clearShip } = useShip();
const checkNodeStopped = useCallback(async () => {
const hostedUserNodeId = await db.hostedUserNodeId.getValue();
const hostedUserId = await db.hostingUserId.getValue();
const hostedAccountIsInitialized =
await db.hostedAccountIsInitialized.getValue();

if (!hostedUserNodeId || !hostedUserId || !hostedAccountIsInitialized) {
// cannot enable node status check unless you logged in after receiving the "robust login" update
return;
}

try {
const nodeStatus = await store.checkHostingNodeStatus();
if (
[
HostedNodeStatus.Paused,
HostedNodeStatus.Suspended,
HostedNodeStatus.UnderMaintenance,
].includes(nodeStatus)
) {
// track that the node was stopped while logged in
await db.nodeStoppedWhileLoggedIn.setValue(true);

// delete Urbit auth and without clearing hosting auth, kick back to unauthenticated view
clearShip();
}
} catch (e) {
// fall through
}
}, [clearShip, store]);

return checkNodeStopped;
}
Loading
Loading