Bpistle/src/providers/UserPreferencesProvider.tsx
2025-12-03 23:28:31 +08:00

102 lines
3.3 KiB
TypeScript

import storage from '@/services/local-storage.service'
import { TEmoji, TNotificationStyle } from '@/types'
import { createContext, useContext, useEffect, useState } from 'react'
import { useScreenSize } from './ScreenSizeProvider'
type TUserPreferencesContext = {
notificationListStyle: TNotificationStyle
updateNotificationListStyle: (style: TNotificationStyle) => void
muteMedia: boolean
updateMuteMedia: (mute: boolean) => void
sidebarCollapse: boolean
updateSidebarCollapse: (collapse: boolean) => void
enableSingleColumnLayout: boolean
updateEnableSingleColumnLayout: (enable: boolean) => void
quickReaction: boolean
updateQuickReaction: (enable: boolean) => void
quickReactionEmoji: string | TEmoji
updateQuickReactionEmoji: (emoji: string | TEmoji) => void
}
const UserPreferencesContext = createContext<TUserPreferencesContext | undefined>(undefined)
export const useUserPreferences = () => {
const context = useContext(UserPreferencesContext)
if (!context) {
throw new Error('useUserPreferences must be used within a UserPreferencesProvider')
}
return context
}
export function UserPreferencesProvider({ children }: { children: React.ReactNode }) {
const { isSmallScreen } = useScreenSize()
const [notificationListStyle, setNotificationListStyle] = useState(
storage.getNotificationListStyle()
)
const [muteMedia, setMuteMedia] = useState(true)
const [sidebarCollapse, setSidebarCollapse] = useState(storage.getSidebarCollapse())
const [enableSingleColumnLayout, setEnableSingleColumnLayout] = useState(
storage.getEnableSingleColumnLayout()
)
const [quickReaction, setQuickReaction] = useState(storage.getQuickReaction())
const [quickReactionEmoji, setQuickReactionEmoji] = useState(storage.getQuickReactionEmoji())
useEffect(() => {
if (!isSmallScreen && enableSingleColumnLayout) {
document.documentElement.style.setProperty('overflow-y', 'scroll')
} else {
document.documentElement.style.removeProperty('overflow-y')
}
}, [enableSingleColumnLayout, isSmallScreen])
const updateNotificationListStyle = (style: TNotificationStyle) => {
setNotificationListStyle(style)
storage.setNotificationListStyle(style)
}
const updateSidebarCollapse = (collapse: boolean) => {
setSidebarCollapse(collapse)
storage.setSidebarCollapse(collapse)
}
const updateEnableSingleColumnLayout = (enable: boolean) => {
setEnableSingleColumnLayout(enable)
storage.setEnableSingleColumnLayout(enable)
}
const updateQuickReaction = (enable: boolean) => {
setQuickReaction(enable)
storage.setQuickReaction(enable)
}
const updateQuickReactionEmoji = (emoji: string | TEmoji) => {
setQuickReactionEmoji(emoji)
storage.setQuickReactionEmoji(emoji)
}
return (
<UserPreferencesContext.Provider
value={{
notificationListStyle,
updateNotificationListStyle,
muteMedia,
updateMuteMedia: setMuteMedia,
sidebarCollapse,
updateSidebarCollapse,
enableSingleColumnLayout: isSmallScreen ? true : enableSingleColumnLayout,
updateEnableSingleColumnLayout,
quickReaction,
updateQuickReaction,
quickReactionEmoji,
updateQuickReactionEmoji
}}
>
{children}
</UserPreferencesContext.Provider>
)
}