-
Notifications
You must be signed in to change notification settings - Fork 3k
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
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 ed1677a
Action to create initial waypoints
neil-marcellini 18bf82c
Connect to transaction and create waypoints
neil-marcellini 6d3820a
Use distance request page
neil-marcellini 35bfb2b
Store waypoints under comment as intended
neil-marcellini 4093ecc
Add secondary icon for waypoint menu items
neil-marcellini d535699
WIP display initial waypoints
neil-marcellini 4b8e4e8
Fix dynamic waypoint title from key
neil-marcellini 1a1e7d2
Set waypoint description instead of title
neil-marcellini 23b584f
Style
neil-marcellini c24b248
WIP add stop button
neil-marcellini c50f083
Center button and set proper size
neil-marcellini 5a52842
Add a new waypoint when add stop is pressed
neil-marcellini abdc242
Show only 4 waypoints max in scroll view
neil-marcellini ceec9bb
Fade the last half waypoint shown in the list
neil-marcellini 3509242
Use key in list to fix console error
neil-marcellini bfa14b8
Disable add stop at max of 25
neil-marcellini 3232cc5
Only fade the waypoint when extending out of view
neil-marcellini 91ae1a0
Expand waypoint container until max size is hit
neil-marcellini aa755c8
Fade waypoints into background vs black
neil-marcellini 0423499
Merge branch 'neil-distance-option' into neil-waypoints-list
neil-marcellini c1f02bf
Add distance icons
neil-marcellini 77f3f35
WIP set waypoint icon based on index
neil-marcellini 5c517e6
Same default color for all waypoint icons
neil-marcellini 792aab1
WIP scroll fade with dynamic waypoints sizes
neil-marcellini c973198
Get scroll content height using it's callback
neil-marcellini 1e97449
Remove console logs
neil-marcellini 7b6d485
layout event to measure scroll container height
neil-marcellini 6658bb8
More cleanup / style
neil-marcellini 9e9b0e5
Add route for distance tab
neil-marcellini dd12bcc
Add unchecked translations
neil-marcellini 9b34056
Use unique unfilled dot for start waypoint
neil-marcellini a821041
Remove unused props
neil-marcellini 324a881
Describe the purpose of the DistanceRequestPage
neil-marcellini 80bd876
Update podfile for LinearGradient
neil-marcellini 5435f9b
Prevent crash with null transaction
neil-marcellini 96b04da
Update with native speaker translations
neil-marcellini 8131df5
Merge branch 'main' into neil-waypoints-list
neil-marcellini 7062ac0
Add request routes for deep linking
neil-marcellini d014713
baseMenuItemHeight is a style variable
neil-marcellini 58f6ab5
Comment up the props for our style guide
neil-marcellini 2afe7b3
Merge branch 'main' into neil-waypoints-list
neil-marcellini File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: {}, | ||
}; | ||
|
||
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} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import LinearGradient from 'react-native-linear-gradient'; | ||
|
||
export default LinearGradient; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default props can be set while destructing props
https://github.com/Expensify/App/blob/main/contributingGuides/STYLE.md#destructuring
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?