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

Theme switching: Dynamic StatusBar and scroll bars #32063

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
9e0d4d8
disable building android from source
chrispader Nov 17, 2023
0c3ba38
add numberOfLines workaround
chrispader Nov 17, 2023
8f830ab
fix: workaround for iOS
chrispader Nov 17, 2023
569c388
fix: android implementation
chrispader Nov 17, 2023
ae5d0aa
fix: android
chrispader Nov 17, 2023
a6c6602
fix: extract style
chrispader Nov 17, 2023
abbd499
remove unused style
chrispader Nov 17, 2023
43a0323
remove unused return
chrispader Nov 17, 2023
e1ef2cf
Merge branch 'main' into @chrispader/number-of-lines-workaround
Nov 23, 2023
221f30e
rename patch
chrispader Nov 23, 2023
110943e
allow dark statusbar content
chrispader Nov 27, 2023
7e930a9
Merge remote-tracking branch 'margelo/@chrispader/dark-sign-in-page' …
chrispader Nov 27, 2023
e948718
Merge branch '@chrispader/dark-sign-in-page' into @chrispader/theme-s…
chrispader Nov 27, 2023
945953f
add CustomScrollbarWrapper and use in SignInPage
chrispader Nov 27, 2023
4ddd498
fix: typo
chrispader Nov 27, 2023
89f924e
adapt Themes
chrispader Nov 27, 2023
81515d4
remove isLight condition
chrispader Nov 27, 2023
b2d2928
remove comment
chrispader Nov 27, 2023
8f23391
add additional theme keys for status bar and scrollbar
chrispader Nov 27, 2023
3bd4136
update CustomStatusBar wrapper
chrispader Nov 27, 2023
4abcfd7
add noop for native
chrispader Nov 27, 2023
7ac2d01
implement custom scrollbar theme
chrispader Nov 27, 2023
c0e1db1
update CustomStatusBar
chrispader Nov 27, 2023
cde61a7
implement CustomStatusBarContext to avoid multiple StatusBars from in…
chrispader Nov 27, 2023
8040abe
fix: CustomScrollBarWrapper
chrispader Nov 27, 2023
edd8bf7
Merge branch '@chrispader/number-of-lines-workaround' into @chrispade…
chrispader Nov 27, 2023
04a9810
remove unused import
chrispader Nov 27, 2023
e43cc64
Merge branch 'main' into @chrispader/theme-switching-status-and-scrol…
chrispader Nov 27, 2023
33efc40
update comment
chrispader Nov 27, 2023
02f6e74
revert number of lines changes
chrispader Nov 27, 2023
faefaf5
fix: minor fixes
chrispader Nov 27, 2023
e335bd0
remove index.html style
chrispader Nov 27, 2023
37b2215
Merge branch 'main' into @chrispader/theme-switching-status-and-scrol…
chrispader Nov 27, 2023
38bcce7
remove patch
chrispader Nov 27, 2023
df2342f
add back patch
chrispader Nov 27, 2023
3353180
Merge branch 'main' into @chrispader/theme-switching-status-and-scrol…
chrispader Nov 28, 2023
9027d7a
change styles
chrispader Nov 28, 2023
94c11e0
update styles and CONST
chrispader Nov 28, 2023
2ffb572
make navigation container theme dynamic
chrispader Nov 28, 2023
5dbca1d
add status bar for android
chrispader Nov 28, 2023
2eba4b7
simplify status bar and scrollbar components and add support for diff…
chrispader Nov 28, 2023
4d833de
improve code
chrispader Nov 28, 2023
941f4dc
implement route change listener
chrispader Nov 28, 2023
497e98e
remove log
chrispader Nov 28, 2023
f05bb31
Merge branch 'main' into @chrispader/theme-switching-status-and-scrol…
chrispader Nov 28, 2023
12099b6
Merge branch 'main' into @chrispader/theme-switching-status-and-scrol…
chrispader Nov 29, 2023
0feb155
add file to .imgbotconfig
chrispader Nov 29, 2023
cb28261
fix: lint
chrispader Nov 29, 2023
1bbcc1d
Merge branch 'main' into @chrispader/theme-switching-status-and-scrol…
chrispader Nov 30, 2023
915c38e
rename scrollbar wrapper
chrispader Nov 30, 2023
bf2fd72
fix: CustomStatusBar component
chrispader Nov 30, 2023
9272b68
Merge branch 'main' into @chrispader/theme-switching-status-and-scrol…
chrispader Nov 30, 2023
331b418
add comment
chrispader Nov 30, 2023
268f683
Update src/components/CustomStatusBar/index.tsx
chrispader Nov 30, 2023
3ca7fc7
Update version to 1.4.6-0
OSBotify Nov 30, 2023
cde5ba8
fix: amend missed imports
koko57 Nov 30, 2023
20d54db
fix: run lint
koko57 Nov 30, 2023
b343ef1
fix: export fix
koko57 Nov 30, 2023
198e4ec
migrate getModalStyles
rezkiy37 Nov 30, 2023
9bc522f
migrate getReportActionContextMenuStyles
rezkiy37 Nov 30, 2023
97d0081
rename argument
rezkiy37 Nov 30, 2023
91f299d
Update version to 1.4.6-1
OSBotify Nov 30, 2023
80f13fc
Fix green line being displayed chaotically in chat
artus9033 Nov 16, 2023
51ef33f
fix: remove invalid param
chrispader Nov 30, 2023
4c41816
Merge branch 'main' into @chrispader/theme-switching-status-and-scrol…
chrispader Nov 30, 2023
f08d0a1
revert changes
chrispader Nov 30, 2023
c0dbdc4
Update src/components/CustomStatusBar/index.tsx
chrispader Nov 30, 2023
3b0ebeb
Update src/components/CustomStatusBar/index.tsx
chrispader Nov 30, 2023
f7df8ad
fix: lint errors
chrispader Nov 30, 2023
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
3 changes: 2 additions & 1 deletion .imgbotconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"ignoredFiles": [
"assets/images/empty-state_background-fade.png" // Caused an issue with colour gradients, https://github.com/Expensify/App/issues/30499
"assets/images/empty-state_background-fade-dark.png", // Caused an issue with colour gradients, https://github.com/Expensify/App/issues/30499
"assets/images/empty-state_background-fade-light.png"
],
"aggressiveCompression": "false"
}
7 changes: 6 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import Onyx from 'react-native-onyx';
import {PickerStateProvider} from 'react-native-picker-select';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import '../wdyr';
import ColorSchemeWrapper from './components/ColorSchemeWrapper';
import ComposeProviders from './components/ComposeProviders';
import CustomStatusBar from './components/CustomStatusBar';
import CustomStatusBarContextProvider from './components/CustomStatusBar/CustomStatusBarContextProvider';
import ErrorBoundary from './components/ErrorBoundary';
import HTMLEngineProvider from './components/HTMLEngineProvider';
import {LocaleContextProvider} from './components/LocaleContextProvider';
Expand Down Expand Up @@ -66,11 +68,14 @@ function App() {
ThemeProvider,
ThemeStylesProvider,
ThemeIllustrationsProvider,
CustomStatusBarContextProvider,
]}
>
<CustomStatusBar />
<ErrorBoundary errorMessage="NewExpensify crash caught by error boundary">
<Expensify />
<ColorSchemeWrapper>
<Expensify />
</ColorSchemeWrapper>
</ErrorBoundary>
</ComposeProviders>
</GestureHandlerRootView>
Expand Down
8 changes: 8 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,14 @@ const CONST = {
DARK: 'dark',
SYSTEM: 'system',
},
COLOR_SCHEME: {
LIGHT: 'light',
DARK: 'dark',
},
STATUS_BAR_STYLE: {
LIGHT_CONTENT: 'light-content',
DARK_CONTENT: 'dark-content',
},
TRANSACTION: {
DEFAULT_MERCHANT: 'Request',
UNKNOWN_MERCHANT: 'Unknown Merchant',
Expand Down
5 changes: 5 additions & 0 deletions src/components/ColorSchemeWrapper/index.native.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function ColorSchemeWrapper({children}: React.PropsWithChildren) {
return children;
}

export default ColorSchemeWrapper;
13 changes: 13 additions & 0 deletions src/components/ColorSchemeWrapper/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import {View} from 'react-native';
import useTheme from '@styles/themes/useTheme';
import useThemeStyles from '@styles/useThemeStyles';

function ColorSchemeWrapper({children}: React.PropsWithChildren): React.ReactElement {
const theme = useTheme();
const themeStyles = useThemeStyles();

return <View style={[themeStyles.flex1, themeStyles.colorSchemeStyle(theme.colorScheme)]}>{children}</View>;
}

export default ColorSchemeWrapper;
11 changes: 11 additions & 0 deletions src/components/CustomStatusBar/CustomStatusBarContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {createContext} from 'react';

type CustomStatusBarContextType = {
isRootStatusBarDisabled: boolean;
disableRootStatusBar: (isDisabled: boolean) => void;
};

const CustomStatusBarContext = createContext<CustomStatusBarContextType>({isRootStatusBarDisabled: false, disableRootStatusBar: () => undefined});

export default CustomStatusBarContext;
export {type CustomStatusBarContextType};
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React, {useMemo, useState} from 'react';
import CustomStatusBarContext from './CustomStatusBarContext';

function CustomStatusBarContextProvider({children}: React.PropsWithChildren) {
const [isRootStatusBarDisabled, disableRootStatusBar] = useState(false);
const value = useMemo(
() => ({
isRootStatusBarDisabled,
disableRootStatusBar,
}),
[isRootStatusBarDisabled],
);

return <CustomStatusBarContext.Provider value={value}>{children}</CustomStatusBarContext.Provider>;
}

export default CustomStatusBarContextProvider;
15 changes: 0 additions & 15 deletions src/components/CustomStatusBar/index.android.tsx

This file was deleted.

94 changes: 78 additions & 16 deletions src/components/CustomStatusBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,91 @@
import React, {useEffect} from 'react';
import Navigation, {navigationRef} from '@libs/Navigation/Navigation';
import {EventListenerCallback, NavigationContainerEventMap} from '@react-navigation/native';
import PropTypes from 'prop-types';
import React, {useCallback, useContext, useEffect} from 'react';
import {navigationRef} from '@libs/Navigation/Navigation';
import StatusBar from '@libs/StatusBar';
import useTheme from '@styles/themes/useTheme';
import type CustomStatusBarType from './types';
import CustomStatusBarContext from './CustomStatusBarContext';

type CustomStatusBarProps = {
isNested: boolean;
};
chrispader marked this conversation as resolved.
Show resolved Hide resolved

const propTypes = {
/** Whether the CustomStatusBar is nested within another CustomStatusBar.
chrispader marked this conversation as resolved.
Show resolved Hide resolved
* A nested CustomStatusBar will disable the "root" CustomStatusBar. */
isNested: PropTypes.bool,
};

type CustomStatusBarType = {
(props: CustomStatusBarProps): React.ReactNode;
displayName: string;
propTypes: typeof propTypes;
};

// eslint-disable-next-line react/function-component-definition
const CustomStatusBar: CustomStatusBarType = () => {
const CustomStatusBar: CustomStatusBarType = ({isNested = false}) => {
const {isRootStatusBarDisabled, disableRootStatusBar} = useContext(CustomStatusBarContext);
const theme = useTheme();

const isDisabled = !isNested && isRootStatusBarDisabled;

useEffect(() => {
Navigation.isNavigationReady().then(() => {
// Set the status bar colour depending on the current route.
// If we don't have any colour defined for a route, fall back to
// appBG color.
const currentRoute = navigationRef.getCurrentRoute();
let currentScreenBackgroundColor = theme.appBG;
if (currentRoute && 'name' in currentRoute && currentRoute.name in theme.PAGE_BACKGROUND_COLORS) {
currentScreenBackgroundColor = theme.PAGE_BACKGROUND_COLORS[currentRoute.name];
if (isNested) {
disableRootStatusBar(true);
}

return () => {
if (!isNested) {
return;
}
StatusBar.setBarStyle('light-content', true);
StatusBar.setBackgroundColor(currentScreenBackgroundColor);
});
}, [theme.PAGE_BACKGROUND_COLORS, theme.appBG]);
disableRootStatusBar(false);
};
}, [disableRootStatusBar, isNested]);

const updateStatusBarStyle = useCallback<EventListenerCallback<NavigationContainerEventMap, 'state'>>(() => {
if (isDisabled) {
return;
}

// Set the status bar colour depending on the current route.
// If we don't have any colour defined for a route, fall back to
// appBG color.
const currentRoute = navigationRef.getCurrentRoute();

let currentScreenBackgroundColor = theme.appBG;
let statusBarStyle = theme.statusBarStyle;
if (currentRoute && 'name' in currentRoute && currentRoute.name in theme.PAGE_THEMES) {
const screenTheme = theme.PAGE_THEMES[currentRoute.name];
currentScreenBackgroundColor = screenTheme.backgroundColor;
statusBarStyle = screenTheme.statusBarStyle;
}

StatusBar.setBackgroundColor(currentScreenBackgroundColor, true);
StatusBar.setBarStyle(statusBarStyle, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

@chrispader I notice that you removed the animated transition between status bar background colors that was present in NavigationRoot.tsx. Was there any discussion around that choice? Can you add it back here please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, sorry my mistake. Just added a PR here: #33200

}, [isDisabled, theme.PAGE_THEMES, theme.appBG, theme.statusBarStyle]);

useEffect(() => {
navigationRef.addListener('state', updateStatusBarStyle);

return () => navigationRef.removeListener('state', updateStatusBarStyle);
}, [updateStatusBarStyle]);

useEffect(() => {
if (isDisabled) {
return;
}

StatusBar.setBarStyle(theme.statusBarStyle, true);
}, [isDisabled, theme.statusBarStyle]);

if (isDisabled) {
return null;
}

return <StatusBar />;
};

CustomStatusBar.displayName = 'CustomStatusBar';
CustomStatusBar.propTypes = propTypes;

export default CustomStatusBar;
6 changes: 0 additions & 6 deletions src/components/CustomStatusBar/types.ts

This file was deleted.

46 changes: 1 addition & 45 deletions src/libs/Navigation/NavigationRoot.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import {DefaultTheme, getPathFromState, NavigationContainer, NavigationState} from '@react-navigation/native';
import React, {useEffect, useMemo, useRef} from 'react';
import {ColorValue} from 'react-native';
import {interpolateColor, runOnJS, useAnimatedReaction, useSharedValue, withDelay, withTiming} from 'react-native-reanimated';
import useCurrentReportID from '@hooks/useCurrentReportID';
import useFlipper from '@hooks/useFlipper';
import useWindowDimensions from '@hooks/useWindowDimensions';
import Log from '@libs/Log';
import StatusBar from '@libs/StatusBar';
import useTheme from '@styles/themes/useTheme';
import AppNavigator from './AppNavigator';
import linkingConfig from './linkingConfig';
Expand Down Expand Up @@ -42,8 +39,8 @@ function parseAndLogRoute(state: NavigationState) {

function NavigationRoot({authenticated, onReady}: NavigationRootProps) {
useFlipper(navigationRef);
const theme = useTheme();
const firstRenderRef = useRef(true);
const theme = useTheme();

const currentReportIDValue = useCurrentReportID();
const {isSmallScreenWidth} = useWindowDimensions();
Expand Down Expand Up @@ -82,46 +79,6 @@ function NavigationRoot({authenticated, onReady}: NavigationRootProps) {
navigationRef.resetRoot(navigationRef.getRootState());
}, [isSmallScreenWidth, authenticated]);

const prevStatusBarBackgroundColor = useRef(theme.appBG);
const statusBarBackgroundColor = useRef(theme.appBG);
const statusBarAnimation = useSharedValue(0);

const updateStatusBarBackgroundColor = (color: ColorValue) => StatusBar.setBackgroundColor(color);
useAnimatedReaction(
() => statusBarAnimation.value,
(current, previous) => {
// Do not run if either of the animated value is null
// or previous animated value is greater than or equal to the current one
if (previous === null || current === null || current <= previous) {
return;
}
const color = interpolateColor(statusBarAnimation.value, [0, 1], [prevStatusBarBackgroundColor.current, statusBarBackgroundColor.current]);
runOnJS(updateStatusBarBackgroundColor)(color);
},
);

const animateStatusBarBackgroundColor = () => {
const currentRoute = navigationRef.getCurrentRoute();

const backgroundColorFromRoute =
currentRoute?.params && 'backgroundColor' in currentRoute.params && typeof currentRoute.params.backgroundColor === 'string' && currentRoute.params.backgroundColor;
const backgroundColorFallback = currentRoute?.name ? theme.PAGE_BACKGROUND_COLORS[currentRoute.name] || theme.appBG : theme.appBG;

// It's possible for backgroundColorFromRoute to be empty string, so we must use "||" to fallback to backgroundColorFallback.
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const currentScreenBackgroundColor = backgroundColorFromRoute || backgroundColorFallback;

prevStatusBarBackgroundColor.current = statusBarBackgroundColor.current;
statusBarBackgroundColor.current = currentScreenBackgroundColor;

if (currentScreenBackgroundColor === theme.appBG && prevStatusBarBackgroundColor.current === theme.appBG) {
return;
}

statusBarAnimation.value = 0;
statusBarAnimation.value = withDelay(300, withTiming(1));
};

const handleStateChange = (state: NavigationState | undefined) => {
if (!state) {
return;
Expand All @@ -132,7 +89,6 @@ function NavigationRoot({authenticated, onReady}: NavigationRootProps) {
currentReportIDValue?.updateCurrentReportID(state);
}, 0);
parseAndLogRoute(state);
animateStatusBarBackgroundColor();
};

return (
Expand Down
14 changes: 9 additions & 5 deletions src/libs/StatusBar/index.android.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import StatusBar from './types';

// Only has custom web implementation
StatusBar.getBackgroundColor = () => null;
const setBackgroundColor = StatusBar.setBackgroundColor;

// We override this because it's not used – on Android our app display edge-to-edge.
// Also because Reanimated's interpolateColor gives Android native colors instead of hex strings, causing this to display a warning.
StatusBar.setBackgroundColor = () => null;
let statusBarColor: string | null = null;

StatusBar.getBackgroundColor = () => statusBarColor;

StatusBar.setBackgroundColor = (color, animated = false) => {
statusBarColor = color as string;
setBackgroundColor(color, animated);
};

export default StatusBar;
2 changes: 1 addition & 1 deletion src/pages/TeachersUnite/SaveTheWorldPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function SaveTheWorldPage(props) {
<IllustratedHeaderPageLayout
shouldShowBackButton
title={translate('sidebarScreen.saveTheWorld')}
backgroundColor={theme.PAGE_BACKGROUND_COLORS[SCREENS.SAVE_THE_WORLD.ROOT]}
backgroundColor={theme.PAGE_THEMES[SCREENS.SAVE_THE_WORLD.ROOT].backgroundColor}
onBackButtonPress={() => Navigation.goBack(ROUTES.HOME)}
illustration={LottieAnimations.SaveTheWorld}
>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/settings/InitialSettingsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ function InitialSettingsPage(props) {
title={translate('common.settings')}
headerContent={headerContent}
headerContainerStyles={[styles.staticHeaderImage, styles.justifyContentCenter]}
backgroundColor={theme.PAGE_BACKGROUND_COLORS[SCREENS.SETTINGS.ROOT]}
backgroundColor={theme.PAGE_THEMES[SCREENS.SETTINGS.ROOT].backgroundColor}
>
<View style={styles.w100}>
{getMenuItems}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/settings/Preferences/PreferencesPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function PreferencesPage(props) {
<IllustratedHeaderPageLayout
title={translate('common.preferences')}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS)}
backgroundColor={theme.PAGE_BACKGROUND_COLORS[SCREENS.SETTINGS.PREFERENCES]}
backgroundColor={theme.PAGE_THEMES[SCREENS.SETTINGS.PREFERENCES].backgroundColor}
illustration={LottieAnimations.PreferencesDJ}
>
<View style={styles.mb6}>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/settings/Profile/CustomStatus/StatusPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function StatusPage({draftStatus, currentUserPersonalDetails}) {
/>
}
headerContainerStyles={[styles.staticHeaderImage]}
backgroundColor={theme.PAGE_BACKGROUND_COLORS[SCREENS.SETTINGS.STATUS]}
backgroundColor={theme.PAGE_THEMES[SCREENS.SETTINGS.STATUS].backgroundColor}
footer={footerComponent}
>
<View style={[styles.mh5, styles.mb5]}>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/settings/Security/SecuritySettingsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function SecuritySettingsPage(props) {
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS)}
shouldShowBackButton
illustration={LottieAnimations.Safe}
backgroundColor={theme.PAGE_BACKGROUND_COLORS[SCREENS.SETTINGS.SECURITY]}
backgroundColor={theme.PAGE_THEMES[SCREENS.SETTINGS.SECURITY].backgroundColor}
>
<ScrollView contentContainerStyle={[styles.flexGrow1, styles.flexColumn, styles.justifyContentBetween]}>
<View style={[styles.flex1]}>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/settings/Wallet/ActivatePhysicalCardPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ function ActivatePhysicalCardPage({
<IllustratedHeaderPageLayout
title={translate('activateCardPage.activateCard')}
onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_WALLET_DOMAINCARD.getRoute(domain))}
backgroundColor={theme.PAGE_BACKGROUND_COLORS[SCREENS.SETTINGS.PREFERENCES]}
backgroundColor={theme.PAGE_THEMES[SCREENS.SETTINGS.PREFERENCES].backgroundColor}
illustration={LottieAnimations.Magician}
scrollViewContainerStyles={[styles.mnh100]}
childrenContainerStyles={[styles.flex1]}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/settings/Wallet/WalletEmptyState.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function WalletEmptyState({onAddPaymentMethod}) {
const {translate} = useLocalize();
return (
<IllustratedHeaderPageLayout
backgroundColor={theme.PAGE_BACKGROUND_COLORS[SCREENS.SETTINGS.WALLET]}
backgroundColor={theme.PAGE_THEMES[SCREENS.SETTINGS.WALLET].backgroundColor}
illustration={LottieAnimations.FastMoney}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS)}
title={translate('common.wallet')}
Expand Down
Loading
Loading