Handle updates

This commit is contained in:
Manav Rathi 2024-02-24 09:11:24 +05:30
parent c81ecd1ec1
commit e1f5121b4f
5 changed files with 60 additions and 28 deletions

View file

@ -1,14 +1,12 @@
import DropdownInput, { DropdownOption } from 'components/DropdownInput';
import { useLocalState } from '@ente/shared/hooks/useLocalState';
import { t } from 'i18next';
import { useRouter } from 'next/router';
import {
type SupportedLocale,
supportedLocales,
closestSupportedLocale,
getLocaleInUse,
setLocaleInUse,
} from '@/ui/i18n';
import { LS_KEYS } from '@ente/shared/storage/localStorage';
import { getUserLocaleString } from '@ente/shared/storage/localStorage/helpers';
/**
* Human readable name for each supported locale
@ -38,15 +36,12 @@ const getLanguageOptions = (): DropdownOption<SupportedLocale>[] => {
};
export const LanguageSelector = () => {
const [userLocale, setUserLocale] = useLocalState(
LS_KEYS.LOCALE,
closestSupportedLocale(getUserLocaleString())
);
const locale = getLocaleInUse();
// Enhancement: Is this full reload needed?
const router = useRouter();
const updateCurrentLocale = (newLocale: SupportedLocale) => {
setUserLocale(newLocale);
setLocaleInUse(newLocale);
router.reload();
};
@ -55,7 +50,7 @@ export const LanguageSelector = () => {
options={getLanguageOptions()}
label={t('LANGUAGE')}
labelProps={{ color: 'text.muted' }}
selected={userLocale}
selected={locale}
setSelected={updateCurrentLocale}
/>
);

View file

@ -29,10 +29,6 @@ export function setLivePhotoInfoShownCount(count: boolean) {
setData(LS_KEYS.LIVE_PHOTO_INFO_SHOWN_COUNT, { count });
}
export function getUserLocaleString(): string {
return getData(LS_KEYS.LOCALE)?.value;
}
export function getLocalMapEnabled(): boolean {
return getData(LS_KEYS.MAP_ENABLED)?.value ?? false;
}

View file

@ -21,7 +21,8 @@ export enum LS_KEYS {
THEME = 'theme',
WAIT_TIME = 'waitTime',
API_ENDPOINT = 'apiEndpoint',
LOCALE = 'locale',
// Moved to the new wrapper @/utils/local-storage
// LOCALE = 'locale',
MAP_ENABLED = 'mapEnabled',
SRP_SETUP_ATTRIBUTES = 'srpSetupAttributes',
SRP_ATTRIBUTES = 'srpAttributes',

View file

@ -36,6 +36,8 @@ export const supportedLocales = [
/** The type of {@link supportedLocales}. */
export type SupportedLocale = (typeof supportedLocales)[number];
const defaultLocale: SupportedLocale = "en-US";
/**
* Load translations.
*
@ -82,7 +84,7 @@ export const setupI18n = async () => {
returnEmptyString: false,
// The language to use if translation for a particular key in the
// current `lng` is not available.
fallbackLng: "en-US",
fallbackLng: defaultLocale,
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
@ -153,6 +155,7 @@ const savedLocaleStringMigratingIfNeeded = () => {
const newValue = mapOldValue(value);
if (newValue) setLSString("locale", newValue);
return newValue;
};
@ -184,9 +187,9 @@ const mapOldValue = (value: string | undefined) => {
* If {@link savedLocaleString} is `undefined`, it tries to deduce the closest
* {@link SupportedLocale} that matches the browser's locale.
*/
export function closestSupportedLocale(
const closestSupportedLocale = (
savedLocaleString?: string,
): SupportedLocale {
): SupportedLocale => {
const ss = savedLocaleString;
if (ss && includes(supportedLocales, ss)) return ss;
@ -209,5 +212,36 @@ export function closestSupportedLocale(
}
// Fallback
return "en-US";
}
return defaultLocale;
};
/**
* Return the locale that is currently being used to show the app's UI.
*
* Note that this may be different from the user's locale. For example, the
* browser might be set to en-GB, but since we don't support that specific
* variant of English, this value will be (say) en-US.
*/
export const getLocaleInUse = (): SupportedLocale => {
const locale = i18n.resolvedLanguage;
if (locale && includes(supportedLocales, locale)) {
return locale;
} else {
// This shouldn't have happened. Log an error to attract attention.
logError(
`Expected the i18next locale to be one of the supported values, but instead found ${locale}`,
);
return defaultLocale;
}
};
/**
* Set the locale that should be used to show the app's UI.
*
* This updates both the i18next state, and also the corresponding user
* preference that is stored in local storage.
*/
export const setLocaleInUse = async (locale: SupportedLocale) => {
setLSString("locale", locale);
return i18n.changeLanguage(locale);
};

View file

@ -1,11 +1,11 @@
/**
* Log an error
*
* The {@link message} property describes what went wrong. Generally in such
* situations we also have an "error" object that has specific details about the
* issue - that gets passed as the second parameter.
* The {@link message} property describes what went wrong. Generally (but not
* always) in such situations we also have an "error" object that has specific
* details about the issue - that gets passed as the second parameter.
*
* Note that the "error" {@link e} is not typed. This is because in JavaScript,
* Note that the "error" {@link e} is not typed. This is because in JavaScript
* any arbitrary value can be thrown. So this function allows us to pass it an
* arbitrary value as the error, and will internally figure out how best to deal
* with it.
@ -16,10 +16,16 @@
* route and show this error elsewhere.
*
* TODO (MR): Currently this is a placeholder function to funnel error logs
* through. This needs to do what the existing logError does, but it cannot have
* a direct Sentry dependency here. For now, we just log on the console.
* through. This needs to do what the existing logError in @ente/shared does,
* but it cannot have a direct Electron/Sentry dependency here. For now, we just
* log on the console.
*/
export const logError = (message: string, e: unknown) => {
export const logError = (message: string, e?: unknown) => {
if (e === undefined || e === null) {
console.error(message);
return;
}
let es: string;
if (e instanceof Error) {
// In practice, we expect ourselves to be called with Error objects, so