about summary refs log tree commit diff
path: root/src/state
diff options
context:
space:
mode:
Diffstat (limited to 'src/state')
-rw-r--r--src/state/persisted/legacy.ts1
-rw-r--r--src/state/persisted/schema.ts2
-rw-r--r--src/state/preferences/hidden-posts.tsx64
-rw-r--r--src/state/preferences/index.tsx6
-rw-r--r--src/state/queries/notifications/util.ts2
-rw-r--r--src/state/queries/post-feed.ts8
-rw-r--r--src/state/queries/preferences/index.ts11
7 files changed, 84 insertions, 10 deletions
diff --git a/src/state/persisted/legacy.ts b/src/state/persisted/legacy.ts
index f689c3d06..cdb542f5a 100644
--- a/src/state/persisted/legacy.ts
+++ b/src/state/persisted/legacy.ts
@@ -108,6 +108,7 @@ export function transform(legacy: Partial<LegacySchema>): Schema {
     onboarding: {
       step: legacy.onboarding?.step || defaults.onboarding.step,
     },
+    hiddenPosts: defaults.hiddenPosts,
   }
 }
 
diff --git a/src/state/persisted/schema.ts b/src/state/persisted/schema.ts
index 5ed8e01f3..27b1f26bd 100644
--- a/src/state/persisted/schema.ts
+++ b/src/state/persisted/schema.ts
@@ -37,6 +37,7 @@ export const schema = z.object({
   onboarding: z.object({
     step: z.string(),
   }),
+  hiddenPosts: z.array(z.string()).optional(), // should move to server
 })
 export type Schema = z.infer<typeof schema>
 
@@ -66,4 +67,5 @@ export const defaults: Schema = {
   onboarding: {
     step: 'Home',
   },
+  hiddenPosts: [],
 }
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>
   )
 }
diff --git a/src/state/queries/notifications/util.ts b/src/state/queries/notifications/util.ts
index cc5943163..438879b7e 100644
--- a/src/state/queries/notifications/util.ts
+++ b/src/state/queries/notifications/util.ts
@@ -2,12 +2,12 @@ import {
   AppBskyNotificationListNotifications,
   ModerationOpts,
   moderateProfile,
-  moderatePost,
   AppBskyFeedDefs,
   AppBskyFeedPost,
   AppBskyFeedRepost,
   AppBskyFeedLike,
 } from '@atproto/api'
+import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped'
 import chunk from 'lodash.chunk'
 import {QueryClient} from '@tanstack/react-query'
 import {getAgent} from '../../session'
diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts
index b91af372f..0e943622a 100644
--- a/src/state/queries/post-feed.ts
+++ b/src/state/queries/post-feed.ts
@@ -1,10 +1,5 @@
 import React, {useCallback, useEffect, useRef} from 'react'
-import {
-  AppBskyFeedDefs,
-  AppBskyFeedPost,
-  moderatePost,
-  PostModeration,
-} from '@atproto/api'
+import {AppBskyFeedDefs, AppBskyFeedPost, PostModeration} from '@atproto/api'
 import {
   useInfiniteQuery,
   InfiniteData,
@@ -12,6 +7,7 @@ import {
   QueryClient,
   useQueryClient,
 } from '@tanstack/react-query'
+import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped'
 import {useFeedTuners} from '../preferences/feed-tuners'
 import {FeedTuner, FeedTunerFn, NoopFeedTuner} from 'lib/api/feed-manip'
 import {FeedAPI, ReasonFeedSource} from 'lib/api/feed/types'
diff --git a/src/state/queries/preferences/index.ts b/src/state/queries/preferences/index.ts
index 872bb21af..a9aa7f26e 100644
--- a/src/state/queries/preferences/index.ts
+++ b/src/state/queries/preferences/index.ts
@@ -19,6 +19,7 @@ import {
 } from '#/state/queries/preferences/const'
 import {getModerationOpts} from '#/state/queries/preferences/moderation'
 import {STALE} from '#/state/queries'
+import {useHiddenPosts} from '#/state/preferences/hidden-posts'
 
 export * from '#/state/queries/preferences/types'
 export * from '#/state/queries/preferences/moderation'
@@ -94,15 +95,21 @@ export function usePreferencesQuery() {
 export function useModerationOpts() {
   const {currentAccount} = useSession()
   const prefs = usePreferencesQuery()
+  const hiddenPosts = useHiddenPosts()
   const opts = useMemo(() => {
     if (!prefs.data) {
       return
     }
-    return getModerationOpts({
+    const moderationOpts = getModerationOpts({
       userDid: currentAccount?.did || '',
       preferences: prefs.data,
     })
-  }, [currentAccount?.did, prefs.data])
+
+    return {
+      ...moderationOpts,
+      hiddenPosts,
+    }
+  }, [currentAccount?.did, prefs.data, hiddenPosts])
   return opts
 }