mirror of
https://github.com/inaturalist/iNaturalistReactNative.git
synced 2026-10-06 18:12:22 -04:00
Merge branch 'main' into mob-1332-species-tab
This commit is contained in:
commit
72df973d4c
195 files changed
+661
-593
No files matched your search
@@ -289,7 +289,7 @@ jobs:
|
||||
name: Notify Slack
|
||||
needs: test
|
||||
if: ${{ success() || failure() }}
|
||||
runs-on: macos-latest
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: iRoachie/slack-github-actions@v2.3.0
|
||||
if: env.SLACK_WEBHOOK_URL != null
|
||||
|
||||
+7
-6
@@ -24,7 +24,7 @@ GEM
|
||||
ast (2.4.3)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.4.0)
|
||||
aws-partitions (1.1263.0)
|
||||
aws-partitions (1.1267.0)
|
||||
aws-sdk-core (3.252.0)
|
||||
aws-eventstream (~> 1, >= 1.3.0)
|
||||
aws-partitions (~> 1, >= 1.992.0)
|
||||
@@ -102,7 +102,8 @@ GEM
|
||||
ethon (0.18.0)
|
||||
ffi (>= 1.15.0)
|
||||
logger
|
||||
excon (0.112.0)
|
||||
excon (1.5.0)
|
||||
logger
|
||||
faraday (1.10.6)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
@@ -132,10 +133,10 @@ GEM
|
||||
faraday_middleware (1.2.1)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.4.1)
|
||||
fastlane (2.236.1)
|
||||
fastlane (2.237.0)
|
||||
CFPropertyList (>= 2.3, < 5.0.0)
|
||||
abbrev (~> 0.1)
|
||||
addressable (>= 2.8, < 3.0.0)
|
||||
addressable (>= 2.9.0, < 3.0.0)
|
||||
artifactory (~> 3.0)
|
||||
aws-sdk-s3 (~> 1.197)
|
||||
babosa (>= 1.0.3, < 2.0.0)
|
||||
@@ -147,7 +148,7 @@ GEM
|
||||
csv (~> 3.3)
|
||||
dotenv (>= 2.1.1, < 3.0.0)
|
||||
emoji_regex (>= 0.1, < 4.0)
|
||||
excon (>= 0.71.0, < 1.0.0)
|
||||
excon (>= 0.71.0, < 2.0.0)
|
||||
faraday (~> 1.0)
|
||||
faraday-cookie_jar (~> 0.0.6)
|
||||
faraday_middleware (~> 1.0)
|
||||
@@ -212,7 +213,7 @@ GEM
|
||||
base64 (~> 0.2)
|
||||
faraday (>= 1.0, < 3.a)
|
||||
google-cloud-errors (1.6.0)
|
||||
google-cloud-storage (1.61.0)
|
||||
google-cloud-storage (1.62.0)
|
||||
addressable (~> 2.8)
|
||||
digest-crc (~> 0.4)
|
||||
google-apis-core (>= 0.18, < 2)
|
||||
|
||||
@@ -348,7 +348,7 @@ fastlane prod
|
||||
1. Change to observations view and view an observation
|
||||
1. Go to the observers profile
|
||||
1. Go to one project this user joined (if not available try another user)
|
||||
1. Sign in
|
||||
1. Log in
|
||||
1. Make an observation by taking a new photo in the AI Camera; tap "Upload Now" to upload immediately; wait for upload to complete before moving on
|
||||
1. Make an observation by taking a new photo in the StandardCamera; save without upload
|
||||
1. Make an observation by importing an existing; save without upload
|
||||
|
||||
@@ -107,7 +107,7 @@ android {
|
||||
applicationId "org.inaturalist.iNaturalistMobile"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 219
|
||||
versionCode 220
|
||||
versionName "1.0.25"
|
||||
manifestPlaceholders = [ GMAPS_API_KEY:project.env.get("GMAPS_API_KEY") ]
|
||||
// Detox Android setup
|
||||
|
||||
+2
-2
@@ -510,11 +510,11 @@ lane :beta do
|
||||
|
||||
build_number = get_build_number( xcodeproj: XCODEPROJ )
|
||||
|
||||
# UI.message "Play Store: promoting build #{build_number} to beta track"
|
||||
UI.message "Play Store: promoting build #{build_number} to Closed beta track"
|
||||
upload_to_play_store(
|
||||
version_code: build_number,
|
||||
track: "internal",
|
||||
track_promote_to: "beta"
|
||||
track_promote_to: "Closed Testing 2026"
|
||||
)
|
||||
|
||||
UI.message "TestFlight: adding build #{build_number} to Open Beta group"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
FIXED
|
||||
* Adding comments to Agreeing IDs
|
||||
* A crash when deleting photo
|
||||
* Location chooser spinning indefinitely
|
||||
+2
-2
@@ -3960,7 +3960,7 @@ PODS:
|
||||
- VisionCamera/React (4.7.3):
|
||||
- React-Core
|
||||
- VisionCamera/FrameProcessors
|
||||
- VisionCameraPluginInatVision (6.0.0-rc.3):
|
||||
- VisionCameraPluginInatVision (6.0.0):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -4564,7 +4564,7 @@ SPEC CHECKSUMS:
|
||||
SensitiveInfo: 09107b865dc23b4e9c0a61ec01385387bf3391a8
|
||||
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
|
||||
VisionCamera: 0044a94f7489f19e19d5938e97dfc36f4784af3c
|
||||
VisionCameraPluginInatVision: 561ffc82eb61315312414a9f4424c5d6411c83ab
|
||||
VisionCameraPluginInatVision: 3b006a7a434ddfc23d789729b6d98e451f90c4e4
|
||||
Yoga: e9fea23bf9b2766818ce9a8df72f584bf5ad36cd
|
||||
|
||||
PODFILE CHECKSUM: 73e24a8590e365c9fec451abf69476ae07116d98
|
||||
|
||||
@@ -548,7 +548,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = iNaturalistReactNative/iNaturalistReactNative.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CURRENT_PROJECT_VERSION = 219;
|
||||
CURRENT_PROJECT_VERSION = 220;
|
||||
DEVELOPMENT_TEAM = N5J7L4P93Z;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
@@ -674,7 +674,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = iNaturalistReactNative/iNaturalistReactNativeRelease.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CURRENT_PROJECT_VERSION = 219;
|
||||
CURRENT_PROJECT_VERSION = 220;
|
||||
DEVELOPMENT_TEAM = N5J7L4P93Z;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
@@ -990,7 +990,7 @@
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = "iNaturalistReactNative-ShareExtension/iNaturalistReactNative-ShareExtension.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 219;
|
||||
CURRENT_PROJECT_VERSION = 220;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = N5J7L4P93Z;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
||||
@@ -1035,7 +1035,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 219;
|
||||
CURRENT_PROJECT_VERSION = 220;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = N5J7L4P93Z;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>219</string>
|
||||
<string>220</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
|
||||
Generated
+4
-4
@@ -116,7 +116,7 @@
|
||||
"realm": "^20.2.0",
|
||||
"sanitize-html": "^2.17.4",
|
||||
"uuid": "^11.1.1",
|
||||
"vision-camera-plugin-inatvision": "github:inaturalist/vision-camera-plugin-inatvision#e8c4782cee82e781e8dc7016fffedbbd95070931",
|
||||
"vision-camera-plugin-inatvision": "github:inaturalist/vision-camera-plugin-inatvision#0354705c124e3a9fabcca3e5881e64cd93d2f0df",
|
||||
"zustand": "^4.5.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -23084,9 +23084,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vision-camera-plugin-inatvision": {
|
||||
"version": "6.0.0-rc.3",
|
||||
"resolved": "git+ssh://git@github.com/inaturalist/vision-camera-plugin-inatvision.git#e8c4782cee82e781e8dc7016fffedbbd95070931",
|
||||
"integrity": "sha512-aarLhPkpgxtFSjrbcbNtzL2VZNM8So+hBzVQROFIEQrj5e/dPp8zWGQ4gONRW9rkUH7t1pmWD4125Eq1/w45+g==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "git+ssh://git@github.com/inaturalist/vision-camera-plugin-inatvision.git#0354705c124e3a9fabcca3e5881e64cd93d2f0df",
|
||||
"integrity": "sha512-HYfaSSb5WnjOLLWLioF7ZgXlk8He8YmoPNV789mhDUBFBgXPaE452O+qW7mIcYVV6cz/WDt+qW3C1ImLEDAWQw==",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"example"
|
||||
|
||||
+1
-1
@@ -153,7 +153,7 @@
|
||||
"realm": "^20.2.0",
|
||||
"sanitize-html": "^2.17.4",
|
||||
"uuid": "^11.1.1",
|
||||
"vision-camera-plugin-inatvision": "github:inaturalist/vision-camera-plugin-inatvision#e8c4782cee82e781e8dc7016fffedbbd95070931",
|
||||
"vision-camera-plugin-inatvision": "github:inaturalist/vision-camera-plugin-inatvision#0354705c124e3a9fabcca3e5881e64cd93d2f0df",
|
||||
"zustand": "^4.5.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/node_modules/react-native-maps/ios/AirMaps/RNMapsMapView.mm b/node_modules/react-native-maps/ios/AirMaps/RNMapsMapView.mm
|
||||
index 447520d..8043dcb 100644
|
||||
--- a/node_modules/react-native-maps/ios/AirMaps/RNMapsMapView.mm
|
||||
+++ b/node_modules/react-native-maps/ios/AirMaps/RNMapsMapView.mm
|
||||
@@ -60,7 +60,7 @@ - (void)animateToRegion:(NSString *)regionJSON duration:(NSInteger)duration{
|
||||
NSDictionary* regionDic = [RCTConvert dictonaryFromString:regionJSON];
|
||||
MKCoordinateRegion region = [RCTConvert MKCoordinateRegion:regionDic];
|
||||
Boolean animated = duration == 0 ? NO :YES;
|
||||
- _view.ignoreRegionChanges = animated;
|
||||
+ // _view.ignoreRegionChanges = animated;
|
||||
[_view setRegion:region animated:animated];
|
||||
}
|
||||
- (void)setCamera:(NSString *)cameraJSON{
|
||||
@@ -30,6 +30,7 @@ export const PROJECT_DETAIL_FIELDS = {
|
||||
header_image_url: true,
|
||||
membership_model: true,
|
||||
place_id: true,
|
||||
project_observation_fields: PROJECT_OBSERVATION_FIELDS_FIELDS,
|
||||
user_ids: true,
|
||||
};
|
||||
|
||||
|
||||
Vendored
+1
@@ -63,6 +63,7 @@ export interface ApiProject extends ApiProjectSummary {
|
||||
header_image_url: string | null;
|
||||
membership_model: "inviteonly" | "open" | null;
|
||||
place_id: number | null;
|
||||
project_observation_fields: ApiProjectObservationField[];
|
||||
user_ids: number[];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import type { ApiTaxon } from "api/types";
|
||||
import UniversalSearchResult
|
||||
from "components/Explore/ExploreV2/components/UniversalSearchResult";
|
||||
import { resultToSubject }
|
||||
from "components/Explore/ExploreV2/helpers/universalSearchSubject";
|
||||
import type { UniversalSearchResultItem }
|
||||
from "components/Explore/ExploreV2/hooks/useUniversalSearch";
|
||||
import IconicTaxonChooser from "components/SharedComponents/IconicTaxonChooser";
|
||||
import Body1 from "components/SharedComponents/Typography/Body1";
|
||||
import { Pressable, ScrollView, View } from "components/styledComponents";
|
||||
import type { ExploreV2Subject } from "providers/ExploreV2Context";
|
||||
import React, { useCallback } from "react";
|
||||
import Taxon from "realmModels/Taxon";
|
||||
import type { RealmTaxon } from "realmModels/types";
|
||||
import useCurrentUser from "sharedHooks/useCurrentUser";
|
||||
import useIconicTaxa from "sharedHooks/useIconicTaxa";
|
||||
import useTranslation from "sharedHooks/useTranslation";
|
||||
|
||||
interface Props {
|
||||
onSelectSubject: ( subject: ExploreV2Subject ) => void;
|
||||
}
|
||||
|
||||
const ROW_CLASSES = "px-[15px] py-[11px] border-b border-lightGray";
|
||||
|
||||
const ICONIC_ROW_STYLE = {
|
||||
alignItems: "center",
|
||||
paddingHorizontal: 15,
|
||||
paddingVertical: 15,
|
||||
} as const;
|
||||
|
||||
const EMPTY_CHOSEN: string[] = [];
|
||||
|
||||
const DefaultSearchOptions = ( { onSelectSubject }: Props ) => {
|
||||
const { t } = useTranslation( );
|
||||
|
||||
const currentUser = useCurrentUser( );
|
||||
const iconicTaxa = useIconicTaxa( );
|
||||
|
||||
const handleIconicTaxon = useCallback( ( iconicTaxonName: string ) => {
|
||||
// Resolve the chooser's name-based callback into a full taxon subject
|
||||
const taxaList = ( iconicTaxa
|
||||
? Array.from( iconicTaxa )
|
||||
: [] ) as unknown as RealmTaxon[];
|
||||
const realmTaxon = taxaList.find(
|
||||
taxon => taxon?.name?.toLowerCase( ) === iconicTaxonName,
|
||||
);
|
||||
if ( !realmTaxon ) { return; }
|
||||
const taxon = Taxon.mapRealmToPojo( realmTaxon ) as ApiTaxon;
|
||||
onSelectSubject( resultToSubject( { type: "taxon", taxon } ) );
|
||||
}, [iconicTaxa, onSelectSubject] );
|
||||
|
||||
const currentUserResult: UniversalSearchResultItem | null = currentUser?.id
|
||||
? {
|
||||
type: "user",
|
||||
user: {
|
||||
id: currentUser.id,
|
||||
login: currentUser.login,
|
||||
icon_url: currentUser.icon_url,
|
||||
observations_count: currentUser.observations_count,
|
||||
},
|
||||
}
|
||||
: null;
|
||||
|
||||
return (
|
||||
<ScrollView keyboardShouldPersistTaps="handled" testID="DefaultSearchOptions">
|
||||
<View className="border-t border-b border-lightGray">
|
||||
<IconicTaxonChooser
|
||||
chosen={EMPTY_CHOSEN}
|
||||
contentContainerStyle={ICONIC_ROW_STYLE}
|
||||
onTaxonChosen={handleIconicTaxon}
|
||||
testID="DefaultSearchOptions.iconicTaxa"
|
||||
withoutUnknown
|
||||
/>
|
||||
</View>
|
||||
{currentUserResult && (
|
||||
<UniversalSearchResult
|
||||
result={currentUserResult}
|
||||
onPress={( ) => onSelectSubject( resultToSubject( currentUserResult ) )}
|
||||
/>
|
||||
)}
|
||||
{currentUser?.id && (
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={t( "Species-I-havent-observed" )}
|
||||
className={ROW_CLASSES}
|
||||
// TODO MOB-1345
|
||||
onPress={( ) => undefined}
|
||||
testID="DefaultSearchOptions.unobserved"
|
||||
>
|
||||
<Body1>{t( "Species-I-havent-observed" )}</Body1>
|
||||
</Pressable>
|
||||
)}
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo( DefaultSearchOptions );
|
||||
@@ -1,5 +1,7 @@
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import classnames from "classnames";
|
||||
import DefaultSearchOptions
|
||||
from "components/Explore/ExploreV2/components/DefaultSearchOptions";
|
||||
import LocationSearchResult
|
||||
from "components/Explore/ExploreV2/components/LocationSearchResult";
|
||||
import UniversalSearchResult
|
||||
@@ -188,6 +190,23 @@ const UniversalSearch = ( ) => {
|
||||
? locationData
|
||||
: subjectData;
|
||||
|
||||
const showDefaultOptions = !showLocation && !subjectHasQuery;
|
||||
const listEmptyComponent = showDefaultOptions
|
||||
? ( <DefaultSearchOptions onSelectSubject={handleSubjectSelect} /> )
|
||||
: (
|
||||
<EmptySearchResults
|
||||
isLoading={showLocation
|
||||
? locationIsLoading
|
||||
: isLoading}
|
||||
searchQuery={showLocation
|
||||
? locationQuery
|
||||
: subjectQuery}
|
||||
refetch={showLocation
|
||||
? locationRefetch
|
||||
: refetch}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<ViewWrapper testID="UniversalSearch">
|
||||
<View className="bg-white" style={DROP_SHADOW}>
|
||||
@@ -261,19 +280,7 @@ const UniversalSearch = ( ) => {
|
||||
keyboardShouldPersistTaps="handled"
|
||||
keyExtractor={resultKey}
|
||||
renderItem={renderItem}
|
||||
ListEmptyComponent={(
|
||||
<EmptySearchResults
|
||||
isLoading={showLocation
|
||||
? locationIsLoading
|
||||
: isLoading}
|
||||
searchQuery={showLocation
|
||||
? locationQuery
|
||||
: subjectQuery}
|
||||
refetch={showLocation
|
||||
? locationRefetch
|
||||
: refetch}
|
||||
/>
|
||||
)}
|
||||
ListEmptyComponent={listEmptyComponent}
|
||||
/>
|
||||
</View>
|
||||
</ViewWrapper>
|
||||
|
||||
+23
-20
@@ -1,5 +1,3 @@
|
||||
// @flow
|
||||
|
||||
import classnames from "classnames";
|
||||
import {
|
||||
CloseButton,
|
||||
@@ -9,8 +7,9 @@ import {
|
||||
} from "components/SharedComponents";
|
||||
import { SharedStackViewWrapper } from "components/SharedComponents/ViewWrapper";
|
||||
import { View } from "components/styledComponents";
|
||||
import type { Node } from "react";
|
||||
import React from "react";
|
||||
import type { LayoutChangeEvent } from "react-native";
|
||||
import type { Region } from "react-native-maps";
|
||||
import { useTranslation } from "sharedHooks";
|
||||
|
||||
import CrosshairCircle from "./CrosshairCircle";
|
||||
@@ -18,23 +17,24 @@ import DisplayLatLng from "./DisplayLatLng";
|
||||
import Footer from "./Footer";
|
||||
import LoadingIndicator from "./LoadingIndicator";
|
||||
import LocationSearch from "./LocationSearch";
|
||||
import type { LocationPickerPlace } from "./types";
|
||||
|
||||
type Props = {
|
||||
accuracy: number,
|
||||
handleSave: Function,
|
||||
hidePlaceResults: boolean,
|
||||
loading: boolean,
|
||||
locationName: string,
|
||||
initialRegion: Object,
|
||||
onCurrentLocationPress: Function,
|
||||
onMapReady: Function,
|
||||
onRegionChangeComplete: Function,
|
||||
region: Object,
|
||||
regionToAnimate: Object,
|
||||
selectPlaceResult: Function,
|
||||
updateLocationName: Function,
|
||||
onMapLayout: Function,
|
||||
};
|
||||
interface Props {
|
||||
accuracy: number;
|
||||
handleSave: ( ) => void;
|
||||
hidePlaceResults: boolean;
|
||||
loading: boolean;
|
||||
locationName: string;
|
||||
initialRegion: Region | null;
|
||||
onCurrentLocationPress: ( ) => void;
|
||||
onMapReady: ( ) => void;
|
||||
onRegionChangeComplete: ( newRegion: Region ) => void;
|
||||
region: Region;
|
||||
regionToAnimate: Region;
|
||||
selectPlaceResult: ( place: LocationPickerPlace ) => void;
|
||||
updateLocationName: ( name: string ) => void;
|
||||
onMapLayout: ( event: LayoutChangeEvent ) => void;
|
||||
}
|
||||
|
||||
const LocationPicker = ( {
|
||||
accuracy,
|
||||
@@ -51,7 +51,7 @@ const LocationPicker = ( {
|
||||
selectPlaceResult,
|
||||
updateLocationName,
|
||||
onMapLayout,
|
||||
}: Props ): Node => {
|
||||
}: Props ) => {
|
||||
const { t } = useTranslation( );
|
||||
|
||||
let regionToDisplay;
|
||||
@@ -110,6 +110,9 @@ const LocationPicker = ( {
|
||||
</View>
|
||||
<Map
|
||||
className="h-full"
|
||||
// TODO: reconcile null vs undef: does a changing initialRegion actually have an effect?
|
||||
// it requires the map ref to settle to inform region's delta properties, but
|
||||
// per docs, prop changes to `initialRegion` are ignored.
|
||||
initialRegion={initialRegion}
|
||||
onCurrentLocationPress={onCurrentLocationPress}
|
||||
onMapReady={onMapReady}
|
||||
+18
-14
@@ -1,26 +1,30 @@
|
||||
// @flow
|
||||
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import {
|
||||
getMapRegion,
|
||||
latitudeDeltaToMeters,
|
||||
metersToLatitudeDelta,
|
||||
} from "components/SharedComponents/Map/helpers/mapHelpers";
|
||||
import type { Node } from "react";
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useReducer,
|
||||
useState,
|
||||
} from "react";
|
||||
import type { LayoutChangeEvent } from "react-native";
|
||||
import type { Region } from "react-native-maps";
|
||||
import fetchPlaceName from "sharedHelpers/fetchPlaceName";
|
||||
import useStore from "stores/useStore";
|
||||
|
||||
import LocationPicker from "./LocationPicker";
|
||||
import type { LocationPickerObservation, LocationPickerPlace } from "./types";
|
||||
|
||||
const CROSSHAIRRADIUS = 254 / 2;
|
||||
|
||||
const setInitialRegion = ( currentObservation, radiusToMapHeight, mapDimensionsRatio ) => {
|
||||
const getInitialRegion = (
|
||||
currentObservation: LocationPickerObservation,
|
||||
radiusToMapHeight: number | null,
|
||||
mapDimensionsRatio: number | null,
|
||||
): Region | null => {
|
||||
if ( !radiusToMapHeight || !mapDimensionsRatio ) {
|
||||
return null;
|
||||
}
|
||||
@@ -59,7 +63,7 @@ const initializeMap = ( state, action ) => {
|
||||
accuracy: action.currentObservation?.positional_accuracy,
|
||||
locationName: action.currentObservation?.place_guess,
|
||||
};
|
||||
const initialRegion = setInitialRegion(
|
||||
const initialRegion = getInitialRegion(
|
||||
action.currentObservation,
|
||||
action.radiusToMapHeight,
|
||||
action.mapDimensionsRatio,
|
||||
@@ -131,14 +135,14 @@ const reducer = ( state, action ) => {
|
||||
}
|
||||
};
|
||||
|
||||
const LocationPickerContainer = ( ): Node => {
|
||||
const LocationPickerContainer = ( ) => {
|
||||
const currentObservation = useStore( state => state.currentObservation );
|
||||
const updateObservationKeys = useStore( state => state.updateObservationKeys );
|
||||
const navigation = useNavigation( );
|
||||
|
||||
const [state, dispatch] = useReducer( reducer, initialState );
|
||||
const [radiusToMapHeight, setRadiusToMapHeight] = useState( undefined );
|
||||
const [mapDimensionsRatio, setMapDimensionsRatio] = useState( undefined );
|
||||
const [radiusToMapHeight, setRadiusToMapHeight] = useState<number | null>( null );
|
||||
const [mapDimensionsRatio, setMapDimensionsRatio] = useState<number | null>( null );
|
||||
|
||||
const {
|
||||
accuracy,
|
||||
@@ -150,20 +154,20 @@ const LocationPickerContainer = ( ): Node => {
|
||||
regionToAnimate,
|
||||
} = state;
|
||||
|
||||
const initialRegion = setInitialRegion(
|
||||
const initialRegion = getInitialRegion(
|
||||
currentObservation,
|
||||
radiusToMapHeight,
|
||||
mapDimensionsRatio,
|
||||
);
|
||||
|
||||
const onRegionChangeComplete = useCallback( async newRegion => {
|
||||
const onRegionChangeComplete = useCallback( async ( newRegion: Region ) => {
|
||||
// prevent initial map render from resetting the coordinates and locationName
|
||||
if ( isFirstMapRender ) {
|
||||
dispatch( { type: "HANDLE_FIRST_MAP_RENDER" } );
|
||||
return;
|
||||
}
|
||||
// We need this ratio to calculate accuracy
|
||||
if ( radiusToMapHeight === undefined ) {
|
||||
if ( radiusToMapHeight === null ) {
|
||||
return;
|
||||
}
|
||||
// We calculate accuracy in meters as the distance represented by the radius of the crosshair
|
||||
@@ -182,7 +186,7 @@ const LocationPickerContainer = ( ): Node => {
|
||||
} );
|
||||
}, [isFirstMapRender, radiusToMapHeight] );
|
||||
|
||||
const updateLocationName = useCallback( name => {
|
||||
const updateLocationName = useCallback( ( name: string ) => {
|
||||
dispatch( { type: "UPDATE_LOCATION_NAME", locationName: name } );
|
||||
}, [] );
|
||||
|
||||
@@ -200,7 +204,7 @@ const LocationPickerContainer = ( ): Node => {
|
||||
[navigation, currentObservation, radiusToMapHeight, mapDimensionsRatio],
|
||||
);
|
||||
|
||||
const selectPlaceResult = place => {
|
||||
const selectPlaceResult = ( place: LocationPickerPlace ) => {
|
||||
const { coordinates } = place.point_geojson;
|
||||
let newRegion = {
|
||||
...region,
|
||||
@@ -248,7 +252,7 @@ const LocationPickerContainer = ( ): Node => {
|
||||
navigation.goBack( );
|
||||
};
|
||||
|
||||
const onMapLayout = event => {
|
||||
const onMapLayout = ( event: LayoutChangeEvent ) => {
|
||||
const { height, width } = event.nativeEvent.layout;
|
||||
setRadiusToMapHeight( CROSSHAIRRADIUS / height );
|
||||
setMapDimensionsRatio( width / height );
|
||||
@@ -12,22 +12,14 @@ import { Keyboard } from "react-native";
|
||||
import useAuthenticatedQuery from "sharedHooks/useAuthenticatedQuery";
|
||||
import { getShadow } from "styles/global";
|
||||
|
||||
import type { LocationPickerPlace } from "./types";
|
||||
|
||||
const DROP_SHADOW = getShadow( );
|
||||
|
||||
interface Place {
|
||||
id: string;
|
||||
display_name: string;
|
||||
point_geojson: {
|
||||
coordinates: [number, number];
|
||||
};
|
||||
bounding_box_geojson?: {
|
||||
coordinates: [number, number][][];
|
||||
};
|
||||
}
|
||||
interface Props {
|
||||
locationName: string;
|
||||
updateLocationName: ( _text: string ) => void;
|
||||
selectPlaceResult: ( _place: Place ) => void;
|
||||
updateLocationName: ( name: string ) => void;
|
||||
selectPlaceResult: ( place: LocationPickerPlace ) => void;
|
||||
hidePlaceResults: boolean;
|
||||
}
|
||||
|
||||
@@ -72,7 +64,7 @@ const LocationSearch = ( {
|
||||
className="absolute top-[65px] right-[26px] left-[26px] bg-white rounded-lg z-100"
|
||||
style={DROP_SHADOW}
|
||||
>
|
||||
{!hidePlaceResults && placeResults?.map( ( place: Place ) => (
|
||||
{!hidePlaceResults && placeResults?.map( ( place: LocationPickerPlace ) => (
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
key={place.id}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
export interface LocationPickerObservation {
|
||||
latitude?: number;
|
||||
longitude?: number;
|
||||
|
||||
privateLatitude?: number;
|
||||
privateLongitude?: number;
|
||||
|
||||
positional_accuracy?: number;
|
||||
}
|
||||
|
||||
export interface LocationPickerPlace {
|
||||
id: string;
|
||||
display_name: string;
|
||||
point_geojson: {
|
||||
coordinates: number[];
|
||||
};
|
||||
bounding_box_geojson: {
|
||||
// bbox is a 5-point clockwise rectangle starting from SW (5th === 1st),
|
||||
// so the 1st and 3rd points give us the SW and NE corners.
|
||||
coordinates: [
|
||||
[
|
||||
// SW
|
||||
[number, number],
|
||||
// (discard)
|
||||
[number, number],
|
||||
// NE
|
||||
[number, number],
|
||||
// ... don't need the rest
|
||||
]
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -371,7 +371,6 @@ const MatchContainer = ( ) => {
|
||||
const onSuggestionChosen = useCallback( ( selection: ApiSuggestion ) => {
|
||||
setSelectedSuggestionId( selection.taxon.id );
|
||||
scrollToTop( );
|
||||
// TODO: should this set owners_identification_from_vision: false?
|
||||
}, [scrollToTop] );
|
||||
|
||||
const createUploadParams = useCallback( async ( uri: string, showLocation: boolean ) => {
|
||||
@@ -461,7 +460,7 @@ const MatchContainer = ( ) => {
|
||||
if ( action === "save" ) {
|
||||
updateObservationKeys( {
|
||||
taxon: taxon || iconicTaxon,
|
||||
owners_identification_from_vision: true,
|
||||
owners_identification_from_vision: !!taxon,
|
||||
} );
|
||||
await saveObservation( getCurrentObservation( ), cameraRollUris, realm );
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ const MyObservationsResults = ( ) => {
|
||||
startUploadObservations,
|
||||
);
|
||||
|
||||
useObservationsUpdates( !!currentUser );
|
||||
const { refetch: refetchObservationsUpdates } = useObservationsUpdates( !!currentUser );
|
||||
|
||||
const {
|
||||
fetchFromLastObservation,
|
||||
@@ -234,7 +234,8 @@ const MyObservationsResults = ( ) => {
|
||||
|
||||
const handlePullToRefresh = useCallback( async ( ) => {
|
||||
await syncManually( { skipUploads: true } );
|
||||
}, [syncManually] );
|
||||
refetchObservationsUpdates( );
|
||||
}, [syncManually, refetchObservationsUpdates] );
|
||||
|
||||
// Scroll the list to the offset we need to restore, e.g. when you are
|
||||
// scrolled way down, edit an observation, and return. Entering ObsEdit
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import {
|
||||
useIconicTaxa,
|
||||
useObservationUpdatesWhenFocused,
|
||||
} from "sharedHooks";
|
||||
import { useIconicTaxa } from "sharedHooks";
|
||||
|
||||
import useTaxonCommonNames from "./hooks/useTaxonCommonNames";
|
||||
import useWorkQueue from "./hooks/useWorkQueue";
|
||||
|
||||
const NetworkService = ( ) => {
|
||||
useObservationUpdatesWhenFocused( );
|
||||
|
||||
useIconicTaxa( { reload: true } );
|
||||
// This only runs when App updates... which is rarely. It works for Settings
|
||||
// b/c it generally updates currentUser
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { useNavigation, useRoute } from "@react-navigation/native";
|
||||
import { createComment } from "api/comments";
|
||||
import { createIdentification } from "api/identifications";
|
||||
import type {
|
||||
AgreeIdentification,
|
||||
} from "components/ObsDetailsSharedComponents/hooks/useObsDetailsSharedLogic";
|
||||
import AgreeWithIDSheet from "components/ObsDetailsSharedComponents/Sheets/AgreeWithIDSheet";
|
||||
import PotentialDisagreementSheet
|
||||
from "components/ObsDetailsSharedComponents/Sheets/PotentialDisagreementSheet";
|
||||
@@ -53,8 +56,6 @@ interface Identification {
|
||||
}
|
||||
|
||||
interface IdentState {
|
||||
comment: string | null;
|
||||
commentIsOptional: boolean;
|
||||
showIdentBodySheet: boolean;
|
||||
newIdentification: Identification | null;
|
||||
showPotentialDisagreementSheet: boolean;
|
||||
@@ -74,8 +75,6 @@ type IdentAction =
|
||||
| { type: "HIDE_SUGGESTED_ID_SHEET" };
|
||||
|
||||
const initialIdentState: IdentState = {
|
||||
comment: null,
|
||||
commentIsOptional: false,
|
||||
showIdentBodySheet: false,
|
||||
newIdentification: null,
|
||||
showPotentialDisagreementSheet: false,
|
||||
@@ -141,14 +140,18 @@ export const identReducer = ( state: IdentState, action: IdentAction ): IdentSta
|
||||
case CLEAR_SUGGESTED_TAXON:
|
||||
return { ...state, identTaxon: null };
|
||||
case HIDE_SUGGESTED_ID_SHEET:
|
||||
return { ...state, showSuggestIdSheet: false };
|
||||
return {
|
||||
...state,
|
||||
showSuggestIdSheet: false,
|
||||
newIdentification: null,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
interface Props {
|
||||
agreeIdentification: boolean;
|
||||
agreeIdentification: AgreeIdentification | null;
|
||||
closeAgreeWithIdSheet: () => void;
|
||||
confirmRemoteObsWasDeleted?: () => void;
|
||||
handleCommentMutationSuccess: ( data: unknown ) => void;
|
||||
@@ -185,8 +188,6 @@ const IdentificationSheets: React.FC<Props> = ( {
|
||||
const [state, dispatch] = useReducer( identReducer, initialIdentState );
|
||||
|
||||
const {
|
||||
comment,
|
||||
commentIsOptional,
|
||||
showIdentBodySheet,
|
||||
identTaxon,
|
||||
newIdentification,
|
||||
@@ -197,30 +198,28 @@ const IdentificationSheets: React.FC<Props> = ( {
|
||||
const realm = useRealm( );
|
||||
const { t } = useTranslation( );
|
||||
|
||||
const hasComment = ( comment || newIdentification?.body || "" ).length > 0;
|
||||
const hasComment = ( newIdentification?.body || "" ).length > 0;
|
||||
|
||||
const showAddCommentHeader = useCallback( ( ) => {
|
||||
if ( hasComment ) {
|
||||
return t( "EDIT-COMMENT" );
|
||||
} if ( commentIsOptional ) {
|
||||
return t( "ADD-OPTIONAL-COMMENT" );
|
||||
}
|
||||
return t( "ADD-COMMENT" );
|
||||
}, [commentIsOptional, hasComment, t] );
|
||||
const showAddCommentHeader = useCallback( ( ) => (
|
||||
hasComment
|
||||
? t( "EDIT-COMMENT" )
|
||||
: t( "ADD-COMMENT" )
|
||||
), [hasComment, t] );
|
||||
|
||||
const editIdentBody = useCallback( ( ) => dispatch( { type: SHOW_EDIT_IDENT_BODY_SHEET } ), [] );
|
||||
|
||||
const onChangeIdentBody = useCallback( ( body: string ) => dispatch( {
|
||||
type: SET_NEW_IDENTIFICATION,
|
||||
taxon: newIdentification?.taxon,
|
||||
taxon: newIdentification?.taxon || agreeIdentification?.taxon,
|
||||
body,
|
||||
} ), [newIdentification?.taxon] );
|
||||
} ), [newIdentification?.taxon, agreeIdentification?.taxon] );
|
||||
|
||||
const onCloseIdentBodySheet = useCallback( ( ) => {
|
||||
dispatch( { type: HIDE_EDIT_IDENT_BODY_SHEET } );
|
||||
}, [] );
|
||||
|
||||
const showErrorAlert = useCallback( error => Alert.alert( "Error", error, [{ text: t( "OK" ) }], {
|
||||
const showErrorAlert
|
||||
= useCallback( ( error: string ) => Alert.alert( "Error", error, [{ text: t( "OK" ) }], {
|
||||
cancelable: true,
|
||||
} ), [t] );
|
||||
|
||||
@@ -258,16 +257,17 @@ const IdentificationSheets: React.FC<Props> = ( {
|
||||
const hasPotentialDisagreement = useCallback( ( taxon: Taxon | null | undefined ) => {
|
||||
// based on disagreement code in iNat web
|
||||
// https://github.com/inaturalist/inaturalist/blob/30a27d0eb79dd17af38292785b0137e6024bbdb7/app/webpack/observations/show/ducks/observation.js#L827-L838
|
||||
let observationTaxon = observation?.taxon;
|
||||
let observationTaxon = observation.taxon;
|
||||
|
||||
const doesNotPreferCommunityTaxon = observation.prefers_community_taxon === false
|
||||
|| ( observation.user?.prefers_community_taxa === false
|
||||
&& observation.prefers_community_taxon === null );
|
||||
|
||||
if ( doesNotPreferCommunityTaxon ) {
|
||||
observationTaxon = observation?.community_taxon || observation.taxon;
|
||||
observationTaxon = observation.community_taxon || observation.taxon;
|
||||
}
|
||||
return observationTaxon
|
||||
&& !!taxon?.id
|
||||
&& taxon?.id !== observationTaxon.id
|
||||
&& observationTaxon.ancestor_ids.includes( taxon?.id );
|
||||
}, [observation] );
|
||||
@@ -396,10 +396,8 @@ const IdentificationSheets: React.FC<Props> = ( {
|
||||
}, [createCommentMutate, uuid, loadActivityItem] );
|
||||
|
||||
const confirmCommentFromCommentSheet = useCallback( ( newComment: string ) => {
|
||||
if ( !commentIsOptional ) {
|
||||
onCommentAdded( newComment );
|
||||
}
|
||||
}, [commentIsOptional, onCommentAdded] );
|
||||
onCommentAdded( newComment );
|
||||
}, [onCommentAdded] );
|
||||
|
||||
const hideSuggestedIdSheet = ( ) => {
|
||||
dispatch( { type: HIDE_SUGGESTED_ID_SHEET } );
|
||||
@@ -416,7 +414,10 @@ const IdentificationSheets: React.FC<Props> = ( {
|
||||
hidden={showIdentBodySheet}
|
||||
loading={isCreateIdPending}
|
||||
onPressClose={closeAgreeWithIdSheet}
|
||||
identification={agreeIdentification}
|
||||
identification={{
|
||||
taxon: agreeIdentification.taxon,
|
||||
body: newIdentification?.body,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{/* AddCommentSheet */}
|
||||
@@ -427,7 +428,6 @@ const IdentificationSheets: React.FC<Props> = ( {
|
||||
onPressClose={hideAddCommentSheet}
|
||||
headerText={addCommentHeaderText}
|
||||
textInputStyle={textInputStyle}
|
||||
initialInput={comment}
|
||||
confirm={confirmCommentFromCommentSheet}
|
||||
/>
|
||||
)}
|
||||
@@ -477,6 +477,7 @@ const IdentificationSheets: React.FC<Props> = ( {
|
||||
text={t( "Sorry-this-observation-was-deleted" )}
|
||||
buttonText={t( "OK" )}
|
||||
confirm={confirmRemoteObsWasDeleted}
|
||||
loading={false}
|
||||
/>
|
||||
) }
|
||||
</>
|
||||
|
||||
@@ -42,7 +42,7 @@ const SET_INITIAL_OBSERVATION = "SET_INITIAL_OBSERVATION";
|
||||
const ADD_ACTIVITY_ITEM = "ADD_ACTIVITY_ITEM";
|
||||
const LOADING_ACTIVITY_ITEM = "LOADING_ACTIVITY_ITEM";
|
||||
|
||||
interface AgreeIdentification {
|
||||
export interface AgreeIdentification {
|
||||
taxon: RealmTaxon;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,18 +16,22 @@ import type {
|
||||
ApiObservationsSearchResponse, ApiPlace, ApiProject, ApiResponse,
|
||||
} from "api/types";
|
||||
import type { TabStackScreenProps } from "navigation/types";
|
||||
import { RealmContext } from "providers/contexts";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import Project from "realmModels/Project";
|
||||
import { log } from "sharedHelpers/logger";
|
||||
import { useAuthenticatedMutation, useAuthenticatedQuery, useCurrentUser } from "sharedHooks";
|
||||
|
||||
import ProjectDetails from "./ProjectDetails";
|
||||
|
||||
const logger = log.extend( "ProjectDetailsContainer" );
|
||||
const { useRealm } = RealmContext;
|
||||
|
||||
const ProjectDetailsContainer = ( ) => {
|
||||
const navigation = useNavigation<TabStackScreenProps<"ProjectDetails">["navigation"]>( );
|
||||
const { params } = useRoute<TabStackScreenProps<"ProjectDetails">["route"]>( );
|
||||
const { id } = params;
|
||||
const realm = useRealm( );
|
||||
const currentUser = useCurrentUser( );
|
||||
const [loading, setLoading] = useState( false );
|
||||
|
||||
@@ -104,6 +108,10 @@ const ProjectDetailsContainer = ( ) => {
|
||||
( _, optsWithAuth ) => joinProject( { id }, optsWithAuth ),
|
||||
{
|
||||
onSuccess: ( ) => {
|
||||
// Persist traditional projects on join
|
||||
if ( project?.project_type === "" ) {
|
||||
Project.upsertRemoteProjects( [project], realm );
|
||||
}
|
||||
queryClient.invalidateQueries( membershipQueryKey );
|
||||
},
|
||||
onError: error => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import classnames from "classnames";
|
||||
import { INatIconButton } from "components/SharedComponents";
|
||||
import { View } from "components/styledComponents";
|
||||
import React, { useCallback } from "react";
|
||||
import type { ListRenderItemInfo } from "react-native";
|
||||
import type { ListRenderItemInfo, StyleProp, ViewStyle } from "react-native";
|
||||
import { FlatList } from "react-native";
|
||||
import { useTranslation } from "sharedHooks";
|
||||
import colors from "styles/tailwindColors";
|
||||
@@ -10,6 +10,7 @@ import colors from "styles/tailwindColors";
|
||||
interface Props {
|
||||
before?: React.ReactNode;
|
||||
chosen: string[];
|
||||
contentContainerStyle?: StyleProp<ViewStyle>;
|
||||
onTaxonChosen: ( taxon: string ) => void;
|
||||
testID?: string;
|
||||
withoutUnknown?: boolean;
|
||||
@@ -41,6 +42,7 @@ const EMPTY_CHOSEN: string[] = [];
|
||||
const IconicTaxonChooser = ( {
|
||||
before,
|
||||
chosen = EMPTY_CHOSEN,
|
||||
contentContainerStyle = STYLESHEET,
|
||||
onTaxonChosen,
|
||||
testID,
|
||||
withoutUnknown,
|
||||
@@ -80,7 +82,7 @@ const IconicTaxonChooser = ( {
|
||||
t( "Iconic-taxon-name", { iconicTaxon: iconicTaxonName } )
|
||||
}
|
||||
accessibilityHint={
|
||||
t( "Selects-iconic-taxon-X-for-identification", { iconicTaxon: iconicTaxonName } )
|
||||
t( "Selects-iconic-taxon-X", { iconicTaxon: iconicTaxonName } )
|
||||
}
|
||||
testID={`INatIconButton.IconicTaxonButton.${iconicTaxonName}`}
|
||||
/>
|
||||
@@ -106,9 +108,10 @@ const IconicTaxonChooser = ( {
|
||||
return (
|
||||
<FlatList
|
||||
ListHeaderComponent={renderHeader}
|
||||
contentContainerStyle={STYLESHEET}
|
||||
contentContainerStyle={contentContainerStyle}
|
||||
data={iconicTaxonIcons}
|
||||
horizontal
|
||||
keyboardShouldPersistTaps="handled"
|
||||
renderItem={renderIcon}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
testID={testID}
|
||||
|
||||
@@ -9,10 +9,11 @@ import React, {
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import type { DimensionValue, ViewStyle } from "react-native";
|
||||
import type { DimensionValue, LayoutChangeEvent, ViewStyle } from "react-native";
|
||||
import { Platform } from "react-native";
|
||||
import type {
|
||||
BoundingBox, LatLng, Region,
|
||||
UserLocationChangeEvent,
|
||||
} from "react-native-maps";
|
||||
import MapView, { UrlTile } from "react-native-maps";
|
||||
import type Observation from "realmModels/Observation";
|
||||
@@ -43,7 +44,7 @@ const CURRENT_LOCATION_ZOOM_LEVEL = 20; // target zoom level when user hits curr
|
||||
const MIN_ZOOM_LEVEL = 0; // default in react-native-maps, for Google Maps only
|
||||
const MIN_CENTER_COORDINATE_DISTANCE = 5;
|
||||
|
||||
const getDefaultRegion = ( initialLatitude, initialLongitude ) => ( {
|
||||
const getDefaultRegion = ( initialLatitude?: number, initialLongitude?: number ) => ( {
|
||||
latitude: initialLatitude || 25, // Default to something US centric
|
||||
longitude: initialLongitude || -85, // Default to something US centric
|
||||
latitudeDelta: initialLatitude
|
||||
@@ -83,7 +84,7 @@ interface Props {
|
||||
withPressableObsTiles?: boolean;
|
||||
zoomEnabled?: boolean;
|
||||
zoomTapEnabled?: boolean;
|
||||
onMapLayout?: ( event: { nativeEvent: { layout: { width: number; height: number } } } ) => void;
|
||||
onMapLayout?: ( event: LayoutChangeEvent ) => void;
|
||||
}
|
||||
|
||||
// TODO: fallback to another map library
|
||||
@@ -313,7 +314,7 @@ const Map = ( {
|
||||
minCenterCoordinateDistance: MIN_CENTER_COORDINATE_DISTANCE,
|
||||
};
|
||||
|
||||
const handleUserLocationChange = async locationChangeEvent => {
|
||||
const handleUserLocationChange = async ( locationChangeEvent: UserLocationChangeEvent ) => {
|
||||
const coordinate = locationChangeEvent?.nativeEvent?.coordinate;
|
||||
setUserLocation( coordinate );
|
||||
};
|
||||
@@ -335,12 +336,15 @@ const Map = ( {
|
||||
|
||||
const [previousTileUrl, setPreviousTileUrl] = useState( tileUrlTemplate );
|
||||
|
||||
const handleRegionChangeComplete = useCallback( async ( newRegion, gesture ) => {
|
||||
const handleRegionChangeComplete = useCallback( async (
|
||||
newRegion: Region,
|
||||
{ isGesture }: { isGesture?: boolean },
|
||||
) => {
|
||||
// We are only interested in region changes due to user interaction.
|
||||
// In Android, onRegionChangeComplete also fires for other map region
|
||||
// changes and gesture.isGesture is available to test for user interaction.
|
||||
let shouldSkipRegionUpdate = false;
|
||||
if ( Platform.OS === "android" && !gesture.isGesture ) {
|
||||
if ( Platform.OS === "android" && !isGesture ) {
|
||||
if ( previousTileUrl !== tileUrlTemplate ) {
|
||||
setPreviousTileUrl( tileUrlTemplate );
|
||||
}
|
||||
@@ -409,19 +413,19 @@ const Map = ( {
|
||||
// In Android, when we render a single frame of <MapView> without <UrlTile>
|
||||
// we use a tiny region increase of 0.001% to get onRegionChangeComplete to
|
||||
// fire and update the obs tile url. This change is too small to be visible.
|
||||
const fuzzRegion = curRegion => (
|
||||
const fuzzRegion = ( curRegion: Region ) => (
|
||||
{
|
||||
...curRegion,
|
||||
latitudeDelta: 1.00001 * curRegion.latitudeDelta,
|
||||
longitudeDelta: 1.00001 * curRegion.longitudeDelta,
|
||||
} );
|
||||
const shouldFuzzRegion = curRegion => (
|
||||
const unfuzzedMapRegion = setRegion( );
|
||||
const shouldFuzzRegion = (
|
||||
Platform.OS === "android"
|
||||
&& curRegion
|
||||
&& unfuzzedMapRegion
|
||||
&& previousTileUrl !== tileUrlTemplate
|
||||
);
|
||||
const unfuzzedMapRegion = setRegion( );
|
||||
const mapRegion = shouldFuzzRegion( unfuzzedMapRegion )
|
||||
const mapRegion = shouldFuzzRegion
|
||||
? fuzzRegion( unfuzzedMapRegion )
|
||||
: unfuzzedMapRegion;
|
||||
|
||||
@@ -534,6 +538,7 @@ const Map = ( {
|
||||
onUserLocationChange={handleUserLocationChange}
|
||||
pitchEnabled={false}
|
||||
ref={setRefs}
|
||||
// TODO: reconcile possible `null` state
|
||||
region={mapRegion}
|
||||
rotateEnabled={false}
|
||||
scrollEnabled={scrollEnabled}
|
||||
@@ -563,7 +568,7 @@ const Map = ( {
|
||||
<LocationIndicator
|
||||
latitude={latitude}
|
||||
longitude={longitude}
|
||||
positionalAccuracy={observation.positionalAccuracy}
|
||||
positionalAccuracy={observation.positional_accuracy}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Afegir Localització
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Afegir observacions
|
||||
ADD-OPTIONAL-COMMENT = AFEGIR COMENTARI OPCIONAL
|
||||
Add-optional-notes = Afegir notes opcionals
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Afegir observacions",
|
||||
"ADD-OPTIONAL-COMMENT": "AFEGIR COMENTARI OPCIONAL",
|
||||
"Add-optional-notes": "Afegir notes opcionals",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Přidat umístění
|
||||
ADD-LOCATION-FOR-BETTER-IDS = PŘIDAT POLOHU PRO LEPŠÍ ID
|
||||
Add-location-to-refresh-suggestions = Přidat umístění k obnově návrhů
|
||||
Add-observations = Přidat pozorování
|
||||
ADD-OPTIONAL-COMMENT = PŘIDAT VOLITELNÝ KOMENTÁŘ
|
||||
Add-optional-notes = Přidat volitelné poznámky
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "PŘIDAT POLOHU PRO LEPŠÍ ID",
|
||||
"Add-location-to-refresh-suggestions": "Přidat umístění k obnově návrhů",
|
||||
"Add-observations": "Přidat pozorování",
|
||||
"ADD-OPTIONAL-COMMENT": "PŘIDAT VOLITELNÝ KOMENTÁŘ",
|
||||
"Add-optional-notes": "Přidat volitelné poznámky",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Tilføj placering
|
||||
ADD-LOCATION-FOR-BETTER-IDS = TILFØJ PLACERING FOR BEDRE ID'ER
|
||||
Add-location-to-refresh-suggestions = Tilføj placering for at opfriske forslag
|
||||
Add-observations = Tilføj observationer
|
||||
ADD-OPTIONAL-COMMENT = TILFØJ VALGFRI KOMMENTAR
|
||||
Add-optional-notes = Tilføj valgfrie notater
|
||||
Add-to-Projects = Føj til projekter
|
||||
ADD-TO-PROJECTS = FØJ TIL PROJEKTER
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "TILFØJ PLACERING FOR BEDRE ID'ER",
|
||||
"Add-location-to-refresh-suggestions": "Tilføj placering for at opfriske forslag",
|
||||
"Add-observations": "Tilføj observationer",
|
||||
"ADD-OPTIONAL-COMMENT": "TILFØJ VALGFRI KOMMENTAR",
|
||||
"Add-optional-notes": "Tilføj valgfrie notater",
|
||||
"Add-to-Projects": "Føj til projekter",
|
||||
"ADD-TO-PROJECTS": "FØJ TIL PROJEKTER",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Standort hinzufügen
|
||||
ADD-LOCATION-FOR-BETTER-IDS = FÜR BESSERE IDS EINEN STANDORT HINZUFÜGEN
|
||||
Add-location-to-refresh-suggestions = Standort hinzufügen, um die Bestimmungsvorschläge zu aktualisieren
|
||||
Add-observations = Beobachtung(en) hinzufügen
|
||||
ADD-OPTIONAL-COMMENT = OPTIONALEN KOMMENTAR HINZUFÜGEN
|
||||
Add-optional-notes = Optionale Anmerkungen hinzufügen
|
||||
Add-to-Projects = Zu Projekten hinzufügen
|
||||
ADD-TO-PROJECTS = ZU PROJEKTEN HINZUFÜGEN
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "FÜR BESSERE IDS EINEN STANDORT HINZUFÜGEN",
|
||||
"Add-location-to-refresh-suggestions": "Standort hinzufügen, um die Bestimmungsvorschläge zu aktualisieren",
|
||||
"Add-observations": "Beobachtung(en) hinzufügen",
|
||||
"ADD-OPTIONAL-COMMENT": "OPTIONALEN KOMMENTAR HINZUFÜGEN",
|
||||
"Add-optional-notes": "Optionale Anmerkungen hinzufügen",
|
||||
"Add-to-Projects": "Zu Projekten hinzufügen",
|
||||
"ADD-TO-PROJECTS": "ZU PROJEKTEN HINZUFÜGEN",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Προσθήκη τοποθεσίας
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ΠΡΟΣΘΉΚΗ ΤΟΠΟΘΕΣΊΑΣ ΓΙΑ ΚΑΛΎΤΕΡΑ ΑΝΑΓΝΩΡΙΣΤΙΚΆ
|
||||
Add-location-to-refresh-suggestions = Προσθήκη τοποθεσίας για ανανέωση προτάσεων
|
||||
Add-observations = Προσθήκη παρατηρήσεων
|
||||
ADD-OPTIONAL-COMMENT = ΠΡΟΣΘΉΚΗ ΠΡΟΑΙΡΕΤΙΚΟΎ ΣΧΟΛΊΟΥ
|
||||
Add-optional-notes = Προσθήκη προαιρετικών σημειώσεων
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ΠΡΟΣΘΉΚΗ ΤΟΠΟΘΕΣΊΑΣ ΓΙΑ ΚΑΛΎΤΕΡΑ ΑΝΑΓΝΩΡΙΣΤΙΚΆ",
|
||||
"Add-location-to-refresh-suggestions": "Προσθήκη τοποθεσίας για ανανέωση προτάσεων",
|
||||
"Add-observations": "Προσθήκη παρατηρήσεων",
|
||||
"ADD-OPTIONAL-COMMENT": "ΠΡΟΣΘΉΚΗ ΠΡΟΑΙΡΕΤΙΚΟΎ ΣΧΟΛΊΟΥ",
|
||||
"Add-optional-notes": "Προσθήκη προαιρετικών σημειώσεων",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -63,7 +63,6 @@ Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
# Accessibility label for a button that starts the process of adding an
|
||||
# observation, e.g. the button in the tab bar
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
@@ -1177,7 +1176,7 @@ Select-photo = Select photo
|
||||
SELECT-THIS-TAXON = SELECT THIS TAXON
|
||||
# Label for an element that let's you select a user
|
||||
Select-user = Select user
|
||||
Selects-iconic-taxon-X-for-identification = Selects iconic taxon { $iconicTaxon } for identification.
|
||||
Selects-iconic-taxon-X = Selects iconic taxon { $iconicTaxon }.
|
||||
Separate-Photos = Separate Photos
|
||||
# Month of September
|
||||
September = September
|
||||
@@ -1233,6 +1232,7 @@ sound-recorder-help-Try-to-isolate = Try to isolate the sound of a single organi
|
||||
Sounds = Sounds
|
||||
Source-List = <0>(Source List: </0><1>{ $source }</1><0>)</0>
|
||||
Species = Species
|
||||
Species-I-havent-observed = Species I haven't observed
|
||||
Species-View = Species View
|
||||
Species-with-the-least-observations-appear-first = Species with the least observations appear first
|
||||
Species-with-the-most-observations-appear-first = Species with the most observations appear first
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
@@ -730,7 +729,7 @@
|
||||
"Select-photo": "Select photo",
|
||||
"SELECT-THIS-TAXON": "SELECT THIS TAXON",
|
||||
"Select-user": "Select user",
|
||||
"Selects-iconic-taxon-X-for-identification": "Selects iconic taxon { $iconicTaxon } for identification.",
|
||||
"Selects-iconic-taxon-X": "Selects iconic taxon { $iconicTaxon }.",
|
||||
"Separate-Photos": "Separate Photos",
|
||||
"September": "September",
|
||||
"SETTINGS": "SETTINGS",
|
||||
@@ -769,6 +768,7 @@
|
||||
"Sounds": "Sounds",
|
||||
"Source-List": "<0>(Source List: </0><1>{ $source }</1><0>)</0>",
|
||||
"Species": "Species",
|
||||
"Species-I-havent-observed": "Species I haven't observed",
|
||||
"Species-View": "Species View",
|
||||
"Species-with-the-least-observations-appear-first": "Species with the least observations appear first",
|
||||
"Species-with-the-most-observations-appear-first": "Species with the most observations appear first",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Añadir ubicación
|
||||
ADD-LOCATION-FOR-BETTER-IDS = AÑADIR UBICACIÓN PARA MEJOR SDI
|
||||
Add-location-to-refresh-suggestions = Añadir ubicación para actualizar sugerencias
|
||||
Add-observations = Añade observaciones
|
||||
ADD-OPTIONAL-COMMENT = AÑADIR COMENTARIO OPCIONAL
|
||||
Add-optional-notes = Añadir notas opcionales
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "AÑADIR UBICACIÓN PARA MEJOR SDI",
|
||||
"Add-location-to-refresh-suggestions": "Añadir ubicación para actualizar sugerencias",
|
||||
"Add-observations": "Añade observaciones",
|
||||
"ADD-OPTIONAL-COMMENT": "AÑADIR COMENTARIO OPCIONAL",
|
||||
"Add-optional-notes": "Añadir notas opcionales",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Añadir ubicación
|
||||
ADD-LOCATION-FOR-BETTER-IDS = AÑADIR UBICACIÓN PARA MEJOR SDI
|
||||
Add-location-to-refresh-suggestions = Añadir ubicación para actualizar sugerencias
|
||||
Add-observations = Agregar observaciones
|
||||
ADD-OPTIONAL-COMMENT = AÑADIR COMENTARIO OPCIONAL
|
||||
Add-optional-notes = Añadir notas opcionales
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "AÑADIR UBICACIÓN PARA MEJOR SDI",
|
||||
"Add-location-to-refresh-suggestions": "Añadir ubicación para actualizar sugerencias",
|
||||
"Add-observations": "Agregar observaciones",
|
||||
"ADD-OPTIONAL-COMMENT": "AÑADIR COMENTARIO OPCIONAL",
|
||||
"Add-optional-notes": "Añadir notas opcionales",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Añadir ubicación
|
||||
ADD-LOCATION-FOR-BETTER-IDS = AÑADIR UBICACIÓN PARA MEJOR SDI
|
||||
Add-location-to-refresh-suggestions = Añadir ubicación para actualizar sugerencias
|
||||
Add-observations = Añade observaciones
|
||||
ADD-OPTIONAL-COMMENT = AÑADIR COMENTARIO OPCIONAL
|
||||
Add-optional-notes = Añadir notas opcionales
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "AÑADIR UBICACIÓN PARA MEJOR SDI",
|
||||
"Add-location-to-refresh-suggestions": "Añadir ubicación para actualizar sugerencias",
|
||||
"Add-observations": "Añade observaciones",
|
||||
"ADD-OPTIONAL-COMMENT": "AÑADIR COMENTARIO OPCIONAL",
|
||||
"Add-optional-notes": "Añadir notas opcionales",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Añadir Ubicación
|
||||
ADD-LOCATION-FOR-BETTER-IDS = AÑADIR UBICACIÓN PARA MEJORES ID
|
||||
Add-location-to-refresh-suggestions = Agrega una ubicación para actualizar las sugerencias
|
||||
Add-observations = Agrega observaciones
|
||||
ADD-OPTIONAL-COMMENT = AÑADIR COMENTARIO OPCIONAL
|
||||
Add-optional-notes = Añadir notas opcionales
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "AÑADIR UBICACIÓN PARA MEJORES ID",
|
||||
"Add-location-to-refresh-suggestions": "Agrega una ubicación para actualizar las sugerencias",
|
||||
"Add-observations": "Agrega observaciones",
|
||||
"ADD-OPTIONAL-COMMENT": "AÑADIR COMENTARIO OPCIONAL",
|
||||
"Add-optional-notes": "Añadir notas opcionales",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Añadir ubicación
|
||||
ADD-LOCATION-FOR-BETTER-IDS = AÑADIR UBICACIÓN PARA MEJOR SDI
|
||||
Add-location-to-refresh-suggestions = Añadir ubicación para actualizar sugerencias
|
||||
Add-observations = Añade observaciones
|
||||
ADD-OPTIONAL-COMMENT = AÑADIR COMENTARIO OPCIONAL
|
||||
Add-optional-notes = Añadir notas opcionales
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "AÑADIR UBICACIÓN PARA MEJOR SDI",
|
||||
"Add-location-to-refresh-suggestions": "Añadir ubicación para actualizar sugerencias",
|
||||
"Add-observations": "Añade observaciones",
|
||||
"ADD-OPTIONAL-COMMENT": "AÑADIR COMENTARIO OPCIONAL",
|
||||
"Add-optional-notes": "Añadir notas opcionales",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Lisa asukoht
|
||||
ADD-LOCATION-FOR-BETTER-IDS = LISA PAREMAKS MÄÄRATLEMISEKS ASUKOHT
|
||||
Add-location-to-refresh-suggestions = Soovituste uuendamiseks lisa asukoht
|
||||
Add-observations = Lisa vaatluseid
|
||||
ADD-OPTIONAL-COMMENT = LISA SOOVIKORRAL KOMMENTAAR
|
||||
Add-optional-notes = Lisa soovi korral märkuseid
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "LISA PAREMAKS MÄÄRATLEMISEKS ASUKOHT",
|
||||
"Add-location-to-refresh-suggestions": "Soovituste uuendamiseks lisa asukoht",
|
||||
"Add-observations": "Lisa vaatluseid",
|
||||
"ADD-OPTIONAL-COMMENT": "LISA SOOVIKORRAL KOMMENTAAR",
|
||||
"Add-optional-notes": "Lisa soovi korral märkuseid",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = افزودن مکان
|
||||
ADD-LOCATION-FOR-BETTER-IDS = برای شناسه های بهتر، مکان را اضافه کنید
|
||||
Add-location-to-refresh-suggestions = برای تازه کردن پیشنهادها، مکان را اضافه کنید
|
||||
Add-observations = افزودن مشاهدات
|
||||
ADD-OPTIONAL-COMMENT = افزودن نظر اختیاری
|
||||
Add-optional-notes = افزودن یادداشت های اختیاری
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "برای شناسه های بهتر، مکان را اضافه کنید",
|
||||
"Add-location-to-refresh-suggestions": "برای تازه کردن پیشنهادها، مکان را اضافه کنید",
|
||||
"Add-observations": "افزودن مشاهدات",
|
||||
"ADD-OPTIONAL-COMMENT": "افزودن نظر اختیاری",
|
||||
"Add-optional-notes": "افزودن یادداشت های اختیاری",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
+16
-17
@@ -34,14 +34,13 @@ Add-Location = Lisää sijainti
|
||||
ADD-LOCATION-FOR-BETTER-IDS = LISÄÄ SIJAINTI SAADAKSESI PAREMPIA TUNNISTUKSIA
|
||||
Add-location-to-refresh-suggestions = Lisää sijainti päivittääksesi ehdotukset
|
||||
Add-observations = Lisää havaintoja
|
||||
ADD-OPTIONAL-COMMENT = LISÄÄ VALINNAINEN KOMMENTTI
|
||||
Add-optional-notes = Lisää valinnaisia merkintöjä
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
Add-to-Projects = Lisää projekteihin
|
||||
ADD-TO-PROJECTS = LISÄÄ PROJEKTEIHIN
|
||||
Added-to-X-Projects =
|
||||
Added to { $count } { $count ->
|
||||
[one] Project
|
||||
*[other] Projects
|
||||
Lisätty { $count } { $count ->
|
||||
[one] projekti
|
||||
*[other] projektia
|
||||
}
|
||||
Adds-ID = Lisää tunnistus
|
||||
Adds-your-vote-of-agreement = Äänestä puolesta
|
||||
@@ -139,7 +138,7 @@ Closes-explanation = Sulkee selityksen
|
||||
Closes-introduction = Sulje intro
|
||||
Closes-withdraw-id-sheet = Sulkee "Peru tunnistus"-kohdan
|
||||
COLLABORATORS = YHTEISTYÖKUMPPANIT
|
||||
Collection-and-Umbrella-Projects = Collection & Umbrella Projects
|
||||
Collection-and-Umbrella-Projects = Kokoelma- ja sateenvarjoprojektit
|
||||
Collection-Project = Koontiprojektit
|
||||
Combine-Photos = Yhdistä kuvat
|
||||
COMMENT = KOMMENTOI
|
||||
@@ -334,7 +333,7 @@ FOLLOWING-X-PEOPLE =
|
||||
[one] SEURAA { $count } HENKILÖÄ
|
||||
*[other] SEURAA { $count } HENKILÖÄ
|
||||
}
|
||||
For-most-other-projects-observations-will-automatically-be-included = For most other projects, observations that meet project requirements will automatically be included in projects.
|
||||
For-most-other-projects-observations-will-automatically-be-included = Useimpiin muihin projekteihin sisällytetään automaattisesti havainnot, jotka täyttävät hankkeen vaatimukset.
|
||||
Forgot-Password = Unohtunut salasana
|
||||
GEOPRIVACY = SIJAINNIN TIETOSUOJA
|
||||
Geoprivacy-status = Sijainnin tietosuoja: { $status }
|
||||
@@ -474,8 +473,8 @@ Log-in-to-iNaturalist = Kirjaudu iNaturalistiin
|
||||
LOG-OUT = Kirjaudu ulos
|
||||
LOG-OUT--question = KIRJAUDU ULOS?
|
||||
Looks-like-you-havent-observed-this-yet-time-to-keep-exploring =
|
||||
Looks like you haven't observed this yet.
|
||||
Time to keep exploring!
|
||||
Näyttää siltä, että et ole vielä havainnut tätä.
|
||||
Aika jatkaa tutkimusta!
|
||||
Lowest = Alin
|
||||
LOWEST-RANK = ALIN TAKSONOMINEN TASO
|
||||
MAP = KARTTA
|
||||
@@ -619,7 +618,7 @@ Please-allow-Microphone-Access = Salli mikrofonin käyttö
|
||||
Please-choose-a-different-password = Valitse toinen salasana.
|
||||
Please-Grant-Permission = Ole hyvä ja anna lupa
|
||||
PLEASE-LOG-IN = KIRJAUDU SISÄÄN
|
||||
Please-log-in = Please log in
|
||||
Please-log-in = Kirjaudu
|
||||
Please-log-in-again = Kirjaudu sisään uudelleen. Meidän täytyy joskus päivittää istuntosi tyhjentääksemme välimuistissa olevat tiedot ja varmistaaksemme, että sovellus toimii parhaiten.
|
||||
Please-make-sure-your-password-is-at-least-6-characters = Varmista, että salasanasi on vähintään 6 merkkiä pitkä.
|
||||
Please-try-again-when-you-are-connected-to-the-internet = Yritä uudelleen, kun olet yhteydessä Internetiin.
|
||||
@@ -898,11 +897,11 @@ This-user-is-not-following-anyone = This user is not following anyone.
|
||||
To-sync-your-observations-to-iNaturalist = Jos haluat synkronoida havaintosi iNaturalistiin, kirjaudu sisään.
|
||||
To-view-nearby-organisms-please-enable-location = Nähdäksesi lähellä olevat eliöt, ota sijainti käyttöön.
|
||||
To-view-nearby-projects-please-enable-location = Nähdäksesi lähellä olevat projektit, ota sijainti käyttöön.
|
||||
To-view-this-observations-Collection-and-Umbrella-Projects = To view this observation’s Collection and Umbrella Projects, go to its observation page once it’s uploaded.
|
||||
To-view-this-observations-Collection-and-Umbrella-Projects = Voit tarkastella, mihin kokoelma- ja sateenvarjoprojekteihin havainto kuuluu havaintosivulla, kun havainto on ladattu.
|
||||
Toggle-map-type = Vaihda karttatyyppiä
|
||||
TOP-ID-SUGGESTION = PARAS TUNNISTUS
|
||||
Traditional-Project = Perinteinen projekti
|
||||
Traditional-Projects = Traditional Projects
|
||||
Traditional-Projects = Perinteiset projektit
|
||||
Umbrella-Project = Sateenvarjoprojekti
|
||||
UNFOLLOW = LOPETA SEURAAMINEN
|
||||
UNFOLLOW-USER = LOPETA KÄYTTÄJÄN SEURAAMINEN?
|
||||
@@ -1116,18 +1115,18 @@ You-can-add-up-to-20-media = Voit liittää enintään 20 kuvaa ja 20 ääntä h
|
||||
You-can-also-check-out-merchandise = Voit myös tutustua iNaturalistin ja Seekin tuotteisiin alla olevassa kaupassamme!
|
||||
You-can-click-join-on-the-project-page = Voit napsauttaa "liity" projektisivulla.
|
||||
You-can-find-answers-on-our-help-page = Löydät vastaukset ohjesivultamme.
|
||||
You-can-manually-add-observations-to-Traditional-Projects-you-have-joined = You can manually add observations to Traditional Projects you have joined.
|
||||
You-can-manually-add-observations-to-Traditional-Projects-you-have-joined = Voit manuaalisesti lisätä havaintoja perinteisiin projekteihin, joihin olet liittynyt.
|
||||
You-can-now-upload-your-observations-to-iNaturalist-and-contribute = Voit nyt ladata havaintosi iNaturalistiin ja osallistua maailmanlaajuiseen biodiversiteettitutkimukseen.
|
||||
You-can-only-add-20-photos-per-observation = Voit liittää vain 20 kuvaa havaintoa kohden.
|
||||
You-can-still-share-the-file = Voit silti jakaa tiedoston toisen sovelluksen kanssa. Jos voit lähettää sen sähköpostitse, lähetä se osoitteeseen { $email }
|
||||
You-can-upload-this-observation-to-our-community = Voit ladata tämän havainnon yhteisöömme saadaksesi tunnistuksen oikealta henkilöltä ja auttaaksesi tekoälyämme parantamaan tunnistamistaan tulevaisuudessa
|
||||
You-cant-add-or-remove-observations-from-collection-and-umbrella-projects = You can’t add or remove observations from collection and umbrella projects.
|
||||
You-cant-add-or-remove-observations-from-collection-and-umbrella-projects = Et voi lisätä tai poistaa havaintoja kokoelma- ja sateenvarjoprojekteista.
|
||||
You-changed-filters-will-be-discarded = Muutit suodattimia, mutta niitä ei käytetty Tutki-hakutuloksissasi.
|
||||
You-have-no-notifications-get-started-by-creating-your-own-observations = You have no notifications! Get started by creating your own observations.
|
||||
You-have-no-notifications-you-will-see-updates-to-obs-you-have-left-IDs-or-comments-on = You have no notifications! You will see updates to observations you have left IDs or comments on here.
|
||||
You-have-opted-out-of-the-Community-Taxon = Olet jättäytynyt pois yhteisön taksonista
|
||||
You-havent-joined-any-projects-yet = Et ole liittynyt yhteenkään projektiin vielä!
|
||||
You-havent-joined-any-Traditional-Projects-yet = You haven’t joined any Traditional Projects yet!
|
||||
You-havent-joined-any-Traditional-Projects-yet = Et ole vielä liittynyt mihinkään perinteiseen projektiin!
|
||||
You-havent-observed-any-species-yet = Et ole vielä havainnut yhtään lajia.
|
||||
You-likely-observed-a-species-in-this-group = Havaitsit todennäköisesti lajin tästä ryhmästä
|
||||
You-likely-observed-this-species = Havaitsit todennäköisesti tämän lajin
|
||||
@@ -1137,7 +1136,7 @@ You-may-notice-changes-to-how-things-look-and-flow = Saatat huomata muutoksia si
|
||||
You-must-install-Google-Play-Services-to-sign-in-with-Google = Sinun on asennettava Google Play -palvelut, jotta voit kirjautua Google-tilillä.
|
||||
You-need-an-Internet-connection-to-do-that = Tarvitset Internet-yhteyden, jotta voit tehdä sen.
|
||||
You-need-log-in-to-do-that = Sinun täytyy kirjautua ensin.
|
||||
You-need-to-be-logged-in-to-add-observations-to-projects = You need to be logged in to add observations to projects.
|
||||
You-need-to-be-logged-in-to-add-observations-to-projects = Sinun täytyy olla kirjautunut sisään lisätäksesi havaintoja projekteihin.
|
||||
You-observed-a-species-in-this-group = Havaitsit lajin tästä ryhmästä
|
||||
You-observed-this-species = Havaitsit tämän lajin
|
||||
You-will-see-notifications = Näet ilmoitukset täällä, kun kirjaudut sisään ja lataat havaintoja.
|
||||
|
||||
+13
-14
@@ -25,11 +25,10 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "LISÄÄ SIJAINTI SAADAKSESI PAREMPIA TUNNISTUKSIA",
|
||||
"Add-location-to-refresh-suggestions": "Lisää sijainti päivittääksesi ehdotukset",
|
||||
"Add-observations": "Lisää havaintoja",
|
||||
"ADD-OPTIONAL-COMMENT": "LISÄÄ VALINNAINEN KOMMENTTI",
|
||||
"Add-optional-notes": "Lisää valinnaisia merkintöjä",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
"Added-to-X-Projects": "Added to { $count } { $count ->\n [one] Project\n *[other] Projects\n}",
|
||||
"Add-to-Projects": "Lisää projekteihin",
|
||||
"ADD-TO-PROJECTS": "LISÄÄ PROJEKTEIHIN",
|
||||
"Added-to-X-Projects": "Lisätty { $count } { $count ->\n [one] projekti\n *[other] projektia\n}",
|
||||
"Adds-ID": "Lisää tunnistus",
|
||||
"Adds-your-vote-of-agreement": "Äänestä puolesta",
|
||||
"Adds-your-vote-of-disagreement": "Äänestä vastaan",
|
||||
@@ -126,7 +125,7 @@
|
||||
"Closes-introduction": "Sulje intro",
|
||||
"Closes-withdraw-id-sheet": "Sulkee \"Peru tunnistus\"-kohdan",
|
||||
"COLLABORATORS": "YHTEISTYÖKUMPPANIT",
|
||||
"Collection-and-Umbrella-Projects": "Collection & Umbrella Projects",
|
||||
"Collection-and-Umbrella-Projects": "Kokoelma- ja sateenvarjoprojektit",
|
||||
"Collection-Project": "Koontiprojektit",
|
||||
"Combine-Photos": "Yhdistä kuvat",
|
||||
"COMMENT": "KOMMENTOI",
|
||||
@@ -305,7 +304,7 @@
|
||||
"Flip-camera": "Vaihda kameraa",
|
||||
"FOLLOW": "SEURAA",
|
||||
"FOLLOWING-X-PEOPLE": "{ $count ->\n [one] SEURAA { $count } HENKILÖÄ\n *[other] SEURAA { $count } HENKILÖÄ\n}",
|
||||
"For-most-other-projects-observations-will-automatically-be-included": "For most other projects, observations that meet project requirements will automatically be included in projects.",
|
||||
"For-most-other-projects-observations-will-automatically-be-included": "Useimpiin muihin projekteihin sisällytetään automaattisesti havainnot, jotka täyttävät hankkeen vaatimukset.",
|
||||
"Forgot-Password": "Unohtunut salasana",
|
||||
"GEOPRIVACY": "SIJAINNIN TIETOSUOJA",
|
||||
"Geoprivacy-status": "Sijainnin tietosuoja: { $status }",
|
||||
@@ -424,7 +423,7 @@
|
||||
"Log-in-to-iNaturalist": "Kirjaudu iNaturalistiin",
|
||||
"LOG-OUT": "Kirjaudu ulos",
|
||||
"LOG-OUT--question": "KIRJAUDU ULOS?",
|
||||
"Looks-like-you-havent-observed-this-yet-time-to-keep-exploring": "Looks like you haven't observed this yet.\nTime to keep exploring!",
|
||||
"Looks-like-you-havent-observed-this-yet-time-to-keep-exploring": "Näyttää siltä, että et ole vielä havainnut tätä.\nAika jatkaa tutkimusta!",
|
||||
"Lowest": "Alin",
|
||||
"LOWEST-RANK": "ALIN TAKSONOMINEN TASO",
|
||||
"MAP": "KARTTA",
|
||||
@@ -560,7 +559,7 @@
|
||||
"Please-choose-a-different-password": "Valitse toinen salasana.",
|
||||
"Please-Grant-Permission": "Ole hyvä ja anna lupa",
|
||||
"PLEASE-LOG-IN": "KIRJAUDU SISÄÄN",
|
||||
"Please-log-in": "Please log in",
|
||||
"Please-log-in": "Kirjaudu",
|
||||
"Please-log-in-again": "Kirjaudu sisään uudelleen. Meidän täytyy joskus päivittää istuntosi tyhjentääksemme välimuistissa olevat tiedot ja varmistaaksemme, että sovellus toimii parhaiten.",
|
||||
"Please-make-sure-your-password-is-at-least-6-characters": "Varmista, että salasanasi on vähintään 6 merkkiä pitkä.",
|
||||
"Please-try-again-when-you-are-connected-to-the-internet": "Yritä uudelleen, kun olet yhteydessä Internetiin.",
|
||||
@@ -835,11 +834,11 @@
|
||||
"To-sync-your-observations-to-iNaturalist": "Jos haluat synkronoida havaintosi iNaturalistiin, kirjaudu sisään.",
|
||||
"To-view-nearby-organisms-please-enable-location": "Nähdäksesi lähellä olevat eliöt, ota sijainti käyttöön.",
|
||||
"To-view-nearby-projects-please-enable-location": "Nähdäksesi lähellä olevat projektit, ota sijainti käyttöön.",
|
||||
"To-view-this-observations-Collection-and-Umbrella-Projects": "To view this observation’s Collection and Umbrella Projects, go to its observation page once it’s uploaded.",
|
||||
"To-view-this-observations-Collection-and-Umbrella-Projects": "Voit tarkastella, mihin kokoelma- ja sateenvarjoprojekteihin havainto kuuluu havaintosivulla, kun havainto on ladattu.",
|
||||
"Toggle-map-type": "Vaihda karttatyyppiä",
|
||||
"TOP-ID-SUGGESTION": "PARAS TUNNISTUS",
|
||||
"Traditional-Project": "Perinteinen projekti",
|
||||
"Traditional-Projects": "Traditional Projects",
|
||||
"Traditional-Projects": "Perinteiset projektit",
|
||||
"Umbrella-Project": "Sateenvarjoprojekti",
|
||||
"UNFOLLOW": "LOPETA SEURAAMINEN",
|
||||
"UNFOLLOW-USER": "LOPETA KÄYTTÄJÄN SEURAAMINEN?",
|
||||
@@ -940,18 +939,18 @@
|
||||
"You-can-also-check-out-merchandise": "Voit myös tutustua iNaturalistin ja Seekin tuotteisiin alla olevassa kaupassamme!",
|
||||
"You-can-click-join-on-the-project-page": "Voit napsauttaa \"liity\" projektisivulla.",
|
||||
"You-can-find-answers-on-our-help-page": "Löydät vastaukset ohjesivultamme.",
|
||||
"You-can-manually-add-observations-to-Traditional-Projects-you-have-joined": "You can manually add observations to Traditional Projects you have joined.",
|
||||
"You-can-manually-add-observations-to-Traditional-Projects-you-have-joined": "Voit manuaalisesti lisätä havaintoja perinteisiin projekteihin, joihin olet liittynyt.",
|
||||
"You-can-now-upload-your-observations-to-iNaturalist-and-contribute": "Voit nyt ladata havaintosi iNaturalistiin ja osallistua maailmanlaajuiseen biodiversiteettitutkimukseen.",
|
||||
"You-can-only-add-20-photos-per-observation": "Voit liittää vain 20 kuvaa havaintoa kohden.",
|
||||
"You-can-still-share-the-file": "Voit silti jakaa tiedoston toisen sovelluksen kanssa. Jos voit lähettää sen sähköpostitse, lähetä se osoitteeseen { $email }",
|
||||
"You-can-upload-this-observation-to-our-community": "Voit ladata tämän havainnon yhteisöömme saadaksesi tunnistuksen oikealta henkilöltä ja auttaaksesi tekoälyämme parantamaan tunnistamistaan tulevaisuudessa",
|
||||
"You-cant-add-or-remove-observations-from-collection-and-umbrella-projects": "You can’t add or remove observations from collection and umbrella projects.",
|
||||
"You-cant-add-or-remove-observations-from-collection-and-umbrella-projects": "Et voi lisätä tai poistaa havaintoja kokoelma- ja sateenvarjoprojekteista.",
|
||||
"You-changed-filters-will-be-discarded": "Muutit suodattimia, mutta niitä ei käytetty Tutki-hakutuloksissasi.",
|
||||
"You-have-no-notifications-get-started-by-creating-your-own-observations": "You have no notifications! Get started by creating your own observations.",
|
||||
"You-have-no-notifications-you-will-see-updates-to-obs-you-have-left-IDs-or-comments-on": "You have no notifications! You will see updates to observations you have left IDs or comments on here.",
|
||||
"You-have-opted-out-of-the-Community-Taxon": "Olet jättäytynyt pois yhteisön taksonista",
|
||||
"You-havent-joined-any-projects-yet": "Et ole liittynyt yhteenkään projektiin vielä!",
|
||||
"You-havent-joined-any-Traditional-Projects-yet": "You haven’t joined any Traditional Projects yet!",
|
||||
"You-havent-joined-any-Traditional-Projects-yet": "Et ole vielä liittynyt mihinkään perinteiseen projektiin!",
|
||||
"You-havent-observed-any-species-yet": "Et ole vielä havainnut yhtään lajia.",
|
||||
"You-likely-observed-a-species-in-this-group": "Havaitsit todennäköisesti lajin tästä ryhmästä",
|
||||
"You-likely-observed-this-species": "Havaitsit todennäköisesti tämän lajin",
|
||||
@@ -961,7 +960,7 @@
|
||||
"You-must-install-Google-Play-Services-to-sign-in-with-Google": "Sinun on asennettava Google Play -palvelut, jotta voit kirjautua Google-tilillä.",
|
||||
"You-need-an-Internet-connection-to-do-that": "Tarvitset Internet-yhteyden, jotta voit tehdä sen.",
|
||||
"You-need-log-in-to-do-that": "Sinun täytyy kirjautua ensin.",
|
||||
"You-need-to-be-logged-in-to-add-observations-to-projects": "You need to be logged in to add observations to projects.",
|
||||
"You-need-to-be-logged-in-to-add-observations-to-projects": "Sinun täytyy olla kirjautunut sisään lisätäksesi havaintoja projekteihin.",
|
||||
"You-observed-a-species-in-this-group": "Havaitsit lajin tästä ryhmästä",
|
||||
"You-observed-this-species": "Havaitsit tämän lajin",
|
||||
"You-will-see-notifications": "Näet ilmoitukset täällä, kun kirjaudut sisään ja lataat havaintoja.",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Ajouter un emplacement
|
||||
ADD-LOCATION-FOR-BETTER-IDS = AJOUTER UN EMPLACEMENT POUR DE MEILLEURES IDS
|
||||
Add-location-to-refresh-suggestions = Ajouter un emplacement pour rafraichir les suggestions
|
||||
Add-observations = Ajouter des observations
|
||||
ADD-OPTIONAL-COMMENT = AJOUTER UN COMMENTAIRE OPTIONNEL
|
||||
Add-optional-notes = Ajouter notes optionnelles
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "AJOUTER UN EMPLACEMENT POUR DE MEILLEURES IDS",
|
||||
"Add-location-to-refresh-suggestions": "Ajouter un emplacement pour rafraichir les suggestions",
|
||||
"Add-observations": "Ajouter des observations",
|
||||
"ADD-OPTIONAL-COMMENT": "AJOUTER UN COMMENTAIRE OPTIONNEL",
|
||||
"Add-optional-notes": "Ajouter notes optionnelles",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Ajouter un emplacement
|
||||
ADD-LOCATION-FOR-BETTER-IDS = AJOUTER UN EMPLACEMENT POUR DE MEILLEURES IDS
|
||||
Add-location-to-refresh-suggestions = Ajouter un emplacement pour rafraichir les suggestions
|
||||
Add-observations = Ajouter des observations
|
||||
ADD-OPTIONAL-COMMENT = AJOUTER UN COMMENTAIRE OPTIONNEL
|
||||
Add-optional-notes = Ajouter notes optionnelles
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "AJOUTER UN EMPLACEMENT POUR DE MEILLEURES IDS",
|
||||
"Add-location-to-refresh-suggestions": "Ajouter un emplacement pour rafraichir les suggestions",
|
||||
"Add-observations": "Ajouter des observations",
|
||||
"ADD-OPTIONAL-COMMENT": "AJOUTER UN COMMENTAIRE OPTIONNEL",
|
||||
"Add-optional-notes": "Ajouter notes optionnelles",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = הוספת מיקום
|
||||
ADD-LOCATION-FOR-BETTER-IDS = הוספת מיקום לזיהויים טובים יותר
|
||||
Add-location-to-refresh-suggestions = הוספת מיקום לרענון הצעות
|
||||
Add-observations = הוספת תצפיות
|
||||
ADD-OPTIONAL-COMMENT = הוספת הערה אופציונלית
|
||||
Add-optional-notes = הוספת הערות אופציונליות
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "הוספת מיקום לזיהויים טובים יותר",
|
||||
"Add-location-to-refresh-suggestions": "הוספת מיקום לרענון הצעות",
|
||||
"Add-observations": "הוספת תצפיות",
|
||||
"ADD-OPTIONAL-COMMENT": "הוספת הערה אופציונלית",
|
||||
"Add-optional-notes": "הוספת הערות אופציונליות",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = A PONTOS AZONOSÍTÁSHOZ HELY IS SZÜKSÉGES
|
||||
Add-location-to-refresh-suggestions = Hely hozzáadásával a javaslatok frissülnek
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "A PONTOS AZONOSÍTÁSHOZ HELY IS SZÜKSÉGES",
|
||||
"Add-location-to-refresh-suggestions": "Hely hozzáadásával a javaslatok frissülnek",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
@@ -31,7 +31,6 @@ Add-Location = Add Location
|
||||
ADD-LOCATION-FOR-BETTER-IDS = ADD LOCATION FOR BETTER IDS
|
||||
Add-location-to-refresh-suggestions = Add location to refresh suggestions
|
||||
Add-observations = Add observations
|
||||
ADD-OPTIONAL-COMMENT = ADD OPTIONAL COMMENT
|
||||
Add-optional-notes = Add optional notes
|
||||
Add-to-Projects = Add to Projects
|
||||
ADD-TO-PROJECTS = ADD TO PROJECTS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"ADD-LOCATION-FOR-BETTER-IDS": "ADD LOCATION FOR BETTER IDS",
|
||||
"Add-location-to-refresh-suggestions": "Add location to refresh suggestions",
|
||||
"Add-observations": "Add observations",
|
||||
"ADD-OPTIONAL-COMMENT": "ADD OPTIONAL COMMENT",
|
||||
"Add-optional-notes": "Add optional notes",
|
||||
"Add-to-Projects": "Add to Projects",
|
||||
"ADD-TO-PROJECTS": "ADD TO PROJECTS",
|
||||
|
||||
Loaded 100 of 195 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user