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