diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt index b0a667ee55..24cfd06a19 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt +++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt @@ -15,6 +15,7 @@ import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.graphics.Bitmap +import android.graphics.drawable.BitmapDrawable import android.os.Build import android.os.Bundle import android.os.Handler @@ -38,6 +39,9 @@ import androidx.work.Data import androidx.work.Worker import androidx.work.WorkerParameters import autodagger.AutoInjector +import coil.executeBlocking +import coil.imageLoader +import coil.request.ImageRequest import com.bluelinelabs.logansquare.LoganSquare import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R @@ -80,13 +84,13 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_MESSAGE_ID import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_ID import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_RESTRICT_DELETION import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_TIMESTAMP +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_OPENED_VIA_NOTIFICATION import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_REMOTE_TALK_SHARE import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ONE_TO_ONE import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SHARE_RECORDING_TO_CHAT_URL import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SYSTEM_NOTIFICATION_ID import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_THREAD_ID -import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_OPENED_VIA_NOTIFICATION import com.nextcloud.talk.utils.preferences.AppPreferences import io.reactivex.Observable import io.reactivex.Observer @@ -137,6 +141,8 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor private var context: Context? = null private var conversationType: String? = "one2one" private lateinit var notificationManager: NotificationManagerCompat + private var imagePreviewUrl: String? = null + private var imageMimeType: String? = null override fun doWork(): Result { sharedApplication!!.componentApplication.inject(this) @@ -477,6 +483,36 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor } else { pushMessage.subject = ncNotification.subject.orEmpty() } + + checkAndExtractImagePreviewData(ncNotification) + } + + private fun checkAndExtractImagePreviewData( + notification: com.nextcloud.talk.models.json.notifications.Notification + ) { + imagePreviewUrl = null + imageMimeType = null + val msgParams = notification.messageRichParameters + if (msgParams != null) { + for ((_, param) in msgParams) { + if (extractImagePreviewData(param)) break + } + } + } + + private fun extractImagePreviewData(param: HashMap): Boolean { + if (param["type"] == "file") { + val mimetype = param["mimetype"].orEmpty() + val fileId = param["id"] + if (mimetype.startsWith("image/") && fileId != null) { + val baseUrl = signatureVerification.user!!.baseUrl!! + val px = context!!.resources.displayMetrics.widthPixels + imagePreviewUrl = ApiUtils.getUrlForFilePreviewWithFileId(baseUrl, fileId, px) + imageMimeType = mimetype + return true + } + } + return false } @Suppress("MagicNumber") @@ -539,7 +575,11 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor if (TYPE_CHAT == pushMessage.type || TYPE_REMINDER == pushMessage.type) { notificationBuilder.setOnlyAlertOnce(false) if (pushMessage.notificationUser != null) { - styleChatNotification(notificationBuilder, activeStatusBarNotification) + if (imagePreviewUrl != null) { + styleImageNotification(notificationBuilder) + } else { + styleChatNotification(notificationBuilder, activeStatusBarNotification) + } addReplyAction(notificationBuilder, systemNotificationId) addMarkAsReadAction(notificationBuilder, systemNotificationId) } @@ -643,6 +683,34 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor return crc32.value } + private fun styleImageNotification(notificationBuilder: NotificationCompat.Builder) { + val bitmap = loadImageBitmapSync(imagePreviewUrl!!) + if (bitmap != null) { + notificationBuilder + .setLargeIcon(bitmap) + .setStyle( + NotificationCompat.BigPictureStyle() + .bigPicture(bitmap) + .bigLargeIcon(null as Bitmap?) + ) + } + } + + private fun loadImageBitmapSync(imageUrl: String): Bitmap? { + var bitmap: Bitmap? = null + val request = ImageRequest.Builder(context!!) + .data(imageUrl) + .allowHardware(false) + .addHeader("Authorization", credentials) + .target( + onSuccess = { result -> bitmap = (result as BitmapDrawable).bitmap }, + onError = { Log.w(TAG, "Failed to load notification image: $imageUrl") } + ) + .build() + context!!.imageLoader.executeBlocking(request) + return bitmap + } + private fun styleChatNotification( notificationBuilder: NotificationCompat.Builder, activeStatusBarNotification: StatusBarNotification?