feat: P3 final batch - zoom, fonts, dark mode, tech debt cleanup
- Page zoom control (0.5-2.0x, localStorage) - Custom monospace font selector (6 presets + custom) - Element Plus dark mode final fixes (dropdown, message-box, switch, popper) - AGENTS.md updated with correct paths + new modules/components/IPC channels - ROADMAP: window state persistence already done via win-state.ts - ROADMAP: tech debt items marked done
This commit is contained in:
@@ -17,6 +17,15 @@ const locales = [
|
||||
{ value: 'en', label: 'English' },
|
||||
{ value: 'zh-CN', label: '中文' },
|
||||
]
|
||||
|
||||
const fontOptions = [
|
||||
'Cascadia Code',
|
||||
'Fira Code',
|
||||
'JetBrains Mono',
|
||||
'Consolas',
|
||||
'Monaco',
|
||||
'Courier New',
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -61,6 +70,40 @@ const locales = [
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<label class="settings-label">{{ t('settings.zoom') }}</label>
|
||||
<el-slider
|
||||
:model-value="appStore.zoom"
|
||||
@update:model-value="appStore.setZoom($event)"
|
||||
:min="0.5"
|
||||
:max="2.0"
|
||||
:step="0.1"
|
||||
show-input
|
||||
size="small"
|
||||
style="width: 200px"
|
||||
/>
|
||||
<span class="zoom-value">{{ Math.round(appStore.zoom * 100) }}%</span>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<label class="settings-label">{{ t('settings.fontFamily') }}</label>
|
||||
<el-select
|
||||
:model-value="appStore.fontFamily"
|
||||
@change="appStore.setFontFamily($event)"
|
||||
size="small"
|
||||
style="width: 180px"
|
||||
allow-create
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="font in fontOptions"
|
||||
:key="font"
|
||||
:label="font"
|
||||
:value="font"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -89,4 +132,10 @@ const locales = [
|
||||
color: var(--text-secondary);
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
.zoom-value {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
min-width: 40px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -299,5 +299,7 @@ export default {
|
||||
language: 'Language',
|
||||
scanCount: 'Keys per SCAN',
|
||||
fontSize: 'Font Size',
|
||||
zoom: 'Page Zoom',
|
||||
fontFamily: 'Monospace Font',
|
||||
},
|
||||
}
|
||||
|
||||
@@ -299,5 +299,7 @@ export default {
|
||||
language: '语言',
|
||||
scanCount: 'SCAN 每次数量',
|
||||
fontSize: '字体大小',
|
||||
zoom: '页面缩放',
|
||||
fontFamily: '等宽字体',
|
||||
},
|
||||
}
|
||||
|
||||
+19
-1
@@ -9,6 +9,8 @@ export const useAppStore = defineStore('app', () => {
|
||||
const isDark = ref(true)
|
||||
const fontSize = ref<number>(Number(localStorage.getItem('fontSize')) || 13)
|
||||
const scanCount = ref<number>(Number(localStorage.getItem('scanCount')) || 100)
|
||||
const zoom = ref<number>(Number(localStorage.getItem('zoom')) || 1.0)
|
||||
const fontFamily = ref<string>(localStorage.getItem('fontFamily') || 'Cascadia Code')
|
||||
|
||||
function applyTheme(mode: ThemeMode, osDark?: boolean) {
|
||||
theme.value = mode
|
||||
@@ -45,5 +47,21 @@ export const useAppStore = defineStore('app', () => {
|
||||
localStorage.setItem('scanCount', String(count))
|
||||
}
|
||||
|
||||
return { theme, isDark, fontSize, scanCount, setTheme, setFontSize, setScanCount }
|
||||
function setZoom(value: number) {
|
||||
zoom.value = value
|
||||
localStorage.setItem('zoom', String(value))
|
||||
document.body.style.zoom = String(value)
|
||||
}
|
||||
|
||||
function setFontFamily(value: string) {
|
||||
fontFamily.value = value
|
||||
localStorage.setItem('fontFamily', value)
|
||||
document.documentElement.style.setProperty('--font-mono', value)
|
||||
}
|
||||
|
||||
// Apply saved zoom and fontFamily on mount
|
||||
document.body.style.zoom = String(zoom.value)
|
||||
document.documentElement.style.setProperty('--font-mono', fontFamily.value)
|
||||
|
||||
return { theme, isDark, fontSize, scanCount, zoom, fontFamily, setTheme, setFontSize, setScanCount, setZoom, setFontFamily }
|
||||
})
|
||||
|
||||
@@ -291,3 +291,68 @@ body {
|
||||
border-color: var(--border-color) !important;
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
|
||||
/* Dropdown Menu */
|
||||
.el-dropdown-menu {
|
||||
background: var(--bg-secondary) !important;
|
||||
border-color: var(--border-color) !important;
|
||||
}
|
||||
|
||||
.el-dropdown-menu__item {
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
|
||||
.el-dropdown-menu__item:not(.is-disabled):hover {
|
||||
background: var(--bg-hover) !important;
|
||||
color: var(--accent-light) !important;
|
||||
}
|
||||
|
||||
/* Message Box */
|
||||
.el-message-box {
|
||||
background: var(--bg-secondary) !important;
|
||||
border-color: var(--border-color) !important;
|
||||
}
|
||||
|
||||
.el-message-box__title {
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
|
||||
.el-message-box__message {
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
|
||||
.el-message-box__content {
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
|
||||
/* Switch */
|
||||
.el-switch {
|
||||
--el-switch-on-color: var(--accent) !important;
|
||||
--el-switch-off-color: var(--bg-tertiary) !important;
|
||||
}
|
||||
|
||||
.el-switch__core {
|
||||
background: var(--bg-tertiary) !important;
|
||||
border-color: var(--border-color) !important;
|
||||
}
|
||||
|
||||
.el-switch.is-checked .el-switch__core {
|
||||
background: var(--accent) !important;
|
||||
border-color: var(--accent) !important;
|
||||
}
|
||||
|
||||
/* Loading Mask */
|
||||
.el-loading-mask {
|
||||
background: rgba(0, 0, 0, 0.7) !important;
|
||||
}
|
||||
|
||||
/* Popper (all popper types) */
|
||||
.el-popper {
|
||||
background: var(--bg-secondary) !important;
|
||||
border-color: var(--border-color) !important;
|
||||
}
|
||||
|
||||
.el-popper__arrow::before {
|
||||
background: var(--bg-secondary) !important;
|
||||
border-color: var(--border-color) !important;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user