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

feat: implement manual gps coordinate entry screen #219

Merged
merged 12 commits into from
May 1, 2024

Conversation

achou11
Copy link
Member

@achou11 achou11 commented Apr 3, 2024

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:

image

image

image

image

@achou11 achou11 requested a review from ErikSin April 3, 2024 20:13
@achou11 achou11 force-pushed the 164/manual-gps-screen branch 4 times, most recently from 6e09e5c to d9f15ff Compare April 3, 2024 20:38
@@ -76,6 +76,7 @@ const draftObservationSlice: StateCreator<DraftObservationSlice> = (
metadata: {
...prevValue.metadata,
position: props.position,
manualLocation: props.manualLocation,
Copy link
Member Author

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 🥲

Comment on lines +18 to +22
manualCoordinateEntryFormat: 'utm',
actions: {
setCoordinateFormat: coordinateFormat => set({coordinateFormat}),
setManualCoordinateEntryFormat: coordinateFormat =>
set({manualCoordinateEntryFormat: coordinateFormat}),
Copy link
Member Author

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

Comment on lines +197 to +207
function entryCoordinateFormatSelector(
state: Parameters<Parameters<typeof usePersistedSettings>[0]>[0],
) {
return state.manualCoordinateEntryFormat;
}

function observationValueSelector(
state: Parameters<Parameters<typeof usePersistedDraftObservation>[0]>[0],
) {
return state.value;
}
Copy link
Member Author

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 : (
Copy link
Member Author

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 ? (
Copy link
Member Author

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;
Copy link
Member Author

Choose a reason for hiding this comment

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

subtle bug fix

Comment on lines +190 to +221
hasLocation &&
(locationSetManually ||
isGpsAccurate(value.metadata.position?.coords?.accuracy))
Copy link
Member Author

Choose a reason for hiding this comment

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

@achou11 achou11 force-pushed the 164/manual-gps-screen branch 5 times, most recently from 4103662 to 83e41ca Compare April 16, 2024 20:31
@achou11 achou11 force-pushed the 164/manual-gps-screen branch 4 times, most recently from c0b2e19 to 8de70c3 Compare April 24, 2024 20:26
@achou11 achou11 force-pushed the 164/manual-gps-screen branch from 8de70c3 to 78d37df Compare April 25, 2024 20:39
Copy link
Contributor

@ErikSin ErikSin left a 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.

Comment on lines 99 to 102
getInitialCardinality('lat', initialCoordinates),
);
const [selectedLonCardinality, setSelectedLonCardinality] = React.useState(
getInitialCardinality('lon', initialCoordinates),
Copy link
Contributor

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)

Copy link
Member Author

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

Copy link
Member Author

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)) {
Copy link
Contributor

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?

Copy link
Member Author

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

Copy link
Member Author

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(() => {
Copy link
Contributor

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 useEffecthere. I don't think we need to block the rendering of the button because it is visually the same(its only functionally different).

Copy link
Member Author

Choose a reason for hiding this comment

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

addressed via 5b57199

Copy link
Contributor

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.

Copy link
Contributor

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'

Copy link
Contributor

@ErikSin ErikSin Apr 29, 2024

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.

Copy link
Member Author

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

Copy link
Member Author

Choose a reason for hiding this comment

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

addressed via e79fb89

Comment on lines +92 to +98
if (convertedData.error) {
return ToastAndroid.showWithGravity(
convertedData.error.message,
ToastAndroid.LONG,
ToastAndroid.TOP,
);
}
Copy link
Contributor

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed via e505753

Copy link

expo bot commented Apr 29, 2024

GitHub Build Trigger Failure

The build trigger failed with the following error:

eas.json not found in the repository.

Please check your GitHub app installation settings and your Expo project's GitHub settings to make sure you've configured everything correctly.

Copy link
Member Author

@achou11 achou11 left a 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

Comment on lines +92 to +98
if (convertedData.error) {
return ToastAndroid.showWithGravity(
convertedData.error.message,
ToastAndroid.LONG,
ToastAndroid.TOP,
);
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed via e505753

Copy link
Member Author

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(() => {
Copy link
Member Author

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)) {
Copy link
Member Author

Choose a reason for hiding this comment

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

addressed via 556dabc

Comment on lines 99 to 102
getInitialCardinality('lat', initialCoordinates),
);
const [selectedLonCardinality, setSelectedLonCardinality] = React.useState(
getInitialCardinality('lon', initialCoordinates),
Copy link
Member Author

Choose a reason for hiding this comment

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

addressed via 298c24b

@achou11 achou11 requested a review from ErikSin April 29, 2024 22:27
Copy link

expo bot commented Apr 29, 2024

GitHub Build Trigger Failure

The build trigger failed with the following error:

eas.json not found in the repository.

Please check your GitHub app installation settings and your Expo project's GitHub settings to make sure you've configured everything correctly.

Copy link

expo bot commented Apr 29, 2024

GitHub Build Trigger Failure

The build trigger failed with the following error:

eas.json not found in the repository.

Please check your GitHub app installation settings and your Expo project's GitHub settings to make sure you've configured everything correctly.

@achou11 achou11 merged commit 46d3e16 into main May 1, 2024
3 checks passed
@achou11 achou11 deleted the 164/manual-gps-screen branch May 1, 2024 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Manual GPS Screen
2 participants