Skip to content

Commit 03e83c3

Browse files
authored
Merge pull request Expensify#63352 from callstack-internal/feature/multi-scan-wire-up
[Multi-Scan] Support Multi-Scan in Receipt page
2 parents 0c28b4e + dd87582 commit 03e83c3

18 files changed

Lines changed: 648 additions & 440 deletions

File tree

src/ROUTES.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,11 @@ const ROUTES = {
910910
`create/${iouType as string}/start/${transactionID}/${reportID}/per-diem/${backToReport ?? ''}` as const,
911911
},
912912

913+
MONEY_REQUEST_RECEIPT_VIEW_MODAL: {
914+
route: 'receipt-view-modal/:transactionID',
915+
getRoute: (transactionID: string, backTo: string) => getUrlWithBackToParam(`receipt-view-modal/${transactionID}`, backTo),
916+
} as const,
917+
913918
MONEY_REQUEST_STATE_SELECTOR: {
914919
route: 'submit/state',
915920

src/SCREENS.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ const SCREENS = {
253253
STEP_WAYPOINT: 'Money_Request_Step_Waypoint',
254254
STEP_TAX_AMOUNT: 'Money_Request_Step_Tax_Amount',
255255
STEP_TAX_RATE: 'Money_Request_Step_Tax_Rate',
256+
RECEIPT_VIEW_MODAL: 'Money_Request_Receipt_View_Modal',
256257
STEP_SPLIT_PAYER: 'Money_Request_Step_Split_Payer',
257258
STEP_SEND_FROM: 'Money_Request_Step_Send_From',
258259
STEP_COMPANY_INFO: 'Money_Request_Step_Company_Info',
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import React, {useCallback, useRef, useState} from 'react';
2+
import {Keyboard, View} from 'react-native';
3+
import CarouselButtons from '@components/Attachments/AttachmentCarousel/CarouselButtons';
4+
import AttachmentCarouselPager from '@components/Attachments/AttachmentCarousel/Pager';
5+
import type {AttachmentCarouselPagerHandle} from '@components/Attachments/AttachmentCarousel/Pager';
6+
import type {AttachmentSource} from '@components/Attachments/types';
7+
import BlockingView from '@components/BlockingViews/BlockingView';
8+
import * as Illustrations from '@components/Icon/Illustrations';
9+
import useLocalize from '@hooks/useLocalize';
10+
import useThemeStyles from '@hooks/useThemeStyles';
11+
import {canUseTouchScreen as canUseTouchScreenUtil} from '@libs/DeviceCapabilities';
12+
import variables from '@styles/variables';
13+
import type AttachmentCarouselViewProps from './types';
14+
15+
function AttachmentCarouselView({
16+
page,
17+
attachments,
18+
shouldShowArrows,
19+
source,
20+
report,
21+
autoHideArrows,
22+
cancelAutoHideArrow,
23+
setShouldShowArrows,
24+
onAttachmentError,
25+
onNavigate,
26+
onClose,
27+
setPage,
28+
attachmentID,
29+
}: AttachmentCarouselViewProps) {
30+
const {translate} = useLocalize();
31+
const canUseTouchScreen = canUseTouchScreenUtil();
32+
const styles = useThemeStyles();
33+
const [activeAttachmentID, setActiveAttachmentID] = useState<AttachmentSource>(attachmentID ?? source);
34+
35+
const pagerRef = useRef<AttachmentCarouselPagerHandle>(null);
36+
37+
/** Updates the page state when the user navigates between attachments */
38+
const updatePage = useCallback(
39+
(newPageIndex: number) => {
40+
Keyboard.dismiss();
41+
setShouldShowArrows(true);
42+
43+
const item = attachments.at(newPageIndex);
44+
45+
setPage(newPageIndex);
46+
if (newPageIndex >= 0 && item) {
47+
setActiveAttachmentID(item.attachmentID ?? item.source);
48+
if (onNavigate) {
49+
onNavigate(item);
50+
}
51+
onNavigate?.(item);
52+
}
53+
},
54+
[setShouldShowArrows, attachments, setPage, onNavigate],
55+
);
56+
57+
/**
58+
* Increments or decrements the index to get another selected item
59+
* @param {Number} deltaSlide
60+
*/
61+
const cycleThroughAttachments = useCallback(
62+
(deltaSlide: number) => {
63+
if (page === undefined) {
64+
return;
65+
}
66+
const nextPageIndex = page + deltaSlide;
67+
updatePage(nextPageIndex);
68+
pagerRef.current?.setPage(nextPageIndex);
69+
70+
autoHideArrows();
71+
},
72+
[autoHideArrows, page, updatePage],
73+
);
74+
75+
return (
76+
<View
77+
style={[styles.flex1, styles.attachmentCarouselContainer]}
78+
onMouseEnter={() => !canUseTouchScreen && setShouldShowArrows(true)}
79+
onMouseLeave={() => !canUseTouchScreen && setShouldShowArrows(false)}
80+
>
81+
{page === -1 ? (
82+
<BlockingView
83+
icon={Illustrations.ToddBehindCloud}
84+
iconWidth={variables.modalTopIconWidth}
85+
iconHeight={variables.modalTopIconHeight}
86+
title={translate('notFound.notHere')}
87+
/>
88+
) : (
89+
<>
90+
<CarouselButtons
91+
page={page}
92+
attachments={attachments}
93+
shouldShowArrows={shouldShowArrows}
94+
onBack={() => cycleThroughAttachments(-1)}
95+
onForward={() => cycleThroughAttachments(1)}
96+
autoHideArrow={autoHideArrows}
97+
cancelAutoHideArrow={cancelAutoHideArrow}
98+
/>
99+
<AttachmentCarouselPager
100+
items={attachments}
101+
initialPage={page}
102+
onAttachmentError={onAttachmentError}
103+
activeAttachmentID={activeAttachmentID}
104+
setShouldShowArrows={setShouldShowArrows}
105+
onPageSelected={({nativeEvent: {position: newPage}}) => updatePage(newPage)}
106+
onClose={onClose}
107+
ref={pagerRef}
108+
reportID={report?.reportID}
109+
/>
110+
</>
111+
)}
112+
</View>
113+
);
114+
}
115+
116+
AttachmentCarouselView.displayName = 'AttachmentCarouselView';
117+
118+
export default AttachmentCarouselView;

0 commit comments

Comments
 (0)