diff --git a/src/api.ts b/src/api.ts index 010b2eaa36..3f268a0cdc 100644 --- a/src/api.ts +++ b/src/api.ts @@ -45,6 +45,7 @@ import { ReciterResponse, TafsirContentResponse, PagesLookUpResponse, + WordByWordTranslationsResponse, } from 'types/ApiResponses'; import AudioData from 'types/AudioData'; import { MushafLines, QuranFont } from 'types/QuranReader'; @@ -100,11 +101,11 @@ export const getAvailableTranslations = async (language: string): Promise} + * @returns {Promise} */ export const getAvailableWordByWordTranslations = async ( language: string, -): Promise => fetcher(makeWordByWordTranslationsUrl(language)); +): Promise => fetcher(makeWordByWordTranslationsUrl(language)); /** * Get the current available languages with the name translated in the current language. diff --git a/src/components/Navbar/SettingsDrawer/WordByWordSection.tsx b/src/components/Navbar/SettingsDrawer/WordByWordSection.tsx index 1afd710038..e796f918ed 100644 --- a/src/components/Navbar/SettingsDrawer/WordByWordSection.tsx +++ b/src/components/Navbar/SettingsDrawer/WordByWordSection.tsx @@ -1,6 +1,6 @@ /* eslint-disable i18next/no-literal-string */ /* eslint-disable max-lines */ -import React from 'react'; +import { useEffect, useState } from 'react'; import { Action } from '@reduxjs/toolkit'; import { useRouter } from 'next/router'; @@ -11,6 +11,7 @@ import { shallowEqual, useSelector } from 'react-redux'; import Section from './Section'; import styles from './WordByWordSection.module.scss'; +import { getAvailableWordByWordTranslations } from '@/api'; import Counter from '@/dls/Counter/Counter'; import Checkbox from '@/dls/Forms/Checkbox/Checkbox'; import Select, { SelectSize } from '@/dls/Forms/Select'; @@ -18,10 +19,10 @@ import Link, { LinkVariant } from '@/dls/Link/Link'; import Separator from '@/dls/Separator/Separator'; import usePersistPreferenceGroup from '@/hooks/auth/usePersistPreferenceGroup'; import { - setSelectedWordByWordLocale, selectReadingPreferences, - setWordByWordDisplay, + setSelectedWordByWordLocale, setWordByWordContentType, + setWordByWordDisplay, setWordClickFunctionality, } from '@/redux/slices/QuranReader/readingPreferences'; import { @@ -31,19 +32,14 @@ import { increaseWordByWordFontScale, selectWordByWordFontScale, } from '@/redux/slices/QuranReader/styles'; +import AvailableWordByWordTranslation from '@/types/AvailableWordByWordTranslation'; import QueryParam from '@/types/QueryParam'; import { WordByWordDisplay, WordByWordType, WordClickFunctionality } from '@/types/QuranReader'; -import { removeItemFromArray } from '@/utils/array'; +import { removeItemFromArray, uniqueArrayByObjectProperty } from '@/utils/array'; import { logValueChange } from '@/utils/eventLogger'; import { getLocaleName } from '@/utils/locale'; import PreferenceGroup from 'types/auth/PreferenceGroup'; -export const WBW_LOCALES = ['en', 'ur', 'id', 'bn', 'tr', 'fa', 'hi', 'ta', 'inh']; -export const WORD_BY_WORD_LOCALES_OPTIONS = WBW_LOCALES.map((locale) => ({ - label: getLocaleName(locale), - value: locale, -})); - const WordByWordSection = () => { const { t, lang } = useTranslation('common'); const { @@ -62,6 +58,33 @@ const WordByWordSection = () => { const wordByWordFontScale = useSelector(selectWordByWordFontScale, shallowEqual); + const [hasError, setHasError] = useState(false); + const [translations, setTranslations] = useState([]); + + useEffect(() => { + getAvailableWordByWordTranslations(lang) + .then((res) => { + if (res.status === 500) { + setHasError(true); + } else { + const data = uniqueArrayByObjectProperty(res.wordByWordTranslations, 'isoCode'); + setTranslations(data); + } + }) + .catch(() => { + setHasError(true); + }); + }, [lang]); + + if (hasError) { + return null; + } + + const WORD_BY_WORD_LOCALES_OPTIONS = translations.map(({ isoCode }) => ({ + label: getLocaleName(isoCode), + value: isoCode, + })); + /** * Persist settings in the DB if the user is logged in before dispatching * Redux action, otherwise just dispatch it. diff --git a/src/utils/array.ts b/src/utils/array.ts index a7f4346340..ceaebb60a1 100644 --- a/src/utils/array.ts +++ b/src/utils/array.ts @@ -70,3 +70,16 @@ export const removeItemFromArray = (itemToRemove: T, array: T[]): T[] => export const mergeTwoArraysUniquely = (array1: T[], array2: T[]): T[] => { return Array.from(new Set(array1.concat(array2))); }; + +/** + * Return a unique array of objects with no dublicates based on an object property + * + * @param {any[]} array + * @param {string} property + * @returns {T[]} + */ +export const uniqueArrayByObjectProperty = (array: any[], property: string) => { + return array.filter( + (obj, index) => array.findIndex((item) => item[property] === obj[property]) === index, + ); +}; diff --git a/types/AvailableWordByWordTranslation.ts b/types/AvailableWordByWordTranslation.ts index 2b81d61deb..6bf7408b73 100644 --- a/types/AvailableWordByWordTranslation.ts +++ b/types/AvailableWordByWordTranslation.ts @@ -1,6 +1,13 @@ import AvailableTranslation from './AvailableTranslation'; +import TranslatedName from './TranslatedName'; interface AvailableWordByWordTranslation extends AvailableTranslation { - isoCode?: string; + id: number; + name: string; + authorName: string; + slug: string; + languageName: string; + isoCode: string; + translatedName: TranslatedName; } export default AvailableWordByWordTranslation;