ContentPolicyProvider.tsx raw
1 import { MEDIA_AUTO_LOAD_POLICY } from '@/constants'
2 import storage, { dispatchSettingsChanged } from '@/services/local-storage.service'
3 import { TMediaAutoLoadPolicy, TNsfwDisplayPolicy } from '@/types'
4 import { createContext, useContext, useEffect, useMemo, useState } from 'react'
5
6 type TContentPolicyContext = {
7 autoplay: boolean
8 setAutoplay: (autoplay: boolean) => void
9
10 nsfwDisplayPolicy: TNsfwDisplayPolicy
11 setNsfwDisplayPolicy: (policy: TNsfwDisplayPolicy) => void
12
13 hideContentMentioningMutedUsers?: boolean
14 setHideContentMentioningMutedUsers?: (hide: boolean) => void
15
16 autoLoadMedia: boolean
17 mediaAutoLoadPolicy: TMediaAutoLoadPolicy
18 setMediaAutoLoadPolicy: (policy: TMediaAutoLoadPolicy) => void
19
20 faviconUrlTemplate: string
21 setFaviconUrlTemplate: (template: string) => void
22
23 verboseLogging: boolean
24 setVerboseLogging: (verbose: boolean) => void
25
26 enableMarkdown: boolean
27 setEnableMarkdown: (enable: boolean) => void
28 }
29
30 const ContentPolicyContext = createContext<TContentPolicyContext | undefined>(undefined)
31
32 export const useContentPolicy = () => {
33 const context = useContext(ContentPolicyContext)
34 if (!context) {
35 throw new Error('useContentPolicy must be used within an ContentPolicyProvider')
36 }
37 return context
38 }
39
40 export function ContentPolicyProvider({ children }: { children: React.ReactNode }) {
41 const [autoplay, setAutoplay] = useState(storage.getAutoplay())
42 const [nsfwDisplayPolicy, setNsfwDisplayPolicy] = useState(storage.getNsfwDisplayPolicy())
43 const [hideContentMentioningMutedUsers, setHideContentMentioningMutedUsers] = useState(
44 storage.getHideContentMentioningMutedUsers()
45 )
46 const [mediaAutoLoadPolicy, setMediaAutoLoadPolicy] = useState(storage.getMediaAutoLoadPolicy())
47 const [faviconUrlTemplate, setFaviconUrlTemplate] = useState(storage.getFaviconUrlTemplate())
48 const [verboseLogging, setVerboseLogging] = useState(storage.getVerboseLogging())
49 const [enableMarkdown, setEnableMarkdown] = useState(storage.getEnableMarkdown())
50 const [connectionType, setConnectionType] = useState((navigator as any).connection?.type)
51
52 useEffect(() => {
53 const connection = (navigator as any).connection
54 if (!connection) {
55 setConnectionType(undefined)
56 return
57 }
58 const handleConnectionChange = () => {
59 setConnectionType(connection.type)
60 }
61 connection.addEventListener('change', handleConnectionChange)
62 return () => {
63 connection.removeEventListener('change', handleConnectionChange)
64 }
65 }, [])
66
67 const autoLoadMedia = useMemo(() => {
68 if (mediaAutoLoadPolicy === MEDIA_AUTO_LOAD_POLICY.ALWAYS) {
69 return true
70 }
71 if (mediaAutoLoadPolicy === MEDIA_AUTO_LOAD_POLICY.NEVER) {
72 return false
73 }
74 // WIFI_ONLY
75 return connectionType === 'wifi' || connectionType === 'ethernet'
76 }, [mediaAutoLoadPolicy, connectionType])
77
78 const updateAutoplay = (autoplay: boolean) => {
79 storage.setAutoplay(autoplay)
80 setAutoplay(autoplay)
81 dispatchSettingsChanged()
82 }
83
84 const updateNsfwDisplayPolicy = (policy: TNsfwDisplayPolicy) => {
85 storage.setNsfwDisplayPolicy(policy)
86 setNsfwDisplayPolicy(policy)
87 dispatchSettingsChanged()
88 }
89
90 const updateHideContentMentioningMutedUsers = (hide: boolean) => {
91 storage.setHideContentMentioningMutedUsers(hide)
92 setHideContentMentioningMutedUsers(hide)
93 dispatchSettingsChanged()
94 }
95
96 const updateMediaAutoLoadPolicy = (policy: TMediaAutoLoadPolicy) => {
97 storage.setMediaAutoLoadPolicy(policy)
98 setMediaAutoLoadPolicy(policy)
99 dispatchSettingsChanged()
100 }
101
102 const updateFaviconUrlTemplate = (template: string) => {
103 storage.setFaviconUrlTemplate(template)
104 setFaviconUrlTemplate(template)
105 dispatchSettingsChanged()
106 }
107
108 const updateVerboseLogging = (verbose: boolean) => {
109 storage.setVerboseLogging(verbose)
110 setVerboseLogging(verbose)
111 dispatchSettingsChanged()
112 }
113
114 const updateEnableMarkdown = (enable: boolean) => {
115 storage.setEnableMarkdown(enable)
116 setEnableMarkdown(enable)
117 dispatchSettingsChanged()
118 }
119
120 return (
121 <ContentPolicyContext.Provider
122 value={{
123 autoplay,
124 setAutoplay: updateAutoplay,
125 nsfwDisplayPolicy,
126 setNsfwDisplayPolicy: updateNsfwDisplayPolicy,
127 hideContentMentioningMutedUsers,
128 setHideContentMentioningMutedUsers: updateHideContentMentioningMutedUsers,
129 autoLoadMedia,
130 mediaAutoLoadPolicy,
131 setMediaAutoLoadPolicy: updateMediaAutoLoadPolicy,
132 faviconUrlTemplate,
133 setFaviconUrlTemplate: updateFaviconUrlTemplate,
134 verboseLogging,
135 setVerboseLogging: updateVerboseLogging,
136 enableMarkdown,
137 setEnableMarkdown: updateEnableMarkdown
138 }}
139 >
140 {children}
141 </ContentPolicyContext.Provider>
142 )
143 }
144