diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index 722460a1..aaae3edb 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -63,6 +63,8 @@ + + @@ -76,6 +78,16 @@ + + + + + + + () private val pushManager by inject() + private val notificationDrawerManager by inject() + // TODO Move this elsewhere private val incomingVerificationRequestHandler by inject() // TODO Move this elsewhere @@ -115,6 +117,20 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { incomingVerificationRequestHandler.ensureStarted() keyRequestHandler.ensureStarted() + + if (intent.hasExtra(EXTRA_CLEAR_EXISTING_NOTIFICATION)) { + notificationDrawerManager.clearAllEvents() + intent.removeExtra(EXTRA_CLEAR_EXISTING_NOTIFICATION) + } + } + + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + + if (intent?.hasExtra(EXTRA_CLEAR_EXISTING_NOTIFICATION) == true) { + notificationDrawerManager.clearAllEvents() + intent.removeExtra(EXTRA_CLEAR_EXISTING_NOTIFICATION) + } } override fun onDestroy() { @@ -189,10 +205,14 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { companion object { - fun newIntent(context: Context): Intent { - return Intent(context, HomeActivity::class.java) - } + private const val EXTRA_CLEAR_EXISTING_NOTIFICATION = "EXTRA_CLEAR_EXISTING_NOTIFICATION" + fun newIntent(context: Context, clearNotification: Boolean = false): Intent { + return Intent(context, HomeActivity::class.java) + .apply { + putExtra(EXTRA_CLEAR_EXISTING_NOTIFICATION, clearNotification) + } + } } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt index 9f5a748c..f8f6f297 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt @@ -43,7 +43,6 @@ import butterknife.BindView import com.airbnb.epoxy.EpoxyVisibilityTracker import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel -import com.airbnb.mvrx.withState import com.github.piasy.biv.BigImageViewer import com.github.piasy.biv.loader.ImageLoader import com.google.android.material.snackbar.Snackbar @@ -92,6 +91,7 @@ import im.vector.riotredesign.features.media.ImageContentRenderer import im.vector.riotredesign.features.media.ImageMediaViewerActivity import im.vector.riotredesign.features.media.VideoContentRenderer import im.vector.riotredesign.features.media.VideoMediaViewerActivity +import im.vector.riotredesign.features.notifications.NotificationDrawerManager import im.vector.riotredesign.features.reactions.EmojiReactionPickerActivity import im.vector.riotredesign.features.settings.PreferencesManager import kotlinx.android.parcel.Parcelize @@ -168,6 +168,8 @@ class RoomDetailFragment : private val autocompleteUserPresenter: AutocompleteUserPresenter by inject { parametersOf(this) } private val permalinkHandler: PermalinkHandler by inject() + private val notificationDrawerManager by inject() + private lateinit var scrollOnNewMessageCallback: ScrollOnNewMessageCallback private lateinit var scrollOnHighlightedEventCallback: ScrollOnHighlightedEventCallback @@ -277,6 +279,18 @@ class RoomDetailFragment : } } + override fun onResume() { + super.onResume() + + notificationDrawerManager.setCurrentRoom(roomDetailArgs.roomId) + } + + override fun onPause() { + super.onPause() + + notificationDrawerManager.setCurrentRoom(null) + } + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (resultCode == RESULT_OK && data != null) { diff --git a/vector/src/main/java/im/vector/riotredesign/features/notifications/NotificationBroadcastReceiver.kt b/vector/src/main/java/im/vector/riotredesign/features/notifications/NotificationBroadcastReceiver.kt index 36692b7d..48f8ef43 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/notifications/NotificationBroadcastReceiver.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/notifications/NotificationBroadcastReceiver.kt @@ -20,11 +20,15 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import androidx.core.app.RemoteInput +import im.vector.matrix.android.api.Matrix +import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.room.Room +import im.vector.riotredesign.R import org.koin.standalone.KoinComponent import org.koin.standalone.inject import timber.log.Timber +import java.util.* /** * Receives actions broadcast by notification (on click, on dismiss, inline replies, etc.) @@ -39,15 +43,15 @@ class NotificationBroadcastReceiver : BroadcastReceiver(), KoinComponent { Timber.v("ReplyNotificationBroadcastReceiver received : $intent") when (intent.action) { - NotificationUtils.SMART_REPLY_ACTION -> + NotificationUtils.SMART_REPLY_ACTION -> handleSmartReply(intent, context) NotificationUtils.DISMISS_ROOM_NOTIF_ACTION -> intent.getStringExtra(KEY_ROOM_ID)?.let { notificationDrawerManager.clearMessageEventOfRoom(it) } - NotificationUtils.DISMISS_SUMMARY_ACTION -> + NotificationUtils.DISMISS_SUMMARY_ACTION -> notificationDrawerManager.clearAllEvents() - NotificationUtils.MARK_ROOM_READ_ACTION -> + NotificationUtils.MARK_ROOM_READ_ACTION -> intent.getStringExtra(KEY_ROOM_ID)?.let { notificationDrawerManager.clearMessageEventOfRoom(it) handleMarkAsRead(context, it) @@ -56,67 +60,59 @@ class NotificationBroadcastReceiver : BroadcastReceiver(), KoinComponent { } private fun handleMarkAsRead(context: Context, roomId: String) { - /* - TODO - Matrix.getInstance(context)?.defaultSession?.let { session -> - session.dataHandler - ?.getRoom(roomId) - ?.markAllAsRead(object : SimpleApiCallback() { - override fun onSuccess(void: Void?) { - // Ignore - } - }) + Matrix.getInstance().currentSession?.let { session -> + session.getRoom(roomId) + ?.markAllAsRead(object : MatrixCallback {}) } - */ } private fun handleSmartReply(intent: Intent, context: Context) { - /* - TODO val message = getReplyMessage(intent) val roomId = intent.getStringExtra(KEY_ROOM_ID) - if (TextUtils.isEmpty(message) || TextUtils.isEmpty(roomId)) { + if (message.isNullOrBlank() || roomId.isBlank()) { //ignore this event //Can this happen? should we update notification? return } val matrixId = intent.getStringExtra(EXTRA_MATRIX_ID) - Matrix.getInstance(context)?.getSession(matrixId)?.let { session -> - session.dataHandler?.getRoom(roomId)?.let { room -> - sendMatrixEvent(message!!, session, roomId!!, room, context) + Matrix.getInstance().currentSession?.let { session -> + session.getRoom(roomId)?.let { room -> + sendMatrixEvent(message, session, room, context) } } - */ } - private fun sendMatrixEvent(message: String, session: Session, roomId: String, room: Room, context: Context?) { - /* - TODO + private fun sendMatrixEvent(message: String, session: Session, room: Room, context: Context?) { - val mxMessage = Message() - mxMessage.msgtype = Message.MSGTYPE_TEXT - mxMessage.body = message + room.sendTextMessage(message) + + // Create a new event to be displayed in the notification drawer, right now + + val notifiableMessageEvent = NotifiableMessageEvent( + Random().nextInt().toString(),// TODO event.eventId, + false, + System.currentTimeMillis(), + session.getUser(session.sessionParams.credentials.userId)?.displayName + ?: context?.getString(R.string.notification_sender_me), + session.sessionParams.credentials.userId, + message, + room.roomId, + "Room name", // TODO room.getRoomDisplayName(context), + false // TODO room.isDirect + ) + notifiableMessageEvent.outGoingMessage = true + + notificationDrawerManager.onNotifiableEventReceived(notifiableMessageEvent) + notificationDrawerManager.refreshNotificationDrawer() + + /* val event = Event(mxMessage, session.credentials.userId, roomId) room.storeOutgoingEvent(event) room.sendEvent(event, object : MatrixCallback { override fun onSuccess(info: Void?) { Timber.v("Send message : onSuccess ") - val notifiableMessageEvent = NotifiableMessageEvent( - event.eventId, - false, - System.currentTimeMillis(), - session.myUser?.displayname - ?: context?.getString(R.string.notification_sender_me), - session.myUserId, - message, - roomId, - room.getRoomDisplayName(context), - room.isDirect) - notifiableMessageEvent.outGoingMessage = true - VectorApp.getInstance().notificationDrawerManager.onNotifiableEventReceived(notifiableMessageEvent) - VectorApp.getInstance().notificationDrawerManager.refreshNotificationDrawer(null) } override fun onNetworkError(e: Exception) { diff --git a/vector/src/main/java/im/vector/riotredesign/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/riotredesign/features/notifications/NotificationDrawerManager.kt index 3e0875b0..6d5d2942 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/notifications/NotificationDrawerManager.kt @@ -127,8 +127,8 @@ class NotificationDrawerManager(val context: Context, } /** - Should be called when the application is currently opened and showing timeline for the given roomId. - Used to ignore events related to that room (no need to display notification) and clean any existing notification on this room. + * Should be called when the application is currently opened and showing timeline for the given roomId. + * Used to ignore events related to that room (no need to display notification) and clean any existing notification on this room. */ fun setCurrentRoom(roomId: String?) { var hasChanged: Boolean diff --git a/vector/src/main/java/im/vector/riotredesign/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/riotredesign/features/notifications/NotificationUtils.kt index c8d478db..67e30c57 100755 --- a/vector/src/main/java/im/vector/riotredesign/features/notifications/NotificationUtils.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/notifications/NotificationUtils.kt @@ -39,6 +39,8 @@ import im.vector.riotredesign.BuildConfig import im.vector.riotredesign.R import im.vector.riotredesign.core.utils.startNotificationChannelSettingsIntent import im.vector.riotredesign.features.home.HomeActivity +import im.vector.riotredesign.features.home.room.detail.RoomDetailActivity +import im.vector.riotredesign.features.home.room.detail.RoomDetailArgs import im.vector.riotredesign.features.settings.PreferencesManager import timber.log.Timber import java.util.* @@ -545,27 +547,21 @@ object NotificationUtils { } private fun buildOpenRoomIntent(context: Context, roomId: String): PendingIntent? { - // TODO - return null - /* - val roomIntentTap = Intent(context, VectorRoomActivity::class.java) - roomIntentTap.putExtra(VectorRoomActivity.EXTRA_ROOM_ID, roomId) + val roomIntentTap = RoomDetailActivity.newIntent(context, RoomDetailArgs(roomId)) roomIntentTap.action = TAP_TO_VIEW_ACTION //pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that roomIntentTap.data = Uri.parse("foobar://openRoom?$roomId") // Recreate the back stack return TaskStackBuilder.create(context) - .addNextIntentWithParentStack(Intent(context, VectorHomeActivity::class.java)) + .addNextIntentWithParentStack(Intent(context, HomeActivity::class.java)) .addNextIntent(roomIntentTap) .getPendingIntent(System.currentTimeMillis().toInt(), PendingIntent.FLAG_UPDATE_CURRENT) - */ } private fun buildOpenHomePendingIntentForSummary(context: Context): PendingIntent { - val intent = Intent(context, HomeActivity::class.java) + val intent = HomeActivity.newIntent(context, clearNotification = true) intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP - // TODO intent.putExtra(VectorHomeActivity.EXTRA_CLEAR_EXISTING_NOTIFICATION, true) intent.data = Uri.parse("foobar://tapSummary") return PendingIntent.getActivity(context, Random().nextInt(1000), intent, PendingIntent.FLAG_UPDATE_CURRENT) }