Tldraw/apps/dotcom/src/utils/userPreferences.ts

60 wiersze
1.6 KiB
TypeScript

import { T, atom } from 'tldraw'
const channel =
typeof BroadcastChannel !== 'undefined' ? new BroadcastChannel('tldrawUserPreferences') : null
export const userPreferences = {
showFileOpenWarning: createPreference('showFileOpenWarning', T.boolean, true),
showFileClearWarning: createPreference('showFileClearWarning', T.boolean, true),
}
if (typeof window !== 'undefined') {
;(window as any).userPreferences = userPreferences
}
function createPreference<Type>(key: string, validator: T.Validator<Type>, defaultValue: Type) {
const preferenceAtom = atom(
`userPreferences.${key}`,
loadItemFromStorage(key, validator) ?? defaultValue
)
channel?.addEventListener('message', (event) => {
if (event.data.key === key) {
preferenceAtom.set(event.data.value)
}
})
return {
get() {
return preferenceAtom.get()
},
set(newValue: Type) {
preferenceAtom.set(newValue)
saveItemToStorage(key, newValue)
channel?.postMessage({ key, value: newValue })
},
}
}
function loadItemFromStorage<Type>(key: string, validator: T.Validator<Type>): Type | null {
if (typeof localStorage === 'undefined' || !localStorage) return null
const item = localStorage.getItem(`tldrawUserPreferences.${key}`)
if (item == null) return null
try {
return validator.validate(JSON.parse(item))
} catch (e) {
return null
}
}
function saveItemToStorage(key: string, value: unknown): void {
if (typeof localStorage === 'undefined' || !localStorage) return
try {
localStorage.setItem(`tldrawUserPreferences.${key}`, JSON.stringify(value))
} catch (e) {
// not a big deal
}
}