@tldraw/editor
Version:
tldraw infinite canvas SDK (editor).
146 lines (127 loc) • 4.29 kB
text/typescript
import { atom, computed } from '@tldraw/state'
import { TLCurrentUser } from '../../../config/createTLCurrentUser'
import { TLUserPreferences, defaultUserPreferences } from '../../../config/TLUserPreferences'
import { getGlobalWindow } from '../../../utils/dom'
/** @public */
export class UserPreferencesManager {
systemColorScheme = atom<'dark' | 'light'>('systemColorScheme', 'light')
disposables = new Set<() => void>()
dispose() {
this.disposables.forEach((d) => d())
}
constructor(
private readonly user: TLCurrentUser,
private readonly colorScheme: 'light' | 'dark' | 'system'
) {
if (typeof window === 'undefined' || !getGlobalWindow().matchMedia) return
const darkModeMediaQuery = getGlobalWindow().matchMedia('(prefers-color-scheme: dark)')
if (darkModeMediaQuery?.matches) {
this.systemColorScheme.set('dark')
}
const handleChange = (e: MediaQueryListEvent) => {
if (e.matches) {
this.systemColorScheme.set('dark')
} else {
this.systemColorScheme.set('light')
}
}
darkModeMediaQuery?.addEventListener('change', handleChange)
this.disposables.add(() => darkModeMediaQuery?.removeEventListener('change', handleChange))
}
updateUserPreferences(userPreferences: Partial<TLUserPreferences>) {
this.user.setUserPreferences({
...this.user.userPreferences.get(),
...userPreferences,
})
}
getUserPreferences() {
return {
id: this.getId(),
name: this.getName(),
locale: this.getLocale(),
color: this.getColor(),
animationSpeed: this.getAnimationSpeed(),
areKeyboardShortcutsEnabled: this.getAreKeyboardShortcutsEnabled(),
isSnapMode: this.getIsSnapMode(),
colorScheme: this.user.userPreferences.get().colorScheme,
isDarkMode: this.getIsDarkMode(),
isWrapMode: this.getIsWrapMode(),
isDynamicResizeMode: this.getIsDynamicResizeMode(),
enhancedA11yMode: this.getEnhancedA11yMode(),
inputMode: this.getInputMode(),
isZoomDirectionInverted: this.getIsZoomDirectionInverted(),
}
}
getIsDarkMode() {
const userColorScheme = this.user.userPreferences.get().colorScheme
const scheme = userColorScheme ?? this.colorScheme
switch (scheme) {
case 'dark':
return true
case 'light':
return false
case 'system':
return this.systemColorScheme.get() === 'dark'
default:
return false
}
}
/**
* The speed at which the user can scroll by dragging toward the edge of the screen.
*/
getEdgeScrollSpeed() {
return this.user.userPreferences.get().edgeScrollSpeed ?? defaultUserPreferences.edgeScrollSpeed
}
getAnimationSpeed() {
return this.user.userPreferences.get().animationSpeed ?? defaultUserPreferences.animationSpeed
}
getAreKeyboardShortcutsEnabled() {
return (
this.user.userPreferences.get().areKeyboardShortcutsEnabled ??
defaultUserPreferences.areKeyboardShortcutsEnabled
)
}
getId() {
return this.user.userPreferences.get().id
}
getName() {
return this.user.userPreferences.get().name?.trim() ?? defaultUserPreferences.name
}
getLocale() {
return this.user.userPreferences.get().locale ?? defaultUserPreferences.locale
}
getColor() {
return this.user.userPreferences.get().color ?? defaultUserPreferences.color
}
getIsSnapMode() {
return this.user.userPreferences.get().isSnapMode ?? defaultUserPreferences.isSnapMode
}
getIsWrapMode() {
return this.user.userPreferences.get().isWrapMode ?? defaultUserPreferences.isWrapMode
}
getIsDynamicResizeMode() {
return (
this.user.userPreferences.get().isDynamicSizeMode ?? defaultUserPreferences.isDynamicSizeMode
)
}
getIsPasteAtCursorMode() {
return (
this.user.userPreferences.get().isPasteAtCursorMode ??
defaultUserPreferences.isPasteAtCursorMode
)
}
getEnhancedA11yMode() {
return (
this.user.userPreferences.get().enhancedA11yMode ?? defaultUserPreferences.enhancedA11yMode
)
}
getInputMode() {
return this.user.userPreferences.get().inputMode ?? defaultUserPreferences.inputMode
}
getIsZoomDirectionInverted() {
return (
this.user.userPreferences.get().isZoomDirectionInverted ??
defaultUserPreferences.isZoomDirectionInverted
)
}
}