<lambda>null1 package expo.modules.mailcomposer
2
3 import android.content.Intent
4 import android.content.pm.LabeledIntent
5 import android.net.Uri
6 import android.os.Bundle
7 import expo.modules.kotlin.Promise
8 import expo.modules.kotlin.exception.Exceptions
9 import expo.modules.kotlin.modules.Module
10 import expo.modules.kotlin.modules.ModuleDefinition
11
12 class MailComposerModule : Module() {
13 private val context
14 get() = appContext.reactContext ?: throw Exceptions.ReactContextLost()
15 private val currentActivity
16 get() = appContext.currentActivity ?: throw Exceptions.MissingActivity()
17 private var composerOpened = false
18 private var pendingPromise: Promise? = null
19
20 override fun definition() = ModuleDefinition {
21 Name("ExpoMailComposer")
22
23 AsyncFunction("isAvailableAsync") {
24 return@AsyncFunction true
25 }
26
27 AsyncFunction("composeAsync") { options: MailComposerOptions, promise: Promise ->
28 val intent = Intent(Intent.ACTION_SENDTO).apply { data = Uri.parse("mailto:") }
29 val application = currentActivity.application
30 val resolveInfo = context.packageManager.queryIntentActivities(intent, 0)
31
32 val mailIntents = resolveInfo.map { info ->
33 val mailIntentBuilder = MailIntentBuilder(options)
34 .setComponentName(info.activityInfo.packageName, info.activityInfo.name)
35 .putRecipients(Intent.EXTRA_EMAIL)
36 .putCcRecipients(Intent.EXTRA_CC)
37 .putBccRecipients(Intent.EXTRA_BCC)
38 .putSubject(Intent.EXTRA_SUBJECT)
39 .putBody(Intent.EXTRA_TEXT, options.isHtml ?: false)
40 .putAttachments(
41 Intent.EXTRA_STREAM,
42 application
43 )
44
45 LabeledIntent(
46 mailIntentBuilder.build(),
47 info.activityInfo.packageName,
48 info.loadLabel(context.packageManager),
49 info.icon
50 )
51 }.toMutableList()
52
53 val chooser = Intent.createChooser(
54 mailIntents.removeAt(mailIntents.size - 1),
55 null
56 ).apply {
57 putExtra(Intent.EXTRA_INITIAL_INTENTS, mailIntents.toTypedArray())
58 addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
59 }
60
61 pendingPromise = promise
62 currentActivity.startActivityForResult(chooser, REQUEST_CODE)
63 composerOpened = true
64 }
65
66 OnActivityResult { _, payload ->
67 if (payload.requestCode == REQUEST_CODE && pendingPromise != null) {
68 val promise = pendingPromise ?: return@OnActivityResult
69 if (composerOpened) {
70 composerOpened = false
71 promise.resolve(Bundle().apply { putString("status", "sent") })
72 }
73 }
74 }
75 }
76
77 companion object {
78 private const val REQUEST_CODE = 8675
79 }
80 }
81