Skip to content

Commit

Permalink
Merge pull request #31452 from margelo/@chrispader/use-theme-illustra…
Browse files Browse the repository at this point in the history
…tions

Feature: Implement theme dependent illustrations (`useThemeIllustrations` hook)
  • Loading branch information
grgia authored Nov 27, 2023
2 parents 8d24b8d + 8330198 commit 0a05917
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 4 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import OnyxUpdateManager from './libs/actions/OnyxUpdateManager';
import * as Session from './libs/actions/Session';
import * as Environment from './libs/Environment/Environment';
import {ReportAttachmentsProvider} from './pages/home/report/ReportAttachmentsContext';
import ThemeIllustrationsProvider from './styles/illustrations/ThemeIllustrationsProvider';
import ThemeProvider from './styles/themes/ThemeProvider';
import ThemeStylesProvider from './styles/ThemeStylesProvider';

Expand Down Expand Up @@ -64,6 +65,7 @@ function App() {
EnvironmentProvider,
ThemeProvider,
ThemeStylesProvider,
ThemeIllustrationsProvider,
]}
>
<CustomStatusBar />
Expand Down
5 changes: 3 additions & 2 deletions src/pages/home/report/AnimatedEmptyStateBackground.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import Animated, {SensorType, useAnimatedSensor, useAnimatedStyle, useSharedValue, withSpring} from 'react-native-reanimated';
import EmptyStateBackgroundImage from '@assets/images/empty-state_background-fade.png';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as NumberUtils from '@libs/NumberUtils';
import useThemeIllustrations from '@styles/illustrations/useThemeIllustrations';
import * as StyleUtils from '@styles/StyleUtils';
import variables from '@styles/variables';
import CONST from '@src/CONST';
Expand All @@ -11,6 +11,7 @@ const IMAGE_OFFSET_Y = 75;

function AnimatedEmptyStateBackground() {
const {windowWidth, isSmallScreenWidth} = useWindowDimensions();
const illustrations = useThemeIllustrations();
const IMAGE_OFFSET_X = windowWidth / 2;

// If window width is greater than the max background width, repeat the background image
Expand Down Expand Up @@ -41,7 +42,7 @@ function AnimatedEmptyStateBackground() {

return (
<Animated.Image
source={EmptyStateBackgroundImage}
source={illustrations.EmptyStateBackgroundImage}
style={[StyleUtils.getReportWelcomeBackgroundImageStyle(isSmallScreenWidth), animatedStyles]}
resizeMode={windowWidth > maxBackgroundWidth ? 'repeat' : 'cover'}
/>
Expand Down
7 changes: 7 additions & 0 deletions src/styles/illustrations/ThemeIllustrationsContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';
import DarkIllustrations from './dark';
import {Illustrations} from './types';

const ThemeIllustrationsContext = React.createContext<Illustrations>(DarkIllustrations);

export default ThemeIllustrationsContext;
21 changes: 21 additions & 0 deletions src/styles/illustrations/ThemeIllustrationsProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, {useMemo} from 'react';
import useThemePreference from '@styles/themes/useThemePreference';
import DarkIllustrations from './dark';
import LightIllustrations from './light';
import ThemeIllustrationsContext from './ThemeIllustrationsContext';

type ThemeIllustrationsProviderProps = {
children: React.ReactNode;
};

function ThemeIllustrationsProvider({children}: ThemeIllustrationsProviderProps) {
const themePreference = useThemePreference();

const illustrations = useMemo(() => (themePreference === 'dark' ? DarkIllustrations : LightIllustrations), [themePreference]);

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

ThemeIllustrationsProvider.displayName = 'ThemeIllustrationsProvider';

export default ThemeIllustrationsProvider;
8 changes: 8 additions & 0 deletions src/styles/illustrations/dark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import EmptyStateBackgroundImage from '@assets/images/empty-state_background-fade-dark.png';
import {Illustrations} from './types';

const illustrations = {
EmptyStateBackgroundImage,
} satisfies Illustrations;

export default illustrations;
8 changes: 8 additions & 0 deletions src/styles/illustrations/light.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import EmptyStateBackgroundImage from '@assets/images/empty-state_background-fade-light.png';
import {Illustrations} from './types';

const illustrations = {
EmptyStateBackgroundImage,
} satisfies Illustrations;

export default illustrations;
8 changes: 8 additions & 0 deletions src/styles/illustrations/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {ImageSourcePropType} from 'react-native';

type Illustrations = {
EmptyStateBackgroundImage: ImageSourcePropType;
};

// eslint-disable-next-line import/prefer-default-export
export {type Illustrations};
14 changes: 14 additions & 0 deletions src/styles/illustrations/useThemeIllustrations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {useContext} from 'react';
import ThemeIllustrationsContext from './ThemeIllustrationsContext';

function useThemeIllustrations() {
const illustrations = useContext(ThemeIllustrationsContext);

if (!illustrations) {
throw new Error('ThemeIllustrationsContext was null! Are you sure that you wrapped the component under a <ThemeIllustrationsProvider>?');
}

return illustrations;
}

export default useThemeIllustrations;
2 changes: 0 additions & 2 deletions src/styles/useThemeStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ function useThemeStyles() {
throw new Error('ThemeStylesContext was null! Are you sure that you wrapped the component under a <ThemeStylesProvider>?');
}

// TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337)
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return themeStyles;
}

Expand Down

0 comments on commit 0a05917

Please sign in to comment.