feat(i18n): add language selector to settings
This commit is contained in:
1 parent
a315ab93c7
commit
a0dcee51bc
6 files changed
+39
-9
No files matched your search
@@ -70,6 +70,8 @@ import AiProviderLogo from "@/components/icons/AiProviderLogo.vue";
|
||||
import AppLogo from "@/components/icons/AppLogo.vue";
|
||||
import type { AppThemeAppearance } from "@/lib/appTheme";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { currentLocale, setLocale, type Locale } from "@/i18n";
|
||||
import { LOCALE_OPTIONS } from "@/lib/localeOptions";
|
||||
|
||||
const { t } = useI18n();
|
||||
const settingsStore = useSettingsStore();
|
||||
@@ -365,6 +367,10 @@ function onThemeChange(v: any) {
|
||||
if (typeof v === "string") editTheme.value = v as typeof DEFAULT_EDITOR_SETTINGS.theme;
|
||||
}
|
||||
|
||||
function onLocaleChange(v: any) {
|
||||
if (typeof v === "string") void setLocale(v as Locale);
|
||||
}
|
||||
|
||||
function onRedisScanPageSizeChange(v: any) {
|
||||
const value = Number(v);
|
||||
if (redisScanPageSizeOptions.includes(value)) editRedisScanPageSize.value = value;
|
||||
@@ -1127,6 +1133,25 @@ watch(
|
||||
</section>
|
||||
|
||||
<section v-else-if="activeSettingsTab === 'appearance'" class="flex flex-col gap-5 py-2">
|
||||
<div class="space-y-2">
|
||||
<Label>{{ t("settings.languageTitle") }}</Label>
|
||||
<Select :model-value="currentLocale()" @update:model-value="onLocaleChange">
|
||||
<SelectTrigger class="min-w-36">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="locale in LOCALE_OPTIONS" :key="locale.value" :value="locale.value">
|
||||
<div class="flex items-center gap-2">
|
||||
<span>{{ locale.flag }}</span>
|
||||
<span>{{ locale.label }}</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<div class="space-y-2">
|
||||
<Label>{{ t("settings.uiScale") }}</Label>
|
||||
<Select
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
DatabaseZap,
|
||||
FilePlus2,
|
||||
Loader2,
|
||||
Globe,
|
||||
Languages,
|
||||
Moon,
|
||||
Sun,
|
||||
SunMoon,
|
||||
@@ -26,12 +26,7 @@ import WindowControls from "@/components/layout/WindowControls.vue";
|
||||
import { shouldReserveMacTrafficLightInset, useWindowControls } from "@/composables/useWindowControls";
|
||||
import { currentLocale, setLocale, type Locale } from "@/i18n";
|
||||
import type { AppThemeMode } from "@/lib/appTheme";
|
||||
|
||||
const localeOptions: { value: Locale; flag: string; label: string }[] = [
|
||||
{ value: "en", flag: "🇺🇸", label: "English" },
|
||||
{ value: "es", flag: "🇪🇸", label: "Español" },
|
||||
{ value: "zh-CN", flag: "🇨🇳", label: "简体中文" },
|
||||
];
|
||||
import { LOCALE_OPTIONS } from "@/lib/localeOptions";
|
||||
|
||||
const props = defineProps<{
|
||||
isDark: boolean;
|
||||
@@ -72,7 +67,7 @@ const themeItems = computed(() => [
|
||||
{ value: "system", label: t("toolbar.themeSystem"), icon: SunMoon },
|
||||
]);
|
||||
const localeItems = computed(() =>
|
||||
localeOptions.map((option) => ({
|
||||
LOCALE_OPTIONS.map((option) => ({
|
||||
value: option.value,
|
||||
label: option.label,
|
||||
leadingText: option.flag,
|
||||
@@ -257,7 +252,7 @@ function onToolbarDblClick(e: MouseEvent) {
|
||||
:model-value="currentLocale()"
|
||||
:items="localeItems"
|
||||
:aria-label="t('common.language')"
|
||||
:trigger-icon="Globe"
|
||||
:trigger-icon="Languages"
|
||||
trigger-class="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
trigger-icon-class="h-4 w-4"
|
||||
:show-trigger-label="false"
|
||||
|
||||
Reference in new issue
Block a user