From ee3a68568ab1a16f977f85dd9d84f538fd8acf09 Mon Sep 17 00:00:00 2001 From: Philipp Walter Date: Thu, 9 Jan 2025 14:14:24 +0100 Subject: [PATCH] fix(restore): backup intro screens seen --- __tests__/todos.ts | 2 +- src/components/Suggestions.tsx | 4 ++-- .../bottom-sheet/QuickPayPrompt.tsx | 10 ++++----- src/screens/Activity/ActivitySavings.tsx | 6 ++---- src/screens/Activity/ActivitySpending.tsx | 2 +- src/screens/Onboarding/RestoreFromSeed.tsx | 5 +++-- src/screens/Settings/Backup/BackupPrompt.tsx | 16 +++++++------- src/screens/Settings/Backup/Success.tsx | 2 +- src/screens/Settings/General/index.tsx | 2 +- .../Settings/Quickpay/QuickpayIntro.tsx | 4 ++-- src/screens/Transfer/Funding.tsx | 6 ++---- src/screens/Transfer/SavingsIntro.tsx | 4 ++-- src/screens/Transfer/SpendingIntro.tsx | 4 ++-- src/screens/Transfer/TransferIntro.tsx | 4 ++-- src/store/index.ts | 2 +- src/store/migrations/index.ts | 13 ++++++++++++ src/store/reselect/settings.ts | 16 ++++++++++++++ src/store/reselect/todos.ts | 7 ++----- src/store/reselect/user.ts | 21 ------------------- src/store/shapes/settings.ts | 5 +++++ src/store/slices/settings.ts | 9 ++++++++ src/store/slices/user.ts | 16 ++------------ 22 files changed, 81 insertions(+), 79 deletions(-) diff --git a/__tests__/todos.ts b/__tests__/todos.ts index 4364c5956..43a300995 100644 --- a/__tests__/todos.ts +++ b/__tests__/todos.ts @@ -67,7 +67,7 @@ describe('Todos selector', () => { it('should not return backupSeedPhraseTodo if backup is verified', () => { const state = cloneDeep(s); - state.user.backupVerified = true; + state.settings.backupVerified = true; expect(todosFullSelector(state)).not.toEqual( expect.arrayContaining([backupSeedPhraseTodo]), diff --git a/src/components/Suggestions.tsx b/src/components/Suggestions.tsx index 7d70caa1b..bf010669c 100644 --- a/src/components/Suggestions.tsx +++ b/src/components/Suggestions.tsx @@ -16,11 +16,11 @@ import SuggestionCard from './SuggestionCard'; import { ITodo, TTodoType } from '../store/types/todos'; import { channelsNotificationsShown, hideTodo } from '../store/slices/todos'; import { showBottomSheet } from '../store/utils/ui'; -import { pinSelector } from '../store/reselect/settings'; import { + pinSelector, quickpayIntroSeenSelector, transferIntroSeenSelector, -} from '../store/reselect/user'; +} from '../store/reselect/settings'; import { newChannelsNotificationsSelector, todosFullSelector, diff --git a/src/navigation/bottom-sheet/QuickPayPrompt.tsx b/src/navigation/bottom-sheet/QuickPayPrompt.tsx index 90933bb99..2c4bf09e0 100644 --- a/src/navigation/bottom-sheet/QuickPayPrompt.tsx +++ b/src/navigation/bottom-sheet/QuickPayPrompt.tsx @@ -14,10 +14,10 @@ import { useSnapPoints, } from '../../hooks/bottomSheet'; import { closeSheet } from '../../store/slices/ui'; -import { updateUser } from '../../store/slices/user'; +import { updateSettings } from '../../store/slices/settings'; import { showBottomSheet } from '../../store/utils/ui'; import { viewControllersSelector } from '../../store/reselect/ui'; -import { quickpayIntroSeenSelector } from '../../store/reselect/user'; +import { quickpayIntroSeenSelector } from '../../store/reselect/settings'; import { RootNavigationProp } from '../types'; const imageSrc = require('../../assets/illustrations/fast-forward.png'); @@ -72,12 +72,12 @@ const QuickPayPrompt = ({ enabled }: { enabled: boolean }): ReactElement => { const onMore = (): void => { navigation.navigate('Settings', { screen: 'QuickpaySettings' }); - dispatch(updateUser({ quickpayIntroSeen: true })); + dispatch(updateSettings({ quickpayIntroSeen: true })); dispatch(closeSheet('quickPay')); }; const onDismiss = (): void => { - dispatch(updateUser({ quickpayIntroSeen: true })); + dispatch(updateSettings({ quickpayIntroSeen: true })); dispatch(closeSheet('quickPay')); }; @@ -86,7 +86,7 @@ const QuickPayPrompt = ({ enabled }: { enabled: boolean }): ReactElement => { view="quickPay" snapPoints={snapPoints} onClose={(): void => { - dispatch(updateUser({ quickpayIntroSeen: true })); + dispatch(updateSettings({ quickpayIntroSeen: true })); }}> { - dispatch(updateUser({ quickpayIntroSeen: true })); + dispatch(updateSettings({ quickpayIntroSeen: true })); navigation.navigate('QuickpaySettings'); }} /> diff --git a/src/screens/Transfer/Funding.tsx b/src/screens/Transfer/Funding.tsx index 12f5058e3..33e4ae000 100644 --- a/src/screens/Transfer/Funding.tsx +++ b/src/screens/Transfer/Funding.tsx @@ -10,10 +10,8 @@ import RectangleButton from '../../components/buttons/RectangleButton'; import SafeAreaInset from '../../components/SafeAreaInset'; import NavigationHeader from '../../components/NavigationHeader'; import { useBalance } from '../../hooks/wallet'; -import { - isGeoBlockedSelector, - spendingIntroSeenSelector, -} from '../../store/reselect/user'; +import { isGeoBlockedSelector } from '../../store/reselect/user'; +import { spendingIntroSeenSelector } from '../../store/reselect/settings'; import { TRANSACTION_DEFAULTS } from '../../utils/wallet/constants'; import { showBottomSheet } from '../../store/utils/ui'; import type { TransferScreenProps } from '../../navigation/types'; diff --git a/src/screens/Transfer/SavingsIntro.tsx b/src/screens/Transfer/SavingsIntro.tsx index f6bd4c916..dc743216d 100644 --- a/src/screens/Transfer/SavingsIntro.tsx +++ b/src/screens/Transfer/SavingsIntro.tsx @@ -4,7 +4,7 @@ import { Trans, useTranslation } from 'react-i18next'; import { Display } from '../../styles/text'; import OnboardingScreen from '../../components/OnboardingScreen'; import { useAppDispatch } from '../../hooks/redux'; -import { updateUser } from '../../store/slices/user'; +import { updateSettings } from '../../store/slices/settings'; import type { TransferScreenProps } from '../../navigation/types'; const imageSrc = require('../../assets/illustrations/piggybank.png'); @@ -17,7 +17,7 @@ const SavingsIntro = ({ const onContinue = (): void => { navigation.navigate('Availability'); - dispatch(updateUser({ savingsIntroSeen: true })); + dispatch(updateSettings({ savingsIntroSeen: true })); }; return ( diff --git a/src/screens/Transfer/SpendingIntro.tsx b/src/screens/Transfer/SpendingIntro.tsx index 1d13facb8..1193de0df 100644 --- a/src/screens/Transfer/SpendingIntro.tsx +++ b/src/screens/Transfer/SpendingIntro.tsx @@ -4,7 +4,7 @@ import { Trans, useTranslation } from 'react-i18next'; import { Display } from '../../styles/text'; import OnboardingScreen from '../../components/OnboardingScreen'; import { useAppDispatch } from '../../hooks/redux'; -import { updateUser } from '../../store/slices/user'; +import { updateSettings } from '../../store/slices/settings'; import type { TransferScreenProps } from '../../navigation/types'; const imageSrc = require('../../assets/illustrations/coin-stack-x.png'); @@ -17,7 +17,7 @@ const SpendingIntro = ({ const onContinue = (): void => { navigation.navigate('SpendingAmount'); - dispatch(updateUser({ spendingIntroSeen: true })); + dispatch(updateSettings({ spendingIntroSeen: true })); }; return ( diff --git a/src/screens/Transfer/TransferIntro.tsx b/src/screens/Transfer/TransferIntro.tsx index 8a6903ffc..d16b757c9 100644 --- a/src/screens/Transfer/TransferIntro.tsx +++ b/src/screens/Transfer/TransferIntro.tsx @@ -4,7 +4,7 @@ import { Trans, useTranslation } from 'react-i18next'; import { Display } from '../../styles/text'; import OnboardingScreen from '../../components/OnboardingScreen'; import { useAppDispatch } from '../../hooks/redux'; -import { updateUser } from '../../store/slices/user'; +import { updateSettings } from '../../store/slices/settings'; import type { TransferScreenProps } from '../../navigation/types'; const imageSrc = require('../../assets/illustrations/lightning.png'); @@ -17,7 +17,7 @@ const TransferIntro = ({ const onContinue = (): void => { navigation.navigate('Funding'); - dispatch(updateUser({ transferIntroSeen: true })); + dispatch(updateSettings({ transferIntroSeen: true })); }; return ( diff --git a/src/store/index.ts b/src/store/index.ts index 28f634111..8ecd5886d 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -32,7 +32,7 @@ const persistConfig = { key: 'root', storage: reduxStorage, // increase version after store shape changes - version: 49, + version: 50, stateReconciler: autoMergeLevel2, blacklist: ['receive', 'ui'], migrate: createMigrate(migrations, { debug: __ENABLE_MIGRATION_DEBUG__ }), diff --git a/src/store/migrations/index.ts b/src/store/migrations/index.ts index 8d23a37ce..9861585e5 100644 --- a/src/store/migrations/index.ts +++ b/src/store/migrations/index.ts @@ -80,6 +80,19 @@ const migrations = { return state; }, + 50: (state): PersistedState => { + return { + ...state, + settings: { + ...state.settings, + backupVerified: state.user.backupVerified, + quickpayIntroSeen: state.user.quickpayIntroSeen, + transferIntroSeen: state.user.transferIntroSeen, + spendingIntroSeen: state.user.spendingIntroSeen, + savingsIntroSeen: state.user.savingsIntroSeen, + }, + }; + }, }; export default migrations; diff --git a/src/store/reselect/settings.ts b/src/store/reselect/settings.ts index 2f784d0cd..9def4b2db 100644 --- a/src/store/reselect/settings.ts +++ b/src/store/reselect/settings.ts @@ -15,10 +15,14 @@ import { } from '../types/settings'; export const settingsSelector = (state: RootState): TSettings => state.settings; + const customElectrumPeersState = (state: RootState): TCustomElectrumPeers => { return state.settings.customElectrumPeers; }; +export const backupVerifiedSelector = (state: RootState): boolean => { + return state.settings.backupVerified; +}; export const selectedCurrencySelector = (state: RootState): string => { return state.settings.selectedCurrency; }; @@ -118,6 +122,18 @@ export const denominationSelector = (state: RootState): EDenomination => { export const webRelaySelector = (state: RootState): string => { return state.settings.webRelay; }; +export const quickpayIntroSeenSelector = (state: RootState): boolean => { + return state.settings.quickpayIntroSeen; +}; +export const transferIntroSeenSelector = (state: RootState): boolean => { + return state.settings.transferIntroSeen; +}; +export const spendingIntroSeenSelector = (state: RootState): boolean => { + return state.settings.spendingIntroSeen; +}; +export const savingsIntroSeenSelector = (state: RootState): boolean => { + return state.settings.savingsIntroSeen; +}; /** * Returns custom Electrum peers for a given network. diff --git a/src/store/reselect/todos.ts b/src/store/reselect/todos.ts index 736fd44cf..b74c7ebbe 100644 --- a/src/store/reselect/todos.ts +++ b/src/store/reselect/todos.ts @@ -17,11 +17,8 @@ import { btFailedTodo, inviteTodo, } from '../shapes/todos'; -import { - backupVerifiedSelector, - startCoopCloseTimestampSelector, -} from './user'; -import { pinSelector } from './settings'; +import { startCoopCloseTimestampSelector } from './user'; +import { backupVerifiedSelector, pinSelector } from './settings'; import { onboardingProfileStepSelector } from './slashtags'; import { closedChannelsSelector, openChannelsSelector } from './lightning'; import { blocktankPaidOrdersFullSelector } from './blocktank'; diff --git a/src/store/reselect/user.ts b/src/store/reselect/user.ts index 4c33fb5ee..3138f163f 100644 --- a/src/store/reselect/user.ts +++ b/src/store/reselect/user.ts @@ -9,11 +9,6 @@ export const isGeoBlockedSelector = createSelector( (user): boolean => user.isGeoBlocked ?? false, ); -export const backupVerifiedSelector = createSelector( - [userState], - (user): boolean => user.backupVerified, -); - export const ignoreBackupTimestampSelector = createSelector( [userState], (user): number => user.ignoreBackupTimestamp, @@ -24,10 +19,6 @@ export const lightningSettingUpStepSelector = createSelector( (user): number => user.lightningSettingUpStep, ); -export const quickpayIntroSeenSelector = (state: RootState): boolean => { - return state.user.quickpayIntroSeen; -}; - export const requiresRemoteRestoreSelector = createSelector( [userState], (user): boolean => user.requiresRemoteRestore, @@ -67,15 +58,3 @@ export const scanAllAddressesTimestampSelector = createSelector( [userState], (user): number => user.scanAllAddressesTimestamp, ); - -export const transferIntroSeenSelector = (state: RootState): boolean => { - return state.user.transferIntroSeen; -}; - -export const spendingIntroSeenSelector = (state: RootState): boolean => { - return state.user.spendingIntroSeen; -}; - -export const savingsIntroSeenSelector = (state: RootState): boolean => { - return state.user.savingsIntroSeen; -}; diff --git a/src/store/shapes/settings.ts b/src/store/shapes/settings.ts index e4ebbfe2e..044de44f7 100644 --- a/src/store/shapes/settings.ts +++ b/src/store/shapes/settings.ts @@ -74,6 +74,7 @@ const defaultReceivePreference = [ ]; export const initialSettingsState: TSettings = { + backupVerified: false, enableAutoReadClipboard: false, enableSendAmountWarning: false, enableSwipeToHideBalance: true, @@ -107,6 +108,10 @@ export const initialSettingsState: TSettings = { treasureChests: [], orangeTickets: [], webRelay: __WEB_RELAY__, + quickpayIntroSeen: false, + transferIntroSeen: false, + spendingIntroSeen: false, + savingsIntroSeen: false, }; export const getDefaultSettingsShape = (): TSettings => { diff --git a/src/store/slices/settings.ts b/src/store/slices/settings.ts index ed0eac59f..558075ad2 100644 --- a/src/store/slices/settings.ts +++ b/src/store/slices/settings.ts @@ -14,6 +14,7 @@ import { EAvailableNetwork } from '../../utils/networks'; import { EDenomination, EUnit } from '../types/wallet'; export type TSettings = { + backupVerified: boolean; enableAutoReadClipboard: boolean; enableSendAmountWarning: boolean; enableSwipeToHideBalance: boolean; @@ -47,6 +48,10 @@ export type TSettings = { treasureChests: TChest[]; orangeTickets: string[]; webRelay: string; + quickpayIntroSeen: boolean; + transferIntroSeen: boolean; + spendingIntroSeen: boolean; + savingsIntroSeen: boolean; }; export const settingsSlice = createSlice({ @@ -83,6 +88,9 @@ export const settingsSlice = createSlice({ addOrangeTicket: (state, action: PayloadAction) => { state.orangeTickets.push(action.payload); }, + verifyBackup: (state) => { + state.backupVerified = true; + }, resetSettingsState: () => initialSettingsState, }, }); @@ -95,6 +103,7 @@ export const { addTreasureChest, updateTreasureChest, addOrangeTicket, + verifyBackup, resetSettingsState, } = actions; diff --git a/src/store/slices/user.ts b/src/store/slices/user.ts index 57896ff31..4d2250703 100644 --- a/src/store/slices/user.ts +++ b/src/store/slices/user.ts @@ -1,43 +1,35 @@ +// NOTE: 'user' slice is persisted to storage, but not included in remote backup + import { PayloadAction, createSlice } from '@reduxjs/toolkit'; export const MAX_WARNINGS = 3; // how many times to show high balance warning export type TUser = { - backupVerified: boolean; ignoreAppUpdateTimestamp: number; ignoreBackupTimestamp: number; ignoreHighBalanceCount: number; ignoreHighBalanceTimestamp: number; isGeoBlocked: boolean; lightningSettingUpStep: number; - quickpayIntroSeen: boolean; requiresRemoteRestore: boolean; startCoopCloseTimestamp: number; ignoresHideBalanceToast: boolean; ignoresSwitchUnitToast: boolean; scanAllAddressesTimestamp: number; - transferIntroSeen: boolean; - spendingIntroSeen: boolean; - savingsIntroSeen: boolean; }; export const initialUserState: TUser = { - backupVerified: false, ignoreAppUpdateTimestamp: 0, ignoreBackupTimestamp: 0, ignoreHighBalanceCount: 0, ignoreHighBalanceTimestamp: 0, isGeoBlocked: false, lightningSettingUpStep: 0, - quickpayIntroSeen: false, requiresRemoteRestore: false, startCoopCloseTimestamp: 0, ignoresHideBalanceToast: false, ignoresSwitchUnitToast: false, scanAllAddressesTimestamp: 0, - transferIntroSeen: false, - spendingIntroSeen: false, - savingsIntroSeen: false, }; export const userSlice = createSlice({ @@ -67,9 +59,6 @@ export const userSlice = createSlice({ clearCoopCloseTimer: (state) => { state.startCoopCloseTimestamp = 0; }, - verifyBackup: (state) => { - state.backupVerified = true; - }, ignoreHideBalanceToast: (state) => { state.ignoresHideBalanceToast = true; }, @@ -90,7 +79,6 @@ export const { setLightningSetupStep, startCoopCloseTimer, clearCoopCloseTimer, - verifyBackup, ignoreHideBalanceToast, ignoreSwitchUnitToast, resetUserState,