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

Fix svg background image appears late in login screen #35038

9 changes: 8 additions & 1 deletion src/Expensify.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ const propTypes = {
/** Tells us if the sidebar has rendered */
isSidebarLoaded: PropTypes.bool,

/** Tells us if the boot splash is auto hide */
isBootSplashAutoHide: PropTypes.bool,

/** Information about a screen share call requested by a GuidesPlus agent */
screenShareRequest: PropTypes.shape({
/** Access token required to join a screen share room, generated by the backend */
Expand All @@ -89,6 +92,7 @@ const defaultProps = {
},
updateAvailable: false,
isSidebarLoaded: false,
isBootSplashAutoHide: true,
screenShareRequest: null,
isCheckingPublicRoom: true,
focusModeNotification: false,
Expand Down Expand Up @@ -121,7 +125,7 @@ function Expensify(props) {
);

const shouldInit = isNavigationReady && (!isAuthenticated || props.isSidebarLoaded) && hasAttemptedToOpenPublicRoom;
const shouldHideSplash = shouldInit && !isSplashHidden;
const shouldHideSplash = shouldInit && !isSplashHidden && props.isBootSplashAutoHide;

const initializeClient = () => {
if (!Visibility.isVisible()) {
Expand Down Expand Up @@ -265,6 +269,9 @@ export default compose(
isSidebarLoaded: {
key: ONYXKEYS.IS_SIDEBAR_LOADED,
},
isBootSplashAutoHide: {
key: ONYXKEYS.IS_BOOT_SPLASH_AUTO_HIDE,
},
screenShareRequest: {
key: ONYXKEYS.SCREEN_SHARE_REQUEST,
},
Expand Down
4 changes: 4 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ const ONYXKEYS = {
/** Boolean flag set whenever the sidebar has loaded */
IS_SIDEBAR_LOADED: 'isSidebarLoaded',

/** Boolean flag set whenever the sidebar has loaded */
IS_BOOT_SPLASH_AUTO_HIDE: 'isBootSplashAutoHide',

/** Boolean flag set whenever we are searching for reports in the server */
IS_SEARCHING_FOR_REPORTS: 'isSearchingForReports',

Expand Down Expand Up @@ -373,6 +376,7 @@ type OnyxValues = {
[ONYXKEYS.ACTIVE_CLIENTS]: string[];
[ONYXKEYS.DEVICE_ID]: string;
[ONYXKEYS.IS_SIDEBAR_LOADED]: boolean;
[ONYXKEYS.IS_BOOT_SPLASH_AUTO_HIDE]: boolean;
[ONYXKEYS.PERSISTED_REQUESTS]: OnyxTypes.Request[];
[ONYXKEYS.CURRENT_DATE]: string;
[ONYXKEYS.CREDENTIALS]: OnyxTypes.Credentials;
Expand Down
25 changes: 25 additions & 0 deletions src/libs/actions/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ Onyx.connect({
initWithStoredValues: false,
});

let isBootSplashAutoHide: boolean | null;
Onyx.connect({
key: ONYXKEYS.IS_BOOT_SPLASH_AUTO_HIDE,
callback: (val) => (isBootSplashAutoHide = val),
initWithStoredValues: true,
});

let preferredLocale: string | null;
Onyx.connect({
key: ONYXKEYS.NVP_PREFERRED_LOCALE,
Expand Down Expand Up @@ -129,6 +136,22 @@ function setSidebarLoaded() {
Performance.markStart(CONST.TIMING.REPORT_INITIAL_RENDER);
}

function preventBootSplashAutoHide() {
if (!isBootSplashAutoHide) {
return;
}

Onyx.set(ONYXKEYS.IS_BOOT_SPLASH_AUTO_HIDE, false);
}

function resetBootSplashAutoHide() {
if (isBootSplashAutoHide) {
return;
}

Onyx.set(ONYXKEYS.IS_BOOT_SPLASH_AUTO_HIDE, true);
}

let appState: AppStateStatus;
AppState.addEventListener('change', (nextAppState) => {
if (nextAppState.match(/inactive|background/) && appState === 'active') {
Expand Down Expand Up @@ -531,6 +554,8 @@ export {
setLocale,
setLocaleAndNavigate,
setSidebarLoaded,
preventBootSplashAutoHide,
resetBootSplashAutoHide,
setUpPoliciesAndNavigate,
openProfile,
redirectThirdPartyDesktopSignIn,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
import {Image} from 'expo-image';
import PropTypes from 'prop-types';
import React from 'react';
import AndroidBackgroundImage from '@assets/images/home-background--android.svg';
import useThemeStyles from '@hooks/useThemeStyles';
import defaultPropTypes from './propTypes';

const defaultProps = {
onLoadEnd: () => {},
};

const propTypes = {
/** Called when the image load either succeeds or fails. */
onLoadEnd: PropTypes.func,

...defaultPropTypes,
};

function BackgroundImage(props) {
const styles = useThemeStyles();
return (
<Image
source={AndroidBackgroundImage}
pointerEvents={props.pointerEvents}
style={[styles.signInBackground, {width: props.width}]}
onLoadEnd={props.onLoadEnd}
/>
);
}

BackgroundImage.displayName = 'BackgroundImage';
BackgroundImage.propTypes = defaultPropTypes;
BackgroundImage.propTypes = propTypes;
BackgroundImage.defaultProps = defaultProps;

export default BackgroundImage;
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@ import defaultPropTypes from './propTypes';

const defaultProps = {
isSmallScreen: false,
onLoadEnd: () => {},
};

const propTypes = {
/** Is the window width narrow, like on a mobile device */
isSmallScreen: PropTypes.bool,

/** Called when the image load either succeeds or fails. */
onLoadEnd: PropTypes.func,

...defaultPropTypes,
};

function BackgroundImage(props) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
Expand All @@ -26,6 +31,7 @@ function BackgroundImage(props) {
<Image
source={src}
style={[styles.signInBackground, StyleUtils.getWidthStyle(props.width)]}
onLoadEnd={props.onLoadEnd}
/>
);
}
Expand Down
13 changes: 12 additions & 1 deletion src/pages/signin/SignInPageLayout/BackgroundImage/index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
import PropTypes from 'prop-types';
import React from 'react';
import React, {useEffect} from 'react';
import DesktopBackgroundImage from '@assets/images/home-background--desktop.svg';
import MobileBackgroundImage from '@assets/images/home-background--mobile.svg';
import useThemeStyles from '@hooks/useThemeStyles';
import defaultPropTypes from './propTypes';

const defaultProps = {
isSmallScreen: false,
onLoadEnd: () => {},
};

const propTypes = {
/** Is the window width narrow, like on a mobile device */
isSmallScreen: PropTypes.bool,

/** Called when the image load either succeeds or fails. */
onLoadEnd: PropTypes.func,

...defaultPropTypes,
};

function BackgroundImage(props) {
const styles = useThemeStyles();

useEffect(() => {
props.onLoadEnd();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return props.isSmallScreen ? (
<MobileBackgroundImage
width={props.width}
Expand Down
18 changes: 17 additions & 1 deletion src/pages/signin/SignInPageLayout/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import PropTypes from 'prop-types';
import React, {forwardRef, useEffect, useImperativeHandle, useMemo, useRef} from 'react';
import React, {forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react';
import {ScrollView, View} from 'react-native';
import {withSafeAreaInsets} from 'react-native-safe-area-context';
import SignInGradient from '@assets/images/home-fade-gradient.svg';
import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
import ImageSVG from '@components/ImageSVG';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import usePrevious from '@hooks/usePrevious';
Expand All @@ -13,6 +14,7 @@ import useWindowDimensions from '@hooks/useWindowDimensions';
import compose from '@libs/compose';
import SignInPageHero from '@pages/signin/SignInPageHero';
import variables from '@styles/variables';
import * as App from '@userActions/App';
import BackgroundImage from './BackgroundImage';
import Footer from './Footer';
import SignInPageContent from './SignInPageContent';
Expand Down Expand Up @@ -67,6 +69,7 @@ function SignInPageLayout(props) {
let containerStyles = [styles.flex1, styles.signInPageInner];
let contentContainerStyles = [styles.flex1, styles.flexRow];
const {windowHeight} = useWindowDimensions();
const [isLoading, setIsLoading] = useState(true);

// To scroll on both mobile and web, we need to set the container height manually
const containerHeight = windowHeight - props.insets.top - props.insets.bottom;
Expand All @@ -87,6 +90,10 @@ function SignInPageLayout(props) {
scrollPageToTop,
}));

useEffect(() => {
App.preventBootSplashAutoHide();
}, []);

useEffect(() => {
if (prevPreferredLocale !== props.preferredLocale) {
return;
Expand All @@ -99,6 +106,7 @@ function SignInPageLayout(props) {

return (
<View style={containerStyles}>
{isLoading && <FullScreenLoadingIndicator style={[styles.opacity1]} />}
{!props.shouldShowSmallScreen ? (
<View style={contentContainerStyles}>
<ScrollView
Expand Down Expand Up @@ -127,6 +135,10 @@ function SignInPageLayout(props) {
isSmallScreen={false}
pointerEvents="none"
width={variables.signInHeroBackgroundWidth}
onLoadEnd={() => {
setIsLoading(false);
App.resetBootSplashAutoHide();
}}
/>
</View>
<View>
Expand Down Expand Up @@ -166,6 +178,10 @@ function SignInPageLayout(props) {
isSmallScreen
pointerEvents="none"
width={variables.signInHeroBackgroundWidthMobile}
onLoadEnd={() => {
setIsLoading(false);
App.resetBootSplashAutoHide();
}}
/>
<SignInPageContent
welcomeHeader={props.welcomeHeader}
Expand Down
1 change: 1 addition & 0 deletions src/setup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default function () {
[ONYXKEYS.ACCOUNT]: CONST.DEFAULT_ACCOUNT_DATA,
[ONYXKEYS.NETWORK]: {isOffline: false},
[ONYXKEYS.IS_SIDEBAR_LOADED]: false,
[ONYXKEYS.IS_BOOT_SPLASH_AUTO_HIDE]: true,
[ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT]: true,
[ONYXKEYS.MODAL]: {
isVisible: false,
Expand Down
Loading