about summary refs log tree commit diff
path: root/src/state/unstable-post-source.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/state/unstable-post-source.tsx')
-rw-r--r--src/state/unstable-post-source.tsx73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/state/unstable-post-source.tsx b/src/state/unstable-post-source.tsx
new file mode 100644
index 000000000..1fb4af287
--- /dev/null
+++ b/src/state/unstable-post-source.tsx
@@ -0,0 +1,73 @@
+import {createContext, useCallback, useContext, useState} from 'react'
+import {type AppBskyFeedDefs} from '@atproto/api'
+
+import {type FeedDescriptor} from './queries/post-feed'
+
+/**
+ * For passing the source of the post (i.e. the original post, from the feed) to the threadview,
+ * without using query params. Deliberately unstable to avoid using query params, use for FeedFeedback
+ * and other ephemeral non-critical systems.
+ */
+
+type Source = {
+  post: AppBskyFeedDefs.FeedViewPost
+  feed?: FeedDescriptor
+}
+
+const SetUnstablePostSourceContext = createContext<
+  (key: string, source: Source) => void
+>(() => {})
+const ConsumeUnstablePostSourceContext = createContext<
+  (uri: string) => Source | undefined
+>(() => undefined)
+
+export function Provider({children}: {children: React.ReactNode}) {
+  const [sources, setSources] = useState<Map<string, Source>>(() => new Map())
+
+  const setUnstablePostSource = useCallback((key: string, source: Source) => {
+    setSources(prev => {
+      const newMap = new Map(prev)
+      newMap.set(key, source)
+      return newMap
+    })
+  }, [])
+
+  const consumeUnstablePostSource = useCallback(
+    (uri: string) => {
+      const source = sources.get(uri)
+      if (source) {
+        setSources(prev => {
+          const newMap = new Map(prev)
+          newMap.delete(uri)
+          return newMap
+        })
+      }
+      return source
+    },
+    [sources],
+  )
+
+  return (
+    <SetUnstablePostSourceContext.Provider value={setUnstablePostSource}>
+      <ConsumeUnstablePostSourceContext.Provider
+        value={consumeUnstablePostSource}>
+        {children}
+      </ConsumeUnstablePostSourceContext.Provider>
+    </SetUnstablePostSourceContext.Provider>
+  )
+}
+
+export function useSetUnstablePostSource() {
+  return useContext(SetUnstablePostSourceContext)
+}
+
+/**
+ * DANGER - This hook is unstable and should only be used for FeedFeedback
+ * and other ephemeral non-critical systems. Does not change when the URI changes.
+ */
+export function useUnstablePostSource(uri: string) {
+  const consume = useContext(ConsumeUnstablePostSourceContext)
+
+  const [source] = useState(() => consume(uri))
+  return source
+}