Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141// src/layout/sidebar-leaf-persistence.ts/** * Sidebar leaf and active view type persistence. * * Persists: * - Which view types have leaves in which sidebar panels (so external Obsidian * plugins that create their leaf only on first install via onUserEnable() * get their tabs restored after page reload). * - Which view type is active per side (left/right). * * Single localStorage key `reams:sidebar-leaves` with version 2 schema: * { version: 2, leaves: [{viewType, side}], activeViewTypes: { left?, right? } } * * Older schemas are ignored; only the current version 2 shape is loaded. */
const STORAGE_KEY = 'reams:sidebar-leaves'
export interface PersistedSidebarLeaf { viewType: string side: 'left' | 'right'}
export interface PersistedActiveViewTypes { left?: string right?: string}
interface PersistedDataV2 { version: 2 leaves: PersistedSidebarLeaf[] activeViewTypes?: PersistedActiveViewTypes}
function isObject(v: unknown): v is Record<string, unknown> { return typeof v === 'object' && v !== null && !Array.isArray(v)}
function parseLeaves(leaves: unknown): PersistedSidebarLeaf[] { if (!Array.isArray(leaves)) return [] return leaves.filter( (e): e is PersistedSidebarLeaf => isObject(e) && typeof e.viewType === 'string' && (e.side === 'left' || e.side === 'right') )}
function loadRawData(): PersistedDataV2 | null { try { const raw = localStorage.getItem(STORAGE_KEY) if (!raw) return null const parsed: unknown = JSON.parse(raw) if (!isObject(parsed)) return null // Validated as object, now check version field const version = (parsed as { version?: unknown }).version if (version !== 2) return null return parsed as unknown as PersistedDataV2 } catch { return null }}
function saveData(data: PersistedDataV2): void { try { localStorage.setItem(STORAGE_KEY, JSON.stringify(data)) } catch { // localStorage may be unavailable }}
function ensureV2Data(): PersistedDataV2 { const raw = loadRawData() if (!raw) { return { version: 2, leaves: [] } } return raw}
/** * Load the persisted sidebar leaf manifest from localStorage. * Returns an empty array if nothing is persisted or data is invalid. * Loads only the current version 2 schema. */export function loadPersistedSidebarLeaves(): PersistedSidebarLeaf[] { const data = ensureV2Data() return parseLeaves(data.leaves)}
/** * Save the sidebar leaf manifest to localStorage. * Preserves existing activeViewTypes. */export function savePersistedSidebarLeaves(leaves: PersistedSidebarLeaf[]): void { const existing = ensureV2Data() const data: PersistedDataV2 = { version: 2, leaves, activeViewTypes: existing.activeViewTypes, } saveData(data)}
/** * Load the persisted active view types for left/right panels. * Returns an empty object if nothing is persisted or data is malformed. */export function loadPersistedActiveViewTypes(): PersistedActiveViewTypes { const data = ensureV2Data() const active = data.activeViewTypes // Guard against malformed activeViewTypes (e.g. string, number, array) if (!active || typeof active !== 'object' || Array.isArray(active)) { return {} } return active}
/** * Save the active view type for a panel side. * Set to null to remove the active view type for that side. * Preserves existing leaves and other active view types. */export function savePersistedActiveViewType( side: 'left' | 'right', viewType: string | null): void { const existing = ensureV2Data() const activeViewTypes: PersistedActiveViewTypes = { ...existing.activeViewTypes } if (viewType === null) { delete activeViewTypes[side] } else { activeViewTypes[side] = viewType } const data: PersistedDataV2 = { version: 2, leaves: existing.leaves, activeViewTypes: Object.keys(activeViewTypes).length > 0 ? activeViewTypes : undefined, } saveData(data)}