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

Add waypoints list and add stop button #23698

Merged
merged 42 commits into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
fd5bd2d
Separate DistanceRequestPage to pass transactionID
neil-marcellini Jul 26, 2023
ed1677a
Action to create initial waypoints
neil-marcellini Jul 26, 2023
18bf82c
Connect to transaction and create waypoints
neil-marcellini Jul 26, 2023
6d3820a
Use distance request page
neil-marcellini Jul 26, 2023
35bfb2b
Store waypoints under comment as intended
neil-marcellini Jul 29, 2023
4093ecc
Add secondary icon for waypoint menu items
neil-marcellini Jul 29, 2023
d535699
WIP display initial waypoints
neil-marcellini Jul 29, 2023
4b8e4e8
Fix dynamic waypoint title from key
neil-marcellini Jul 29, 2023
1a1e7d2
Set waypoint description instead of title
neil-marcellini Jul 29, 2023
23b584f
Style
neil-marcellini Jul 29, 2023
c24b248
WIP add stop button
neil-marcellini Aug 2, 2023
c50f083
Center button and set proper size
neil-marcellini Aug 2, 2023
5a52842
Add a new waypoint when add stop is pressed
neil-marcellini Aug 2, 2023
abdc242
Show only 4 waypoints max in scroll view
neil-marcellini Aug 2, 2023
ceec9bb
Fade the last half waypoint shown in the list
neil-marcellini Aug 3, 2023
3509242
Use key in list to fix console error
neil-marcellini Aug 3, 2023
bfa14b8
Disable add stop at max of 25
neil-marcellini Aug 3, 2023
3232cc5
Only fade the waypoint when extending out of view
neil-marcellini Aug 3, 2023
91ae1a0
Expand waypoint container until max size is hit
neil-marcellini Aug 3, 2023
aa755c8
Fade waypoints into background vs black
neil-marcellini Aug 3, 2023
0423499
Merge branch 'neil-distance-option' into neil-waypoints-list
neil-marcellini Aug 4, 2023
c1f02bf
Add distance icons
neil-marcellini Aug 4, 2023
77f3f35
WIP set waypoint icon based on index
neil-marcellini Aug 4, 2023
5c517e6
Same default color for all waypoint icons
neil-marcellini Aug 4, 2023
792aab1
WIP scroll fade with dynamic waypoints sizes
neil-marcellini Aug 4, 2023
c973198
Get scroll content height using it's callback
neil-marcellini Aug 4, 2023
1e97449
Remove console logs
neil-marcellini Aug 4, 2023
7b6d485
layout event to measure scroll container height
neil-marcellini Aug 4, 2023
6658bb8
More cleanup / style
neil-marcellini Aug 4, 2023
9e9b0e5
Add route for distance tab
neil-marcellini Aug 5, 2023
dd12bcc
Add unchecked translations
neil-marcellini Aug 5, 2023
9b34056
Use unique unfilled dot for start waypoint
neil-marcellini Aug 7, 2023
a821041
Remove unused props
neil-marcellini Aug 7, 2023
324a881
Describe the purpose of the DistanceRequestPage
neil-marcellini Aug 7, 2023
80bd876
Update podfile for LinearGradient
neil-marcellini Aug 7, 2023
5435f9b
Prevent crash with null transaction
neil-marcellini Aug 7, 2023
96b04da
Update with native speaker translations
neil-marcellini Aug 8, 2023
8131df5
Merge branch 'main' into neil-waypoints-list
neil-marcellini Aug 8, 2023
7062ac0
Add request routes for deep linking
neil-marcellini Aug 8, 2023
d014713
baseMenuItemHeight is a style variable
neil-marcellini Aug 9, 2023
58f6ab5
Comment up the props for our style guide
neil-marcellini Aug 9, 2023
2afe7b3
Merge branch 'main' into neil-waypoints-list
neil-marcellini Aug 10, 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
4 changes: 4 additions & 0 deletions .well-known/apple-app-site-association
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
"/": "/iou/*",
"comment": "I Owe You reports"
},
{
"/": "/request/*",
"comment": "Money request"
},
{
"/": "/enable-payments/*",
"comment": "Payments setup"
Expand Down
2 changes: 2 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/v"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/bank-account"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/iou"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/request"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/enable-payments"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/statements"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/concierge"/>
Expand All @@ -72,6 +73,7 @@
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/v"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/bank-account"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/iou"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/request"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/enable-payments"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/statements"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/concierge"/>
Expand Down
10 changes: 10 additions & 0 deletions assets/images/dot-indicator-unfilled.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions assets/images/drag-handles.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions assets/images/location.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ PODS:
- Airship/MessageCenter (= 16.11.3)
- Airship/PreferenceCenter (= 16.11.3)
- boost (1.76.0)
- BVLinearGradient (2.8.1):
- React-Core
- CocoaAsyncSocket (7.6.5)
- DoubleConversion (1.1.6)
- FBLazyVector (0.72.1)
Expand Down Expand Up @@ -792,6 +794,7 @@ PODS:

DEPENDENCIES:
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
- BVLinearGradient (from `../node_modules/react-native-linear-gradient`)
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
Expand Down Expand Up @@ -942,6 +945,8 @@ SPEC REPOS:
EXTERNAL SOURCES:
boost:
:podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
BVLinearGradient:
:path: "../node_modules/react-native-linear-gradient"
DoubleConversion:
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
FBLazyVector:
Expand Down Expand Up @@ -1114,6 +1119,7 @@ SPEC CHECKSUMS:
Airship: c70eed50e429f97f5adb285423c7291fb7a032ae
AirshipFrameworkProxy: 7bc4130c668c6c98e2d4c60fe4c9eb61a999be99
boost: 57d2868c099736d80fcd648bf211b4431e51a558
BVLinearGradient: 421743791a59d259aec53f4c58793aad031da2ca
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
FBLazyVector: 55cd4593d570bd9e5e227488d637ce6a9581ce51
Expand Down
31 changes: 31 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
"react-native-image-picker": "^5.1.0",
"react-native-image-size": "git+https://github.com/Expensify/react-native-image-size#8393b7e58df6ff65fd41f60aee8ece8822c91e2b",
"react-native-key-command": "^1.0.1",
"react-native-linear-gradient": "^2.8.1",
"react-native-localize": "^2.2.6",
"react-native-modal": "^13.0.0",
"react-native-onyx": "1.0.52",
Expand All @@ -136,6 +137,7 @@
"react-native-tab-view": "^3.5.2",
"react-native-view-shot": "^3.6.0",
"react-native-vision-camera": "^2.15.4",
"react-native-web-linear-gradient": "^1.1.2",
"react-native-web-lottie": "^1.4.4",
"react-native-webview": "^11.17.2",
"react-pdf": "^6.2.2",
Expand Down
147 changes: 131 additions & 16 deletions src/components/DistanceRequest.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,155 @@
import React, {useEffect} from 'react';
import {View} from 'react-native';
import React, {useEffect, useState} from 'react';
import {ScrollView, View} from 'react-native';
import lodashGet from 'lodash/get';
import _ from 'underscore';
import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
import Text from './Text';
import * as IOU from '../libs/actions/IOU';
import styles from '../styles/styles';
import ONYXKEYS from '../ONYXKEYS';
import * as Transaction from '../libs/actions/Transaction';
import MenuItemWithTopDescription from './MenuItemWithTopDescription';
import withLocalize, {withLocalizePropTypes} from './withLocalize';
import compose from '../libs/compose';
import * as Expensicons from './Icon/Expensicons';
import theme from '../styles/themes/default';
import Button from './Button';
import styles from '../styles/styles';
import variables from '../styles/variables';
import LinearGradient from './LinearGradient';

const MAX_WAYPOINTS = 25;
const MAX_WAYPOINTS_TO_DISPLAY = 4;

const propTypes = {
/** The transactionID of this request */
transactionID: PropTypes.string,

/** The optimistic transaction for this request */
transaction: PropTypes.shape({
/** The transactionID of this request */
transactionID: PropTypes.string,

/** The comment object on the transaction */
comment: PropTypes.shape({
/** The waypoints defining the distance request */
waypoints: PropTypes.shape({
/** The latitude of the waypoint */
lat: PropTypes.number,

/** The longitude of the waypoint */
lng: PropTypes.number,

/** The address of the waypoint */
address: PropTypes.string,
}),
}),
}),

...withLocalizePropTypes,
};

const defaultProps = {
transactionID: '',
transaction: {},
};
Comment on lines 50 to 53
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@neil-marcellini neil-marcellini Aug 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that but then eslint complained. Many components still use default props so I think we can keep this for now. cc @hayata-suenaga since you wrote this, what do you think is happening here?
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we returned down that ESLint rule

@neil-marcellini what is the exact ESLint rule that is warning?


function DistanceRequest(props) {
function DistanceRequest({transactionID, transaction, translate}) {
const [shouldShowGradient, setShouldShowGradient] = useState(false);
const [scrollContainerHeight, setScrollContainerHeight] = useState(0);
const [scrollContentHeight, setScrollContentHeight] = useState(0);

const waypoints = lodashGet(transaction, 'comment.waypoints', {});
const numberOfWaypoints = _.size(waypoints);
const lastWaypointIndex = numberOfWaypoints - 1;

// Show up to the max number of waypoints plus 1/2 of one to hint at scrolling
const halfMenuItemHeight = Math.floor(variables.baseMenuItemHeight / 2);
const scrollContainerMaxHeight = variables.baseMenuItemHeight * MAX_WAYPOINTS_TO_DISPLAY + halfMenuItemHeight;

useEffect(() => {
if (props.transactionID) {
if (!transaction.transactionID || !_.isEmpty(waypoints)) {
return;
}
IOU.createEmptyTransaction();
}, [props.transactionID]);
// Create the initial start and stop waypoints
Transaction.createInitialWaypoints(transaction.transactionID);
}, [transaction.transactionID, waypoints]);

const updateGradientVisibility = (event = {}) => {
// If a waypoint extends past the bottom of the visible area show the gradient, else hide it.
const visibleAreaEnd = lodashGet(event, 'nativeEvent.contentOffset.y', 0) + scrollContainerHeight;
setShouldShowGradient(visibleAreaEnd < scrollContentHeight);
};

useEffect(updateGradientVisibility, [scrollContainerHeight, scrollContentHeight]);

return (
<View style={[styles.flex1, styles.flexColumn, styles.w100, styles.alignItemsCenter, styles.mt4]}>
<Text>Distance Request</Text>
<Text>transactionID: {props.transactionID}</Text>
</View>
<>
<View
style={{maxHeight: scrollContainerMaxHeight}}
onLayout={(event = {}) => setScrollContainerHeight(lodashGet(event, 'nativeEvent.layout.height', 0))}
>
<ScrollView
onContentSizeChange={(width, height) => setScrollContentHeight(height)}
onScroll={updateGradientVisibility}
scrollEventThrottle={16}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this value need to be a CONST?

>
{_.map(waypoints, (waypoint, key) => {
// key is of the form waypoint0, waypoint1, ...
const index = Number(key.replace('waypoint', ''));
let descriptionKey = 'distance.waypointDescription.';
let waypointIcon;
if (index === 0) {
descriptionKey += 'start';
waypointIcon = Expensicons.DotIndicatorUnfilled;
} else if (index === lastWaypointIndex) {
descriptionKey += 'finish';
waypointIcon = Expensicons.Location;
} else {
descriptionKey += 'stop';
waypointIcon = Expensicons.DotIndicator;
}

return (
<MenuItemWithTopDescription
description={translate(descriptionKey)}
icon={Expensicons.DragHandles}
secondaryIcon={waypointIcon}
secondaryIconFill={theme.icon}
shouldShowRightIcon
key={key}
/>
);
})}
</ScrollView>
{shouldShowGradient && (
<LinearGradient
style={[styles.pAbsolute, styles.b0, styles.l0, styles.r0, {height: halfMenuItemHeight}]}
colors={[theme.transparent, theme.modalBackground]}
/>
)}
</View>
<View style={[styles.flexRow, styles.justifyContentCenter, styles.pt1]}>
<Button
small
icon={Expensicons.Plus}
onPress={() => Transaction.addStop(transactionID, lastWaypointIndex + 1)}
text={translate('distance.addStop')}
isDisabled={numberOfWaypoints === MAX_WAYPOINTS}
innerStyles={[styles.ph10]}
/>
</View>
</>
);
}

DistanceRequest.displayName = 'DistanceRequest';
DistanceRequest.propTypes = propTypes;
DistanceRequest.defaultProps = defaultProps;
export default withOnyx({
transactionID: {key: ONYXKEYS.IOU, selector: (iou) => (iou && iou.transactionID) || ''},
})(DistanceRequest);
export default compose(
withLocalize,
withOnyx({
transaction: {
key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`,
selector: (transaction) => (transaction ? {transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}} : null),
},
}),
)(DistanceRequest);
6 changes: 6 additions & 0 deletions src/components/Icon/Expensicons.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ import Document from '../../../assets/images/document.svg';
import DeletedRoomAvatar from '../../../assets/images/avatars/deleted-room.svg';
import DomainRoomAvatar from '../../../assets/images/avatars/domain-room.svg';
import DotIndicator from '../../../assets/images/dot-indicator.svg';
import DotIndicatorUnfilled from '../../../assets/images/dot-indicator-unfilled.svg';
import DownArrow from '../../../assets/images/down.svg';
import Download from '../../../assets/images/download.svg';
import DragHandles from '../../../assets/images/drag-handles.svg';
import Emoji from '../../../assets/images/emoji.svg';
import Exclamation from '../../../assets/images/exclamation.svg';
import Exit from '../../../assets/images/exit.svg';
Expand All @@ -60,6 +62,7 @@ import Key from '../../../assets/images/key.svg';
import Keyboard from '../../../assets/images/keyboard.svg';
import Link from '../../../assets/images/link.svg';
import LinkCopy from '../../../assets/images/link-copy.svg';
import Location from '../../../assets/images/location.svg';
import Lock from '../../../assets/images/lock.svg';
import LoungeAccess from '../../../assets/images/lounge-access.svg';
import Luggage from '../../../assets/images/luggage.svg';
Expand Down Expand Up @@ -154,9 +157,11 @@ export {
Document,
DomainRoomAvatar,
DotIndicator,
DotIndicatorUnfilled,
DownArrow,
Download,
DragAndDrop,
DragHandles,
Emoji,
Exclamation,
Exit,
Expand Down Expand Up @@ -187,6 +192,7 @@ export {
Keyboard,
Link,
LinkCopy,
Location,
Lock,
LoungeAccess,
Luggage,
Expand Down
3 changes: 3 additions & 0 deletions src/components/LinearGradient/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import LinearGradient from 'react-native-web-linear-gradient';

export default LinearGradient;
3 changes: 3 additions & 0 deletions src/components/LinearGradient/index.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import LinearGradient from 'react-native-linear-gradient';

export default LinearGradient;
Loading