|
| 1 | +import React, { useMemo, useState } from 'react'; |
| 2 | +import PropTypes from 'prop-types'; |
| 3 | +import { publish } from '@edx/frontend-platform'; |
| 4 | +import { |
| 5 | + injectIntl, LOCALE_CHANGED, getLocale, handleRtl, getPrimaryLanguageSubtag, |
| 6 | +} from '@edx/frontend-platform/i18n'; |
| 7 | +import { logError } from '@edx/frontend-platform/logging'; |
| 8 | +import { Dropdown, useWindowSize } from '@openedx/paragon'; |
| 9 | +import { Language } from '@openedx/paragon/icons'; |
| 10 | +import { getCookies } from '@edx/frontend-platform/i18n/lib'; |
| 11 | +import { patchPreferences, postSetLang } from './data'; |
| 12 | + |
| 13 | +const onLanguageSelected = async ({ langCookieName, username, selectedLlocale }) => { |
| 14 | + try { |
| 15 | + if (username) { |
| 16 | + await patchPreferences(username, { prefLang: selectedLlocale }); |
| 17 | + await postSetLang(selectedLlocale); |
| 18 | + } else { |
| 19 | + getCookies().set(langCookieName, selectedLlocale); |
| 20 | + } |
| 21 | + publish(LOCALE_CHANGED, getLocale()); |
| 22 | + handleRtl(); |
| 23 | + } catch (error) { |
| 24 | + logError(error); |
| 25 | + } |
| 26 | +}; |
| 27 | +const getLocaleName = (locale) => { |
| 28 | + const langName = new Intl.DisplayNames([locale], { type: 'language', languageDisplay: 'standard' }).of(locale); |
| 29 | + return langName.replace(/^\w/, (c) => c.toUpperCase()); |
| 30 | +}; |
| 31 | + |
| 32 | +const LanguageSelector = ({ |
| 33 | + langCookieName, options, username, |
| 34 | +}) => { |
| 35 | + const [currentLocale, setLocale] = useState(getLocale()); |
| 36 | + const { width } = useWindowSize(); |
| 37 | + |
| 38 | + const handleSelect = (selectedLlocale) => { |
| 39 | + if (currentLocale !== selectedLlocale) { |
| 40 | + onLanguageSelected({ langCookieName, username, selectedLlocale }); |
| 41 | + } |
| 42 | + setLocale(selectedLlocale); |
| 43 | + }; |
| 44 | + |
| 45 | + const currentLocaleLabel = useMemo(() => { |
| 46 | + if (width < 576) { |
| 47 | + return null; |
| 48 | + } |
| 49 | + if (width < 768) { |
| 50 | + return getPrimaryLanguageSubtag(currentLocale).toUpperCase(); |
| 51 | + } |
| 52 | + return getLocaleName(currentLocale); |
| 53 | + }, [currentLocale, width]); |
| 54 | + |
| 55 | + return ( |
| 56 | + <Dropdown onSelect={handleSelect}> |
| 57 | + <Dropdown.Toggle |
| 58 | + id="lang-selector-dropdown" |
| 59 | + iconBefore={Language} |
| 60 | + variant="outline-primary" |
| 61 | + size="sm" |
| 62 | + > |
| 63 | + {currentLocaleLabel} |
| 64 | + </Dropdown.Toggle> |
| 65 | + <Dropdown.Menu> |
| 66 | + {options.map((locale) => ( |
| 67 | + <Dropdown.Item key={`lang-selector-${locale}`} eventKey={locale}> |
| 68 | + {getLocaleName(locale)} |
| 69 | + </Dropdown.Item> |
| 70 | + ))} |
| 71 | + </Dropdown.Menu> |
| 72 | + </Dropdown> |
| 73 | + ); |
| 74 | +}; |
| 75 | + |
| 76 | +LanguageSelector.propTypes = { |
| 77 | + langCookieName: PropTypes.string.isRequired, |
| 78 | + options: PropTypes.arrayOf(PropTypes.string).isRequired, |
| 79 | + username: PropTypes.string, |
| 80 | +}; |
| 81 | + |
| 82 | +export default injectIntl(LanguageSelector); |
0 commit comments