UserPreferencesProvider.tsx raw

   1  import storage, { dispatchSettingsChanged } from '@/services/local-storage.service'
   2  import { TEmoji, TNotificationStyle } from '@/types'
   3  import { createContext, useContext, useEffect, useState } from 'react'
   4  import { useScreenSize } from './ScreenSizeProvider'
   5  
   6  type TUserPreferencesContext = {
   7    notificationListStyle: TNotificationStyle
   8    updateNotificationListStyle: (style: TNotificationStyle) => void
   9  
  10    muteMedia: boolean
  11    updateMuteMedia: (mute: boolean) => void
  12  
  13    sidebarCollapse: boolean
  14    updateSidebarCollapse: (collapse: boolean) => void
  15  
  16    enableSingleColumnLayout: boolean
  17    updateEnableSingleColumnLayout: (enable: boolean) => void
  18  
  19    autoInsertNewNotes: boolean
  20    updateAutoInsertNewNotes: (enable: boolean) => void
  21  
  22    quickReaction: boolean
  23    updateQuickReaction: (enable: boolean) => void
  24  
  25    quickReactionEmoji: string | TEmoji
  26    updateQuickReactionEmoji: (emoji: string | TEmoji) => void
  27  }
  28  
  29  const UserPreferencesContext = createContext<TUserPreferencesContext | undefined>(undefined)
  30  
  31  export const useUserPreferences = () => {
  32    const context = useContext(UserPreferencesContext)
  33    if (!context) {
  34      throw new Error('useUserPreferences must be used within a UserPreferencesProvider')
  35    }
  36    return context
  37  }
  38  
  39  export function UserPreferencesProvider({ children }: { children: React.ReactNode }) {
  40    const { canUseDoublePane } = useScreenSize()
  41    const [notificationListStyle, setNotificationListStyle] = useState(
  42      storage.getNotificationListStyle()
  43    )
  44    const [muteMedia, setMuteMedia] = useState(true)
  45    const [sidebarCollapse, setSidebarCollapse] = useState(storage.getSidebarCollapse())
  46    const [enableSingleColumnLayout, setEnableSingleColumnLayout] = useState(
  47      storage.getEnableSingleColumnLayout()
  48    )
  49    const [autoInsertNewNotes, setAutoInsertNewNotes] = useState(storage.getAutoInsertNewNotes())
  50    const [quickReaction, setQuickReaction] = useState(storage.getQuickReaction())
  51    const [quickReactionEmoji, setQuickReactionEmoji] = useState(storage.getQuickReactionEmoji())
  52  
  53    useEffect(() => {
  54      if (canUseDoublePane && enableSingleColumnLayout) {
  55        document.documentElement.style.setProperty('overflow-y', 'scroll')
  56      } else {
  57        document.documentElement.style.removeProperty('overflow-y')
  58      }
  59    }, [enableSingleColumnLayout, canUseDoublePane])
  60  
  61    const updateNotificationListStyle = (style: TNotificationStyle) => {
  62      setNotificationListStyle(style)
  63      storage.setNotificationListStyle(style)
  64      dispatchSettingsChanged()
  65    }
  66  
  67    const updateSidebarCollapse = (collapse: boolean) => {
  68      setSidebarCollapse(collapse)
  69      storage.setSidebarCollapse(collapse)
  70      dispatchSettingsChanged()
  71    }
  72  
  73    const updateEnableSingleColumnLayout = (enable: boolean) => {
  74      setEnableSingleColumnLayout(enable)
  75      storage.setEnableSingleColumnLayout(enable)
  76      dispatchSettingsChanged()
  77    }
  78  
  79    const updateAutoInsertNewNotes = (enable: boolean) => {
  80      setAutoInsertNewNotes(enable)
  81      storage.setAutoInsertNewNotes(enable)
  82      dispatchSettingsChanged()
  83    }
  84  
  85    const updateQuickReaction = (enable: boolean) => {
  86      setQuickReaction(enable)
  87      storage.setQuickReaction(enable)
  88      dispatchSettingsChanged()
  89    }
  90  
  91    const updateQuickReactionEmoji = (emoji: string | TEmoji) => {
  92      setQuickReactionEmoji(emoji)
  93      storage.setQuickReactionEmoji(emoji)
  94      dispatchSettingsChanged()
  95    }
  96  
  97    return (
  98      <UserPreferencesContext.Provider
  99        value={{
 100          notificationListStyle,
 101          updateNotificationListStyle,
 102          muteMedia,
 103          updateMuteMedia: setMuteMedia,
 104          sidebarCollapse,
 105          updateSidebarCollapse,
 106          enableSingleColumnLayout: !canUseDoublePane ? true : enableSingleColumnLayout,
 107          updateEnableSingleColumnLayout,
 108          autoInsertNewNotes,
 109          updateAutoInsertNewNotes,
 110          quickReaction,
 111          updateQuickReaction,
 112          quickReactionEmoji,
 113          updateQuickReactionEmoji
 114        }}
 115      >
 116        {children}
 117      </UserPreferencesContext.Provider>
 118    )
 119  }
 120