From db88caf7faa3713fbfc7c1f4557954afba79a1c6 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 18 Jul 2019 18:49:28 +0200 Subject: [PATCH 1/8] Better image fullscreen preview animation --- CHANGES.md | 2 +- .../home/room/detail/RoomDetailFragment.kt | 13 +- .../timeline/item/MessageImageVideoItem.kt | 2 + .../features/media/ImageContentRenderer.kt | 47 +++++++ .../media/ImageMediaViewerActivity.kt | 127 +++++++++++++++++- .../layout/activity_image_media_viewer.xml | 39 ++++-- .../transition/image_preview_transition.xml | 15 +++ .../src/main/res/values-v21/theme_black.xml | 5 + vector/src/main/res/values-v21/theme_dark.xml | 5 + .../src/main/res/values-v21/theme_light.xml | 4 + 10 files changed, 242 insertions(+), 17 deletions(-) create mode 100644 vector/src/main/res/transition/image_preview_transition.xml diff --git a/CHANGES.md b/CHANGES.md index ff2c81e18e..d0eb96d45d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ Features: - Improvements: - - + - UX image preview screen transition (#393) Other changes: - diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index b7491ae6b2..b260979fab 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -22,6 +22,7 @@ import android.content.Context import android.content.Intent import android.graphics.drawable.ColorDrawable import android.net.Uri +import android.os.Build import android.os.Bundle import android.os.Parcelable import android.text.Editable @@ -35,7 +36,9 @@ import android.widget.TextView import android.widget.Toast import androidx.annotation.DrawableRes import androidx.appcompat.app.AlertDialog +import androidx.core.app.ActivityOptionsCompat import androidx.core.content.ContextCompat +import androidx.core.view.ViewCompat import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager @@ -618,8 +621,14 @@ class RoomDetailFragment : override fun onImageMessageClicked(messageImageContent: MessageImageContent, mediaData: ImageContentRenderer.Data, view: View) { // TODO Use navigator - val intent = ImageMediaViewerActivity.newIntent(vectorBaseActivity, mediaData) - startActivity(intent) + + val intent = ImageMediaViewerActivity.newIntent(vectorBaseActivity, mediaData, ViewCompat.getTransitionName(view)) + var bundle: Bundle? = null + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(requireActivity(), view, ViewCompat.getTransitionName(view) + ?: "").toBundle() + } + startActivity(intent, bundle) } override fun onVideoMessageClicked(messageVideoContent: MessageVideoContent, mediaData: VideoContentRenderer.Data, view: View) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageImageVideoItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageImageVideoItem.kt index d551e44c23..6a68557f86 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageImageVideoItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageImageVideoItem.kt @@ -19,6 +19,7 @@ package im.vector.riotx.features.home.room.detail.timeline.item import android.view.View import android.view.ViewGroup import android.widget.ImageView +import androidx.core.view.ViewCompat import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R @@ -45,6 +46,7 @@ abstract class MessageImageVideoItem : AbsMessageItem Unit)? = null) { + val (width, height) = processSize(data, mode) + + val glideRequest = if (data.elementToDecrypt != null) { + // Encrypted image + GlideApp + .with(imageView) + .load(data) + } else { + // Clear image + val contentUrlResolver = activeSessionHolder.getActiveSession().contentUrlResolver() + val resolvedUrl = when (mode) { + Mode.FULL_SIZE -> contentUrlResolver.resolveFullSize(data.url) + Mode.THUMBNAIL -> contentUrlResolver.resolveThumbnail(data.url, width, height, ContentUrlResolver.ThumbnailMethod.SCALE) + } + //Fallback to base url + ?: data.url + + GlideApp + .with(imageView) + .load(resolvedUrl) + } + + glideRequest + .listener(object: RequestListener { + override fun onLoadFailed(e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean): Boolean { + callback?.invoke(false) + return false + } + + override fun onResourceReady(resource: Drawable?, model: Any?, target: Target?, dataSource: DataSource?, isFirstResource: Boolean): Boolean { + callback?.invoke(true) + return false + } + + }) + .fitCenter() + .into(imageView) + } fun render(data: Data, imageView: BigImageView) { diff --git a/vector/src/main/java/im/vector/riotx/features/media/ImageMediaViewerActivity.kt b/vector/src/main/java/im/vector/riotx/features/media/ImageMediaViewerActivity.kt index bd3f4480f2..73968a7627 100644 --- a/vector/src/main/java/im/vector/riotx/features/media/ImageMediaViewerActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/media/ImageMediaViewerActivity.kt @@ -18,15 +18,30 @@ package im.vector.riotx.features.media import android.content.Context import android.content.Intent +import android.graphics.drawable.Drawable +import android.os.Build import android.os.Bundle +import android.os.Handler +import android.view.View +import android.view.ViewTreeObserver +import androidx.annotation.RequiresApi import androidx.appcompat.widget.Toolbar +import androidx.core.transition.addListener +import androidx.core.view.ViewCompat +import androidx.core.view.isInvisible import androidx.core.view.isVisible +import androidx.transition.Transition +import com.bumptech.glide.load.DataSource +import com.bumptech.glide.load.engine.GlideException +import com.bumptech.glide.request.RequestListener +import com.bumptech.glide.request.target.Target import com.github.piasy.biv.indicator.progresspie.ProgressPieIndicator import com.github.piasy.biv.view.GlideImageViewFactory import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.glide.GlideApp import im.vector.riotx.core.platform.VectorBaseActivity import kotlinx.android.synthetic.main.activity_image_media_viewer.* +import timber.log.Timber import javax.inject.Inject @@ -34,6 +49,10 @@ class ImageMediaViewerActivity : VectorBaseActivity() { @Inject lateinit var imageContentRenderer: ImageContentRenderer + private val mHideHandler = Handler() + + lateinit var mediaData: ImageContentRenderer.Data + override fun injectWith(injector: ScreenComponent) { injector.inject(this) } @@ -41,11 +60,29 @@ class ImageMediaViewerActivity : VectorBaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(im.vector.riotx.R.layout.activity_image_media_viewer) - val mediaData = intent.getParcelableExtra(EXTRA_MEDIA_DATA) + mediaData = intent.getParcelableExtra(EXTRA_MEDIA_DATA) + intent.extras.getString(EXTRA_SHARED_TRANSITION_NAME)?.let { + ViewCompat.setTransitionName(imageTransitionView, it) + } if (mediaData.url.isNullOrEmpty()) { finish() + return + } + + configureToolbar(imageMediaViewerToolbar, mediaData) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && addTransitionListener()) { + // Encrypted image + imageTransitionView.isVisible = true + imageMediaViewerImageView.isVisible = false + encryptedImageView.isVisible = false + supportPostponeEnterTransition() + imageContentRenderer.renderFitTarget(mediaData, ImageContentRenderer.Mode.THUMBNAIL, imageTransitionView) { + scheduleStartPostponedTransition(imageTransitionView) + } + } else { - configureToolbar(imageMediaViewerToolbar, mediaData) + imageTransitionView.isVisible = false if (mediaData.elementToDecrypt != null) { // Encrypted image @@ -78,13 +115,97 @@ class ImageMediaViewerActivity : VectorBaseActivity() { } } + override fun onBackPressed() { + //show again for exit animation + imageTransitionView.isVisible = true + super.onBackPressed() + } + + private fun scheduleStartPostponedTransition(sharedElement: View) { + sharedElement.viewTreeObserver.addOnPreDrawListener( + object : ViewTreeObserver.OnPreDrawListener { + override fun onPreDraw(): Boolean { + sharedElement.viewTreeObserver.removeOnPreDrawListener(this) + supportStartPostponedEnterTransition() + return true + } + }) + + //Any how hide the transition image view after a delay + mHideHandler.postDelayed({ imageTransitionView.isInvisible = true }, 600) + } + + /** + * Try and add a [Transition.TransitionListener] to the entering shared element + * [Transition]. We do this so that we can load the full-size image after the transition + * has completed. + * + * @return true if we were successful in adding a listener to the enter transition + */ + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + private fun addTransitionListener(): Boolean { + val transition = window.sharedElementEnterTransition + + if (transition != null) { + // There is an entering shared element transition so add a listener to it + transition.addListener( + onEnd = { + if (mediaData.elementToDecrypt != null) { + // Encrypted image + GlideApp + .with(this) + .load(mediaData) + .dontAnimate() + .listener(object : RequestListener { + override fun onLoadFailed(e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean): Boolean { + //TODO ? + Timber.e("TRANSITION onLoadFailed") + imageMediaViewerImageView.isVisible = false + encryptedImageView.isVisible = true + return false + } + + override fun onResourceReady(resource: Drawable?, model: Any?, target: Target?, dataSource: DataSource?, isFirstResource: Boolean): Boolean { + Timber.e("TRANSITION onResourceReady") + imageTransitionView.isInvisible = true + imageMediaViewerImageView.isVisible = false + encryptedImageView.isVisible = true + return false + } + + }) + .into(encryptedImageView) + } else { + imageTransitionView.isInvisible = true + // Clear image + imageMediaViewerImageView.isVisible = true + encryptedImageView.isVisible = false + + imageMediaViewerImageView.setImageViewFactory(GlideImageViewFactory()) + imageMediaViewerImageView.setProgressIndicator(ProgressPieIndicator()) + imageContentRenderer.render(mediaData, imageMediaViewerImageView) + } + }, + onCancel = { + //Something to do? + } + ) + return true + } + + // If we reach here then we have not added a listener + return false + } + companion object { private const val EXTRA_MEDIA_DATA = "EXTRA_MEDIA_DATA" + private const val EXTRA_SHARED_TRANSITION_NAME = "EXTRA_SHARED_TRANSITION_NAME" - fun newIntent(context: Context, mediaData: ImageContentRenderer.Data): Intent { + fun newIntent(context: Context, mediaData: ImageContentRenderer.Data, shareTransitionName: String?): Intent { return Intent(context, ImageMediaViewerActivity::class.java).apply { putExtra(EXTRA_MEDIA_DATA, mediaData) + shareTransitionName?.let { putExtra(EXTRA_SHARED_TRANSITION_NAME, it) } } } } diff --git a/vector/src/main/res/layout/activity_image_media_viewer.xml b/vector/src/main/res/layout/activity_image_media_viewer.xml index 61d5d286f9..f1d557492f 100644 --- a/vector/src/main/res/layout/activity_image_media_viewer.xml +++ b/vector/src/main/res/layout/activity_image_media_viewer.xml @@ -12,18 +12,35 @@ android:layout_height="?attr/actionBarSize" android:elevation="4dp" /> - - + android:layout_height="match_parent"> + + + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/transition/image_preview_transition.xml b/vector/src/main/res/transition/image_preview_transition.xml new file mode 100644 index 0000000000..3674324c4e --- /dev/null +++ b/vector/src/main/res/transition/image_preview_transition.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/vector/src/main/res/values-v21/theme_black.xml b/vector/src/main/res/values-v21/theme_black.xml index 5ab2ed8901..74ec2cd9e2 100644 --- a/vector/src/main/res/values-v21/theme_black.xml +++ b/vector/src/main/res/values-v21/theme_black.xml @@ -7,6 +7,11 @@ true + + + @transition/image_preview_transition + @transition/image_preview_transition + + + From 10490e3aa629d86b4c425c05eaf861882de5c83e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 19 Jul 2019 16:00:06 +0200 Subject: [PATCH 5/8] Close detail room screen when the room is left with another client (#256) --- CHANGES.md | 1 + .../features/home/room/detail/RoomDetailFragment.kt | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index cc5689d4a6..50cbb3e15c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Other changes: Bugfix: - Edited message: link confusion when (edited) appears in body (#398) + - Close detail room screen when the room is left with another client (#256) Translations: - diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index b7491ae6b2..1ff2c67dc1 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -536,9 +536,14 @@ class RoomDetailFragment : private fun renderRoomSummary(state: RoomDetailViewState) { state.asyncRoomSummary()?.let { - roomToolbarTitleView.text = it.displayName - avatarRenderer.render(it, roomToolbarAvatarImageView) - roomToolbarSubtitleView.setTextOrHide(it.topic) + if (it.membership.isLeft()) { + Timber.w("The room has been left") + activity?.finish() + } else { + roomToolbarTitleView.text = it.displayName + avatarRenderer.render(it, roomToolbarAvatarImageView) + roomToolbarSubtitleView.setTextOrHide(it.topic) + } } } From 1a4ec34bb284db2d4bb7bf32e1862690b2118f5b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 19 Jul 2019 16:03:37 +0200 Subject: [PATCH 6/8] Code cleanup --- .../settings/VectorSettingsActivity.kt | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt index 5db218c3e4..fcf7efa426 100755 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt @@ -17,7 +17,6 @@ package im.vector.riotx.features.settings import android.content.Context import android.content.Intent -import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat @@ -75,32 +74,30 @@ class VectorSettingsActivity : VectorBaseActivity(), } } - override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat?, pref: Preference?): Boolean { - var oFragment: Fragment? = null - - if (VectorPreferences.SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY == pref?.key) { - oFragment = VectorSettingsNotificationsTroubleshootFragment.newInstance(session.myUserId) - } else if (VectorPreferences.SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY == pref?.key) { - oFragment = VectorSettingsAdvancedNotificationPreferenceFragment.newInstance(session.myUserId) - } else { - try { - pref?.fragment?.let { - oFragment = supportFragmentManager.fragmentFactory - .instantiate(classLoader, it) + override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean { + val oFragment = when { + VectorPreferences.SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY == pref.key -> + VectorSettingsNotificationsTroubleshootFragment.newInstance(session.myUserId) + VectorPreferences.SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY == pref.key -> + VectorSettingsAdvancedNotificationPreferenceFragment.newInstance(session.myUserId) + else -> + try { + pref.fragment?.let { + supportFragmentManager.fragmentFactory.instantiate(classLoader, it) + } + } catch (e: Throwable) { + showSnackbar(getString(R.string.not_implemented)) + Timber.e(e) + null } - } catch (e: Throwable) { - showSnackbar(getString(R.string.not_implemented)) - Timber.e(e) - } } if (oFragment != null) { - oFragment!!.setTargetFragment(caller, 0) + oFragment.setTargetFragment(caller, 0) // Replace the existing Fragment with the new Fragment supportFragmentManager.beginTransaction() - .setCustomAnimations(R.anim.right_in, R.anim.fade_out, - R.anim.fade_in, R.anim.right_out) - .replace(R.id.vector_settings_page, oFragment!!, pref?.title.toString()) + .setCustomAnimations(R.anim.right_in, R.anim.fade_out, R.anim.fade_in, R.anim.right_out) + .replace(R.id.vector_settings_page, oFragment, pref.title.toString()) .addToBackStack(null) .commit() return true From 4a2bf0d6c625269c72f6fcac47e7173f166b40b3 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 19 Jul 2019 16:18:47 +0200 Subject: [PATCH 7/8] Cleaning Lint --- .../riotx/features/media/ImageContentRenderer.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/media/ImageContentRenderer.kt b/vector/src/main/java/im/vector/riotx/features/media/ImageContentRenderer.kt index ddd2356497..4ae9f47358 100644 --- a/vector/src/main/java/im/vector/riotx/features/media/ImageContentRenderer.kt +++ b/vector/src/main/java/im/vector/riotx/features/media/ImageContentRenderer.kt @@ -120,12 +120,19 @@ class ImageContentRenderer @Inject constructor(private val activeSessionHolder: glideRequest .listener(object: RequestListener { - override fun onLoadFailed(e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean): Boolean { + override fun onLoadFailed(e: GlideException?, + model: Any?, + target: Target?, + isFirstResource: Boolean): Boolean { callback?.invoke(false) return false } - override fun onResourceReady(resource: Drawable?, model: Any?, target: Target?, dataSource: DataSource?, isFirstResource: Boolean): Boolean { + override fun onResourceReady(resource: Drawable?, + model: Any?, + target: Target?, + dataSource: DataSource?, + isFirstResource: Boolean): Boolean { callback?.invoke(true) return false } From 6d01a570fdcec11387614bb02612c81a4f149a7c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 19 Jul 2019 16:44:30 +0200 Subject: [PATCH 8/8] Clear notification for a room left on another client --- CHANGES.md | 1 + .../android/api/pushrules/PushRuleService.kt | 1 + .../session/notification/DefaultPushRuleService.kt | 14 +++++++++++--- .../notification/ProcessEventForPushTask.kt | 4 ++++ .../notifications/PushRuleTriggerListener.kt | 4 ++++ 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 50cbb3e15c..1ba5b11ebd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ Other changes: Bugfix: - Edited message: link confusion when (edited) appears in body (#398) - Close detail room screen when the room is left with another client (#256) + - Clear notification for a room left on another client Translations: - diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/PushRuleService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/PushRuleService.kt index b00450b561..1fc37cd467 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/PushRuleService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/PushRuleService.kt @@ -41,6 +41,7 @@ interface PushRuleService { interface PushRuleListener { fun onMatchRule(event: Event, actions: List) + fun onRoomLeft(roomId: String) fun batchFinish() } } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/DefaultPushRuleService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/DefaultPushRuleService.kt index 5b21f0e562..7397f0eefb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/DefaultPushRuleService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/DefaultPushRuleService.kt @@ -20,12 +20,10 @@ import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.auth.data.SessionParams import im.vector.matrix.android.api.pushrules.Action import im.vector.matrix.android.api.pushrules.PushRuleService -import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse import im.vector.matrix.android.api.pushrules.rest.PushRule import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.internal.database.mapper.PushRulesMapper import im.vector.matrix.android.internal.database.model.PushRulesEntity -import im.vector.matrix.android.internal.database.model.PusherEntityFields import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.session.pushers.GetPushRulesTask @@ -122,13 +120,23 @@ internal class DefaultPushRuleService @Inject constructor( } } + fun dispatchRoomLeft(roomid: String) { + try { + listeners.forEach { + it.onRoomLeft(roomid) + } + } catch (e: Throwable) { + Timber.e(e, "Error while dispatching room left") + } + } + fun dispatchFinish() { try { listeners.forEach { it.batchFinish() } } catch (e: Throwable) { - + Timber.e(e, "Error while dispatching finish") } } } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/ProcessEventForPushTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/ProcessEventForPushTask.kt index fc6c88384b..d196e563fe 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/ProcessEventForPushTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/ProcessEventForPushTask.kt @@ -44,6 +44,10 @@ internal class DefaultProcessEventForPushTask @Inject constructor( override suspend fun execute(params: ProcessEventForPushTask.Params): Try { return Try { + // Handle left rooms + params.syncResponse.leave.keys.forEach { + defaultPushRuleService.dispatchRoomLeft(it) + } val newJoinEvents = params.syncResponse.join .map { entries -> entries.value.timeline?.events?.map { it.copy(roomId = entries.key) } diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/PushRuleTriggerListener.kt b/vector/src/main/java/im/vector/riotx/features/notifications/PushRuleTriggerListener.kt index 760128dee1..d404b64c1e 100644 --- a/vector/src/main/java/im/vector/riotx/features/notifications/PushRuleTriggerListener.kt +++ b/vector/src/main/java/im/vector/riotx/features/notifications/PushRuleTriggerListener.kt @@ -56,6 +56,10 @@ class PushRuleTriggerListener @Inject constructor( } } + override fun onRoomLeft(roomId: String) { + notificationDrawerManager.clearMessageEventOfRoom(roomId) + } + override fun batchFinish() { notificationDrawerManager.refreshNotificationDrawer() }