diff --git a/e2e/signedIn.e2e.js b/e2e/signedIn.e2e.js index a544c3805..8c2ce6467 100644 --- a/e2e/signedIn.e2e.js +++ b/e2e/signedIn.e2e.js @@ -145,7 +145,7 @@ describe( "Signed in user", () => { await element( by.id( `ObsDetails.${uuid}` ) ).scrollTo( "bottom" ); const comment = element( by.text( "This is a comment" ) ); await waitFor( comment ).toBeVisible().withTimeout( 10000 ); - await element( by.label( "Navigate back" ) ).tap( ); + await element( by.label( "Go back" ) ).tap( ); await waitFor( username ).toBeVisible( ).withTimeout( 10000 ); /* diff --git a/metro.config.js b/metro.config.js index 2a479ab1a..a79cf4c35 100644 --- a/metro.config.js +++ b/metro.config.js @@ -12,6 +12,10 @@ const { resolver: { sourceExts, assetExts } } = getDefaultConfig(); +const localPackagePaths = [ + // If you reference any local paths in package.json, you'll need to list them here +]; + /** * Metro configuration * https://facebook.github.io/metro/docs/configuration @@ -27,8 +31,10 @@ const config = { sourceExts: process.env.MOCK_MODE === "e2e" ? ["e2e-mock", ...sourceExts, "svg"] - : [...sourceExts, "svg"] - } + : [...sourceExts, "svg"], + nodeModulesPaths: [...localPackagePaths] + }, + watchFolders: [...localPackagePaths] }; module.exports = mergeConfig( getDefaultConfig( __dirname ), config ); diff --git a/src/components/AddObsModal.js b/src/components/AddObsModal.js index d20d5fff3..b95489597 100644 --- a/src/components/AddObsModal.js +++ b/src/components/AddObsModal.js @@ -159,7 +159,7 @@ const AddObsModal = ( { closeModal }: Props ): React.Node => { className="h-[69px] w-[69px] bg-inatGreen rounded-full" onPress={( ) => closeModal( )} accessibilityLabel={t( "Close" )} - accessibilityHint={t( "Close-add-observation-modal" )} + accessibilityHint={t( "Closes-new-observation-options" )} /> diff --git a/src/components/Camera/Buttons/GreenCheckmark.js b/src/components/Camera/Buttons/GreenCheckmark.js index 652cb539c..014557ca5 100644 --- a/src/components/Camera/Buttons/GreenCheckmark.js +++ b/src/components/Camera/Buttons/GreenCheckmark.js @@ -20,8 +20,8 @@ const GreenCheckmark = ( { return ( setShowDiscardSheet( false )} - headerText={t( "DISCARD-PHOTOS" )} + headerText={t( "DISCARD-PHOTOS--question" )} text={t( "By-exiting-your-photos-will-not-be-saved" )} secondButtonText={t( "CANCEL" )} handleSecondButtonPress={( ) => setShowDiscardSheet( false )} diff --git a/src/components/Explore/Header/Header.js b/src/components/Explore/Header/Header.js index dad2a56cb..3b8b7ad4c 100644 --- a/src/components/Explore/Header/Header.js +++ b/src/components/Explore/Header/Header.js @@ -68,6 +68,7 @@ const Header = ( { {taxon ? ( setMediaToDelete( null )} confirm={confirmDelete} - headerText={t( "DISCARD-MEDIA" )} + headerText={t( "DISCARD-MEDIA--question" )} buttonText={t( "DISCARD" )} secondButtonText={t( "CANCEL" )} handleSecondButtonPress={( ) => setMediaToDelete( null )} diff --git a/src/components/ObsDetails/ActivityTab/ActivityHeader.js b/src/components/ObsDetails/ActivityTab/ActivityHeader.js index 174d9a70c..1d7a25379 100644 --- a/src/components/ObsDetails/ActivityTab/ActivityHeader.js +++ b/src/components/ObsDetails/ActivityTab/ActivityHeader.js @@ -163,7 +163,7 @@ const ActivityHeader = ( { {( currentUser && showDeleteCommentSheet ) && ( setShowDeleteCommentSheet( false )} - headerText={t( "DELETE-COMMENT-QUESTION" )} + headerText={t( "DELETE-COMMENT--question" )} confirm={deleteComment} buttonText={t( "DELETE" )} handleSecondButtonPress={( ) => setShowDeleteCommentSheet( false )} diff --git a/src/components/ObsDetails/ActivityTab/FloatingButtons.js b/src/components/ObsDetails/ActivityTab/FloatingButtons.js index 1ef2f7a59..ce3e5408f 100644 --- a/src/components/ObsDetails/ActivityTab/FloatingButtons.js +++ b/src/components/ObsDetails/ActivityTab/FloatingButtons.js @@ -51,7 +51,7 @@ const FloatingButtons = ( { className="w-1/2 mx-6" testID="ObsDetail.cvSuggestionsButton" accessibilityRole="link" - accessibilityHint={t( "Navigates-to-suggest-identification" )} + accessibilityHint={t( "Shows-identification-suggestions" )} /> ); diff --git a/src/components/ObsDetails/DetailsTab/CoordinatesCopiedNotification.js b/src/components/ObsDetails/DetailsTab/CoordinatesCopiedNotification.js index 5b96462ca..010f04daf 100644 --- a/src/components/ObsDetails/DetailsTab/CoordinatesCopiedNotification.js +++ b/src/components/ObsDetails/DetailsTab/CoordinatesCopiedNotification.js @@ -28,7 +28,7 @@ const CoordinatesCopiedNotification = ( ): React.Node => { style={getShadowForColor( theme.colors.primary )} > - {t( "Coordinates-copied-to-keyboard" )} + {t( "Coordinates-copied-to-clipboard" )} removeVote( { metric, vote: true } )} - accessibilityLabel={t( "Arrow-up-selected" )} + accessibilityLabel={t( "Add-agreement" )} + accessibilityHint={t( "Adds-your-vote-of-agreement" )} /> ); } @@ -86,7 +87,8 @@ const DQAVoteButtons = ( { icon="arrow-up-bold-circle-outline" size={33} onPress={() => setVote( { metric, vote: true } )} - accessibilityLabel={t( "Arrow-up-unselected" )} + accessibilityLabel={t( "Remove-agreement" )} + accessibilityHint={t( "Removes-your-vote-of-agreement" )} /> ); }; @@ -104,7 +106,8 @@ const DQAVoteButtons = ( { size={33} color={theme.colors.error} onPress={() => removeVote( { metric, vote: false } )} - accessibilityLabel={t( "Arrow-down-selected" )} + accessibilityLabel={t( "Remove-disagreement" )} + accessibilityHint={t( "Removes-your-vote-of-disagreement" )} /> ); } @@ -114,7 +117,8 @@ const DQAVoteButtons = ( { icon="arrow-down-bold-circle-outline" size={33} onPress={() => setVote( { metric, vote: false } )} - accessibilityLabel={t( "Arrow-down-unselected" )} + accessibilityLabel={t( "Add-disagreement" )} + accessibilityHint={t( "Adds-your-vote-of-disagreement" )} /> ); }; diff --git a/src/components/ObsDetails/DetailsTab/DetailsTab.js b/src/components/ObsDetails/DetailsTab/DetailsTab.js index 27f866457..96ce3f8d4 100644 --- a/src/components/ObsDetails/DetailsTab/DetailsTab.js +++ b/src/components/ObsDetails/DetailsTab/DetailsTab.js @@ -198,7 +198,7 @@ const DetailsTab = ( { observation }: Props ): Node => { {t( "DATE" )} )} diff --git a/src/components/ObsEdit/Sheets/DeleteObservationSheet.js b/src/components/ObsEdit/Sheets/DeleteObservationSheet.js index 78b58a800..bedabde0f 100644 --- a/src/components/ObsEdit/Sheets/DeleteObservationSheet.js +++ b/src/components/ObsEdit/Sheets/DeleteObservationSheet.js @@ -58,7 +58,7 @@ const DeleteObservationSheet = ( { return ( ( - - - - {user.login} - {user.name} - - - {t( "Unblock" )} - - -); - -export default BlockedUser; diff --git a/src/components/Settings/MutedUser.js b/src/components/Settings/MutedUser.js deleted file mode 100644 index 8cbfc3dcc..000000000 --- a/src/components/Settings/MutedUser.js +++ /dev/null @@ -1,40 +0,0 @@ -// @flow - -import { t } from "i18next"; -import type { Node } from "react"; -import React from "react"; -import { - Image, - Pressable, - Text, - View -} from "react-native"; -import { viewStyles } from "styles/settings/settings"; - -type Props = { - unmuteUser: Function, - user: Object -} - -const MutedUser = ( { user, unmuteUser }: Props ): Node => ( - - - - {user.login} - {user.name} - - - {t( "Unmute" )} - - -); - -export default MutedUser; diff --git a/src/components/Settings/PlaceSearchInput.js b/src/components/Settings/PlaceSearchInput.js deleted file mode 100644 index 6127ac5bb..000000000 --- a/src/components/Settings/PlaceSearchInput.js +++ /dev/null @@ -1,98 +0,0 @@ -// import { useQueryClient } from "@tanstack/react-query"; -// import fetchPlace from "api/places"; -// import fetchSearchResults from "api/search"; -// import inatPlaceTypes from "dictionaries/places"; -// import React, { useEffect } from "react"; -// import { -// Image, Text, TextInput, View -// } from "react-native"; -// import Pressable from "react-native/Libraries/Components/Pressable/Pressable"; -// import useAuthenticatedQuery from "sharedHooks/useAuthenticatedQuery"; -// import { textStyles, viewStyles } from "styles/settings/settings"; -// import { useDebounce } from "use-debounce"; - -// const PlaceSearchInput = ( { placeId, onPlaceChanged } ): React.Node => { -// const [hideResults, setHideResults] = React.useState( true ); -// const [placeSearch, setPlaceSearch] = React.useState( "" ); -// // So we'll start searching only once the user finished typing -// const [finalPlaceSearch] = useDebounce( placeSearch, 500 ); - -// const queryClient = useQueryClient( ); - -// // this seems necessary for clearing the cache between searches -// queryClient.invalidateQueries( { queryKey: ["fetchSearchResults"] } ); - -// const { -// data: placeResults -// } = useAuthenticatedQuery( -// ["fetchSearchResults", finalPlaceSearch], -// optsWithAuth => fetchSearchResults( { -// q: finalPlaceSearch, -// sources: "places", -// fields: "place,place.display_name,place.place_type" -// }, optsWithAuth ) -// ); - -// const { -// data: placeDetails -// } = useAuthenticatedQuery( -// ["fetchPlace", placeId], -// optsWithAuth => fetchPlace( placeId, optsWithAuth ) -// ); - -// useEffect( () => { -// if ( placeDetails ) { -// setPlaceSearch( placeDetails.display_name ); -// } else { -// setPlaceSearch( "" ); -// } -// }, [placeDetails] ); - -// return ( -// -// -// { -// setHideResults( false ); -// setPlaceSearch( v ); -// }} -// value={placeSearch} -// /> -// { -// setHideResults( true ); -// setPlaceSearch( "" ); -// onPlaceChanged( 0 ); -// }} -// > -// -// -// -// {!hideResults && finalPlaceSearch.length > 0 && placeResults?.map( place => ( -// { -// setHideResults( true ); -// onPlaceChanged( place.id ); -// }} -// > -// {place.display_name} -// {inatPlaceTypes[place.place_type]} -// -// ) )} -// -// ); -// }; - -// export default PlaceSearchInput; diff --git a/src/components/Settings/Relationship.js b/src/components/Settings/Relationship.js deleted file mode 100644 index 07ba93a0d..000000000 --- a/src/components/Settings/Relationship.js +++ /dev/null @@ -1,65 +0,0 @@ -// @flow - -import { Checkbox } from "components/SharedComponents"; -import { t } from "i18next"; -import type { Node } from "react"; -import React from "react"; -import { - Image, - Pressable, - Text, - View -} from "react-native"; -import { viewStyles } from "styles/settings/settings"; - -type Props = { - relationship: Object, - updateRelationship: Function, - askToRemoveRelationship: Function -} - -const Relationship = ( { - askToRemoveRelationship, - relationship, - updateRelationship -}: Props ): Node => ( - - - - - {relationship.friendUser.login} - {relationship.friendUser.name} - - - { updateRelationship( relationship, { following: !relationship.following } ); } - } - text={t( "Following" )} - /> - { updateRelationship( relationship, { trust: !relationship.trust } ); } - } - text={t( "Trust-with-hidden-coordinates" )} - /> - - - {t( "Added-on-date", { date: relationship.created_at } )} - askToRemoveRelationship( relationship )} - > - {t( "Remove-Relationship" )} - - -); - -export default Relationship; diff --git a/src/components/Settings/SettingsAccount.js b/src/components/Settings/SettingsAccount.js deleted file mode 100644 index 2063006fe..000000000 --- a/src/components/Settings/SettingsAccount.js +++ /dev/null @@ -1,79 +0,0 @@ -// @flow - -import { Picker } from "@react-native-picker/picker"; -import { Checkbox } from "components/SharedComponents"; -import inatLanguages from "dictionaries/languages"; -import inatNetworks from "dictionaries/networks"; -import { t } from "i18next"; -import type { Node } from "react"; -import React from "react"; -import { Text, View } from "react-native"; -import { textStyles, viewStyles } from "styles/settings/settings"; -import colors from "styles/tailwindColors"; - -import PlaceSearchInput from "./PlaceSearchInput"; -import type { SettingsProps } from "./types"; - -const SettingsAccount = ( { settings, onSettingsModified }: SettingsProps ): Node => ( - <> - {t( "Account" )} - - {t( "Language-Locale" )} - {t( "This-sets-your-language-and-date-formatting-preferences-across-iNaturalist" )} - - onSettingsModified( { ...settings, locale: itemValue } ) - } - > - {Object.keys( inatLanguages ).map( k => ( - - ) )} - - - - {t( "Default-Search-Place" )} - {t( "This-will-be-your-default-place-for-all-searches-in-Explore-and-Identify" )} - onSettingsModified( { ...settings, search_place_id: p } )} - /> - - {t( "Privacy" )} - onSettingsModified( { ...settings, prefers_no_tracking: v } )} - text={t( "Do-not-collect-stability-and-usage-data-using-third-party-services" )} - /> - {t( "iNaturalist-Network-Affiliation" )} - - onSettingsModified( { ...settings, site_id: itemValue } ) - } - > - {Object.keys( inatNetworks ).map( k => ( - - ) )} - - - {t( "The-iNaturalist-Network-is-a-collection-of-localized-websites" )} - - -); - -export default SettingsAccount; diff --git a/src/components/Settings/SettingsApplications.js b/src/components/Settings/SettingsApplications.js deleted file mode 100644 index 5ece3a9ac..000000000 --- a/src/components/Settings/SettingsApplications.js +++ /dev/null @@ -1,116 +0,0 @@ -// @flow - -import { useQueryClient } from "@tanstack/react-query"; -import { - fetchAuthorizedApplications, revokeAuthorizedApplications -} from "api/authorizedApplications"; -import fetchProviderAuthorizations from "api/providerAuthorizations"; -import inatProviders from "dictionaries/providers"; -import { t } from "i18next"; -import type { Node } from "react"; -import React from "react"; -import { Alert, Text, View } from "react-native"; -import Pressable from "react-native/Libraries/Components/Pressable/Pressable"; -import useAuthenticatedMutation from "sharedHooks/useAuthenticatedMutation"; -import useAuthenticatedQuery from "sharedHooks/useAuthenticatedQuery"; -import { textStyles, viewStyles } from "styles/settings/settings"; - -const SettingsApplications = ( ): Node => { - const { - data: authorizedApps, - refetch - } = useAuthenticatedQuery( - ["fetchAuthorizedApplications"], - optsWithAuth => fetchAuthorizedApplications( { }, optsWithAuth ) - ); - - const { - data: providerAuthorizations - } = useAuthenticatedQuery( - ["fetchProviderAuthorizations"], - optsWithAuth => fetchProviderAuthorizations( { }, optsWithAuth ) - ); - - const queryClient = useQueryClient( ); - - const revokeAppMutation = useAuthenticatedMutation( - ( params, optsWithAuth ) => revokeAuthorizedApplications( params, optsWithAuth ), - { - onSuccess: ( ) => { - queryClient.invalidateQueries( { queryKey: ["fetchAuthorizedApplications"] } ); - refetch( ); - } - } - ); - - const revokeApp = async appId => { - revokeAppMutation.mutate( { id: appId } ); - }; - - const askToRevokeApp = app => { - Alert.alert( - `Revoke ${app.application.name}?`, - "This will sign you out of your current session on this application.", - [ - { text: "Revoke", onPress: () => revokeApp( app.application.id ) } - ], - { - cancelable: true - } - ); - }; - - return ( - - {t( "iNaturalist-Applications" )} - {authorizedApps?.filter( app => app.application.official ).map( app => ( - - - {app.application.name} - - askToRevokeApp( app )} - > - {t( "Revoke" )} - - - ) )} - - {t( "Connected-Accounts" )} - {Object.keys( inatProviders ).map( providerKey => { - const connectedProvider = providerAuthorizations?.find( - x => x.provider_name === providerKey - ); - return ( - - {inatProviders[providerKey]} - {" "} - {connectedProvider && `(authorized on: ${connectedProvider.created_at})`} - - ); - } )} - - {t( "External-Applications" )} - {authorizedApps?.filter( app => !app.application.official ).map( app => ( - - - {t( "app-authorized-on-date", { appName: app.application.name, date: app.created_at } )} - - askToRevokeApp( app )} - > - {t( "Revoke" )} - - - ) )} - - ); -}; - -export default SettingsApplications; diff --git a/src/components/Settings/SettingsContentDisplay.js b/src/components/Settings/SettingsContentDisplay.js deleted file mode 100644 index b8a677d3a..000000000 --- a/src/components/Settings/SettingsContentDisplay.js +++ /dev/null @@ -1,223 +0,0 @@ -// @flow - -import { Picker } from "@react-native-picker/picker"; -import { Checkbox } from "components/SharedComponents"; -import inatLicenses from "dictionaries/licenses"; -import { t } from "i18next"; -import type { Node } from "react"; -import React from "react"; -import { Text, View } from "react-native"; -import { textStyles, viewStyles } from "styles/settings/settings"; -import colors from "styles/tailwindColors"; - -import PlaceSearchInput from "./PlaceSearchInput"; -import type { SettingsProps } from "./types"; - -const PROJECT_SETTINGS = { - any: "Any", - joined: "Projects you've joined", - none: "None, only you can add your observations to projects" -}; - -const TAXON_DISPLAY = { - prefers_common_names: "Common Name (Scientific Name)", - prefers_scientific_name_first: "Scientific Name (Common Name)", - prefers_scientific_names: "Scientific Name" -}; - -const ADD_OBSERVATION_FIELDS = { - anyone: "Anyone", - curators: "Curators", - observer: "Only you" -}; - -const LicenseSelector = ( { - value, - onValueChanged, - title, - updateExistingTitle, - onUpdateExisting, - updateExisting -} ): Node => ( - <> - {title} - - - {inatLicenses.map( l => ( - - ) )} - - - - -); - -const SettingsContentDisplay = ( { settings, onSettingsModified }: SettingsProps ): Node => { - let taxonNamePreference = "prefers_common_names"; - if ( settings.prefers_scientific_name_first ) { - taxonNamePreference = "prefers_scientific_name_first"; - } else if ( settings.prefers_scientific_names ) { - taxonNamePreference = "prefers_scientific_names"; - } - - return ( - <> - {t( "Project-Settings" )} - - {t( "Which-traditional-projects-can-add-your-observations" )} - - - onSettingsModified( { - ...settings, - preferred_project_addition_by: itemValue - } )} - > - {Object.keys( PROJECT_SETTINGS ).map( k => ( - - ) )} - - - - {t( "Taxonomy-Settings" )} - { - onSettingsModified( { ...settings, prefers_automatic_taxonomic_changes: v } ); - }} - text={t( "Automatically-update-my-content-for-taxon-changes" )} - /> - {t( "Names" )} - {t( "Display" )} - {t( "This-is-how-all-taxon-names-will-be-displayed-to-you-across-iNaturalist" )} - - { - if ( value === "prefers_common_names" ) { - onSettingsModified( { - ...settings, - prefers_common_names: true, - prefers_scientific_name_first: false - } ); - } else if ( value === "prefers_scientific_name_first" ) { - onSettingsModified( { - ...settings, - prefers_common_names: true, - prefers_scientific_name_first: true - } ); - } else if ( value === "prefers_scientific_names" ) { - onSettingsModified( { - ...settings, - prefers_common_names: false, - prefers_scientific_name_first: false - } ); - } - }} - > - {Object.keys( TAXON_DISPLAY ).map( k => ( - - ) )} - - - {t( "Prioritize-common-names-used-in-this-place" )} - onSettingsModified( { ...settings, place_id: p } )} - /> - - - {t( "Community-Moderation-Settings" )} - - { - onSettingsModified( { ...settings, prefers_community_taxa: v } ); - }} - text={t( "Accept-community-identifications" )} - /> - - {t( "Who-can-add-observation-fields-to-my-observations" )} - - - onSettingsModified( { - ...settings, - preferred_observation_fields_by: itemValue - } )} - > - {Object.keys( ADD_OBSERVATION_FIELDS ).map( k => ( - - ) )} - - - - {t( "Licensing" )} - onSettingsModified( { - ...settings, - preferred_observation_license: v - } )} - updateExistingTitle="Update existing observations with new license choices" - updateExisting={settings.make_observation_licenses_same} - onUpdateExisting={v => onSettingsModified( { - ...settings, - make_observation_licenses_same: v - } )} - /> - onSettingsModified( { ...settings, preferred_photo_license: v } )} - updateExistingTitle="Update existing photos with new license choices" - updateExisting={settings.make_photo_licenses_same} - onUpdateExisting={v => onSettingsModified( { ...settings, make_photo_licenses_same: v } )} - /> - onSettingsModified( { ...settings, preferred_sound_license: v } )} - updateExistingTitle="Update existing sounds with new license choices" - updateExisting={settings.make_sound_licenses_same} - onUpdateExisting={v => onSettingsModified( { ...settings, make_sound_licenses_same: v } )} - /> - - ); -}; - -export default SettingsContentDisplay; diff --git a/src/components/Settings/SettingsNotifications.js b/src/components/Settings/SettingsNotifications.js deleted file mode 100644 index 8cb904640..000000000 --- a/src/components/Settings/SettingsNotifications.js +++ /dev/null @@ -1,98 +0,0 @@ -// @flow - -import { Checkbox } from "components/SharedComponents"; -import { t } from "i18next"; -import type { Node } from "react"; -import React from "react"; -import { Text, View } from "react-native"; -import Switch from "react-native/Libraries/Components/Switch/Switch"; -import { textStyles, viewStyles } from "styles/settings/settings"; - -import type { SettingsProps } from "./types"; - -const EMAIL_NOTIFICATIONS = { - Comments: "prefers_comment_email_notification", - Identifications: "prefers_identification_email_notification", - Mentions: "prefers_mention_email_notification", - Messages: "prefers_message_email_notification", - "Project journal posts": "prefers_project_journal_post_email_notification", - // eslint-disable-next-line max-len - "When a project adds your observations": "prefers_project_added_your_observation_email_notification", - "Project curator changes": "prefers_project_curator_change_email_notification", - "Taxonomy changes": "prefers_taxon_change_email_notification", - "Observations by people I follow": "prefers_user_observation_email_notification", - // eslint-disable-next-line max-len - "Observations of taxa or from places that I subscribe to": "prefers_taxon_or_place_observation_email_notification" -}; - -const EmailNotification = ( { title, value, onValueChange } ): Node => ( - -); - -const Notification = ( { - title, description, value, onValueChange -} ): Node => ( - - - {title} - {description} - - - - - -); - -const SettingsNotifications = ( { settings, onSettingsModified }: SettingsProps ): Node => ( - <> - {t( "iNaturalist-Activity-Notifications" )} - onSettingsModified( { ...settings, prefers_receive_mentions: v } )} - /> - onSettingsModified( { - ...settings, - prefers_redundant_identification_notifications: v - } )} - /> - {t( "Email-Notifications" )} - onSettingsModified( { ...settings, prefers_no_email: !v } )} - /> - - {!settings.prefers_no_email - && ( - <> - {Object.keys( EMAIL_NOTIFICATIONS ).map( k => ( - onSettingsModified( { ...settings, [EMAIL_NOTIFICATIONS[k]]: v } ) - } - /> - ) )} - - )} - -); - -export { EMAIL_NOTIFICATIONS, SettingsNotifications }; diff --git a/src/components/Settings/SettingsProfile.js b/src/components/Settings/SettingsProfile.js deleted file mode 100644 index f17f26ec9..000000000 --- a/src/components/Settings/SettingsProfile.js +++ /dev/null @@ -1,97 +0,0 @@ -// @flow - -import { t } from "i18next"; -import type { Node } from "react"; -import React from "react"; -import { - Button, Image, Text, TextInput, View -} from "react-native"; -// $FlowIgnore -import { launchImageLibrary } from "react-native-image-picker"; -import { viewStyles } from "styles/settings/settings"; - -import type { SettingsProps } from "./types"; - -const SettingsProfile = ( { settings, onSettingsModified }: SettingsProps ): Node => { - let profileSource; - if ( settings.newProfilePhoto && !settings.removeProfilePhoto ) { - profileSource = { uri: settings.newProfilePhoto.uri }; - } else if ( - settings.icon && !settings.removeProfilePhoto ) { - profileSource = { uri: settings.icon }; - } else { - profileSource = require( "images/profile.png" ); - } - - const onImageSelected = response => { - if ( response.didCancel ) { return; } - onSettingsModified( { - ...settings, - newProfilePhoto: response.assets[0], - removeProfilePhoto: false - } ); - }; - - return ( - <> - {t( "Profile-Picture" )} - - - -