From 0b9e09e1d2b7d8ee525e8d0deceb9f329def8c5c Mon Sep 17 00:00:00 2001 From: Angie Ta Date: Tue, 27 Feb 2024 01:39:21 -0800 Subject: [PATCH 1/7] Taxon map preview, taxon detail map screen, moved DetailsMap to SharedComponents --- .../DetailsTab/DetailsMapContainer.js | 75 ++++++++----- .../DetailsMap.js | 102 +++++++++-------- src/components/TaxonDetails/TaxonDetails.js | 2 + .../TaxonDetails/TaxonDetailsMapContainer.js | 38 +++++++ .../TaxonDetails/TaxonMapPreview.js | 104 ++++++++++++++++++ 5 files changed, 242 insertions(+), 79 deletions(-) rename src/components/{ObsDetails/DetailsTab => SharedComponents}/DetailsMap.js (69%) create mode 100644 src/components/TaxonDetails/TaxonDetailsMapContainer.js create mode 100644 src/components/TaxonDetails/TaxonMapPreview.js diff --git a/src/components/ObsDetails/DetailsTab/DetailsMapContainer.js b/src/components/ObsDetails/DetailsTab/DetailsMapContainer.js index 4d282505d..29074cb40 100644 --- a/src/components/ObsDetails/DetailsTab/DetailsMapContainer.js +++ b/src/components/ObsDetails/DetailsTab/DetailsMapContainer.js @@ -1,12 +1,17 @@ // @flow -import Clipboard from "@react-native-clipboard/clipboard"; -import DetailsMap from "components/ObsDetails/DetailsTab/DetailsMap"; import checkCamelAndSnakeCase from "components/ObsDetails/helpers/checkCamelAndSnakeCase"; +import { + Body2, + Body4 +} from "components/SharedComponents"; +import DetailsMap from "components/SharedComponents/DetailsMap"; +import { + View +} from "components/styledComponents"; import { t } from "i18next"; import type { Node } from "react"; -import React, { useRef, useState } from "react"; -import openMap from "react-native-open-maps"; +import React, { useRef } from "react"; type Props = { observation: Object, @@ -17,6 +22,35 @@ type Props = { tileMapParams: ?Object } +const DetailsMapHeader = ( { + displayLocation, + displayCoordinates, + obscured +} ) => ( + + + {displayLocation} + + + + {displayCoordinates} + + {obscured && ( + + {t( "Obscured-observation-location-map-description" )} + + ) } + +); + const DetailsMapContainer = ( { observation, latitude, longitude, closeModal, obscured, tileMapParams }: Props ): Node => { @@ -25,7 +59,6 @@ const DetailsMapContainer = ( { longitude } ); - const [showNotificationModal, setShowNotificationModal] = useState( false ); const displayCoordinates = t( "Lat-Lon-Acc", { latitude, longitude, @@ -40,21 +73,6 @@ const DetailsMapContainer = ( { displayLocation = t( "No-Location" ); } - const closeShowNotificationModal = () => { - setShowNotificationModal( false ); - }; - const copyCoordinates = () => { - Clipboard.setString( coordinateString ); - setShowNotificationModal( true ); - // notification disappears after 2 secs - setTimeout( closeShowNotificationModal, 2000 ); - }; - - const shareMap = () => { - // takes in a provider prop but opens in browser instead of in app(google maps on iOS) - openMap( { query: `${latitude}, ${longitude}` } ); - }; - const mapViewRef = useRef( null ); return ( @@ -63,15 +81,18 @@ const DetailsMapContainer = ( { latitude={latitude} longitude={longitude} obscured={obscured} - positionalAccuracy={observation.positional_accuracy} - displayLocation={displayLocation} - displayCoordinates={displayCoordinates} - copyCoordinates={copyCoordinates} - shareMap={shareMap} - showNotificationModal={showNotificationModal} - closeNotificationsModal={closeShowNotificationModal} + coordinateString={coordinateString} closeModal={closeModal} + positionalAccuracy={observation.positional_accuracy} tileMapParams={tileMapParams} + showLocationIndicator + headerTitle={( + + )} /> ); }; diff --git a/src/components/ObsDetails/DetailsTab/DetailsMap.js b/src/components/SharedComponents/DetailsMap.js similarity index 69% rename from src/components/ObsDetails/DetailsTab/DetailsMap.js rename to src/components/SharedComponents/DetailsMap.js index 5310a221b..6884d01db 100644 --- a/src/components/ObsDetails/DetailsTab/DetailsMap.js +++ b/src/components/SharedComponents/DetailsMap.js @@ -1,10 +1,12 @@ // @flow +import Clipboard from "@react-native-clipboard/clipboard"; import { HeaderBackButton } from "@react-navigation/elements"; import classnames from "classnames"; +import CoordinatesCopiedNotification + from "components/ObsDetails/DetailsTab/CoordinatesCopiedNotification"; import { - Body2, - Body4, + Heading2, INatIconButton, Map, Modal @@ -15,13 +17,12 @@ import { } from "components/styledComponents"; import { t } from "i18next"; import type { Node } from "react"; -import React from "react"; +import React, { useState } from "react"; +import openMap from "react-native-open-maps"; import { useTheme } from "react-native-paper"; import IconMaterial from "react-native-vector-icons/MaterialCommunityIcons"; import { getShadowForColor } from "styles/global"; -import CoordinatesCopiedNotification from "./CoordinatesCopiedNotification"; - const HEADER_BACK_BUTTON_STYLE = { marginBottom: 15, marginLeft: 15 @@ -31,16 +32,14 @@ type Props = { latitude: number, longitude: number, obscured?: boolean, - positionalAccuracy: number, + positionalAccuracy?: number, mapViewRef: any, - showNotificationModal: boolean, - displayLocation: string, - displayCoordinates: string, - closeNotificationsModal: Function, - copyCoordinates: Function, - shareMap: Function, + region?: Object, closeModal: Function, - tileMapParams: Object + tileMapParams: Object, + headerTitle?: Object, + showLocationIndicator: boolean, + coordinateString?: string } const FloatingActionButton = ( { @@ -82,29 +81,57 @@ const FloatingActionButton = ( { const DetailsMap = ( { closeModal, - closeNotificationsModal, - copyCoordinates, - displayCoordinates, - displayLocation, latitude, longitude, mapViewRef, obscured, positionalAccuracy, - shareMap, - showNotificationModal, - tileMapParams + tileMapParams, + headerTitle, + showLocationIndicator, + region, + coordinateString }: Props ): Node => { const theme = useTheme( ); + const [showNotificationModal, setShowNotificationModal] = useState( false ); + + const closeShowNotificationModal = () => { + setShowNotificationModal( false ); + }; + const copyCoordinates = () => { + if ( coordinateString ) { + Clipboard.setString( coordinateString ); + setShowNotificationModal( true ); + // notification disappears after 2 secs + setTimeout( closeShowNotificationModal, 2000 ); + } + }; + + const shareMap = () => { + // takes in a provider prop but opens in browser instead of in app(google maps on iOS) + openMap( { query: `${latitude}, ${longitude}` } ); + }; + return ( + + closeModal()} + style={HEADER_BACK_BUTTON_STYLE} + /> + + {headerTitle || {t( "Map-Area" )}} + + - { !obscured && ( + { ( !obscured && showLocationIndicator ) && ( <> - - closeModal()} - style={HEADER_BACK_BUTTON_STYLE} - /> - - - {displayLocation} - - - - {displayCoordinates} - - {obscured && ( - - {t( "Obscured-observation-location-map-description" )} - - ) } - - closeNotificationsModal( false )} + closeModal={( ) => closeShowNotificationModal( false )} modal={( )} diff --git a/src/components/TaxonDetails/TaxonDetails.js b/src/components/TaxonDetails/TaxonDetails.js index b3b78b2d1..1451672d9 100644 --- a/src/components/TaxonDetails/TaxonDetails.js +++ b/src/components/TaxonDetails/TaxonDetails.js @@ -32,6 +32,7 @@ import { useAuthenticatedQuery, useTranslation, useUserMe } from "sharedHooks"; import EstablishmentMeans from "./EstablishmentMeans"; import TaxonDetailsMediaViewerHeader from "./TaxonDetailsMediaViewerHeader"; import TaxonDetailsTitle from "./TaxonDetailsTitle"; +import TaxonMapPreview from "./TaxonMapPreview"; import Taxonomy from "./Taxonomy"; import Wikipedia from "./Wikipedia"; @@ -119,6 +120,7 @@ const TaxonDetails = ( ): Node => { + ); }; diff --git a/src/components/TaxonDetails/TaxonDetailsMapContainer.js b/src/components/TaxonDetails/TaxonDetailsMapContainer.js new file mode 100644 index 000000000..b2cad9f7c --- /dev/null +++ b/src/components/TaxonDetails/TaxonDetailsMapContainer.js @@ -0,0 +1,38 @@ +// @flow + +import DetailsMap from "components/SharedComponents/DetailsMap"; +import type { Node } from "react"; +import React, { useRef } from "react"; + +import TaxonDetailsTitle from "./TaxonDetailsTitle"; + +type Props = { + taxon: Object, + latitude: number, + longitude: number, + closeModal: Function, + tileMapParams: ?Object, + region: Object +} + +const TaxonDetailsMapContainer = ( { + taxon, region, latitude, longitude, closeModal, tileMapParams +}: Props ): Node => { + const mapViewRef = useRef( null ); + + return ( + } + + /> + ); +}; + +export default TaxonDetailsMapContainer; diff --git a/src/components/TaxonDetails/TaxonMapPreview.js b/src/components/TaxonDetails/TaxonMapPreview.js new file mode 100644 index 000000000..377ac189e --- /dev/null +++ b/src/components/TaxonDetails/TaxonMapPreview.js @@ -0,0 +1,104 @@ +// @flow + +import { searchObservations } from "api/observations"; +import { + Heading4, + Map, + Modal +} from "components/SharedComponents"; +import { + View +} from "components/styledComponents"; +import type { Node } from "react"; +import React, { useState } from "react"; +import { useTranslation } from "sharedHooks"; +import useAuthenticatedQuery from "sharedHooks/useAuthenticatedQuery"; + +import TaxonDetailsMapContainer from "./TaxonDetailsMapContainer"; + + type Props = { + taxon: Object + } + +const TaxonMapPreview = ( { + taxon +}: Props ): Node => { + const { t } = useTranslation( ); + const [showMapModal, setShowMapModal] = useState( false ); + const { + data: taxonList + } = useAuthenticatedQuery( + ["fetchTaxonBoundingBox"], + optsWithAuth => searchObservations( { + taxon_id: taxon.id, + return_bounds: true, + verifiable: true, + ttl: -1 + }, optsWithAuth ) + ); + + const tileMapParams = { + taxon: taxon.id + }; + + const getMapRegion = bounds => { + const { + nelat, nelng, swlat, swlng + } = bounds; + const lat = ( Number( nelat ) + Number( swlat ) ) / 2; + const lng = ( Number( nelng ) + Number( swlng ) ) / 2; + const latDelta = Number( nelat ) - lat; + const lngDelta = Number( nelat ) - lng; + + return { + latitude: lat, + longitude: lng, + latitudeDelta: latDelta, + longitudeDelta: lngDelta + }; + }; + + if ( taxonList?.total_bounds ) { + const region = getMapRegion( taxonList?.total_bounds ); + + return ( + + {t( "MAP" )} + setShowMapModal( true )} + tileMapParams={tileMapParams} + withObsTiles={tileMapParams !== null} + /> + setShowMapModal( false )} + disableSwipeDirection + // eslint-disable-next-line react-native/no-inline-styles + style={{ margin: 0 }} + modal={( + setShowMapModal( false )} + tileMapParams={tileMapParams} + /> + )} + /> + + + ); + } + + return ( + + + ); +}; + +export default TaxonMapPreview; From 3082e8e3857d286ae98b163055310dc21e134e5c Mon Sep 17 00:00:00 2001 From: Angie Ta Date: Tue, 27 Feb 2024 01:43:42 -0800 Subject: [PATCH 2/7] Fix typo, add comment for TODO --- src/components/SharedComponents/DetailsMap.js | 2 +- src/components/TaxonDetails/TaxonMapPreview.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/SharedComponents/DetailsMap.js b/src/components/SharedComponents/DetailsMap.js index 6884d01db..20b83bc21 100644 --- a/src/components/SharedComponents/DetailsMap.js +++ b/src/components/SharedComponents/DetailsMap.js @@ -167,7 +167,7 @@ const DetailsMap = ( { animationIn="fadeIn" animationOut="fadeOut" showModal={showNotificationModal} - closeModal={( ) => closeShowNotificationModal( false )} + closeModal={( ) => closeShowNotificationModal( )} modal={( )} diff --git a/src/components/TaxonDetails/TaxonMapPreview.js b/src/components/TaxonDetails/TaxonMapPreview.js index 377ac189e..041fbf765 100644 --- a/src/components/TaxonDetails/TaxonMapPreview.js +++ b/src/components/TaxonDetails/TaxonMapPreview.js @@ -25,6 +25,8 @@ const TaxonMapPreview = ( { }: Props ): Node => { const { t } = useTranslation( ); const [showMapModal, setShowMapModal] = useState( false ); + + // TODO: add a loading indicator for map preview const { data: taxonList } = useAuthenticatedQuery( From caa269537c49431ec72c52154083d38b0c23e314 Mon Sep 17 00:00:00 2001 From: Angie Ta Date: Mon, 25 Mar 2024 21:56:36 -0700 Subject: [PATCH 3/7] Map shows observation tiles for Taxon, taxon range map zoom better --- src/components/TaxonDetails/TaxonMapPreview.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/TaxonDetails/TaxonMapPreview.js b/src/components/TaxonDetails/TaxonMapPreview.js index 041fbf765..e8461fb6f 100644 --- a/src/components/TaxonDetails/TaxonMapPreview.js +++ b/src/components/TaxonDetails/TaxonMapPreview.js @@ -40,7 +40,7 @@ const TaxonMapPreview = ( { ); const tileMapParams = { - taxon: taxon.id + taxon_id: taxon.id }; const getMapRegion = bounds => { @@ -49,8 +49,8 @@ const TaxonMapPreview = ( { } = bounds; const lat = ( Number( nelat ) + Number( swlat ) ) / 2; const lng = ( Number( nelng ) + Number( swlng ) ) / 2; - const latDelta = Number( nelat ) - lat; - const lngDelta = Number( nelat ) - lng; + const latDelta = ( Number( nelat ) - lat ) * 2; + const lngDelta = ( Number( nelng ) - lng ) * 2; return { latitude: lat, From df46bb8d37509ae188964eaf434cce42a171f85a Mon Sep 17 00:00:00 2001 From: Angie Ta Date: Tue, 26 Mar 2024 10:26:47 -0700 Subject: [PATCH 4/7] Adjust padding for header text --- src/components/SharedComponents/DetailsMap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/SharedComponents/DetailsMap.js b/src/components/SharedComponents/DetailsMap.js index d592eced8..0e8855ace 100644 --- a/src/components/SharedComponents/DetailsMap.js +++ b/src/components/SharedComponents/DetailsMap.js @@ -114,7 +114,7 @@ const DetailsMap = ( { return ( - + closeModal()} From 521307f44d700353e9a1b83e947f788702f3f743 Mon Sep 17 00:00:00 2001 From: Ken-ichi Ueda Date: Tue, 26 Mar 2024 17:19:33 -0700 Subject: [PATCH 5/7] Several minor fixes * disable interaction on TaxonDetails map * disable SpeciesSeenCheckmark when signed out * Remove x margin on TaxonDetails map * Fix broken region calculation on TaxonDetails map * Ensure TaxonDetails map uses same obs search params for bounds calculation and tiles --- ios/Podfile.lock | 4 +- .../project.pbxproj | 12 +--- src/components/SharedComponents/Map.js | 11 ++- .../SharedComponents/SpeciesSeenCheckmark.js | 5 +- src/components/TaxonDetails/TaxonDetails.js | 2 +- .../TaxonDetails/TaxonMapPreview.js | 72 ++++++++++--------- 6 files changed, 58 insertions(+), 48 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index a6d7e6745..b3fc328aa 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -727,7 +727,7 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - boost: 57d2868c099736d80fcd648bf211b4431e51a558 + boost: 7dcd2de282d72e344012f7d6564d024930a6a440 BVLinearGradient: 880f91a7854faff2df62518f0281afb1c60d49a3 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 FBLazyVector: 9840513ec2766e31fb9e34c2dabb2c4671400fcd @@ -810,4 +810,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 77ed9526d4011b245ce5afa1ea331dea4c67d753 -COCOAPODS: 1.14.2 +COCOAPODS: 1.14.3 diff --git a/ios/iNaturalistReactNative.xcodeproj/project.pbxproj b/ios/iNaturalistReactNative.xcodeproj/project.pbxproj index b61aa5d9f..3dfe1e31f 100644 --- a/ios/iNaturalistReactNative.xcodeproj/project.pbxproj +++ b/ios/iNaturalistReactNative.xcodeproj/project.pbxproj @@ -979,11 +979,7 @@ "-DFOLLY_MOBILE=1", "-DFOLLY_USE_LIBCPP=1", ); - OTHER_LDFLAGS = ( - "$(inherited)", - "-Wl", - "-ld_classic", - ); + OTHER_LDFLAGS = "$(inherited)"; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; }; @@ -1052,11 +1048,7 @@ "-DFOLLY_MOBILE=1", "-DFOLLY_USE_LIBCPP=1", ); - OTHER_LDFLAGS = ( - "$(inherited)", - "-Wl", - "-ld_classic", - ); + OTHER_LDFLAGS = "$(inherited)"; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; diff --git a/src/components/SharedComponents/Map.js b/src/components/SharedComponents/Map.js index 8b59a7699..d0c8c0fdf 100644 --- a/src/components/SharedComponents/Map.js +++ b/src/components/SharedComponents/Map.js @@ -86,6 +86,7 @@ type Props = { permissionRequested?: boolean, positionalAccuracy?: number, region?: Object, + scrollEnabled?: boolean, showCurrentLocationButton?: boolean, showLocationIndicator?: boolean, showsCompass?: boolean, @@ -98,6 +99,8 @@ type Props = { tileMapParams?: Object, withObsTiles?: boolean, withPressableObsTiles?: boolean, + zoomEnabled?: boolean, + zoomTapEnabled?: boolean } const getShadow = shadowColor => getShadowStyle( { @@ -135,6 +138,7 @@ const Map = ( { permissionRequested: permissionRequestedProp, positionalAccuracy, region, + scrollEnabled = true, showCurrentLocationButton, showLocationIndicator, showsCompass, @@ -146,7 +150,9 @@ const Map = ( { testID, tileMapParams, withObsTiles, - withPressableObsTiles + withPressableObsTiles, + zoomEnabled = true, + zoomTapEnabled = true }: Props ): Node => { const { screenWidth } = useDeviceOrientation( ); const [currentZoom, setCurrentZoom] = useState( @@ -449,6 +455,9 @@ const Map = ( { minZoomLevel={minZoomLevel} rotateEnabled={false} pitchEnabled={false} + scrollEnabled={scrollEnabled} + zoomEnabled={zoomEnabled} + zoomTapEnabled={zoomTapEnabled} > {( showLocationIndicator && ( !obscured ) ) && ( diff --git a/src/components/SharedComponents/SpeciesSeenCheckmark.js b/src/components/SharedComponents/SpeciesSeenCheckmark.js index b98be68d5..92551974c 100644 --- a/src/components/SharedComponents/SpeciesSeenCheckmark.js +++ b/src/components/SharedComponents/SpeciesSeenCheckmark.js @@ -36,14 +36,15 @@ const SpeciesSeenCheckmark = ( { ["searchObservations", taxonId], optsWithAuth => searchObservations( { - user_id: currentUser.id, + user_id: currentUser?.id, per_page: 0, taxon_id: taxonId }, optsWithAuth ), { - keepPreviousData: false + keepPreviousData: false, + enabled: !!currentUser } ); diff --git a/src/components/TaxonDetails/TaxonDetails.js b/src/components/TaxonDetails/TaxonDetails.js index c9c303be5..20cc1c820 100644 --- a/src/components/TaxonDetails/TaxonDetails.js +++ b/src/components/TaxonDetails/TaxonDetails.js @@ -120,7 +120,7 @@ const TaxonDetails = ( ): Node => { } return ( - + diff --git a/src/components/TaxonDetails/TaxonMapPreview.js b/src/components/TaxonDetails/TaxonMapPreview.js index e8461fb6f..bb295aca9 100644 --- a/src/components/TaxonDetails/TaxonMapPreview.js +++ b/src/components/TaxonDetails/TaxonMapPreview.js @@ -16,52 +16,55 @@ import useAuthenticatedQuery from "sharedHooks/useAuthenticatedQuery"; import TaxonDetailsMapContainer from "./TaxonDetailsMapContainer"; - type Props = { - taxon: Object - } +type Props = { + taxon: Object +} + +function getMapRegion( bounds: { nelat: number, nelng: number, swlat: number, swlng: number } ) { + const { + nelat, nelng, swlat, swlng + } = bounds; + // Deltas shouldn't be negative + const latDelta = Math.abs( Number( nelat ) - Number( swlat ) ); + const lngDelta = Math.abs( Number( nelng ) - Number( swlng ) ); + const lat = nelat - ( latDelta / 2 ); + const lng = nelng - ( lngDelta / 2 ); + + return { + latitude: lat, + longitude: lng, + // Pad the detlas so the user sees the full range, make sure we don't + // specify impossible deltas like 190 degrees of latitude + latitudeDelta: Math.min( latDelta + 5, 175 ), + longitudeDelta: Math.min( lngDelta + 5, 355 ) + }; +} const TaxonMapPreview = ( { taxon }: Props ): Node => { const { t } = useTranslation( ); const [showMapModal, setShowMapModal] = useState( false ); + const obsParams = { + taxon_id: taxon.id, + verifiable: true + }; // TODO: add a loading indicator for map preview const { - data: taxonList + data: obsSearchResponse } = useAuthenticatedQuery( ["fetchTaxonBoundingBox"], optsWithAuth => searchObservations( { - taxon_id: taxon.id, + ...obsParams, return_bounds: true, - verifiable: true, + per_page: 0, ttl: -1 }, optsWithAuth ) ); - const tileMapParams = { - taxon_id: taxon.id - }; - - const getMapRegion = bounds => { - const { - nelat, nelng, swlat, swlng - } = bounds; - const lat = ( Number( nelat ) + Number( swlat ) ) / 2; - const lng = ( Number( nelng ) + Number( swlng ) ) / 2; - const latDelta = ( Number( nelat ) - lat ) * 2; - const lngDelta = ( Number( nelng ) - lng ) * 2; - - return { - latitude: lat, - longitude: lng, - latitudeDelta: latDelta, - longitudeDelta: lngDelta - }; - }; - - if ( taxonList?.total_bounds ) { - const region = getMapRegion( taxonList?.total_bounds ); + if ( obsSearchResponse?.total_bounds ) { + const region = getMapRegion( obsSearchResponse?.total_bounds ); return ( @@ -70,8 +73,13 @@ const TaxonMapPreview = ( { region={region} mapHeight={230} openMapScreen={() => setShowMapModal( true )} - tileMapParams={tileMapParams} - withObsTiles={tileMapParams !== null} + tileMapParams={obsParams} + withObsTiles + mapViewClassName="-mx-3" + // Disalbe interaction + zoomEanbled={false} + zoomTapEnabled={false} + scrollEanbled={false} /> setShowMapModal( false )} - tileMapParams={tileMapParams} + tileMapParams={obsParams} /> )} /> From 1965c365225bf5044e5c4859fb7fbf1a4419c157 Mon Sep 17 00:00:00 2001 From: Ken-ichi Ueda Date: Tue, 26 Mar 2024 18:28:12 -0700 Subject: [PATCH 6/7] DetailsMap updates * Removed containers that weren't adding much logic * Restyled ObsDetail map model per spec * Disabled interaction for maps on TaxonDetails and ObsDetails (closes #1233) --- .../DetailsTab/DetailsMapContainer.js | 100 ------------------ .../ObsDetails/DetailsTab/DetailsMapHeader.js | 38 +++++++ .../ObsDetails/DetailsTab/DetailsTab.js | 45 ++++---- src/components/SharedComponents/DetailsMap.js | 12 +-- .../SharedComponents/ObservationLocation.js | 100 ++++++++++-------- src/components/SharedComponents/index.js | 1 + .../TaxonDetails/TaxonDetailsMapContainer.js | 38 ------- .../TaxonDetails/TaxonMapPreview.js | 8 +- 8 files changed, 130 insertions(+), 212 deletions(-) delete mode 100644 src/components/ObsDetails/DetailsTab/DetailsMapContainer.js create mode 100644 src/components/ObsDetails/DetailsTab/DetailsMapHeader.js delete mode 100644 src/components/TaxonDetails/TaxonDetailsMapContainer.js diff --git a/src/components/ObsDetails/DetailsTab/DetailsMapContainer.js b/src/components/ObsDetails/DetailsTab/DetailsMapContainer.js deleted file mode 100644 index 29074cb40..000000000 --- a/src/components/ObsDetails/DetailsTab/DetailsMapContainer.js +++ /dev/null @@ -1,100 +0,0 @@ -// @flow - -import checkCamelAndSnakeCase from "components/ObsDetails/helpers/checkCamelAndSnakeCase"; -import { - Body2, - Body4 -} from "components/SharedComponents"; -import DetailsMap from "components/SharedComponents/DetailsMap"; -import { - View -} from "components/styledComponents"; -import { t } from "i18next"; -import type { Node } from "react"; -import React, { useRef } from "react"; - -type Props = { - observation: Object, - latitude: number, - longitude: number, - closeModal: Function, - obscured: bool, - tileMapParams: ?Object -} - -const DetailsMapHeader = ( { - displayLocation, - displayCoordinates, - obscured -} ) => ( - - - {displayLocation} - - - - {displayCoordinates} - - {obscured && ( - - {t( "Obscured-observation-location-map-description" )} - - ) } - -); - -const DetailsMapContainer = ( { - observation, latitude, longitude, closeModal, obscured, tileMapParams -}: Props ): Node => { - const coordinateString = t( "Lat-Lon", { - latitude, - longitude - } ); - - const displayCoordinates = t( "Lat-Lon-Acc", { - latitude, - longitude, - accuracy: observation?.positional_accuracy?.toFixed( 0 ) || t( "none" ) - } ); - let displayLocation = ( - checkCamelAndSnakeCase( observation, "placeGuess" ) - || checkCamelAndSnakeCase( observation, "privatePlaceGuess" ) - ); - - if ( !displayLocation ) { - displayLocation = t( "No-Location" ); - } - - const mapViewRef = useRef( null ); - - return ( - - )} - /> - ); -}; - -export default DetailsMapContainer; diff --git a/src/components/ObsDetails/DetailsTab/DetailsMapHeader.js b/src/components/ObsDetails/DetailsTab/DetailsMapHeader.js new file mode 100644 index 000000000..b30ce73a4 --- /dev/null +++ b/src/components/ObsDetails/DetailsTab/DetailsMapHeader.js @@ -0,0 +1,38 @@ +// @flow + +import { + Body4, + ObservationLocation +} from "components/SharedComponents"; +import { View } from "components/styledComponents"; +import type { Node } from "react"; +import React from "react"; +import { useTranslation } from "sharedHooks"; + +type Props = { + observation: Object, + obscured?: boolean +} + +const DetailsMapHeader = ( { + observation, + obscured +}: Props ): Node => { + const { t } = useTranslation( ); + return ( + + + {obscured && ( + + {t( "Obscured-observation-location-map-description" )} + + ) } + + ); +}; + +export default DetailsMapHeader; diff --git a/src/components/ObsDetails/DetailsTab/DetailsTab.js b/src/components/ObsDetails/DetailsTab/DetailsTab.js index f35c740f4..27f866457 100644 --- a/src/components/ObsDetails/DetailsTab/DetailsTab.js +++ b/src/components/ObsDetails/DetailsTab/DetailsTab.js @@ -7,6 +7,7 @@ import { Body4, Button, DateDisplay, + DetailsMap, Divider, Heading4, ObservationLocation, @@ -28,12 +29,14 @@ import { } from "sharedHooks"; import Attribution from "./Attribution"; -import DetailsMapContainer from "./DetailsMapContainer"; +import DetailsMapHeader from "./DetailsMapHeader"; type Props = { observation: Object } +const DETAILS_MAP_MODAL_STYLE = { margin: 0 }; + const ViewInBrowserButton = ( { id } ) => { const url = `https://inaturalist.org/observations/${id}`; const handlePress = useCallback( async () => { @@ -175,13 +178,15 @@ const DetailsTab = ( { observation }: Props ): Node => { positionalAccuracy={positionalAccuracy} tileMapParams={tileMapParams} withObsTiles={tileMapParams !== null} + scrollEnabled={false} + zoomEnabled={false} + zoomTapEnabled={false} /> ) } - {isObscured - && ( + {isObscured && ( {t( "Obscured-observation-location-map-description" )} @@ -222,18 +227,13 @@ const DetailsTab = ( { observation }: Props ): Node => { - - {t( "PROJECTS" )} - - { - // eslint-disable-next-line i18next/no-literal-string - } - TODO: this section does nothing - -