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

Backups V2 Follow-up Fixes / Improvements #6213

Merged
merged 53 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
c035b9f
remove useState that is getting wiped between renders
walmat Oct 18, 2024
ea2fd09
lots of provider structure changes
walmat Oct 19, 2024
3735f81
Merge branch 'develop' into @matthew/APP-1297
walmat Oct 25, 2024
4afed74
lots more progress on restructuring and code sharing
walmat Nov 6, 2024
fb913bc
more code quality improvements
walmat Nov 6, 2024
afc42bf
prevent App.tsx from re-rendering unless it needs to
walmat Nov 8, 2024
6946626
fix password not being pulled from local password keychain and add lo…
walmat Nov 8, 2024
9ea81dd
misc backups improvements
walmat Nov 8, 2024
fd16a13
Update .vscode/settings.json
walmat Nov 8, 2024
00d1bff
cleanup
walmat Nov 8, 2024
7016d47
Merge branch '@matthew/APP-1297' of https://github.com/rainbow-me/rai…
walmat Nov 8, 2024
5420054
fix lint
walmat Nov 11, 2024
c20670c
Merge branch 'develop' into @matthew/APP-1297
walmat Nov 14, 2024
5784cb2
fix overlay causing top leve re-renders
walmat Nov 14, 2024
0c81b5f
nav back to wallet screen on both new user restore / existing restore
walmat Nov 14, 2024
1fadaf5
convert cloud backup provider to zustand store, remove userData as it…
walmat Nov 16, 2024
a9948af
lots of cleanup
walmat Nov 18, 2024
5c5a848
add icon to indicate wrogn backup password
walmat Nov 18, 2024
6d7b6fa
simplify prompt to backup selected wallet
walmat Nov 18, 2024
9823919
more manual backup to cloud backup transitions
walmat Nov 18, 2024
7b18523
Update src/components/backup/RestoreCloudStep.tsx
walmat Nov 18, 2024
1f42ab9
reset backup provider to undefined if no condition is met
walmat Nov 18, 2024
466f3dc
adjust logic for displaying backed up status on Android when switchin…
walmat Nov 18, 2024
461ee79
more android tweaks
walmat Nov 18, 2024
053231c
more android fixes
walmat Nov 25, 2024
e1569fa
cleanup logs, prevent consolidatedTransactions when no address, and p…
walmat Nov 25, 2024
176cac6
prevent backups on wallets which are damaged
walmat Nov 25, 2024
11f079f
prevent portal overlay on pin authentication screen
walmat Nov 25, 2024
ebd631d
Merge branch 'develop' into @matthew/APP-1297
walmat Nov 25, 2024
25bb9c2
prevent copying address and more improvements to disabling backups if…
walmat Nov 25, 2024
664a035
i18n wallet loading states
walmat Nov 26, 2024
f550f68
fix lint
walmat Nov 26, 2024
3ccb2fb
fix lint
walmat Nov 26, 2024
e995093
Merge branch 'develop' into @matthew/APP-1297
walmat Nov 26, 2024
380103f
possibly fix the enable cloud backups on android
walmat Nov 27, 2024
d0fd2e3
fix button not being disabled and confetti (#6281)
walmat Nov 27, 2024
11fbc3c
[1297] - Prevent a few faceID prompts during restore / backup flow (#…
walmat Dec 3, 2024
109ca08
fix backup prompt seemingly being stuck (#6289)
walmat Dec 4, 2024
7dfd7e2
[1297] - Fix infinite sync (#6280)
walmat Dec 4, 2024
64d075b
fix: code review changes
walmat Dec 4, 2024
48c346a
prevent backup prompt from firing until backups status is synced
walmat Dec 4, 2024
515691b
replace inline flex with flatlist 3 column
walmat Dec 4, 2024
ee330be
fix non-visible wallets from appearing in backup section wallet addre…
walmat Dec 4, 2024
869a1fe
properly space items and calculate width based on device
walmat Dec 4, 2024
f9249f8
fix inconsistencies with keys
walmat Dec 4, 2024
308437a
fix lint
walmat Dec 6, 2024
7494991
add backup prompt to checks to avoid stacking sheets
walmat Dec 6, 2024
1b4e81f
add authentication in order to allow backup deletion
walmat Dec 6, 2024
1091d47
chore: merge
walmat Dec 11, 2024
fc5ee51
chore: merge
walmat Dec 19, 2024
6ccfad1
chore: merge
walmat Dec 19, 2024
1b149e9
fix botched merge
walmat Dec 20, 2024
ff305c6
remove unused imports
walmat Dec 20, 2024
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
34 changes: 23 additions & 11 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import '@/languages';
import * as Sentry from '@sentry/react-native';
import React, { useCallback, useEffect, useState } from 'react';
import React, { useCallback, useEffect, useState, memo } from 'react';
import { AppRegistry, Dimensions, LogBox, StyleSheet, View } from 'react-native';
import { Toaster } from 'sonner-native';
import { MobileWalletProtocolProvider } from '@coinbase/mobile-wallet-protocol-host';
Expand All @@ -9,7 +9,7 @@ import { useApplicationSetup } from '@/hooks/useApplicationSetup';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
import { enableScreens } from 'react-native-screens';
import { connect, Provider as ReduxProvider } from 'react-redux';
import { connect, Provider as ReduxProvider, shallowEqual } from 'react-redux';
import { RecoilRoot } from 'recoil';
import PortalConsumer from '@/components/PortalConsumer';
import ErrorBoundary from '@/components/error-boundary/ErrorBoundary';
Expand All @@ -22,7 +22,7 @@ import * as keychain from '@/model/keychain';
import { Navigation } from '@/navigation';
import { PersistQueryClientProvider, persistOptions, queryClient } from '@/react-query';
import store, { AppDispatch, type AppState } from '@/redux/store';
import { MainThemeProvider, useTheme } from '@/theme/ThemeContext';
import { MainThemeProvider } from '@/theme/ThemeContext';
import { addressKey } from '@/utils/keychainConstants';
import { SharedValuesProvider } from '@/helpers/SharedValuesContext';
import { InitialRouteContext } from '@/navigation/initialRoute';
Expand All @@ -42,7 +42,7 @@ import { Address } from 'viem';
import { IS_ANDROID, IS_DEV } from '@/env';
import { prefetchDefaultFavorites } from '@/resources/favorites';
import Routes from '@/navigation/Routes';
import { BackendNetworks } from '@/components/BackendNetworks';
import { BackupsSync } from '@/state/sync/BackupsSync';

if (IS_DEV) {
reactNativeDisableYellowBox && LogBox.ignoreAllLogs();
Expand Down Expand Up @@ -70,27 +70,39 @@ function App({ walletReady }: AppProps) {
}, []);

return (
<Portal>
<>
<View style={[sx.container, { paddingBottom: IS_ANDROID ? bottom : 0 }]}>
{initialRoute && (
<InitialRouteContext.Provider value={initialRoute}>
<Routes ref={handleNavigatorRef} />
<PortalConsumer />
</InitialRouteContext.Provider>
)}
<OfflineToast />
<Toaster />
</View>
<NotificationsHandler walletReady={walletReady} />
<DeeplinkHandler initialRoute={initialRoute} walletReady={walletReady} />
<BackendNetworks />
</Portal>
<Portal />
<PortalConsumer />
walmat marked this conversation as resolved.
Show resolved Hide resolved
<BackupsSync />
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In charge of initial backup store sync on mount

</>
);
}

const AppWithRedux = connect<AppProps, AppDispatch, AppProps, AppState>(state => ({
walletReady: state.appState.walletReady,
}))(App);
const AppWithRedux = connect<AppProps, AppDispatch, AppProps, AppState>(
state => ({
walletReady: state.appState.walletReady,
}),
null,
null,
{
areStatesEqual: (next, prev) => {
// Only update if walletReady actually changed
return next.appState.walletReady === prev.appState.walletReady;
},
areOwnPropsEqual: shallowEqual,
}
)(memo(App));
Comment on lines +89 to +102
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we only really want to re-render the App when walletReady has changed.. this fixes that


function Root() {
const [initializing, setInitializing] = useState(true);
Expand Down
10 changes: 5 additions & 5 deletions src/components/PortalConsumer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ import React, { useEffect } from 'react';
import { LoadingOverlay } from './modal';
import { useWallets } from '@/hooks';
import { sheetVerticalOffset } from '@/navigation/effects';
import { usePortal } from '@/react-native-cool-modals/Portal';
import { portalStore } from '@/state/portal/portal';

export default function PortalConsumer() {
const { isWalletLoading } = useWallets();
const { setComponent, hide } = usePortal();

useEffect(() => {
if (isWalletLoading) {
setComponent(<LoadingOverlay paddingTop={sheetVerticalOffset} title={isWalletLoading} />, true);
portalStore.getState().setComponent(<LoadingOverlay paddingTop={sheetVerticalOffset} title={isWalletLoading} />, true);
}
return hide;
}, [hide, isWalletLoading, setComponent]);
return portalStore.getState().hide;
}, [isWalletLoading]);

return null;
}
54 changes: 28 additions & 26 deletions src/components/backup/AddWalletToCloudBackupStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,40 @@ import { ButtonPressAnimation } from '../animations';
import Routes from '@/navigation/routesNames';
import { useNavigation } from '@/navigation';
import { useWallets } from '@/hooks';
import { WalletCountPerType, useVisibleWallets } from '@/screens/SettingsSheet/useVisibleWallets';
import { format } from 'date-fns';
import { useCreateBackup } from './useCreateBackup';
import { login } from '@/handlers/cloudBackup';
import { useCreateBackup } from '@/components/backup/useCreateBackup';
import { backupsStore } from '@/state/backups/backups';
import { executeFnIfCloudBackupAvailable } from '@/model/backup';

const imageSize = 72;

export default function AddWalletToCloudBackupStep() {
const { goBack } = useNavigation();
const { wallets, selectedWallet } = useWallets();
const { selectedWallet } = useWallets();
const createBackup = useCreateBackup();

const walletTypeCount: WalletCountPerType = {
phrase: 0,
privateKey: 0,
};

const { lastBackupDate } = useVisibleWallets({ wallets, walletTypeCount });

const { onSubmit } = useCreateBackup({
walletId: selectedWallet.id,
navigateToRoute: {
route: Routes.SETTINGS_SHEET,
params: {
screen: Routes.SETTINGS_SECTION_BACKUP,
},
},
});
const { mostRecentBackup } = backupsStore(state => ({
mostRecentBackup: state.mostRecentBackup,
}));

const potentiallyLoginAndSubmit = useCallback(async () => {
await login();
return onSubmit({});
}, [onSubmit]);
const result = await executeFnIfCloudBackupAvailable({
fn: () =>
createBackup({
walletId: selectedWallet.id,
navigateToRoute: {
route: Routes.SETTINGS_SHEET,
params: {
screen: Routes.SETTINGS_SECTION_BACKUP,
},
},
}),
});

if (result) {
goBack();
}
}, [createBackup, goBack, selectedWallet.id]);

const onMaybeLater = useCallback(() => goBack(), [goBack]);

Expand Down Expand Up @@ -70,7 +72,7 @@ export default function AddWalletToCloudBackupStep() {
<Separator color="separatorSecondary" thickness={1} />
</Bleed>

<ButtonPressAnimation scaleTo={0.95} onPress={() => potentiallyLoginAndSubmit().then(success => success && goBack())}>
<ButtonPressAnimation scaleTo={0.95} onPress={potentiallyLoginAndSubmit}>
<Box alignItems="center" justifyContent="center" paddingTop={'24px'} paddingBottom={'24px'}>
<Box alignItems="center" justifyContent="center" width="full">
<Inline alignHorizontal="justify" alignVertical="center" wrap={false}>
Expand Down Expand Up @@ -105,13 +107,13 @@ export default function AddWalletToCloudBackupStep() {
<Separator color="separatorSecondary" thickness={1} />
</Bleed>

{lastBackupDate && (
{mostRecentBackup && (
<Box alignItems="center" justifyContent="center" paddingTop={'24px'} paddingBottom={'24px'}>
<Box alignItems="center" justifyContent="center" width="full">
<Inline alignHorizontal="justify" alignVertical="center" wrap={false}>
<Text color={'labelTertiary'} size="15pt" weight="medium">
{lang.t(lang.l.back_up.cloud.latest_backup, {
date: format(lastBackupDate, "M/d/yy 'at' h:mm a"),
date: format(new Date(mostRecentBackup.lastModified), "M/d/yy 'at' h:mm a"),
})}
</Text>
</Inline>
Expand Down
81 changes: 20 additions & 61 deletions src/components/backup/BackupChooseProviderStep.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import { useCreateBackup } from '@/components/backup/useCreateBackup';
import { Bleed, Box, Inline, Inset, Separator, Stack, Text } from '@/design-system';
import * as lang from '@/languages';
import { ImgixImage } from '../images';
Expand All @@ -16,74 +15,34 @@ import { SETTINGS_BACKUP_ROUTES } from '@/screens/SettingsSheet/components/Backu
import { useWallets } from '@/hooks';
import walletTypes from '@/helpers/walletTypes';
import walletBackupTypes from '@/helpers/walletBackupTypes';
import { IS_ANDROID } from '@/env';
import { GoogleDriveUserData, getGoogleAccountUserData, isCloudBackupAvailable, login } from '@/handlers/cloudBackup';
import { WrappedAlert as Alert } from '@/helpers/alert';
import { RainbowError, logger } from '@/logger';
import { Linking } from 'react-native';
import { useCreateBackup } from '@/components/backup/useCreateBackup';
import { backupsStore, CloudBackupState } from '@/state/backups/backups';
import { executeFnIfCloudBackupAvailable } from '@/model/backup';

const imageSize = 72;

export default function BackupSheetSectionNoProvider() {
const { colors } = useTheme();
const { navigate, goBack } = useNavigation();
const { selectedWallet } = useWallets();
const createBackup = useCreateBackup();
const { status } = backupsStore(state => ({
status: state.status,
}));

const { onSubmit, loading } = useCreateBackup({
walletId: selectedWallet.id,
navigateToRoute: {
route: Routes.SETTINGS_SHEET,
params: {
screen: Routes.SETTINGS_SECTION_BACKUP,
},
},
});

const onCloudBackup = async () => {
if (loading !== 'none') {
return;
}
// NOTE: On Android we need to make sure the user is signed into a Google account before trying to backup
// otherwise we'll fake backup and it's confusing...
if (IS_ANDROID) {
try {
await login();
getGoogleAccountUserData().then((accountDetails: GoogleDriveUserData | undefined) => {
if (!accountDetails) {
Alert.alert(lang.t(lang.l.back_up.errors.no_account_found));
return;
}
});
} catch (e) {
logger.error(new RainbowError('[BackupSheetSectionNoProvider]: No account found'), {
error: e,
});
Alert.alert(lang.t(lang.l.back_up.errors.no_account_found));
}
} else {
const isAvailable = await isCloudBackupAvailable();
if (!isAvailable) {
Alert.alert(
lang.t(lang.l.modal.back_up.alerts.cloud_not_enabled.label),
lang.t(lang.l.modal.back_up.alerts.cloud_not_enabled.description),
[
{
onPress: () => {
Linking.openURL('https://support.apple.com/en-us/HT204025');
},
text: lang.t(lang.l.modal.back_up.alerts.cloud_not_enabled.show_me),
},
{
style: 'cancel',
text: lang.t(lang.l.modal.back_up.alerts.cloud_not_enabled.no_thanks),
const onCloudBackup = () => {
executeFnIfCloudBackupAvailable({
fn: () =>
createBackup({
walletId: selectedWallet.id,
navigateToRoute: {
route: Routes.SETTINGS_SHEET,
params: {
screen: Routes.SETTINGS_SECTION_BACKUP,
},
]
);
return;
}
}

onSubmit({});
},
}),
});
};

const onManualBackup = async () => {
Expand Down Expand Up @@ -117,7 +76,7 @@ export default function BackupSheetSectionNoProvider() {
</Bleed>

{/* replace this with BackUpMenuButton */}
<ButtonPressAnimation scaleTo={0.95} onPress={onCloudBackup}>
<ButtonPressAnimation disabled={status !== CloudBackupState.Ready} scaleTo={0.95} onPress={onCloudBackup}>
<Box alignItems="flex-start" justifyContent="flex-start" paddingTop={'24px'} paddingBottom={'36px'} gap={8}>
<Box justifyContent="center" width="full">
<Inline alignHorizontal="justify" alignVertical="center" wrap={false}>
Expand Down
27 changes: 12 additions & 15 deletions src/components/backup/BackupSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { SimpleSheet } from '@/components/sheet/SimpleSheet';
import AddWalletToCloudBackupStep from '@/components/backup/AddWalletToCloudBackupStep';
import BackupManuallyStep from './BackupManuallyStep';
import { getHeightForStep } from '@/navigation/config';
import { CloudBackupProvider } from './CloudBackupProvider';

type BackupSheetParams = {
BackupSheet: {
Expand Down Expand Up @@ -40,19 +39,17 @@ export default function BackupSheet() {
}, [step]);

return (
<CloudBackupProvider>
<BackgroundProvider color="surfaceSecondary">
{({ backgroundColor }) => (
<SimpleSheet
testID={'backup-sheet'}
backgroundColor={backgroundColor as string}
customHeight={getHeightForStep(step)}
scrollEnabled={false}
>
{renderStep()}
</SimpleSheet>
)}
</BackgroundProvider>
</CloudBackupProvider>
<BackgroundProvider color="surfaceSecondary">
{({ backgroundColor }) => (
<SimpleSheet
testID={'backup-sheet'}
backgroundColor={backgroundColor as string}
customHeight={getHeightForStep(step)}
scrollEnabled={false}
>
{renderStep()}
</SimpleSheet>
)}
</BackgroundProvider>
);
}
Loading
Loading