Notification: open room and clear drawer - Smart reply - Mark as read - dismiss all

This commit is contained in:
Benoit Marty 2019-06-25 15:39:51 +02:00 committed by Benoit Marty
parent 328f090723
commit 785f33177d
6 changed files with 97 additions and 59 deletions

View File

@ -63,6 +63,8 @@
<activity android:name=".features.home.room.detail.RoomDetailActivity" />
<activity android:name=".features.debug.DebugMenuActivity" />

<!-- Services -->

<service
android:name=".core.services.CallService"
android:exported="false" />
@ -76,6 +78,16 @@

</service>

<!-- Receivers -->

<!-- Exported false, should only be accessible from this app!! -->
<receiver
android:name=".features.notifications.NotificationBroadcastReceiver"
android:enabled="true"
android:exported="false" />

<!-- Providers -->

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider"

View File

@ -37,19 +37,19 @@ import im.vector.riotredesign.core.extensions.replaceFragment
import im.vector.riotredesign.core.platform.OnBackPressed
import im.vector.riotredesign.core.platform.ToolbarConfigurable
import im.vector.riotredesign.core.platform.VectorBaseActivity
import im.vector.riotredesign.core.pushers.PushersManager
import im.vector.riotredesign.features.crypto.keysrequest.KeyRequestHandler
import im.vector.riotredesign.features.crypto.verification.IncomingVerificationRequestHandler
import im.vector.riotredesign.core.pushers.PushersManager
import im.vector.riotredesign.features.notifications.NotificationDrawerManager
import im.vector.riotredesign.features.rageshake.BugReporter
import im.vector.riotredesign.features.rageshake.VectorUncaughtExceptionHandler
import im.vector.riotredesign.features.workers.signout.SignOutUiWorker
import im.vector.riotredesign.features.workers.signout.SignOutViewModel
import im.vector.riotredesign.push.fcm.FcmHelper
import kotlinx.android.synthetic.main.activity_home.*
import org.koin.android.ext.android.inject
import org.koin.android.scope.ext.android.bindScope
import org.koin.android.scope.ext.android.getOrCreateScope
import im.vector.riotredesign.features.workers.signout.SignOutViewModel



class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
@ -64,6 +64,8 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
private val homeNavigator by inject<HomeNavigator>()
private val pushManager by inject<PushersManager>()

private val notificationDrawerManager by inject<NotificationDrawerManager>()

// TODO Move this elsewhere
private val incomingVerificationRequestHandler by inject<IncomingVerificationRequestHandler>()
// 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)
}
}
}

}

View File

@ -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<NotificationDrawerManager>()

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) {

View File

@ -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<Unit>() {
override fun onSuccess(void: Void?) {
// Ignore
}
})
Matrix.getInstance().currentSession?.let { session ->
session.getRoom(roomId)
?.markAllAsRead(object : MatrixCallback<Unit> {})
}
*/
}

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<Void?> {
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) {

View File

@ -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

View File

@ -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)
}