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