From f977b566a5caa39355241c3e0f809bcd50c8033c Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 7 Jul 2022 17:48:03 +0200 Subject: [PATCH] Implement mark as read via notification Resolves #2164 Signed-off-by: Andy Scherzinger --- app/src/main/AndroidManifest.xml | 1 + .../talk/jobs/NotificationWorker.java | 35 +++++ .../talk/receivers/MarkAsReadReceiver.kt | 125 ++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 app/src/main/java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9e1b27e5c..be6102c29 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -199,6 +199,7 @@ + = Build.VERSION_CODES.S) { + intentFlag = PendingIntent.FLAG_MUTABLE|PendingIntent.FLAG_UPDATE_CURRENT; + } else { + intentFlag = PendingIntent.FLAG_UPDATE_CURRENT; + } + PendingIntent pendingIntent = + PendingIntent.getBroadcast(context, systemNotificationId, actualIntent, intentFlag); + + NotificationCompat.Action action = + new NotificationCompat.Action.Builder(R.drawable.ic_eye, label, pendingIntent) + .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ) + .setShowsUserInterface(false) + .build(); + + notificationBuilder.addAction(action); + } + @RequiresApi(api = Build.VERSION_CODES.N) private void addReplyAction(NotificationCompat.Builder notificationBuilder, int systemNotificationId) { String replyLabel = context.getResources().getString(R.string.nc_reply); diff --git a/app/src/main/java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt b/app/src/main/java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt new file mode 100644 index 000000000..8a5814ca3 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt @@ -0,0 +1,125 @@ +/* + * Nextcloud Talk application + * + * @author Andy Scherzinger + * @author Dariusz Olszewski + * Copyright (C) 2022 Andy Scherzinger + * Copyright (C) 2022 Dariusz Olszewski + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.nextcloud.talk.receivers + +import android.app.NotificationManager +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.os.Build +import android.util.Log +import androidx.annotation.RequiresApi +import autodagger.AutoInjector +import com.nextcloud.talk.api.NcApi +import com.nextcloud.talk.application.NextcloudTalkApplication +import com.nextcloud.talk.models.database.UserEntity +import com.nextcloud.talk.models.json.generic.GenericOverall +import com.nextcloud.talk.utils.ApiUtils +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_MESSAGE_ID +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SYSTEM_NOTIFICATION_ID +import com.nextcloud.talk.utils.database.user.UserUtils +import io.reactivex.Observer +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.Disposable +import io.reactivex.schedulers.Schedulers +import javax.inject.Inject + +@AutoInjector(NextcloudTalkApplication::class) +class MarkAsReadReceiver : BroadcastReceiver() { + + @Inject + lateinit var userUtils: UserUtils + + @Inject + lateinit var ncApi: NcApi + + lateinit var context: Context + lateinit var currentUser: UserEntity + private var systemNotificationId: Int? = null + private var roomToken: String? = null + private var messageId: Int = 0 + + init { + NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) + } + + override fun onReceive(receiveContext: Context, intent: Intent?) { + context = receiveContext + + // NOTE - systemNotificationId is an internal ID used on the device only. + // It is NOT the same as the notification ID used in communication with the server. + systemNotificationId = intent!!.getIntExtra(KEY_SYSTEM_NOTIFICATION_ID, 0) + roomToken = intent.getStringExtra(KEY_ROOM_TOKEN) + messageId = intent.getIntExtra(KEY_MESSAGE_ID, 0) + + val id = intent.getLongExtra(KEY_INTERNAL_USER_ID, userUtils.currentUser!!.id) + currentUser = userUtils.getUserWithId(id) + + markAsRead() + } + + private fun markAsRead() { + val credentials = ApiUtils.getCredentials(currentUser.username, currentUser.token) + val apiVersion = ApiUtils.getChatApiVersion(currentUser, intArrayOf(1)) + val url = ApiUtils.getUrlForSetChatReadMarker( + apiVersion, + currentUser.baseUrl, + roomToken + ) + + ncApi.setChatReadMarker(credentials, url, messageId) + ?.subscribeOn(Schedulers.io()) + ?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribe(object : Observer { + override fun onSubscribe(d: Disposable) { + // unused atm + } + + @RequiresApi(Build.VERSION_CODES.N) + override fun onNext(genericOverall: GenericOverall) { + cancelNotification(systemNotificationId!!) + } + + @RequiresApi(Build.VERSION_CODES.N) + override fun onError(e: Throwable) { + Log.e(TAG, "Failed to send reply", e) + } + + override fun onComplete() { + // unused atm + } + }) + } + + @RequiresApi(Build.VERSION_CODES.N) + private fun cancelNotification(notificationId: Int) { + val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + notificationManager.cancel(notificationId) + } + + companion object { + const val TAG = "MarkAsReadReceiver" + } +}