[Share Extension] Move away from deprecated API, implement JS side of things (#5509)
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 => {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user