From 1c59f89a147005d3e3f8ed30ae453688eb5ae616 Mon Sep 17 00:00:00 2001
From: Amanda Bullington <35536439+albullington@users.noreply.github.com>
Date: Thu, 26 Dec 2024 21:35:27 -0800
Subject: [PATCH] Add functionality for advanced iNaturalist mode (#2591)
* Add functionality for advanced iNaturalist mode
* Fix language settings test by toggling advanced mode on
* Fix e2e tests by adding advanced user toggle
* Fix more tests in Settings with advanced toggle
---
e2e/sharedFlows/switchPowerMode.js | 4 +
src/components/Settings/LanguageSetting.tsx | 7 +-
src/components/Settings/Settings.js | 157 ++++++++++--------
src/i18n/l10n/en.ftl | 4 +-
src/i18n/l10n/en.ftl.json | 4 +-
src/i18n/strings.ftl | 4 +-
tests/integration/LanguageSettings.test.js | 8 +
.../unit/components/Settings/Settings.test.js | 10 ++
8 files changed, 116 insertions(+), 82 deletions(-)
diff --git a/e2e/sharedFlows/switchPowerMode.js b/e2e/sharedFlows/switchPowerMode.js
index 6cda003d8..6a07b3a31 100644
--- a/e2e/sharedFlows/switchPowerMode.js
+++ b/e2e/sharedFlows/switchPowerMode.js
@@ -10,6 +10,10 @@ export default async function switchPowerMode() {
const settingsDrawerMenuItem = element( by.id( "settings" ) );
await waitFor( settingsDrawerMenuItem ).toBeVisible().withTimeout( 10000 );
await settingsDrawerMenuItem.tap();
+ // Tap the settings radio button for advanced interface mode
+ const advancedInterfaceRadioButton = element( by.id( "advanced-interface-option" ) );
+ await waitFor( advancedInterfaceRadioButton ).toBeVisible().withTimeout( 10000 );
+ await advancedInterfaceRadioButton.tap();
// Tap the settings radio button for power user mode
const powerUserRadioButton = element( by.id( "all-observation-option" ) );
await waitFor( powerUserRadioButton ).toBeVisible().withTimeout( 10000 );
diff --git a/src/components/Settings/LanguageSetting.tsx b/src/components/Settings/LanguageSetting.tsx
index 3e3404166..be91d353b 100644
--- a/src/components/Settings/LanguageSetting.tsx
+++ b/src/components/Settings/LanguageSetting.tsx
@@ -4,6 +4,7 @@ import {
Heading4,
PickerSheet
} from "components/SharedComponents";
+import { View } from "components/styledComponents";
import _ from "lodash";
import React, { useEffect, useState } from "react";
import changeLanguage from "sharedHelpers/changeLanguage.ts";
@@ -51,8 +52,8 @@ const LanguageSetting = ( { onChange }: Props ) => {
}
return (
- <>
- {t( "APP-LANGUAGE" )}
+
+ {t( "APP-LANGUAGE" )}
);
};
diff --git a/src/components/Settings/Settings.js b/src/components/Settings/Settings.js
index c2280f0df..c8ea5c11b 100644
--- a/src/components/Settings/Settings.js
+++ b/src/components/Settings/Settings.js
@@ -145,16 +145,9 @@ const Settings = ( ) => {
updateUserMutation.mutate( payload );
}, [settings?.id, updateUserMutation] );
- const renderLoggedIn = ( ) => (
-
- {( isSaving || isLoading ) && (
-
-
-
- )}
- {t( "TAXON-NAMES-DISPLAY" )}
+ const renderTaxonNamesSection = ( ) => (
+
+ {t( "TAXON-NAMES-DISPLAY" )}{t( "This-is-how-taxon-names-will-be-displayed" )} {
label={t( "Scientific-Name" )}
/>
+
+ );
+
+ const renderLoggedIn = ( ) => (
+
+ {( isSaving || isLoading ) && (
+
+
+
+ )}
+ {!isDefaultMode && renderTaxonNamesSection( )}
{
QueueItem.enqueue(
@@ -194,46 +200,48 @@ const Settings = ( ) => {
);
}}
/>
- {t( "INATURALIST-ACCOUNT-SETTINGS" )}
- {t( "Edit-your-profile-change-your-settings" )}
-
);
@@ -241,9 +249,9 @@ const Settings = ( ) => {
-
- {t( "INATURALIST-INTERFACE-MODE" )}
-
+
+ {t( "INATURALIST-MODE" )}
+ {
label={t( "Default--interface-mode" )}
/>
-
+ setIsDefaultMode( false )}
- label={t( "Advanced--interface-mode" )}
+ label={t( "Advanced--interface-mode-with-explainer" )}
/>
-
- {t( "OBSERVATION-BUTTON" )}
- {t( "When-tapping-the-green-observation-button" )}
-
- setIsAllAddObsOptionsMode( false )}
- label={t( "iNaturalist-AI-Camera" )}
- />
-
-
- setIsAllAddObsOptionsMode( true )}
- label={t( "All-observation-option" )}
- />
+ {!isDefaultMode && (
+
+ {t( "OBSERVATION-BUTTON" )}
+ {t( "When-tapping-the-green-observation-button" )}
+
+ setIsAllAddObsOptionsMode( false )}
+ label={t( "iNaturalist-AI-Camera" )}
+ />
+
+
+ setIsAllAddObsOptionsMode( true )}
+ label={t( "All-observation-option" )}
+ />
+
-
+ )}
{currentUser && renderLoggedIn( )}
diff --git a/src/i18n/l10n/en.ftl b/src/i18n/l10n/en.ftl
index ff3bc46e6..884ef3d8b 100644
--- a/src/i18n/l10n/en.ftl
+++ b/src/i18n/l10n/en.ftl
@@ -64,7 +64,7 @@ Add-optional-notes = Add optional notes
Adds-your-vote-of-agreement = Adds your vote of agreement
# Hint for a button that adds a vote of disagreement
Adds-your-vote-of-disagreement = Adds your vote of disagreement
-Advanced--interface-mode = Advanced
+Advanced--interface-mode-with-explainer = Advanced (Upload multiple photos and sounds)
Affiliation = Affiliation: { $site }
# Label for button that adds an identification of the same taxon as another identification
Agree = Agree
@@ -581,7 +581,6 @@ iNaturalist-has-no-ID-suggestions-for-this-photo = iNaturalist has no ID suggest
INATURALIST-HELP-PAGE = INATURALIST HELP PAGE
iNaturalist-helps-you-identify = iNaturalist helps you identify the plants and animals around you while generating data for science and conservation. Get connected with a community of millions scientists and naturalists who can help you learn more about nature!
iNaturalist-identification-suggestions-are-based-on = iNaturalist's identification suggestions are based on observations and identifications made by the iNaturalist community, including { $user1 }, { $user2 }, { $user3 }, and many others.
-INATURALIST-INTERFACE-MODE = INATURALIST INTERFACE MODE
iNaturalist-is-a-501 = iNaturalist is a 501(c)(3) non-profit in the United States of America (Tax ID/EIN 92-1296468).
iNaturalist-is-a-community-of-naturalists = iNaturalist is a community of naturalists that works together to create and identify wild biodiversity observations.
iNaturalist-is-loading-ID-suggestions = iNaturalist is loading ID suggestions...
@@ -589,6 +588,7 @@ iNaturalist-is-supported-by = iNaturalist is supported by an independent, 501(c)
iNaturalist-is-supported-by-our-community = iNaturalist is supported by our amazing community. From everyday naturalists who add observations and identifications, to curators who manage our taxonomy and help with moderation, to the volunteer translators who make iNaturalist more accessible to worldwide audiences, to our community-based donors, we are extraordinarily grateful to all the people in our community who make iNaturalist the platform it is.
iNaturalist-mission-is-to-connect = iNaturalist's mission is to connect people to nature and advance biodiversity science and conservation.
INATURALIST-MISSION-VISION = INATURALIST'S MISSION & VISION
+INATURALIST-MODE = INATURALIST MODE
INATURALIST-NETWORK = INATURALIST NETWORK
INATURALIST-SETTINGS = INATURALIST SETTINGS
# Label for the role a user plays on iNaturalist, e.g. "INATURALIST STAFF"
diff --git a/src/i18n/l10n/en.ftl.json b/src/i18n/l10n/en.ftl.json
index 9d76e689b..9fecc40da 100644
--- a/src/i18n/l10n/en.ftl.json
+++ b/src/i18n/l10n/en.ftl.json
@@ -26,7 +26,7 @@
"Add-optional-notes": "Add optional notes",
"Adds-your-vote-of-agreement": "Adds your vote of agreement",
"Adds-your-vote-of-disagreement": "Adds your vote of disagreement",
- "Advanced--interface-mode": "Advanced",
+ "Advanced--interface-mode-with-explainer": "Advanced (Upload multiple photos and sounds)",
"Affiliation": "Affiliation: { $site }",
"Agree": "Agree",
"AGREE": "AGREE",
@@ -337,7 +337,6 @@
"INATURALIST-HELP-PAGE": "INATURALIST HELP PAGE",
"iNaturalist-helps-you-identify": "iNaturalist helps you identify the plants and animals around you while generating data for science and conservation. Get connected with a community of millions scientists and naturalists who can help you learn more about nature!",
"iNaturalist-identification-suggestions-are-based-on": "iNaturalist's identification suggestions are based on observations and identifications made by the iNaturalist community, including { $user1 }, { $user2 }, { $user3 }, and many others.",
- "INATURALIST-INTERFACE-MODE": "INATURALIST INTERFACE MODE",
"iNaturalist-is-a-501": "iNaturalist is a 501(c)(3) non-profit in the United States of America (Tax ID/EIN 92-1296468).",
"iNaturalist-is-a-community-of-naturalists": "iNaturalist is a community of naturalists that works together to create and identify wild biodiversity observations.",
"iNaturalist-is-loading-ID-suggestions": "iNaturalist is loading ID suggestions...",
@@ -345,6 +344,7 @@
"iNaturalist-is-supported-by-our-community": "iNaturalist is supported by our amazing community. From everyday naturalists who add observations and identifications, to curators who manage our taxonomy and help with moderation, to the volunteer translators who make iNaturalist more accessible to worldwide audiences, to our community-based donors, we are extraordinarily grateful to all the people in our community who make iNaturalist the platform it is.",
"iNaturalist-mission-is-to-connect": "iNaturalist's mission is to connect people to nature and advance biodiversity science and conservation.",
"INATURALIST-MISSION-VISION": "INATURALIST'S MISSION & VISION",
+ "INATURALIST-MODE": "INATURALIST MODE",
"INATURALIST-NETWORK": "INATURALIST NETWORK",
"INATURALIST-SETTINGS": "INATURALIST SETTINGS",
"INATURALIST-STAFF": "{ $inaturalist } STAFF",
diff --git a/src/i18n/strings.ftl b/src/i18n/strings.ftl
index ff3bc46e6..884ef3d8b 100644
--- a/src/i18n/strings.ftl
+++ b/src/i18n/strings.ftl
@@ -64,7 +64,7 @@ Add-optional-notes = Add optional notes
Adds-your-vote-of-agreement = Adds your vote of agreement
# Hint for a button that adds a vote of disagreement
Adds-your-vote-of-disagreement = Adds your vote of disagreement
-Advanced--interface-mode = Advanced
+Advanced--interface-mode-with-explainer = Advanced (Upload multiple photos and sounds)
Affiliation = Affiliation: { $site }
# Label for button that adds an identification of the same taxon as another identification
Agree = Agree
@@ -581,7 +581,6 @@ iNaturalist-has-no-ID-suggestions-for-this-photo = iNaturalist has no ID suggest
INATURALIST-HELP-PAGE = INATURALIST HELP PAGE
iNaturalist-helps-you-identify = iNaturalist helps you identify the plants and animals around you while generating data for science and conservation. Get connected with a community of millions scientists and naturalists who can help you learn more about nature!
iNaturalist-identification-suggestions-are-based-on = iNaturalist's identification suggestions are based on observations and identifications made by the iNaturalist community, including { $user1 }, { $user2 }, { $user3 }, and many others.
-INATURALIST-INTERFACE-MODE = INATURALIST INTERFACE MODE
iNaturalist-is-a-501 = iNaturalist is a 501(c)(3) non-profit in the United States of America (Tax ID/EIN 92-1296468).
iNaturalist-is-a-community-of-naturalists = iNaturalist is a community of naturalists that works together to create and identify wild biodiversity observations.
iNaturalist-is-loading-ID-suggestions = iNaturalist is loading ID suggestions...
@@ -589,6 +588,7 @@ iNaturalist-is-supported-by = iNaturalist is supported by an independent, 501(c)
iNaturalist-is-supported-by-our-community = iNaturalist is supported by our amazing community. From everyday naturalists who add observations and identifications, to curators who manage our taxonomy and help with moderation, to the volunteer translators who make iNaturalist more accessible to worldwide audiences, to our community-based donors, we are extraordinarily grateful to all the people in our community who make iNaturalist the platform it is.
iNaturalist-mission-is-to-connect = iNaturalist's mission is to connect people to nature and advance biodiversity science and conservation.
INATURALIST-MISSION-VISION = INATURALIST'S MISSION & VISION
+INATURALIST-MODE = INATURALIST MODE
INATURALIST-NETWORK = INATURALIST NETWORK
INATURALIST-SETTINGS = INATURALIST SETTINGS
# Label for the role a user plays on iNaturalist, e.g. "INATURALIST STAFF"
diff --git a/tests/integration/LanguageSettings.test.js b/tests/integration/LanguageSettings.test.js
index f62eab4f8..080e83f47 100644
--- a/tests/integration/LanguageSettings.test.js
+++ b/tests/integration/LanguageSettings.test.js
@@ -35,6 +35,12 @@ beforeAll( uniqueRealmBeforeAll );
afterAll( uniqueRealmAfterAll );
// /UNIQUE REALM SETUP
+const toggleAdvancedMode = async ( ) => {
+ const advancedRadioButton = await screen
+ .findByText( /Advanced/ );
+ fireEvent.press( advancedRadioButton );
+};
+
describe( "LanguageSettings", ( ) => {
test( "uses locale preference of the local device", ( ) => {
renderAppWithComponent( );
@@ -63,12 +69,14 @@ describe( "LanguageSettings", ( ) => {
test( "uses locale preference from server", async ( ) => {
renderAppWithComponent( );
+ await toggleAdvancedMode( );
const sciNameText = await screen.findByText( /Научное название/ );
expect( sciNameText ).toBeVisible( );
} );
test( "changes locales and updates server with new locale", async ( ) => {
renderAppWithComponent( );
+ await toggleAdvancedMode( );
const changeLocaleButton = await screen.findByText( /CHANGE APP LANGUAGE/ );
fireEvent.press( changeLocaleButton );
const picker = await screen.findByTestId( "ReactNativePicker" );
diff --git a/tests/unit/components/Settings/Settings.test.js b/tests/unit/components/Settings/Settings.test.js
index c4b03932d..00e8a57cf 100644
--- a/tests/unit/components/Settings/Settings.test.js
+++ b/tests/unit/components/Settings/Settings.test.js
@@ -26,6 +26,12 @@ jest.mock( "@react-navigation/native", ( ) => {
const initialStoreState = useStore.getState( );
+const toggleAdvancedMode = async ( ) => {
+ const advancedRadioButton = await screen
+ .findByText( /Advanced/ );
+ fireEvent.press( advancedRadioButton );
+};
+
beforeAll( async ( ) => {
useStore.setState( initialStoreState, true );
// userEvent recommends fake timers
@@ -48,6 +54,7 @@ beforeEach( ( ) => {
describe( "Settings", ( ) => {
it( "should toggle the green observation button", async ( ) => {
renderComponent( );
+ await toggleAdvancedMode( );
const aiCameraRow = await screen.findByLabelText( "iNaturalist AI Camera" );
expect( aiCameraRow ).toHaveProp( "accessibilityState", expect.objectContaining( {
checked: true
@@ -73,6 +80,7 @@ describe( "Settings", ( ) => {
it( "should toggle taxon names display", async ( ) => {
renderComponent( );
+ await toggleAdvancedMode( );
const sciNameFirst = await screen.findByLabelText( "Scientific Name (Common Name)" );
expect( sciNameFirst ).toHaveProp( "accessibilityState", expect.objectContaining( {
checked: false
@@ -110,6 +118,7 @@ describe( "Settings", ( ) => {
it( "should not change state if taxon names toggled with no internet", async ( ) => {
renderComponent( );
+ await toggleAdvancedMode( );
const sciNameFirst = await screen.findByLabelText( "Scientific Name (Common Name)" );
expect( sciNameFirst ).toHaveProp( "accessibilityState", expect.objectContaining( {
checked: false
@@ -135,6 +144,7 @@ describe( "Settings", ( ) => {
test( "should change language immediately via language picker via online results", async ( ) => {
renderComponent( );
+ await toggleAdvancedMode( );
const changeLanguageButton = await screen.findByText( /CHANGE APP LANGUAGE/ );
fireEvent.press( changeLanguageButton );
const picker = await screen.findByTestId( "ReactNativePicker" );