mattermost-mobile/android/app/src/main/java/com/mattermost/rnbeta/CustomPushNotification.kt

179 lines
7.6 KiB
Kotlin

package com.mattermost.rnbeta
import android.app.PendingIntent
import android.content.Context
import android.os.Bundle
import android.util.Log
import androidx.core.app.NotificationCompat
import com.mattermost.helpers.CustomPushNotificationHelper
import com.mattermost.helpers.DatabaseHelper
import com.mattermost.helpers.Network
import com.mattermost.helpers.NotificationHelper
import com.mattermost.helpers.PushNotificationDataHelper
import com.mattermost.helpers.database_extension.getServerUrlForIdentifier
import com.mattermost.share.ShareModule
import com.wix.reactnativenotifications.Defs.NOTIFICATION_RECEIVED_EVENT_NAME
import com.wix.reactnativenotifications.core.AppLaunchHelper
import com.wix.reactnativenotifications.core.AppLifecycleFacade
import com.wix.reactnativenotifications.core.JsIOHelper
import com.wix.reactnativenotifications.core.NotificationIntentAdapter
import com.wix.reactnativenotifications.core.notification.PushNotification
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class CustomPushNotification(
context: Context,
bundle: Bundle,
appLifecycleFacade: AppLifecycleFacade,
appLaunchHelper: AppLaunchHelper,
jsIoHelper: JsIOHelper
) : PushNotification(context, bundle, appLifecycleFacade, appLaunchHelper, jsIoHelper) {
private val dataHelper = PushNotificationDataHelper(context)
init {
try {
DatabaseHelper.instance?.init(context)
Network.init(context)
NotificationHelper.cleanNotificationPreferencesIfNeeded(context)
} catch (e: Exception) {
e.printStackTrace()
}
}
@OptIn(DelicateCoroutinesApi::class)
override fun onReceived() {
val initialData = mNotificationProps.asBundle()
val type = initialData.getString("type")
val ackId = initialData.getString("ack_id")
val postId = initialData.getString("post_id")
val channelId = initialData.getString("channel_id")
val signature = initialData.getString("signature")
val isIdLoaded = initialData.getString("id_loaded") == "true"
val notificationId = NotificationHelper.getNotificationId(initialData)
val serverUrl = addServerUrlToBundle(initialData)
GlobalScope.launch {
try {
handlePushNotificationInCoroutine(serverUrl, type, channelId, ackId, isIdLoaded, notificationId, postId, signature)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
private suspend fun handlePushNotificationInCoroutine(
serverUrl: String?,
type: String?,
channelId: String?,
ackId: String?,
isIdLoaded: Boolean,
notificationId: Int,
postId: String?,
signature: String?
) {
if (ackId != null && serverUrl != null) {
val response = ReceiptDelivery.send(ackId, serverUrl, postId, type, isIdLoaded)
if (isIdLoaded && response != null) {
val current = mNotificationProps.asBundle()
if (!current.containsKey("server_url")) {
response.putString("server_url", serverUrl)
}
current.putAll(response)
mNotificationProps = createProps(current)
}
}
if (!CustomPushNotificationHelper.verifySignature(mContext, signature, serverUrl, ackId)) {
Log.i("Mattermost Notifications Signature verification", "Notification skipped because we could not verify it.")
return
}
finishProcessingNotification(serverUrl, type, channelId, notificationId)
}
override fun onOpened() {
mNotificationProps?.let {
digestNotification()
NotificationHelper.clearChannelOrThreadNotifications(mContext, it.asBundle())
}
}
private suspend fun finishProcessingNotification(serverUrl: String?, type: String?, channelId: String?, notificationId: Int) {
val isReactInit = mAppLifecycleFacade.isReactInitialized()
when (type) {
CustomPushNotificationHelper.PUSH_TYPE_MESSAGE, CustomPushNotificationHelper.PUSH_TYPE_SESSION -> {
val shareModule = ShareModule.getInstance()
val currentActivityName = shareModule?.currentActivityName ?: ""
Log.i("ReactNative", currentActivityName)
if (!mAppLifecycleFacade.isAppVisible() || currentActivityName != "MainActivity") {
var createSummary = type == CustomPushNotificationHelper.PUSH_TYPE_MESSAGE
if (type == CustomPushNotificationHelper.PUSH_TYPE_MESSAGE) {
channelId?.let {
val notificationBundle = mNotificationProps.asBundle()
serverUrl?.let {
val notificationResult = dataHelper.fetchAndStoreDataForPushNotification(notificationBundle, isReactInit)
notificationResult?.let { result ->
notificationBundle.putBundle("data", result)
mNotificationProps = createProps(notificationBundle)
}
}
createSummary = NotificationHelper.addNotificationToPreferences(mContext, notificationId, notificationBundle)
}
}
buildNotification(notificationId, createSummary)
}
}
CustomPushNotificationHelper.PUSH_TYPE_CLEAR -> NotificationHelper.clearChannelOrThreadNotifications(mContext, mNotificationProps.asBundle())
}
if (isReactInit) {
notifyReceivedToJS()
}
}
private fun buildNotification(notificationId: Int, createSummary: Boolean) {
val pendingIntent = NotificationIntentAdapter.createPendingNotificationIntent(mContext, mNotificationProps)
val notification = buildNotification(pendingIntent)
if (createSummary) {
val summary = getNotificationSummaryBuilder(pendingIntent).build()
super.postNotification(summary, notificationId + 1)
}
super.postNotification(notification, notificationId)
}
override fun getNotificationBuilder(intent: PendingIntent): NotificationCompat.Builder {
val bundle = mNotificationProps.asBundle()
return CustomPushNotificationHelper.createNotificationBuilder(mContext, intent, bundle, false)
}
private fun getNotificationSummaryBuilder(intent: PendingIntent): NotificationCompat.Builder {
val bundle = mNotificationProps.asBundle()
return CustomPushNotificationHelper.createNotificationBuilder(mContext, intent, bundle, true)
}
private fun notifyReceivedToJS() {
mJsIOHelper.sendEventToJS(NOTIFICATION_RECEIVED_EVENT_NAME, mNotificationProps.asBundle(), mAppLifecycleFacade.runningReactContext)
}
private fun addServerUrlToBundle(bundle: Bundle): String? {
val dbHelper = DatabaseHelper.instance
val serverId = bundle.getString("server_id")
var serverUrl: String? = null
dbHelper?.let {
serverUrl = if (serverId == null) {
it.onlyServerUrl
} else {
it.getServerUrlForIdentifier(serverId)
}
if (!serverUrl.isNullOrEmpty()) {
bundle.putString("server_url", serverUrl)
mNotificationProps = createProps(bundle)
}
}
return serverUrl
}
}