diff --git a/.github/workflows/e2e_android.yml b/.github/workflows/e2e_android.yml index ddfc70cc7..fed851e2b 100644 --- a/.github/workflows/e2e_android.yml +++ b/.github/workflows/e2e_android.yml @@ -83,7 +83,8 @@ jobs: E2E_TEST_USERNAME: ${{ secrets.E2E_TEST_USERNAME }} E2E_TEST_PASSWORD: ${{ secrets.E2E_TEST_PASSWORD }} JWT_ANONYMOUS_API_SECRET: ${{ secrets.JWT_ANONYMOUS_API_SECRET }} - run: printf 'API_URL=https://stagingapi.inaturalist.org/v2\nOAUTH_API_URL=https://staging.inaturalist.org\nJWT_ANONYMOUS_API_SECRET=%s\nOAUTH_CLIENT_ID=%s\nOAUTH_CLIENT_SECRET=%s\nE2E_TEST_USERNAME=%s\nE2E_TEST_PASSWORD=%s\n' "JWT_ANONYMOUS_API_SECRET" "$OAUTH_CLIENT_ID" "$OAUTH_CLIENT_SECRET" "$E2E_TEST_USERNAME" "$E2E_TEST_PASSWORD" > .env + GMAPS_API_KEY: ${{ secrets.GMAPS_API_KEY }} + run: printf 'API_URL=https://stagingapi.inaturalist.org/v2\nOAUTH_API_URL=https://staging.inaturalist.org\nJWT_ANONYMOUS_API_SECRET=%s\nOAUTH_CLIENT_ID=%s\nOAUTH_CLIENT_SECRET=%s\nE2E_TEST_USERNAME=%s\nE2E_TEST_PASSWORD=%s\nGMAPS_API_KEY=%s\n' "JWT_ANONYMOUS_API_SECRET" "$OAUTH_CLIENT_ID" "$OAUTH_CLIENT_SECRET" "$E2E_TEST_USERNAME" "$E2E_TEST_PASSWORD" "$GMAPS_API_KEY" > .env - name: Create keystore.properties file env: ANDROID_KEY_STORE_PASSWORD: ${{ secrets.ANDROID_KEY_STORE_PASSWORD }} diff --git a/.gitignore b/.gitignore index 45c103df5..20596ecb2 100644 --- a/.gitignore +++ b/.gitignore @@ -78,4 +78,4 @@ artifacts/ *.log # VisualStudioCode # -.vscode +.vscode \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index 0fcec44ed..a64e9eff8 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -129,6 +129,7 @@ android { // Detox Android setup testBuildType System.getProperty('testBuildType', 'debug') testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' + manifestPlaceholders = [ GMAPS_API_KEY:project.env.get("GMAPS_API_KEY") ] // Detox end } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c9d153cb7..43e85432c 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -17,6 +17,8 @@ android:theme="@style/AppTheme" android:requestLegacyExternalStorage="true" android:networkSecurityConfig="@xml/network_security_config"> + + { diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 43b773845..03d6c3a97 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -293,7 +293,7 @@ PODS: - React-Core - react-native-mail (6.1.1): - React-Core - - react-native-maps (0.31.1): + - react-native-maps (1.7.1): - React-Core - react-native-netinfo (9.3.9): - React-Core @@ -723,7 +723,7 @@ SPEC CHECKSUMS: react-native-image-resizer: 00ceb0e05586c7aadf061eea676957a6c2ec60fa react-native-keep-awake: acbee258db16483744910f0da3ace39eb9ab47fd react-native-mail: 8fdcd3aef007c33a6877a18eb4cf7447a1d4ce4a - react-native-maps: 8b8bfada2c86205a7f5a07dd1f92f29b33ea83aa + react-native-maps: 667f9b975549c6fa9b1631bf859440f68ebd3b8f react-native-netinfo: 22c082970cbd99071a4e5aa7a612ac20d66b08f0 react-native-orientation-locker: 851f6510d8046ea2f14aa169b1e01fcd309a94ba react-native-render-html: 984dfe2294163d04bf5fe25d7c9f122e60e05ebe @@ -765,4 +765,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 1e393412e8a65a884dff99189d809b73ea234bcd -COCOAPODS: 1.11.3 +COCOAPODS: 1.12.0 diff --git a/package-lock.json b/package-lock.json index 506c1b012..edd64402a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -71,7 +71,7 @@ "react-native-localize": "^2.2.6", "react-native-logs": "^5.0.1", "react-native-mail": "github:chirag04/react-native-mail", - "react-native-maps": "^0.31.1", + "react-native-maps": "^1.7.1", "react-native-modal": "^13.0.1", "react-native-modal-datetime-picker": "^15.0.0", "react-native-network-logger": "^1.14.1", @@ -8893,16 +8893,6 @@ "node": ">= 0.8" } }, - "node_modules/deprecated-react-native-prop-types": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-2.3.0.tgz", - "integrity": "sha512-pWD0voFtNYxrVqvBMYf5gq3NA2GCpfodS1yNynTPc93AYA/KEMGeWDqqeUB6R2Z9ZofVhks2aeJXiuQqKNpesA==", - "dependencies": { - "@react-native/normalize-color": "*", - "invariant": "*", - "prop-types": "*" - } - }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -21525,16 +21515,15 @@ "license": "MIT" }, "node_modules/react-native-maps": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/react-native-maps/-/react-native-maps-0.31.1.tgz", - "integrity": "sha512-vipeOPykqLRMCLcLUCZEB+cTdNSlq88NLb0jChY4UGTY5fgOS7GYWkfswy6bW1ayTRLxJS3zpMGFDUY59/ZrXA==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/react-native-maps/-/react-native-maps-1.7.1.tgz", + "integrity": "sha512-CHVLzL+Q2jiUGgbt4/vosxVI1SukWyaLGjD62VLgR/wZpnH4Umi9ql1bmKDPWcfj2C1QZwMU0Yc7rXTbvZUIiw==", "dependencies": { - "@types/geojson": "^7946.0.7", - "deprecated-react-native-prop-types": "^2.3.0" + "@types/geojson": "^7946.0.10" }, "peerDependencies": { - "react": ">= 16.0", - "react-native": ">= 0.51", + "react": ">= 17.0.1", + "react-native": ">= 0.64.3", "react-native-web": ">= 0.11" }, "peerDependenciesMeta": { @@ -31556,16 +31545,6 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, - "deprecated-react-native-prop-types": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-2.3.0.tgz", - "integrity": "sha512-pWD0voFtNYxrVqvBMYf5gq3NA2GCpfodS1yNynTPc93AYA/KEMGeWDqqeUB6R2Z9ZofVhks2aeJXiuQqKNpesA==", - "requires": { - "@react-native/normalize-color": "*", - "invariant": "*", - "prop-types": "*" - } - }, "destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -40876,12 +40855,11 @@ "from": "react-native-mail@github:chirag04/react-native-mail" }, "react-native-maps": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/react-native-maps/-/react-native-maps-0.31.1.tgz", - "integrity": "sha512-vipeOPykqLRMCLcLUCZEB+cTdNSlq88NLb0jChY4UGTY5fgOS7GYWkfswy6bW1ayTRLxJS3zpMGFDUY59/ZrXA==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/react-native-maps/-/react-native-maps-1.7.1.tgz", + "integrity": "sha512-CHVLzL+Q2jiUGgbt4/vosxVI1SukWyaLGjD62VLgR/wZpnH4Umi9ql1bmKDPWcfj2C1QZwMU0Yc7rXTbvZUIiw==", "requires": { - "@types/geojson": "^7946.0.7", - "deprecated-react-native-prop-types": "^2.3.0" + "@types/geojson": "^7946.0.10" } }, "react-native-modal": { diff --git a/package.json b/package.json index f3bf7ddee..1f449c1ce 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "react-native-localize": "^2.2.6", "react-native-logs": "^5.0.1", "react-native-mail": "github:chirag04/react-native-mail", - "react-native-maps": "^0.31.1", + "react-native-maps": "^1.7.1", "react-native-modal": "^13.0.1", "react-native-modal-datetime-picker": "^15.0.0", "react-native-network-logger": "^1.14.1", diff --git a/src/components/LocationPicker/CrosshairCircle.js b/src/components/LocationPicker/CrosshairCircle.js new file mode 100644 index 000000000..0243bdd9d --- /dev/null +++ b/src/components/LocationPicker/CrosshairCircle.js @@ -0,0 +1,57 @@ +// @flow + +import classnames from "classnames"; +import { INatIcon } from "components/SharedComponents"; +import { View } from "components/styledComponents"; +import type { Node } from "react"; +import React from "react"; +import { useTheme } from "react-native-paper"; + +type Props = { + accuracyTest: string, + containerStyle: Object +}; + +const CrosshairCircle = ( { accuracyTest, containerStyle }: Props ): Node => { + const theme = useTheme( ); + + return ( + + + {/* vertical crosshair */} + + {/* horizontal crosshair */} + + + + {accuracyTest === "pass" && ( + + )} + {accuracyTest === "fail" && ( + + )} + + + ); +}; + +export default CrosshairCircle; diff --git a/src/components/LocationPicker/DisplayLatLng.js b/src/components/LocationPicker/DisplayLatLng.js new file mode 100644 index 000000000..176aedeb8 --- /dev/null +++ b/src/components/LocationPicker/DisplayLatLng.js @@ -0,0 +1,47 @@ +// @flow + +import { + Body4 +} from "components/SharedComponents"; +import { View } from "components/styledComponents"; +import type { Node } from "react"; +import React from "react"; +import { useTheme } from "react-native-paper"; + +type Props = { + region: Object, + accuracy: number, + getShadow: Function +}; + +const DisplayLatLng = ( { region, accuracy, getShadow }: Props ): Node => { + const theme = useTheme( ); + const formatDecimal = coordinate => coordinate && coordinate.toFixed( 6 ); + + const displayLocation = ( ) => { + let location = ""; + if ( region.latitude ) { + location += `Lat: ${formatDecimal( region.latitude )}`; + } + if ( region.longitude ) { + location += `, Lon: ${formatDecimal( region.longitude )}`; + } + if ( accuracy ) { + location += `, Acc: ${accuracy.toFixed( 0 )}`; + } + return location; + }; + + return ( + + + {displayLocation( )} + + + ); +}; + +export default DisplayLatLng; diff --git a/src/components/LocationPicker/Footer.js b/src/components/LocationPicker/Footer.js new file mode 100644 index 000000000..49bfaa23a --- /dev/null +++ b/src/components/LocationPicker/Footer.js @@ -0,0 +1,45 @@ +// @flow + +import { useNavigation } from "@react-navigation/native"; +import { + Button, StickyToolbar +} from "components/SharedComponents"; +import { ObsEditContext } from "providers/contexts"; +import type { Node } from "react"; +import React, { + useContext +} from "react"; +import { Platform } from "react-native"; +import useTranslation from "sharedHooks/useTranslation"; + +type Props = { + keysToUpdate: Object, + goBackOnSave: boolean +}; + +const Footer = ( { keysToUpdate, goBackOnSave }: Props ): Node => { + const navigation = useNavigation( ); + const { t } = useTranslation( ); + const { + updateObservationKeys + } = useContext( ObsEditContext ); + + return ( + +