Bluesky app fork with some witchin' additions 馃挮
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 017120b3e8bff4881d577ea0d8a2ee455e555096 141 lines 4.0 kB view raw
1import {createContext, useContext, useMemo} from 'react' 2 3import {useLanguagePrefs} from '#/state/preferences/languages' 4import {useServiceConfigQuery} from '#/state/queries/service-config' 5import {useSession} from '#/state/session' 6import {useAnalytics} from '#/analytics' 7import {IS_DEV} from '#/env' 8import {device} from '#/storage' 9 10type TrendingContext = { 11 enabled: boolean 12} 13 14type LiveNowContext = { 15 did: string 16 domains: string[] 17}[] 18 19const TrendingContext = createContext<TrendingContext>({ 20 enabled: false, 21}) 22TrendingContext.displayName = 'TrendingContext' 23 24const LiveNowContext = createContext<LiveNowContext>([]) 25LiveNowContext.displayName = 'LiveNowContext' 26 27const CheckEmailConfirmedContext = createContext<boolean | null>(null) 28 29export function Provider({children}: {children: React.ReactNode}) { 30 const langPrefs = useLanguagePrefs() 31 const {data: config, isLoading: isInitialLoad} = useServiceConfigQuery() 32 const trending = useMemo<TrendingContext>(() => { 33 if (__DEV__) { 34 return {enabled: true} 35 } 36 37 /* 38 * Only English during beta period 39 */ 40 if ( 41 !!langPrefs.contentLanguages.length && 42 !langPrefs.contentLanguages.includes('en') 43 ) { 44 return {enabled: false} 45 } 46 47 /* 48 * While loading, use cached value 49 */ 50 const cachedEnabled = device.get(['trendingBetaEnabled']) 51 if (isInitialLoad) { 52 return {enabled: Boolean(cachedEnabled)} 53 } 54 55 const enabled = Boolean(config?.topicsEnabled) 56 57 // update cache 58 device.set(['trendingBetaEnabled'], enabled) 59 60 return {enabled} 61 }, [isInitialLoad, config, langPrefs.contentLanguages]) 62 63 const liveNow = useMemo<LiveNowContext>(() => config?.liveNow ?? [], [config]) 64 65 // probably true, so default to true when loading 66 // if the call fails, the query will set it to false for us 67 const checkEmailConfirmed = config?.checkEmailConfirmed ?? true 68 69 return ( 70 <TrendingContext.Provider value={trending}> 71 <LiveNowContext.Provider value={liveNow}> 72 <CheckEmailConfirmedContext.Provider value={checkEmailConfirmed}> 73 {children} 74 </CheckEmailConfirmedContext.Provider> 75 </LiveNowContext.Provider> 76 </TrendingContext.Provider> 77 ) 78} 79 80export function useTrendingConfig() { 81 return useContext(TrendingContext) 82} 83 84const DEFAULT_LIVE_ALLOWED_DOMAINS = [ 85 'twitch.tv', 86 'www.twitch.tv', 87 'stream.place', 88 'bluecast.app', 89 'www.bluecast.app', 90] 91export type LiveNowConfig = { 92 currentAccountAllowedHosts: Set<string> 93 defaultAllowedHosts: Set<string> 94 allowedHostsExceptionsByDid: Map<string, Set<string>> 95} 96export function useLiveNowConfig(): LiveNowConfig { 97 const ctx = useContext(LiveNowContext) 98 const canGoLive = useCanGoLive() 99 const {currentAccount} = useSession() 100 return useMemo(() => { 101 const defaultAllowedHosts = new Set(DEFAULT_LIVE_ALLOWED_DOMAINS) 102 const allowedHostsExceptionsByDid = new Map<string, Set<string>>() 103 for (const live of ctx) { 104 allowedHostsExceptionsByDid.set( 105 live.did, 106 new Set(DEFAULT_LIVE_ALLOWED_DOMAINS.concat(live.domains)), 107 ) 108 } 109 if (!currentAccount?.did || !canGoLive) 110 return { 111 currentAccountAllowedHosts: new Set(), 112 defaultAllowedHosts, 113 allowedHostsExceptionsByDid, 114 } 115 const vip = ctx.find(live => live.did === currentAccount.did) 116 return { 117 currentAccountAllowedHosts: new Set( 118 DEFAULT_LIVE_ALLOWED_DOMAINS.concat(vip ? vip.domains : []), 119 ), 120 defaultAllowedHosts, 121 allowedHostsExceptionsByDid, 122 } 123 }, [ctx, currentAccount, canGoLive]) 124} 125 126export function useCanGoLive() { 127 const ax = useAnalytics() 128 const {hasSession} = useSession() 129 if (!hasSession) return false 130 return IS_DEV ? true : !ax.features.enabled(ax.features.LiveNowBetaDisable) 131} 132 133export function useCheckEmailConfirmed() { 134 const ctx = useContext(CheckEmailConfirmedContext) 135 if (ctx === null) { 136 throw new Error( 137 'useCheckEmailConfirmed must be used within a ServiceConfigManager', 138 ) 139 } 140 return ctx 141}