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

[ideal-nav] Bottom tab navigator #32993

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5201869
add const for bottom tab
adamgrzybowski Dec 12, 2023
4f6e869
patch for react-navigation
adamgrzybowski Dec 12, 2023
1592ff8
styles for bottom tab navigator
adamgrzybowski Dec 12, 2023
4696731
public bottom tab navigator
adamgrzybowski Dec 13, 2023
0f61ed9
move workspace screens
adamgrzybowski Dec 13, 2023
c6f1600
improve types for tab to central pane mapping
adamgrzybowski Dec 13, 2023
2a22d8a
prepare BottomTabBarFloatingActionButton
adamgrzybowski Dec 13, 2023
593618f
move tab to central pane mapping
adamgrzybowski Dec 13, 2023
70b3db6
add and modify navigation types
adamgrzybowski Dec 13, 2023
018c055
add helpers for navigation
adamgrzybowski Dec 13, 2023
c1613c8
modify linking config
adamgrzybowski Dec 13, 2023
2d0c560
add bottomTabBar
adamgrzybowski Dec 13, 2023
62a63ec
add comment to the PublicBottomTabNavigator
adamgrzybowski Dec 13, 2023
32ba7c6
update type in Navigation.js
adamgrzybowski Dec 13, 2023
c0f1351
use proper color for BottomTabBar
adamgrzybowski Dec 13, 2023
7b4cef9
add bottom tab navigator
adamgrzybowski Dec 13, 2023
2a23586
move trigger for state rehydration to createCustomStackNavigator
adamgrzybowski Dec 13, 2023
644c770
modify custom router for the CustomStackNavigator
adamgrzybowski Dec 13, 2023
0c75097
modify linkTo
adamgrzybowski Dec 13, 2023
4050128
fix linting errors
adamgrzybowski Dec 13, 2023
8706109
add POP_TO_TOP when navigating to bottom tab on small screen
adamgrzybowski Dec 15, 2023
8be9983
add removed workspace currency page
adamgrzybowski Dec 15, 2023
6eb6398
change workspace settings to workspace overview
adamgrzybowski Dec 15, 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
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ index 7558eb3..b7bb75e 100644
}) : STATE_TRANSITIONING_OR_BELOW_TOP;
}
+
+ const isHomeScreenAndNotOnTop = route.name === 'Home' && isScreenActive !== STATE_ON_TOP;
+ const isHomeScreenAndNotOnTop = route.name === 'BottomTabNavigator' && isScreenActive !== STATE_ON_TOP;
+
const {
headerShown = true,
Expand Down
2 changes: 1 addition & 1 deletion src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1404,7 +1404,7 @@ const CONST = {
GUIDES_CALL_TASK_IDS: {
CONCIERGE_DM: 'NewExpensifyConciergeDM',
WORKSPACE_INITIAL: 'WorkspaceHome',
WORKSPACE_SETTINGS: 'WorkspaceGeneralSettings',
WORKSPACE_OVERVIEW: 'WorkspaceGeneralSettings',
WORKSPACE_CARD: 'WorkspaceCorporateCards',
WORKSPACE_REIMBURSE: 'WorkspaceReimburseReceipts',
WORKSPACE_BILLS: 'WorkspacePayBills',
Expand Down
1 change: 1 addition & 0 deletions src/NAVIGATORS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* */
export default {
CENTRAL_PANE_NAVIGATOR: 'CentralPaneNavigator',
BOTTOM_TAB_NAVIGATOR: 'BottomTabNavigator',
RIGHT_MODAL_NAVIGATOR: 'RightModalNavigator',
FULL_SCREEN_NAVIGATOR: 'FullScreenNavigator',
} as const;
14 changes: 8 additions & 6 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ function getUrlWithBackToParam<TUrl extends string>(url: TUrl, backTo?: string):
const ROUTES = {
HOME: '',

ALL_SETTINGS: 'all-settings',

// This is a utility route used to go to the user's concierge chat, or the sign-in page if the user's not authenticated
CONCIERGE: 'concierge',
FLAG_COMMENT: {
Expand Down Expand Up @@ -420,13 +422,13 @@ const ROUTES = {
route: 'workspace/:policyID/invite-message',
getRoute: (policyID: string) => `workspace/${policyID}/invite-message` as const,
},
WORKSPACE_SETTINGS: {
route: 'workspace/:policyID/settings',
getRoute: (policyID: string) => `workspace/${policyID}/settings` as const,
WORKSPACE_OVERVIEW: {
route: 'workspace/:policyID/overview',
getRoute: (policyID: string) => `workspace/${policyID}/overview` as const,
},
WORKSPACE_SETTINGS_CURRENCY: {
route: 'workspace/:policyID/settings/currency',
getRoute: (policyID: string) => `workspace/${policyID}/settings/currency` as const,
WORKSPACE_OVERVIEW_CURRENCY: {
route: 'workspace/:policyID/overview/currency',
getRoute: (policyID: string) => `workspace/${policyID}/overview/currency` as const,
},
WORKSPACE_CARD: {
route: 'workspace/:policyID/card',
Expand Down
5 changes: 3 additions & 2 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const PROTECTED_SCREENS = {

const SCREENS = {
...PROTECTED_SCREENS,
ALL_SETTINGS: 'AllSettings',
REPORT: 'Report',
NOT_FOUND: 'not-found',
TRANSITION_BETWEEN_APPS: 'TransitionBetweenApps',
Expand Down Expand Up @@ -184,7 +185,7 @@ const SCREENS = {

WORKSPACE: {
INITIAL: 'Workspace_Initial',
SETTINGS: 'Workspace_Settings',
OVERVIEW: 'Workspace_Overview',
CARD: 'Workspace_Card',
REIMBURSE: 'Workspace_Reimburse',
RATE_AND_UNIT: 'Workspace_RateAndUnit',
Expand All @@ -194,7 +195,7 @@ const SCREENS = {
MEMBERS: 'Workspace_Members',
INVITE: 'Workspace_Invite',
INVITE_MESSAGE: 'Workspace_Invite_Message',
CURRENCY: 'Workspace_Settings_Currency',
CURRENCY: 'Workspace_Overview_Currency',
},

EDIT_REQUEST: {
Expand Down
50 changes: 24 additions & 26 deletions src/components/FloatingActionButton.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React, {PureComponent} from 'react';
import {Animated, Easing, View} from 'react-native';
import {Animated, Easing} from 'react-native';
import compose from '@libs/compose';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
Expand Down Expand Up @@ -84,31 +84,29 @@ class FloatingActionButton extends PureComponent {

return (
<Tooltip text={this.props.translate('common.new')}>
<View style={this.props.themeStyles.floatingActionButtonContainer}>
<AnimatedPressable
ref={(el) => {
this.fabPressable = el;
if (this.props.buttonRef) {
this.props.buttonRef.current = el;
}
}}
accessibilityLabel={this.props.accessibilityLabel}
role={this.props.role}
pressDimmingValue={1}
onPress={(e) => {
// Drop focus to avoid blue focus ring.
this.fabPressable.blur();
this.props.onPress(e);
}}
onLongPress={() => {}}
style={[this.props.themeStyles.floatingActionButton, this.props.StyleUtils.getAnimatedFABStyle(rotate, backgroundColor)]}
>
<AnimatedIcon
src={Expensicons.Plus}
fill={fill}
/>
</AnimatedPressable>
</View>
<AnimatedPressable
ref={(el) => {
this.fabPressable = el;
if (this.props.buttonRef) {
this.props.buttonRef.current = el;
}
}}
accessibilityLabel={this.props.accessibilityLabel}
role={this.props.role}
pressDimmingValue={1}
onPress={(e) => {
// Drop focus to avoid blue focus ring.
this.fabPressable.blur();
this.props.onPress(e);
}}
onLongPress={() => {}}
style={[this.props.themeStyles.floatingActionButton, this.props.StyleUtils.getAnimatedFABStyle(rotate, backgroundColor)]}
>
<AnimatedIcon
src={Expensicons.Plus}
fill={fill}
/>
</AnimatedPressable>
</Tooltip>
);
}
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1455,6 +1455,7 @@ export default {
invoices: 'Invoices',
travel: 'Travel',
members: 'Members',
overview: 'Overview',
bankAccount: 'Bank account',
connectBankAccount: 'Connect bank account',
testTransactions: 'Test transactions',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1478,6 +1478,7 @@ export default {
invoices: 'Enviar facturas',
travel: 'Viajes',
members: 'Miembros',
overview: 'Descripción',
bankAccount: 'Cuenta bancaria',
connectBankAccount: 'Conectar cuenta bancaria',
testTransactions: 'Transacciones de prueba',
Expand Down
6 changes: 3 additions & 3 deletions src/libs/Navigation/AppNavigator/AuthScreens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import type {SelectedTimezone, Timezone} from '@src/types/onyx/PersonalDetails';
import createCustomStackNavigator from './createCustomStackNavigator';
import defaultScreenOptions from './defaultScreenOptions';
import getRootNavigatorScreenOptions from './getRootNavigatorScreenOptions';
import BottomTabNavigator from './Navigators/BottomTabNavigator';
import CentralPaneNavigator from './Navigators/CentralPaneNavigator';
import RightModalNavigator from './Navigators/RightModalNavigator';

Expand All @@ -56,7 +57,6 @@ type AuthScreensProps = {
};

const loadReportAttachments = () => require('../../../pages/home/report/ReportAttachments').default as React.ComponentType;
const loadSidebarScreen = () => require('../../../pages/home/sidebar/SidebarScreen').default as React.ComponentType;
const loadValidateLoginPage = () => require('../../../pages/ValidateLoginPage').default as React.ComponentType;
const loadLogOutPreviousUserPage = () => require('../../../pages/LogOutPreviousUserPage').default as React.ComponentType;
const loadConciergePage = () => require('../../../pages/ConciergePage').default as React.ComponentType;
Expand Down Expand Up @@ -255,9 +255,9 @@ function AuthScreens({lastUpdateIDAppliedToClient, session, lastOpenedPublicRoom
<View style={styles.rootNavigatorContainerStyles(isSmallScreenWidth)}>
<RootStack.Navigator isSmallScreenWidth={isSmallScreenWidth}>
<RootStack.Screen
name={SCREENS.HOME}
name={NAVIGATORS.BOTTOM_TAB_NAVIGATOR}
options={screenOptions.homeScreen}
getComponent={loadSidebarScreen}
component={BottomTabNavigator}
/>
<RootStack.Screen
name={NAVIGATORS.CENTRAL_PANE_NAVIGATOR}
Expand Down
11 changes: 1 addition & 10 deletions src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ const NewTeachersUniteNavigator = createModalStackNavigator<TeachersUniteNavigat
const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorParamList>({
[SCREENS.SETTINGS.ROOT]: () => require('../../../pages/settings/InitialSettingsPage').default as React.ComponentType,
[SCREENS.SETTINGS.SHARE_CODE]: () => require('../../../pages/ShareCodePage').default as React.ComponentType,
[SCREENS.SETTINGS.WORKSPACES]: () => require('../../../pages/workspace/WorkspacesListPage').default as React.ComponentType,
[SCREENS.SETTINGS.PROFILE.ROOT]: () => require('../../../pages/settings/Profile/ProfilePage').default as React.ComponentType,
[SCREENS.SETTINGS.PROFILE.PRONOUNS]: () => require('../../../pages/settings/Profile/PronounsPage').default as React.ComponentType,
[SCREENS.SETTINGS.PROFILE.DISPLAY_NAME]: () => require('../../../pages/settings/Profile/DisplayNamePage').default as React.ComponentType,
Expand Down Expand Up @@ -220,16 +219,8 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.SETTINGS.ADD_BANK_ACCOUNT]: () => require('../../../pages/AddPersonalBankAccountPage').default as React.ComponentType,
[SCREENS.SETTINGS.PROFILE.STATUS]: () => require('../../../pages/settings/Profile/CustomStatus/StatusPage').default as React.ComponentType,
[SCREENS.SETTINGS.PROFILE.STATUS_SET]: () => require('../../../pages/settings/Profile/CustomStatus/StatusSetPage').default as React.ComponentType,
[SCREENS.WORKSPACE.INITIAL]: () => require('../../../pages/workspace/WorkspaceInitialPage').default as React.ComponentType,
[SCREENS.WORKSPACE.SETTINGS]: () => require('../../../pages/workspace/WorkspaceSettingsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.CURRENCY]: () => require('../../../pages/workspace/WorkspaceSettingsCurrencyPage').default as React.ComponentType,
[SCREENS.WORKSPACE.CARD]: () => require('../../../pages/workspace/card/WorkspaceCardPage').default as React.ComponentType,
[SCREENS.WORKSPACE.REIMBURSE]: () => require('../../../pages/workspace/reimburse/WorkspaceReimbursePage').default as React.ComponentType,
[SCREENS.WORKSPACE.RATE_AND_UNIT]: () => require('../../../pages/workspace/reimburse/WorkspaceRateAndUnitPage').default as React.ComponentType,
[SCREENS.WORKSPACE.BILLS]: () => require('../../../pages/workspace/bills/WorkspaceBillsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.INVOICES]: () => require('../../../pages/workspace/invoices/WorkspaceInvoicesPage').default as React.ComponentType,
[SCREENS.WORKSPACE.TRAVEL]: () => require('../../../pages/workspace/travel/WorkspaceTravelPage').default as React.ComponentType,
[SCREENS.WORKSPACE.MEMBERS]: () => require('../../../pages/workspace/WorkspaceMembersPage').default as React.ComponentType,
[SCREENS.WORKSPACE.CURRENCY]: () => require('../../../pages/workspace/WorkspaceOverviewCurrencyPage').default as React.ComponentType,
[SCREENS.WORKSPACE.INVITE]: () => require('../../../pages/workspace/WorkspaceInvitePage').default as React.ComponentType,
[SCREENS.WORKSPACE.INVITE_MESSAGE]: () => require('../../../pages/workspace/WorkspaceInviteMessagePage').default as React.ComponentType,
[SCREENS.REIMBURSEMENT_ACCOUNT]: () => require('../../../pages/ReimbursementAccount/ReimbursementAccountPage').default as React.ComponentType,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {StackNavigationOptions} from '@react-navigation/stack';
import React from 'react';
import {Text, View} from 'react-native';
import {PressableWithFeedback} from '@components/Pressable';
import createCustomBottomTabNavigator from '@libs/Navigation/AppNavigator/createCustomBottomTabNavigator';
import Navigation from '@libs/Navigation/Navigation';
import {BottomTabNavigatorParamList} from '@libs/Navigation/types';
import SidebarScreen from '@pages/home/sidebar/SidebarScreen';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import SCREENS from '@src/SCREENS';

const loadWorkspaceInitialPage = () => require('../../../../pages/workspace/WorkspaceInitialPage').default as React.ComponentType;

const Tab = createCustomBottomTabNavigator<BottomTabNavigatorParamList>();

// TODO-IDEAL replace with the actuall screen.
function SecondTab() {
return (
<View>
<Text style={{color: 'white', fontSize: 30}}>Expensify settings</Text>

<PressableWithFeedback
role={CONST.ACCESSIBILITY_ROLE.BUTTON}
accessibilityLabel="Workspaces"
onPress={() => {
Navigation.navigate(ROUTES.SETTINGS_WORKSPACES);
}}
>
<Text style={{color: 'white', fontSize: 30}}>Workspaces</Text>
</PressableWithFeedback>
</View>
);
}

const screenOptions: StackNavigationOptions = {
headerShown: false,
};

function BottomTabNavigator() {
return (
<Tab.Navigator screenOptions={screenOptions}>
<Tab.Screen
name={SCREENS.HOME}
component={SidebarScreen}
/>
<Tab.Screen
name={SCREENS.ALL_SETTINGS}
component={SecondTab}
/>
<Tab.Screen
name={SCREENS.WORKSPACE.INITIAL}
getComponent={loadWorkspaceInitialPage}
/>
</Tab.Navigator>
);
}

BottomTabNavigator.displayName = 'BottomTabNavigator';

export default BottomTabNavigator;
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,44 @@ const Stack = createStackNavigator<CentralPaneNavigatorParamList>();
const url = getCurrentUrl();
const openOnAdminRoom = url ? new URL(url).searchParams.get('openOnAdminRoom') : undefined;

type Screens = Partial<Record<keyof CentralPaneNavigatorParamList, () => React.ComponentType>>;

const workspaceSettingsScreens = {
[SCREENS.SETTINGS.WORKSPACES]: () => require('../../../../../pages/workspace/WorkspacesListPage').default as React.ComponentType,
[SCREENS.WORKSPACE.OVERVIEW]: () => require('../../../../../pages/workspace/WorkspaceOverviewPage').default as React.ComponentType,
[SCREENS.WORKSPACE.CARD]: () => require('../../../../../pages/workspace/card/WorkspaceCardPage').default as React.ComponentType,
[SCREENS.WORKSPACE.REIMBURSE]: () => require('../../../../../pages/workspace/reimburse/WorkspaceReimbursePage').default as React.ComponentType,
[SCREENS.WORKSPACE.BILLS]: () => require('../../../../../pages/workspace/bills/WorkspaceBillsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.INVOICES]: () => require('../../../../../pages/workspace/invoices/WorkspaceInvoicesPage').default as React.ComponentType,
[SCREENS.WORKSPACE.TRAVEL]: () => require('../../../../../pages/workspace/travel/WorkspaceTravelPage').default as React.ComponentType,
[SCREENS.WORKSPACE.MEMBERS]: () => require('../../../../../pages/workspace/WorkspaceMembersPage').default as React.ComponentType,
} satisfies Screens;

function BaseCentralPaneNavigator() {
const styles = useThemeStyles();
const options = {
headerShown: false,
title: 'New Expensify',

// Prevent unnecessary scrolling
cardStyle: styles.cardStyleNavigator,
};
return (
<Stack.Navigator>
<Stack.Navigator screenOptions={options}>
<Stack.Screen
name={SCREENS.REPORT}
// We do it this way to avoid adding the url params to url
initialParams={{openOnAdminRoom: openOnAdminRoom === 'true' || undefined}}
options={{
headerShown: false,
title: 'New Expensify',

// Prevent unnecessary scrolling
cardStyle: styles.cardStyleNavigator,
}}
component={ReportScreenWrapper}
/>

{Object.entries(workspaceSettingsScreens).map(([screenName, componentGetter]) => (
<Stack.Screen
key={screenName}
name={screenName as keyof Screens}
getComponent={componentGetter}
/>
))}
</Stack.Navigator>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {StackNavigationOptions} from '@react-navigation/stack';
import React from 'react';
import createCustomBottomTabNavigator from '@libs/Navigation/AppNavigator/createCustomBottomTabNavigator';
import {BottomTabNavigatorParamList} from '@libs/Navigation/types';
import SignInPage from '@pages/signin/SignInPage';
import SCREENS from '@src/SCREENS';

// This type is not exactly right because we are using the same route in public and auth screens.
const Tab = createCustomBottomTabNavigator<BottomTabNavigatorParamList>();

const screenOptions: StackNavigationOptions = {
headerShown: false,
};

// The structure for the HOME route have to be the same in public and auth screens. That's why we need to wrap the HOME screen with "fake" bottomTabNavigator.
function PublicBottomTabNavigator() {
return (
<Tab.Navigator screenOptions={screenOptions}>
<Tab.Screen
name={SCREENS.HOME}
component={SignInPage}
/>
</Tab.Navigator>
);
}

PublicBottomTabNavigator.displayName = 'BottomTabNavigator';

export default PublicBottomTabNavigator;
4 changes: 3 additions & 1 deletion src/libs/Navigation/AppNavigator/PublicScreens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import SAMLSignInPage from '@pages/signin/SAMLSignInPage';
import SignInPage from '@pages/signin/SignInPage';
import UnlinkLoginPage from '@pages/UnlinkLoginPage';
import ValidateLoginPage from '@pages/ValidateLoginPage';
import NAVIGATORS from '@src/NAVIGATORS';
import SCREENS from '@src/SCREENS';
import defaultScreenOptions from './defaultScreenOptions';

Expand All @@ -16,8 +17,9 @@ const RootStack = createStackNavigator<PublicScreensParamList>();
function PublicScreens() {
return (
<RootStack.Navigator>
{/* The structure for the HOME route have to be the same in public and auth screens. That's why we need to wrap the HOME screen with "fake" bottomTabNavigator. */}
<RootStack.Screen
name={SCREENS.HOME}
name={NAVIGATORS.BOTTOM_TAB_NAVIGATOR}
options={defaultScreenOptions}
component={SignInPage}
/>
Expand Down
Loading
Loading