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