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 issue: Android - Chat - "Go back to homepage" link, leads to chat again and not to inbox #192

Merged
merged 2 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ComposeProviders from './components/ComposeProviders';
import CustomStatusBarAndBackground from './components/CustomStatusBarAndBackground';
import CustomStatusBarAndBackgroundContextProvider from './components/CustomStatusBarAndBackground/CustomStatusBarAndBackgroundContextProvider';
import ErrorBoundary from './components/ErrorBoundary';
import FullScreenBlockingViewContextProvider from './components/FullScreenBlockingViewContextProvider';
import HTMLEngineProvider from './components/HTMLEngineProvider';
import InitialURLContextProvider from './components/InitialURLContextProvider';
import {InputBlurContextProvider} from './components/InputBlurContext';
Expand Down Expand Up @@ -96,6 +97,7 @@ function App({url}: AppProps) {
SearchRouterContextProvider,
ProductTrainingContextProvider,
InputBlurContextProvider,
FullScreenBlockingViewContextProvider,
]}
>
<CustomStatusBarAndBackground />
Expand Down
14 changes: 13 additions & 1 deletion src/components/BlockingViews/ForceFullScreenView/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import React from 'react';
import {useRoute} from '@react-navigation/native';
import React, {useContext, useEffect} from 'react';
import {View} from 'react-native';
import {FullScreenBlockingViewContext} from '@components/FullScreenBlockingViewContextProvider';
import useThemeStyles from '@hooks/useThemeStyles';
import type ForceFullScreenViewProps from './types';

function ForceFullScreenView({children, shouldForceFullScreen = false}: ForceFullScreenViewProps) {
const route = useRoute();
const styles = useThemeStyles();
const {addRouteKey, removeRouteKey} = useContext(FullScreenBlockingViewContext);

useEffect(() => {
if (!shouldForceFullScreen) {
addRouteKey(route.key);
}

return () => removeRouteKey(route.key);
}, [addRouteKey, removeRouteKey, route, shouldForceFullScreen]);

if (shouldForceFullScreen) {
return <View style={styles.forcedBlockingViewContainer}>{children}</View>;
Expand Down
2 changes: 1 addition & 1 deletion src/components/BlockingViews/FullPageNotFoundView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function FullPageNotFoundView({
onBackButtonPress = () => Navigation.goBack(),
shouldShowLink = true,
shouldShowBackButton = true,
onLinkPress = () => Navigation.dismissModal(),
onLinkPress = () => Navigation.goBackToHome(),
shouldForceFullScreen = false,
}: FullPageNotFoundViewProps) {
const styles = useThemeStyles();
Expand Down
54 changes: 54 additions & 0 deletions src/components/FullScreenBlockingViewContextProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, {createContext, useCallback, useMemo, useState} from 'react';

type FullScreenBlockingViewContextValue = {
addRouteKey: (key: string) => void;
removeRouteKey: (key: string) => void;
isBlockingViewVisible: boolean;
};

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

const defaultValue: FullScreenBlockingViewContextValue = {
addRouteKey: () => {},
removeRouteKey: () => {},
isBlockingViewVisible: false,
};

const FullScreenBlockingViewContext = createContext<FullScreenBlockingViewContextValue>(defaultValue);

function FullScreenBlockingViewContextProvider({children}: FullScreenBlockingViewContextProviderProps) {
const [routeKeys, setRouteKeys] = useState<Set<string>>(new Set());

const addRouteKey = useCallback((key: string) => {
setRouteKeys((prevKeys) => new Set(prevKeys).add(key));
}, []);

const removeRouteKey = useCallback((key: string) => {
setRouteKeys((prevKeys) => {
const newKeys = new Set(prevKeys);
newKeys.delete(key);
return newKeys;
});
}, []);

const isBlockingViewVisible = useMemo(() => routeKeys.size > 0, [routeKeys]);

const contextValue = useMemo(
() => ({
addRouteKey,
removeRouteKey,
isBlockingViewVisible,
}),
[addRouteKey, removeRouteKey, isBlockingViewVisible],
);

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

export default FullScreenBlockingViewContextProvider;

export {FullScreenBlockingViewContext};

export type {FullScreenBlockingViewContextProviderProps, FullScreenBlockingViewContextValue};
6 changes: 4 additions & 2 deletions src/components/Navigation/TopLevelBottomTabBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {findFocusedRoute, useNavigationState} from '@react-navigation/native';
import React, {useEffect, useRef, useState} from 'react';
import React, {useContext, useEffect, useRef, useState} from 'react';
import {InteractionManager, View} from 'react-native';
import {FullScreenBlockingViewContext} from '@components/FullScreenBlockingViewContextProvider';
import BottomTabBar from '@components/Navigation/BottomTabBar';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useStyledSafeAreaInsets from '@hooks/useStyledSafeAreaInsets';
Expand Down Expand Up @@ -29,6 +30,7 @@ function TopLevelBottomTabBar() {
const {paddingBottom} = useStyledSafeAreaInsets();
const [isAfterClosingTransition, setIsAfterClosingTransition] = useState(false);
const cancelAfterInteractions = useRef<ReturnType<typeof InteractionManager.runAfterInteractions> | undefined>();
const {isBlockingViewVisible} = useContext(FullScreenBlockingViewContext);

const selectedTab = useNavigationState((state) => {
const topmostFullScreenRoute = state?.routes.findLast((route) => isFullScreenName(route.name));
Expand All @@ -48,7 +50,7 @@ function TopLevelBottomTabBar() {
const isBottomTabVisibleDirectly = useIsBottomTabVisibleDirectly();

const shouldDisplayBottomBar = shouldUseNarrowLayout ? isScreenWithBottomTabFocused : isBottomTabVisibleDirectly;
const isReadyToDisplayBottomBar = isAfterClosingTransition && shouldDisplayBottomBar;
const isReadyToDisplayBottomBar = isAfterClosingTransition && shouldDisplayBottomBar && !isBlockingViewVisible;

useEffect(() => {
cancelAfterInteractions.current?.cancel();
Expand Down
35 changes: 28 additions & 7 deletions src/libs/Navigation/Navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,32 +250,31 @@ const defaultGoBackOptions: Required<GoBackOptions> = {
* @param options - Optional configuration that affects navigation logic, such as parameter comparison.
*/
function goUp(fallbackRoute: Route, options?: GoBackOptions) {
if (!canNavigate('goUp')) {
if (!canNavigate('goUp') || !navigationRef.current) {
Log.hmmm(`[Navigation] Unable to go up. Can't navigate.`);
return;
}

if (!navigationRef.current) {
Log.hmmm('[Navigation] Unable to go up');
return;
}
const compareParams = options?.compareParams ?? defaultGoBackOptions.compareParams;

const rootState = navigationRef.current.getRootState();
const stateFromPath = getStateFromPath(fallbackRoute);

const action = getActionFromState(stateFromPath, linkingConfig.config);

if (!action) {
Log.hmmm(`[Navigation] Unable to go up. Action is undefined.`);
return;
}

const {action: minimalAction, targetState} = getMinimalAction(action, rootState);

if (minimalAction.type !== CONST.NAVIGATION.ACTION_TYPE.NAVIGATE || !targetState) {
Log.hmmm('[Navigation] Unable to go up. Minimal action type is wrong.');
return;
}

const compareParams = options?.compareParams ?? defaultGoBackOptions.compareParams;
const indexOfFallbackRoute = targetState.routes.findLastIndex((route) => doesRouteMatchToMinimalActionPayload(route, minimalAction, compareParams));

const distanceToPop = targetState.routes.length - indexOfFallbackRoute - 1;

// If we need to pop more than one route from rootState, we replace the current route to not lose visited routes from the navigation state
Expand Down Expand Up @@ -343,6 +342,27 @@ function resetToHome() {
navigationRef.dispatch({payload, type: CONST.NAVIGATION.ACTION_TYPE.REPLACE, target: rootState.key});
}

/**
* The goBack function doesn't support recursive pop e.g. pop route from root and then from nested navigator.
* There is only one case where recursive pop is needed which is going back to home.
* This function will cover this case.
* We will implement recursive pop if more use cases will appear.
*/
function goBackToHome() {
const isNarrowLayout = getIsNarrowLayout();

// This set the right split navigator.
goBack(ROUTES.HOME);

// We want to keep the report screen in the split navigator on wide layout.
if (!isNarrowLayout) {
return;
}

// This set the right route in this split navigator.
goBack(ROUTES.HOME);
}

/**
* Update route params for the specified route.
*/
Expand Down Expand Up @@ -550,6 +570,7 @@ export default {
waitForProtectedRoutes,
parseHybridAppUrl,
resetToHome,
goBackToHome,
closeRHPFlow,
setNavigationActionToMicrotaskQueue,
navigateToReportWithPolicyCheck,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function CardSection() {
const requestRefund = useCallback(() => {
requestRefundByUser();
setIsRequestRefundModalVisible(false);
Navigation.goBack(ROUTES.HOME);
Navigation.goBackToHome();
}, []);

const viewPurchases = useCallback(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/pages/workspace/WorkspaceInitialPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
>
<FullPageNotFoundView
onBackButtonPress={Navigation.dismissModal}
onLinkPress={() => Navigation.goBack(ROUTES.HOME)}
onLinkPress={Navigation.goBackToHome}
shouldShow={shouldShowNotFoundPage}
subtitleKey={shouldShowPolicy ? 'workspace.common.notAuthorized' : undefined}
>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/workspace/WorkspacePageWithSections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ function WorkspacePageWithSections({
>
<FullPageNotFoundView
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)}
onLinkPress={() => Navigation.goBack(ROUTES.HOME)}
onLinkPress={Navigation.goBackToHome}
shouldShow={shouldShow}
subtitleKey={shouldShowPolicy ? 'workspace.common.notAuthorized' : undefined}
shouldForceFullScreen
Expand Down
Loading