forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import React from 'react'
2
3import * as persisted from '#/state/persisted'
4
5type StateContext = {
6 trendingDisabled: Exclude<persisted.Schema['trendingDisabled'], undefined>
7 trendingVideoDisabled: Exclude<
8 persisted.Schema['trendingVideoDisabled'],
9 undefined
10 >
11}
12type ApiContext = {
13 setTrendingDisabled(
14 hidden: Exclude<persisted.Schema['trendingDisabled'], undefined>,
15 ): void
16 setTrendingVideoDisabled(
17 hidden: Exclude<persisted.Schema['trendingVideoDisabled'], undefined>,
18 ): void
19}
20
21const StateContext = React.createContext<StateContext>({
22 trendingDisabled: Boolean(persisted.defaults.trendingDisabled),
23 trendingVideoDisabled: Boolean(persisted.defaults.trendingVideoDisabled),
24})
25StateContext.displayName = 'TrendingStateContext'
26const ApiContext = React.createContext<ApiContext>({
27 setTrendingDisabled() {},
28 setTrendingVideoDisabled() {},
29})
30ApiContext.displayName = 'TrendingApiContext'
31
32function usePersistedBooleanValue<T extends keyof persisted.Schema>(key: T) {
33 const [value, _set] = React.useState(() => {
34 return Boolean(persisted.get(key))
35 })
36 const set = React.useCallback<
37 (value: Exclude<persisted.Schema[T], undefined>) => void
38 >(
39 hidden => {
40 _set(Boolean(hidden))
41 persisted.write(key, hidden)
42 },
43 [key, _set],
44 )
45 React.useEffect(() => {
46 return persisted.onUpdate(key, hidden => {
47 _set(Boolean(hidden))
48 })
49 }, [key, _set])
50
51 return [value, set] as const
52}
53
54export function Provider({children}: React.PropsWithChildren<{}>) {
55 const [trendingDisabled, setTrendingDisabled] =
56 usePersistedBooleanValue('trendingDisabled')
57 const [trendingVideoDisabled, setTrendingVideoDisabled] =
58 usePersistedBooleanValue('trendingVideoDisabled')
59
60 /*
61 * Context
62 */
63 const state = React.useMemo(
64 () => ({trendingDisabled, trendingVideoDisabled}),
65 [trendingDisabled, trendingVideoDisabled],
66 )
67 const api = React.useMemo(
68 () => ({setTrendingDisabled, setTrendingVideoDisabled}),
69 [setTrendingDisabled, setTrendingVideoDisabled],
70 )
71
72 return (
73 <StateContext.Provider value={state}>
74 <ApiContext.Provider value={api}>{children}</ApiContext.Provider>
75 </StateContext.Provider>
76 )
77}
78
79export function useTrendingSettings() {
80 return React.useContext(StateContext)
81}
82
83export function useTrendingSettingsApi() {
84 return React.useContext(ApiContext)
85}