Skip to content

Commit

Permalink
Merge pull request #20663 from Expensify/Rory-AnimateHeaderBackground…
Browse files Browse the repository at this point in the history
…Color

Animate StatusBar background color
  • Loading branch information
AndrewGable authored Jun 29, 2023
2 parents 9f2418a + bfd0cdf commit c83b2d1
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/components/withCurrentReportID.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,4 @@ export default function withCurrentReportID(WrappedComponent) {
return WithCurrentReportID;
}

export {withCurrentReportIDPropTypes, withCurrentReportIDDefaultProps, CurrentReportIDContextProvider};
export {withCurrentReportIDPropTypes, withCurrentReportIDDefaultProps, CurrentReportIDContextProvider, CurrentReportIDContext};
6 changes: 6 additions & 0 deletions src/hooks/useCurrentReportID.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {useContext} from 'react';
import {CurrentReportIDContext} from '../components/withCurrentReportID';

export default function useCurrentReportID() {
return useContext(CurrentReportIDContext);
}
53 changes: 44 additions & 9 deletions src/libs/Navigation/NavigationRoot.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import React, {useRef} from 'react';
import PropTypes from 'prop-types';
import {NavigationContainer, DefaultTheme, getPathFromState} from '@react-navigation/native';
import {useFlipper} from '@react-navigation/devtools';
import {useSharedValue, useAnimatedReaction, interpolateColor, withTiming, withDelay, Easing, runOnJS} from 'react-native-reanimated';
import Navigation, {navigationRef} from './Navigation';
import linkingConfig from './linkingConfig';
import AppNavigator from './AppNavigator';
import themeColors from '../../styles/themes/default';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions';
import Log from '../Log';
import withCurrentReportID, {withCurrentReportIDPropTypes} from '../../components/withCurrentReportID';
import compose from '../compose';
import StatusBar from '../StatusBar';
import useCurrentReportID from '../../hooks/useCurrentReportID';
import useWindowDimensions from '../../hooks/useWindowDimensions';

// https://reactnavigation.org/docs/themes
const navigationTheme = {
Expand All @@ -21,14 +22,11 @@ const navigationTheme = {
};

const propTypes = {
...windowDimensionsPropTypes,

/** Whether the current user is logged in with an authToken */
authenticated: PropTypes.bool.isRequired,

/** Fired when react-navigation is ready */
onReady: PropTypes.func.isRequired,
...withCurrentReportIDPropTypes,
};

/**
Expand Down Expand Up @@ -56,18 +54,55 @@ function NavigationRoot(props) {
useFlipper(navigationRef);
const navigationStateRef = useRef(undefined);

const {updateCurrentReportID} = useCurrentReportID();
const {isSmallScreenWidth} = useWindowDimensions();

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

const updateStatusBarBackgroundColor = (color) => StatusBar.setBackgroundColor(color);
useAnimatedReaction(
() => statusBarAnimation.value,
() => {
const color = interpolateColor(statusBarAnimation.value, [0, 1], [prevStatusBarBackgroundColor.current, statusBarBackgroundColor.current]);
runOnJS(updateStatusBarBackgroundColor)(color);
},
);

const animateStatusBarBackgroundColor = () => {
const currentRoute = navigationRef.getCurrentRoute();
const currentScreenBackgroundColor = themeColors.PAGE_BACKGROUND_COLORS[currentRoute.name] || themeColors.appBG;

prevStatusBarBackgroundColor.current = statusBarBackgroundColor.current;
statusBarBackgroundColor.current = currentScreenBackgroundColor;
if (prevStatusBarBackgroundColor.current === statusBarBackgroundColor.current) {
return;
}

statusBarAnimation.value = 0;
statusBarAnimation.value = withDelay(
300,
withTiming(1, {
duration: 300,
easing: Easing.in,
}),
);
};

const updateSavedNavigationStateAndLogRoute = (state) => {
if (!state) {
return;
}
navigationStateRef.current = state;
props.updateCurrentReportID(state);
updateCurrentReportID(state);
parseAndLogRoute(state);
animateStatusBarBackgroundColor();
};

return (
<NavigationContainer
key={props.isSmallScreenWidth ? 'small' : 'big'}
key={isSmallScreenWidth ? 'small' : 'big'}
onStateChange={updateSavedNavigationStateAndLogRoute}
initialState={navigationStateRef.current}
onReady={props.onReady}
Expand All @@ -85,4 +120,4 @@ function NavigationRoot(props) {

NavigationRoot.displayName = 'NavigationRoot';
NavigationRoot.propTypes = propTypes;
export default compose(withWindowDimensions, withCurrentReportID)(NavigationRoot);
export default NavigationRoot;
4 changes: 4 additions & 0 deletions src/libs/StatusBar/index.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@ import {StatusBar} from 'react-native';
// Only has custom web implementation
StatusBar.getBackgroundColor = () => null;

// 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;

// Just export StatusBar – no changes.
export default StatusBar;
5 changes: 5 additions & 0 deletions src/styles/themes/default.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable no-unused-vars */
import colors from '../colors';
import SCREENS from '../../SCREENS';

const darkTheme = {
// Figma keys
Expand Down Expand Up @@ -77,6 +78,10 @@ const darkTheme = {
ourMentionBG: colors.green600,
};

darkTheme.PAGE_BACKGROUND_COLORS = {
[SCREENS.HOME]: darkTheme.sidebar,
};

const oldTheme = {
shadow: colors.black,
link: colors.blue,
Expand Down

0 comments on commit c83b2d1

Please sign in to comment.