feat: 实现笔临 P0/P1 Electron 桌面应用 v0.1.0
交付写作核心(TipTap、自动保存、分卷分章)、Onboarding、7 主题与双语 i18n、快捷键设置;主进程使用 node:sqlite;补全 Vitest 与 Playwright E2E;统一 design/ 目录并移除 desigin 拼写错误路径。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { DEFAULT_SHORTCUTS } from '../../shared/default-shortcuts'
|
||||
import type { GlobalSettings } from '../../shared/types'
|
||||
|
||||
const FILE = 'global_settings.json'
|
||||
|
||||
function defaults(): GlobalSettings {
|
||||
return {
|
||||
penName: '未命名作者',
|
||||
onboardingCompleted: false,
|
||||
theme: 'default',
|
||||
language: 'zh-CN',
|
||||
dailyWordGoal: 0,
|
||||
shortcuts: { ...DEFAULT_SHORTCUTS }
|
||||
}
|
||||
}
|
||||
|
||||
export class GlobalSettingsService {
|
||||
constructor(private userDataDir: string) {
|
||||
if (!existsSync(userDataDir)) mkdirSync(userDataDir, { recursive: true })
|
||||
}
|
||||
|
||||
private filePath(): string {
|
||||
return join(this.userDataDir, FILE)
|
||||
}
|
||||
|
||||
get(): GlobalSettings {
|
||||
if (!existsSync(this.filePath())) return defaults()
|
||||
const raw = JSON.parse(readFileSync(this.filePath(), 'utf-8')) as Partial<GlobalSettings>
|
||||
return {
|
||||
...defaults(),
|
||||
...raw,
|
||||
shortcuts: { ...DEFAULT_SHORTCUTS, ...raw.shortcuts }
|
||||
}
|
||||
}
|
||||
|
||||
update(partial: Partial<GlobalSettings>): GlobalSettings {
|
||||
const current = this.get()
|
||||
const next: GlobalSettings = {
|
||||
...current,
|
||||
...partial,
|
||||
shortcuts: partial.shortcuts
|
||||
? { ...current.shortcuts, ...partial.shortcuts }
|
||||
: current.shortcuts
|
||||
}
|
||||
writeFileSync(this.filePath(), JSON.stringify(next, null, 2), 'utf-8')
|
||||
return next
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user