From a217f1d6496bd271f3fd37a3bfd153157e300bab Mon Sep 17 00:00:00 2001 From: Maciej Dobosz Date: Tue, 19 Dec 2023 14:20:01 +0100 Subject: [PATCH 01/12] Add subscript icon to SubscriptAvatar --- src/components/Icon/index.tsx | 1 + src/components/SubscriptAvatar.tsx | 94 ++++++++++++++++++++------ src/stories/SubscriptAvatar.stories.js | 15 +++- src/styles/index.ts | 9 +++ 4 files changed, 95 insertions(+), 24 deletions(-) diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index 5f82421c0e8e..0ba7d444324b 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -100,4 +100,5 @@ function Icon({ Icon.displayName = 'Icon'; +export type {IconProps}; export default Icon; diff --git a/src/components/SubscriptAvatar.tsx b/src/components/SubscriptAvatar.tsx index 9a0aa934ff1b..9a224265a341 100644 --- a/src/components/SubscriptAvatar.tsx +++ b/src/components/SubscriptAvatar.tsx @@ -8,8 +8,20 @@ import type {AvatarSource} from '@libs/UserUtils'; import CONST from '@src/CONST'; import {AvatarType} from '@src/types/onyx/OnyxCommon'; import Avatar from './Avatar'; +import Icon, {IconProps} from './Icon'; import UserDetailsTooltip from './UserDetailsTooltip'; +type SubIcon = { + /** Avatar source to display */ + source: IconProps['src']; + + /** Width of the icon */ + width?: number; + + /** Height of the icon */ + height?: number; +}; + type SubAvatar = { /** Avatar source to display */ source?: AvatarSource; @@ -31,15 +43,18 @@ type SubscriptAvatarProps = { /** Avatar URL or icon */ mainAvatar?: SubAvatar; - /** Subscript avatar URL or icon */ - secondaryAvatar?: SubAvatar; - /** Set the size of avatars */ size?: ValueOf; /** Background color used for subscript avatar border */ backgroundColor?: string; + /** Subscript avatar URL or icon */ + secondaryAvatar?: SubAvatar; + + /** Subscript icon type */ + subscriptIcon?: SubIcon; + /** Removes margin from around the avatar, used for the chat view */ noMargin?: boolean; @@ -47,7 +62,15 @@ type SubscriptAvatarProps = { showTooltip?: boolean; }; -function SubscriptAvatar({mainAvatar = {}, secondaryAvatar = {}, size = CONST.AVATAR_SIZE.DEFAULT, backgroundColor, noMargin = false, showTooltip = true}: SubscriptAvatarProps) { +function SubscriptAvatar({ + mainAvatar = {}, + secondaryAvatar, + subscriptIcon, + size = CONST.AVATAR_SIZE.DEFAULT, + backgroundColor, + noMargin = false, + showTooltip = true, +}: SubscriptAvatarProps) { const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -73,31 +96,58 @@ function SubscriptAvatar({mainAvatar = {}, secondaryAvatar = {}, size = CONST.AV /> - + {secondaryAvatar && ( + + + + + + )} + {subscriptIcon && ( - - + )} ); } diff --git a/src/stories/SubscriptAvatar.stories.js b/src/stories/SubscriptAvatar.stories.js index 9ca055aaa5d8..e13e1e6a84b5 100644 --- a/src/stories/SubscriptAvatar.stories.js +++ b/src/stories/SubscriptAvatar.stories.js @@ -1,5 +1,6 @@ import React from 'react'; import * as defaultAvatars from '@components/Icon/DefaultAvatars'; +import * as Expensicons from '@components/Icon/Expensicons'; import * as defaultWorkspaceAvatars from '@components/Icon/WorkspaceDefaultAvatars'; import SubscriptAvatar from '@components/SubscriptAvatar'; import CONST from '@src/CONST'; @@ -14,7 +15,6 @@ export default { component: SubscriptAvatar, args: { mainAvatar: {source: defaultAvatars.Avatar5, name: '', type: CONST.ICON_TYPE_AVATAR}, - secondaryAvatar: {source: defaultWorkspaceAvatars.WorkspaceE, name: '', type: CONST.ICON_TYPE_WORKSPACE}, size: CONST.AVATAR_SIZE.DEFAULT, }, argTypes: { @@ -39,4 +39,15 @@ AvatarURLStory.args = { secondaryAvatar: {source: defaultAvatars.Avatar3, name: '', type: CONST.ICON_TYPE_AVATAR}, }; -export {Default, AvatarURLStory}; +const SubscriptIcon = Template.bind({}); +SubscriptIcon.args = { + subscriptIcon: {source: Expensicons.DownArrow, width: 8, height: 8}, +}; + +const WorkspaceSubscriptIcon = Template.bind({}); +WorkspaceSubscriptIcon.args = { + mainAvatar: {source: defaultAvatars.Avatar1, name: '', type: CONST.ICON_TYPE_WORKSPACE}, + subscriptIcon: {source: Expensicons.DownArrow, width: 8, height: 8}, +}; + +export {Default, AvatarURLStory, SubscriptIcon, WorkspaceSubscriptIcon}; diff --git a/src/styles/index.ts b/src/styles/index.ts index a24d7ffdf869..2353fb89c3b0 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -2142,6 +2142,15 @@ const styles = (theme: ThemeColors) => marginRight: variables.avatarChatSpacing - 4, }, + subscriptIcon: { + position: 'absolute', + bottom: -4, + right: -4, + width: 20, + height: 20, + backgroundColor: theme.buttonDefaultBG, + }, + borderTop: { borderTopWidth: variables.borderTopWidth, borderColor: theme.border, From 3a58c656138b8892998632d8269ecbdc08b1a889 Mon Sep 17 00:00:00 2001 From: Maciej Dobosz Date: Tue, 19 Dec 2023 14:21:33 +0100 Subject: [PATCH 02/12] WorkspaceSwitcherButton --- src/components/Icon/Expensicons.ts | 2 ++ src/components/WorkspaceSwitcherButton.tsx | 30 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/components/WorkspaceSwitcherButton.tsx diff --git a/src/components/Icon/Expensicons.ts b/src/components/Icon/Expensicons.ts index 66a162bf2e5f..6da6ea169471 100644 --- a/src/components/Icon/Expensicons.ts +++ b/src/components/Icon/Expensicons.ts @@ -51,6 +51,7 @@ import EReceiptIcon from '@assets/images/eReceiptIcon.svg'; import Exclamation from '@assets/images/exclamation.svg'; import Exit from '@assets/images/exit.svg'; import Expand from '@assets/images/expand.svg'; +import ExpensifyAppIcon from '@assets/images/expensify-app-icon.svg'; import ExpensifyFooterLogoVertical from '@assets/images/expensify-footer-logo-vertical.svg'; import ExpensifyFooterLogo from '@assets/images/expensify-footer-logo.svg'; import ExpensifyWordmark from '@assets/images/expensify-wordmark.svg'; @@ -182,6 +183,7 @@ export { EmptyStateAttachReceipt, Exclamation, Exit, + ExpensifyAppIcon, ExpensifyCard, ExpensifyWordmark, ExpensifyFooterLogo, diff --git a/src/components/WorkspaceSwitcherButton.tsx b/src/components/WorkspaceSwitcherButton.tsx new file mode 100644 index 000000000000..30a10cc96da0 --- /dev/null +++ b/src/components/WorkspaceSwitcherButton.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import useLocalize from '@hooks/useLocalize'; +import CONST from '@src/CONST'; +import * as Expensicons from './Icon/Expensicons'; +import {PressableWithFeedback} from './Pressable'; +import SubscriptAvatar from './SubscriptAvatar'; + +function WorkspaceSwitcherButton() { + const {translate} = useLocalize(); + + return ( + {}} + > + + + ); +} + +WorkspaceSwitcherButton.displayName = 'WorkspaceSwitcherButton'; + +export default WorkspaceSwitcherButton; From 5c3abec00c041725f7c5d9a27ee5e85b30ac311e Mon Sep 17 00:00:00 2001 From: Maciej Dobosz Date: Tue, 19 Dec 2023 14:26:16 +0100 Subject: [PATCH 03/12] Change default color for border --- src/components/SubscriptAvatar.tsx | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/components/SubscriptAvatar.tsx b/src/components/SubscriptAvatar.tsx index 9a224265a341..05c0aa6138e6 100644 --- a/src/components/SubscriptAvatar.tsx +++ b/src/components/SubscriptAvatar.tsx @@ -62,15 +62,7 @@ type SubscriptAvatarProps = { showTooltip?: boolean; }; -function SubscriptAvatar({ - mainAvatar = {}, - secondaryAvatar, - subscriptIcon, - size = CONST.AVATAR_SIZE.DEFAULT, - backgroundColor, - noMargin = false, - showTooltip = true, -}: SubscriptAvatarProps) { +function SubscriptAvatar({mainAvatar = {}, secondaryAvatar, subscriptIcon, size = CONST.AVATAR_SIZE.DEFAULT, backgroundColor, noMargin = false, showTooltip = true}: SubscriptAvatarProps) { const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -131,7 +123,7 @@ function SubscriptAvatar({ StyleUtils.getAvatarBorderWidth(CONST.AVATAR_SIZE.SMALL), // Nullish coalescing thinks that empty strings are truthy, thus I'm using OR operator // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - StyleUtils.getBorderColorStyle(backgroundColor || theme.componentBG), + StyleUtils.getBorderColorStyle(backgroundColor || theme.sidebar), styles.subscriptIcon, styles.dFlex, styles.justifyContentCenter, From 9875fe7eff9ce4c3b79acd396ca782bb025c91ac Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Tue, 19 Dec 2023 14:56:53 +0100 Subject: [PATCH 04/12] add new search bar --- src/components/IllustratedHeaderPageLayout.js | 4 +- src/languages/en.ts | 2 +- .../createCustomBottomTabNavigator/TopBar.js | 61 +++++++++++++++++++ .../createCustomBottomTabNavigator/index.tsx | 2 + src/pages/home/sidebar/SidebarLinks.js | 47 -------------- src/stories/SubscriptAvatar.stories.js | 1 - src/styles/utils/spacing.ts | 8 +++ 7 files changed, 74 insertions(+), 51 deletions(-) create mode 100644 src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js diff --git a/src/components/IllustratedHeaderPageLayout.js b/src/components/IllustratedHeaderPageLayout.js index dff3c52f4315..0658d19f7f8d 100644 --- a/src/components/IllustratedHeaderPageLayout.js +++ b/src/components/IllustratedHeaderPageLayout.js @@ -1,8 +1,8 @@ import PropTypes from 'prop-types'; import React from 'react'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import useTheme from '../hooks/useTheme'; -import useThemeStyles from '../hooks/useThemeStyles'; +import useTheme from '@hooks/useTheme'; +import useThemeStyles from '@hooks/useThemeStyles'; import HeaderPageLayout from './HeaderPageLayout'; import headerWithBackButtonPropTypes from './HeaderWithBackButton/headerWithBackButtonPropTypes'; import Lottie from './Lottie'; diff --git a/src/languages/en.ts b/src/languages/en.ts index db59a833a0a7..4bb2431dfc55 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1993,7 +1993,7 @@ export default { }, breadcrumbs: { // TODO-IDEAL: Verify translations in Spanish - chats: 'Chats' + chats: 'Chats', }, referralProgram: { [CONST.REFERRAL_PROGRAM.CONTENT_TYPES.START_CHAT]: { diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js new file mode 100644 index 000000000000..c3ceb455039f --- /dev/null +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js @@ -0,0 +1,61 @@ +import PropTypes from 'prop-types'; +import React, {useCallback} from 'react'; +import {View} from 'react-native'; +import * as Expensicons from '@components/Icon/Expensicons'; +import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; +import Search from '@components/Search'; +import SubscriptAvatar from '@components/SubscriptAvatar'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import Navigation from '@libs/Navigation/Navigation'; +import SignInOrAvatarWithOptionalStatus from '@pages/home/sidebar/SignInOrAvatarWithOptionalStatus'; +import * as Session from '@userActions/Session'; +import CONST from '@src/CONST'; +import ROUTES from '@src/ROUTES'; + +// TODO-IDEAL: isCreateMenuOpen wasn't used before +function TopBar({isCreateMenuOpen = false}) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + + const showSearchPage = useCallback(() => { + if (isCreateMenuOpen) { + // Prevent opening Search page when click Search icon quickly after clicking FAB icon + return; + } + + Navigation.navigate(ROUTES.SEARCH); + }, [isCreateMenuOpen]); + + return ( + + + + + + + + ); +} + +TopBar.displayName = 'TopBar'; +TopBar.propTypes = { + isCreateMenuOpen: PropTypes.bool, +}; +TopBar.defaultProps = { + isCreateMenuOpen: false, +}; + +export default TopBar; diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/index.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/index.tsx index 24be4ce5a174..e6a34a428527 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/index.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/index.tsx @@ -15,6 +15,7 @@ import {View} from 'react-native'; import {NavigationStateRoute} from '@libs/Navigation/types'; import SCREENS from '@src/SCREENS'; import BottomTabBar from './BottomTabBar'; +import TopBar from './TopBar'; type CustomNavigatorProps = DefaultNavigatorOptions, StackNavigationOptions, StackNavigationEventMap> & { initialRouteName: string; @@ -67,6 +68,7 @@ function CustomBottomTabNavigator({initialRouteName, children, screenOptions, .. return ( + { - if (isCreateMenuOpen) { - // Prevent opening Search page when click Search icon quickly after clicking FAB icon - return; - } - - Navigation.navigate(ROUTES.SEARCH); - }, [isCreateMenuOpen]); - /** * Show Report page with selected report id * @@ -152,33 +132,6 @@ function SidebarLinks({onLinkClick, insets, optionListItems, isLoading, priority return ( - -
- } - role={CONST.ROLE.PRESENTATION} - shouldShowEnvironmentBadge - /> - - - - - - - Date: Wed, 20 Dec 2023 09:47:11 +0100 Subject: [PATCH 05/12] fixes --- src/components/IllustratedHeaderPageLayout.js | 2 +- src/libs/Navigation/Navigation.ts | 11 ++++++++++- src/pages/settings/InitialSettingsPage.js | 4 +--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/components/IllustratedHeaderPageLayout.js b/src/components/IllustratedHeaderPageLayout.js index 0658d19f7f8d..89e21c92c31e 100644 --- a/src/components/IllustratedHeaderPageLayout.js +++ b/src/components/IllustratedHeaderPageLayout.js @@ -1,8 +1,8 @@ import PropTypes from 'prop-types'; import React from 'react'; -import useWindowDimensions from '@hooks/useWindowDimensions'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; +import useWindowDimensions from '@hooks/useWindowDimensions'; import HeaderPageLayout from './HeaderPageLayout'; import headerWithBackButtonPropTypes from './HeaderWithBackButton/headerWithBackButtonPropTypes'; import Lottie from './Lottie'; diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index 6b43bc5b8134..4a8f4f174b8b 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -166,7 +166,7 @@ function goBack(fallbackRoute: Route, shouldEnforceFallback = false, shouldPopTo const rootState = navigationRef.getRootState(); const lastRoute = rootState.routes.at(-1); // If the user comes from a different flow (there is more than one route in ModalNavigator) we should go back to the previous flow on UP button press instead of using the fallbackRoute. - if (lastRoute?.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR || (lastRoute?.name === NAVIGATORS.LEFT_MODAL_NAVIGATOR && (lastRoute.state?.index ?? 0) > 0)) { + if ((lastRoute?.name === NAVIGATORS.LEFT_MODAL_NAVIGATOR || lastRoute?.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR) && (lastRoute.state?.index ?? 0) > 0) { navigationRef.current.goBack(); return; } @@ -195,6 +195,14 @@ function goBack(fallbackRoute: Route, shouldEnforceFallback = false, shouldPopTo navigationRef.current.goBack(); } +/** + * Close the full screen modal. + */ +function closeFullScreen() { + const rootState = navigationRef.getRootState(); + navigationRef.dispatch({...StackActions.pop(), target: rootState.key}); +} + /** * Update route params for the specified route. */ @@ -307,6 +315,7 @@ export default { getRouteNameFromStateEvent, getTopmostReportActionId, waitForProtectedRoutes, + closeFullScreen, }; export {navigationRef}; diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 1acc6f2e3add..59dc8cf35716 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -355,14 +355,12 @@ function InitialSettingsPage(props) { ); - const navigateBackTo = lodashGet(props.route, 'params.backTo', ROUTES.HOME); - return ( Navigation.navigate(navigateBackTo)} + onBackButtonPress={() => Navigation.closeFullScreen()} backgroundColor={theme.PAGE_THEMES[SCREENS.SETTINGS.ROOT].backgroundColor} childrenContainerStyles={[styles.m0, styles.p0]} > From 255794f2d0bb8c6df4362861dc7e0b95a612840c Mon Sep 17 00:00:00 2001 From: Adam Grzybowski Date: Tue, 19 Dec 2023 19:20:13 +0100 Subject: [PATCH 06/12] fix crash after loggin in --- .../BottomTabBar.tsx | 7 ++++- .../CustomRouter.ts | 28 +++++++++++-------- .../getMatchingCentralPaneRouteForState.ts | 6 +++- .../Navigation/getTopmostBottomTabRoute.ts | 5 ++-- src/libs/Navigation/linkTo.ts | 6 ++-- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx index e8e6a8a5c4d5..b7e4a7cfd613 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx @@ -19,7 +19,12 @@ function BottomTabBar() { const styles = useThemeStyles(); // Parent navigator of the bottom tab bar is the root navigator. - const currentTabName = useNavigationState((state) => getTopmostBottomTabRoute(state).name); + const currentTabName = useNavigationState((state) => { + const topmostBottomTabRoute = getTopmostBottomTabRoute(state); + if (topmostBottomTabRoute) { + return topmostBottomTabRoute.name; + } + }); return ( diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts index 21f64835ccfc..a00489fbe8be 100644 --- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts @@ -19,7 +19,9 @@ const isAtLeastOneInState = (state: State, screenName: string): boolean => !!sta * @param state - react-navigation state */ const addCentralPaneNavigatorRoute = (state: State) => { - const matchingCentralPaneRoute = getMatchingCentralPaneRouteForState(state); + // We only add the route if the bottom tab state is defined therefore matchingCentralPaneRoute will be defined. + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const matchingCentralPaneRoute = getMatchingCentralPaneRouteForState(state)!; const bottomTabRoute = state.routes.filter((route) => route.name === NAVIGATORS.BOTTOM_TAB_NAVIGATOR); const centralPaneRoutes = state.routes.filter((route) => route.name === NAVIGATORS.CENTRAL_PANE_NAVIGATOR); @@ -105,19 +107,23 @@ function CustomRouter(options: ResponsiveStackNavigatorRouterOptions) { return { ...stackRouter, getRehydratedState(partialState: StackNavigationState, {routeNames, routeParamList, routeGetIdList}: RouterConfigOptions): StackNavigationState { - const isSmallScreenWidth = getIsSmallScreenWidth(); // Make sure that there is at least one CentralPaneNavigator (ReportScreen by default) in the state if this is a wide layout - const topmostCentralPaneRoute = getTopmostCentralPaneRoute(partialState); const topmostBottomTabRoute = getTopmostBottomTabRoute(partialState); + const isSmallScreenWidth = getIsSmallScreenWidth(); - const isBottomTabMatchingCentralPane = topmostCentralPaneRoute && TAB_TO_CENTRAL_PANE_MAPPING[topmostBottomTabRoute.name].includes(topmostCentralPaneRoute.name); - - if (!isSmallScreenWidth && !isBottomTabMatchingCentralPane) { - // If we added a route we need to make sure that the state.stale is true to generate new key for this route - // @ts-expect-error Updating read only property - // noinspection JSConstantReassignment - partialState.stale = true; // eslint-disable-line - addCentralPaneNavigatorRoute(partialState); + // If we log in there is a few rehydrations where the state for the bottomTab doesn't exist yet. + // isSmallScreen is checked here to avoid calling check functions for optimazation purposes. + if (topmostBottomTabRoute && !isSmallScreenWidth) { + const topmostCentralPaneRoute = getTopmostCentralPaneRoute(partialState); + const isBottomTabMatchingCentralPane = topmostCentralPaneRoute && TAB_TO_CENTRAL_PANE_MAPPING[topmostBottomTabRoute.name].includes(topmostCentralPaneRoute.name); + + if (!isSmallScreenWidth && !isBottomTabMatchingCentralPane) { + // If we added a route we need to make sure that the state.stale is true to generate new key for this route + // @ts-expect-error Updating read only property + // noinspection JSConstantReassignment + partialState.stale = true; // eslint-disable-line + addCentralPaneNavigatorRoute(partialState); + } } handleSettingsOpened(partialState); const state = stackRouter.getRehydratedState(partialState, {routeNames, routeParamList, routeGetIdList}); diff --git a/src/libs/Navigation/getMatchingCentralPaneRouteForState.ts b/src/libs/Navigation/getMatchingCentralPaneRouteForState.ts index f00107308b2d..ab04bdb3bff6 100644 --- a/src/libs/Navigation/getMatchingCentralPaneRouteForState.ts +++ b/src/libs/Navigation/getMatchingCentralPaneRouteForState.ts @@ -32,9 +32,13 @@ const getTopMostReportIDFromRHP = (state: State): string => { }; // Get matching central pane route for bottom tab navigator. e.g HOME -> REPORT -function getMatchingCentralPaneRouteForState(state: State): NavigationPartialRoute { +function getMatchingCentralPaneRouteForState(state: State): NavigationPartialRoute | undefined { const topmostBottomTabRoute = getTopmostBottomTabRoute(state); + if (!topmostBottomTabRoute) { + return; + } + const centralPaneName = TAB_TO_CENTRAL_PANE_MAPPING[topmostBottomTabRoute.name][0]; if (topmostBottomTabRoute.name === SCREENS.WORKSPACE.INITIAL) { diff --git a/src/libs/Navigation/getTopmostBottomTabRoute.ts b/src/libs/Navigation/getTopmostBottomTabRoute.ts index 053f866bc3b5..47dd22886346 100644 --- a/src/libs/Navigation/getTopmostBottomTabRoute.ts +++ b/src/libs/Navigation/getTopmostBottomTabRoute.ts @@ -1,10 +1,11 @@ import {BottomTabName, NavigationPartialRoute, RootStackParamList, State} from './types'; -function getTopmostBottomTabRoute(state: State): NavigationPartialRoute { +function getTopmostBottomTabRoute(state: State): NavigationPartialRoute | undefined { const bottomTabNavigatorRoute = state.routes[0]; + // The bottomTabNavigatorRoute state may be empty if we just logged in. if (!bottomTabNavigatorRoute || bottomTabNavigatorRoute.name !== 'BottomTabNavigator' || bottomTabNavigatorRoute.state === undefined) { - throw new Error('There is no bottomTabNavigator route mounted as the first route in the root state.'); + return undefined; } const topmostBottomTabRoute = bottomTabNavigatorRoute.state.routes.at(-1); diff --git a/src/libs/Navigation/linkTo.ts b/src/libs/Navigation/linkTo.ts index 75bd2a5d02b4..debcba81cd01 100644 --- a/src/libs/Navigation/linkTo.ts +++ b/src/libs/Navigation/linkTo.ts @@ -124,7 +124,7 @@ export default function linkTo(navigation: NavigationContainerRef Date: Tue, 19 Dec 2023 19:25:28 +0100 Subject: [PATCH 07/12] remove redundand isSmallScreen check --- .../AppNavigator/createCustomStackNavigator/CustomRouter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts index a00489fbe8be..1e438f66b302 100644 --- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts @@ -117,7 +117,7 @@ function CustomRouter(options: ResponsiveStackNavigatorRouterOptions) { const topmostCentralPaneRoute = getTopmostCentralPaneRoute(partialState); const isBottomTabMatchingCentralPane = topmostCentralPaneRoute && TAB_TO_CENTRAL_PANE_MAPPING[topmostBottomTabRoute.name].includes(topmostCentralPaneRoute.name); - if (!isSmallScreenWidth && !isBottomTabMatchingCentralPane) { + if (!isBottomTabMatchingCentralPane) { // If we added a route we need to make sure that the state.stale is true to generate new key for this route // @ts-expect-error Updating read only property // noinspection JSConstantReassignment From 34586d84cd6f915e77f91b044216da76f0146706 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Wed, 20 Dec 2023 10:21:05 +0100 Subject: [PATCH 08/12] design fixes --- .../AppNavigator/createCustomBottomTabNavigator/TopBar.js | 2 +- src/styles/theme/themes/dark.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js index c3ceb455039f..792304453aff 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js @@ -41,7 +41,7 @@ function TopBar({isCreateMenuOpen = false}) { /> diff --git a/src/styles/theme/themes/dark.ts b/src/styles/theme/themes/dark.ts index 315593a3a8b2..75832a412f81 100644 --- a/src/styles/theme/themes/dark.ts +++ b/src/styles/theme/themes/dark.ts @@ -45,7 +45,7 @@ const darkTheme = { hoverComponentBG: colors.productDark300, activeComponentBG: colors.productDark400, signInSidebar: colors.green800, - sidebar: colors.productDark200, + sidebar: colors.productDark100, sidebarHover: colors.productDark300, heading: colors.productDark900, textLight: colors.productDark900, From adbcde9045a3fea4dba6bc19489a8dd6a818e61d Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Wed, 20 Dec 2023 13:15:46 +0100 Subject: [PATCH 09/12] add spanish translation --- src/languages/en.ts | 1 - src/languages/es.ts | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 4bb2431dfc55..27d0e8ca3a7d 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1992,7 +1992,6 @@ export default { transactionDate: 'Transaction date', }, breadcrumbs: { - // TODO-IDEAL: Verify translations in Spanish chats: 'Chats', }, referralProgram: { diff --git a/src/languages/es.ts b/src/languages/es.ts index 72710f1f8714..874fa33cba89 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2478,6 +2478,10 @@ export default { guaranteed: 'eRecibo garantizado', transactionDate: 'Fecha de transacción', }, + breadcrumbs: { + // TODO-IDEAL: Verify translations in Spanish + chats: 'Chats', + }, referralProgram: { [CONST.REFERRAL_PROGRAM.CONTENT_TYPES.START_CHAT]: { buttonText1: 'Inicia un chat y ', From 7bd9f47cc05e33ee4ac2d85cff7968e5c1611bc5 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Wed, 20 Dec 2023 14:05:08 +0100 Subject: [PATCH 10/12] address review --- .../AppNavigator/createCustomBottomTabNavigator/TopBar.js | 2 +- src/styles/theme/themes/light.ts | 2 +- src/styles/utils/spacing.ts | 4 ---- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js index 792304453aff..fc92d8514b7c 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.js @@ -32,7 +32,7 @@ function TopBar({isCreateMenuOpen = false}) { style={[styles.gap6, styles.flexRow, styles.ph5, styles.pv3, styles.justifyContentBetween, styles.alignItemsCenter]} dataSet={{dragArea: true}} > - + Date: Tue, 19 Dec 2023 13:07:42 +0100 Subject: [PATCH 11/12] fix regressions from other PR --- src/components/MenuItem.js | 8 +++++++- src/components/menuItemPropTypes.js | 3 +++ src/pages/settings/InitialSettingsPage.js | 1 + src/styles/theme/themes/dark.ts | 2 +- src/styles/theme/themes/light.ts | 2 +- src/styles/utils/index.ts | 8 ++++---- 6 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index b1f6b7f7319a..4c47f60a894d 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -84,6 +84,7 @@ const defaultProps = { shouldShowRightComponent: false, titleWithTooltips: [], shouldCheckActionAllowedOnPress: true, + isPaneMenu: false, }; const MenuItem = React.forwardRef((props, ref) => { @@ -234,6 +235,7 @@ const MenuItem = React.forwardRef((props, ref) => { StyleUtils.getIconFillColor( getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), true, + props.isPaneMenu, ) } /> @@ -266,7 +268,11 @@ const MenuItem = React.forwardRef((props, ref) => { height={props.iconHeight} fill={ props.secondaryIconFill || - StyleUtils.getIconFillColor(getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), true) + StyleUtils.getIconFillColor( + getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), + true, + props.isPaneMenu, + ) } /> diff --git a/src/components/menuItemPropTypes.js b/src/components/menuItemPropTypes.js index 4d2de3275e23..576fff6d78da 100644 --- a/src/components/menuItemPropTypes.js +++ b/src/components/menuItemPropTypes.js @@ -162,6 +162,9 @@ const propTypes = { /** Should check anonymous user in onPress function */ shouldCheckActionAllowedOnPress: PropTypes.bool, + + /** Is this menu item in the settings pane */ + isPaneMenu: PropTypes.bool, }; export default propTypes; diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 59dc8cf35716..513e8c314f59 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -273,6 +273,7 @@ function InitialSettingsPage(props) { !_.isEmpty(item.link) ? (e) => ReportActionContextMenu.showContextMenu(CONTEXT_MENU_TYPES.LINK, e, item.link, popoverAnchor.current) : undefined } focused={activeRoute && activeRoute.startsWith(item.routeName, 1)} + isPaneMenu /> ); })} diff --git a/src/styles/theme/themes/dark.ts b/src/styles/theme/themes/dark.ts index 75832a412f81..7a94988eb019 100644 --- a/src/styles/theme/themes/dark.ts +++ b/src/styles/theme/themes/dark.ts @@ -12,7 +12,7 @@ const darkTheme = { borderLighter: colors.productDark400, borderFocus: colors.green400, icon: colors.productDark700, - iconMenu: colors.productDark700, + iconMenu: colors.green400, iconHovered: colors.productDark900, iconMenuHovered: colors.green400, iconSuccessFill: colors.green400, diff --git a/src/styles/theme/themes/light.ts b/src/styles/theme/themes/light.ts index daf39e1021bb..228917d73d26 100644 --- a/src/styles/theme/themes/light.ts +++ b/src/styles/theme/themes/light.ts @@ -12,7 +12,7 @@ const lightTheme = { borderLighter: colors.productLight400, borderFocus: colors.green400, icon: colors.productLight700, - iconMenu: colors.productLight700, + iconMenu: colors.green400, iconHovered: colors.productLight900, iconMenuHovered: colors.green400, iconSuccessFill: colors.green400, diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index c4130d9b2475..ab2f42065c72 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1301,12 +1301,12 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ * @param buttonState - One of {'default', 'hovered', 'pressed'} * @param isMenuIcon - whether this icon is apart of a list */ - getIconFillColor: (buttonState: ButtonStateName = CONST.BUTTON_STATES.DEFAULT, isMenuIcon = false): string => { + getIconFillColor: (buttonState: ButtonStateName = CONST.BUTTON_STATES.DEFAULT, isMenuIcon = false, isPane = false): string => { switch (buttonState) { case CONST.BUTTON_STATES.ACTIVE: case CONST.BUTTON_STATES.PRESSED: - if (isMenuIcon) { - return theme.iconMenuHovered; + if (isPane) { + return theme.iconMenu; } return theme.iconHovered; case CONST.BUTTON_STATES.COMPLETE: @@ -1314,7 +1314,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ case CONST.BUTTON_STATES.DEFAULT: case CONST.BUTTON_STATES.DISABLED: default: - if (isMenuIcon) { + if (isMenuIcon && !isPane) { return theme.iconMenu; } return theme.icon; From ba1bbf30445acf91daceaccca80db98c94c1659f Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Wed, 20 Dec 2023 15:03:02 +0100 Subject: [PATCH 12/12] fix new-expensify color --- assets/images/new-expensify.svg | 2 +- src/pages/settings/InitialSettingsPage.js | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/assets/images/new-expensify.svg b/assets/images/new-expensify.svg index 38276ecd9385..dc7aec87c6fd 100644 --- a/assets/images/new-expensify.svg +++ b/assets/images/new-expensify.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 513e8c314f59..c8a6238f9305 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -178,8 +178,6 @@ function InitialSettingsPage(props) { action: () => { Link.openExternalLink(CONST.EXPENSIFY_INBOX_URL); }, - shouldShowRightIcon: true, - iconRight: Expensicons.NewWindow, link: CONST.EXPENSIFY_INBOX_URL, }, { @@ -210,8 +208,6 @@ function InitialSettingsPage(props) { action: () => { Link.openExternalLink(CONST.NEWHELP_URL); }, - shouldShowRightIcon: true, - iconRight: Expensicons.NewWindow, link: CONST.NEWHELP_URL, }, {