ultisuite-client/lib/drive/docs-view-settings.ts
2026-06-09 17:06:20 +02:00

113 lines
2.8 KiB
TypeScript

"use client"
import { useCallback, useEffect, useState } from "react"
import {
DEFAULT_PAGE_FORMAT_ID,
type PageFormatId,
} from "@/lib/drive/page-formats"
export type DocsViewSettings = {
pageFormatId: PageFormatId
zoom: number
spellcheck: boolean
chromeCollapsed: boolean
}
const STORAGE_KEY = "ultidrive-docs-view-settings"
const DEFAULT_SETTINGS: DocsViewSettings = {
pageFormatId: DEFAULT_PAGE_FORMAT_ID,
zoom: 100,
spellcheck: true,
chromeCollapsed: false,
}
const ZOOM_MIN = 50
const ZOOM_MAX = 200
const ZOOM_STEP = 10
export function clampZoom(value: number): number {
return Math.min(ZOOM_MAX, Math.max(ZOOM_MIN, Math.round(value / ZOOM_STEP) * ZOOM_STEP))
}
function readSettings(): DocsViewSettings {
if (typeof localStorage === "undefined") return DEFAULT_SETTINGS
try {
const raw = localStorage.getItem(STORAGE_KEY)
if (!raw) return DEFAULT_SETTINGS
const parsed = JSON.parse(raw) as Partial<DocsViewSettings>
return {
pageFormatId: parsed.pageFormatId ?? DEFAULT_PAGE_FORMAT_ID,
zoom: clampZoom(parsed.zoom ?? DEFAULT_SETTINGS.zoom),
spellcheck: parsed.spellcheck ?? DEFAULT_SETTINGS.spellcheck,
chromeCollapsed: parsed.chromeCollapsed ?? DEFAULT_SETTINGS.chromeCollapsed,
}
} catch {
return DEFAULT_SETTINGS
}
}
function writeSettings(settings: DocsViewSettings) {
if (typeof localStorage === "undefined") return
localStorage.setItem(STORAGE_KEY, JSON.stringify(settings))
}
export function useDocsViewSettings() {
const [settings, setSettings] = useState<DocsViewSettings>(DEFAULT_SETTINGS)
useEffect(() => {
setSettings(readSettings())
}, [])
const setPageFormatId = useCallback((pageFormatId: PageFormatId) => {
setSettings((prev) => {
const next = { ...prev, pageFormatId }
writeSettings(next)
return next
})
}, [])
const setZoom = useCallback((zoom: number) => {
setSettings((prev) => {
const next = { ...prev, zoom: clampZoom(zoom) }
writeSettings(next)
return next
})
}, [])
const setSpellcheck = useCallback((spellcheck: boolean) => {
setSettings((prev) => {
const next = { ...prev, spellcheck }
writeSettings(next)
return next
})
}, [])
const toggleSpellcheck = useCallback(() => {
setSettings((prev) => {
const next = { ...prev, spellcheck: !prev.spellcheck }
writeSettings(next)
return next
})
}, [])
const toggleChromeCollapsed = useCallback(() => {
setSettings((prev) => {
const next = { ...prev, chromeCollapsed: !prev.chromeCollapsed }
writeSettings(next)
return next
})
}, [])
return {
settings,
setPageFormatId,
setZoom,
setSpellcheck,
toggleSpellcheck,
toggleChromeCollapsed,
zoomMin: ZOOM_MIN,
zoomMax: ZOOM_MAX,
}
}