about summary refs log tree commit diff
path: root/src/state/preferences
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2023-12-24 16:24:56 -0600
committerGitHub <noreply@github.com>2023-12-24 14:24:56 -0800
commitb1994051344c8dbb1f3b710d6343591daa6756b8 (patch)
tree1c19750ad5f4748a29f0d41fd79142a7c1a7846f /src/state/preferences
parent28e0df595fef024526da4a0ba22cba9fdc07808f (diff)
downloadvoidsky-b1994051344c8dbb1f3b710d6343591daa6756b8.tar.zst
Hide posts tool (#2299)
* Set up hidden posts persisted state

* Wrap moderatePost

* Integrate hidden posts into moderation

* Complete hide-post behaviors

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
Diffstat (limited to 'src/state/preferences')
-rw-r--r--src/state/preferences/hidden-posts.tsx64
-rw-r--r--src/state/preferences/index.tsx6
2 files changed, 69 insertions, 1 deletions
diff --git a/src/state/preferences/hidden-posts.tsx b/src/state/preferences/hidden-posts.tsx
new file mode 100644
index 000000000..11119ce75
--- /dev/null
+++ b/src/state/preferences/hidden-posts.tsx
@@ -0,0 +1,64 @@
+import React from 'react'
+import * as persisted from '#/state/persisted'
+
+type SetStateCb = (
+  s: persisted.Schema['hiddenPosts'],
+) => persisted.Schema['hiddenPosts']
+type StateContext = persisted.Schema['hiddenPosts']
+type ApiContext = {
+  hidePost: ({uri}: {uri: string}) => void
+  unhidePost: ({uri}: {uri: string}) => void
+}
+
+const stateContext = React.createContext<StateContext>(
+  persisted.defaults.hiddenPosts,
+)
+const apiContext = React.createContext<ApiContext>({
+  hidePost: () => {},
+  unhidePost: () => {},
+})
+
+export function Provider({children}: React.PropsWithChildren<{}>) {
+  const [state, setState] = React.useState(persisted.get('hiddenPosts'))
+
+  const setStateWrapped = React.useCallback(
+    (fn: SetStateCb) => {
+      const s = fn(persisted.get('hiddenPosts'))
+      setState(s)
+      persisted.write('hiddenPosts', s)
+    },
+    [setState],
+  )
+
+  const api = React.useMemo(
+    () => ({
+      hidePost: ({uri}: {uri: string}) => {
+        setStateWrapped(s => [...(s || []), uri])
+      },
+      unhidePost: ({uri}: {uri: string}) => {
+        setStateWrapped(s => (s || []).filter(u => u !== uri))
+      },
+    }),
+    [setStateWrapped],
+  )
+
+  React.useEffect(() => {
+    return persisted.onUpdate(() => {
+      setState(persisted.get('hiddenPosts'))
+    })
+  }, [setStateWrapped])
+
+  return (
+    <stateContext.Provider value={state}>
+      <apiContext.Provider value={api}>{children}</apiContext.Provider>
+    </stateContext.Provider>
+  )
+}
+
+export function useHiddenPosts() {
+  return React.useContext(stateContext)
+}
+
+export function useHiddenPostsApi() {
+  return React.useContext(apiContext)
+}
diff --git a/src/state/preferences/index.tsx b/src/state/preferences/index.tsx
index 1f4348cfc..5ec659031 100644
--- a/src/state/preferences/index.tsx
+++ b/src/state/preferences/index.tsx
@@ -1,17 +1,21 @@
 import React from 'react'
 import {Provider as LanguagesProvider} from './languages'
 import {Provider as AltTextRequiredProvider} from '../preferences/alt-text-required'
+import {Provider as HiddenPostsProvider} from '../preferences/hidden-posts'
 
 export {useLanguagePrefs, useLanguagePrefsApi} from './languages'
 export {
   useRequireAltTextEnabled,
   useSetRequireAltTextEnabled,
 } from './alt-text-required'
+export * from './hidden-posts'
 
 export function Provider({children}: React.PropsWithChildren<{}>) {
   return (
     <LanguagesProvider>
-      <AltTextRequiredProvider>{children}</AltTextRequiredProvider>
+      <AltTextRequiredProvider>
+        <HiddenPostsProvider>{children}</HiddenPostsProvider>
+      </AltTextRequiredProvider>
     </LanguagesProvider>
   )
 }