Skip to content

Commit 095c8a0

Browse files
committed
New layout for Scan screen in landscape mode
1 parent 4a24621 commit 095c8a0

6 files changed

Lines changed: 261 additions & 186 deletions

File tree

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import React from 'react';
22
import {View} from 'react-native';
33
import useThemeStyles from '@hooks/useThemeStyles';
4-
import type ChildrenProps from '@src/types/utils/ChildrenProps';
4+
import type {SubmitButtonShadowProps} from './types';
55

6-
function SubmitButtonShadow({children}: ChildrenProps) {
6+
function SubmitButtonShadow({children, isInLandscapeMode = false}: SubmitButtonShadowProps) {
77
const styles = useThemeStyles();
88

9-
return <View style={[styles.receiptsSubmitButton, styles.buttonShadowContainer, styles.buttonShadow]}>{children}</View>;
9+
return <View style={[isInLandscapeMode ? styles.receiptsSubmitButtonLandscape : styles.receiptsSubmitButton, styles.buttonShadowContainer, styles.buttonShadow]}>{children}</View>;
1010
}
1111

1212
export default SubmitButtonShadow;

src/pages/iou/request/step/IOURequestStepScan/components/ReceiptPreviews/SubmitButtonShadow/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import React from 'react';
22
import {View} from 'react-native';
33
import useThemeStyles from '@hooks/useThemeStyles';
4-
import type ChildrenProps from '@src/types/utils/ChildrenProps';
4+
import type {SubmitButtonShadowProps} from './types';
55

6-
function SubmitButtonShadow({children}: ChildrenProps) {
6+
// isInLandscapeMode is only used on native platforms.
7+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
8+
function SubmitButtonShadow({children, isInLandscapeMode}: SubmitButtonShadowProps) {
79
const styles = useThemeStyles();
810

911
return <View style={[styles.receiptsSubmitButton, styles.buttonShadowContainer, styles.webButtonShadow]}>{children}</View>;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type ChildrenProps from '@src/types/utils/ChildrenProps';
2+
3+
type SubmitButtonShadowProps = ChildrenProps & {
4+
isInLandscapeMode?: boolean;
5+
};
6+
7+
// eslint-disable-next-line import/prefer-default-export
8+
export type {SubmitButtonShadowProps};

src/pages/iou/request/step/IOURequestStepScan/components/ReceiptPreviews/index.tsx

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
1414
import useTransactionDraftReceipts from '@hooks/useTransactionDraftReceipts';
1515
import useWindowDimensions from '@hooks/useWindowDimensions';
1616
import Navigation from '@libs/Navigation/Navigation';
17+
import variables from '@styles/variables';
1718
import CONST from '@src/CONST';
1819
import ROUTES from '@src/ROUTES';
1920
import type {Receipt} from '@src/types/onyx/Transaction';
@@ -30,18 +31,48 @@ type ReceiptPreviewsProps = {
3031

3132
/** If a photo is currently being captured */
3233
isCapturingPhoto?: boolean;
34+
35+
/** Whether the component is rendered in landscape orientation */
36+
isInLandscapeMode?: boolean;
3337
};
3438

35-
function ReceiptPreviews({submit, isMultiScanEnabled, isCapturingPhoto = false}: ReceiptPreviewsProps) {
39+
function useReceiptPreviewsSizes(isInLandscapeMode: boolean) {
40+
const styles = useThemeStyles();
41+
const {windowWidth, windowHeight} = useWindowDimensions();
42+
43+
if (isInLandscapeMode) {
44+
const previewItemSize = styles.receiptPlaceholderLandscape.height + styles.receiptPlaceholderLandscape.marginBottom;
45+
46+
const submitButtonHeight = styles.singleAvatarMedium.height;
47+
const tabSelectorButtonHeight = variables.tabSelectorButtonHeight + styles.pb4.paddingBottom;
48+
const contentHeaderHeight = variables.contentHeaderHeight;
49+
const initialReceiptsAmount = (windowHeight - submitButtonHeight - tabSelectorButtonHeight - contentHeaderHeight) / previewItemSize;
50+
51+
return {
52+
previewsSize: styles.receiptPlaceholder.width + styles.ph6.paddingHorizontal * 2,
53+
previewItemSize,
54+
initialReceiptsAmount,
55+
};
56+
}
57+
58+
const previewItemSize = styles.receiptPlaceholder.width + styles.receiptPlaceholder.marginRight;
59+
const initialReceiptsAmount = (windowWidth - styles.ph4.paddingHorizontal * 2 - styles.singleAvatarMedium.width) / previewItemSize;
60+
61+
return {
62+
previewsSize: styles.receiptPlaceholder.height + styles.pv2.paddingVertical * 2,
63+
previewItemSize,
64+
initialReceiptsAmount,
65+
};
66+
}
67+
68+
function ReceiptPreviews({submit, isMultiScanEnabled, isCapturingPhoto = false, isInLandscapeMode = false}: ReceiptPreviewsProps) {
3669
const icons = useMemoizedLazyExpensifyIcons(['ArrowRight']);
3770
const styles = useThemeStyles();
3871
const theme = useTheme();
3972
const {translate} = useLocalize();
40-
const {windowWidth} = useWindowDimensions();
4173
const isPreviewsVisible = useSharedValue(false);
42-
const previewsHeight = styles.receiptPlaceholder.height + styles.pv2.paddingVertical * 2;
43-
const previewItemWidth = styles.receiptPlaceholder.width + styles.receiptPlaceholder.marginRight;
44-
const initialReceiptsAmount = (windowWidth - styles.ph4.paddingHorizontal * 2 - styles.singleAvatarMedium.width) / previewItemWidth;
74+
const {previewsSize, previewItemSize, initialReceiptsAmount} = useReceiptPreviewsSizes(isInLandscapeMode);
75+
4576
const optimisticTransactionsReceipts = useTransactionDraftReceipts();
4677
const receipts = (() => {
4778
if (optimisticTransactionsReceipts.length >= initialReceiptsAmount) {
@@ -83,8 +114,9 @@ function ReceiptPreviews({submit, isMultiScanEnabled, isCapturingPhoto = false}:
83114
}, [receiptsPhotosLength, previousReceiptsPhotosLength, initialReceiptsAmount]);
84115

85116
const renderItem = ({item}: {item: ReceiptWithTransactionID | undefined}) => {
117+
const placeholderStyle = isInLandscapeMode ? styles.receiptPlaceholderLandscape : styles.receiptPlaceholder;
86118
if (!item) {
87-
return <View style={styles.receiptPlaceholder} />;
119+
return <View style={placeholderStyle} />;
88120
}
89121

90122
return (
@@ -97,7 +129,7 @@ function ReceiptPreviews({submit, isMultiScanEnabled, isCapturingPhoto = false}:
97129
>
98130
<Image
99131
source={typeof item.source === 'string' ? {uri: item.source} : item.source}
100-
style={[styles.receiptPlaceholder, styles.overflowHidden]}
132+
style={[placeholderStyle, styles.overflowHidden]}
101133
loadingIconSize="small"
102134
loadingIndicatorStyles={styles.bgTransparent}
103135
/>
@@ -106,29 +138,33 @@ function ReceiptPreviews({submit, isMultiScanEnabled, isCapturingPhoto = false}:
106138
};
107139

108140
const slideInStyle = useAnimatedStyle(() => {
109-
return {
110-
height: withTiming(isPreviewsVisible.get() ? previewsHeight : 0, {
111-
duration: 300,
112-
}),
113-
};
141+
const sizeValue = withTiming(isPreviewsVisible.get() ? previewsSize : 0, {duration: 300});
142+
143+
if (isInLandscapeMode) {
144+
return {width: sizeValue};
145+
}
146+
147+
return {height: sizeValue};
114148
});
115149

116150
return (
117151
<Animated.View style={slideInStyle}>
118-
<View style={styles.pr4}>
152+
<View style={isInLandscapeMode ? styles.pb4 : styles.pr4}>
119153
<FlatList
120154
ref={flatListRef}
121155
data={receipts}
122-
horizontal
156+
horizontal={!isInLandscapeMode}
123157
keyExtractor={(_, index) => index.toString()}
124158
renderItem={renderItem}
125-
getItemLayout={(data, index) => ({length: previewItemWidth, offset: previewItemWidth * index, index})}
126-
style={styles.pv2}
159+
getItemLayout={(data, index) => ({length: previewItemSize, offset: previewItemSize * index, index})}
160+
style={isInLandscapeMode ? styles.ph2 : styles.pv2}
127161
scrollEnabled={isScrollEnabled}
128162
showsHorizontalScrollIndicator={false}
129-
contentContainerStyle={[{paddingRight: styles.singleAvatarMedium.width}, styles.pl4]}
163+
contentContainerStyle={
164+
isInLandscapeMode ? [{paddingBottom: styles.singleAvatarMedium.height}, styles.ph4] : [{paddingRight: styles.singleAvatarMedium.width}, styles.pl4]
165+
}
130166
/>
131-
<SubmitButtonShadow>
167+
<SubmitButtonShadow isInLandscapeMode={isInLandscapeMode}>
132168
<Button
133169
large
134170
isDisabled={!optimisticTransactionsReceipts.length || isCapturingPhoto}

0 commit comments

Comments
 (0)