diff options
-rw-r--r-- | modules/Share-with-Bluesky/ShareViewController.swift | 7 | ||||
-rw-r--r-- | src/lib/hooks/useIntentHandler.ts | 24 | ||||
-rw-r--r-- | src/state/queries/video/video.ts | 52 | ||||
-rw-r--r-- | src/state/shell/composer/index.tsx | 1 | ||||
-rw-r--r-- | src/view/com/composer/Composer.tsx | 2 | ||||
-rw-r--r-- | src/view/shell/Composer.ios.tsx | 1 | ||||
-rw-r--r-- | src/view/shell/Composer.tsx | 1 |
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> ) |