mirror of
https://git.vectorsigma.ru/public/AdGuardHome.git
synced 2026-07-28 20:19:13 +00:00
fix language change
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"client_settings": "Настройки клиентов"
|
||||
"privacy_policy": "Политика конфиденциальности"
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import escapeRegExp from 'lodash/escapeRegExp';
|
||||
import React from 'react';
|
||||
import { compose } from 'redux';
|
||||
import type { Dispatch } from 'redux';
|
||||
import intl from 'panel/common/intl';
|
||||
import intl, { type LocalesType } from 'panel/common/intl';
|
||||
import {
|
||||
splitByNewLine,
|
||||
sortClients,
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
SETTINGS_NAMES,
|
||||
MANUAL_UPDATE_LINK,
|
||||
DISABLE_PROTECTION_TIMINGS,
|
||||
THEMES,
|
||||
} from '../helpers/constants';
|
||||
import { areEqualVersions } from '../helpers/version';
|
||||
import { getTlsStatus } from './encryption';
|
||||
@@ -32,6 +33,7 @@ import { getFilteringStatus, setRules } from './filtering';
|
||||
|
||||
type SafeSearchConfig = Record<string, boolean> & { enabled: boolean };
|
||||
type ToggleSettingKey = keyof typeof SETTINGS_NAMES;
|
||||
type Theme = typeof THEMES[keyof typeof THEMES];
|
||||
|
||||
export const toggleSettingStatus = createAction<{
|
||||
settingKey: ToggleSettingKey;
|
||||
@@ -441,13 +443,13 @@ export const testUpstreamWithFormValues = (formValues: any) => async (dispatch:
|
||||
|
||||
export const changeLanguageRequest = createAction('CHANGE_LANGUAGE_REQUEST');
|
||||
export const changeLanguageFailure = createAction('CHANGE_LANGUAGE_FAILURE');
|
||||
export const changeLanguageSuccess = createAction('CHANGE_LANGUAGE_SUCCESS');
|
||||
export const changeLanguageSuccess = createAction<{ language: LocalesType }>('CHANGE_LANGUAGE_SUCCESS');
|
||||
|
||||
export const changeLanguage = (lang: any) => async (dispatch: any) => {
|
||||
export const changeLanguage = (lang: LocalesType) => async (dispatch: Dispatch) => {
|
||||
dispatch(changeLanguageRequest());
|
||||
try {
|
||||
await apiClient.changeLanguage({ language: lang });
|
||||
dispatch(changeLanguageSuccess());
|
||||
dispatch(changeLanguageSuccess({ language: lang }));
|
||||
} catch (error) {
|
||||
dispatch(addErrorToast({ error }));
|
||||
dispatch(changeLanguageFailure());
|
||||
@@ -456,9 +458,9 @@ export const changeLanguage = (lang: any) => async (dispatch: any) => {
|
||||
|
||||
export const changeThemeRequest = createAction('CHANGE_THEME_REQUEST');
|
||||
export const changeThemeFailure = createAction('CHANGE_THEME_FAILURE');
|
||||
export const changeThemeSuccess = createAction('CHANGE_THEME_SUCCESS');
|
||||
export const changeThemeSuccess = createAction<{ theme: Theme }>('CHANGE_THEME_SUCCESS');
|
||||
|
||||
export const changeTheme = (theme: any) => async (dispatch: any) => {
|
||||
export const changeTheme = (theme: Theme) => async (dispatch: Dispatch) => {
|
||||
dispatch(changeThemeRequest());
|
||||
try {
|
||||
await apiClient.changeTheme({ theme });
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import axios from 'axios';
|
||||
|
||||
import type { LocalesType } from 'panel/common/intl';
|
||||
|
||||
import { BASE_URL } from '../../constants';
|
||||
|
||||
import { getPathWithQueryString } from '../helpers/helpers';
|
||||
@@ -7,6 +9,8 @@ import { QUERY_LOGS_PAGE_LIMIT, HTML_PAGES, R_PATH_LAST_PART, THEMES } from '../
|
||||
import i18n from '../i18n';
|
||||
import { LANGUAGES } from '../helpers/twosky';
|
||||
|
||||
type Theme = typeof THEMES[keyof typeof THEMES];
|
||||
|
||||
class Api {
|
||||
baseUrl: string;
|
||||
|
||||
@@ -258,8 +262,7 @@ class Api {
|
||||
// }
|
||||
|
||||
// Language
|
||||
|
||||
async changeLanguage(config: any) {
|
||||
async changeLanguage(config: { language: LocalesType }) {
|
||||
const profile = await this.getProfile();
|
||||
profile.language = config.language;
|
||||
|
||||
@@ -267,8 +270,7 @@ class Api {
|
||||
}
|
||||
|
||||
// Theme
|
||||
|
||||
async changeTheme(config: any) {
|
||||
async changeTheme(config: { theme: Theme }) {
|
||||
const profile = await this.getProfile();
|
||||
profile.theme = config.theme;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import ptPt from 'panel/__locales/pt-pt.json';
|
||||
import ru from 'panel/__locales/ru.json';
|
||||
import zhCn from 'panel/__locales/zh-cn.json';
|
||||
import zhTw from 'panel/__locales/zh-tw.json';
|
||||
import { LOCAL_STORAGE_KEYS, LocalStorageHelper } from 'panel/helpers/localStorageHelper';
|
||||
|
||||
export type LocalesType = ReturnType<I18nInterface['getUILanguage']>;
|
||||
|
||||
@@ -37,14 +38,55 @@ const LOCALES = {
|
||||
|
||||
const messages: LocalesTypes = LOCALES;
|
||||
|
||||
export const i18n = (lang: LocalesType) => ({
|
||||
getMessage: (key: string) => messages[lang]?.[key] || '',
|
||||
getUILanguage: () => (lang.includes('zh') ? 'zh' : lang),
|
||||
getBaseMessage: (key: string) => messages.en![key] || key,
|
||||
getBaseUILanguage: () => BASE_LOCALE as LocalesType,
|
||||
});
|
||||
const resolveLanguage = (lng: string): LocalesType => {
|
||||
const l = lng.toLowerCase();
|
||||
|
||||
let currentLanguage: LocalesType = BASE_LOCALE as LocalesType;
|
||||
if (messages[l as LocalesType]) {
|
||||
return l as LocalesType;
|
||||
}
|
||||
|
||||
// Chinese locales
|
||||
if (l.startsWith('zh')) {
|
||||
if (l.includes('tw') || l.includes('hk') || l.includes('mo')) {
|
||||
return 'zh-tw' as LocalesType;
|
||||
}
|
||||
return 'zh-cn' as LocalesType;
|
||||
}
|
||||
|
||||
// Portuguese locales
|
||||
if (l.startsWith('pt')) {
|
||||
if (l.includes('br')) {
|
||||
return 'pt-br' as LocalesType;
|
||||
}
|
||||
return 'pt-pt' as LocalesType;
|
||||
}
|
||||
|
||||
// Try base language (e.g., en-us -> en)
|
||||
const base = l.split('-')[0] as LocalesType;
|
||||
if (messages[base]) {
|
||||
return base;
|
||||
}
|
||||
|
||||
return BASE_LOCALE as LocalesType;
|
||||
};
|
||||
|
||||
export const i18n = (lang: LocalesType) => {
|
||||
const resolved = resolveLanguage(lang);
|
||||
return {
|
||||
getMessage: (key: string) => messages[resolved]?.[key] || '',
|
||||
getUILanguage: () => resolved,
|
||||
getBaseMessage: (key: string) => messages.en![key] || key,
|
||||
getBaseUILanguage: () => BASE_LOCALE as LocalesType,
|
||||
};
|
||||
};
|
||||
|
||||
const detectedLanguage = (
|
||||
(typeof window !== 'undefined' && typeof localStorage !== 'undefined' && LocalStorageHelper.getItem(LOCAL_STORAGE_KEYS.LANGUAGE)) ||
|
||||
(typeof navigator !== 'undefined' && (navigator.language as string)) ||
|
||||
BASE_LOCALE
|
||||
) as LocalesType;
|
||||
|
||||
let currentLanguage: LocalesType = resolveLanguage(detectedLanguage);
|
||||
|
||||
let translator = translate.createReactTranslator<any>(i18n(currentLanguage), React, {
|
||||
tags: [
|
||||
@@ -77,8 +119,9 @@ const intl = {
|
||||
getBaseUILanguage: () => BASE_LOCALE as LocalesType,
|
||||
|
||||
changeLanguage: (newLang: LocalesType) => {
|
||||
currentLanguage = newLang;
|
||||
translator = translate.createReactTranslator<any>(i18n(newLang), React, {
|
||||
const resolved = resolveLanguage(newLang);
|
||||
currentLanguage = resolved;
|
||||
translator = translate.createReactTranslator<any>(i18n(resolved), React, {
|
||||
tags: [
|
||||
{
|
||||
key: 'br',
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Dropdown } from 'panel/common/ui/Dropdown';
|
||||
import { Icon } from 'panel/common/ui/Icon';
|
||||
import intl, { LocalesType } from 'panel/common/intl';
|
||||
|
||||
import { LOCAL_STORAGE_KEYS, LocalStorageHelper } from 'panel/helpers/localStorageHelper';
|
||||
import { REPOSITORY, PRIVACY_POLICY_LINK, THEMES } from '../../../helpers/constants';
|
||||
import { LANGUAGES } from '../../../helpers/twosky';
|
||||
import { setHtmlLangAttr, setUITheme } from '../../../helpers/helpers';
|
||||
@@ -73,11 +74,11 @@ export const Footer = () => {
|
||||
};
|
||||
|
||||
const changeLanguage = async (newLang: LocalesType) => {
|
||||
intl.changeLanguage(newLang);
|
||||
setHtmlLangAttr(newLang);
|
||||
|
||||
try {
|
||||
await dispatch(changeLanguageAction(newLang));
|
||||
LocalStorageHelper.setItem(LOCAL_STORAGE_KEYS.LANGUAGE, newLang);
|
||||
window.location.reload();
|
||||
} catch (error) {
|
||||
console.error('Failed to save language preference:', error);
|
||||
|
||||
@@ -5,6 +5,7 @@ export const LOCAL_STORAGE_KEYS = {
|
||||
CLIENTS_PAGE_SIZE: 'clients_page_size',
|
||||
REWRITES_PAGE_SIZE: 'rewrites_page_size',
|
||||
AUTO_CLIENTS_PAGE_SIZE: 'auto_clients_page_size',
|
||||
LANGUAGE: 'language',
|
||||
};
|
||||
|
||||
export const LocalStorageHelper = {
|
||||
|
||||
@@ -163,6 +163,10 @@ const dashboard = handleActions(
|
||||
theme: payload.theme,
|
||||
processingProfile: false,
|
||||
}),
|
||||
[actions.changeLanguageSuccess.toString()]: (state, { payload }: any) => ({
|
||||
...state,
|
||||
language: payload.language,
|
||||
}),
|
||||
[actions.changeThemeSuccess.toString()]: (state, { payload }: any) => ({
|
||||
...state,
|
||||
theme: payload.theme,
|
||||
@@ -188,6 +192,7 @@ const dashboard = handleActions(
|
||||
supportedTags: [],
|
||||
name: '',
|
||||
theme: undefined,
|
||||
language: undefined,
|
||||
checkUpdateFlag: false,
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user