fix: polish settings toggles and favicon wiring

- make the forgot-password toggle save independently with clearer disabled-state feedback

- add the app logo as the browser tab icon and remove redundant AI settings helper copy

- update settings and layout regression checks for the new toggle and favicon behavior
This commit is contained in:
SmileQWQ
2026-05-11 21:39:55 +08:00
parent 7c18c55134
commit 373a2e5de2
4 changed files with 48 additions and 6 deletions

View File

@@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/png" href="/src/assets/brand-logo.png" />
<title>SubTracker</title>
</head>
<body>

View File

@@ -455,9 +455,6 @@
<n-switch v-model:value="settingsForm.aiConfig.enabled" />
<span class="switch-label">启用 AI 能力</span>
</n-form-item>
<n-alert type="info" :show-icon="false" style="margin-bottom: 12px">
AI 能力总开关控制识别与连接测试AI 总结可单独开启或关闭
</n-alert>
<n-grid :cols="formCols" :x-gap="12" :y-gap="12">
<n-grid-item>
@@ -559,9 +556,23 @@
<div class="switch-group switch-group--single">
<div class="switch-group__item">
<span class="switch-inline-label">允许通过通知验证码找回密码</span>
<n-tooltip v-if="!forgotPasswordToggleUnlocked" trigger="hover">
<template #trigger>
<div class="switch-disabled-wrapper">
<n-switch
v-model:value="settingsForm.forgotPasswordEnabled"
:disabled="true"
/>
</div>
</template>
<span>需先启用至少一个直达通知渠道</span>
</n-tooltip>
<n-switch
v-else
v-model:value="settingsForm.forgotPasswordEnabled"
:disabled="!forgotPasswordToggleUnlocked"
:loading="savingForgotPasswordToggle"
:disabled="savingForgotPasswordToggle"
@update:value="handleForgotPasswordToggleChange"
/>
</div>
</div>
@@ -850,6 +861,7 @@ const savingGotifySettings = ref(false)
const savingWebhookSettings = ref(false)
const savingAiSettings = ref(false)
const savingCredentials = ref(false)
const savingForgotPasswordToggle = ref(false)
const sourceCurrency = ref('USD')
const targetCurrency = ref('CNY')
const converterAmount = ref(1)
@@ -1369,6 +1381,25 @@ async function submitCredentialsChange() {
}
}
async function handleForgotPasswordToggleChange(value: boolean) {
if (savingForgotPasswordToggle.value) return
const previousValue = settingsForm.forgotPasswordEnabled
settingsForm.forgotPasswordEnabled = value
savingForgotPasswordToggle.value = true
try {
const result = await api.updateSettings({
forgotPasswordEnabled: value
})
applySavedSettings(result)
message.success(value ? '找回密码已开启' : '找回密码已关闭')
} catch (error) {
settingsForm.forgotPasswordEnabled = previousValue
message.error(error instanceof Error ? error.message : '找回密码设置保存失败')
} finally {
savingForgotPasswordToggle.value = false
}
}
async function testEmail() {
if (!validateEmailSettings('test')) return
try {
@@ -1630,6 +1661,10 @@ function previewSettingsReminderRules() {
min-height: 34px;
}
.switch-disabled-wrapper {
display: inline-flex;
}
.label-with-tip {
display: inline-flex;
align-items: center;

View File

@@ -5,6 +5,7 @@ describe('app layout sidebar behavior', () => {
it('keeps desktop sidebar fixed and menu independently scrollable', () => {
const source = readFileSync('src/App.vue', 'utf8')
const globalStyle = readFileSync('src/style.css', 'utf8')
const html = readFileSync('index.html', 'utf8')
expect(source).toContain('content-style="overflow: visible;"')
expect(source).toContain('class="desktop-sider"')
@@ -21,5 +22,7 @@ describe('app layout sidebar behavior', () => {
expect(globalStyle).toContain('background: #111827;')
expect(globalStyle).toContain('#app {')
expect(globalStyle).toContain('background: var(--app-bg);')
expect(html).toContain('rel="icon"')
expect(html).toContain('/src/assets/brand-logo.png')
})
})

View File

@@ -46,9 +46,9 @@ describe('settings import export section', () => {
expect(source).toContain('title="AI 能力设置"')
expect(source).toContain('启用 AI 能力')
expect(source).toContain('AI 总结')
expect(source).toContain('AI 能力总开关控制识别与连接测试AI 总结可单独开启或关闭')
expect(source).toContain('自定义识别提示词')
expect(source).toContain('自定义总结提示词')
expect(source).not.toContain('AI 能力总开关控制识别与连接测试AI 总结可单独开启或关闭')
expect(source).not.toContain('title="AI 识别设置"')
expect(source).not.toContain('启用 AI 识别')
})
@@ -74,7 +74,10 @@ describe('settings import export section', () => {
expect(source).toContain('允许通过通知验证码找回密码')
expect(source).toContain('settingsForm.forgotPasswordEnabled')
expect(source).toContain('forgotPasswordToggleUnlocked')
expect(source).toContain(":disabled=\"!forgotPasswordToggleUnlocked\"")
expect(source).toContain('savingForgotPasswordToggle')
expect(source).toContain('handleForgotPasswordToggleChange')
expect(source).toContain('需先启用至少一个直达通知渠道')
expect(source).toContain("@update:value=\"handleForgotPasswordToggleChange\"")
expect(source).toContain('switch-group switch-group--single')
expect(source).toContain('switch-inline-label')
expect(source).toContain('label="新密码"')