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/queries/resolve-link.ts70
-rw-r--r--src/state/shell/composer/index.tsx23
-rw-r--r--src/state/shell/index.tsx16
3 files changed, 100 insertions, 9 deletions
diff --git a/src/state/queries/resolve-link.ts b/src/state/queries/resolve-link.ts
new file mode 100644
index 000000000..5856cfb5f
--- /dev/null
+++ b/src/state/queries/resolve-link.ts
@@ -0,0 +1,70 @@
+import {QueryClient, useQuery} from '@tanstack/react-query'
+
+import {STALE} from '#/state/queries/index'
+import {useAgent} from '../session'
+
+const RQKEY_LINK_ROOT = 'resolve-link'
+export const RQKEY_LINK = (url: string) => [RQKEY_LINK_ROOT, url]
+
+const RQKEY_GIF_ROOT = 'resolve-gif'
+export const RQKEY_GIF = (url: string) => [RQKEY_GIF_ROOT, url]
+
+import {BskyAgent} from '@atproto/api'
+
+import {ResolvedLink, resolveGif, resolveLink} from '#/lib/api/resolve'
+import {Gif} from './tenor'
+
+export function useResolveLinkQuery(url: string) {
+  const agent = useAgent()
+  return useQuery({
+    staleTime: STALE.HOURS.ONE,
+    queryKey: RQKEY_LINK(url),
+    queryFn: async () => {
+      return await resolveLink(agent, url)
+    },
+  })
+}
+export function fetchResolveLinkQuery(
+  queryClient: QueryClient,
+  agent: BskyAgent,
+  url: string,
+) {
+  return queryClient.fetchQuery({
+    staleTime: STALE.HOURS.ONE,
+    queryKey: RQKEY_LINK(url),
+    queryFn: async () => {
+      return await resolveLink(agent, url)
+    },
+  })
+}
+export function precacheResolveLinkQuery(
+  queryClient: QueryClient,
+  url: string,
+  resolvedLink: ResolvedLink,
+) {
+  queryClient.setQueryData(RQKEY_LINK(url), resolvedLink)
+}
+
+export function useResolveGifQuery(gif: Gif) {
+  const agent = useAgent()
+  return useQuery({
+    staleTime: STALE.HOURS.ONE,
+    queryKey: RQKEY_GIF(gif.url),
+    queryFn: async () => {
+      return await resolveGif(agent, gif)
+    },
+  })
+}
+export function fetchResolveGifQuery(
+  queryClient: QueryClient,
+  agent: BskyAgent,
+  gif: Gif,
+) {
+  return queryClient.fetchQuery({
+    staleTime: STALE.HOURS.ONE,
+    queryKey: RQKEY_GIF(gif.url),
+    queryFn: async () => {
+      return await resolveGif(agent, gif)
+    },
+  })
+}
diff --git a/src/state/shell/composer/index.tsx b/src/state/shell/composer/index.tsx
index 770b0789e..096948506 100644
--- a/src/state/shell/composer/index.tsx
+++ b/src/state/shell/composer/index.tsx
@@ -7,9 +7,12 @@ import {
 } from '@atproto/api'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
+import {useQueryClient} from '@tanstack/react-query'
 
 import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
+import {postUriToRelativePath, toBskyAppUrl} from '#/lib/strings/url-helpers'
 import {purgeTemporaryImageFiles} from '#/state/gallery'
+import {precacheResolveLinkQuery} from '#/state/queries/resolve-link'
 import * as Toast from '#/view/com/util/Toast'
 
 export interface ComposerOptsPostRef {
@@ -58,8 +61,28 @@ const controlsContext = React.createContext<ControlsContext>({
 export function Provider({children}: React.PropsWithChildren<{}>) {
   const {_} = useLingui()
   const [state, setState] = React.useState<StateContext>()
+  const queryClient = useQueryClient()
 
   const openComposer = useNonReactiveCallback((opts: ComposerOpts) => {
+    if (opts.quote) {
+      const path = postUriToRelativePath(opts.quote.uri)
+      if (path) {
+        const appUrl = toBskyAppUrl(path)
+        precacheResolveLinkQuery(queryClient, appUrl, {
+          type: 'record',
+          kind: 'post',
+          record: {
+            cid: opts.quote.cid,
+            uri: opts.quote.uri,
+          },
+          meta: {
+            author: opts.quote.author,
+            indexedAt: opts.quote.indexedAt,
+            text: opts.quote.text,
+          },
+        })
+      }
+    }
     const author = opts.replyTo?.author || opts.quote?.author
     const isBlocked = Boolean(
       author &&
diff --git a/src/state/shell/index.tsx b/src/state/shell/index.tsx
index 07909c000..f61dc3c41 100644
--- a/src/state/shell/index.tsx
+++ b/src/state/shell/index.tsx
@@ -1,22 +1,22 @@
 import React from 'react'
-import {Provider as ShellLayoutProvder} from './shell-layout'
+
+import {Provider as ColorModeProvider} from './color-mode'
 import {Provider as DrawerOpenProvider} from './drawer-open'
 import {Provider as DrawerSwipableProvider} from './drawer-swipe-disabled'
 import {Provider as MinimalModeProvider} from './minimal-mode'
-import {Provider as ColorModeProvider} from './color-mode'
 import {Provider as OnboardingProvider} from './onboarding'
-import {Provider as ComposerProvider} from './composer'
+import {Provider as ShellLayoutProvder} from './shell-layout'
 import {Provider as TickEveryMinuteProvider} from './tick-every-minute'
 
+export {useSetThemePrefs, useThemePrefs} from './color-mode'
+export {useComposerControls, useComposerState} from './composer'
 export {useIsDrawerOpen, useSetDrawerOpen} from './drawer-open'
 export {
   useIsDrawerSwipeDisabled,
   useSetDrawerSwipeDisabled,
 } from './drawer-swipe-disabled'
 export {useMinimalShellMode, useSetMinimalShellMode} from './minimal-mode'
-export {useThemePrefs, useSetThemePrefs} from './color-mode'
-export {useOnboardingState, useOnboardingDispatch} from './onboarding'
-export {useComposerState, useComposerControls} from './composer'
+export {useOnboardingDispatch, useOnboardingState} from './onboarding'
 export {useTickEveryMinute} from './tick-every-minute'
 
 export function Provider({children}: React.PropsWithChildren<{}>) {
@@ -27,9 +27,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
           <MinimalModeProvider>
             <ColorModeProvider>
               <OnboardingProvider>
-                <ComposerProvider>
-                  <TickEveryMinuteProvider>{children}</TickEveryMinuteProvider>
-                </ComposerProvider>
+                <TickEveryMinuteProvider>{children}</TickEveryMinuteProvider>
               </OnboardingProvider>
             </ColorModeProvider>
           </MinimalModeProvider>