fix: server overrides user's locale/appearance (#2771)

pull/2776/head
Hanqin Guan 1 year ago committed by GitHub
parent 24bb3e096a
commit 15e6542f0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -82,12 +82,11 @@ const App = () => {
}, [systemStatus.customizedProfile]); }, [systemStatus.customizedProfile]);
useEffect(() => { useEffect(() => {
document.documentElement.setAttribute("lang", locale); const { locale: storageLocale } = storage.get(["locale"]);
i18n.changeLanguage(locale); const currentLocale = storageLocale || userStore?.userSetting?.locale || locale;
storage.set({ i18n.changeLanguage(currentLocale);
locale: locale, document.documentElement.setAttribute("lang", currentLocale);
}); if (currentLocale === "ar") {
if (locale === "ar") {
document.documentElement.setAttribute("dir", "rtl"); document.documentElement.setAttribute("dir", "rtl");
} else { } else {
document.documentElement.setAttribute("dir", "ltr"); document.documentElement.setAttribute("dir", "ltr");
@ -95,12 +94,9 @@ const App = () => {
}, [locale]); }, [locale]);
useEffect(() => { useEffect(() => {
storage.set({ const { appearance: storageAppearance } = storage.get(["appearance"]);
appearance: appearance, let currentAppearance = (storageAppearance || userStore?.userSetting?.appearance || appearance) as Appearance;
}); if (currentAppearance === "system") {
let currentAppearance = appearance;
if (appearance === "system") {
currentAppearance = getSystemColorScheme(); currentAppearance = getSystemColorScheme();
} }

@ -7,10 +7,9 @@ import store, { useAppSelector } from "../";
import { setAppearance, setGlobalState, setLocale } from "../reducer/global"; import { setAppearance, setGlobalState, setLocale } from "../reducer/global";
export const initialGlobalState = async () => { export const initialGlobalState = async () => {
const { locale: storageLocale, appearance: storageAppearance } = storage.get(["locale", "appearance"]);
const defaultGlobalState = { const defaultGlobalState = {
locale: (storageLocale || "en") as Locale, locale: "en" as Locale,
appearance: (storageAppearance || "system") as Appearance, appearance: "system" as Appearance,
systemStatus: { systemStatus: {
allowSignUp: false, allowSignUp: false,
disablePasswordLogin: false, disablePasswordLogin: false,
@ -44,9 +43,19 @@ export const initialGlobalState = async () => {
externalUrl: "", externalUrl: "",
}, },
}; };
// Use storageLocale > userLocale > customizedProfile.locale (server's default locale)
// Initially, storageLocale is undefined and user is not logged in, so use server's default locale.
// User can change locale in login/sign up page, set storageLocale and override userLocale after logged in.
// Otherwise, storageLocale remains undefined and if userLocale has value after user logged in, set to storageLocale and re-render.
// Otherwise, use server's default locale, set to storageLocale.
const { locale: storageLocale, appearance: storageAppearance } = storage.get(["locale", "appearance"]);
defaultGlobalState.locale = defaultGlobalState.locale =
defaultGlobalState.systemStatus.customizedProfile.locale || defaultGlobalState.locale || findNearestLanguageMatch(i18n.language); storageLocale ||
defaultGlobalState.appearance = defaultGlobalState.systemStatus.customizedProfile.appearance || defaultGlobalState.appearance; defaultGlobalState.systemStatus.customizedProfile.locale ||
defaultGlobalState.locale ||
findNearestLanguageMatch(i18n.language);
defaultGlobalState.appearance =
storageAppearance || defaultGlobalState.systemStatus.customizedProfile.appearance || defaultGlobalState.appearance;
} }
store.dispatch(setGlobalState(defaultGlobalState)); store.dispatch(setGlobalState(defaultGlobalState));
}; };
@ -83,9 +92,17 @@ export const useGlobalStore = () => {
); );
}, },
setLocale: (locale: Locale) => { setLocale: (locale: Locale) => {
// Set storageLocale to user selected locale.
storage.set({
locale: locale,
});
store.dispatch(setLocale(locale)); store.dispatch(setLocale(locale));
}, },
setAppearance: (appearance: Appearance) => { setAppearance: (appearance: Appearance) => {
// Set storageAppearance to user selected appearance.
storage.set({
appearance: appearance,
});
store.dispatch(setAppearance(appearance)); store.dispatch(setAppearance(appearance));
}, },
}; };

@ -1,6 +1,9 @@
import { create } from "zustand"; import { create } from "zustand";
import { combine } from "zustand/middleware"; import { combine } from "zustand/middleware";
import { authServiceClient, userServiceClient } from "@/grpcweb"; import { authServiceClient, userServiceClient } from "@/grpcweb";
import storage from "@/helpers/storage";
import store from "@/store";
import { setAppearance, setLocale } from "@/store/reducer/global";
import { User, UserSetting } from "@/types/proto/api/v2/user_service"; import { User, UserSetting } from "@/types/proto/api/v2/user_service";
import { UserNamePrefix, extractUsernameFromName } from "./resourceName"; import { UserNamePrefix, extractUsernameFromName } from "./resourceName";
@ -110,6 +113,22 @@ export const useUserStore = create(
...setting, ...setting,
}), }),
}); });
const userLocale = get().userSetting?.locale;
const userAppearance = get().userSetting?.appearance;
const { locale: storedLocale, appearance: storedAppearance } = storage.get(["locale", "appearance"]);
// Use storageLocale > userLocale > default locale
const locale = storedLocale || userLocale || store.getState().global.locale;
const appearance = (storedAppearance || userAppearance || store.getState().global.appearance) as Appearance;
// If storedLocale is undefined, set storageLocale to userLocale.
if (storedLocale === undefined && storedAppearance === undefined) {
storage.set({ locale: locale });
storage.set({ appearance: appearance });
}
store.dispatch(setLocale(locale));
store.dispatch(setAppearance(appearance));
return user; return user;
}, },
updateUserSetting: async (userSetting: Partial<UserSetting>, updateMask: string[]) => { updateUserSetting: async (userSetting: Partial<UserSetting>, updateMask: string[]) => {

Loading…
Cancel
Save