diff --git a/frontend/src/components/projectCreate/projectCreationMap.js b/frontend/src/components/projectCreate/projectCreationMap.js index 9e98a292d2..89765e0a28 100644 --- a/frontend/src/components/projectCreate/projectCreationMap.js +++ b/frontend/src/components/projectCreate/projectCreationMap.js @@ -7,7 +7,9 @@ import MapboxLanguage from '@mapbox/mapbox-gl-language'; import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder'; import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css'; import { useDropzone } from 'react-dropzone'; + import { mapboxLayerDefn } from '../projects/projectsMap'; +import useMapboxSupportedLanguage from '../../hooks/UseMapboxSupportedLanguage'; import { MAPBOX_TOKEN, @@ -31,7 +33,7 @@ try { const ProjectCreationMap = ({ mapObj, setMapObj, metadata, updateMetadata, step, uploadFile }) => { const mapRef = createRef(); - const locale = useSelector((state) => state.preferences['locale']); + const mapboxSupportedLanguage = useMapboxSupportedLanguage(); const token = useSelector((state) => state.auth.token); const [showProjectsAOILayer, setShowProjectsAOILayer] = useState(true); const [aoiCanBeActivated, setAOICanBeActivated] = useState(false); @@ -85,7 +87,7 @@ const ProjectCreationMap = ({ mapObj, setMapObj, metadata, updateMetadata, step, attributionControl: false, }) .addControl(new mapboxgl.AttributionControl({ compact: false })) - .addControl(new MapboxLanguage({ defaultLanguage: locale.substr(0, 2) || 'en' })) + .addControl(new MapboxLanguage({ defaultLanguage: mapboxSupportedLanguage })) .addControl(new mapboxgl.ScaleControl({ unit: 'metric' })); if (MAPBOX_TOKEN) { map.addControl( @@ -94,7 +96,7 @@ const ProjectCreationMap = ({ mapObj, setMapObj, metadata, updateMetadata, step, mapboxgl: mapboxgl, marker: false, collapsed: true, - language: locale.substr(0, 2) || 'en', + language: mapboxSupportedLanguage, }), 'top-right', ); diff --git a/frontend/src/components/projectEdit/priorityAreasForm.js b/frontend/src/components/projectEdit/priorityAreasForm.js index f0c7bd7d35..25574bca2b 100644 --- a/frontend/src/components/projectEdit/priorityAreasForm.js +++ b/frontend/src/components/projectEdit/priorityAreasForm.js @@ -1,5 +1,4 @@ import { useState, useContext, useLayoutEffect, createRef } from 'react'; -import { useSelector } from 'react-redux'; import mapboxgl from 'mapbox-gl'; import 'mapbox-gl/dist/mapbox-gl.css'; import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'; @@ -25,6 +24,7 @@ import { import { getErrorMsg } from '../projectCreate/fileUploadErrors'; import { Alert } from '../alert'; import WebglUnsupported from '../webglUnsupported'; +import useMapboxSupportedLanguage from '../../hooks/UseMapboxSupportedLanguage'; mapboxgl.accessToken = MAPBOX_TOKEN; try { @@ -35,7 +35,7 @@ try { export const PriorityAreasForm = () => { const { projectInfo, setProjectInfo } = useContext(StateContext); - const locale = useSelector((state) => state.preferences['locale']); + const mapboxSupportedLanguage = useMapboxSupportedLanguage(); const mapRef = createRef(); const [error, setError] = useState({ error: false, message: null }); @@ -129,7 +129,7 @@ export const PriorityAreasForm = () => { attributionControl: false, }) .addControl(new mapboxgl.AttributionControl({ compact: false })) - .addControl(new MapboxLanguage({ defaultLanguage: locale.substr(0, 2) || 'en' })) + .addControl(new MapboxLanguage({ defaultLanguage: mapboxSupportedLanguage })) .addControl(new mapboxgl.NavigationControl()); setMapObj({ ...mapObj, map: map }); diff --git a/frontend/src/components/projects/projectsMap.js b/frontend/src/components/projects/projectsMap.js index 762cfc37ad..64f7a7bb6e 100644 --- a/frontend/src/components/projects/projectsMap.js +++ b/frontend/src/components/projects/projectsMap.js @@ -1,5 +1,4 @@ import { createRef, useLayoutEffect, useState, useCallback } from 'react'; -import { useSelector } from 'react-redux'; import mapboxgl from 'mapbox-gl'; import 'mapbox-gl/dist/mapbox-gl.css'; import MapboxLanguage from '@mapbox/mapbox-gl-language'; @@ -7,6 +6,7 @@ import MapboxLanguage from '@mapbox/mapbox-gl-language'; import WebglUnsupported from '../webglUnsupported'; import { MAPBOX_TOKEN, MAP_STYLE, MAPBOX_RTL_PLUGIN_URL } from '../../config'; import mapMarker from '../../assets/img/mapMarker.png'; +import useMapboxSupportedLanguage from '../../hooks/UseMapboxSupportedLanguage'; let markerIcon = new Image(17, 20); markerIcon.src = mapMarker; @@ -97,8 +97,8 @@ export const mapboxLayerDefn = (map, mapResults, clickOnProjectID, disablePoiCli export const ProjectsMap = ({ mapResults, fullProjectsQuery, setQuery, className }) => { const mapRef = createRef(); - const locale = useSelector((state) => state.preferences['locale']); const [map, setMapObj] = useState(null); + const mapboxSupportedLanguage = useMapboxSupportedLanguage(); const clickOnProjectID = useCallback( (projectIdSearch) => @@ -131,7 +131,7 @@ export const ProjectsMap = ({ mapResults, fullProjectsQuery, setQuery, className attributionControl: false, }) .addControl(new mapboxgl.AttributionControl({ compact: false })) - .addControl(new MapboxLanguage({ defaultLanguage: locale.substr(0, 2) || 'en' })), + .addControl(new MapboxLanguage({ defaultLanguage: mapboxSupportedLanguage })), ); return () => { diff --git a/frontend/src/components/taskSelection/map.js b/frontend/src/components/taskSelection/map.js index 4c0b644bd2..d5236a3159 100644 --- a/frontend/src/components/taskSelection/map.js +++ b/frontend/src/components/taskSelection/map.js @@ -11,6 +11,7 @@ import messages from './messages'; import { MAPBOX_TOKEN, TASK_COLOURS, MAP_STYLE, MAPBOX_RTL_PLUGIN_URL } from '../../config'; import lock from '../../assets/img/lock.png'; import redlock from '../../assets/img/red-lock.png'; +import useMapboxSupportedLanguage from '../../hooks/UseMapboxSupportedLanguage'; let lockIcon = new Image(17, 20); lockIcon.src = lock; @@ -42,7 +43,7 @@ export const TasksMap = ({ }) => { const intl = useIntl(); const mapRef = createRef(); - const locale = useSelector((state) => state.preferences['locale']); + const mapboxSupportedLanguage = useMapboxSupportedLanguage(); const authDetails = useSelector((state) => state.auth.userDetails); const [hoveredTaskId, setHoveredTaskId] = useState(null); @@ -62,7 +63,7 @@ export const TasksMap = ({ attributionControl: false, }) .addControl(new mapboxgl.AttributionControl({ compact: false })) - .addControl(new MapboxLanguage({ defaultLanguage: locale.substr(0, 2) || 'en' })), + .addControl(new MapboxLanguage({ defaultLanguage: mapboxSupportedLanguage })), ); return () => { diff --git a/frontend/src/components/userDetail/countriesMapped.js b/frontend/src/components/userDetail/countriesMapped.js index 322a8d5f75..5f4fa1ee83 100644 --- a/frontend/src/components/userDetail/countriesMapped.js +++ b/frontend/src/components/userDetail/countriesMapped.js @@ -1,5 +1,4 @@ import { createRef, useLayoutEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { useNavigate } from 'react-router-dom'; import mapboxgl from 'mapbox-gl'; import MapboxLanguage from '@mapbox/mapbox-gl-language'; @@ -10,6 +9,7 @@ import { MAPBOX_TOKEN, MAP_STYLE, MAPBOX_RTL_PLUGIN_URL } from '../../config'; import { mapboxLayerDefn } from '../projects/projectsMap'; import { BarListChart } from './barListChart'; import WebglUnsupported from '../webglUnsupported'; +import useMapboxSupportedLanguage from '../../hooks/UseMapboxSupportedLanguage'; mapboxgl.accessToken = MAPBOX_TOKEN; try { @@ -20,7 +20,7 @@ try { const UserCountriesMap = ({ projects }) => { const navigate = useNavigate(); - const locale = useSelector((state) => state.preferences['locale']); + const mapboxSupportedLanguage = useMapboxSupportedLanguage(); const [map, setMap] = useState(null); const mapRef = createRef(); @@ -36,7 +36,7 @@ const UserCountriesMap = ({ projects }) => { attributionControl: false, }) .addControl(new mapboxgl.AttributionControl({ compact: false })) - .addControl(new MapboxLanguage({ defaultLanguage: locale.substr(0, 2) || 'en' })), + .addControl(new MapboxLanguage({ defaultLanguage: mapboxSupportedLanguage })), ); return () => { diff --git a/frontend/src/hooks/UseMapboxSupportedLanguage.js b/frontend/src/hooks/UseMapboxSupportedLanguage.js new file mode 100644 index 0000000000..577fb6407a --- /dev/null +++ b/frontend/src/hooks/UseMapboxSupportedLanguage.js @@ -0,0 +1,23 @@ +import { useSelector } from 'react-redux'; +import MapboxLanguage from '@mapbox/mapbox-gl-language'; + +const { supportedLanguages } = new MapboxLanguage(); + +const defaultLocale = 'en'; + +/** + * A React custom hook to check if the locale language is supported by Mapbox GL or not + * + * Returns `en` if the locale is not supported, else returns preferred locale + * + */ +export default function useMapboxSupportedLanguage() { + const locale = useSelector((state) => state.preferences.locale); + + if (!locale) return defaultLocale; + + const language = locale.substr(0, 2); + if (supportedLanguages.includes(language)) return language; + + return defaultLocale; +}