about summary refs log tree commit diff
path: root/src/lib/hooks/useIntentHandler.ts
diff options
context:
space:
mode:
authorHailey <me@haileyok.com>2024-02-27 10:35:38 -0800
committerGitHub <noreply@github.com>2024-02-27 10:35:38 -0800
commit2a04546c7305b9bf03ea6cd26ce728ed773e2673 (patch)
treeac52dcc02d170bdc9970514387352ab8e08b2bc1 /src/lib/hooks/useIntentHandler.ts
parentc8d02a791a84a243b290b3a1479aa6ac097a51fa (diff)
downloadvoidsky-2a04546c7305b9bf03ea6cd26ce728ed773e2673.tar.zst
Intent handler (#2992)
* Handle URL params

* Add resources

* Add other params

* refactor for scope

* modify the pr to support intents rather than utm

remove linebreak

remove linebreak

handle web

adjust path check to work on web

add a short delay for opening the composer

setup compose intent, move to `intents` directory

fix intent logic

ignore incoming intents in the navigation router

* refactor

---------

Co-authored-by: Eric Bailey <git@esb.lol>
Diffstat (limited to 'src/lib/hooks/useIntentHandler.ts')
-rw-r--r--src/lib/hooks/useIntentHandler.ts64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/lib/hooks/useIntentHandler.ts b/src/lib/hooks/useIntentHandler.ts
new file mode 100644
index 000000000..249e6898e
--- /dev/null
+++ b/src/lib/hooks/useIntentHandler.ts
@@ -0,0 +1,64 @@
+import React from 'react'
+import * as Linking from 'expo-linking'
+import {isNative} from 'platform/detection'
+import {useComposerControls} from 'state/shell'
+import {useSession} from 'state/session'
+
+type IntentType = 'compose'
+
+export function useIntentHandler() {
+  const incomingUrl = Linking.useURL()
+  const composeIntent = useComposeIntent()
+
+  React.useEffect(() => {
+    const handleIncomingURL = (url: string) => {
+      const urlp = new URL(url)
+      const [_, intentTypeNative, intentTypeWeb] = urlp.pathname.split('/')
+
+      // On native, our links look like bluesky://intent/SomeIntent, so we have to check the hostname for the
+      // intent check. On web, we have to check the first part of the path since we have an actual hostname
+      const intentType = isNative ? intentTypeNative : intentTypeWeb
+      const isIntent = isNative
+        ? urlp.hostname === 'intent'
+        : intentTypeNative === 'intent'
+      const params = urlp.searchParams
+
+      if (!isIntent) return
+
+      switch (intentType as IntentType) {
+        case 'compose': {
+          composeIntent({
+            text: params.get('text'),
+            imageUris: params.get('imageUris'),
+          })
+        }
+      }
+    }
+
+    if (incomingUrl) handleIncomingURL(incomingUrl)
+  }, [incomingUrl, composeIntent])
+}
+
+function useComposeIntent() {
+  const {openComposer} = useComposerControls()
+  const {hasSession} = useSession()
+
+  return React.useCallback(
+    ({
+      // eslint-disable-next-line @typescript-eslint/no-unused-vars
+      text,
+      // eslint-disable-next-line @typescript-eslint/no-unused-vars
+      imageUris,
+    }: {
+      text: string | null
+      imageUris: string | null // unused for right now, will be used later with intents
+    }) => {
+      if (!hasSession) return
+
+      setTimeout(() => {
+        openComposer({}) // will pass in values to the composer here in the share extension
+      }, 500)
+    },
+    [openComposer, hasSession],
+  )
+}