about summary refs log tree commit diff
diff options
context:
space:
mode:
authorHailey <me@haileyok.com>2024-09-26 12:37:51 -0700
committerGitHub <noreply@github.com>2024-09-26 12:37:51 -0700
commit7ee67e4e7e10a808f8e885efea4caf0465ee9619 (patch)
tree871ffa8fad2b864a67da4a067b50c50a932ad998
parent175df72972343795a67be208e58edb02267e1ced (diff)
downloadvoidsky-7ee67e4e7e10a808f8e885efea4caf0465ee9619.tar.zst
[Share Extension] Move away from deprecated API, implement JS side of things (#5509)
-rw-r--r--modules/Share-with-Bluesky/ShareViewController.swift7
-rw-r--r--src/lib/hooks/useIntentHandler.ts24
-rw-r--r--src/state/queries/video/video.ts52
-rw-r--r--src/state/shell/composer/index.tsx1
-rw-r--r--src/view/com/composer/Composer.tsx2
-rw-r--r--src/view/shell/Composer.ios.tsx1
-rw-r--r--src/view/shell/Composer.tsx1
7 files changed, 59 insertions, 29 deletions
diff --git a/modules/Share-with-Bluesky/ShareViewController.swift b/modules/Share-with-Bluesky/ShareViewController.swift
index e166c22d2..46851a0d7 100644
--- a/modules/Share-with-Bluesky/ShareViewController.swift
+++ b/modules/Share-with-Bluesky/ShareViewController.swift
@@ -23,7 +23,7 @@ class ShareViewController: UIViewController {
         await self.handleUrl(item: firstAttachment)
       } else if firstAttachment.hasItemConformingToTypeIdentifier("public.image") {
         await self.handleImages(items: attachments)
-      } else if firstAttachment.hasItemConformingToTypeIdentifier("public.video") {
+      } else if firstAttachment.hasItemConformingToTypeIdentifier("public.movie") {
         await self.handleVideos(items: attachments)
       } else {
         self.completeRequest()
@@ -107,7 +107,7 @@ class ShareViewController: UIViewController {
         let data = try? Data(contentsOf: dataUri)
         try? data?.write(to: tempUrl)
 
-        if let encoded = dataUri.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
+        if let encoded = tempUrl.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
            let url = URL(string: "\(self.appScheme)://intent/compose?videoUri=\(encoded)") {
           _ = self.openURL(url)
         }
@@ -150,7 +150,8 @@ class ShareViewController: UIViewController {
     var responder: UIResponder? = self
     while responder != nil {
       if let application = responder as? UIApplication {
-          return application.perform(#selector(openURL(_:)), with: url) != nil
+        application.open(url)
+        return true
       }
       responder = responder?.next
     }
diff --git a/src/lib/hooks/useIntentHandler.ts b/src/lib/hooks/useIntentHandler.ts
index fd1638703..ce1d474d3 100644
--- a/src/lib/hooks/useIntentHandler.ts
+++ b/src/lib/hooks/useIntentHandler.ts
@@ -1,11 +1,11 @@
 import React from 'react'
 import * as Linking from 'expo-linking'
 
-import {logEvent} from 'lib/statsig/statsig'
-import {isNative} from 'platform/detection'
-import {useSession} from 'state/session'
-import {useComposerControls} from 'state/shell'
-import {useCloseAllActiveElements} from 'state/util'
+import {logEvent} from '#/lib/statsig/statsig'
+import {isNative} from '#/platform/detection'
+import {useSession} from '#/state/session'
+import {useComposerControls} from '#/state/shell'
+import {useCloseAllActiveElements} from '#/state/util'
 import {useIntentDialogs} from '#/components/intents/IntentDialogs'
 import {Referrer} from '../../../modules/expo-bluesky-swiss-army'
 
@@ -52,6 +52,7 @@ export function useIntentHandler() {
           composeIntent({
             text: params.get('text'),
             imageUrisStr: params.get('imageUris'),
+            videoUri: params.get('videoUri'),
           })
           return
         }
@@ -80,14 +81,25 @@ export function useComposeIntent() {
     ({
       text,
       imageUrisStr,
+      videoUri,
     }: {
       text: string | null
-      imageUrisStr: string | null // unused for right now, will be used later with intents
+      imageUrisStr: string | null
+      videoUri: string | null
     }) => {
       if (!hasSession) return
 
       closeAllActiveElements()
 
+      // Whenever a video URI is present, we don't support adding images right now.
+      if (videoUri) {
+        openComposer({
+          text: text ?? undefined,
+          videoUri,
+        })
+        return
+      }
+
       const imageUris = imageUrisStr
         ?.split(',')
         .filter(part => {
diff --git a/src/state/queries/video/video.ts b/src/state/queries/video/video.ts
index 32d02a63c..0d77935da 100644
--- a/src/state/queries/video/video.ts
+++ b/src/state/queries/video/video.ts
@@ -7,17 +7,17 @@ import {QueryClient, useQuery, useQueryClient} from '@tanstack/react-query'
 
 import {AbortError} from '#/lib/async/cancelable'
 import {SUPPORTED_MIME_TYPES, SupportedMimeTypes} from '#/lib/constants'
-import {logger} from '#/logger'
-import {isWeb} from '#/platform/detection'
 import {
   ServerError,
   UploadLimitError,
   VideoTooLargeError,
-} from 'lib/media/video/errors'
-import {CompressedVideo} from 'lib/media/video/types'
-import {useCompressVideoMutation} from 'state/queries/video/compress-video'
-import {useVideoAgent} from 'state/queries/video/util'
-import {useUploadVideoMutation} from 'state/queries/video/video-upload'
+} from '#/lib/media/video/errors'
+import {CompressedVideo} from '#/lib/media/video/types'
+import {logger} from '#/logger'
+import {isWeb} from '#/platform/detection'
+import {useCompressVideoMutation} from '#/state/queries/video/compress-video'
+import {useVideoAgent} from '#/state/queries/video/util'
+import {useUploadVideoMutation} from '#/state/queries/video/video-upload'
 
 type Status = 'idle' | 'compressing' | 'processing' | 'uploading' | 'done'
 
@@ -101,9 +101,11 @@ function reducer(queryClient: QueryClient) {
 
 export function useUploadVideo({
   setStatus,
+  initialVideoUri,
 }: {
   setStatus: (status: string) => void
   onSuccess: () => void
+  initialVideoUri?: string
 }) {
   const {_} = useLingui()
   const queryClient = useQueryClient()
@@ -237,21 +239,24 @@ export function useUploadVideo({
     signal: state.abortController.signal,
   })
 
-  const selectVideo = (asset: ImagePickerAsset) => {
-    // compression step on native converts to mp4, so no need to check there
-    if (isWeb) {
-      const mimeType = getMimeType(asset)
-      if (!SUPPORTED_MIME_TYPES.includes(mimeType as SupportedMimeTypes)) {
-        throw new Error(_(msg`Unsupported video type: ${mimeType}`))
+  const selectVideo = React.useCallback(
+    (asset: ImagePickerAsset) => {
+      // compression step on native converts to mp4, so no need to check there
+      if (isWeb) {
+        const mimeType = getMimeType(asset)
+        if (!SUPPORTED_MIME_TYPES.includes(mimeType as SupportedMimeTypes)) {
+          throw new Error(_(msg`Unsupported video type: ${mimeType}`))
+        }
       }
-    }
 
-    dispatch({
-      type: 'SetAsset',
-      asset,
-    })
-    onSelectVideo(asset)
-  }
+      dispatch({
+        type: 'SetAsset',
+        asset,
+      })
+      onSelectVideo(asset)
+    },
+    [_, onSelectVideo],
+  )
 
   const clearVideo = () => {
     dispatch({type: 'Reset'})
@@ -265,6 +270,13 @@ export function useUploadVideo({
     })
   }, [])
 
+  // Whenever we receive an initial video uri, we should immediately run compression if necessary
+  useEffect(() => {
+    if (initialVideoUri) {
+      selectVideo({uri: initialVideoUri} as ImagePickerAsset)
+    }
+  }, [initialVideoUri, selectVideo])
+
   return {
     state,
     dispatch,
diff --git a/src/state/shell/composer/index.tsx b/src/state/shell/composer/index.tsx
index 8e12386bd..1c3aa6a81 100644
--- a/src/state/shell/composer/index.tsx
+++ b/src/state/shell/composer/index.tsx
@@ -38,6 +38,7 @@ export interface ComposerOpts {
   openEmojiPicker?: (pos: DOMRect | undefined) => void
   text?: string
   imageUris?: {uri: string; width: number; height: number; altText?: string}[]
+  videoUri?: string
 }
 
 type StateContext = ComposerOpts | undefined
diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx
index 3b7cf1385..49ce0d442 100644
--- a/src/view/com/composer/Composer.tsx
+++ b/src/view/com/composer/Composer.tsx
@@ -137,6 +137,7 @@ export const ComposePost = ({
   openEmojiPicker,
   text: initText,
   imageUris: initImageUris,
+  videoUri: initVideoUri,
   cancelRef,
 }: Props & {
   cancelRef?: React.RefObject<CancelRef>
@@ -199,6 +200,7 @@ export const ComposePost = ({
         onPressPublish(true)
       }
     },
+    initialVideoUri: initVideoUri,
   })
   const hasVideo = Boolean(videoUploadState.asset || videoUploadState.video)
 
diff --git a/src/view/shell/Composer.ios.tsx b/src/view/shell/Composer.ios.tsx
index bbb837f1f..18410bf39 100644
--- a/src/view/shell/Composer.ios.tsx
+++ b/src/view/shell/Composer.ios.tsx
@@ -34,6 +34,7 @@ export function Composer({}: {winHeight: number}) {
             mention={state?.mention}
             text={state?.text}
             imageUris={state?.imageUris}
+            videoUri={state?.videoUri}
           />
         </Providers>
       </View>
diff --git a/src/view/shell/Composer.tsx b/src/view/shell/Composer.tsx
index 049f35d35..4a07cf9d9 100644
--- a/src/view/shell/Composer.tsx
+++ b/src/view/shell/Composer.tsx
@@ -54,6 +54,7 @@ export function Composer({winHeight}: {winHeight: number}) {
         mention={state.mention}
         text={state.text}
         imageUris={state.imageUris}
+        videoUri={state.videoUri}
       />
     </Animated.View>
   )