fix: enable frosted glass effect by default
This commit is contained in:
+1
-1
@@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
两种主题必须保持相同的信息层级,但不要求机械地反转明暗。浅色主题以白色主内容画布、冰蓝灰侧栏和轻微着色的顶栏建立空间关系;深色主题使用深海军蓝与蓝灰表面逐层提亮,避免纯黑。蓝色承担主要选择和交互,青绿色主要承担成功与可用状态,二者不得混用语义。
|
两种主题必须保持相同的信息层级,但不要求机械地反转明暗。浅色主题以白色主内容画布、冰蓝灰侧栏和轻微着色的顶栏建立空间关系;深色主题使用深海军蓝与蓝灰表面逐层提亮,避免纯黑。蓝色承担主要选择和交互,青绿色主要承担成功与可用状态,二者不得混用语义。
|
||||||
|
|
||||||
外观设置提供“透明磨砂特效”开关,当前默认关闭,文字在左、共享 Switch 在右。选择保存在应用设置中,保存成功后立即生效,重启后恢复。开启时,右侧内容框架顶栏的背景不透明度在浅色主题为 65%、深色主题为 70%,保留 18px 背景模糊与淡分隔线。聊天滚动视口向上延伸 58px,消息上滚时实际经过顶栏背后;不使用人工渐变充当背景。初始留白放在滚动内容中,包含顶栏高度和当前任务/待办条的实测高度,首条消息仍从这些控件下方开始。任务/待办条固定在顶栏下方并保持实色;展开的 Runtime 待办卡片使用两主题各自的 75% 不透明背景、18px 背景模糊和清晰的文字颜色。
|
外观设置提供“透明磨砂特效”开关,默认开启,文字在左、共享 Switch 在右。新用户及缺少该字段的旧配置使用开启状态;已保存的开关选择保持不变。选择保存在应用设置中,保存成功后立即生效,重启后恢复。开启时,右侧内容框架顶栏的背景不透明度在浅色主题为 65%、深色主题为 70%,保留 18px 背景模糊与淡分隔线。聊天滚动视口向上延伸 58px,消息上滚时实际经过顶栏背后;不使用人工渐变充当背景。初始留白放在滚动内容中,包含顶栏高度和当前任务/待办条的实测高度,首条消息仍从这些控件下方开始。任务/待办条固定在顶栏下方并保持实色;展开的 Runtime 待办卡片使用两主题各自的 75% 不透明背景、18px 背景模糊和清晰的文字颜色。
|
||||||
|
|
||||||
已保存的开关状态同步到文档根节点,卸载时清理,使 body/top layer 中的待办卡片也能应用样式;其他菜单保持原有表面。输入区、右侧工作栏和非聊天页面保持原有位置,聊天加载态及无活动消息面板时不扩展视口。窗口拖拽和控制按钮保持原有行为;该效果不透出操作系统桌面。关闭后恢复顶栏下方的聊天布局,顶栏与待办卡片均恢复实色。`tests/frosted-glass.electron.test.ts` 使用真实 `ChatHistoryPane` 检查消息与顶栏的可见矩形交叠、初始留白、关闭恢复、浅深主题、跳底、历史加载锚点和会话切换。
|
已保存的开关状态同步到文档根节点,卸载时清理,使 body/top layer 中的待办卡片也能应用样式;其他菜单保持原有表面。输入区、右侧工作栏和非聊天页面保持原有位置,聊天加载态及无活动消息面板时不扩展视口。窗口拖拽和控制按钮保持原有行为;该效果不透出操作系统桌面。关闭后恢复顶栏下方的聊天布局,顶栏与待办卡片均恢复实色。`tests/frosted-glass.electron.test.ts` 使用真实 `ChatHistoryPane` 检查消息与顶栏的可见矩形交叠、初始留白、关闭恢复、浅深主题、跳底、历史加载锚点和会话切换。
|
||||||
|
|
||||||
|
|||||||
@@ -75,18 +75,18 @@ describe('ApplicationSettingsStore', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it.each([11, 12])('defaults missing frosted glass to off in version %s', async (version) => {
|
it.each([11, 12])('defaults missing frosted glass to on in version %s', async (version) => {
|
||||||
const { filePath, store } = await createStore()
|
const { filePath, store } = await createStore()
|
||||||
const legacy: Record<string, unknown> = { ...defaultApplicationSettings, version, lastSeenReleaseNotesVersion: null, checkUpdatesOnStartup: false }
|
const legacy: Record<string, unknown> = { ...defaultApplicationSettings, version, lastSeenReleaseNotesVersion: null, checkUpdatesOnStartup: false }
|
||||||
delete legacy.transparentFrostedEffectEnabled
|
delete legacy.transparentFrostedEffectEnabled
|
||||||
await writeFile(filePath, JSON.stringify(legacy))
|
await writeFile(filePath, JSON.stringify(legacy))
|
||||||
expect(await store.get()).toEqual({ ...defaultApplicationSettings, checkUpdatesOnStartup: false })
|
expect(await store.get()).toEqual({ ...defaultApplicationSettings, checkUpdatesOnStartup: false })
|
||||||
expect(applicationSettingsSchema.parse({ ...defaultApplicationSettings, transparentFrostedEffectEnabled: undefined }).transparentFrostedEffectEnabled).toBe(false)
|
expect(applicationSettingsSchema.parse({ ...defaultApplicationSettings, transparentFrostedEffectEnabled: undefined }).transparentFrostedEffectEnabled).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('persists and publishes both frosted glass choices across unrelated updates and reloads', async () => {
|
it('persists and publishes both frosted glass choices across unrelated updates and reloads', async () => {
|
||||||
const { filePath, store } = await createStore()
|
const { filePath, store } = await createStore()
|
||||||
expect((await store.get()).transparentFrostedEffectEnabled).toBe(false)
|
expect((await store.get()).transparentFrostedEffectEnabled).toBe(true)
|
||||||
const changed = vi.fn()
|
const changed = vi.fn()
|
||||||
store.onChanged(changed)
|
store.onChanged(changed)
|
||||||
for (const transparentFrostedEffectEnabled of [true, false]) {
|
for (const transparentFrostedEffectEnabled of [true, false]) {
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ export const resolveLegacyLocalToolEnvironmentPaths: LegacyLocalToolEnvironmentR
|
|||||||
export const defaultApplicationSettings: ApplicationSettings = {
|
export const defaultApplicationSettings: ApplicationSettings = {
|
||||||
checkUpdatesOnStartup: true,
|
checkUpdatesOnStartup: true,
|
||||||
desktopNotificationsEnabled: true,
|
desktopNotificationsEnabled: true,
|
||||||
transparentFrostedEffectEnabled: false,
|
transparentFrostedEffectEnabled: true,
|
||||||
updateSource: 'github',
|
updateSource: 'github',
|
||||||
modelDownloadSource: 'modelscope',
|
modelDownloadSource: 'modelscope',
|
||||||
localToolEnvironment: defaultLocalToolEnvironmentSettings,
|
localToolEnvironment: defaultLocalToolEnvironmentSettings,
|
||||||
|
|||||||
@@ -11173,7 +11173,7 @@ function App(): React.JSX.Element {
|
|||||||
<Suspense fallback={null}>
|
<Suspense fallback={null}>
|
||||||
<SettingsPanel
|
<SettingsPanel
|
||||||
appearanceTheme={appearanceTheme}
|
appearanceTheme={appearanceTheme}
|
||||||
transparentFrostedEffectEnabled={applicationSettings?.transparentFrostedEffectEnabled ?? false}
|
transparentFrostedEffectEnabled={applicationSettings?.transparentFrostedEffectEnabled ?? true}
|
||||||
applicationSettingsPending={applicationSettingsPending}
|
applicationSettingsPending={applicationSettingsPending}
|
||||||
applicationSettingsLocked={applicationSettingsUnconfirmed || !applicationSettings}
|
applicationSettingsLocked={applicationSettingsUnconfirmed || !applicationSettings}
|
||||||
applicationSettingsError={applicationSettingsError}
|
applicationSettingsError={applicationSettingsError}
|
||||||
|
|||||||
@@ -1583,17 +1583,17 @@ describe('SettingsPanel runtime files', () => {
|
|||||||
const { rerender } = render(<SettingsPanel {...props} />)
|
const { rerender } = render(<SettingsPanel {...props} />)
|
||||||
fireEvent.click(screen.getByRole('tab', { name: category }))
|
fireEvent.click(screen.getByRole('tab', { name: category }))
|
||||||
const toggle = screen.getByRole('switch', { name: label })
|
const toggle = screen.getByRole('switch', { name: label })
|
||||||
expect(toggle).not.toBeChecked()
|
expect(toggle).toBeChecked()
|
||||||
expect(toggle).toHaveAccessibleDescription(description)
|
expect(toggle).toHaveAccessibleDescription(description)
|
||||||
expect(toggle.closest('label')).toHaveClass('toggle-row')
|
expect(toggle.closest('label')).toHaveClass('toggle-row')
|
||||||
fireEvent.click(toggle)
|
fireEvent.click(toggle)
|
||||||
expect(onChange).toHaveBeenCalledExactlyOnceWith(true)
|
expect(onChange).toHaveBeenCalledExactlyOnceWith(false)
|
||||||
rerender(<SettingsPanel {...props} transparentFrostedEffectEnabled applicationSettingsPending />)
|
rerender(<SettingsPanel {...props} transparentFrostedEffectEnabled={false} applicationSettingsPending />)
|
||||||
expect(toggle).toBeChecked()
|
expect(toggle).not.toBeChecked()
|
||||||
expect(toggle).toBeDisabled()
|
expect(toggle).toBeDisabled()
|
||||||
rerender(<SettingsPanel {...props} transparentFrostedEffectEnabled />)
|
rerender(<SettingsPanel {...props} transparentFrostedEffectEnabled={false} />)
|
||||||
fireEvent.click(toggle)
|
fireEvent.click(toggle)
|
||||||
expect(onChange).toHaveBeenLastCalledWith(false)
|
expect(onChange).toHaveBeenLastCalledWith(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
|
|||||||
@@ -656,7 +656,7 @@ export function SettingsPanel({
|
|||||||
onClearLocalData,
|
onClearLocalData,
|
||||||
onExpertsChanged = () => {},
|
onExpertsChanged = () => {},
|
||||||
appearanceTheme = 'system',
|
appearanceTheme = 'system',
|
||||||
transparentFrostedEffectEnabled = false,
|
transparentFrostedEffectEnabled = true,
|
||||||
applicationSettingsPending = false,
|
applicationSettingsPending = false,
|
||||||
applicationSettingsLocked = false,
|
applicationSettingsLocked = false,
|
||||||
applicationSettingsError,
|
applicationSettingsError,
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ const applicationPreferencesSchema = z
|
|||||||
.object({
|
.object({
|
||||||
checkUpdatesOnStartup: z.boolean(),
|
checkUpdatesOnStartup: z.boolean(),
|
||||||
desktopNotificationsEnabled: z.boolean().default(true),
|
desktopNotificationsEnabled: z.boolean().default(true),
|
||||||
transparentFrostedEffectEnabled: z.boolean().default(false),
|
transparentFrostedEffectEnabled: z.boolean().default(true),
|
||||||
updateSource: updateSourceSchema,
|
updateSource: updateSourceSchema,
|
||||||
modelDownloadSource: modelDownloadSourceSchema,
|
modelDownloadSource: modelDownloadSourceSchema,
|
||||||
localToolEnvironment: localToolEnvironmentSettingsSchema,
|
localToolEnvironment: localToolEnvironmentSettingsSchema,
|
||||||
|
|||||||
Reference in New Issue
Block a user