Files
tolaria/src/utils/configMigration.ts
Test fa49251459 feat: persist editor mode (raw/preview) across note switches
Editor mode is now stored as a global preference in VaultConfig instead of
being tracked per-tab. Toggling raw mode persists across tab switches and
app restarts via the editor_mode field in config/ui.config.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 11:41:35 +01:00

89 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { VaultConfig } from '../types'
const MIGRATION_FLAG = 'laputa:config-migrated-to-vault'
/** Keys to migrate from localStorage to vault config file. */
const LS_KEYS = {
zoom: 'laputa:zoom-level',
viewMode: 'laputa-view-mode',
tagColors: 'laputa:tag-color-overrides',
statusColors: 'laputa:status-color-overrides',
propertyModes: 'laputa:display-mode-overrides',
} as const
function readJson<T>(key: string): T | null {
try {
const raw = localStorage.getItem(key)
return raw ? JSON.parse(raw) as T : null
} catch {
return null
}
}
/**
* One-time migration: read localStorage values and merge into vault config.
* Returns the merged config. If already migrated (flag set), returns the loaded config unchanged.
* Passing null for `loaded` means the vault file didn't exist yet.
*/
export function migrateLocalStorageToVaultConfig(loaded: VaultConfig | null): VaultConfig {
const base: VaultConfig = loaded ?? {
zoom: null, view_mode: null, editor_mode: null, tag_colors: null,
status_colors: null, property_display_modes: null,
}
// Skip migration if already done
try {
if (localStorage.getItem(MIGRATION_FLAG) === '1') return base
} catch {
return base
}
const result = { ...base }
// Zoom (localStorage stores as string "80""150", vault config stores as fraction 0.81.5)
if (result.zoom === null) {
try {
const raw = localStorage.getItem(LS_KEYS.zoom)
if (raw !== null) {
const val = Number(raw)
if (val >= 80 && val <= 150) result.zoom = val / 100
}
} catch { /* ignore */ }
}
// View mode
if (result.view_mode === null) {
try {
const raw = localStorage.getItem(LS_KEYS.viewMode)
if (raw === 'editor-only' || raw === 'editor-list' || raw === 'all') {
result.view_mode = raw
}
} catch { /* ignore */ }
}
// Tag colors
if (result.tag_colors === null) {
const colors = readJson<Record<string, string>>(LS_KEYS.tagColors)
if (colors && Object.keys(colors).length > 0) result.tag_colors = colors
}
// Status colors
if (result.status_colors === null) {
const colors = readJson<Record<string, string>>(LS_KEYS.statusColors)
if (colors && Object.keys(colors).length > 0) result.status_colors = colors
}
// Property display modes
if (result.property_display_modes === null) {
const modes = readJson<Record<string, string>>(LS_KEYS.propertyModes)
if (modes && Object.keys(modes).length > 0) result.property_display_modes = modes
}
// Mark migration as done
try {
localStorage.setItem(MIGRATION_FLAG, '1')
} catch { /* ignore */ }
return result
}