about summary refs log tree commit diff
path: root/modules
diff options
context:
space:
mode:
authorHailey <me@haileyok.com>2024-09-27 09:54:37 -0700
committerGitHub <noreply@github.com>2024-09-27 09:54:37 -0700
commitd8f72c1ee10632860de9a67ce9c84831463ad07c (patch)
tree0a3cca507a3d2311cd1e69a622e9d03cbe15d6b6 /modules
parent4553e6b64955c32225cefbe14117e4d08a0520ca (diff)
downloadvoidsky-d8f72c1ee10632860de9a67ce9c84831463ad07c.tar.zst
[Share Extension] Support on Android for sharing videos to app (#5466)
Diffstat (limited to 'modules')
-rw-r--r--modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt100
1 files changed, 79 insertions, 21 deletions
diff --git a/modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt b/modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt
index 7ecea1631..c88442057 100644
--- a/modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt
+++ b/modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt
@@ -12,6 +12,11 @@ import java.io.File
 import java.io.FileOutputStream
 import java.net.URLEncoder
 
+enum class AttachmentType {
+  IMAGE,
+  VIDEO,
+}
+
 class ExpoReceiveAndroidIntentsModule : Module() {
   override fun definition() =
     ModuleDefinition {
@@ -23,17 +28,26 @@ class ExpoReceiveAndroidIntentsModule : Module() {
     }
 
   private fun handleIntent(intent: Intent?) {
-    if (appContext.currentActivity == null || intent == null) return
-
-    if (intent.action == Intent.ACTION_SEND) {
-      if (intent.type == "text/plain") {
-        handleTextIntent(intent)
-      } else if (intent.type.toString().startsWith("image/")) {
-        handleImageIntent(intent)
+    if (appContext.currentActivity == null) return
+    intent?.let {
+      if (it.action == Intent.ACTION_SEND && it.type == "text/plain") {
+        handleTextIntent(it)
+        return
       }
-    } else if (intent.action == Intent.ACTION_SEND_MULTIPLE) {
-      if (intent.type.toString().startsWith("image/")) {
-        handleImagesIntent(intent)
+
+      val type =
+        if (it.type.toString().startsWith("image/")) {
+          AttachmentType.IMAGE
+        } else if (it.type.toString().startsWith("video/")) {
+          AttachmentType.VIDEO
+        } else {
+          return
+        }
+
+      if (it.action == Intent.ACTION_SEND) {
+        handleAttachmentIntent(it, type)
+      } else if (it.action == Intent.ACTION_SEND_MULTIPLE) {
+        handleAttachmentsIntent(it, type)
       }
     }
   }
@@ -48,26 +62,46 @@ class ExpoReceiveAndroidIntentsModule : Module() {
     }
   }
 
-  private fun handleImageIntent(intent: Intent) {
+  private fun handleAttachmentIntent(
+    intent: Intent,
+    type: AttachmentType,
+  ) {
     val uri =
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
         intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)
       } else {
         intent.getParcelableExtra(Intent.EXTRA_STREAM)
       }
-    if (uri == null) return
 
-    handleImageIntents(listOf(uri))
+    uri?.let {
+      when (type) {
+        AttachmentType.IMAGE -> handleImageIntents(listOf(it))
+        AttachmentType.VIDEO -> handleVideoIntents(listOf(it))
+      }
+    }
   }
 
-  private fun handleImagesIntent(intent: Intent) {
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
-      intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)?.let {
-        handleImageIntents(it.filterIsInstance<Uri>().take(4))
+  private fun handleAttachmentsIntent(
+    intent: Intent,
+    type: AttachmentType,
+  ) {
+    val uris =
+      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+        intent
+          .getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)
+          ?.filterIsInstance<Uri>()
+          ?.take(4)
+      } else {
+        intent
+          .getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)
+          ?.filterIsInstance<Uri>()
+          ?.take(4)
       }
-    } else {
-      intent.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)?.let {
-        handleImageIntents(it.filterIsInstance<Uri>().take(4))
+
+    uris?.let {
+      when (type) {
+        AttachmentType.IMAGE -> handleImageIntents(it)
+        else -> return
       }
     }
   }
@@ -93,11 +127,33 @@ class ExpoReceiveAndroidIntentsModule : Module() {
     }
   }
 
+  private fun handleVideoIntents(uris: List<Uri>) {
+    val uri = uris[0]
+    // If there is no extension for the file, substringAfterLast returns the original string - not
+    // null, so we check for that below
+    // It doesn't actually matter what the extension is, so defaulting to mp4 is fine, even if the
+    // video isn't actually an mp4
+    var extension = uri.path?.substringAfterLast(".")
+    if (extension == null || extension == uri.path) {
+      extension = "mp4"
+    }
+    val file = createFile(extension)
+
+    val out = FileOutputStream(file)
+    appContext.currentActivity?.contentResolver?.openInputStream(uri)?.use {
+      it.copyTo(out)
+    }
+    "bluesky://intent/compose?videoUri=${URLEncoder.encode(file.path, "UTF-8")}".toUri().let {
+      val newIntent = Intent(Intent.ACTION_VIEW, it)
+      appContext.currentActivity?.startActivity(newIntent)
+    }
+  }
+
   private fun getImageInfo(uri: Uri): Map<String, Any> {
     val bitmap = MediaStore.Images.Media.getBitmap(appContext.currentActivity?.contentResolver, uri)
     // We have to save this so that we can access it later when uploading the image.
     // createTempFile will automatically place a unique string between "img" and "temp.jpeg"
-    val file = File.createTempFile("img", "temp.jpeg", appContext.currentActivity?.cacheDir)
+    val file = createFile("jpeg")
     val out = FileOutputStream(file)
     bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)
     out.flush()
@@ -110,6 +166,8 @@ class ExpoReceiveAndroidIntentsModule : Module() {
     )
   }
 
+  private fun createFile(extension: String): File = File.createTempFile(extension, "temp.$extension", appContext.currentActivity?.cacheDir)
+
   // We will pas the width and height to the app here, since getting measurements
   // on the RN side is a bit more involved, and we already have them here anyway.
   private fun buildUriData(info: Map<String, Any>): String {