fix(home): sequence onboarding modals

This commit is contained in:
digua committed 2026-05-19 23:55:00 +08:00
1 parent 415dcefc7d
commit 9c93aa9701
4 files changed
+41 -18

No files matched your search

@@ -5,6 +5,7 @@ import { useSettingsStore } from '@/stores/settings'
import UITabs from '@/components/UI/Tabs.vue'
import { availableLocales, type LocaleType } from '@/i18n'
import { usePreferencesService } from '@/services'
import { resolveLanguageBootstrap } from '../onboardingFlow'
const emit = defineEmits<{
(e: 'done'): void
@@ -30,8 +31,10 @@ const currentLocale = computed({
onMounted(async () => {
try {
const savedLocale = await usePreferencesService().getLocale()
if (!savedLocale) {
isOpen.value = true
const bootstrap = resolveLanguageBootstrap(savedLocale)
isOpen.value = bootstrap.shouldOpenLanguageModal
if (bootstrap.shouldContinue) {
emit('done')
}
} catch {
isOpen.value = true
@@ -45,12 +48,6 @@ function handleNext() {
isOpen.value = false
emit('done')
}
function wasSkipped(): boolean {
return !isOpen.value
}
defineExpose({ wasSkipped })
</script>
<template>
+2 -10
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import LanguageSelectModal from './components/LanguageSelectModal.vue'
import AgreementModal from './components/AgreementModal.vue'
@@ -11,17 +11,9 @@ import HomeFooter from './components/HomeFooter.vue'
const { t } = useI18n()
// 弹窗引用
const languageSelectRef = ref<InstanceType<typeof LanguageSelectModal> | null>(null)
const changelogModalRef = ref<InstanceType<typeof ChangelogModal> | null>(null)
const agreementModalRef = ref<InstanceType<typeof AgreementModal> | null>(null)
onMounted(() => {
// 已有语言设置(非首次用户)→ 直接检查协议
if (languageSelectRef.value?.wasSkipped() && agreementModalRef.value?.needsAgreement()) {
agreementModalRef.value.open()
}
})
// 语言选择完成后,检查是否需要显示协议弹窗
function onLanguageSelectDone() {
if (agreementModalRef.value?.needsAgreement()) {
@@ -101,7 +93,7 @@ const features = computed(() => [
</div>
<!-- 新用户语言选择弹窗 -->
<LanguageSelectModal ref="languageSelectRef" @done="onLanguageSelectDone" />
<LanguageSelectModal @done="onLanguageSelectDone" />
<!-- 用户协议弹窗 -->
<AgreementModal ref="agreementModalRef" />
+18
View File
@@ -0,0 +1,18 @@
import assert from 'node:assert/strict'
import test from 'node:test'
import { resolveLanguageBootstrap } from './onboardingFlow.ts'
test('新用户没有保存语言时应先打开语言选择,不继续后续弹窗流程', () => {
assert.deepEqual(resolveLanguageBootstrap(''), {
shouldOpenLanguageModal: true,
shouldContinue: false,
})
})
test('已有保存语言时应跳过语言选择并继续后续弹窗流程', () => {
assert.deepEqual(resolveLanguageBootstrap('zh-CN'), {
shouldOpenLanguageModal: false,
shouldContinue: true,
})
})
+16
View File
@@ -0,0 +1,16 @@
export interface LanguageBootstrapResult {
shouldOpenLanguageModal: boolean
shouldContinue: boolean
}
/**
* 根据后端保存的语言配置决定首次启动弹窗流程。
* 空语言代表新用户,需要先完成语言选择,避免用户协议和语言弹窗同时打开。
*/
export function resolveLanguageBootstrap(savedLocale: string | null | undefined): LanguageBootstrapResult {
const hasSavedLocale = Boolean(savedLocale)
return {
shouldOpenLanguageModal: !hasSavedLocale,
shouldContinue: hasSavedLocale,
}
}