+79
-21
modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt
+79
-21
modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt
···
12
12
import java.io.FileOutputStream
13
13
import java.net.URLEncoder
14
14
15
+
enum class AttachmentType {
16
+
IMAGE,
17
+
VIDEO,
18
+
}
19
+
15
20
class ExpoReceiveAndroidIntentsModule : Module() {
16
21
override fun definition() =
17
22
ModuleDefinition {
···
23
28
}
24
29
25
30
private fun handleIntent(intent: Intent?) {
26
-
if (appContext.currentActivity == null || intent == null) return
31
+
if (appContext.currentActivity == null) return
32
+
intent?.let {
33
+
if (it.action == Intent.ACTION_SEND && it.type == "text/plain") {
34
+
handleTextIntent(it)
35
+
return
36
+
}
27
37
28
-
if (intent.action == Intent.ACTION_SEND) {
29
-
if (intent.type == "text/plain") {
30
-
handleTextIntent(intent)
31
-
} else if (intent.type.toString().startsWith("image/")) {
32
-
handleImageIntent(intent)
33
-
}
34
-
} else if (intent.action == Intent.ACTION_SEND_MULTIPLE) {
35
-
if (intent.type.toString().startsWith("image/")) {
36
-
handleImagesIntent(intent)
38
+
val type =
39
+
if (it.type.toString().startsWith("image/")) {
40
+
AttachmentType.IMAGE
41
+
} else if (it.type.toString().startsWith("video/")) {
42
+
AttachmentType.VIDEO
43
+
} else {
44
+
return
45
+
}
46
+
47
+
if (it.action == Intent.ACTION_SEND) {
48
+
handleAttachmentIntent(it, type)
49
+
} else if (it.action == Intent.ACTION_SEND_MULTIPLE) {
50
+
handleAttachmentsIntent(it, type)
37
51
}
38
52
}
39
53
}
···
48
62
}
49
63
}
50
64
51
-
private fun handleImageIntent(intent: Intent) {
65
+
private fun handleAttachmentIntent(
66
+
intent: Intent,
67
+
type: AttachmentType,
68
+
) {
52
69
val uri =
53
70
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
54
71
intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)
55
72
} else {
56
73
intent.getParcelableExtra(Intent.EXTRA_STREAM)
57
74
}
58
-
if (uri == null) return
59
75
60
-
handleImageIntents(listOf(uri))
76
+
uri?.let {
77
+
when (type) {
78
+
AttachmentType.IMAGE -> handleImageIntents(listOf(it))
79
+
AttachmentType.VIDEO -> handleVideoIntents(listOf(it))
80
+
}
81
+
}
61
82
}
62
83
63
-
private fun handleImagesIntent(intent: Intent) {
64
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
65
-
intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)?.let {
66
-
handleImageIntents(it.filterIsInstance<Uri>().take(4))
84
+
private fun handleAttachmentsIntent(
85
+
intent: Intent,
86
+
type: AttachmentType,
87
+
) {
88
+
val uris =
89
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
90
+
intent
91
+
.getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)
92
+
?.filterIsInstance<Uri>()
93
+
?.take(4)
94
+
} else {
95
+
intent
96
+
.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)
97
+
?.filterIsInstance<Uri>()
98
+
?.take(4)
67
99
}
68
-
} else {
69
-
intent.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)?.let {
70
-
handleImageIntents(it.filterIsInstance<Uri>().take(4))
100
+
101
+
uris?.let {
102
+
when (type) {
103
+
AttachmentType.IMAGE -> handleImageIntents(it)
104
+
else -> return
71
105
}
72
106
}
73
107
}
···
93
127
}
94
128
}
95
129
130
+
private fun handleVideoIntents(uris: List<Uri>) {
131
+
val uri = uris[0]
132
+
// If there is no extension for the file, substringAfterLast returns the original string - not
133
+
// null, so we check for that below
134
+
// It doesn't actually matter what the extension is, so defaulting to mp4 is fine, even if the
135
+
// video isn't actually an mp4
136
+
var extension = uri.path?.substringAfterLast(".")
137
+
if (extension == null || extension == uri.path) {
138
+
extension = "mp4"
139
+
}
140
+
val file = createFile(extension)
141
+
142
+
val out = FileOutputStream(file)
143
+
appContext.currentActivity?.contentResolver?.openInputStream(uri)?.use {
144
+
it.copyTo(out)
145
+
}
146
+
"bluesky://intent/compose?videoUri=${URLEncoder.encode(file.path, "UTF-8")}".toUri().let {
147
+
val newIntent = Intent(Intent.ACTION_VIEW, it)
148
+
appContext.currentActivity?.startActivity(newIntent)
149
+
}
150
+
}
151
+
96
152
private fun getImageInfo(uri: Uri): Map<String, Any> {
97
153
val bitmap = MediaStore.Images.Media.getBitmap(appContext.currentActivity?.contentResolver, uri)
98
154
// We have to save this so that we can access it later when uploading the image.
99
155
// createTempFile will automatically place a unique string between "img" and "temp.jpeg"
100
-
val file = File.createTempFile("img", "temp.jpeg", appContext.currentActivity?.cacheDir)
156
+
val file = createFile("jpeg")
101
157
val out = FileOutputStream(file)
102
158
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)
103
159
out.flush()
···
109
165
"path" to file.path.toString(),
110
166
)
111
167
}
168
+
169
+
private fun createFile(extension: String): File = File.createTempFile(extension, "temp.$extension", appContext.currentActivity?.cacheDir)
112
170
113
171
// We will pas the width and height to the app here, since getting measurements
114
172
// on the RN side is a bit more involved, and we already have them here anyway.