From cd3d67b75f879fed444edaf8f4c6b8f9aca933f8 Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:02:17 -0500 Subject: [PATCH 01/43] MOB-1339: init default search options --- .../components/DefaultSearchOptions.tsx | 153 ++++++++++++++++++ .../ExploreV2/screens/UniversalSearch.tsx | 6 +- src/i18n/l10n/en.ftl | 1 + src/i18n/l10n/en.ftl.json | 1 + src/i18n/strings.ftl | 1 + .../ExploreV2/screens/UniversalSearch.test.js | 81 ++++++++++ 6 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx diff --git a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx new file mode 100644 index 000000000..1b80d1625 --- /dev/null +++ b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx @@ -0,0 +1,153 @@ +import type { ApiUser } from "api/types"; +import classnames from "classnames"; +import UniversalSearchResult + from "components/Explore/ExploreV2/components/UniversalSearchResult"; +import { resultToSubject } + from "components/Explore/ExploreV2/helpers/universalSearchSubject"; +import INatIconButton from "components/SharedComponents/Buttons/INatIconButton"; +import Body2 from "components/SharedComponents/Typography/Body2"; +import { Pressable, ScrollView, View } from "components/styledComponents"; +import type { ExploreV2Subject } from "providers/ExploreV2Context"; +import React, { useCallback, useMemo } from "react"; +import type { ListRenderItemInfo } from "react-native"; +import { FlatList } from "react-native"; +import useCurrentUser from "sharedHooks/useCurrentUser"; +import useIconicTaxa from "sharedHooks/useIconicTaxa"; +import useTranslation from "sharedHooks/useTranslation"; +import type { UniversalSearchResultItem } from "sharedHooks/useUniversalSearch"; +import colors from "styles/tailwindColors"; + +interface Props { + onSelectSubject: ( subject: ExploreV2Subject ) => void; +} + +interface IconicTaxon { + id: number; + name: string; + preferred_common_name?: string; + iconic_taxon_name?: string; + rank_level?: number; + default_photo?: { url?: string }; +} + +// Display order for the iconic taxa row, matching the Figma "SearchDefaults" +// frame. "unknown" is intentionally omitted since it isn't a searchable taxon. +const ICONIC_TAXA_ORDER = [ + "plantae", + "insecta", + "aves", + "animalia", + "fungi", + "arachnida", + "mollusca", + "mammalia", + "reptilia", + "amphibia", + "actinopterygii", + "chromista", + "protozoa", +]; + +const ICON_BUTTON_WRAPPER = classnames( + "border-darkGray border border-[2px] mr-4 justify-center items-center", + "h-[36px] w-[36px] rounded-full", +); + +const ROW_CLASSES = "px-4 py-2 border-b border-lightGray"; + +const ICONIC_ROW_STYLE = { + alignItems: "center", + paddingHorizontal: 16, +} as const; + +const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { + const { t } = useTranslation( ); + // The Realm User model isn't strongly typed; treat the current user as an + // ApiUser for the fields we read, matching how universalSearchSubject casts. + const currentUser = useCurrentUser( ) as unknown as ApiUser | null; + const iconicTaxa = useIconicTaxa( ); + + // Order the iconic taxa returned from Realm by the design's display order. Any + // that haven't been synced into Realm yet (see NetworkService) are skipped. + const orderedIconicTaxa = useMemo( ( ): IconicTaxon[] => { + const taxaByName = new Map( ); + const taxaList = ( iconicTaxa + ? Array.from( iconicTaxa ) + : [] ) as unknown as IconicTaxon[]; + taxaList.forEach( taxon => { + if ( taxon?.name ) { + taxaByName.set( taxon.name.toLowerCase( ), taxon ); + } + } ); + return ICONIC_TAXA_ORDER + .map( name => taxaByName.get( name ) ) + .filter( ( taxon ): taxon is IconicTaxon => !!taxon ); + }, [iconicTaxa] ); + + const renderIconicTaxon = useCallback( + ( { item: taxon }: ListRenderItemInfo ) => { + const iconicName = ( taxon.iconic_taxon_name || taxon.name ).toLowerCase( ); + return ( + + onSelectSubject( resultToSubject( { type: "taxon", taxon } ) )} + size={22} + testID={`DefaultSearchOptions.iconicTaxonButton.${taxon.id}`} + /> + + ); + }, + [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 ( + + `iconic-${taxon.id}`} + renderItem={renderIconicTaxon} + showsHorizontalScrollIndicator={false} + testID="DefaultSearchOptions.iconicTaxa" + /> + {currentUserResult && ( + onSelectSubject( resultToSubject( currentUserResult ) )} + /> + )} + undefined} + testID="DefaultSearchOptions.unobserved" + > + {t( "Species-I-havent-observed" )} + + + ); +}; + +export default DefaultSearchOptions; diff --git a/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx b/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx index 12dd41572..c57bdd2f6 100644 --- a/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx +++ b/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx @@ -1,5 +1,7 @@ import { useNavigation } from "@react-navigation/native"; import classnames from "classnames"; +import DefaultSearchOptions + from "components/Explore/ExploreV2/components/DefaultSearchOptions"; import UniversalSearchResult from "components/Explore/ExploreV2/components/UniversalSearchResult"; import { @@ -118,7 +120,7 @@ const UniversalSearch = ( ) => { /> ), [handleSelect] ); - let body = null; + let body; if ( showResults ) { body = ( { )} /> ); + } else { + body = ( ); } return ( diff --git a/src/i18n/l10n/en.ftl b/src/i18n/l10n/en.ftl index c1961e980..a7c137289 100644 --- a/src/i18n/l10n/en.ftl +++ b/src/i18n/l10n/en.ftl @@ -1219,6 +1219,7 @@ sound-recorder-help-Try-to-isolate = Try to isolate the sound of a single organi Sounds = Sounds Source-List = <0>(Source List: <1>{ $source }<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 diff --git a/src/i18n/l10n/en.ftl.json b/src/i18n/l10n/en.ftl.json index 73acc9f02..ed2a2b926 100644 --- a/src/i18n/l10n/en.ftl.json +++ b/src/i18n/l10n/en.ftl.json @@ -762,6 +762,7 @@ "Sounds": "Sounds", "Source-List": "<0>(Source List: <1>{ $source }<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", diff --git a/src/i18n/strings.ftl b/src/i18n/strings.ftl index c1961e980..a7c137289 100644 --- a/src/i18n/strings.ftl +++ b/src/i18n/strings.ftl @@ -1219,6 +1219,7 @@ sound-recorder-help-Try-to-isolate = Try to isolate the sound of a single organi Sounds = Sounds Source-List = <0>(Source List: <1>{ $source }<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 diff --git a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js index 3c7edcae4..4bfe174df 100644 --- a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js +++ b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js @@ -37,6 +37,27 @@ jest.mock( "sharedHooks/useCurrentUser", ( ) => ( { } ) ); const useCurrentUser = require( "sharedHooks/useCurrentUser" ).default; +jest.mock( "sharedHooks/useIconicTaxa", ( ) => ( { + __esModule: true, + default: jest.fn( ), +} ) ); +const useIconicTaxa = require( "sharedHooks/useIconicTaxa" ).default; + +const ICONIC_TAXA = [ + { + id: 47126, + name: "Plantae", + iconic_taxon_name: "Plantae", + preferred_common_name: "Plants", + }, + { + id: 3, + name: "Aves", + iconic_taxon_name: "Aves", + preferred_common_name: "Birds", + }, +]; + const CURRENT_USER = { id: 99, login: "tester", @@ -97,6 +118,7 @@ beforeEach( ( ) => { mockDispatch.mockClear( ); useExploreV2.mockReturnValue( { dispatch: mockDispatch, state: {} } ); useCurrentUser.mockReturnValue( CURRENT_USER ); + useIconicTaxa.mockReturnValue( ICONIC_TAXA ); useUniversalSearch.mockReturnValue( { results: [], isLoading: false, refetch: jest.fn( ) } ); } ); @@ -238,6 +260,65 @@ describe( "UniversalSearch screen", ( ) => { ).toBeNull( ); } ); + describe( "default search options (empty query)", ( ) => { + it( "shows the iconic taxa row, current user, and unobserved shortcut", ( ) => { + renderComponent( ); + + expect( screen.getByTestId( "DefaultSearchOptions" ) ).toBeTruthy( ); + expect( screen.getByTestId( "DefaultSearchOptions.iconicTaxonButton.47126" ) ).toBeTruthy( ); + // current user's profile row, reusing the user result row + expect( screen.getByTestId( "UniversalSearchResult.user.99" ) ).toBeTruthy( ); + expect( screen.getByText( "tester" ) ).toBeTruthy( ); + // "Species I haven't observed" shortcut + expect( screen.getByText( i18next.t( "Species-I-havent-observed" ) ) ).toBeTruthy( ); + } ); + + it( "fills the field and sets the subject when an iconic taxon is tapped", ( ) => { + renderComponent( ); + + fireEvent.press( screen.getByTestId( "DefaultSearchOptions.iconicTaxonButton.47126" ) ); + + expect( mockDispatch ).toHaveBeenCalledWith( + expect.objectContaining( { + type: "SET_SUBJECT", + subject: expect.objectContaining( { + type: "taxon", + taxon: expect.objectContaining( { id: 47126, name: "Plantae" } ), + } ), + } ), + ); + // common name is primary for the test user, so the field shows "Plants" + expect( screen.getByDisplayValue( "Plants" ) ).toBeTruthy( ); + } ); + + it( "sets the current user as the subject when their profile row is tapped", ( ) => { + renderComponent( ); + + fireEvent.press( screen.getByTestId( "UniversalSearchResult.user.99" ) ); + + expect( mockDispatch ).toHaveBeenCalledWith( + expect.objectContaining( { + type: "SET_SUBJECT", + subject: expect.objectContaining( { + type: "user", + user: expect.objectContaining( { id: 99, login: "tester" } ), + } ), + } ), + ); + expect( screen.getByDisplayValue( "tester" ) ).toBeTruthy( ); + } ); + + it( "hides the current user row when logged out", ( ) => { + useCurrentUser.mockReturnValue( null ); + renderComponent( ); + + expect( screen.queryByTestId( "UniversalSearchResult.user.99" ) ).toBeNull( ); + // the iconic taxa row and unobserved shortcut still render + expect( screen.getByTestId( "DefaultSearchOptions.iconicTaxonButton.47126" ) ).toBeTruthy( ); + expect( screen.getByText( i18next.t( "Species-I-havent-observed" ) ) ).toBeTruthy( ); + } ); + } ); + it( "navigates to Advanced Search", ( ) => { renderComponent( ); From 672667c990d5779fd0825f3e513caef18b0b4f84 Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:31:41 -0500 Subject: [PATCH 02/43] MOB-1339: visual audit --- .../components/DefaultSearchOptions.tsx | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx index 1b80d1625..6b9ac0112 100644 --- a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx +++ b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx @@ -5,7 +5,7 @@ import UniversalSearchResult import { resultToSubject } from "components/Explore/ExploreV2/helpers/universalSearchSubject"; import INatIconButton from "components/SharedComponents/Buttons/INatIconButton"; -import Body2 from "components/SharedComponents/Typography/Body2"; +import Body1 from "components/SharedComponents/Typography/Body1"; import { Pressable, ScrollView, View } from "components/styledComponents"; import type { ExploreV2Subject } from "providers/ExploreV2Context"; import React, { useCallback, useMemo } from "react"; @@ -49,15 +49,16 @@ const ICONIC_TAXA_ORDER = [ ]; const ICON_BUTTON_WRAPPER = classnames( - "border-darkGray border border-[2px] mr-4 justify-center items-center", + "border-darkGray border border-[2px] mr-[15px] justify-center items-center", "h-[36px] w-[36px] rounded-full", ); -const ROW_CLASSES = "px-4 py-2 border-b border-lightGray"; +const ROW_CLASSES = "px-[15px] py-[11px] border-b border-lightGray"; const ICONIC_ROW_STYLE = { alignItems: "center", - paddingHorizontal: 16, + paddingHorizontal: 15, + paddingVertical: 15, } as const; const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { @@ -120,15 +121,17 @@ const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { return ( - `iconic-${taxon.id}`} - renderItem={renderIconicTaxon} - showsHorizontalScrollIndicator={false} - testID="DefaultSearchOptions.iconicTaxa" - /> + + `iconic-${taxon.id}`} + renderItem={renderIconicTaxon} + showsHorizontalScrollIndicator={false} + testID="DefaultSearchOptions.iconicTaxa" + /> + {currentUserResult && ( { onPress={( ) => undefined} testID="DefaultSearchOptions.unobserved" > - {t( "Species-I-havent-observed" )} + {t( "Species-I-havent-observed" )} ); From b5ea406f936fb4083ee993e2d7650073c20ce17e Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Sat, 27 Jun 2026 18:13:59 -0500 Subject: [PATCH 03/43] MOB-1339: use taxon mapping function --- .../components/DefaultSearchOptions.tsx | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx index 6b9ac0112..e2c59a7ab 100644 --- a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx +++ b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx @@ -1,4 +1,4 @@ -import type { ApiUser } from "api/types"; +import type { ApiTaxon, ApiUser } from "api/types"; import classnames from "classnames"; import UniversalSearchResult from "components/Explore/ExploreV2/components/UniversalSearchResult"; @@ -11,6 +11,8 @@ import type { ExploreV2Subject } from "providers/ExploreV2Context"; import React, { useCallback, useMemo } from "react"; import type { ListRenderItemInfo } from "react-native"; import { FlatList } from "react-native"; +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"; @@ -21,15 +23,6 @@ interface Props { onSelectSubject: ( subject: ExploreV2Subject ) => void; } -interface IconicTaxon { - id: number; - name: string; - preferred_common_name?: string; - iconic_taxon_name?: string; - rank_level?: number; - default_photo?: { url?: string }; -} - // Display order for the iconic taxa row, matching the Figma "SearchDefaults" // frame. "unknown" is intentionally omitted since it isn't a searchable taxon. const ICONIC_TAXA_ORDER = [ @@ -63,31 +56,31 @@ const ICONIC_ROW_STYLE = { const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { const { t } = useTranslation( ); - // The Realm User model isn't strongly typed; treat the current user as an - // ApiUser for the fields we read, matching how universalSearchSubject casts. + const currentUser = useCurrentUser( ) as unknown as ApiUser | null; const iconicTaxa = useIconicTaxa( ); - // Order the iconic taxa returned from Realm by the design's display order. Any - // that haven't been synced into Realm yet (see NetworkService) are skipped. - const orderedIconicTaxa = useMemo( ( ): IconicTaxon[] => { - const taxaByName = new Map( ); + // Order the iconic taxa returned from Realm by the design's display order + const orderedIconicTaxa = useMemo( ( ): ApiTaxon[] => { + const taxaByName = new Map( ); const taxaList = ( iconicTaxa ? Array.from( iconicTaxa ) - : [] ) as unknown as IconicTaxon[]; + : [] ) as unknown as RealmTaxon[]; taxaList.forEach( taxon => { if ( taxon?.name ) { taxaByName.set( taxon.name.toLowerCase( ), taxon ); } } ); + return ICONIC_TAXA_ORDER .map( name => taxaByName.get( name ) ) - .filter( ( taxon ): taxon is IconicTaxon => !!taxon ); + .filter( ( taxon ): taxon is RealmTaxon => !!taxon ) + .map( taxon => Taxon.mapRealmToApi( taxon ) as ApiTaxon ); }, [iconicTaxa] ); const renderIconicTaxon = useCallback( - ( { item: taxon }: ListRenderItemInfo ) => { - const iconicName = ( taxon.iconic_taxon_name || taxon.name ).toLowerCase( ); + ( { item: taxon }: ListRenderItemInfo ) => { + const iconicName = ( taxon.iconic_taxon_name || taxon.name || "" ).toLowerCase( ); return ( { accessibilityRole="button" accessibilityLabel={t( "Species-I-havent-observed" )} className={ROW_CLASSES} - // TODO MOB-1339 follow-up: wire to an unobserved_by_user_id filter once - // ExploreV2 supports it (the filter does not exist yet). + // TODO MOB-1345 onPress={( ) => undefined} testID="DefaultSearchOptions.unobserved" > From 9138c793ca793111f516db60f09d1f5388b9eace Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Mon, 29 Jun 2026 13:54:40 -0500 Subject: [PATCH 04/43] MOB-1339: too much context in comment --- src/realmModels/Taxon.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/realmModels/Taxon.js b/src/realmModels/Taxon.js index 3d81c82e4..d02d91ffe 100644 --- a/src/realmModels/Taxon.js +++ b/src/realmModels/Taxon.js @@ -163,12 +163,6 @@ class Taxon extends Realm.Object { /** * Inverse of mapApiToRealm: maps a live Realm Taxon into the plain, * snake_case ApiTaxon shape the API and most display/search code expect. - * Live Realm objects expose camelCase mapTo accessors (preferredCommonName, - * defaultPhoto); we read those (falling back to the snake_case keys so a - * plain object passes through unchanged) and return a detached POJO. Use - * this whenever a live Taxon needs to leave the data layer (React/Zustand - * state, async boundaries, child components) so we aren't passing around an - * object Realm can invalidate underneath us. * * @param {object} taxon - a live Realm Taxon (or an already-plain object) * @returns {object} plain ApiTaxon-shaped object From 14e36f0df7ab8b23e1810d868c3e6cd303b5e810 Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Mon, 29 Jun 2026 14:09:18 -0500 Subject: [PATCH 05/43] MOB-1339 clarify logged out test --- .../components/Explore/ExploreV2/screens/UniversalSearch.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js index 4bfe174df..8efe0e521 100644 --- a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js +++ b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js @@ -315,6 +315,7 @@ describe( "UniversalSearch screen", ( ) => { expect( screen.queryByTestId( "UniversalSearchResult.user.99" ) ).toBeNull( ); // the iconic taxa row and unobserved shortcut still render expect( screen.getByTestId( "DefaultSearchOptions.iconicTaxonButton.47126" ) ).toBeTruthy( ); + // depending on how this is implemented, we may not actually show this for logged out expect( screen.getByText( i18next.t( "Species-I-havent-observed" ) ) ).toBeTruthy( ); } ); } ); From dbaae0cf1af1499b235816f4ef00c7b090b446c9 Mon Sep 17 00:00:00 2001 From: Abbey Campbell Date: Tue, 30 Jun 2026 15:18:15 -0700 Subject: [PATCH 06/43] read comment from newIdentification --- .../IdentificationSheets.tsx | 21 ++++++++++++++----- .../hooks/useObsDetailsSharedLogic.ts | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx index 209f4eb72..7b6dabd14 100644 --- a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx +++ b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx @@ -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"; @@ -141,14 +144,19 @@ 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, + identTaxon: null, + newIdentification: null, + }; default: return state; } }; interface Props { - agreeIdentification: boolean; + agreeIdentification: AgreeIdentification | null; closeAgreeWithIdSheet: () => void; confirmRemoteObsWasDeleted?: () => void; handleCommentMutationSuccess: ( data: unknown ) => void; @@ -212,9 +220,9 @@ const IdentificationSheets: React.FC = ( { 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 } ); @@ -416,7 +424,10 @@ const IdentificationSheets: React.FC = ( { hidden={showIdentBodySheet} loading={isCreateIdPending} onPressClose={closeAgreeWithIdSheet} - identification={agreeIdentification} + identification={{ + taxon: agreeIdentification.taxon, + body: newIdentification?.body, + }} /> )} {/* AddCommentSheet */} diff --git a/src/components/ObsDetailsSharedComponents/hooks/useObsDetailsSharedLogic.ts b/src/components/ObsDetailsSharedComponents/hooks/useObsDetailsSharedLogic.ts index 98ed44adb..512ec6fb2 100644 --- a/src/components/ObsDetailsSharedComponents/hooks/useObsDetailsSharedLogic.ts +++ b/src/components/ObsDetailsSharedComponents/hooks/useObsDetailsSharedLogic.ts @@ -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; } From 082651e79ac72dc6c89b98449a56841478c2b48a Mon Sep 17 00:00:00 2001 From: Abbey Campbell Date: Tue, 30 Jun 2026 15:28:23 -0700 Subject: [PATCH 07/43] add missing prop --- src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx index 7b6dabd14..f2e1a7dfd 100644 --- a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx +++ b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx @@ -488,6 +488,7 @@ const IdentificationSheets: React.FC = ( { text={t( "Sorry-this-observation-was-deleted" )} buttonText={t( "OK" )} confirm={confirmRemoteObsWasDeleted} + loading={false} /> ) } From d5e3c4c21a64e21dd5ab5ec339b757e1d10e9fd5 Mon Sep 17 00:00:00 2001 From: Abbey Campbell Date: Tue, 30 Jun 2026 15:48:05 -0700 Subject: [PATCH 08/43] clean up dead state values --- .../IdentificationSheets.tsx | 28 ++++++------------- src/i18n/l10n/en.ftl | 1 - src/i18n/l10n/en.ftl.json | 1 - src/i18n/strings.ftl | 1 - 4 files changed, 8 insertions(+), 23 deletions(-) diff --git a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx index f2e1a7dfd..6bfadac02 100644 --- a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx +++ b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx @@ -56,8 +56,6 @@ interface Identification { } interface IdentState { - comment: string | null; - commentIsOptional: boolean; showIdentBodySheet: boolean; newIdentification: Identification | null; showPotentialDisagreementSheet: boolean; @@ -77,8 +75,6 @@ type IdentAction = | { type: "HIDE_SUGGESTED_ID_SHEET" }; const initialIdentState: IdentState = { - comment: null, - commentIsOptional: false, showIdentBodySheet: false, newIdentification: null, showPotentialDisagreementSheet: false, @@ -193,8 +189,6 @@ const IdentificationSheets: React.FC = ( { const [state, dispatch] = useReducer( identReducer, initialIdentState ); const { - comment, - commentIsOptional, showIdentBodySheet, identTaxon, newIdentification, @@ -205,16 +199,13 @@ const IdentificationSheets: React.FC = ( { 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 } ), [] ); @@ -404,10 +395,8 @@ const IdentificationSheets: React.FC = ( { }, [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 } ); @@ -438,7 +427,6 @@ const IdentificationSheets: React.FC = ( { onPressClose={hideAddCommentSheet} headerText={addCommentHeaderText} textInputStyle={textInputStyle} - initialInput={comment} confirm={confirmCommentFromCommentSheet} /> )} diff --git a/src/i18n/l10n/en.ftl b/src/i18n/l10n/en.ftl index 4b3f430df..52c8b2317 100644 --- a/src/i18n/l10n/en.ftl +++ b/src/i18n/l10n/en.ftl @@ -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 diff --git a/src/i18n/l10n/en.ftl.json b/src/i18n/l10n/en.ftl.json index 6a1c5d099..4ef643f7a 100644 --- a/src/i18n/l10n/en.ftl.json +++ b/src/i18n/l10n/en.ftl.json @@ -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", diff --git a/src/i18n/strings.ftl b/src/i18n/strings.ftl index 4b3f430df..52c8b2317 100644 --- a/src/i18n/strings.ftl +++ b/src/i18n/strings.ftl @@ -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 From e168ff4bfc060558d2d03e764f095a71b6afa830 Mon Sep 17 00:00:00 2001 From: Abbey Campbell Date: Tue, 30 Jun 2026 21:48:23 -0700 Subject: [PATCH 09/43] couple other type fixes --- src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx index 6bfadac02..19d57c89a 100644 --- a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx +++ b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx @@ -219,7 +219,8 @@ const IdentificationSheets: React.FC = ( { 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] ); @@ -267,6 +268,7 @@ const IdentificationSheets: React.FC = ( { observationTaxon = observation?.community_taxon || observation.taxon; } return observationTaxon + && !!taxon?.id && taxon?.id !== observationTaxon.id && observationTaxon.ancestor_ids.includes( taxon?.id ); }, [observation] ); From 107a88c566173c45d20b8fd73c62176c28bc94fa Mon Sep 17 00:00:00 2001 From: Abbey Campbell Date: Wed, 1 Jul 2026 11:05:54 -0700 Subject: [PATCH 10/43] remove un-needed optional chaining --- .../ObsDetailsDefaultMode/IdentificationSheets.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx index 19d57c89a..e7bf3a250 100644 --- a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx +++ b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx @@ -258,14 +258,14 @@ const IdentificationSheets: React.FC = ( { 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 @@ -323,14 +323,14 @@ const IdentificationSheets: React.FC = ( { const onAgree = useCallback( ( ident: Identification ) => { const agreeParams = { - observation_id: observation?.uuid, + observation_id: observation.uuid, taxon_id: ident.taxon?.id, body: ident.body, }; loadActivityItem( ); createIdentificationMutate( { identification: agreeParams } ); - }, [createIdentificationMutate, observation?.uuid, loadActivityItem] ); + }, [createIdentificationMutate, observation.uuid, loadActivityItem] ); const potentialDisagreeSheetDiscardChanges = useCallback( ( ) => { dispatch( { type: HIDE_POTENTIAL_DISAGREEMENT_SHEET } ); From 166764adc82c2aae3155ad38687340689e059026 Mon Sep 17 00:00:00 2001 From: Abbey Campbell Date: Wed, 1 Jul 2026 12:23:32 -0700 Subject: [PATCH 11/43] test clean up --- .../ObsDetailsDefaultMode/IdentificationSheets.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/unit/components/ObsDetailsDefaultMode/IdentificationSheets.test.js b/tests/unit/components/ObsDetailsDefaultMode/IdentificationSheets.test.js index e735535c7..02328b449 100644 --- a/tests/unit/components/ObsDetailsDefaultMode/IdentificationSheets.test.js +++ b/tests/unit/components/ObsDetailsDefaultMode/IdentificationSheets.test.js @@ -142,8 +142,6 @@ describe( "IdentificationSheets", () => { describe( "identReducer", () => { const initialState = { - comment: null, - commentIsOptional: false, showIdentBodySheet: false, newIdentification: null, showPotentialDisagreementSheet: false, From ff8d719a8340746b3805abf65d6c86ff42bd5a64 Mon Sep 17 00:00:00 2001 From: Abbey Campbell Date: Wed, 1 Jul 2026 13:12:00 -0700 Subject: [PATCH 12/43] restore optional chaining --- src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx index e7bf3a250..60751ed00 100644 --- a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx +++ b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx @@ -323,14 +323,14 @@ const IdentificationSheets: React.FC = ( { const onAgree = useCallback( ( ident: Identification ) => { const agreeParams = { - observation_id: observation.uuid, + observation_id: observation?.uuid, taxon_id: ident.taxon?.id, body: ident.body, }; loadActivityItem( ); createIdentificationMutate( { identification: agreeParams } ); - }, [createIdentificationMutate, observation.uuid, loadActivityItem] ); + }, [createIdentificationMutate, observation?.uuid, loadActivityItem] ); const potentialDisagreeSheetDiscardChanges = useCallback( ( ) => { dispatch( { type: HIDE_POTENTIAL_DISAGREEMENT_SHEET } ); From a08f77231b6a1c80e6bcfbac0633351fc0a9ab32 Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Thu, 2 Jul 2026 16:05:05 -0500 Subject: [PATCH 13/43] renamed taxon mapper --- .../Explore/ExploreV2/components/DefaultSearchOptions.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx index e2c59a7ab..8c26d8489 100644 --- a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx +++ b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx @@ -75,7 +75,7 @@ const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { return ICONIC_TAXA_ORDER .map( name => taxaByName.get( name ) ) .filter( ( taxon ): taxon is RealmTaxon => !!taxon ) - .map( taxon => Taxon.mapRealmToApi( taxon ) as ApiTaxon ); + .map( taxon => Taxon.mapRealmToPojo( taxon ) as ApiTaxon ); }, [iconicTaxa] ); const renderIconicTaxon = useCallback( From f8a2f382ccd9618add8f406c5b26a4327da9521e Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Thu, 2 Jul 2026 16:30:32 -0500 Subject: [PATCH 14/43] MOB-1339: Flatlist eating taps --- .../Explore/ExploreV2/components/DefaultSearchOptions.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx index 8c26d8489..9b7a20651 100644 --- a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx +++ b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx @@ -120,6 +120,7 @@ const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { data={orderedIconicTaxa} horizontal keyExtractor={taxon => `iconic-${taxon.id}`} + keyboardShouldPersistTaps="handled" renderItem={renderIconicTaxon} showsHorizontalScrollIndicator={false} testID="DefaultSearchOptions.iconicTaxa" From d36e9274ce90d43907426a5b5cd498467464847a Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Thu, 2 Jul 2026 17:05:33 -0500 Subject: [PATCH 15/43] MOB-1339: gate default options on actual text input text --- .../ExploreV2/screens/UniversalSearch.tsx | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx b/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx index 49793035f..b065470e7 100644 --- a/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx +++ b/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx @@ -103,6 +103,28 @@ const UniversalSearch = ( ) => { /> ), [handleSelect] ); + let mainContent = null; + /* Results for an active query, default options when empty, else nothing */ + if ( subjectText.trim( ).length === 0 ) { + mainContent = ( ); + } else if ( subjectHasQuery ) { + mainContent = ( + + )} + /> + ); + } + return ( @@ -169,24 +191,7 @@ const UniversalSearch = ( ) => { - {/* Surface results for an active query, otherwise the default options */} - {subjectHasQuery - ? ( - - )} - /> - ) - : ( )} + {mainContent} ); From e605a51c15aacbe8174d9a255006d29813091ce9 Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Thu, 2 Jul 2026 17:20:33 -0500 Subject: [PATCH 16/43] MOB-1339: reuse IconicTaxonChooser --- .../components/DefaultSearchOptions.tsx | 85 +++++-------------- .../SharedComponents/IconicTaxonChooser.tsx | 13 ++- src/i18n/l10n/en.ftl | 3 + src/i18n/l10n/en.ftl.json | 1 + src/i18n/strings.ftl | 3 + 5 files changed, 37 insertions(+), 68 deletions(-) diff --git a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx index 9b7a20651..9f2f3779b 100644 --- a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx +++ b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx @@ -1,51 +1,24 @@ import type { ApiTaxon, ApiUser } from "api/types"; -import classnames from "classnames"; import UniversalSearchResult from "components/Explore/ExploreV2/components/UniversalSearchResult"; import { resultToSubject } from "components/Explore/ExploreV2/helpers/universalSearchSubject"; -import INatIconButton from "components/SharedComponents/Buttons/INatIconButton"; +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, useMemo } from "react"; -import type { ListRenderItemInfo } from "react-native"; -import { FlatList } from "react-native"; 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"; import type { UniversalSearchResultItem } from "sharedHooks/useUniversalSearch"; -import colors from "styles/tailwindColors"; interface Props { onSelectSubject: ( subject: ExploreV2Subject ) => void; } -// Display order for the iconic taxa row, matching the Figma "SearchDefaults" -// frame. "unknown" is intentionally omitted since it isn't a searchable taxon. -const ICONIC_TAXA_ORDER = [ - "plantae", - "insecta", - "aves", - "animalia", - "fungi", - "arachnida", - "mollusca", - "mammalia", - "reptilia", - "amphibia", - "actinopterygii", - "chromista", - "protozoa", -]; - -const ICON_BUTTON_WRAPPER = classnames( - "border-darkGray border border-[2px] mr-[15px] justify-center items-center", - "h-[36px] w-[36px] rounded-full", -); - const ROW_CLASSES = "px-[15px] py-[11px] border-b border-lightGray"; const ICONIC_ROW_STYLE = { @@ -54,51 +27,35 @@ const ICONIC_ROW_STYLE = { paddingVertical: 15, } as const; +const EMPTY_CHOSEN: string[] = []; + const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { const { t } = useTranslation( ); const currentUser = useCurrentUser( ) as unknown as ApiUser | null; const iconicTaxa = useIconicTaxa( ); - // Order the iconic taxa returned from Realm by the design's display order - const orderedIconicTaxa = useMemo( ( ): ApiTaxon[] => { - const taxaByName = new Map( ); + // Map iconic taxon name -> Realm taxon, so the shared chooser's name-based + // callback can be resolved into a full taxon subject. + const taxaByName = useMemo( ( ): Map => { + const map = new Map( ); const taxaList = ( iconicTaxa ? Array.from( iconicTaxa ) : [] ) as unknown as RealmTaxon[]; taxaList.forEach( taxon => { if ( taxon?.name ) { - taxaByName.set( taxon.name.toLowerCase( ), taxon ); + map.set( taxon.name.toLowerCase( ), taxon ); } } ); - - return ICONIC_TAXA_ORDER - .map( name => taxaByName.get( name ) ) - .filter( ( taxon ): taxon is RealmTaxon => !!taxon ) - .map( taxon => Taxon.mapRealmToPojo( taxon ) as ApiTaxon ); + return map; }, [iconicTaxa] ); - const renderIconicTaxon = useCallback( - ( { item: taxon }: ListRenderItemInfo ) => { - const iconicName = ( taxon.iconic_taxon_name || taxon.name || "" ).toLowerCase( ); - return ( - - onSelectSubject( resultToSubject( { type: "taxon", taxon } ) )} - size={22} - testID={`DefaultSearchOptions.iconicTaxonButton.${taxon.id}`} - /> - - ); - }, - [onSelectSubject], - ); + const handleIconicTaxon = useCallback( ( iconicTaxonName: string ) => { + const realmTaxon = taxaByName.get( iconicTaxonName ); + if ( !realmTaxon ) { return; } + const taxon = Taxon.mapRealmToPojo( realmTaxon ) as ApiTaxon; + onSelectSubject( resultToSubject( { type: "taxon", taxon } ) ); + }, [taxaByName, onSelectSubject] ); const currentUserResult: UniversalSearchResultItem | null = currentUser?.id ? { @@ -115,15 +72,13 @@ const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { return ( - `iconic-${taxon.id}`} - keyboardShouldPersistTaps="handled" - renderItem={renderIconicTaxon} - showsHorizontalScrollIndicator={false} + onTaxonChosen={handleIconicTaxon} testID="DefaultSearchOptions.iconicTaxa" + withoutUnknown /> {currentUserResult && ( diff --git a/src/components/SharedComponents/IconicTaxonChooser.tsx b/src/components/SharedComponents/IconicTaxonChooser.tsx index 67168b581..fb8b8df3e 100644 --- a/src/components/SharedComponents/IconicTaxonChooser.tsx +++ b/src/components/SharedComponents/IconicTaxonChooser.tsx @@ -2,14 +2,16 @@ 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"; interface Props { + accessibilityHint?: string; before?: React.ReactNode; chosen: string[]; + contentContainerStyle?: StyleProp; onTaxonChosen: ( taxon: string ) => void; testID?: string; withoutUnknown?: boolean; @@ -39,8 +41,10 @@ const ICONIC_TAXA = [ const EMPTY_CHOSEN: string[] = []; const IconicTaxonChooser = ( { + accessibilityHint, before, chosen = EMPTY_CHOSEN, + contentContainerStyle = STYLESHEET, onTaxonChosen, testID, withoutUnknown, @@ -80,13 +84,15 @@ const IconicTaxonChooser = ( { t( "Iconic-taxon-name", { iconicTaxon: iconicTaxonName } ) } accessibilityHint={ - t( "Selects-iconic-taxon-X-for-identification", { iconicTaxon: iconicTaxonName } ) + accessibilityHint + ?? t( "Selects-iconic-taxon-X-for-identification", { iconicTaxon: iconicTaxonName } ) } testID={`INatIconButton.IconicTaxonButton.${iconicTaxonName}`} /> ); }, [ + accessibilityHint, chosen, onTaxonChosen, t, @@ -106,9 +112,10 @@ const IconicTaxonChooser = ( { return ( Date: Thu, 2 Jul 2026 16:54:37 -0700 Subject: [PATCH 17/43] remove hook that sets observations to viewed on foreground --- src/components/NetworkService.ts | 7 +-- src/sharedHooks/index.ts | 1 - .../useObservationUpdatesWhenFocused.js | 50 --------------- .../useObservationUpdatesWhenFocused.test.js | 63 ------------------- 4 files changed, 1 insertion(+), 120 deletions(-) delete mode 100644 src/sharedHooks/useObservationUpdatesWhenFocused.js delete mode 100644 tests/integration/sharedHooks/useObservationUpdatesWhenFocused.test.js diff --git a/src/components/NetworkService.ts b/src/components/NetworkService.ts index 69a6ae0cc..7d77d1c46 100644 --- a/src/components/NetworkService.ts +++ b/src/components/NetworkService.ts @@ -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 diff --git a/src/sharedHooks/index.ts b/src/sharedHooks/index.ts index 7b426c9c9..a2a93d5d0 100644 --- a/src/sharedHooks/index.ts +++ b/src/sharedHooks/index.ts @@ -22,7 +22,6 @@ export { default as useLocalObservations } from "./useLocalObservations"; export { default as useLocationPermission } from "./useLocationPermission"; export { default as useNavigateToObsEdit } from "./useNavigateToObsEdit"; export { default as useObservationsUpdates } from "./useObservationsUpdates"; -export { default as useObservationUpdatesWhenFocused } from "./useObservationUpdatesWhenFocused"; export { default as useQuery } from "./useQuery"; export { default as useRemoteObservation } from "./useRemoteObservation"; export { default as useScrollToOffset } from "./useScrollToOffset"; diff --git a/src/sharedHooks/useObservationUpdatesWhenFocused.js b/src/sharedHooks/useObservationUpdatesWhenFocused.js deleted file mode 100644 index d46840732..000000000 --- a/src/sharedHooks/useObservationUpdatesWhenFocused.js +++ /dev/null @@ -1,50 +0,0 @@ -// @flow - -import { RealmContext } from "providers/contexts"; -import { useCallback, useEffect } from "react"; -import { AppState } from "react-native"; -import safeRealmWrite from "sharedHelpers/safeRealmWrite"; - -const { useRealm } = RealmContext; - -const useObservationUpdatesWhenFocused = () => { - const realm = useRealm(); - - const setObservationUpdatesViewedRealm = useCallback( () => { - // Set all observations to viewed - const observations = realm - .objects( "Observation" ) - .filtered( "comments_viewed == false OR identifications_viewed == false" ); - if ( observations.length === 0 ) { return; } - safeRealmWrite( realm, () => { - observations.forEach( observation => { - observation.comments_viewed = true; - observation.identifications_viewed = true; - } ); - }, "setting comments_viewed and ids_viewed to true in useObservationsUpdatesWhenFocused" ); - }, [realm] ); - - const onAppStateChange = useCallback( - status => { - // if the app is coming back from the background, set all observations to viewed - if ( status === "active" ) { - setObservationUpdatesViewedRealm(); - } - }, - [setObservationUpdatesViewedRealm], - ); - - useEffect( () => { - // subscribe to app state changes - const subscription = AppState.addEventListener( - "change", - onAppStateChange, - ); - setObservationUpdatesViewedRealm(); - - // unsubscribe on unmount - return () => subscription?.remove(); - }, [onAppStateChange, setObservationUpdatesViewedRealm] ); -}; - -export default useObservationUpdatesWhenFocused; diff --git a/tests/integration/sharedHooks/useObservationUpdatesWhenFocused.test.js b/tests/integration/sharedHooks/useObservationUpdatesWhenFocused.test.js deleted file mode 100644 index 064987a74..000000000 --- a/tests/integration/sharedHooks/useObservationUpdatesWhenFocused.test.js +++ /dev/null @@ -1,63 +0,0 @@ -import { renderHook } from "@testing-library/react-native"; -import safeRealmWrite from "sharedHelpers/safeRealmWrite"; -import useObservationUpdatesWhenFocused from "sharedHooks/useObservationUpdatesWhenFocused"; -import factory from "tests/factory"; -import setupUniqueRealm from "tests/helpers/uniqueRealm"; - -// UNIQUE REALM SETUP -const mockRealmIdentifier = __filename; -const { mockRealmModelsIndex, uniqueRealmBeforeAll, uniqueRealmAfterAll } = setupUniqueRealm( - mockRealmIdentifier, -); -jest.mock( "realmModels/index", ( ) => mockRealmModelsIndex ); -jest.mock( "providers/contexts", ( ) => { - const originalModule = jest.requireActual( "providers/contexts" ); - return { - __esModule: true, - ...originalModule, - RealmContext: { - ...originalModule.RealmContext, - useRealm: ( ) => global.mockRealms[mockRealmIdentifier], - useQuery: ( ) => [], - }, - }; -} ); -beforeAll( uniqueRealmBeforeAll ); -afterAll( uniqueRealmAfterAll ); -// /UNIQUE REALM SETUP - -jest.mock( "react-native/Libraries/AppState/AppState", () => ( { - __esModule: true, - default: { - addEventListener: jest.fn( ( event, callback ) => { - callback( "active" ); - } ), - }, -} ) ); - -const mockObservations = [ - factory( "LocalObservation", { comments_viewed: false, identifications_viewed: false } ), - factory( "LocalObservation", { comments_viewed: true, identifications_viewed: false } ), - factory( "LocalObservation", { comments_viewed: false, identifications_viewed: true } ), - factory( "LocalObservation", { comments_viewed: true, identifications_viewed: true } ), -]; - -describe( "useObservationUpdatesWhenFocused", () => { - beforeAll( ( ) => { - // Write mock observations to realm - safeRealmWrite( global.mockRealms[mockRealmIdentifier], ( ) => { - mockObservations.forEach( o => { - global.mockRealms[mockRealmIdentifier].create( "Observation", o ); - } ); - }, "write observations to realm, useObservationUpdatesWhenFocused test" ); - } ); - - it( "should reset state of all observations in realm", () => { - renderHook( () => useObservationUpdatesWhenFocused() ); - const observations = global.mockRealms[mockRealmIdentifier].objects( "Observation" ); - observations.forEach( o => { - expect( o.comments_viewed ).toBe( true ); - expect( o.identifications_viewed ).toBe( true ); - } ); - } ); -} ); From 02905db07717c42d373c55e046666c37557bc9a6 Mon Sep 17 00:00:00 2001 From: Abbey Campbell Date: Thu, 2 Jul 2026 17:48:59 -0700 Subject: [PATCH 18/43] refetch obs updates on pull to refresh --- src/components/MyObservations/MyObservationsResults.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/MyObservations/MyObservationsResults.tsx b/src/components/MyObservations/MyObservationsResults.tsx index a0e6290b9..de0f8beb9 100644 --- a/src/components/MyObservations/MyObservationsResults.tsx +++ b/src/components/MyObservations/MyObservationsResults.tsx @@ -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 From 17deb8c1711de80f743cdfac89297fab0e1d4088 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Fri, 3 Jul 2026 08:37:40 +0200 Subject: [PATCH 19/43] Also query for project_observation_fields in ProjectDetails --- src/api/fields.ts | 1 + src/api/types.d.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/api/fields.ts b/src/api/fields.ts index 238b3f347..3515c4e14 100644 --- a/src/api/fields.ts +++ b/src/api/fields.ts @@ -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, }; diff --git a/src/api/types.d.ts b/src/api/types.d.ts index e4251b4d5..d46a9527d 100644 --- a/src/api/types.d.ts +++ b/src/api/types.d.ts @@ -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[]; } From f916b6db3057cd03d504abe40ca35baf5ac277a6 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Fri, 3 Jul 2026 08:39:30 +0200 Subject: [PATCH 20/43] On join success persist traditional project to realm --- src/components/ProjectDetails/ProjectDetailsContainer.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/components/ProjectDetails/ProjectDetailsContainer.tsx b/src/components/ProjectDetails/ProjectDetailsContainer.tsx index 96bbe497c..5511e9961 100644 --- a/src/components/ProjectDetails/ProjectDetailsContainer.tsx +++ b/src/components/ProjectDetails/ProjectDetailsContainer.tsx @@ -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["navigation"]>( ); const { params } = useRoute["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 => { From a5fa09dc8a8eabe714aee93f181bc45eb4e801b0 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Fri, 3 Jul 2026 12:11:08 +0200 Subject: [PATCH 21/43] Do not set to true for iconicTaxon Which is a user choice not based on CV. --- src/components/Match/MatchContainer.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Match/MatchContainer.tsx b/src/components/Match/MatchContainer.tsx index 460006c7f..9e563d7e3 100644 --- a/src/components/Match/MatchContainer.tsx +++ b/src/components/Match/MatchContainer.tsx @@ -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 ); } From a8ed883393e447fd61c7d6e46c3c7aa022070803 Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Mon, 6 Jul 2026 09:55:09 -0500 Subject: [PATCH 22/43] Use Realm useQuery for iconic taxa collection useIconicTaxa returned realm.objects("Taxon").filtered(...), which produces a new Results instance on every call and sets up no change subscription. Consumers (DefaultSearchOptions, useTaxonSearch) saw a fresh reference each render, defeating downstream memoization, and the collection never re-rendered when the async seed write landed. Switch to RealmContext.useQuery, which returns a referentially stable collection and subscribes to changes. This stabilizes dependent memos and makes the iconic-taxa row reactive to the seed write, so a tap resolves to a taxon even when it happens right after the screen opens. Co-Authored-By: Claude Opus 4.8 --- src/sharedHooks/useIconicTaxa.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sharedHooks/useIconicTaxa.ts b/src/sharedHooks/useIconicTaxa.ts index 68e3825cf..b114aa01f 100644 --- a/src/sharedHooks/useIconicTaxa.ts +++ b/src/sharedHooks/useIconicTaxa.ts @@ -7,7 +7,7 @@ import Taxon from "realmModels/Taxon"; import safeRealmWrite from "sharedHelpers/safeRealmWrite"; import { useAuthenticatedQuery } from "sharedHooks"; -const { useRealm } = RealmContext; +const { useRealm, useQuery } = RealmContext; const useIconicTaxa = ( options: { reload: boolean } = { reload: false } ) => { const { reload } = options; @@ -37,7 +37,13 @@ const useIconicTaxa = ( options: { reload: boolean } = { reload: false } ) => { } }, [iconicTaxa, realm, isUpdatingRealm] ); - return realm?.objects( "Taxon" ).filtered( "isIconic = true" ); + return useQuery( + { + type: Taxon, + query: taxa => taxa.filtered( "isIconic = true" ), + }, + [], + ); }; export default useIconicTaxa; From 942b5930de53fbded43f3149a553c9b66393a2ac Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Mon, 6 Jul 2026 10:09:16 -0500 Subject: [PATCH 23/43] MOB-1339: memoize default search options --- .../Explore/ExploreV2/components/DefaultSearchOptions.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx index 9f2f3779b..f5f1ddd87 100644 --- a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx +++ b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx @@ -101,4 +101,4 @@ const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { ); }; -export default DefaultSearchOptions; +export default React.memo( DefaultSearchOptions ); From 9eb759a789e02734eea49e3a88988a1e518e9c31 Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Mon, 6 Jul 2026 11:27:48 -0500 Subject: [PATCH 24/43] fix unit test --- tests/integration/sharedHooks/useTaxon.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/sharedHooks/useTaxon.test.js b/tests/integration/sharedHooks/useTaxon.test.js index 1e2d5d323..f2c15d1b1 100644 --- a/tests/integration/sharedHooks/useTaxon.test.js +++ b/tests/integration/sharedHooks/useTaxon.test.js @@ -21,6 +21,7 @@ jest.mock( "providers/contexts", ( ) => { RealmContext: { ...originalModule.RealmContext, useRealm: ( ) => global.mockRealms[mockRealmIdentifier], + useQuery: ( ) => [], }, }; } ); From c506160908ba12f5e90c21503304d4b938edd6b7 Mon Sep 17 00:00:00 2001 From: Abbey Campbell Date: Mon, 6 Jul 2026 12:14:21 -0700 Subject: [PATCH 25/43] flip viewed state to true when an observation is viewed on another platform --- src/sharedHooks/useObservationsUpdates.js | 45 ++++++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/src/sharedHooks/useObservationsUpdates.js b/src/sharedHooks/useObservationsUpdates.js index 9aee9bba6..760632559 100644 --- a/src/sharedHooks/useObservationsUpdates.js +++ b/src/sharedHooks/useObservationsUpdates.js @@ -10,6 +10,8 @@ const { useRealm } = RealmContext; export const fetchObservationUpdatesKey = "fetchObservationUpdates"; +const PER_PAGE = 100; + const useObservationsUpdates = ( enabled: boolean ): Object => { const realm = useRealm(); @@ -18,7 +20,7 @@ const useObservationsUpdates = ( enabled: boolean ): Object => { observations_by: "owner", viewed: false, fields: "viewed,resource_uuid,comment_id,identification_id", - per_page: 50, + per_page: PER_PAGE, }; const { @@ -63,6 +65,18 @@ const useObservationsUpdates = ( enabled: boolean ): Object => { useEffect( ( ) => { // Looping through all unviewed updates const remoteUnviewed = data?.filter( result => result.viewed === false ); + + // Per-observation summary of what kinds of updates the server still considers unviewed, + // used below to reconcile obs the user viewed elsewhere (e.g. the website). + const unviewedByUuid = new Map(); + remoteUnviewed?.forEach( update => { + const entry = unviewedByUuid.get( update.resource_uuid ) + || { hasComment: false, hasIdent: false }; + if ( update.comment_id ) entry.hasComment = true; + if ( update.identification_id ) entry.hasIdent = true; + unviewedByUuid.set( update.resource_uuid, entry ); + } ); + safeRealmWrite( realm, ( ) => { remoteUnviewed?.forEach( update => { // Get the observation from local realm that matches the update's resource_uuid @@ -97,7 +111,34 @@ const useObservationsUpdates = ( enabled: boolean ): Object => { } } } ); - }, "setting comments and/or identifications false in useObservationsUpdates" ); + + // If the response was capped at per_page, we can't tell if observations beyond that cap + // are truly viewed or not, so we'll skip the sweep to avoid falsely clearing filled state. + if ( data && data.length >= PER_PAGE ) { + return; + } + + // Reconcile obs the user viewed elsewhere (e.g. the website): any observation currently + // marked unviewed locally that no longer has a matching unviewed update on the + // server should flip back to viewed. + const locallyUnviewed = realm.objects( "Observation" ).filtered( + "comments_viewed == false OR identifications_viewed == false", + ); + locallyUnviewed.forEach( obs => { + const serverUnviewed = unviewedByUuid.get( obs.uuid ); + if ( !serverUnviewed ) { + obs.comments_viewed = true; + obs.identifications_viewed = true; + return; + } + if ( obs.comments_viewed === false && !serverUnviewed.hasComment ) { + obs.comments_viewed = true; + } + if ( obs.identifications_viewed === false && !serverUnviewed.hasIdent ) { + obs.identifications_viewed = true; + } + } ); + }, "reconciling comments and/or identifications viewed state in useObservationsUpdates" ); }, [data, realm] ); return { refetch }; From edb5c7572daae5d80ddbb548db8a2f05df57ba39 Mon Sep 17 00:00:00 2001 From: Abbey Campbell Date: Mon, 6 Jul 2026 13:02:41 -0700 Subject: [PATCH 26/43] test refactor --- .../useObservationsUpdates.test.js | 147 ++++++++++-------- 1 file changed, 84 insertions(+), 63 deletions(-) diff --git a/tests/integration/sharedHooks/useObservationsUpdates.test.js b/tests/integration/sharedHooks/useObservationsUpdates.test.js index c1722422f..5f49b63b0 100644 --- a/tests/integration/sharedHooks/useObservationsUpdates.test.js +++ b/tests/integration/sharedHooks/useObservationsUpdates.test.js @@ -31,84 +31,105 @@ jest.mock( "api/observations" ); const mockUser = factory( "LocalUser" ); -const mockCommentUpdate = factory( "RemoteUpdate", { - comment_id: 1, - viewed: false, - resource_uuid: faker.string.uuid( ), -} ); -const mockIdentificationUpdate = factory( "RemoteUpdate", { - identification_id: 2, - viewed: false, - resource_uuid: faker.string.uuid( ), -} ); -const mockData = [mockCommentUpdate, mockIdentificationUpdate]; +let mockCurrentData = []; jest.mock( "sharedHooks/useAuthenticatedQuery", () => ( { __esModule: true, default: ( ) => ( { - data: mockData, + data: mockCurrentData, } ), } ) ); -const mockObservation = factory( "LocalObservation", { - comments_viewed: false, - identifications_view: false, +const commentUpdateFor = uuid => factory( "RemoteUpdate", { + comment_id: 1, + viewed: false, + resource_uuid: uuid, } ); +const identificationUpdateFor = uuid => factory( "RemoteUpdate", { + identification_id: 2, + viewed: false, + resource_uuid: uuid, +} ); + +const writeObs = attrs => { + const realm = global.mockRealms[mockRealmIdentifier]; + safeRealmWrite( realm, ( ) => { + realm.deleteAll( ); + realm.create( "Observation", factory( "LocalObservation", attrs ) ); + }, "write test observation, useObservationsUpdates test" ); +}; + +const findObs = uuid => global.mockRealms[mockRealmIdentifier] + .objectForPrimaryKey( "Observation", uuid ); describe( "useObservationsUpdates", ( ) => { - it( "should return an object", ( ) => { - const { result } = renderHook( ( ) => useObservationsUpdates( ) ); - expect( result.current ).toBeInstanceOf( Object ); + beforeEach( ( ) => { + mockCurrentData = []; } ); - describe( "when there is no local observation with the resource_uuid", ( ) => { - beforeEach( ( ) => { - // Write mock observation to realm - safeRealmWrite( global.mockRealms[mockRealmIdentifier], ( ) => { - global.mockRealms[mockRealmIdentifier].create( "Observation", mockObservation ); - }, "write mock observation, useObservationUpdates test" ); - } ); + it( "marks comments_viewed false when a matching unread comment arrives", ( ) => { + const uuid = faker.string.uuid( ); + writeObs( { uuid, comments_viewed: true, identifications_viewed: true } ); + mockCurrentData = [commentUpdateFor( uuid )]; - it( "should return without writing to a local observation", ( ) => { - const { result } = renderHook( ( ) => useObservationsUpdates( ) ); - const observation = global.mockRealms[mockRealmIdentifier] - .objectForPrimaryKey( "Observation", mockObservation.uuid ); - expect( mockCommentUpdate.resource_uuid ).not.toEqual( observation.uuid ); - expect( mockIdentificationUpdate.resource_uuid ).not.toEqual( observation.uuid ); - expect( result.current.refetch ).toEqual( undefined ); - } ); + renderHook( ( ) => useObservationsUpdates( mockUser ) ); + + const observation = findObs( uuid ); + expect( observation.comments_viewed ).toBe( false ); + expect( observation.identifications_viewed ).toBe( true ); } ); - describe.each( [ - ["comment", [mockCommentUpdate]], - ["identification", [mockIdentificationUpdate]], - ["both", mockData], - ] )( "when the update is a %s", ( ) => { - describe.each( [ - ["viewed fields not initialized", null, null], - ["viewed comments and viewed identifications", true, true], - ["viewed comments and not viewed identifications", true, false], - ["not viewed comments and viewed identifications", false, true], - ["not viewed comments and not viewed identifications", false, false], - ] )( "when the local observation has %s", ( a1, viewedComments, viewedIdentifications ) => { - beforeEach( ( ) => { - // Write mock observation to realm - safeRealmWrite( global.mockRealms[mockRealmIdentifier], ( ) => { - global.mockRealms[mockRealmIdentifier].deleteAll( ); - global.mockRealms[mockRealmIdentifier].create( "Observation", { - ...mockObservation, - comments_viewed: viewedComments, - identifications_viewed: viewedIdentifications, - } ); - }, "delete all and create observation, useObservationsUpdates test" ); - } ); + it( "marks identifications_viewed false when a matching unread identification arrives", ( ) => { + const uuid = faker.string.uuid( ); + writeObs( { uuid, comments_viewed: true, identifications_viewed: true } ); + mockCurrentData = [identificationUpdateFor( uuid )]; - it( "should write correct viewed status for comments and identifications", ( ) => { - renderHook( ( ) => useObservationsUpdates( mockUser ) ); - const observation = global.mockRealms[mockRealmIdentifier].objects( "Observation" )[0]; - expect( observation.comments_viewed ).toEqual( viewedComments ); - expect( observation.identifications_viewed ).toEqual( viewedIdentifications ); - } ); - } ); + renderHook( ( ) => useObservationsUpdates( mockUser ) ); + + const observation = findObs( uuid ); + expect( observation.comments_viewed ).toBe( true ); + expect( observation.identifications_viewed ).toBe( false ); + } ); + + it( "marks both flags false when matching comment and identification updates arrive", ( ) => { + const uuid = faker.string.uuid( ); + writeObs( { uuid, comments_viewed: true, identifications_viewed: true } ); + mockCurrentData = [commentUpdateFor( uuid ), identificationUpdateFor( uuid )]; + + renderHook( ( ) => useObservationsUpdates( mockUser ) ); + + const observation = findObs( uuid ); + expect( observation.comments_viewed ).toBe( false ); + expect( observation.identifications_viewed ).toBe( false ); + } ); + + it( "reconciles a locally-unviewed obs back to viewed when viewed elsewhere", ( ) => { + const uuid = faker.string.uuid( ); + writeObs( { uuid, comments_viewed: false, identifications_viewed: false } ); + // Response contains an update for a different observation. + mockCurrentData = [commentUpdateFor( faker.string.uuid( ) )]; + + renderHook( ( ) => useObservationsUpdates( mockUser ) ); + + const observation = findObs( uuid ); + expect( observation.comments_viewed ).toBe( true ); + expect( observation.identifications_viewed ).toBe( true ); + } ); + + it( "skips the sweep when the response reaches per_page limit and may be truncated", ( ) => { + const uuid = faker.string.uuid( ); + writeObs( { uuid, comments_viewed: false, identifications_viewed: false } ); + // Fill the response to PER_PAGE (100) with updates for unrelated observations, + // simulating a user whose server-side unread queue may extend beyond the page. + mockCurrentData = Array.from( + { length: 100 }, + ( ) => commentUpdateFor( faker.string.uuid( ) ), + ); + + renderHook( ( ) => useObservationsUpdates( mockUser ) ); + + const observation = findObs( uuid ); + expect( observation.comments_viewed ).toBe( false ); + expect( observation.identifications_viewed ).toBe( false ); } ); } ); From fdef5450e5bbee4751e57582471ca3921c44388b Mon Sep 17 00:00:00 2001 From: Abbey Campbell Date: Mon, 6 Jul 2026 14:15:54 -0700 Subject: [PATCH 27/43] drop unneeded taxon = null --- src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx index 60751ed00..82bb9894f 100644 --- a/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx +++ b/src/components/ObsDetailsDefaultMode/IdentificationSheets.tsx @@ -143,7 +143,6 @@ export const identReducer = ( state: IdentState, action: IdentAction ): IdentSta return { ...state, showSuggestIdSheet: false, - identTaxon: null, newIdentification: null, }; default: From ba01a2b465985e10adb5fa2c6a5acd425fc26075 Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Mon, 6 Jul 2026 18:50:10 -0500 Subject: [PATCH 28/43] MOB-1339: fix defaults after merge, readd tests --- .../ExploreV2/screens/UniversalSearch.tsx | 47 ++++--------- .../ExploreV2/screens/UniversalSearch.test.js | 69 +++++++++++++++++++ 2 files changed, 84 insertions(+), 32 deletions(-) diff --git a/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx b/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx index 932b578b1..3cf87c979 100644 --- a/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx +++ b/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx @@ -175,27 +175,22 @@ const UniversalSearch = ( ) => { ? locationData : subjectData; - let mainContent = null; - /* Results for an active query, default options when empty, else nothing */ - if ( subjectText.trim( ).length === 0 ) { - mainContent = ( ); - } else if ( subjectHasQuery ) { - mainContent = ( - - )} + const showDefaultOptions = !showLocation && !subjectHasQuery; + const listEmptyComponent = showDefaultOptions + ? ( ) + : ( + ); - } return ( @@ -270,19 +265,7 @@ const UniversalSearch = ( ) => { keyboardShouldPersistTaps="handled" keyExtractor={resultKey} renderItem={renderItem} - ListEmptyComponent={( - - )} + ListEmptyComponent={listEmptyComponent} /> diff --git a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js index cbc2301ab..3914607d8 100644 --- a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js +++ b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js @@ -285,6 +285,75 @@ describe( "UniversalSearch screen", ( ) => { ).toBeNull( ); } ); + describe( "default search options (empty subject field)", ( ) => { + it( "shows the iconic taxa chooser, current user, and unobserved shortcut", ( ) => { + renderComponent( ); + + expect( screen.getByTestId( "DefaultSearchOptions" ) ).toBeTruthy( ); + expect( screen.getByTestId( "INatIconButton.IconicTaxonButton.plantae" ) ).toBeTruthy( ); + // current user's profile row, reusing the user result row + expect( screen.getByTestId( "UniversalSearchResult.user.99" ) ).toBeTruthy( ); + expect( screen.getByText( "tester" ) ).toBeTruthy( ); + // "Species I haven't observed" shortcut + expect( screen.getByText( i18next.t( "Species-I-havent-observed" ) ) ).toBeTruthy( ); + } ); + + it( "fills the field and sets the subject when an iconic taxon is tapped", ( ) => { + renderComponent( ); + + fireEvent.press( screen.getByTestId( "INatIconButton.IconicTaxonButton.plantae" ) ); + + expect( mockDispatch ).toHaveBeenCalledWith( + expect.objectContaining( { + type: "SET_SUBJECT", + subject: expect.objectContaining( { + type: "taxon", + taxon: expect.objectContaining( { id: 47126, name: "Plantae" } ), + } ), + } ), + ); + // common name is primary for the test user, so the field shows "Plants" + expect( screen.getByDisplayValue( "Plants" ) ).toBeTruthy( ); + } ); + + it( "sets the current user as the subject when their profile row is tapped", ( ) => { + renderComponent( ); + + fireEvent.press( screen.getByTestId( "UniversalSearchResult.user.99" ) ); + + expect( mockDispatch ).toHaveBeenCalledWith( + expect.objectContaining( { + type: "SET_SUBJECT", + subject: expect.objectContaining( { + type: "user", + user: expect.objectContaining( { id: 99, login: "tester" } ), + } ), + } ), + ); + expect( screen.getByDisplayValue( "tester" ) ).toBeTruthy( ); + } ); + + it( "hides the current user row when logged out", ( ) => { + useCurrentUser.mockReturnValue( null ); + renderComponent( ); + + expect( screen.queryByTestId( "UniversalSearchResult.user.99" ) ).toBeNull( ); + // the iconic taxa chooser and unobserved shortcut still render + expect( screen.getByTestId( "INatIconButton.IconicTaxonButton.plantae" ) ).toBeTruthy( ); + expect( screen.getByText( i18next.t( "Species-I-havent-observed" ) ) ).toBeTruthy( ); + } ); + + it( "hides the default options once a subject query is entered", ( ) => { + renderComponent( ); + + expect( screen.getByTestId( "DefaultSearchOptions" ) ).toBeTruthy( ); + + typeQuery( "ver" ); + + expect( screen.queryByTestId( "DefaultSearchOptions" ) ).toBeNull( ); + } ); + } ); + it( "shows place autocomplete results while typing in the location field", ( ) => { useLocationSearch.mockReturnValue( { results: PLACE_RESULTS, From 50f4cfcc9328038c00764e5dcd5665d4adc314c2 Mon Sep 17 00:00:00 2001 From: iNaturalist Crowdin Sync Date: Tue, 7 Jul 2026 11:37:01 -0400 Subject: [PATCH 29/43] New Crowdin translations by GitHub Action (#3805) Co-authored-by: Crowdin Bot --- src/i18n/l10n/af.ftl | 1 - src/i18n/l10n/af.ftl.json | 1 - src/i18n/l10n/ar.ftl | 1 - src/i18n/l10n/ar.ftl.json | 1 - src/i18n/l10n/be.ftl | 1 - src/i18n/l10n/be.ftl.json | 1 - src/i18n/l10n/bg.ftl | 1 - src/i18n/l10n/bg.ftl.json | 1 - src/i18n/l10n/br.ftl | 1 - src/i18n/l10n/br.ftl.json | 1 - src/i18n/l10n/bs.ftl | 1 - src/i18n/l10n/bs.ftl.json | 1 - src/i18n/l10n/ca.ftl | 1 - src/i18n/l10n/ca.ftl.json | 1 - src/i18n/l10n/cs.ftl | 1 - src/i18n/l10n/cs.ftl.json | 1 - src/i18n/l10n/da.ftl | 1 - src/i18n/l10n/da.ftl.json | 1 - src/i18n/l10n/de.ftl | 1 - src/i18n/l10n/de.ftl.json | 1 - src/i18n/l10n/el.ftl | 1 - src/i18n/l10n/el.ftl.json | 1 - src/i18n/l10n/en-GB.ftl | 1 - src/i18n/l10n/en-GB.ftl.json | 1 - src/i18n/l10n/en-NZ.ftl | 1 - src/i18n/l10n/en-NZ.ftl.json | 1 - src/i18n/l10n/eo.ftl | 1 - src/i18n/l10n/eo.ftl.json | 1 - src/i18n/l10n/es-AR.ftl | 1 - src/i18n/l10n/es-AR.ftl.json | 1 - src/i18n/l10n/es-CO.ftl | 1 - src/i18n/l10n/es-CO.ftl.json | 1 - src/i18n/l10n/es-CR.ftl | 1 - src/i18n/l10n/es-CR.ftl.json | 1 - src/i18n/l10n/es-MX.ftl | 1 - src/i18n/l10n/es-MX.ftl.json | 1 - src/i18n/l10n/es.ftl | 1 - src/i18n/l10n/es.ftl.json | 1 - src/i18n/l10n/et.ftl | 1 - src/i18n/l10n/et.ftl.json | 1 - src/i18n/l10n/eu.ftl | 1 - src/i18n/l10n/eu.ftl.json | 1 - src/i18n/l10n/fa.ftl | 1 - src/i18n/l10n/fa.ftl.json | 1 - src/i18n/l10n/fi.ftl | 33 ++++++++++++++++----------------- src/i18n/l10n/fi.ftl.json | 27 +++++++++++++-------------- src/i18n/l10n/fil.ftl | 1 - src/i18n/l10n/fil.ftl.json | 1 - src/i18n/l10n/fo.ftl | 1 - src/i18n/l10n/fo.ftl.json | 1 - src/i18n/l10n/fr-CA.ftl | 1 - src/i18n/l10n/fr-CA.ftl.json | 1 - src/i18n/l10n/fr.ftl | 1 - src/i18n/l10n/fr.ftl.json | 1 - src/i18n/l10n/gd.ftl | 1 - src/i18n/l10n/gd.ftl.json | 1 - src/i18n/l10n/gl.ftl | 1 - src/i18n/l10n/gl.ftl.json | 1 - src/i18n/l10n/gu.ftl | 1 - src/i18n/l10n/gu.ftl.json | 1 - src/i18n/l10n/he.ftl | 1 - src/i18n/l10n/he.ftl.json | 1 - src/i18n/l10n/hi.ftl | 1 - src/i18n/l10n/hi.ftl.json | 1 - src/i18n/l10n/hr.ftl | 1 - src/i18n/l10n/hr.ftl.json | 1 - src/i18n/l10n/hu.ftl | 1 - src/i18n/l10n/hu.ftl.json | 1 - src/i18n/l10n/hy.ftl | 1 - src/i18n/l10n/hy.ftl.json | 1 - src/i18n/l10n/id.ftl | 1 - src/i18n/l10n/id.ftl.json | 1 - src/i18n/l10n/it.ftl | 1 - src/i18n/l10n/it.ftl.json | 1 - src/i18n/l10n/ja.ftl | 1 - src/i18n/l10n/ja.ftl.json | 1 - src/i18n/l10n/ka.ftl | 1 - src/i18n/l10n/ka.ftl.json | 1 - src/i18n/l10n/kk.ftl | 1 - src/i18n/l10n/kk.ftl.json | 1 - src/i18n/l10n/kl.ftl | 1 - src/i18n/l10n/kl.ftl.json | 1 - src/i18n/l10n/kn.ftl | 1 - src/i18n/l10n/kn.ftl.json | 1 - src/i18n/l10n/ko.ftl | 1 - src/i18n/l10n/ko.ftl.json | 1 - src/i18n/l10n/lb.ftl | 1 - src/i18n/l10n/lb.ftl.json | 1 - src/i18n/l10n/lt.ftl | 1 - src/i18n/l10n/lt.ftl.json | 1 - src/i18n/l10n/lv.ftl | 1 - src/i18n/l10n/lv.ftl.json | 1 - src/i18n/l10n/mi.ftl | 1 - src/i18n/l10n/mi.ftl.json | 1 - src/i18n/l10n/mk.ftl | 1 - src/i18n/l10n/mk.ftl.json | 1 - src/i18n/l10n/ml.ftl | 1 - src/i18n/l10n/ml.ftl.json | 1 - src/i18n/l10n/mr.ftl | 1 - src/i18n/l10n/mr.ftl.json | 1 - src/i18n/l10n/ms.ftl | 1 - src/i18n/l10n/ms.ftl.json | 1 - src/i18n/l10n/nb.ftl | 1 - src/i18n/l10n/nb.ftl.json | 1 - src/i18n/l10n/nl.ftl | 1 - src/i18n/l10n/nl.ftl.json | 1 - src/i18n/l10n/pa.ftl | 1 - src/i18n/l10n/pa.ftl.json | 1 - src/i18n/l10n/pl.ftl | 1 - src/i18n/l10n/pl.ftl.json | 1 - src/i18n/l10n/pt-BR.ftl | 1 - src/i18n/l10n/pt-BR.ftl.json | 1 - src/i18n/l10n/pt.ftl | 1 - src/i18n/l10n/pt.ftl.json | 1 - src/i18n/l10n/ro.ftl | 1 - src/i18n/l10n/ro.ftl.json | 1 - src/i18n/l10n/ru.ftl | 1 - src/i18n/l10n/ru.ftl.json | 1 - src/i18n/l10n/sat.ftl | 1 - src/i18n/l10n/sat.ftl.json | 1 - src/i18n/l10n/si.ftl | 1 - src/i18n/l10n/si.ftl.json | 1 - src/i18n/l10n/sk.ftl | 1 - src/i18n/l10n/sk.ftl.json | 1 - src/i18n/l10n/sl.ftl | 1 - src/i18n/l10n/sl.ftl.json | 1 - src/i18n/l10n/sq.ftl | 1 - src/i18n/l10n/sq.ftl.json | 1 - src/i18n/l10n/sr.ftl | 1 - src/i18n/l10n/sr.ftl.json | 1 - src/i18n/l10n/sv.ftl | 1 - src/i18n/l10n/sv.ftl.json | 1 - src/i18n/l10n/sw.ftl | 1 - src/i18n/l10n/sw.ftl.json | 1 - src/i18n/l10n/ta.ftl | 1 - src/i18n/l10n/ta.ftl.json | 1 - src/i18n/l10n/te.ftl | 1 - src/i18n/l10n/te.ftl.json | 1 - src/i18n/l10n/th.ftl | 1 - src/i18n/l10n/th.ftl.json | 1 - src/i18n/l10n/tl.ftl | 1 - src/i18n/l10n/tl.ftl.json | 1 - src/i18n/l10n/tr.ftl | 1 - src/i18n/l10n/tr.ftl.json | 1 - src/i18n/l10n/uk.ftl | 1 - src/i18n/l10n/uk.ftl.json | 1 - src/i18n/l10n/vi.ftl | 1 - src/i18n/l10n/vi.ftl.json | 1 - src/i18n/l10n/zh-CN.ftl | 1 - src/i18n/l10n/zh-CN.ftl.json | 1 - src/i18n/l10n/zh-HK.ftl | 1 - src/i18n/l10n/zh-HK.ftl.json | 1 - src/i18n/l10n/zh-TW.ftl | 1 - src/i18n/l10n/zh-TW.ftl.json | 1 - 154 files changed, 29 insertions(+), 183 deletions(-) diff --git a/src/i18n/l10n/af.ftl b/src/i18n/l10n/af.ftl index f4837afdc..1b2ae780d 100644 --- a/src/i18n/l10n/af.ftl +++ b/src/i18n/l10n/af.ftl @@ -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 diff --git a/src/i18n/l10n/af.ftl.json b/src/i18n/l10n/af.ftl.json index b042d8a44..c0733bd88 100644 --- a/src/i18n/l10n/af.ftl.json +++ b/src/i18n/l10n/af.ftl.json @@ -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", diff --git a/src/i18n/l10n/ar.ftl b/src/i18n/l10n/ar.ftl index 76fb177aa..3c2264599 100644 --- a/src/i18n/l10n/ar.ftl +++ b/src/i18n/l10n/ar.ftl @@ -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 diff --git a/src/i18n/l10n/ar.ftl.json b/src/i18n/l10n/ar.ftl.json index 0e1f9a7be..d5961b6bf 100644 --- a/src/i18n/l10n/ar.ftl.json +++ b/src/i18n/l10n/ar.ftl.json @@ -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", diff --git a/src/i18n/l10n/be.ftl b/src/i18n/l10n/be.ftl index 546b840b3..2a8edcdc8 100644 --- a/src/i18n/l10n/be.ftl +++ b/src/i18n/l10n/be.ftl @@ -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 diff --git a/src/i18n/l10n/be.ftl.json b/src/i18n/l10n/be.ftl.json index 7b4e2452c..e08c7cf50 100644 --- a/src/i18n/l10n/be.ftl.json +++ b/src/i18n/l10n/be.ftl.json @@ -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", diff --git a/src/i18n/l10n/bg.ftl b/src/i18n/l10n/bg.ftl index a34829742..8a62f096d 100644 --- a/src/i18n/l10n/bg.ftl +++ b/src/i18n/l10n/bg.ftl @@ -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 diff --git a/src/i18n/l10n/bg.ftl.json b/src/i18n/l10n/bg.ftl.json index de61cc1d7..c4a5a8656 100644 --- a/src/i18n/l10n/bg.ftl.json +++ b/src/i18n/l10n/bg.ftl.json @@ -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", diff --git a/src/i18n/l10n/br.ftl b/src/i18n/l10n/br.ftl index 9bada8269..4d161b49c 100644 --- a/src/i18n/l10n/br.ftl +++ b/src/i18n/l10n/br.ftl @@ -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 diff --git a/src/i18n/l10n/br.ftl.json b/src/i18n/l10n/br.ftl.json index 566861ce1..502c2a37b 100644 --- a/src/i18n/l10n/br.ftl.json +++ b/src/i18n/l10n/br.ftl.json @@ -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", diff --git a/src/i18n/l10n/bs.ftl b/src/i18n/l10n/bs.ftl index c4da79274..0480b112d 100644 --- a/src/i18n/l10n/bs.ftl +++ b/src/i18n/l10n/bs.ftl @@ -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 diff --git a/src/i18n/l10n/bs.ftl.json b/src/i18n/l10n/bs.ftl.json index d129b69b2..b0a5d3308 100644 --- a/src/i18n/l10n/bs.ftl.json +++ b/src/i18n/l10n/bs.ftl.json @@ -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", diff --git a/src/i18n/l10n/ca.ftl b/src/i18n/l10n/ca.ftl index 8f5a0eb07..765443047 100644 --- a/src/i18n/l10n/ca.ftl +++ b/src/i18n/l10n/ca.ftl @@ -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 diff --git a/src/i18n/l10n/ca.ftl.json b/src/i18n/l10n/ca.ftl.json index 7afd58b56..335d075f1 100644 --- a/src/i18n/l10n/ca.ftl.json +++ b/src/i18n/l10n/ca.ftl.json @@ -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", diff --git a/src/i18n/l10n/cs.ftl b/src/i18n/l10n/cs.ftl index 535053833..e9bfc9652 100644 --- a/src/i18n/l10n/cs.ftl +++ b/src/i18n/l10n/cs.ftl @@ -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 diff --git a/src/i18n/l10n/cs.ftl.json b/src/i18n/l10n/cs.ftl.json index 45b82d67e..306d59aaa 100644 --- a/src/i18n/l10n/cs.ftl.json +++ b/src/i18n/l10n/cs.ftl.json @@ -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", diff --git a/src/i18n/l10n/da.ftl b/src/i18n/l10n/da.ftl index 5e831dce8..cefc8f82b 100644 --- a/src/i18n/l10n/da.ftl +++ b/src/i18n/l10n/da.ftl @@ -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 diff --git a/src/i18n/l10n/da.ftl.json b/src/i18n/l10n/da.ftl.json index 8c328af14..ebebcc11c 100644 --- a/src/i18n/l10n/da.ftl.json +++ b/src/i18n/l10n/da.ftl.json @@ -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", diff --git a/src/i18n/l10n/de.ftl b/src/i18n/l10n/de.ftl index 7da97ad4a..6c8b1083b 100644 --- a/src/i18n/l10n/de.ftl +++ b/src/i18n/l10n/de.ftl @@ -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 diff --git a/src/i18n/l10n/de.ftl.json b/src/i18n/l10n/de.ftl.json index a40af75e8..482a9e66e 100644 --- a/src/i18n/l10n/de.ftl.json +++ b/src/i18n/l10n/de.ftl.json @@ -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", diff --git a/src/i18n/l10n/el.ftl b/src/i18n/l10n/el.ftl index 7b48dbb3f..596fca0b0 100644 --- a/src/i18n/l10n/el.ftl +++ b/src/i18n/l10n/el.ftl @@ -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 diff --git a/src/i18n/l10n/el.ftl.json b/src/i18n/l10n/el.ftl.json index 86c246c03..5d335777f 100644 --- a/src/i18n/l10n/el.ftl.json +++ b/src/i18n/l10n/el.ftl.json @@ -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", diff --git a/src/i18n/l10n/en-GB.ftl b/src/i18n/l10n/en-GB.ftl index 16234914c..1ee4c83f6 100644 --- a/src/i18n/l10n/en-GB.ftl +++ b/src/i18n/l10n/en-GB.ftl @@ -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 diff --git a/src/i18n/l10n/en-GB.ftl.json b/src/i18n/l10n/en-GB.ftl.json index 391711a2a..490584301 100644 --- a/src/i18n/l10n/en-GB.ftl.json +++ b/src/i18n/l10n/en-GB.ftl.json @@ -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", diff --git a/src/i18n/l10n/en-NZ.ftl b/src/i18n/l10n/en-NZ.ftl index 16234914c..1ee4c83f6 100644 --- a/src/i18n/l10n/en-NZ.ftl +++ b/src/i18n/l10n/en-NZ.ftl @@ -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 diff --git a/src/i18n/l10n/en-NZ.ftl.json b/src/i18n/l10n/en-NZ.ftl.json index 391711a2a..490584301 100644 --- a/src/i18n/l10n/en-NZ.ftl.json +++ b/src/i18n/l10n/en-NZ.ftl.json @@ -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", diff --git a/src/i18n/l10n/eo.ftl b/src/i18n/l10n/eo.ftl index 3764c2278..da8af1967 100644 --- a/src/i18n/l10n/eo.ftl +++ b/src/i18n/l10n/eo.ftl @@ -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 diff --git a/src/i18n/l10n/eo.ftl.json b/src/i18n/l10n/eo.ftl.json index aa5eff828..72abc2125 100644 --- a/src/i18n/l10n/eo.ftl.json +++ b/src/i18n/l10n/eo.ftl.json @@ -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", diff --git a/src/i18n/l10n/es-AR.ftl b/src/i18n/l10n/es-AR.ftl index 9fb2a292a..832f7d1ea 100644 --- a/src/i18n/l10n/es-AR.ftl +++ b/src/i18n/l10n/es-AR.ftl @@ -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 diff --git a/src/i18n/l10n/es-AR.ftl.json b/src/i18n/l10n/es-AR.ftl.json index 16473bcd4..6233aea52 100644 --- a/src/i18n/l10n/es-AR.ftl.json +++ b/src/i18n/l10n/es-AR.ftl.json @@ -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", diff --git a/src/i18n/l10n/es-CO.ftl b/src/i18n/l10n/es-CO.ftl index 1bda4c274..27927e196 100644 --- a/src/i18n/l10n/es-CO.ftl +++ b/src/i18n/l10n/es-CO.ftl @@ -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 diff --git a/src/i18n/l10n/es-CO.ftl.json b/src/i18n/l10n/es-CO.ftl.json index 952ad0a85..02c119f9b 100644 --- a/src/i18n/l10n/es-CO.ftl.json +++ b/src/i18n/l10n/es-CO.ftl.json @@ -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", diff --git a/src/i18n/l10n/es-CR.ftl b/src/i18n/l10n/es-CR.ftl index bba2113d6..18b88f794 100644 --- a/src/i18n/l10n/es-CR.ftl +++ b/src/i18n/l10n/es-CR.ftl @@ -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 diff --git a/src/i18n/l10n/es-CR.ftl.json b/src/i18n/l10n/es-CR.ftl.json index b9d1281b4..ca11c53d4 100644 --- a/src/i18n/l10n/es-CR.ftl.json +++ b/src/i18n/l10n/es-CR.ftl.json @@ -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", diff --git a/src/i18n/l10n/es-MX.ftl b/src/i18n/l10n/es-MX.ftl index 5526a43d8..59b7c593e 100644 --- a/src/i18n/l10n/es-MX.ftl +++ b/src/i18n/l10n/es-MX.ftl @@ -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 diff --git a/src/i18n/l10n/es-MX.ftl.json b/src/i18n/l10n/es-MX.ftl.json index ed1c8e572..572e7b2e2 100644 --- a/src/i18n/l10n/es-MX.ftl.json +++ b/src/i18n/l10n/es-MX.ftl.json @@ -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", diff --git a/src/i18n/l10n/es.ftl b/src/i18n/l10n/es.ftl index c89ead4d8..353f44317 100644 --- a/src/i18n/l10n/es.ftl +++ b/src/i18n/l10n/es.ftl @@ -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 diff --git a/src/i18n/l10n/es.ftl.json b/src/i18n/l10n/es.ftl.json index ddcd21db3..75f8acb67 100644 --- a/src/i18n/l10n/es.ftl.json +++ b/src/i18n/l10n/es.ftl.json @@ -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", diff --git a/src/i18n/l10n/et.ftl b/src/i18n/l10n/et.ftl index add2f99cb..ad7f85222 100644 --- a/src/i18n/l10n/et.ftl +++ b/src/i18n/l10n/et.ftl @@ -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 diff --git a/src/i18n/l10n/et.ftl.json b/src/i18n/l10n/et.ftl.json index 93bbcf11b..1ccfd707b 100644 --- a/src/i18n/l10n/et.ftl.json +++ b/src/i18n/l10n/et.ftl.json @@ -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", diff --git a/src/i18n/l10n/eu.ftl b/src/i18n/l10n/eu.ftl index a1db927cf..ca6860cce 100644 --- a/src/i18n/l10n/eu.ftl +++ b/src/i18n/l10n/eu.ftl @@ -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 diff --git a/src/i18n/l10n/eu.ftl.json b/src/i18n/l10n/eu.ftl.json index 32ba7cb17..9d1695d95 100644 --- a/src/i18n/l10n/eu.ftl.json +++ b/src/i18n/l10n/eu.ftl.json @@ -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", diff --git a/src/i18n/l10n/fa.ftl b/src/i18n/l10n/fa.ftl index 2a942340c..b5bb146ef 100644 --- a/src/i18n/l10n/fa.ftl +++ b/src/i18n/l10n/fa.ftl @@ -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 diff --git a/src/i18n/l10n/fa.ftl.json b/src/i18n/l10n/fa.ftl.json index d9bfa1bff..efe6a739a 100644 --- a/src/i18n/l10n/fa.ftl.json +++ b/src/i18n/l10n/fa.ftl.json @@ -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", diff --git a/src/i18n/l10n/fi.ftl b/src/i18n/l10n/fi.ftl index 76e09d2d3..7f21ac03e 100644 --- a/src/i18n/l10n/fi.ftl +++ b/src/i18n/l10n/fi.ftl @@ -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. diff --git a/src/i18n/l10n/fi.ftl.json b/src/i18n/l10n/fi.ftl.json index da76f5323..f2dd90d25 100644 --- a/src/i18n/l10n/fi.ftl.json +++ b/src/i18n/l10n/fi.ftl.json @@ -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.", diff --git a/src/i18n/l10n/fil.ftl b/src/i18n/l10n/fil.ftl index 72117054a..f3ce7d92a 100644 --- a/src/i18n/l10n/fil.ftl +++ b/src/i18n/l10n/fil.ftl @@ -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 diff --git a/src/i18n/l10n/fil.ftl.json b/src/i18n/l10n/fil.ftl.json index 5138f7e10..35341bca0 100644 --- a/src/i18n/l10n/fil.ftl.json +++ b/src/i18n/l10n/fil.ftl.json @@ -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", diff --git a/src/i18n/l10n/fo.ftl b/src/i18n/l10n/fo.ftl index 1e13b2d89..97a187d25 100644 --- a/src/i18n/l10n/fo.ftl +++ b/src/i18n/l10n/fo.ftl @@ -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 diff --git a/src/i18n/l10n/fo.ftl.json b/src/i18n/l10n/fo.ftl.json index f0732adc8..c3d97a2bc 100644 --- a/src/i18n/l10n/fo.ftl.json +++ b/src/i18n/l10n/fo.ftl.json @@ -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", diff --git a/src/i18n/l10n/fr-CA.ftl b/src/i18n/l10n/fr-CA.ftl index 18fd0a748..05a6de934 100644 --- a/src/i18n/l10n/fr-CA.ftl +++ b/src/i18n/l10n/fr-CA.ftl @@ -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 diff --git a/src/i18n/l10n/fr-CA.ftl.json b/src/i18n/l10n/fr-CA.ftl.json index 4bec8bedc..a58a2dc70 100644 --- a/src/i18n/l10n/fr-CA.ftl.json +++ b/src/i18n/l10n/fr-CA.ftl.json @@ -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", diff --git a/src/i18n/l10n/fr.ftl b/src/i18n/l10n/fr.ftl index 09d33f774..d281bb4ad 100644 --- a/src/i18n/l10n/fr.ftl +++ b/src/i18n/l10n/fr.ftl @@ -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 diff --git a/src/i18n/l10n/fr.ftl.json b/src/i18n/l10n/fr.ftl.json index bc695cdca..51208db83 100644 --- a/src/i18n/l10n/fr.ftl.json +++ b/src/i18n/l10n/fr.ftl.json @@ -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", diff --git a/src/i18n/l10n/gd.ftl b/src/i18n/l10n/gd.ftl index 26531830f..068c02feb 100644 --- a/src/i18n/l10n/gd.ftl +++ b/src/i18n/l10n/gd.ftl @@ -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 diff --git a/src/i18n/l10n/gd.ftl.json b/src/i18n/l10n/gd.ftl.json index b8cd3717c..af673dd97 100644 --- a/src/i18n/l10n/gd.ftl.json +++ b/src/i18n/l10n/gd.ftl.json @@ -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", diff --git a/src/i18n/l10n/gl.ftl b/src/i18n/l10n/gl.ftl index a0ce3beda..e05c7113e 100644 --- a/src/i18n/l10n/gl.ftl +++ b/src/i18n/l10n/gl.ftl @@ -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 diff --git a/src/i18n/l10n/gl.ftl.json b/src/i18n/l10n/gl.ftl.json index a27ce10a7..a5954c82c 100644 --- a/src/i18n/l10n/gl.ftl.json +++ b/src/i18n/l10n/gl.ftl.json @@ -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", diff --git a/src/i18n/l10n/gu.ftl b/src/i18n/l10n/gu.ftl index 1e13b2d89..97a187d25 100644 --- a/src/i18n/l10n/gu.ftl +++ b/src/i18n/l10n/gu.ftl @@ -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 diff --git a/src/i18n/l10n/gu.ftl.json b/src/i18n/l10n/gu.ftl.json index f0732adc8..c3d97a2bc 100644 --- a/src/i18n/l10n/gu.ftl.json +++ b/src/i18n/l10n/gu.ftl.json @@ -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", diff --git a/src/i18n/l10n/he.ftl b/src/i18n/l10n/he.ftl index e7287fb09..c33ba6d6f 100644 --- a/src/i18n/l10n/he.ftl +++ b/src/i18n/l10n/he.ftl @@ -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 diff --git a/src/i18n/l10n/he.ftl.json b/src/i18n/l10n/he.ftl.json index bb7dc5bba..f56193403 100644 --- a/src/i18n/l10n/he.ftl.json +++ b/src/i18n/l10n/he.ftl.json @@ -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", diff --git a/src/i18n/l10n/hi.ftl b/src/i18n/l10n/hi.ftl index 904e43cd3..ea07376d8 100644 --- a/src/i18n/l10n/hi.ftl +++ b/src/i18n/l10n/hi.ftl @@ -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 diff --git a/src/i18n/l10n/hi.ftl.json b/src/i18n/l10n/hi.ftl.json index 01c53d957..1eac1988d 100644 --- a/src/i18n/l10n/hi.ftl.json +++ b/src/i18n/l10n/hi.ftl.json @@ -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", diff --git a/src/i18n/l10n/hr.ftl b/src/i18n/l10n/hr.ftl index c5508de5c..6a3d352dd 100644 --- a/src/i18n/l10n/hr.ftl +++ b/src/i18n/l10n/hr.ftl @@ -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 diff --git a/src/i18n/l10n/hr.ftl.json b/src/i18n/l10n/hr.ftl.json index 2da9797de..91549ccc2 100644 --- a/src/i18n/l10n/hr.ftl.json +++ b/src/i18n/l10n/hr.ftl.json @@ -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", diff --git a/src/i18n/l10n/hu.ftl b/src/i18n/l10n/hu.ftl index feff208c0..ecb31ad85 100644 --- a/src/i18n/l10n/hu.ftl +++ b/src/i18n/l10n/hu.ftl @@ -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 diff --git a/src/i18n/l10n/hu.ftl.json b/src/i18n/l10n/hu.ftl.json index e5d10765b..74e48ad31 100644 --- a/src/i18n/l10n/hu.ftl.json +++ b/src/i18n/l10n/hu.ftl.json @@ -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", diff --git a/src/i18n/l10n/hy.ftl b/src/i18n/l10n/hy.ftl index 1e13b2d89..97a187d25 100644 --- a/src/i18n/l10n/hy.ftl +++ b/src/i18n/l10n/hy.ftl @@ -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 diff --git a/src/i18n/l10n/hy.ftl.json b/src/i18n/l10n/hy.ftl.json index f0732adc8..c3d97a2bc 100644 --- a/src/i18n/l10n/hy.ftl.json +++ b/src/i18n/l10n/hy.ftl.json @@ -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", diff --git a/src/i18n/l10n/id.ftl b/src/i18n/l10n/id.ftl index cb6cbf891..a0743e0be 100644 --- a/src/i18n/l10n/id.ftl +++ b/src/i18n/l10n/id.ftl @@ -31,7 +31,6 @@ Add-Location = Tambah Lokasi ADD-LOCATION-FOR-BETTER-IDS = TAMBAHKAN LOKASI SUPAYA ID-NYA LEBIH BAIK Add-location-to-refresh-suggestions = Tambahkan lokasi untuk menyegarkan rekomendasi Add-observations = Tambah pengamatan -ADD-OPTIONAL-COMMENT = TAMBAH KOMENTAR OPSIONAL Add-optional-notes = Tambahkan catatan opsional Add-to-Projects = Tambahkan ke Proyek ADD-TO-PROJECTS = TAMBAHKAN KE PROYEK diff --git a/src/i18n/l10n/id.ftl.json b/src/i18n/l10n/id.ftl.json index 16e8dba09..4983cdcff 100644 --- a/src/i18n/l10n/id.ftl.json +++ b/src/i18n/l10n/id.ftl.json @@ -25,7 +25,6 @@ "ADD-LOCATION-FOR-BETTER-IDS": "TAMBAHKAN LOKASI SUPAYA ID-NYA LEBIH BAIK", "Add-location-to-refresh-suggestions": "Tambahkan lokasi untuk menyegarkan rekomendasi", "Add-observations": "Tambah pengamatan", - "ADD-OPTIONAL-COMMENT": "TAMBAH KOMENTAR OPSIONAL", "Add-optional-notes": "Tambahkan catatan opsional", "Add-to-Projects": "Tambahkan ke Proyek", "ADD-TO-PROJECTS": "TAMBAHKAN KE PROYEK", diff --git a/src/i18n/l10n/it.ftl b/src/i18n/l10n/it.ftl index 9e30ea806..6a5b2a45f 100644 --- a/src/i18n/l10n/it.ftl +++ b/src/i18n/l10n/it.ftl @@ -31,7 +31,6 @@ Add-Location = Aggiungi Posizione ADD-LOCATION-FOR-BETTER-IDS = AGGIUNGI LA POSIZIONE MIGLIORI ID Add-location-to-refresh-suggestions = Aggiungi posizione per aggiornare i suggerimenti Add-observations = Aggiungere osservazioni -ADD-OPTIONAL-COMMENT = AGGIUNGI COMMENTO FACOLTATIVO Add-optional-notes = Aggiungi note opzionali Add-to-Projects = Add to Projects ADD-TO-PROJECTS = ADD TO PROJECTS diff --git a/src/i18n/l10n/it.ftl.json b/src/i18n/l10n/it.ftl.json index 397450705..1a7601185 100644 --- a/src/i18n/l10n/it.ftl.json +++ b/src/i18n/l10n/it.ftl.json @@ -25,7 +25,6 @@ "ADD-LOCATION-FOR-BETTER-IDS": "AGGIUNGI LA POSIZIONE MIGLIORI ID", "Add-location-to-refresh-suggestions": "Aggiungi posizione per aggiornare i suggerimenti", "Add-observations": "Aggiungere osservazioni", - "ADD-OPTIONAL-COMMENT": "AGGIUNGI COMMENTO FACOLTATIVO", "Add-optional-notes": "Aggiungi note opzionali", "Add-to-Projects": "Add to Projects", "ADD-TO-PROJECTS": "ADD TO PROJECTS", diff --git a/src/i18n/l10n/ja.ftl b/src/i18n/l10n/ja.ftl index 6124836c2..3cf7c5348 100644 --- a/src/i18n/l10n/ja.ftl +++ b/src/i18n/l10n/ja.ftl @@ -31,7 +31,6 @@ Add-Location = 場所を追加 ADD-LOCATION-FOR-BETTER-IDS = より良いIDのために場所を追加 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 diff --git a/src/i18n/l10n/ja.ftl.json b/src/i18n/l10n/ja.ftl.json index b375da7ea..0290eeb76 100644 --- a/src/i18n/l10n/ja.ftl.json +++ b/src/i18n/l10n/ja.ftl.json @@ -25,7 +25,6 @@ "ADD-LOCATION-FOR-BETTER-IDS": "より良いIDのために場所を追加", "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", diff --git a/src/i18n/l10n/ka.ftl b/src/i18n/l10n/ka.ftl index b1ee97df5..1e1c4d5ed 100644 --- a/src/i18n/l10n/ka.ftl +++ b/src/i18n/l10n/ka.ftl @@ -31,7 +31,6 @@ Add-Location = ადგილმდებარეობის დამატ ADD-LOCATION-FOR-BETTER-IDS = უკეთესი ID-ებისთვის დაამატეთ ადგილმდებარეობა 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 diff --git a/src/i18n/l10n/ka.ftl.json b/src/i18n/l10n/ka.ftl.json index 426f864ef..8f13b037a 100644 --- a/src/i18n/l10n/ka.ftl.json +++ b/src/i18n/l10n/ka.ftl.json @@ -25,7 +25,6 @@ "ADD-LOCATION-FOR-BETTER-IDS": "უკეთესი ID-ებისთვის დაამატეთ ადგილმდებარეობა", "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", diff --git a/src/i18n/l10n/kk.ftl b/src/i18n/l10n/kk.ftl index 146dee7bf..ef93d0799 100644 --- a/src/i18n/l10n/kk.ftl +++ b/src/i18n/l10n/kk.ftl @@ -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 diff --git a/src/i18n/l10n/kk.ftl.json b/src/i18n/l10n/kk.ftl.json index b8ba41ca3..cbdbba5ad 100644 --- a/src/i18n/l10n/kk.ftl.json +++ b/src/i18n/l10n/kk.ftl.json @@ -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", diff --git a/src/i18n/l10n/kl.ftl b/src/i18n/l10n/kl.ftl index 1e13b2d89..97a187d25 100644 --- a/src/i18n/l10n/kl.ftl +++ b/src/i18n/l10n/kl.ftl @@ -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 diff --git a/src/i18n/l10n/kl.ftl.json b/src/i18n/l10n/kl.ftl.json index f0732adc8..c3d97a2bc 100644 --- a/src/i18n/l10n/kl.ftl.json +++ b/src/i18n/l10n/kl.ftl.json @@ -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", diff --git a/src/i18n/l10n/kn.ftl b/src/i18n/l10n/kn.ftl index e0a3fcf1c..307bb9fc2 100644 --- a/src/i18n/l10n/kn.ftl +++ b/src/i18n/l10n/kn.ftl @@ -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 diff --git a/src/i18n/l10n/kn.ftl.json b/src/i18n/l10n/kn.ftl.json index 8f58275a7..f16e28afa 100644 --- a/src/i18n/l10n/kn.ftl.json +++ b/src/i18n/l10n/kn.ftl.json @@ -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", diff --git a/src/i18n/l10n/ko.ftl b/src/i18n/l10n/ko.ftl index 9dd9093ac..6c9ceb987 100644 --- a/src/i18n/l10n/ko.ftl +++ b/src/i18n/l10n/ko.ftl @@ -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 diff --git a/src/i18n/l10n/ko.ftl.json b/src/i18n/l10n/ko.ftl.json index 0304649d2..f8bf48228 100644 --- a/src/i18n/l10n/ko.ftl.json +++ b/src/i18n/l10n/ko.ftl.json @@ -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", diff --git a/src/i18n/l10n/lb.ftl b/src/i18n/l10n/lb.ftl index 40153eceb..00ce0cece 100644 --- a/src/i18n/l10n/lb.ftl +++ b/src/i18n/l10n/lb.ftl @@ -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 diff --git a/src/i18n/l10n/lb.ftl.json b/src/i18n/l10n/lb.ftl.json index 2224c8727..650a5df2a 100644 --- a/src/i18n/l10n/lb.ftl.json +++ b/src/i18n/l10n/lb.ftl.json @@ -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", diff --git a/src/i18n/l10n/lt.ftl b/src/i18n/l10n/lt.ftl index 93f4e410f..7e3d38c5d 100644 --- a/src/i18n/l10n/lt.ftl +++ b/src/i18n/l10n/lt.ftl @@ -31,7 +31,6 @@ Add-Location = Add Location ADD-LOCATION-FOR-BETTER-IDS = GERESNĖMS ID PRIDĖTI VIETĄ Add-location-to-refresh-suggestions = Pridėti vietą pasiūlymams atnaujinti 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 diff --git a/src/i18n/l10n/lt.ftl.json b/src/i18n/l10n/lt.ftl.json index 90b172a29..d7b4a370d 100644 --- a/src/i18n/l10n/lt.ftl.json +++ b/src/i18n/l10n/lt.ftl.json @@ -25,7 +25,6 @@ "ADD-LOCATION-FOR-BETTER-IDS": "GERESNĖMS ID PRIDĖTI VIETĄ", "Add-location-to-refresh-suggestions": "Pridėti vietą pasiūlymams atnaujinti", "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", diff --git a/src/i18n/l10n/lv.ftl b/src/i18n/l10n/lv.ftl index 97fc08e86..9ea42269b 100644 --- a/src/i18n/l10n/lv.ftl +++ b/src/i18n/l10n/lv.ftl @@ -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 diff --git a/src/i18n/l10n/lv.ftl.json b/src/i18n/l10n/lv.ftl.json index 954e4d165..84f526ae2 100644 --- a/src/i18n/l10n/lv.ftl.json +++ b/src/i18n/l10n/lv.ftl.json @@ -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", diff --git a/src/i18n/l10n/mi.ftl b/src/i18n/l10n/mi.ftl index dc225ebc4..44c9e3ed8 100644 --- a/src/i18n/l10n/mi.ftl +++ b/src/i18n/l10n/mi.ftl @@ -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 diff --git a/src/i18n/l10n/mi.ftl.json b/src/i18n/l10n/mi.ftl.json index 1c47fae69..bccaa7bef 100644 --- a/src/i18n/l10n/mi.ftl.json +++ b/src/i18n/l10n/mi.ftl.json @@ -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", diff --git a/src/i18n/l10n/mk.ftl b/src/i18n/l10n/mk.ftl index f9e48011f..c0878bf51 100644 --- a/src/i18n/l10n/mk.ftl +++ b/src/i18n/l10n/mk.ftl @@ -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 diff --git a/src/i18n/l10n/mk.ftl.json b/src/i18n/l10n/mk.ftl.json index 0a8ee6664..7931bbfaf 100644 --- a/src/i18n/l10n/mk.ftl.json +++ b/src/i18n/l10n/mk.ftl.json @@ -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", diff --git a/src/i18n/l10n/ml.ftl b/src/i18n/l10n/ml.ftl index 3f0283b2a..296381b10 100644 --- a/src/i18n/l10n/ml.ftl +++ b/src/i18n/l10n/ml.ftl @@ -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 diff --git a/src/i18n/l10n/ml.ftl.json b/src/i18n/l10n/ml.ftl.json index ce818a1f9..d7a29ada9 100644 --- a/src/i18n/l10n/ml.ftl.json +++ b/src/i18n/l10n/ml.ftl.json @@ -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", diff --git a/src/i18n/l10n/mr.ftl b/src/i18n/l10n/mr.ftl index 8fa8dfb16..814d76a0c 100644 --- a/src/i18n/l10n/mr.ftl +++ b/src/i18n/l10n/mr.ftl @@ -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 diff --git a/src/i18n/l10n/mr.ftl.json b/src/i18n/l10n/mr.ftl.json index 3b3ab6b87..e66caf30a 100644 --- a/src/i18n/l10n/mr.ftl.json +++ b/src/i18n/l10n/mr.ftl.json @@ -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", diff --git a/src/i18n/l10n/ms.ftl b/src/i18n/l10n/ms.ftl index 574c3d76b..e000265c6 100644 --- a/src/i18n/l10n/ms.ftl +++ b/src/i18n/l10n/ms.ftl @@ -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 diff --git a/src/i18n/l10n/ms.ftl.json b/src/i18n/l10n/ms.ftl.json index 0d57d9da0..54d12ba2a 100644 --- a/src/i18n/l10n/ms.ftl.json +++ b/src/i18n/l10n/ms.ftl.json @@ -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", diff --git a/src/i18n/l10n/nb.ftl b/src/i18n/l10n/nb.ftl index b421cc92a..00073de23 100644 --- a/src/i18n/l10n/nb.ftl +++ b/src/i18n/l10n/nb.ftl @@ -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 diff --git a/src/i18n/l10n/nb.ftl.json b/src/i18n/l10n/nb.ftl.json index 1dfa45499..ea0c949c9 100644 --- a/src/i18n/l10n/nb.ftl.json +++ b/src/i18n/l10n/nb.ftl.json @@ -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", diff --git a/src/i18n/l10n/nl.ftl b/src/i18n/l10n/nl.ftl index 836a68d97..6fcf2c84a 100644 --- a/src/i18n/l10n/nl.ftl +++ b/src/i18n/l10n/nl.ftl @@ -37,7 +37,6 @@ Add-Location = Locatie toevoegen ADD-LOCATION-FOR-BETTER-IDS = VOEG LOCATIE TOE VOOR BETERE DETERMINATIES Add-location-to-refresh-suggestions = Voeg locatie toe om voorstellen te verversen Add-observations = Waarnemingen toevoegen -ADD-OPTIONAL-COMMENT = OPTIONEEL COMMENTAAR TOEVOEGEN Add-optional-notes = Optionele notities toevoegen Add-to-Projects = Voeg toe aan projecten ADD-TO-PROJECTS = VOEG TOE AAN PROJECTEN diff --git a/src/i18n/l10n/nl.ftl.json b/src/i18n/l10n/nl.ftl.json index 5db3432e7..fab4cdfd7 100644 --- a/src/i18n/l10n/nl.ftl.json +++ b/src/i18n/l10n/nl.ftl.json @@ -25,7 +25,6 @@ "ADD-LOCATION-FOR-BETTER-IDS": "VOEG LOCATIE TOE VOOR BETERE DETERMINATIES", "Add-location-to-refresh-suggestions": "Voeg locatie toe om voorstellen te verversen", "Add-observations": "Waarnemingen toevoegen", - "ADD-OPTIONAL-COMMENT": "OPTIONEEL COMMENTAAR TOEVOEGEN", "Add-optional-notes": "Optionele notities toevoegen", "Add-to-Projects": "Voeg toe aan projecten", "ADD-TO-PROJECTS": "VOEG TOE AAN PROJECTEN", diff --git a/src/i18n/l10n/pa.ftl b/src/i18n/l10n/pa.ftl index 6ac7be1e3..bc293972b 100644 --- a/src/i18n/l10n/pa.ftl +++ b/src/i18n/l10n/pa.ftl @@ -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 diff --git a/src/i18n/l10n/pa.ftl.json b/src/i18n/l10n/pa.ftl.json index 3bd51893f..cb0ff3e19 100644 --- a/src/i18n/l10n/pa.ftl.json +++ b/src/i18n/l10n/pa.ftl.json @@ -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", diff --git a/src/i18n/l10n/pl.ftl b/src/i18n/l10n/pl.ftl index 4afe83f54..af0ed5fac 100644 --- a/src/i18n/l10n/pl.ftl +++ b/src/i18n/l10n/pl.ftl @@ -31,7 +31,6 @@ Add-Location = Dodaj lokalizację ADD-LOCATION-FOR-BETTER-IDS = DODAJ LOKALIZACJĘ, ABY UZYSKAĆ LEPSZE WYNIKI Add-location-to-refresh-suggestions = Dodaj lokalizację, aby odświeżyć sugestie Add-observations = Dodaj obserwacje -ADD-OPTIONAL-COMMENT = DODAJ OPCJONALNY KOMENTARZ Add-optional-notes = Dodaj opcjonalne notatki Add-to-Projects = Add to Projects ADD-TO-PROJECTS = ADD TO PROJECTS diff --git a/src/i18n/l10n/pl.ftl.json b/src/i18n/l10n/pl.ftl.json index 62a7595a3..246a62426 100644 --- a/src/i18n/l10n/pl.ftl.json +++ b/src/i18n/l10n/pl.ftl.json @@ -25,7 +25,6 @@ "ADD-LOCATION-FOR-BETTER-IDS": "DODAJ LOKALIZACJĘ, ABY UZYSKAĆ LEPSZE WYNIKI", "Add-location-to-refresh-suggestions": "Dodaj lokalizację, aby odświeżyć sugestie", "Add-observations": "Dodaj obserwacje", - "ADD-OPTIONAL-COMMENT": "DODAJ OPCJONALNY KOMENTARZ", "Add-optional-notes": "Dodaj opcjonalne notatki", "Add-to-Projects": "Add to Projects", "ADD-TO-PROJECTS": "ADD TO PROJECTS", diff --git a/src/i18n/l10n/pt-BR.ftl b/src/i18n/l10n/pt-BR.ftl index 20b584612..ea2bb0fc2 100644 --- a/src/i18n/l10n/pt-BR.ftl +++ b/src/i18n/l10n/pt-BR.ftl @@ -31,7 +31,6 @@ Add-Location = Adicionar Localização ADD-LOCATION-FOR-BETTER-IDS = ADICIONAR LOCAL PARA MELHORES IDS Add-location-to-refresh-suggestions = Adicionar localização para atualizar as sugestões Add-observations = Adicionar observações -ADD-OPTIONAL-COMMENT = Adicionar COMENTÁRIO OPCIONAL Add-optional-notes = Adicionar notas opcionais Add-to-Projects = Add to Projects ADD-TO-PROJECTS = ADD TO PROJECTS diff --git a/src/i18n/l10n/pt-BR.ftl.json b/src/i18n/l10n/pt-BR.ftl.json index 558baa1a5..661a958f4 100644 --- a/src/i18n/l10n/pt-BR.ftl.json +++ b/src/i18n/l10n/pt-BR.ftl.json @@ -25,7 +25,6 @@ "ADD-LOCATION-FOR-BETTER-IDS": "ADICIONAR LOCAL PARA MELHORES IDS", "Add-location-to-refresh-suggestions": "Adicionar localização para atualizar as sugestões", "Add-observations": "Adicionar observações", - "ADD-OPTIONAL-COMMENT": "Adicionar COMENTÁRIO OPCIONAL", "Add-optional-notes": "Adicionar notas opcionais", "Add-to-Projects": "Add to Projects", "ADD-TO-PROJECTS": "ADD TO PROJECTS", diff --git a/src/i18n/l10n/pt.ftl b/src/i18n/l10n/pt.ftl index 2f4c3bfb8..b1b67c88a 100644 --- a/src/i18n/l10n/pt.ftl +++ b/src/i18n/l10n/pt.ftl @@ -31,7 +31,6 @@ Add-Location = Adicionar localização ADD-LOCATION-FOR-BETTER-IDS = ADICIONAR LOCALIZAÇÃO PARA MELHORES IDS Add-location-to-refresh-suggestions = Adicionar localização para atualizar sugestões Add-observations = Adicionar observações -ADD-OPTIONAL-COMMENT = ADICIONAR COMENTÁRIO OPCIONAL Add-optional-notes = Adicionar notas opcionais Add-to-Projects = Add to Projects ADD-TO-PROJECTS = ADD TO PROJECTS diff --git a/src/i18n/l10n/pt.ftl.json b/src/i18n/l10n/pt.ftl.json index 56ed283e2..c5d9fa8a9 100644 --- a/src/i18n/l10n/pt.ftl.json +++ b/src/i18n/l10n/pt.ftl.json @@ -25,7 +25,6 @@ "ADD-LOCATION-FOR-BETTER-IDS": "ADICIONAR LOCALIZAÇÃO PARA MELHORES IDS", "Add-location-to-refresh-suggestions": "Adicionar localização para atualizar sugestões", "Add-observations": "Adicionar observações", - "ADD-OPTIONAL-COMMENT": "ADICIONAR COMENTÁRIO OPCIONAL", "Add-optional-notes": "Adicionar notas opcionais", "Add-to-Projects": "Add to Projects", "ADD-TO-PROJECTS": "ADD TO PROJECTS", diff --git a/src/i18n/l10n/ro.ftl b/src/i18n/l10n/ro.ftl index d37546b30..fe0ffda59 100644 --- a/src/i18n/l10n/ro.ftl +++ b/src/i18n/l10n/ro.ftl @@ -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 diff --git a/src/i18n/l10n/ro.ftl.json b/src/i18n/l10n/ro.ftl.json index cb3a8f168..c97acaf70 100644 --- a/src/i18n/l10n/ro.ftl.json +++ b/src/i18n/l10n/ro.ftl.json @@ -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", diff --git a/src/i18n/l10n/ru.ftl b/src/i18n/l10n/ru.ftl index 837f56622..2bb9f726d 100644 --- a/src/i18n/l10n/ru.ftl +++ b/src/i18n/l10n/ru.ftl @@ -34,7 +34,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 diff --git a/src/i18n/l10n/ru.ftl.json b/src/i18n/l10n/ru.ftl.json index fa1a4947e..a2d9e763e 100644 --- a/src/i18n/l10n/ru.ftl.json +++ b/src/i18n/l10n/ru.ftl.json @@ -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", diff --git a/src/i18n/l10n/sat.ftl b/src/i18n/l10n/sat.ftl index 5f371ed64..45bade596 100644 --- a/src/i18n/l10n/sat.ftl +++ b/src/i18n/l10n/sat.ftl @@ -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 diff --git a/src/i18n/l10n/sat.ftl.json b/src/i18n/l10n/sat.ftl.json index ffd300192..ab5ef4b30 100644 --- a/src/i18n/l10n/sat.ftl.json +++ b/src/i18n/l10n/sat.ftl.json @@ -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", diff --git a/src/i18n/l10n/si.ftl b/src/i18n/l10n/si.ftl index d39898035..1fa923470 100644 --- a/src/i18n/l10n/si.ftl +++ b/src/i18n/l10n/si.ftl @@ -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 diff --git a/src/i18n/l10n/si.ftl.json b/src/i18n/l10n/si.ftl.json index 340687375..201d441c6 100644 --- a/src/i18n/l10n/si.ftl.json +++ b/src/i18n/l10n/si.ftl.json @@ -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", diff --git a/src/i18n/l10n/sk.ftl b/src/i18n/l10n/sk.ftl index 2de700054..3350b7d9d 100644 --- a/src/i18n/l10n/sk.ftl +++ b/src/i18n/l10n/sk.ftl @@ -31,7 +31,6 @@ Add-Location = Pridať umiestnenie ADD-LOCATION-FOR-BETTER-IDS = PRIDAŤ POLOHU PRE LEPŠIE ID Add-location-to-refresh-suggestions = Pridať umiestnenie na obnovu návrhov Add-observations = Pridať pozorovanie -ADD-OPTIONAL-COMMENT = PRIDAŤ VOLITEĽNÝ KOMENTÁR Add-optional-notes = Pridať voliteľné poznámky Add-to-Projects = Add to Projects ADD-TO-PROJECTS = ADD TO PROJECTS diff --git a/src/i18n/l10n/sk.ftl.json b/src/i18n/l10n/sk.ftl.json index 3c67d1e3f..07a897e26 100644 --- a/src/i18n/l10n/sk.ftl.json +++ b/src/i18n/l10n/sk.ftl.json @@ -25,7 +25,6 @@ "ADD-LOCATION-FOR-BETTER-IDS": "PRIDAŤ POLOHU PRE LEPŠIE ID", "Add-location-to-refresh-suggestions": "Pridať umiestnenie na obnovu návrhov", "Add-observations": "Pridať pozorovanie", - "ADD-OPTIONAL-COMMENT": "PRIDAŤ VOLITEĽNÝ KOMENTÁR", "Add-optional-notes": "Pridať voliteľné poznámky", "Add-to-Projects": "Add to Projects", "ADD-TO-PROJECTS": "ADD TO PROJECTS", diff --git a/src/i18n/l10n/sl.ftl b/src/i18n/l10n/sl.ftl index 7c2a1d49f..0fc26217b 100644 --- a/src/i18n/l10n/sl.ftl +++ b/src/i18n/l10n/sl.ftl @@ -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 diff --git a/src/i18n/l10n/sl.ftl.json b/src/i18n/l10n/sl.ftl.json index 64ee775eb..bc008d765 100644 --- a/src/i18n/l10n/sl.ftl.json +++ b/src/i18n/l10n/sl.ftl.json @@ -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", diff --git a/src/i18n/l10n/sq.ftl b/src/i18n/l10n/sq.ftl index 2c7a2fc3a..2d17fe163 100644 --- a/src/i18n/l10n/sq.ftl +++ b/src/i18n/l10n/sq.ftl @@ -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 diff --git a/src/i18n/l10n/sq.ftl.json b/src/i18n/l10n/sq.ftl.json index 2bd81a852..2d7e6046b 100644 --- a/src/i18n/l10n/sq.ftl.json +++ b/src/i18n/l10n/sq.ftl.json @@ -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", diff --git a/src/i18n/l10n/sr.ftl b/src/i18n/l10n/sr.ftl index 8cbe11431..5a484b750 100644 --- a/src/i18n/l10n/sr.ftl +++ b/src/i18n/l10n/sr.ftl @@ -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 diff --git a/src/i18n/l10n/sr.ftl.json b/src/i18n/l10n/sr.ftl.json index ff7fb3d32..78b845a3e 100644 --- a/src/i18n/l10n/sr.ftl.json +++ b/src/i18n/l10n/sr.ftl.json @@ -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", diff --git a/src/i18n/l10n/sv.ftl b/src/i18n/l10n/sv.ftl index c241f57ae..53337d945 100644 --- a/src/i18n/l10n/sv.ftl +++ b/src/i18n/l10n/sv.ftl @@ -37,7 +37,6 @@ Add-Location = Lägg till plats ADD-LOCATION-FOR-BETTER-IDS = LÄGG TILL FYNDPLATS FÖR BÄTTRE BESTÄMNINGAR Add-location-to-refresh-suggestions = Lägg till fyndplats för nya förslag Add-observations = Lägg till fynd -ADD-OPTIONAL-COMMENT = LÄGG TILL EV. KOMMENTAR Add-optional-notes = Lägg till valfria anteckningar Add-to-Projects = Add to Projects ADD-TO-PROJECTS = ADD TO PROJECTS diff --git a/src/i18n/l10n/sv.ftl.json b/src/i18n/l10n/sv.ftl.json index 951f23d61..81e8d6cdf 100644 --- a/src/i18n/l10n/sv.ftl.json +++ b/src/i18n/l10n/sv.ftl.json @@ -25,7 +25,6 @@ "ADD-LOCATION-FOR-BETTER-IDS": "LÄGG TILL FYNDPLATS FÖR BÄTTRE BESTÄMNINGAR", "Add-location-to-refresh-suggestions": "Lägg till fyndplats för nya förslag", "Add-observations": "Lägg till fynd", - "ADD-OPTIONAL-COMMENT": "LÄGG TILL EV. KOMMENTAR", "Add-optional-notes": "Lägg till valfria anteckningar", "Add-to-Projects": "Add to Projects", "ADD-TO-PROJECTS": "ADD TO PROJECTS", diff --git a/src/i18n/l10n/sw.ftl b/src/i18n/l10n/sw.ftl index bd134f888..40ea8dce8 100644 --- a/src/i18n/l10n/sw.ftl +++ b/src/i18n/l10n/sw.ftl @@ -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 diff --git a/src/i18n/l10n/sw.ftl.json b/src/i18n/l10n/sw.ftl.json index 5838ef278..734a303e4 100644 --- a/src/i18n/l10n/sw.ftl.json +++ b/src/i18n/l10n/sw.ftl.json @@ -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", diff --git a/src/i18n/l10n/ta.ftl b/src/i18n/l10n/ta.ftl index 01e969b55..da5750655 100644 --- a/src/i18n/l10n/ta.ftl +++ b/src/i18n/l10n/ta.ftl @@ -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 diff --git a/src/i18n/l10n/ta.ftl.json b/src/i18n/l10n/ta.ftl.json index 2511af71c..c5a2b4599 100644 --- a/src/i18n/l10n/ta.ftl.json +++ b/src/i18n/l10n/ta.ftl.json @@ -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", diff --git a/src/i18n/l10n/te.ftl b/src/i18n/l10n/te.ftl index 298cb6cf1..550305e41 100644 --- a/src/i18n/l10n/te.ftl +++ b/src/i18n/l10n/te.ftl @@ -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 diff --git a/src/i18n/l10n/te.ftl.json b/src/i18n/l10n/te.ftl.json index cc14d0099..c907f77c1 100644 --- a/src/i18n/l10n/te.ftl.json +++ b/src/i18n/l10n/te.ftl.json @@ -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", diff --git a/src/i18n/l10n/th.ftl b/src/i18n/l10n/th.ftl index d1b7ca7ea..d6c1e69ab 100644 --- a/src/i18n/l10n/th.ftl +++ b/src/i18n/l10n/th.ftl @@ -31,7 +31,6 @@ 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-OPTIONAL-COMMENT = เพิ่มความคิดเห็นเพิ่มเติม Add-optional-notes = Add optional notes Add-to-Projects = Add to Projects ADD-TO-PROJECTS = ADD TO PROJECTS diff --git a/src/i18n/l10n/th.ftl.json b/src/i18n/l10n/th.ftl.json index 0935ce31e..b0579cd9b 100644 --- a/src/i18n/l10n/th.ftl.json +++ b/src/i18n/l10n/th.ftl.json @@ -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-OPTIONAL-COMMENT": "เพิ่มความคิดเห็นเพิ่มเติม", "Add-optional-notes": "Add optional notes", "Add-to-Projects": "Add to Projects", "ADD-TO-PROJECTS": "ADD TO PROJECTS", diff --git a/src/i18n/l10n/tl.ftl b/src/i18n/l10n/tl.ftl index 1e13b2d89..97a187d25 100644 --- a/src/i18n/l10n/tl.ftl +++ b/src/i18n/l10n/tl.ftl @@ -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 diff --git a/src/i18n/l10n/tl.ftl.json b/src/i18n/l10n/tl.ftl.json index f0732adc8..c3d97a2bc 100644 --- a/src/i18n/l10n/tl.ftl.json +++ b/src/i18n/l10n/tl.ftl.json @@ -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", diff --git a/src/i18n/l10n/tr.ftl b/src/i18n/l10n/tr.ftl index 23d0c77c4..185d2432d 100644 --- a/src/i18n/l10n/tr.ftl +++ b/src/i18n/l10n/tr.ftl @@ -31,7 +31,6 @@ Add-Location = Konum ekle ADD-LOCATION-FOR-BETTER-IDS = DAHA İYİ TANIMLAMALAR İÇİN KONUM EKLE Add-location-to-refresh-suggestions = Önerileri yenilemek için konum ekle Add-observations = Gözlemleri ekle -ADD-OPTIONAL-COMMENT = İSTEĞE BAĞLI YORUM EKLE Add-optional-notes = İsteğe bağlı not ekle Add-to-Projects = Projelere Ekle ADD-TO-PROJECTS = PROJELERE EKLE diff --git a/src/i18n/l10n/tr.ftl.json b/src/i18n/l10n/tr.ftl.json index de4d328ac..339d3a759 100644 --- a/src/i18n/l10n/tr.ftl.json +++ b/src/i18n/l10n/tr.ftl.json @@ -25,7 +25,6 @@ "ADD-LOCATION-FOR-BETTER-IDS": "DAHA İYİ TANIMLAMALAR İÇİN KONUM EKLE", "Add-location-to-refresh-suggestions": "Önerileri yenilemek için konum ekle", "Add-observations": "Gözlemleri ekle", - "ADD-OPTIONAL-COMMENT": "İSTEĞE BAĞLI YORUM EKLE", "Add-optional-notes": "İsteğe bağlı not ekle", "Add-to-Projects": "Projelere Ekle", "ADD-TO-PROJECTS": "PROJELERE EKLE", diff --git a/src/i18n/l10n/uk.ftl b/src/i18n/l10n/uk.ftl index 6225b3572..dd10c3221 100644 --- a/src/i18n/l10n/uk.ftl +++ b/src/i18n/l10n/uk.ftl @@ -31,7 +31,6 @@ 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-OPTIONAL-COMMENT = ДОДАТИ НЕОБОВ'ЯЗКОВИЙ КОМЕНТАР Add-optional-notes = Додати необов'язкові записи Add-to-Projects = Add to Projects ADD-TO-PROJECTS = ADD TO PROJECTS diff --git a/src/i18n/l10n/uk.ftl.json b/src/i18n/l10n/uk.ftl.json index c462fb875..f936481b8 100644 --- a/src/i18n/l10n/uk.ftl.json +++ b/src/i18n/l10n/uk.ftl.json @@ -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-OPTIONAL-COMMENT": "ДОДАТИ НЕОБОВ'ЯЗКОВИЙ КОМЕНТАР", "Add-optional-notes": "Додати необов'язкові записи", "Add-to-Projects": "Add to Projects", "ADD-TO-PROJECTS": "ADD TO PROJECTS", diff --git a/src/i18n/l10n/vi.ftl b/src/i18n/l10n/vi.ftl index 0011d5772..f210f81ec 100644 --- a/src/i18n/l10n/vi.ftl +++ b/src/i18n/l10n/vi.ftl @@ -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 diff --git a/src/i18n/l10n/vi.ftl.json b/src/i18n/l10n/vi.ftl.json index 993caa853..c4f92b19c 100644 --- a/src/i18n/l10n/vi.ftl.json +++ b/src/i18n/l10n/vi.ftl.json @@ -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", diff --git a/src/i18n/l10n/zh-CN.ftl b/src/i18n/l10n/zh-CN.ftl index cdf6600bd..2fd29cf7c 100644 --- a/src/i18n/l10n/zh-CN.ftl +++ b/src/i18n/l10n/zh-CN.ftl @@ -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 diff --git a/src/i18n/l10n/zh-CN.ftl.json b/src/i18n/l10n/zh-CN.ftl.json index a43e86775..5e7babf69 100644 --- a/src/i18n/l10n/zh-CN.ftl.json +++ b/src/i18n/l10n/zh-CN.ftl.json @@ -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", diff --git a/src/i18n/l10n/zh-HK.ftl b/src/i18n/l10n/zh-HK.ftl index 37967de21..aa4099a28 100644 --- a/src/i18n/l10n/zh-HK.ftl +++ b/src/i18n/l10n/zh-HK.ftl @@ -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 diff --git a/src/i18n/l10n/zh-HK.ftl.json b/src/i18n/l10n/zh-HK.ftl.json index 579e5e827..dbdbdcbc0 100644 --- a/src/i18n/l10n/zh-HK.ftl.json +++ b/src/i18n/l10n/zh-HK.ftl.json @@ -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", diff --git a/src/i18n/l10n/zh-TW.ftl b/src/i18n/l10n/zh-TW.ftl index bca4cd0a7..f906712fc 100644 --- a/src/i18n/l10n/zh-TW.ftl +++ b/src/i18n/l10n/zh-TW.ftl @@ -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 diff --git a/src/i18n/l10n/zh-TW.ftl.json b/src/i18n/l10n/zh-TW.ftl.json index b2dc107a0..28a475ab3 100644 --- a/src/i18n/l10n/zh-TW.ftl.json +++ b/src/i18n/l10n/zh-TW.ftl.json @@ -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", From 8f2f5d9eae249532d9837e46d54bf19010d840c2 Mon Sep 17 00:00:00 2001 From: Ryan Stelly Date: Tue, 7 Jul 2026 14:16:59 -0500 Subject: [PATCH 30/43] rn-maps patch: don't ignore region change cbs on large map jumps (#3798) --- patches/react-native-maps+1.27.1.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 patches/react-native-maps+1.27.1.patch diff --git a/patches/react-native-maps+1.27.1.patch b/patches/react-native-maps+1.27.1.patch new file mode 100644 index 000000000..47605c0c9 --- /dev/null +++ b/patches/react-native-maps+1.27.1.patch @@ -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{ From aabd6e06f4a542ae4963d01a3e6ea0b4a346d7d2 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Tue, 7 Jul 2026 22:10:13 +0200 Subject: [PATCH 31/43] bundle update fastlane --- Gemfile.lock | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7b2a9931f..d9fedcca5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) From 0fdb2218604ec9a332138b52838bb07026a81c01 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Tue, 7 Jul 2026 22:40:33 +0200 Subject: [PATCH 32/43] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a6d20e8c..5366830c9 100644 --- a/README.md +++ b/README.md @@ -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 From 1e1ca3d3b0c9502ea1865e1ed2666048e84f0c0d Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Tue, 7 Jul 2026 15:41:29 -0500 Subject: [PATCH 33/43] MOB-1339: fix import --- .../Explore/ExploreV2/components/DefaultSearchOptions.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx index f5f1ddd87..c2f5f79df 100644 --- a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx +++ b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx @@ -1,8 +1,10 @@ -import type { ApiTaxon, ApiUser } from "api/types"; +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"; @@ -13,7 +15,6 @@ import type { RealmTaxon } from "realmModels/types"; import useCurrentUser from "sharedHooks/useCurrentUser"; import useIconicTaxa from "sharedHooks/useIconicTaxa"; import useTranslation from "sharedHooks/useTranslation"; -import type { UniversalSearchResultItem } from "sharedHooks/useUniversalSearch"; interface Props { onSelectSubject: ( subject: ExploreV2Subject ) => void; @@ -32,7 +33,7 @@ const EMPTY_CHOSEN: string[] = []; const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { const { t } = useTranslation( ); - const currentUser = useCurrentUser( ) as unknown as ApiUser | null; + const currentUser = useCurrentUser( ); const iconicTaxa = useIconicTaxa( ); // Map iconic taxon name -> Realm taxon, so the shared chooser's name-based From b4cdf6e3ea55f7ccaa9449167ec0b4f31276893e Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Tue, 7 Jul 2026 22:57:45 +0200 Subject: [PATCH 34/43] v1.0.25+220 --- android/app/build.gradle | 2 +- fastlane/metadata/android/en-US/changelogs/220.txt | 4 ++++ ios/iNaturalistReactNative.xcodeproj/project.pbxproj | 8 ++++---- ios/iNaturalistReactNative/Info.plist | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/220.txt diff --git a/android/app/build.gradle b/android/app/build.gradle index 1ce82033e..0099597fc 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -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 diff --git a/fastlane/metadata/android/en-US/changelogs/220.txt b/fastlane/metadata/android/en-US/changelogs/220.txt new file mode 100644 index 000000000..111bf8706 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/220.txt @@ -0,0 +1,4 @@ +FIXED +* Adding comments to Agreeing IDs +* A crash when deleting photo +* Location chooser spinning indefinitely diff --git a/ios/iNaturalistReactNative.xcodeproj/project.pbxproj b/ios/iNaturalistReactNative.xcodeproj/project.pbxproj index 2dda9258b..8aab700d2 100644 --- a/ios/iNaturalistReactNative.xcodeproj/project.pbxproj +++ b/ios/iNaturalistReactNative.xcodeproj/project.pbxproj @@ -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; diff --git a/ios/iNaturalistReactNative/Info.plist b/ios/iNaturalistReactNative/Info.plist index 8b47d3fa1..432e7aca8 100644 --- a/ios/iNaturalistReactNative/Info.plist +++ b/ios/iNaturalistReactNative/Info.plist @@ -42,7 +42,7 @@ CFBundleVersion - 219 + 220 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes From 98821141ae385afd019ce3ad3be7e8aff1da37e5 Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Tue, 7 Jul 2026 16:14:55 -0500 Subject: [PATCH 35/43] MOB-1339: fix tests --- .../ExploreV2/screens/UniversalSearch.test.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js index 8629641e1..06bc04d3d 100644 --- a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js +++ b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js @@ -303,11 +303,17 @@ describe( "UniversalSearch screen", ( ) => { expect( screen.getByText( i18next.t( "Species-I-havent-observed" ) ) ).toBeTruthy( ); } ); - it( "fills the field and sets the subject when an iconic taxon is tapped", ( ) => { + it( "fills the field and stages the subject when an iconic taxon is tapped", ( ) => { renderComponent( ); fireEvent.press( screen.getByTestId( "INatIconButton.IconicTaxonButton.plantae" ) ); + // the selection is staged locally, not written to context until Search + expect( mockDispatch ).not.toHaveBeenCalled( ); + // common name is primary for the test user, so the field shows "Plants" + expect( screen.getByDisplayValue( "Plants" ) ).toBeTruthy( ); + + fireEvent.press( screen.getByTestId( "UniversalSearch.searchButton" ) ); expect( mockDispatch ).toHaveBeenCalledWith( expect.objectContaining( { type: "SET_SUBJECT", @@ -317,15 +323,18 @@ describe( "UniversalSearch screen", ( ) => { } ), } ), ); - // common name is primary for the test user, so the field shows "Plants" - expect( screen.getByDisplayValue( "Plants" ) ).toBeTruthy( ); } ); - it( "sets the current user as the subject when their profile row is tapped", ( ) => { + it( "stages the current user as the subject when their profile row is tapped", ( ) => { renderComponent( ); fireEvent.press( screen.getByTestId( "UniversalSearchResult.user.99" ) ); + // the selection is staged locally, not written to context until Search + expect( mockDispatch ).not.toHaveBeenCalled( ); + expect( screen.getByDisplayValue( "tester" ) ).toBeTruthy( ); + + fireEvent.press( screen.getByTestId( "UniversalSearch.searchButton" ) ); expect( mockDispatch ).toHaveBeenCalledWith( expect.objectContaining( { type: "SET_SUBJECT", @@ -335,7 +344,6 @@ describe( "UniversalSearch screen", ( ) => { } ), } ), ); - expect( screen.getByDisplayValue( "tester" ) ).toBeTruthy( ); } ); it( "hides the current user row when logged out", ( ) => { From 80bcae1c2c8ceac161dd6f2d1a637fe1163af07a Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Tue, 7 Jul 2026 23:40:36 +0200 Subject: [PATCH 36/43] Send Android build to Closed beta 2026 using lane beta --- fastlane/Fastfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 7e3b83c6e..632c039a2 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -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" From aac44fcc8b80ccba185657ea0f282402033c4891 Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Wed, 8 Jul 2026 09:50:01 -0500 Subject: [PATCH 37/43] MOB-1339: accessibilityHint simplification --- .../Explore/ExploreV2/components/DefaultSearchOptions.tsx | 1 - src/components/SharedComponents/IconicTaxonChooser.tsx | 6 +----- src/i18n/l10n/en.ftl | 5 +---- src/i18n/l10n/en.ftl.json | 3 +-- src/i18n/strings.ftl | 5 +---- 5 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx index c2f5f79df..ad968bdc2 100644 --- a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx +++ b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx @@ -74,7 +74,6 @@ const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { ; @@ -41,7 +40,6 @@ const ICONIC_TAXA = [ const EMPTY_CHOSEN: string[] = []; const IconicTaxonChooser = ( { - accessibilityHint, before, chosen = EMPTY_CHOSEN, contentContainerStyle = STYLESHEET, @@ -84,15 +82,13 @@ const IconicTaxonChooser = ( { t( "Iconic-taxon-name", { iconicTaxon: iconicTaxonName } ) } accessibilityHint={ - accessibilityHint - ?? t( "Selects-iconic-taxon-X-for-identification", { iconicTaxon: iconicTaxonName } ) + t( "Selects-iconic-taxon-X", { iconicTaxon: iconicTaxonName } ) } testID={`INatIconButton.IconicTaxonButton.${iconicTaxonName}`} /> ); }, [ - accessibilityHint, chosen, onTaxonChosen, t, diff --git a/src/i18n/l10n/en.ftl b/src/i18n/l10n/en.ftl index 92898be36..2516b2c5b 100644 --- a/src/i18n/l10n/en.ftl +++ b/src/i18n/l10n/en.ftl @@ -1158,9 +1158,6 @@ Search-suggestions-with-location = Search suggestions with location Search-suggestions-without-location = Search suggestions without location SEARCH-TAXA = SEARCH TAXA SEARCH-USERS = SEARCH USERS -# Accessibility hint for an iconic taxon button in Explore search that searches -# for observations of that taxon. -Searches-for-iconic-taxon = Searches for iconic taxon. # Accessibility label for navigating to journal posts screen See-journal-posts = See journal posts # Accessibility label for Observations button on UserProfile screen @@ -1179,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 diff --git a/src/i18n/l10n/en.ftl.json b/src/i18n/l10n/en.ftl.json index 00ae57dec..7277c1408 100644 --- a/src/i18n/l10n/en.ftl.json +++ b/src/i18n/l10n/en.ftl.json @@ -717,7 +717,6 @@ "Search-suggestions-without-location": "Search suggestions without location", "SEARCH-TAXA": "SEARCH TAXA", "SEARCH-USERS": "SEARCH USERS", - "Searches-for-iconic-taxon": "Searches for iconic taxon.", "See-journal-posts": "See journal posts", "See-observations-by-this-user-in-Explore": "See observations by this user in Explore", "See-observations-of-this-taxon-in-explore": "See observations of this taxon in explore", @@ -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", diff --git a/src/i18n/strings.ftl b/src/i18n/strings.ftl index 92898be36..2516b2c5b 100644 --- a/src/i18n/strings.ftl +++ b/src/i18n/strings.ftl @@ -1158,9 +1158,6 @@ Search-suggestions-with-location = Search suggestions with location Search-suggestions-without-location = Search suggestions without location SEARCH-TAXA = SEARCH TAXA SEARCH-USERS = SEARCH USERS -# Accessibility hint for an iconic taxon button in Explore search that searches -# for observations of that taxon. -Searches-for-iconic-taxon = Searches for iconic taxon. # Accessibility label for navigating to journal posts screen See-journal-posts = See journal posts # Accessibility label for Observations button on UserProfile screen @@ -1179,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 From cdf14a20a51780a7b46881b807848eac01329db6 Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Wed, 8 Jul 2026 09:53:21 -0500 Subject: [PATCH 38/43] MOB-1339: gate unobserved option on logged in --- .../components/DefaultSearchOptions.tsx | 22 ++++++++++--------- .../ExploreV2/screens/UniversalSearch.test.js | 4 ++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx index ad968bdc2..5cd22adcb 100644 --- a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx +++ b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx @@ -87,16 +87,18 @@ const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { onPress={( ) => onSelectSubject( resultToSubject( currentUserResult ) )} /> )} - undefined} - testID="DefaultSearchOptions.unobserved" - > - {t( "Species-I-havent-observed" )} - + {currentUser?.id && ( + undefined} + testID="DefaultSearchOptions.unobserved" + > + {t( "Species-I-havent-observed" )} + + )} ); }; diff --git a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js index 06bc04d3d..ebb0d0ea8 100644 --- a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js +++ b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js @@ -351,9 +351,9 @@ describe( "UniversalSearch screen", ( ) => { renderComponent( ); expect( screen.queryByTestId( "UniversalSearchResult.user.99" ) ).toBeNull( ); - // the iconic taxa chooser and unobserved shortcut still render + // the iconic taxa chooser still renders, but the unobserved shortcut does not expect( screen.getByTestId( "INatIconButton.IconicTaxonButton.plantae" ) ).toBeTruthy( ); - expect( screen.getByText( i18next.t( "Species-I-havent-observed" ) ) ).toBeTruthy( ); + expect( screen.queryByText( i18next.t( "Species-I-havent-observed" ) ) ).toBeNull( ); } ); it( "hides the default options once a subject query is entered", ( ) => { From a5ed9128bdcdc141aebf0c19ace11a4e558ce17d Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:54:06 -0500 Subject: [PATCH 39/43] MOB-1339: map realm object only on tap --- .../components/DefaultSearchOptions.tsx | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx index 5cd22adcb..1a9d13912 100644 --- a/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx +++ b/src/components/Explore/ExploreV2/components/DefaultSearchOptions.tsx @@ -9,7 +9,7 @@ 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, useMemo } from "react"; +import React, { useCallback } from "react"; import Taxon from "realmModels/Taxon"; import type { RealmTaxon } from "realmModels/types"; import useCurrentUser from "sharedHooks/useCurrentUser"; @@ -36,27 +36,18 @@ const DefaultSearchOptions = ( { onSelectSubject }: Props ) => { const currentUser = useCurrentUser( ); const iconicTaxa = useIconicTaxa( ); - // Map iconic taxon name -> Realm taxon, so the shared chooser's name-based - // callback can be resolved into a full taxon subject. - const taxaByName = useMemo( ( ): Map => { - const map = new Map( ); + 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[]; - taxaList.forEach( taxon => { - if ( taxon?.name ) { - map.set( taxon.name.toLowerCase( ), taxon ); - } - } ); - return map; - }, [iconicTaxa] ); - - const handleIconicTaxon = useCallback( ( iconicTaxonName: string ) => { - const realmTaxon = taxaByName.get( iconicTaxonName ); + const realmTaxon = taxaList.find( + taxon => taxon?.name?.toLowerCase( ) === iconicTaxonName, + ); if ( !realmTaxon ) { return; } const taxon = Taxon.mapRealmToPojo( realmTaxon ) as ApiTaxon; onSelectSubject( resultToSubject( { type: "taxon", taxon } ) ); - }, [taxaByName, onSelectSubject] ); + }, [iconicTaxa, onSelectSubject] ); const currentUserResult: UniversalSearchResultItem | null = currentUser?.id ? { From ba7e11fa7d34c54d0fedb0992f3f447a6fb6cf1f Mon Sep 17 00:00:00 2001 From: Ryan Stelly Date: Wed, 8 Jul 2026 11:03:25 -0500 Subject: [PATCH 40/43] use ubuntu for androide2e slack notif, replace deprecated macos-latest label (#3809) --- .github/workflows/e2e_android.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e_android.yml b/.github/workflows/e2e_android.yml index a7f8dc971..eea994f2c 100644 --- a/.github/workflows/e2e_android.yml +++ b/.github/workflows/e2e_android.yml @@ -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 From 58edf184365cca7b795deaf8ce2c3dc7df7fc77c Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Wed, 8 Jul 2026 11:10:44 -0500 Subject: [PATCH 41/43] MOB-1339: test refinements --- .../ExploreV2/screens/UniversalSearch.test.js | 181 +++++++++--------- 1 file changed, 95 insertions(+), 86 deletions(-) diff --git a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js index ebb0d0ea8..970d3f4d6 100644 --- a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js +++ b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js @@ -1,4 +1,6 @@ -import { act, fireEvent, screen } from "@testing-library/react-native"; +import { + act, fireEvent, screen, userEvent, +} from "@testing-library/react-native"; import UniversalSearch from "components/Explore/ExploreV2/screens/UniversalSearch"; import initI18next from "i18n/initI18next"; import i18next from "i18next"; @@ -116,10 +118,12 @@ const PLACE_RESULTS = [ }, ]; +const actor = userEvent.setup( ); + const typeQuery = text => { fireEvent.changeText( screen.getByTestId( "UniversalSearch.subjectInput" ), text ); - // Only the timer advancement needs an act wrapper; fireEvent is already - // wrapped internally by Testing Library. + // The debounce timing is exercised directly with fake timers, so we keep + // fireEvent + manual advancement here rather than userEvent.type. act( ( ) => { jest.advanceTimersByTime( 400 ); } ); @@ -175,13 +179,13 @@ describe( "UniversalSearch screen", ( ) => { expect( screen.getByDisplayValue( "California" ) ).toBeTruthy( ); } ); - it( "clears both fields when reset is pressed", ( ) => { + it( "clears both fields when reset is pressed", async ( ) => { renderComponent( ); fireEvent.changeText( screen.getByTestId( "UniversalSearch.subjectInput" ), "cup plant" ); fireEvent.changeText( screen.getByTestId( "UniversalSearch.locationInput" ), "California" ); - fireEvent.press( screen.getByText( i18next.t( "Reset-verb" ) ) ); + await actor.press( screen.getByText( i18next.t( "Reset-verb" ) ) ); expect( screen.queryByDisplayValue( "cup plant" ) ).toBeNull( ); expect( screen.queryByDisplayValue( "California" ) ).toBeNull( ); @@ -204,7 +208,7 @@ describe( "UniversalSearch screen", ( ) => { expect( screen.getByTestId( "UniversalSearchResult.info.7" ) ).toBeTruthy( ); } ); - it( "fills the field but does not commit to context when a result is tapped", ( ) => { + it( "fills the field but does not commit to context when a result is tapped", async ( ) => { useUniversalSearch.mockReturnValue( { results: MIXED_RESULTS, isLoading: false, @@ -214,7 +218,7 @@ describe( "UniversalSearch screen", ( ) => { typeQuery( "ver" ); - fireEvent.press( screen.getByTestId( "UniversalSearchResult.user.7" ) ); + await actor.press( screen.getByTestId( "UniversalSearchResult.user.7" ) ); // the selection is staged locally, not written to context until Search expect( mockDispatch ).not.toHaveBeenCalled( ); @@ -222,35 +226,38 @@ describe( "UniversalSearch screen", ( ) => { expect( screen.getByDisplayValue( "seth_msp" ) ).toBeTruthy( ); } ); - it( "clears the field but keeps the staged subject when refocusing after a selection", ( ) => { - useUniversalSearch.mockReturnValue( { - results: MIXED_RESULTS, - isLoading: false, - refetch: jest.fn( ), - } ); - renderComponent( ); + it( + "clears the field but keeps the staged subject when refocusing after a selection", + async ( ) => { + useUniversalSearch.mockReturnValue( { + results: MIXED_RESULTS, + isLoading: false, + refetch: jest.fn( ), + } ); + renderComponent( ); - typeQuery( "ver" ); - fireEvent.press( screen.getByTestId( "UniversalSearchResult.user.7" ) ); - expect( screen.getByDisplayValue( "seth_msp" ) ).toBeTruthy( ); + typeQuery( "ver" ); + await actor.press( screen.getByTestId( "UniversalSearchResult.user.7" ) ); + expect( screen.getByDisplayValue( "seth_msp" ) ).toBeTruthy( ); - fireEvent( screen.getByTestId( "UniversalSearch.subjectInput" ), "focus" ); + fireEvent( screen.getByTestId( "UniversalSearch.subjectInput" ), "focus" ); - // the field is cleared for a fresh search... - expect( screen.queryByDisplayValue( "seth_msp" ) ).toBeNull( ); + // the field is cleared for a fresh search... + expect( screen.queryByDisplayValue( "seth_msp" ) ).toBeNull( ); - fireEvent.press( screen.getByTestId( "UniversalSearch.searchButton" ) ); - expect( mockDispatch ).toHaveBeenCalledWith( - expect.objectContaining( { - type: "SET_SUBJECT", - subject: expect.objectContaining( { - type: "user", - user: expect.objectContaining( { id: 7, login: "seth_msp" } ), + await actor.press( screen.getByTestId( "UniversalSearch.searchButton" ) ); + expect( mockDispatch ).toHaveBeenCalledWith( + expect.objectContaining( { + type: "SET_SUBJECT", + subject: expect.objectContaining( { + type: "user", + user: expect.objectContaining( { id: 7, login: "seth_msp" } ), + } ), } ), - } ), - ); - expect( mockDispatch ).not.toHaveBeenCalledWith( { type: "CLEAR_SUBJECT" } ); - } ); + ); + expect( mockDispatch ).not.toHaveBeenCalledWith( { type: "CLEAR_SUBJECT" } ); + }, + ); it( "shows an empty-state message when a query returns no results", ( ) => { useUniversalSearch.mockReturnValue( { results: [], isLoading: false, refetch: jest.fn( ) } ); @@ -296,24 +303,23 @@ describe( "UniversalSearch screen", ( ) => { expect( screen.getByTestId( "DefaultSearchOptions" ) ).toBeTruthy( ); expect( screen.getByTestId( "INatIconButton.IconicTaxonButton.plantae" ) ).toBeTruthy( ); - // current user's profile row, reusing the user result row - expect( screen.getByTestId( "UniversalSearchResult.user.99" ) ).toBeTruthy( ); + // current user's profile row, identified by their login expect( screen.getByText( "tester" ) ).toBeTruthy( ); // "Species I haven't observed" shortcut expect( screen.getByText( i18next.t( "Species-I-havent-observed" ) ) ).toBeTruthy( ); } ); - it( "fills the field and stages the subject when an iconic taxon is tapped", ( ) => { + it( "fills the field and stages the subject when an iconic taxon is tapped", async ( ) => { renderComponent( ); - fireEvent.press( screen.getByTestId( "INatIconButton.IconicTaxonButton.plantae" ) ); + await actor.press( screen.getByTestId( "INatIconButton.IconicTaxonButton.plantae" ) ); // the selection is staged locally, not written to context until Search expect( mockDispatch ).not.toHaveBeenCalled( ); // common name is primary for the test user, so the field shows "Plants" expect( screen.getByDisplayValue( "Plants" ) ).toBeTruthy( ); - fireEvent.press( screen.getByTestId( "UniversalSearch.searchButton" ) ); + await actor.press( screen.getByTestId( "UniversalSearch.searchButton" ) ); expect( mockDispatch ).toHaveBeenCalledWith( expect.objectContaining( { type: "SET_SUBJECT", @@ -325,16 +331,16 @@ describe( "UniversalSearch screen", ( ) => { ); } ); - it( "stages the current user as the subject when their profile row is tapped", ( ) => { + it( "stages the current user as the subject when their profile row is tapped", async ( ) => { renderComponent( ); - fireEvent.press( screen.getByTestId( "UniversalSearchResult.user.99" ) ); + await actor.press( screen.getByTestId( "UniversalSearchResult.user.99" ) ); // the selection is staged locally, not written to context until Search expect( mockDispatch ).not.toHaveBeenCalled( ); expect( screen.getByDisplayValue( "tester" ) ).toBeTruthy( ); - fireEvent.press( screen.getByTestId( "UniversalSearch.searchButton" ) ); + await actor.press( screen.getByTestId( "UniversalSearch.searchButton" ) ); expect( mockDispatch ).toHaveBeenCalledWith( expect.objectContaining( { type: "SET_SUBJECT", @@ -423,81 +429,84 @@ describe( "UniversalSearch screen", ( ) => { expect( screen.queryByTestId( "LocationSearchResult.1" ) ).toBeNull( ); } ); - it( "fills the field and dismisses the keyboard on place selection, without committing", ( ) => { - const dismissSpy = jest.spyOn( Keyboard, "dismiss" ).mockImplementation( ( ) => {} ); - useLocationSearch.mockReturnValue( { - results: PLACE_RESULTS, - isLoading: false, - refetch: jest.fn( ), - } ); + it( + "fills the field and dismisses the keyboard on place selection, without committing", + async ( ) => { + const dismissSpy = jest.spyOn( Keyboard, "dismiss" ).mockImplementation( ( ) => {} ); + useLocationSearch.mockReturnValue( { + results: PLACE_RESULTS, + isLoading: false, + refetch: jest.fn( ), + } ); + renderComponent( ); + + typeLocationQuery( "mon" ); + await actor.press( screen.getByTestId( "LocationSearchResult.1" ) ); + + // the location field is filled with the selected place + expect( screen.getByDisplayValue( "Monterey, CA, US" ) ).toBeTruthy( ); + expect( dismissSpy ).toHaveBeenCalled( ); + + dismissSpy.mockRestore( ); + }, + ); + + it( "navigates to Advanced Search", async ( ) => { renderComponent( ); - typeLocationQuery( "mon" ); - fireEvent.press( screen.getByTestId( "LocationSearchResult.1" ) ); - - // the location field is filled with the selected place - expect( screen.getByDisplayValue( "Monterey, CA, US" ) ).toBeTruthy( ); - expect( dismissSpy ).toHaveBeenCalled( ); - - dismissSpy.mockRestore( ); - } ); - - it( "navigates to Advanced Search", ( ) => { - renderComponent( ); - - fireEvent.press( screen.getByText( i18next.t( "Advanced-Search" ) ) ); + await actor.press( screen.getByText( i18next.t( "Advanced-Search" ) ) ); expect( mockNavigate ).toHaveBeenCalledWith( "AdvancedSearch" ); } ); describe( "search submission", ( ) => { - const selectSubject = ( ) => { + const selectSubject = async ( ) => { useUniversalSearch.mockReturnValue( { results: MIXED_RESULTS, isLoading: false, refetch: jest.fn( ), } ); typeQuery( "ver" ); - fireEvent.press( screen.getByTestId( "UniversalSearchResult.user.7" ) ); + await actor.press( screen.getByTestId( "UniversalSearchResult.user.7" ) ); }; // Stage a location pick on this instance of the screen. - const selectPlace = ( ) => { + const selectPlace = async ( ) => { useLocationSearch.mockReturnValue( { results: PLACE_RESULTS, isLoading: false, refetch: jest.fn( ), } ); typeLocationQuery( "mon" ); - fireEvent.press( screen.getByTestId( "LocationSearchResult.1" ) ); + await actor.press( screen.getByTestId( "LocationSearchResult.1" ) ); }; - const pressSearch = ( ) => fireEvent.press( + const pressSearch = ( ) => actor.press( screen.getByTestId( "UniversalSearch.searchButton" ), ); - it( "navigates to ExploreResults when the search button is pressed", ( ) => { + it( "navigates to ExploreResults when the search button is pressed", async ( ) => { renderComponent( ); - pressSearch( ); + await pressSearch( ); expect( mockPopTo ).toHaveBeenCalledWith( "ExploreResults" ); } ); - it( "commits all organisms + worldwide when nothing is selected", ( ) => { + it( "commits all organisms + worldwide when nothing is selected", async ( ) => { renderComponent( ); - pressSearch( ); + await pressSearch( ); expect( mockDispatch ).toHaveBeenCalledWith( { type: "CLEAR_SUBJECT" } ); expect( mockDispatch ).toHaveBeenCalledWith( { type: "SET_LOCATION_WORLDWIDE" } ); } ); - it( "commits the subject + worldwide when only a subject is selected", ( ) => { + it( "commits the subject + worldwide when only a subject is selected", async ( ) => { renderComponent( ); - selectSubject( ); - pressSearch( ); + await selectSubject( ); + await pressSearch( ); expect( mockDispatch ).toHaveBeenCalledWith( expect.objectContaining( { @@ -512,11 +521,11 @@ describe( "UniversalSearch screen", ( ) => { expect( mockDispatch ).toHaveBeenCalledWith( { type: "SET_LOCATION_WORLDWIDE" } ); } ); - it( "commits all organisms + the place when only a location is selected", ( ) => { + it( "commits all organisms + the place when only a location is selected", async ( ) => { renderComponent( ); - selectPlace( ); - pressSearch( ); + await selectPlace( ); + await pressSearch( ); // subject was left untouched → all organisms expect( mockDispatch ).toHaveBeenCalledWith( { type: "CLEAR_SUBJECT" } ); @@ -526,12 +535,12 @@ describe( "UniversalSearch screen", ( ) => { } ); } ); - it( "commits both when a subject and a location are selected", ( ) => { + it( "commits both when a subject and a location are selected", async ( ) => { renderComponent( ); - selectSubject( ); - selectPlace( ); - pressSearch( ); + await selectSubject( ); + await selectPlace( ); + await pressSearch( ); expect( mockDispatch ).toHaveBeenCalledWith( expect.objectContaining( { type: "SET_SUBJECT" } ), @@ -544,25 +553,25 @@ describe( "UniversalSearch screen", ( ) => { expect( mockDispatch ).not.toHaveBeenCalledWith( { type: "SET_LOCATION_WORLDWIDE" } ); } ); - it( "does not commit anything after Reset clears the staged selections", ( ) => { + it( "does not commit anything after Reset clears the staged selections", async ( ) => { renderComponent( ); - selectSubject( ); - selectPlace( ); - fireEvent.press( screen.getByText( i18next.t( "Reset-verb" ) ) ); + await selectSubject( ); + await selectPlace( ); + await actor.press( screen.getByText( i18next.t( "Reset-verb" ) ) ); - pressSearch( ); + await pressSearch( ); // Reset cleared the staged picks, so Search falls back to the defaults. expect( mockDispatch ).toHaveBeenCalledWith( { type: "CLEAR_SUBJECT" } ); expect( mockDispatch ).toHaveBeenCalledWith( { type: "SET_LOCATION_WORLDWIDE" } ); } ); - it( "dismisses the keyboard when the search button is pressed", ( ) => { + it( "dismisses the keyboard when the search button is pressed", async ( ) => { const dismissSpy = jest.spyOn( Keyboard, "dismiss" ).mockImplementation( ( ) => {} ); renderComponent( ); - pressSearch( ); + await pressSearch( ); expect( dismissSpy ).toHaveBeenCalled( ); From b470156381e007d007b41acec53ba603800d5c4e Mon Sep 17 00:00:00 2001 From: Ryan Stelly Date: Wed, 8 Jul 2026 13:37:35 -0500 Subject: [PATCH 42/43] Location picker types (#3797) * LocationPicker.js => .tsx * LocationPickerContainer.js => .tsx & related types * fix region and positional acc --- .../{LocationPicker.js => LocationPicker.tsx} | 43 ++++++++++--------- ...ntainer.js => LocationPickerContainer.tsx} | 32 ++++++++------ .../LocationPicker/LocationSearch.tsx | 18 +++----- src/components/LocationPicker/types.ts | 32 ++++++++++++++ src/components/SharedComponents/Map/Map.tsx | 29 +++++++------ 5 files changed, 95 insertions(+), 59 deletions(-) rename src/components/LocationPicker/{LocationPicker.js => LocationPicker.tsx} (77%) rename src/components/LocationPicker/{LocationPickerContainer.js => LocationPickerContainer.tsx} (88%) create mode 100644 src/components/LocationPicker/types.ts diff --git a/src/components/LocationPicker/LocationPicker.js b/src/components/LocationPicker/LocationPicker.tsx similarity index 77% rename from src/components/LocationPicker/LocationPicker.js rename to src/components/LocationPicker/LocationPicker.tsx index dd69141cf..875f599dc 100644 --- a/src/components/LocationPicker/LocationPicker.js +++ b/src/components/LocationPicker/LocationPicker.tsx @@ -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 = ( { { +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( null ); + const [mapDimensionsRatio, setMapDimensionsRatio] = useState( 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 ); diff --git a/src/components/LocationPicker/LocationSearch.tsx b/src/components/LocationPicker/LocationSearch.tsx index 3325b257c..60d3d3d2f 100644 --- a/src/components/LocationPicker/LocationSearch.tsx +++ b/src/components/LocationPicker/LocationSearch.tsx @@ -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 ) => ( ( { +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 without // 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 = ( { ) : ( From b5dfd11ce9b4426977f472075f2d94309d002ff4 Mon Sep 17 00:00:00 2001 From: Johannes Klein Date: Wed, 8 Jul 2026 23:08:09 +0200 Subject: [PATCH 43/43] Update VC plugin to enable CV model 2.30 (#3812) Diff in the package is only these two commits: https://github.com/inaturalist/vision-camera-plugin-inatvision/commit/214eb07b94ccf9d65a933a9b330f3c806f2c6f8d https://github.com/inaturalist/vision-camera-plugin-inatvision/commit/0354705c124e3a9fabcca3e5881e64cd93d2f0df Co-authored-by: Johannes Klein <17345891+jtklein@users.noreply.github.com> --- ios/Podfile.lock | 4 ++-- package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6477a98e6..ab0725227 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -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 diff --git a/package-lock.json b/package-lock.json index b669dc74b..1a64c1c7c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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" diff --git a/package.json b/package.json index a1b4810c8..9d671d47b 100644 --- a/package.json +++ b/package.json @@ -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": {