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