diff --git a/app/soapbox/actions/settings.ts b/app/soapbox/actions/settings.ts index 79ffe19752..fdc6f394cd 100644 --- a/app/soapbox/actions/settings.ts +++ b/app/soapbox/actions/settings.ts @@ -1,9 +1,10 @@ import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet } from 'immutable'; -import { defineMessages } from 'react-intl'; +import { defineMessage } from 'react-intl'; import { createSelector } from 'reselect'; import { v4 as uuid } from 'uuid'; import { patchMe } from 'soapbox/actions/me'; +import messages from 'soapbox/locales/messages'; import toast from 'soapbox/toast'; import { isLoggedIn } from 'soapbox/utils/auth'; @@ -21,9 +22,7 @@ type SettingOpts = { showAlert?: boolean } -const messages = defineMessages({ - saveSuccess: { id: 'settings.save.success', defaultMessage: 'Your preferences have been saved!' }, -}); +const saveSuccessMessage = defineMessage({ id: 'settings.save.success', defaultMessage: 'Your preferences have been saved!' }); const defaultSettings = ImmutableMap({ onboarded: false, @@ -40,7 +39,7 @@ const defaultSettings = ImmutableMap({ defaultPrivacy: 'public', defaultContentType: 'text/plain', themeMode: 'system', - locale: navigator.language.split(/[-_]/)[0] || 'en', + locale: navigator.language || 'en', showExplanationBox: true, explanationBox: true, autoloadTimelines: true, @@ -221,7 +220,7 @@ const saveSettingsImmediate = (opts?: SettingOpts) => dispatch({ type: SETTING_SAVE }); if (opts?.showAlert) { - toast.success(messages.saveSuccess); + toast.success(saveSuccessMessage); } }).catch(error => { toast.showAlertForError(error); @@ -231,6 +230,12 @@ const saveSettingsImmediate = (opts?: SettingOpts) => const saveSettings = (opts?: SettingOpts) => (dispatch: AppDispatch) => dispatch(saveSettingsImmediate(opts)); +const getLocale = (state: RootState, fallback = 'en') => { + const localeWithVariant = (getSettings(state).get('locale') as string).replace('_', '-'); + const locale = localeWithVariant.split('-')[0]; + return Object.keys(messages).includes(localeWithVariant) ? localeWithVariant : Object.keys(messages).includes(locale) ? locale : fallback; +}; + export { SETTING_CHANGE, SETTING_SAVE, @@ -242,4 +247,5 @@ export { changeSetting, saveSettingsImmediate, saveSettings, + getLocale, }; diff --git a/app/soapbox/actions/streaming.ts b/app/soapbox/actions/streaming.ts index c9095e0218..f3e393f274 100644 --- a/app/soapbox/actions/streaming.ts +++ b/app/soapbox/actions/streaming.ts @@ -1,4 +1,4 @@ -import { getSettings } from 'soapbox/actions/settings'; +import { getLocale, getSettings } from 'soapbox/actions/settings'; import messages from 'soapbox/locales/messages'; import { ChatKeys, IChat, isLastMessage } from 'soapbox/queries/chats'; import { queryClient } from 'soapbox/queries/client'; @@ -34,13 +34,6 @@ import type { APIEntity, Chat } from 'soapbox/types/entities'; const STREAMING_CHAT_UPDATE = 'STREAMING_CHAT_UPDATE'; const STREAMING_FOLLOW_RELATIONSHIPS_UPDATE = 'STREAMING_FOLLOW_RELATIONSHIPS_UPDATE'; -const validLocale = (locale: string) => Object.keys(messages).includes(locale); - -const getLocale = (state: RootState) => { - const locale = getSettings(state).get('locale') as string; - return validLocale(locale) ? locale : 'en'; -}; - const updateFollowRelationships = (relationships: APIEntity) => (dispatch: AppDispatch, getState: () => RootState) => { const me = getState().me; diff --git a/app/soapbox/hooks/useLocale.ts b/app/soapbox/hooks/useLocale.ts index 98619d969a..21302e1748 100644 --- a/app/soapbox/hooks/useLocale.ts +++ b/app/soapbox/hooks/useLocale.ts @@ -1,15 +1,12 @@ -import MESSAGES from 'soapbox/locales/messages'; +import { getLocale } from 'soapbox/actions/settings'; -import { useSettings } from './useSettings'; +import { useAppSelector } from './useAppSelector'; import type { CSSProperties } from 'react'; /** Locales which should be presented in right-to-left. */ const RTL_LOCALES = ['ar', 'ckb', 'fa', 'he']; -/** Ensure the given locale exists in our codebase */ -const validLocale = (locale: string): boolean => Object.keys(MESSAGES).includes(locale); - interface UseLocaleResult { locale: string direction: CSSProperties['direction'] @@ -17,13 +14,7 @@ interface UseLocaleResult { /** Get valid locale from settings. */ const useLocale = (fallback = 'en'): UseLocaleResult => { - const settings = useSettings(); - const userLocale = settings.get('locale') as unknown; - - const locale = - (typeof userLocale === 'string' && validLocale(userLocale)) - ? userLocale - : fallback; + const locale = useAppSelector((state) => getLocale(state, fallback)); const direction: CSSProperties['direction'] = RTL_LOCALES.includes(locale)