mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-25 17:54:34 +08:00
fix(home): sequence onboarding modals
This commit is contained in:
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>
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
})
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user