mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-04-19 21:42:24 +00:00
Compare commits
2 commits
d6f9f3f6d3
...
751f564c4a
Author | SHA1 | Date | |
---|---|---|---|
![]() |
751f564c4a | ||
![]() |
6658f648e6 |
5 changed files with 119 additions and 114 deletions
|
@ -1,103 +0,0 @@
|
||||||
const supportLangs = [
|
|
||||||
{
|
|
||||||
name: "English",
|
|
||||||
value: "en-US",
|
|
||||||
icon: "🇺🇸",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "فارسی",
|
|
||||||
value: "fa-IR",
|
|
||||||
icon: "🇮🇷",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "简体中文",
|
|
||||||
value: "zh-CN",
|
|
||||||
icon: "🇨🇳",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "繁體中文",
|
|
||||||
value: "zh-TW",
|
|
||||||
icon: "🇹🇼",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "日本語",
|
|
||||||
value: "ja-JP",
|
|
||||||
icon: "🇯🇵",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Русский",
|
|
||||||
value: "ru-RU",
|
|
||||||
icon: "🇷🇺",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Tiếng Việt",
|
|
||||||
value: "vi-VN",
|
|
||||||
icon: "🇻🇳",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Español",
|
|
||||||
value: "es-ES",
|
|
||||||
icon: "🇪🇸",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Indonesian",
|
|
||||||
value: "id-ID",
|
|
||||||
icon: "🇮🇩",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Український",
|
|
||||||
value: "uk-UA",
|
|
||||||
icon: "🇺🇦",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Türkçe",
|
|
||||||
value: "tr-TR",
|
|
||||||
icon: "🇹🇷",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Português",
|
|
||||||
value: "pt-BR",
|
|
||||||
icon: "🇧🇷",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
function getLang() {
|
|
||||||
let lang = CookieManager.getCookie("lang");
|
|
||||||
|
|
||||||
if (!lang) {
|
|
||||||
if (window.navigator) {
|
|
||||||
lang = window.navigator.language || window.navigator.userLanguage;
|
|
||||||
|
|
||||||
if (isSupportLang(lang)) {
|
|
||||||
CookieManager.setCookie("lang", lang, 150);
|
|
||||||
} else {
|
|
||||||
CookieManager.setCookie("lang", "en-US", 150);
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
CookieManager.setCookie("lang", "en-US", 150);
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return lang;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setLang(lang) {
|
|
||||||
if (!isSupportLang(lang)) {
|
|
||||||
lang = "en-US";
|
|
||||||
}
|
|
||||||
|
|
||||||
CookieManager.setCookie("lang", lang, 150);
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSupportLang(lang) {
|
|
||||||
for (l of supportLangs) {
|
|
||||||
if (l.value === lang) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
|
@ -515,17 +515,22 @@ class ClipboardManager {
|
||||||
class Base64 {
|
class Base64 {
|
||||||
static encode(content = "", safe = false) {
|
static encode(content = "", safe = false) {
|
||||||
if (safe) {
|
if (safe) {
|
||||||
return window.btoa(content)
|
return Base64.encode(content)
|
||||||
.replace(/\+/g, '-')
|
.replace(/\+/g, '-')
|
||||||
.replace(/=/g, '')
|
.replace(/=/g, '')
|
||||||
.replace(/\//g, '_')
|
.replace(/\//g, '_')
|
||||||
}
|
}
|
||||||
|
|
||||||
return window.btoa(content)
|
return window.btoa(
|
||||||
|
String.fromCharCode(...new TextEncoder().encode(content))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
static decode(content = "") {
|
static decode(content = "") {
|
||||||
return window.atob(content)
|
return new TextDecoder()
|
||||||
|
.decode(
|
||||||
|
Uint8Array.from(window.atob(content), c => c.charCodeAt(0))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,4 +674,108 @@ class URLBuilder {
|
||||||
|
|
||||||
return `${protocol}//${host}${port}${base}${path}`;
|
return `${protocol}//${host}${port}${base}${path}`;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LanguageManager {
|
||||||
|
static supportedLanguages = [
|
||||||
|
{
|
||||||
|
name: "English",
|
||||||
|
value: "en-US",
|
||||||
|
icon: "🇺🇸",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "فارسی",
|
||||||
|
value: "fa-IR",
|
||||||
|
icon: "🇮🇷",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "简体中文",
|
||||||
|
value: "zh-CN",
|
||||||
|
icon: "🇨🇳",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "繁體中文",
|
||||||
|
value: "zh-TW",
|
||||||
|
icon: "🇹🇼",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "日本語",
|
||||||
|
value: "ja-JP",
|
||||||
|
icon: "🇯🇵",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Русский",
|
||||||
|
value: "ru-RU",
|
||||||
|
icon: "🇷🇺",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Tiếng Việt",
|
||||||
|
value: "vi-VN",
|
||||||
|
icon: "🇻🇳",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Español",
|
||||||
|
value: "es-ES",
|
||||||
|
icon: "🇪🇸",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Indonesian",
|
||||||
|
value: "id-ID",
|
||||||
|
icon: "🇮🇩",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Український",
|
||||||
|
value: "uk-UA",
|
||||||
|
icon: "🇺🇦",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Türkçe",
|
||||||
|
value: "tr-TR",
|
||||||
|
icon: "🇹🇷",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Português",
|
||||||
|
value: "pt-BR",
|
||||||
|
icon: "🇧🇷",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
static getLanguage() {
|
||||||
|
let lang = CookieManager.getCookie("lang");
|
||||||
|
|
||||||
|
if (!lang) {
|
||||||
|
if (window.navigator) {
|
||||||
|
lang = window.navigator.language || window.navigator.userLanguage;
|
||||||
|
|
||||||
|
if (LanguageManager.isSupportLanguage(lang)) {
|
||||||
|
CookieManager.setCookie("lang", lang, 150);
|
||||||
|
} else {
|
||||||
|
CookieManager.setCookie("lang", "en-US", 150);
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CookieManager.setCookie("lang", "en-US", 150);
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lang;
|
||||||
|
}
|
||||||
|
|
||||||
|
static setLanguage(language) {
|
||||||
|
if (!LanguageManager.isSupportLanguage(language)) {
|
||||||
|
language = "en-US";
|
||||||
|
}
|
||||||
|
|
||||||
|
CookieManager.setCookie("lang", language, 150);
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
static isSupportLanguage(language) {
|
||||||
|
const languageFilter = LanguageManager.supportedLanguages.filter((lang) => {
|
||||||
|
return lang.value === language
|
||||||
|
})
|
||||||
|
|
||||||
|
return languageFilter.length > 0;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -7,7 +7,6 @@
|
||||||
<script src="{{ .base_path }}assets/js/axios-init.js?{{ .cur_ver }}"></script>
|
<script src="{{ .base_path }}assets/js/axios-init.js?{{ .cur_ver }}"></script>
|
||||||
<script src="{{ .base_path }}assets/js/util/date-util.js?{{ .cur_ver }}"></script>
|
<script src="{{ .base_path }}assets/js/util/date-util.js?{{ .cur_ver }}"></script>
|
||||||
<script src="{{ .base_path }}assets/js/util/index.js?{{ .cur_ver }}"></script>
|
<script src="{{ .base_path }}assets/js/util/index.js?{{ .cur_ver }}"></script>
|
||||||
<script src="{{ .base_path }}assets/js/langs.js"></script>
|
|
||||||
<script>
|
<script>
|
||||||
const basePath = '{{ .base_path }}';
|
const basePath = '{{ .base_path }}';
|
||||||
axios.defaults.baseURL = basePath;
|
axios.defaults.baseURL = basePath;
|
||||||
|
|
|
@ -449,9 +449,9 @@
|
||||||
<a-row justify="center" class="centered">
|
<a-row justify="center" class="centered">
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-select ref="selectLang" v-model="lang"
|
<a-select ref="selectLang" v-model="lang"
|
||||||
@change="setLang(lang)" style="width: 200px;"
|
@change="LanguageManager.setLanguage(lang)" style="width: 200px;"
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-select-option :value="l.value" label="English" v-for="l in supportLangs">
|
<a-select-option :value="l.value" label="English" v-for="l in LanguageManager.supportedLanguages">
|
||||||
<span role="img" aria-label="l.name" v-text="l.icon"></span>
|
<span role="img" aria-label="l.name" v-text="l.icon"></span>
|
||||||
<span v-text="l.name"></span>
|
<span v-text="l.name"></span>
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
|
@ -493,7 +493,7 @@
|
||||||
lang: ""
|
lang: ""
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
this.lang = getLang();
|
this.lang = LanguageManager.getLanguage();
|
||||||
this.secretEnable = await this.getSecretStatus();
|
this.secretEnable = await this.getSecretStatus();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -179,10 +179,10 @@
|
||||||
<template #control>
|
<template #control>
|
||||||
<a-select ref="selectLang"
|
<a-select ref="selectLang"
|
||||||
v-model="lang"
|
v-model="lang"
|
||||||
@change="setLang(lang)"
|
@change="LanguageManager.setLanguage(lang)"
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme"
|
:dropdown-class-name="themeSwitcher.currentTheme"
|
||||||
style="width: 100%">
|
style="width: 100%">
|
||||||
<a-select-option :value="l.value" :label="l.value" v-for="l in supportLangs">
|
<a-select-option :value="l.value" :label="l.value" v-for="l in LanguageManager.supportedLanguages">
|
||||||
<span role="img" :aria-label="l.name" v-text="l.icon"></span> <span v-text="l.name"></span>
|
<span role="img" :aria-label="l.name" v-text="l.icon"></span> <span v-text="l.name"></span>
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
|
@ -344,7 +344,7 @@
|
||||||
<template #title>{{ i18n "pages.settings.telegramBotLanguage"}}</template>
|
<template #title>{{ i18n "pages.settings.telegramBotLanguage"}}</template>
|
||||||
<template #control>
|
<template #control>
|
||||||
<a-select ref="selectBotLang" v-model="allSetting.tgLang" :dropdown-class-name="themeSwitcher.currentTheme" style="width: 100%">
|
<a-select ref="selectBotLang" v-model="allSetting.tgLang" :dropdown-class-name="themeSwitcher.currentTheme" style="width: 100%">
|
||||||
<a-select-option :value="l.value" :label="l.value" v-for="l in supportLangs">
|
<a-select-option :value="l.value" :label="l.value" v-for="l in LanguageManager.supportedLanguages">
|
||||||
<span role="img" :aria-label="l.name" v-text="l.icon"></span> <span v-text="l.name"></span>
|
<span role="img" :aria-label="l.name" v-text="l.icon"></span> <span v-text="l.name"></span>
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
|
@ -672,7 +672,7 @@
|
||||||
allSetting: new AllSetting(),
|
allSetting: new AllSetting(),
|
||||||
saveBtnDisable: true,
|
saveBtnDisable: true,
|
||||||
user: {},
|
user: {},
|
||||||
lang: getLang(),
|
lang: LanguageManager.getLanguage(),
|
||||||
remarkModels: { i: 'Inbound', e: 'Email', o: 'Other' },
|
remarkModels: { i: 'Inbound', e: 'Email', o: 'Other' },
|
||||||
remarkSeparators: [' ', '-', '_', '@', ':', '~', '|', ',', '.', '/'],
|
remarkSeparators: [' ', '-', '_', '@', ':', '~', '|', ',', '.', '/'],
|
||||||
datepickerList: [{ name: 'Gregorian (Standard)', value: 'gregorian' }, { name: 'Jalalian (شمسی)', value: 'jalalian' }],
|
datepickerList: [{ name: 'Gregorian (Standard)', value: 'gregorian' }, { name: 'Jalalian (شمسی)', value: 'jalalian' }],
|
||||||
|
|
Loading…
Reference in a new issue