fix(ux): preserve localized save errors and current language retries
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import React, { createContext, useCallback, useContext, useEffect, useState } from "react";
|
||||
import React, { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
|
||||
import { translations, TranslationKey, UiLanguage } from "./translations";
|
||||
import { api } from "../api";
|
||||
import { useOptionalToast } from "../toast";
|
||||
|
||||
type TranslationParams = Record<string, string | number>;
|
||||
|
||||
@@ -19,12 +20,16 @@ function interpolate(template: string, params?: TranslationParams) {
|
||||
}
|
||||
|
||||
export function I18nProvider({ children }: { children: React.ReactNode }) {
|
||||
const feedback = useOptionalToast();
|
||||
const [language, setLanguageState] = useState<UiLanguage>(() => {
|
||||
const raw = window.localStorage.getItem("uiLanguage");
|
||||
return raw === "nb" || raw === "nb-NO" || raw === "no" ? "nb" : "en";
|
||||
});
|
||||
const currentLanguage = useRef(language);
|
||||
const languageSaveSequence = useRef(0);
|
||||
|
||||
const applyLanguage = useCallback((l: UiLanguage) => {
|
||||
currentLanguage.current = l;
|
||||
setLanguageState(l);
|
||||
window.localStorage.setItem("uiLanguage", l);
|
||||
document.documentElement.lang = l === "nb" ? "nb-NO" : "en";
|
||||
@@ -32,7 +37,16 @@ export function I18nProvider({ children }: { children: React.ReactNode }) {
|
||||
|
||||
const setLanguage = (l: UiLanguage) => {
|
||||
applyLanguage(l);
|
||||
void api.put("/auth/preferences/language", { language: l === "nb" ? "nb-NO" : "en" }).catch(() => undefined);
|
||||
const requestSequence = ++languageSaveSequence.current;
|
||||
void api.put("/auth/preferences/language", { language: l === "nb" ? "nb-NO" : "en" }).catch(() => {
|
||||
if (requestSequence !== languageSaveSequence.current || currentLanguage.current !== l) return;
|
||||
feedback?.toast(translations[l].settingsLanguageSaveFailed, "error", {
|
||||
label: translations[l].retry,
|
||||
onClick: () => {
|
||||
if (requestSequence === languageSaveSequence.current && currentLanguage.current === l) setLanguage(l);
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const hydrateLanguage = useCallback((value?: string | null) => {
|
||||
|
||||
@@ -1149,6 +1149,7 @@ export const translations = {
|
||||
settingsLanguageTitle: "Language and localization",
|
||||
settingsLanguageBody: "Set your preferred app language. This is also the language used when deciding whether imported job descriptions should show translated text.",
|
||||
settingsPreferredLanguage: "Preferred language",
|
||||
settingsLanguageSaveFailed: "The language changed on this device, but your account preference could not be saved.",
|
||||
settingsEnglish: "English",
|
||||
settingsNorwegian: "Norwegian Bokmål",
|
||||
settingsJobs: "Jobs",
|
||||
@@ -3732,6 +3733,7 @@ export const translations = {
|
||||
settingsLanguageTitle: "Språk og lokalisering",
|
||||
settingsLanguageBody: "Velg foretrukket språk i appen. Dette brukes også når appen avgjør om importerte stillingsbeskrivelser skal vise oversatt tekst.",
|
||||
settingsPreferredLanguage: "Foretrukket språk",
|
||||
settingsLanguageSaveFailed: "Språket er endret på denne enheten, men kunne ikke lagres på kontoen din.",
|
||||
settingsEnglish: "Engelsk",
|
||||
settingsNorwegian: "Norsk Bokmål",
|
||||
settingsJobs: "Jobber",
|
||||
|
||||
Reference in New Issue
Block a user