-
Notifications
You must be signed in to change notification settings - Fork 1
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
feat: implement manual gps coordinate entry screen #219
Conversation
6e09e5c
to
d9f15ff
Compare
@@ -76,6 +76,7 @@ const draftObservationSlice: StateCreator<DraftObservationSlice> = ( | |||
metadata: { | |||
...prevValue.metadata, | |||
position: props.position, | |||
manualLocation: props.manualLocation, |
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.
super subtle but found out why updateObservationPosition()
didn't update the manualLocation
field when initially implementing this 🥲
manualCoordinateEntryFormat: 'utm', | ||
actions: { | ||
setCoordinateFormat: coordinateFormat => set({coordinateFormat}), | ||
setManualCoordinateEntryFormat: coordinateFormat => | ||
set({manualCoordinateEntryFormat: coordinateFormat}), |
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.
in Mapeo Mobile, we use to store an individual value in async storage that pertained to the coordinate format used specifically for manual entry. I believe the context for this is that the user's chosen coordinate format setting for displaying is not necessarily the same as for manual input, hence the separation
function entryCoordinateFormatSelector( | ||
state: Parameters<Parameters<typeof usePersistedSettings>[0]>[0], | ||
) { | ||
return state.manualCoordinateEntryFormat; | ||
} | ||
|
||
function observationValueSelector( | ||
state: Parameters<Parameters<typeof usePersistedDraftObservation>[0]>[0], | ||
) { | ||
return state.value; | ||
} |
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.
probably unnecessary but small easy-to-implement optimization when working with zustand selectors
</Text> | ||
{!accuracy ? null : ( | ||
{coordinateInfo.accuracy === undefined ? null : ( |
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.
subtle bug fix
|
||
return ( | ||
<View style={styles.locationContainer}> | ||
{!lat || !lon ? ( | ||
{coordinateInfo.lat === undefined || coordinateInfo.lon === undefined ? ( |
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.
subtle bug fix
@@ -184,11 +184,12 @@ export const SaveButton = ({ | |||
return; | |||
} | |||
|
|||
const hasLocation = value.lat && value.lon; | |||
const hasLocation = value.lat !== undefined && value.lon !== undefined; |
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.
subtle bug fix
hasLocation && | ||
(locationSetManually || | ||
isGpsAccurate(value.metadata.position?.coords?.accuracy)) |
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.
potentially subtle bug fix? noticed that it differs from Mapeo Mobile implementation:
4103662
to
83e41ca
Compare
c0b2e19
to
8de70c3
Compare
8de70c3
to
78d37df
Compare
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 know you talked about this before, but the heavy use of useEffect
to track the global state is not ideal. I know that you more or less just copied this over for time sake, but perhaps we should create an issue to refactor this in the future.
Otherwise lets write the unit tests before we merge this.
getInitialCardinality('lat', initialCoordinates), | ||
); | ||
const [selectedLonCardinality, setSelectedLonCardinality] = React.useState( | ||
getInitialCardinality('lon', initialCoordinates), |
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.
getInitialCardinality
should be curried (read third comment in thread)
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.
oh wow TIL - in this case, i don't need the currying because the intention is to return an initial value (not a function), but will update
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.
addressed via 298c24b
<Select | ||
containerStyles={styles.selectContainer} | ||
onChange={value => { | ||
if (typeof value === 'number' || !isCoordinateFormat(value)) { |
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.
is there a reason for the number
check?
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.
hm good question - doesn't seem like it's needed
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.
addressed via 556dabc
const {setManualCoordinateEntryFormat} = usePersistedSettingsAction(); | ||
const {updateObservationPosition} = useDraftObservation(); | ||
|
||
React.useLayoutEffect(() => { |
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.
perhaps a slight and unnecessary optimization, but I think we can use useEffect
here. I don't think we need to block the rendering of the button because it is visually the same(its only functionally different).
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.
addressed via 5b57199
src/frontend/screens/ObservationEdit/useMostAccurateLocationForObservation.ts
Show resolved
Hide resolved
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.
it is possible to save when there is no East
or North
. This is returning a latLon of NaN
.
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.
for posterity i saved zone number as 8
and zone letter as 'S'
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.
When trying to save the observation (in the observationEdit Screen), it throws an error.
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.
thanks for catching. was hoping to avoid adding fixes for pre-existing bugs to this PR but was able to fix this pretty easily, so will include the changes for that in this PR
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.
addressed via e79fb89
if (convertedData.error) { | ||
return ToastAndroid.showWithGravity( | ||
convertedData.error.message, | ||
ToastAndroid.LONG, | ||
ToastAndroid.TOP, | ||
); | ||
} |
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 think we should also check if lat
and lon
are valid here. I know that we attempted to do that in each component BUT having one last check will avoid the issue that I found in UTM form
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.
Addressed via e505753
GitHub Build Trigger Failure The build trigger failed with the following error:
Please check your GitHub app installation settings and your Expo project's GitHub settings to make sure you've configured everything correctly. |
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.
Addressed feedback and added some unit tests, which mostly test the various functions that are used to determine if the inputs in the various forms are valid or not. Not a full solution to testing this but think it's fine for now, especially if this screen sees a major refactor
if (convertedData.error) { | ||
return ToastAndroid.showWithGravity( | ||
convertedData.error.message, | ||
ToastAndroid.LONG, | ||
ToastAndroid.TOP, | ||
); | ||
} |
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.
Addressed via e505753
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.
addressed via e79fb89
const {setManualCoordinateEntryFormat} = usePersistedSettingsAction(); | ||
const {updateObservationPosition} = useDraftObservation(); | ||
|
||
React.useLayoutEffect(() => { |
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.
addressed via 5b57199
<Select | ||
containerStyles={styles.selectContainer} | ||
onChange={value => { | ||
if (typeof value === 'number' || !isCoordinateFormat(value)) { |
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.
addressed via 556dabc
getInitialCardinality('lat', initialCoordinates), | ||
); | ||
const [selectedLonCardinality, setSelectedLonCardinality] = React.useState( | ||
getInitialCardinality('lon', initialCoordinates), |
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.
addressed via 298c24b
GitHub Build Trigger Failure The build trigger failed with the following error:
Please check your GitHub app installation settings and your Expo project's GitHub settings to make sure you've configured everything correctly. |
GitHub Build Trigger Failure The build trigger failed with the following error:
Please check your GitHub app installation settings and your Expo project's GitHub settings to make sure you've configured everything correctly. |
Closes #164
Mostly ported over from Mapeo Mobile. Had to do a non-trivial amount of refactoring due to different setups for persisted state and differences in hooks though.
Mostly worried about any potential edge cases throughout the app that may be dependent on the
manualLocation
field of the observation. Tried my best to address the more notable areas (such as in the observation creation screen)There are also a few small changes that are not strictly related to adding this feature but fix subtle bugs that one could encounter by using this.
Preview: