feat: update language selection to use dropdown and improve tooltip text (#1725)

This commit is contained in:
jeessy2
2026-07-16 21:01:03 +08:00
committed by GitHub
parent 86f0ecc74f
commit bcab5727a6
3 changed files with 54 additions and 36 deletions
+35 -9
View File
@@ -292,18 +292,33 @@ main {
background-color: transparent;
}
.lang-toggle {
.action-button.lang-select {
-webkit-appearance: none;
appearance: none;
height: 30px;
width: 90px;
box-sizing: border-box;
padding: 4px 24px 4px 8px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='%23adbac7' d='M1 0l4 4 4-4 1 1-5 5-5-5z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 8px center;
text-align: left;
cursor: pointer;
}
.lang-toggle:focus {
outline: none;
box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.2);
.lang-select:disabled {
cursor: wait;
opacity: 0.65;
}
[data-theme='dark'] .lang-toggle {
border-color: #adbac7;
.lang-select option {
color: #212529;
background-color: #fff;
}
[data-theme='dark'] .lang-select option {
color: #adbac7;
background-color: #2d333b;
}
.action-button {
@@ -313,7 +328,9 @@ main {
color: #adbac7;
border: 1px solid #adbac7;
border-radius: 8px;
background-color: transparent;
background-color: rgba(255, 255, 255, 0.06);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
transition: border-color 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
text-align: center;
text-decoration: none;
}
@@ -324,11 +341,20 @@ main {
.action-button:focus {
color: #adbac7;
border-color: #adbac7;
background-color: transparent;
background-color: rgba(255, 255, 255, 0.06);
text-decoration: none;
outline: none;
}
.lang-select:hover,
.lang-select:focus,
.logout-button:hover,
.logout-button:focus {
border-color: #fff;
background-color: rgba(255, 255, 255, 0.1);
box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.16);
}
.tooltip[x-placement^="top"] .arrow,
.tooltip[x-placement^="bottom"] .arrow {
left: 50%;
@@ -383,4 +409,4 @@ main {
[data-theme="dark"] .tooltip.bs-tooltip-right .arrow::before {
border-right-color: #2d333b;
}
}
+3 -20
View File
@@ -180,9 +180,9 @@ const I18N_MAP = {
'en': 'OK',
'zh-cn': '确定'
},
'languageToggleTooltip': {
'en': 'Switch language',
'zh-cn': '切换语言'
'languageSelectTooltip': {
'en': 'Select language',
'zh-cn': '选择语言'
},
"Ipv4UrlHelp": {
'en': "https://api.ipify.org, https://ddns.oray.com/checkip, https://ip.3322.net, https://v4.yinghualuo.cn/bejson, https://myip.ipip.net",
@@ -264,8 +264,6 @@ const getCurrentLang = () => {
return localStorage.getItem('lang') || (navigator.language || navigator.browserLanguage).replaceAll('_', '-').toLowerCase();
};
const LANG_SWITCH_OPTIONS = ['zh-cn', 'en'];
const getLocalLang = (langs) => {
const langValue = getCurrentLang();
if (langs.includes(langValue)) {
@@ -302,20 +300,6 @@ const i18n = (keyOrLangDict) => {
return key;
}
const syncLangToggle = (dom = document) => {
dom.querySelectorAll('[data-lang-toggle]').forEach(el => {
if (el.dataset.langToggleInitialized !== 'true') {
el.dataset.langToggleInitialized = 'true';
el.addEventListener('click', () => {
const currentLang = getLocalLang(LANG_SWITCH_OPTIONS);
const nextLang = currentLang === 'zh-cn' ? 'en' : 'zh-cn';
localStorage.setItem('lang', nextLang);
window.location.reload();
});
}
});
}
const convertDom = (dom = document) => {
dom.querySelectorAll('[data-i18n]').forEach(el => {
const key = el.dataset.i18n;
@@ -333,7 +317,6 @@ const convertDom = (dom = document) => {
el.setAttribute(attr, i18n(key));
});
});
syncLangToggle(dom);
}
document.addEventListener('DOMContentLoaded', () => { convertDom(); });
+16 -7
View File
@@ -31,10 +31,11 @@
<span class="theme-button gg-dark-mode" data-toggle="tooltip" data-placement="bottom" data-html="true"
data-i18n-attr="title:themeTooltip" id="themeButton"></span>
<span class="badge badge-secondary">{{.Version}}</span>
<button type="button" class="action-button action-button-text lang-toggle" id="langToggleButton" data-lang-toggle
data-toggle="tooltip" data-placement="bottom" data-i18n-attr="title:languageToggleTooltip" aria-label="Language toggle">
文/A
</button>
<select class="action-button lang-select" id="langSelect" data-toggle="tooltip" data-placement="bottom"
data-i18n-attr="title:languageSelectTooltip" aria-label="Language">
<option value="zh">中文</option>
<option value="en">English</option>
</select>
<a href="./logout" class="action-button action-button-text logout-button" data-i18n="Logout">
Logout
</a>
@@ -626,11 +627,16 @@
return dnsConf[idx].Name || `${idx + 1} - ${_default}`;
}
document.getElementById("langToggleButton").addEventListener('click', async () => {
const nextLang = globalConf.Lang === "zh" || globalConf.Lang === "zh-cn" ? "en" : "zh";
const $langSelect = document.getElementById("langSelect");
$langSelect.value = globalConf.Lang === "zh" || globalConf.Lang === "zh-cn" ? "zh" : "en";
$langSelect.addEventListener('change', async () => {
const previousLang = globalConf.Lang === "zh" || globalConf.Lang === "zh-cn" ? "zh" : "en";
const nextLang = $langSelect.value;
$langSelect.disabled = true;
try {
const resp = await request.post("./setLang", { Lang: nextLang });
if (resp.result !== "ok") {
$langSelect.value = previousLang;
showMessage({
content: resp.result,
type: "error",
@@ -642,11 +648,14 @@
localStorage.setItem('lang', resp.lang);
window.location.reload();
} catch (err) {
$langSelect.value = previousLang;
showMessage({
content: err.toString(),
type: "error",
duration: 5000,
});
} finally {
$langSelect.disabled = false;
}
});
@@ -970,4 +979,4 @@
});
</script>
</html>
</html>