feat: add system language detection and prompt on first launch

This commit is contained in:
pa
2026-03-17 20:31:56 +09:00
parent 6720f1a294
commit 120a4c3533
19 changed files with 323 additions and 34 deletions
+74 -2
View File
@@ -202,9 +202,12 @@
import { useI18n } from 'vue-i18n';
import { z } from 'zod';
import { useAppearanceSettingsStore, useAuthStore, useVrcStatusStore, useVRCXUpdaterStore } from '../../stores';
import { getLanguageName, languageCodes } from '../../localization';
import { useAppearanceSettingsStore, useAuthStore, useModalStore, useVrcStatusStore, useVRCXUpdaterStore } from '../../stores';
import { getLanguageName, languageCodes, resolveSystemLanguage } from '../../localization';
import { tForLocale } from '../../plugins';
import { openExternalLink } from '../../shared/utils';
import configRepository from '../../services/config';
import { useUserDisplay } from '../../composables/useUserDisplay';
import { watchState } from '../../services/watchState';
@@ -221,6 +224,7 @@
const appearanceSettingsStore = useAppearanceSettingsStore();
const { appLanguage } = storeToRefs(appearanceSettingsStore);
const { changeAppLanguage } = appearanceSettingsStore;
const modalStore = useModalStore();
const vrcStatusStore = useVrcStatusStore();
@@ -311,12 +315,80 @@
}
}
);
let isActive = true;
let isLanguagePromptOpen = false;
async function detectAndPromptLanguage() {
try {
const savedLanguage = await configRepository.getString('VRCX_appLanguage');
if (savedLanguage || !isActive) return;
const systemLanguage = await AppApi.CurrentLanguage();
if (!systemLanguage || !isActive) return;
const matchedCode = resolveSystemLanguage(systemLanguage, languageCodes);
if (!matchedCode || matchedCode === 'en') {
if (isActive) await changeAppLanguage('en');
return;
}
const languageName = getLanguageName(matchedCode);
const [
promptTitle,
promptDescription,
promptConfirmText,
promptCancelText
] = await Promise.all([
tForLocale(matchedCode, 'view.login.language_detect.title'),
tForLocale(
matchedCode,
'view.login.language_detect.description',
{
language: languageName
}
),
tForLocale(matchedCode, 'dialog.alertdialog.confirm'),
tForLocale(matchedCode, 'dialog.alertdialog.cancel')
]);
isLanguagePromptOpen = true;
const { ok } = await modalStore.confirm({
title: promptTitle,
description: promptDescription,
confirmText: promptConfirmText,
cancelText: promptCancelText
});
isLanguagePromptOpen = false;
if (!isActive) return;
// Re-check: user may have manually switched language while the dialog was open
const currentLanguage = await configRepository.getString('VRCX_appLanguage');
if (currentLanguage || !isActive) return;
if (ok) {
await changeAppLanguage(matchedCode);
} else {
await changeAppLanguage('en');
}
} catch (error) {
isLanguagePromptOpen = false;
console.error('Language detection failed:', error);
}
}
onBeforeMount(async () => {
updateSavedCredentials();
detectAndPromptLanguage();
});
onBeforeUnmount(() => {
isActive = false;
if (isLanguagePromptOpen) {
modalStore.handleCancel();
isLanguagePromptOpen = false;
}
resetForm({
values: {
username: '',