diff --git a/src/handlers/cloudBackup.ts b/src/handlers/cloudBackup.ts index 1a7b2a286d3..14347c42a75 100644 --- a/src/handlers/cloudBackup.ts +++ b/src/handlers/cloudBackup.ts @@ -73,7 +73,7 @@ export async function fetchAllBackups(): Promise { }); return { - files: files?.files?.filter((file: BackupFile) => file.name !== USERDATA_FILE) || [], + files: files?.files?.filter((file: BackupFile) => normalizeAndroidBackupFilename(file.name) !== USERDATA_FILE) || [], }; } diff --git a/src/hooks/useManageCloudBackups.ts b/src/hooks/useManageCloudBackups.ts index 1a50c8b079d..d5e6bc73f58 100644 --- a/src/hooks/useManageCloudBackups.ts +++ b/src/hooks/useManageCloudBackups.ts @@ -3,13 +3,19 @@ import lang from 'i18n-js'; import { useDispatch } from 'react-redux'; import { cloudPlatform } from '../utils/platform'; import { WrappedAlert as Alert } from '@/helpers/alert'; -import { GoogleDriveUserData, getGoogleAccountUserData, deleteAllBackups, logoutFromGoogleDrive } from '@/handlers/cloudBackup'; +import { + GoogleDriveUserData, + getGoogleAccountUserData, + deleteAllBackups, + logoutFromGoogleDrive as logout, + login, +} from '@/handlers/cloudBackup'; import { clearAllWalletsBackupStatus } from '@/redux/wallets'; import { showActionSheetWithOptions } from '@/utils'; import { IS_ANDROID } from '@/env'; import { RainbowError, logger } from '@/logger'; import * as i18n from '@/languages'; -import { backupsStore } from '@/state/backups/backups'; +import { backupsStore, CloudBackupState } from '@/state/backups/backups'; export default function useManageCloudBackups() { const dispatch = useDispatch(); @@ -49,8 +55,19 @@ export default function useManageCloudBackups() { await dispatch(clearAllWalletsBackupStatus()); }; + const logoutFromGoogleDrive = async () => { + await logout(); + backupsStore.setState({ + backupProvider: undefined, + backups: { files: [] }, + mostRecentBackup: undefined, + status: CloudBackupState.NotAvailable, + }); + }; + const loginToGoogleDrive = async () => { try { + await login(); const accountDetails = await getGoogleAccountUserData(); backupsStore.getState().syncAndFetchBackups(); setAccountDetails(accountDetails ?? undefined); diff --git a/src/model/backup.ts b/src/model/backup.ts index 7a1efac021d..8bef43d6347 100644 --- a/src/model/backup.ts +++ b/src/model/backup.ts @@ -10,6 +10,7 @@ import { getGoogleAccountUserData, login, logoutFromGoogleDrive, + normalizeAndroidBackupFilename, } from '@/handlers/cloudBackup'; import { Alert as NativeAlert } from '@/components/alerts'; import WalletBackupTypes from '../helpers/walletBackupTypes'; @@ -53,8 +54,9 @@ export interface BackupFile { } export const parseTimestampFromFilename = (filename: string) => { + const name = normalizeAndroidBackupFilename(filename); return Number( - filename + name .replace('.backup_', '') .replace('backup_', '') .replace('.json', '') diff --git a/src/react-native-cool-modals/Portal.tsx b/src/react-native-cool-modals/Portal.tsx index 8ab9a0d2c3f..4fadb8753ef 100644 --- a/src/react-native-cool-modals/Portal.tsx +++ b/src/react-native-cool-modals/Portal.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { IS_IOS } from '@/env'; import { portalStore } from '@/state/portal/portal'; -import { Platform, requireNativeComponent, StyleSheet, View } from 'react-native'; +import { requireNativeComponent, StyleSheet, View } from 'react-native'; const NativePortal = IS_IOS ? requireNativeComponent('WindowPortal') : View; const Wrapper = IS_IOS ? ({ children }: { children: React.ReactNode }) => children : View; @@ -35,7 +35,6 @@ export function Portal() { const sx = StyleSheet.create({ wrapper: { - zIndex: Number.MAX_SAFE_INTEGER, ...StyleSheet.absoluteFillObject, }, }); diff --git a/src/screens/SettingsSheet/components/Backups/WalletsAndBackup.tsx b/src/screens/SettingsSheet/components/Backups/WalletsAndBackup.tsx index 8d09b71c94c..57c61ecedcd 100644 --- a/src/screens/SettingsSheet/components/Backups/WalletsAndBackup.tsx +++ b/src/screens/SettingsSheet/components/Backups/WalletsAndBackup.tsx @@ -25,7 +25,6 @@ import { backupsCard } from '@/components/cards/utils/constants'; import { WalletCountPerType, useVisibleWallets } from '../../useVisibleWallets'; import { SETTINGS_BACKUP_ROUTES } from './routes'; import { RainbowAccount, createWallet } from '@/model/wallet'; -import { PROFILES, useExperimentalFlag } from '@/config'; import { useDispatch } from 'react-redux'; import { setIsWalletLoading, walletsLoadState } from '@/redux/wallets'; import { RainbowError, logger } from '@/logger'; @@ -193,6 +192,20 @@ export const WalletsAndBackup = () => { ); const { status: iconStatusType, text } = useMemo<{ status: StatusType; text: string }>(() => { + if (!backupProvider) { + if (!allBackedUp) { + return { + status: 'out-of-date', + text: 'Out of Date', + }; + } + + return { + status: 'up-to-date', + text: 'Up to date', + }; + } + if (status === CloudBackupState.FailedToInitialize || status === CloudBackupState.NotAvailable) { return { status: 'not-enabled', @@ -218,7 +231,7 @@ export const WalletsAndBackup = () => { status: 'up-to-date', text: 'Up to date', }; - }, [status, allBackedUp]); + }, [backupProvider, status, allBackedUp]); const renderView = useCallback(() => { switch (backupProvider) { @@ -256,14 +269,15 @@ export const WalletsAndBackup = () => { - {sortedWallets.map(({ id, name, backedUp, imported, addresses }) => { + {sortedWallets.map(({ id, name, backedUp, backupFile, backupType, imported, addresses }) => { + const isBackedUp = isWalletBackedUpForCurrentAccount({ backedUp, backupFile, backupType }); + return ( { } > - {!backedUp && ( + {!isBackedUp && ( { /> } - leftComponent={} + leftComponent={} onPress={() => onNavigateToWalletView(id, name)} size={60} titleComponent={} @@ -404,6 +418,7 @@ export const WalletsAndBackup = () => { {sortedWallets.map(({ id, name, backedUp, backupFile, backupType, imported, addresses }) => { const isBackedUp = isWalletBackedUpForCurrentAccount({ backedUp, backupFile, backupType }); + console.log('isBackedUp', isBackedUp); return ( diff --git a/src/screens/SettingsSheet/utils.ts b/src/screens/SettingsSheet/utils.ts index bd25ae11223..b92b5a8c4e3 100644 --- a/src/screens/SettingsSheet/utils.ts +++ b/src/screens/SettingsSheet/utils.ts @@ -7,7 +7,7 @@ import * as i18n from '@/languages'; import { cloudPlatform } from '@/utils/platform'; import { backupsStore, CloudBackupState } from '@/state/backups/backups'; import { RainbowWallet } from '@/model/wallet'; -import { IS_IOS } from '@/env'; +import { IS_ANDROID, IS_IOS } from '@/env'; import { normalizeAndroidBackupFilename } from '@/handlers/cloudBackup'; type WalletBackupStatus = { @@ -30,6 +30,26 @@ export const checkLocalWalletsForBackupStatus = (wallets: ReturnType( + (acc, wallet) => { + const isBackupEligible = wallet.type !== WalletTypes.readOnly && wallet.type !== WalletTypes.bluetooth; + const hasBackupFile = backupFiles.files.some( + file => normalizeAndroidBackupFilename(file.name) === normalizeAndroidBackupFilename(wallet.backupFile ?? '') + ); + + return { + allBackedUp: acc.allBackedUp && hasBackupFile && (wallet.backedUp || !isBackupEligible), + areBackedUp: acc.areBackedUp && hasBackupFile && (wallet.backedUp || !isBackupEligible), + canBeBackedUp: acc.canBeBackedUp || isBackupEligible, + }; + }, + { allBackedUp: true, areBackedUp: true, canBeBackedUp: false } + ); + } + return Object.values(wallets).reduce( (acc, wallet) => { const isBackupEligible = wallet.type !== WalletTypes.readOnly && wallet.type !== WalletTypes.bluetooth; @@ -81,7 +101,12 @@ export const titleForBackupState: Partial> = { }; export const isWalletBackedUpForCurrentAccount = ({ backupType, backedUp, backupFile }: Partial) => { - if (!backupType || !backedUp || !backupFile) { + console.log({ + backupType, + backedUp, + backupFile, + }); + if (!backupType || !backupFile) { return false; } @@ -89,6 +114,8 @@ export const isWalletBackedUpForCurrentAccount = ({ backupType, backedUp, backup return backedUp; } + console.log('backupFile', backupFile); + // NOTE: For Android, we also need to check if the current google account has the matching backup file if (!backupFile) { return false; diff --git a/src/state/backups/backups.ts b/src/state/backups/backups.ts index 74e34ec3cf3..a54a6e759fc 100644 --- a/src/state/backups/backups.ts +++ b/src/state/backups/backups.ts @@ -87,7 +87,7 @@ export const backupsStore = createRainbowStore((set, get) => ({ const gdata = await getGoogleAccountUserData(); if (!gdata) { logger.debug('[backupsStore]: Google account is not available'); - set({ status: CloudBackupState.NotAvailable }); + set({ status: CloudBackupState.NotAvailable, backups: { files: [] }, mostRecentBackup: undefined }); return { success: false, retry: false,