diff --git a/src/CONST.ts b/src/CONST.ts index 5c99c5877559..627d689aca6c 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -3023,6 +3023,9 @@ const CONST = { NEW_ROOM: 'room', RECEIPT_TAB_ID: 'ReceiptTab', IOU_REQUEST_TYPE: 'iouRequestType', + SHARE_TAB_ID: 'ShareTab', + SHARE: 'share', + SCAN: 'scan', }, TAB_REQUEST: { MANUAL: 'manual', diff --git a/src/ROUTES.ts b/src/ROUTES.ts index c5043ae779a5..32fadb8973ba 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -504,9 +504,13 @@ const ROUTES = { getRoute: (contentType: string) => `referral/${contentType}` as const, }, PROCESS_MONEY_REQUEST_HOLD: 'hold-request-educational', + SHARE: 'share', SHARE_ROOT: 'share/root', SHARE_MESSAGE: 'share/message', - SHARE_SCAN_CONFIRM: 'share/scan-confirm', + SHARE_SCAN_CONFIRM: { + route: 'share/scan-confirm/:iouType/:transactionID/:reportID', + getRoute: (iouType: ValueOf, transactionID: string, reportID: string) => `share/scan-confirm/${iouType}/${transactionID}/${reportID}` as const, + }, } as const; /** diff --git a/src/components/TabSelector/TabSelector.tsx b/src/components/TabSelector/TabSelector.tsx index 1b8b6bc1b22b..d63d1dccfee4 100644 --- a/src/components/TabSelector/TabSelector.tsx +++ b/src/components/TabSelector/TabSelector.tsx @@ -44,6 +44,10 @@ function getIconAndTitle(route: string, translate: LocaleContextProps['translate return {icon: Expensicons.Hashtag, title: translate('tabSelector.room')}; case CONST.TAB_REQUEST.DISTANCE: return {icon: Expensicons.Car, title: translate('common.distance')}; + case CONST.TAB.SCAN: + return {icon: Expensicons.Receipt, title: translate('tabSelector.scan')}; + case CONST.TAB.SHARE: + return {icon: Expensicons.UploadAlt, title: translate('common.share')}; default: throw new Error(`Route ${route} has no icon nor title set.`); } diff --git a/src/languages/en.ts b/src/languages/en.ts index 0baaee4c07a8..12df0bb69b59 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2278,6 +2278,9 @@ export default { secondDescription: "Don't worry, Expensify Classic has everything you need.", buttonText: 'Take me to Expensify Classic', }, + share: { + title: 'Share to Expensify', + }, violations: { allTagLevelsRequired: 'All tags required', autoReportedRejectedExpense: ({rejectReason, rejectedBy}: ViolationsAutoReportedRejectedExpenseParams) => `${rejectedBy} rejected this expense with the comment "${rejectReason}"`, diff --git a/src/languages/es.ts b/src/languages/es.ts index ae566f3033f0..52fc985a382c 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2767,6 +2767,9 @@ export default { secondDescription: 'No te preocupes, Expensify Classic tiene todo lo que necesitas.', buttonText: 'Llévame a Expensify Classic', }, + share: { + title: 'Share to Expensify', + }, violations: { allTagLevelsRequired: 'Todas las etiquetas son obligatorias', autoReportedRejectedExpense: ({rejectedBy, rejectReason}: ViolationsAutoReportedRejectedExpenseParams) => `${rejectedBy} rechazó la solicitud y comentó "${rejectReason}"`, diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx index df0f1bfd09c7..a5d210f9be28 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx @@ -300,7 +300,7 @@ const ProcessMoneyRequestHoldStackNavigator = createModalStackNavigator({ const ShareModalStackNavigator = createModalStackNavigator({ [SCREENS.SHARE.ROOT]: () => require('../../../pages/share/ShareRootPage').default as React.ComponentType, [SCREENS.SHARE.MESSAGE]: () => require('../../../pages/share/ShareComposeMessagePage').default as React.ComponentType, - [SCREENS.SHARE.SCAN_CONFIRM]: () => require('../../../pages/iou/steps/MoneyRequestConfirmPage').default as React.ComponentType, + [SCREENS.SHARE.SCAN_CONFIRM]: () => require('../../../pages/iou/request/step/IOURequestStepConfirmation').default as React.ComponentType, }); export { diff --git a/src/libs/Navigation/dismissModal.ts b/src/libs/Navigation/dismissModal.ts index 484008d2e070..eaf1ca7bd0e9 100644 --- a/src/libs/Navigation/dismissModal.ts +++ b/src/libs/Navigation/dismissModal.ts @@ -23,6 +23,7 @@ function dismissModal(navigationRef: NavigationContainerRef) case NAVIGATORS.FULL_SCREEN_NAVIGATOR: case NAVIGATORS.LEFT_MODAL_NAVIGATOR: case NAVIGATORS.RIGHT_MODAL_NAVIGATOR: + case NAVIGATORS.SHARE_MODAL_NAVIGATOR: case SCREENS.NOT_FOUND: case SCREENS.REPORT_ATTACHMENTS: navigationRef.dispatch({...StackActions.pop(), target: state.key}); diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index f1a2acf5ddf1..f1b0dba6a174 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -525,12 +525,24 @@ const config: LinkingOptions['config'] = { }, [NAVIGATORS.SHARE_MODAL_NAVIGATOR]: { - path: ROUTES.SHARE_ROOT, initialRouteName: SCREENS.SHARE.ROOT, screens: { - [SCREENS.SHARE.ROOT]: ROUTES.SHARE_ROOT, - [SCREENS.SHARE.MESSAGE]: ROUTES.SHARE_MESSAGE, - [SCREENS.SHARE.SCAN_CONFIRM]: ROUTES.SHARE_SCAN_CONFIRM, + [SCREENS.SHARE.ROOT]: { + path: ROUTES.SHARE_ROOT, + exact: true, + screens: { + share: { + path: 'share/root/share', + exact: true, + }, + scan: { + path: 'share/root/scan', + exact: true, + }, + }, + }, + [SCREENS.SHARE.MESSAGE]: {path: ROUTES.SHARE_MESSAGE}, + [SCREENS.SHARE.SCAN_CONFIRM]: {path: ROUTES.SHARE_SCAN_CONFIRM.route}, }, }, }, diff --git a/src/pages/share/ShareRootPage.tsx b/src/pages/share/ShareRootPage.tsx index 7463a0d83303..ef5fc7c66341 100644 --- a/src/pages/share/ShareRootPage.tsx +++ b/src/pages/share/ShareRootPage.tsx @@ -1,12 +1,40 @@ -import React, {useEffect, useRef} from 'react'; +import React, {useCallback, useEffect, useRef} from 'react'; import type {AppStateStatus} from 'react-native'; import {AppState, View} from 'react-native'; -import Text from '@components/Text'; +import type {OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import ScreenWrapper from '@components/ScreenWrapper'; +import TabSelector from '@components/TabSelector/TabSelector'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as IOU from '@libs/actions/IOU'; +import * as DeviceCapabilities from '@libs/DeviceCapabilities'; +import * as ReportUtils from '@libs/ReportUtils'; +import Navigation from '@navigation/Navigation'; +import OnyxTabNavigator, {TopTab} from '@navigation/OnyxTabNavigator'; +import MoneyRequestParticipantsSelector from '@pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector'; +import CONST from '@src/CONST'; import ShareExtensionHandlerModule from '@src/modules/ShareExtensionHandlerModule'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; +import type {Report} from '@src/types/onyx'; -// type ShareRootPageProps = {}; +type ShareRootPageOnyxProps = { + selectedTab: OnyxEntry; -export default function ShareRootPage() { + iou: OnyxEntry; +}; + +type ShareRootPageProps = ShareRootPageOnyxProps; + +function ShareRootPage({selectedTab, iou}: ShareRootPageProps) { + const transactionID = CONST.IOU.OPTIMISTIC_TRANSACTION_ID; + const styles = useThemeStyles(); + const {translate} = useLocalize(); + const fileIsScannable = false; + const optimisticReportID = ReportUtils.generateReportID(); + const selectedReportID = useRef(optimisticReportID); const appState = useRef(AppState.currentState); const handleAppStateChange = (nextAppState: AppStateStatus) => { @@ -30,9 +58,87 @@ export default function ShareRootPage() { }; }, []); + const navigateBack = () => { + Navigation.dismissModal(); + }; + + const goToNextStep = useCallback(() => { + // const nextStepIOUType = numberOfParticipants.current === 1 ? CONST.IOU.TYPE.REQUEST : CONST.IOU.TYPE.SPLIT; + const nextStepIOUType = CONST.IOU.TYPE.REQUEST; + IOU.startMoneyRequest_temporaryForRefactor(optimisticReportID, false, CONST.IOU.REQUEST_TYPE.SCAN); + IOU.setMoneyRequestTag(transactionID, ''); + IOU.resetMoneyRequestCategory_temporaryForRefactor(transactionID); + Navigation.navigate(ROUTES.SHARE_SCAN_CONFIRM.getRoute(nextStepIOUType, transactionID, selectedReportID.current || optimisticReportID)); + }, [transactionID, optimisticReportID]); + return ( - - share root - + + + + ( + + )} + > + + {() => ( + + )} + + + {() => ( + + )} + + + + ); } + +ShareRootPage.displayName = 'ShareRootPage'; + +export default withOnyx({ + selectedTab: { + key: `${ONYXKEYS.COLLECTION.SELECTED_TAB}${CONST.TAB.RECEIPT_TAB_ID}`, + }, + // @ts-expect-error To fix + iou: { + key: ONYXKEYS.IOU, + }, +})(ShareRootPage);