[Share Extension] Move away from deprecated API, implement JS side of things (#5509)

This commit is contained in:
Hailey
2024-09-26 12:37:51 -07:00
committed by GitHub
parent 175df72972
commit 7ee67e4e7e
7 changed files with 59 additions and 29 deletions
@@ -23,7 +23,7 @@ class ShareViewController: UIViewController {
await self.handleUrl(item: firstAttachment) await self.handleUrl(item: firstAttachment)
} else if firstAttachment.hasItemConformingToTypeIdentifier("public.image") { } else if firstAttachment.hasItemConformingToTypeIdentifier("public.image") {
await self.handleImages(items: attachments) await self.handleImages(items: attachments)
} else if firstAttachment.hasItemConformingToTypeIdentifier("public.video") { } else if firstAttachment.hasItemConformingToTypeIdentifier("public.movie") {
await self.handleVideos(items: attachments) await self.handleVideos(items: attachments)
} else { } else {
self.completeRequest() self.completeRequest()
@@ -107,7 +107,7 @@ class ShareViewController: UIViewController {
let data = try? Data(contentsOf: dataUri) let data = try? Data(contentsOf: dataUri)
try? data?.write(to: tempUrl) 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)") { let url = URL(string: "\(self.appScheme)://intent/compose?videoUri=\(encoded)") {
_ = self.openURL(url) _ = self.openURL(url)
} }
@@ -150,7 +150,8 @@ class ShareViewController: UIViewController {
var responder: UIResponder? = self var responder: UIResponder? = self
while responder != nil { while responder != nil {
if let application = responder as? UIApplication { if let application = responder as? UIApplication {
return application.perform(#selector(openURL(_:)), with: url) != nil application.open(url)
return true
} }
responder = responder?.next responder = responder?.next
} }
+18 -6
View File
@@ -1,11 +1,11 @@
import React from 'react' import React from 'react'
import * as Linking from 'expo-linking' import * as Linking from 'expo-linking'
import {logEvent} from 'lib/statsig/statsig' import {logEvent} from '#/lib/statsig/statsig'
import {isNative} from 'platform/detection' import {isNative} from '#/platform/detection'
import {useSession} from 'state/session' import {useSession} from '#/state/session'
import {useComposerControls} from 'state/shell' import {useComposerControls} from '#/state/shell'
import {useCloseAllActiveElements} from 'state/util' import {useCloseAllActiveElements} from '#/state/util'
import {useIntentDialogs} from '#/components/intents/IntentDialogs' import {useIntentDialogs} from '#/components/intents/IntentDialogs'
import {Referrer} from '../../../modules/expo-bluesky-swiss-army' import {Referrer} from '../../../modules/expo-bluesky-swiss-army'
@@ -52,6 +52,7 @@ export function useIntentHandler() {
composeIntent({ composeIntent({
text: params.get('text'), text: params.get('text'),
imageUrisStr: params.get('imageUris'), imageUrisStr: params.get('imageUris'),
videoUri: params.get('videoUri'),
}) })
return return
} }
@@ -80,14 +81,25 @@ export function useComposeIntent() {
({ ({
text, text,
imageUrisStr, imageUrisStr,
videoUri,
}: { }: {
text: string | null 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 if (!hasSession) return
closeAllActiveElements() 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 const imageUris = imageUrisStr
?.split(',') ?.split(',')
.filter(part => { .filter(part => {
+32 -20
View File
@@ -7,17 +7,17 @@ import {QueryClient, useQuery, useQueryClient} from '@tanstack/react-query'
import {AbortError} from '#/lib/async/cancelable' import {AbortError} from '#/lib/async/cancelable'
import {SUPPORTED_MIME_TYPES, SupportedMimeTypes} from '#/lib/constants' import {SUPPORTED_MIME_TYPES, SupportedMimeTypes} from '#/lib/constants'
import {logger} from '#/logger'
import {isWeb} from '#/platform/detection'
import { import {
ServerError, ServerError,
UploadLimitError, UploadLimitError,
VideoTooLargeError, VideoTooLargeError,
} from 'lib/media/video/errors' } from '#/lib/media/video/errors'
import {CompressedVideo} from 'lib/media/video/types' import {CompressedVideo} from '#/lib/media/video/types'
import {useCompressVideoMutation} from 'state/queries/video/compress-video' import {logger} from '#/logger'
import {useVideoAgent} from 'state/queries/video/util' import {isWeb} from '#/platform/detection'
import {useUploadVideoMutation} from 'state/queries/video/video-upload' 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' type Status = 'idle' | 'compressing' | 'processing' | 'uploading' | 'done'
@@ -101,9 +101,11 @@ function reducer(queryClient: QueryClient) {
export function useUploadVideo({ export function useUploadVideo({
setStatus, setStatus,
initialVideoUri,
}: { }: {
setStatus: (status: string) => void setStatus: (status: string) => void
onSuccess: () => void onSuccess: () => void
initialVideoUri?: string
}) { }) {
const {_} = useLingui() const {_} = useLingui()
const queryClient = useQueryClient() const queryClient = useQueryClient()
@@ -237,21 +239,24 @@ export function useUploadVideo({
signal: state.abortController.signal, signal: state.abortController.signal,
}) })
const selectVideo = (asset: ImagePickerAsset) => { const selectVideo = React.useCallback(
// compression step on native converts to mp4, so no need to check there (asset: ImagePickerAsset) => {
if (isWeb) { // compression step on native converts to mp4, so no need to check there
const mimeType = getMimeType(asset) if (isWeb) {
if (!SUPPORTED_MIME_TYPES.includes(mimeType as SupportedMimeTypes)) { const mimeType = getMimeType(asset)
throw new Error(_(msg`Unsupported video type: ${mimeType}`)) if (!SUPPORTED_MIME_TYPES.includes(mimeType as SupportedMimeTypes)) {
throw new Error(_(msg`Unsupported video type: ${mimeType}`))
}
} }
}
dispatch({ dispatch({
type: 'SetAsset', type: 'SetAsset',
asset, asset,
}) })
onSelectVideo(asset) onSelectVideo(asset)
} },
[_, onSelectVideo],
)
const clearVideo = () => { const clearVideo = () => {
dispatch({type: 'Reset'}) 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 { return {
state, state,
dispatch, dispatch,
+1
View File
@@ -38,6 +38,7 @@ export interface ComposerOpts {
openEmojiPicker?: (pos: DOMRect | undefined) => void openEmojiPicker?: (pos: DOMRect | undefined) => void
text?: string text?: string
imageUris?: {uri: string; width: number; height: number; altText?: string}[] imageUris?: {uri: string; width: number; height: number; altText?: string}[]
videoUri?: string
} }
type StateContext = ComposerOpts | undefined type StateContext = ComposerOpts | undefined
+2
View File
@@ -137,6 +137,7 @@ export const ComposePost = ({
openEmojiPicker, openEmojiPicker,
text: initText, text: initText,
imageUris: initImageUris, imageUris: initImageUris,
videoUri: initVideoUri,
cancelRef, cancelRef,
}: Props & { }: Props & {
cancelRef?: React.RefObject<CancelRef> cancelRef?: React.RefObject<CancelRef>
@@ -199,6 +200,7 @@ export const ComposePost = ({
onPressPublish(true) onPressPublish(true)
} }
}, },
initialVideoUri: initVideoUri,
}) })
const hasVideo = Boolean(videoUploadState.asset || videoUploadState.video) const hasVideo = Boolean(videoUploadState.asset || videoUploadState.video)
+1
View File
@@ -34,6 +34,7 @@ export function Composer({}: {winHeight: number}) {
mention={state?.mention} mention={state?.mention}
text={state?.text} text={state?.text}
imageUris={state?.imageUris} imageUris={state?.imageUris}
videoUri={state?.videoUri}
/> />
</Providers> </Providers>
</View> </View>
+1
View File
@@ -54,6 +54,7 @@ export function Composer({winHeight}: {winHeight: number}) {
mention={state.mention} mention={state.mention}
text={state.text} text={state.text}
imageUris={state.imageUris} imageUris={state.imageUris}
videoUri={state.videoUri}
/> />
</Animated.View> </Animated.View>
) )