Fix issues on Notification Event resolver
This commit is contained in:
parent
6743dc6273
commit
4e6b34b9d1
|
@ -23,7 +23,7 @@ import io.reactivex.Observable
|
|||
class RxRoom(private val room: Room) {
|
||||
|
||||
fun liveRoomSummary(): Observable<RoomSummary> {
|
||||
return room.roomSummary.asObservable()
|
||||
return room.liveRoomSummary.asObservable()
|
||||
}
|
||||
|
||||
fun liveRoomMemberIds(): Observable<List<String>> {
|
||||
|
|
|
@ -47,6 +47,8 @@ interface Room :
|
|||
* A live [RoomSummary] associated with the room
|
||||
* You can observe this summary to get dynamic data from this room.
|
||||
*/
|
||||
val roomSummary: LiveData<RoomSummary>
|
||||
val liveRoomSummary: LiveData<RoomSummary>
|
||||
|
||||
val roomSummary: RoomSummary?
|
||||
|
||||
}
|
|
@ -39,4 +39,6 @@ data class CallInviteContent(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fun isVideo(): Boolean = offer.sdp.contains(Offer.SDP_VIDEO)
|
||||
}
|
|
@ -52,7 +52,7 @@ internal class DefaultRoom(
|
|||
RelationService by relationService,
|
||||
MembershipService by roomMembersService {
|
||||
|
||||
override val roomSummary: LiveData<RoomSummary> by lazy {
|
||||
override val liveRoomSummary: LiveData<RoomSummary> by lazy {
|
||||
val liveRealmData = RealmLiveData<RoomSummaryEntity>(monarchy.realmConfiguration) { realm ->
|
||||
RoomSummaryEntity.where(realm, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME)
|
||||
}
|
||||
|
@ -68,6 +68,15 @@ internal class DefaultRoom(
|
|||
}
|
||||
}
|
||||
|
||||
override val roomSummary: RoomSummary?
|
||||
get() {
|
||||
var sum: RoomSummaryEntity? = null
|
||||
monarchy.runTransactionSync {
|
||||
sum = RoomSummaryEntity.where(it, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME).findFirst()
|
||||
}
|
||||
return sum?.asDomain()
|
||||
}
|
||||
|
||||
override fun isEncrypted(): Boolean {
|
||||
return cryptoService.isRoomEncrypted(roomId)
|
||||
}
|
||||
|
|
|
@ -175,7 +175,10 @@ class PushrulesConditionTest {
|
|||
return _numberOfJoinedMembers
|
||||
}
|
||||
|
||||
override val roomSummary: LiveData<RoomSummary>
|
||||
override val liveRoomSummary: LiveData<RoomSummary>
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
|
||||
override val roomSummary: RoomSummary?
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
|
||||
override fun createTimeline(eventId: String?, allowedTypes: List<String>?): Timeline {
|
||||
|
|
|
@ -49,10 +49,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
private val notificationDrawerManager by inject<NotificationDrawerManager>()
|
||||
private val pusherManager by inject<PushersManager>()
|
||||
|
||||
private val notifiableEventResolver by lazy {
|
||||
NotifiableEventResolver(this)
|
||||
}
|
||||
|
||||
private val notifiableEventResolver by inject<NotifiableEventResolver>()
|
||||
// UI handler
|
||||
private val mUIHandler by lazy {
|
||||
Handler(Looper.getMainLooper())
|
||||
|
@ -69,8 +66,8 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
return
|
||||
}
|
||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
||||
Timber.i("## onMessageReceived()" + message.data.toString())
|
||||
Timber.i("## onMessageReceived() from FCM with priority " + message.priority)
|
||||
Timber.i("## onMessageReceived() %s", message.data.toString())
|
||||
Timber.i("## onMessageReceived() from FCM with priority %s", message.priority)
|
||||
}
|
||||
mUIHandler.post {
|
||||
if (ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
|
||||
|
@ -168,7 +165,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
val room = session.getRoom(roomId) ?: return false
|
||||
return room.getTimeLineEvent(eventId) != null
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "## isEventAlreadyKnown() : failed to check if the event was already defined " + e.message)
|
||||
Timber.e(e, "## isEventAlreadyKnown() : failed to check if the event was already defined")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -209,44 +206,39 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
return
|
||||
} else {
|
||||
|
||||
val event = parseEvent(data)
|
||||
if (event?.roomId == null) {
|
||||
//unsupported event
|
||||
Timber.e("Received an event with no room id")
|
||||
return
|
||||
val event = parseEvent(data) ?: return
|
||||
|
||||
val notifiableEvent = notifiableEventResolver.resolveEvent(event, session)
|
||||
|
||||
if (notifiableEvent == null) {
|
||||
Timber.e("Unsupported notifiable event ${eventId}")
|
||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
||||
Timber.e("--> ${event}")
|
||||
}
|
||||
} else {
|
||||
|
||||
var notifiableEvent = notifiableEventResolver.resolveEvent(event, session)
|
||||
|
||||
if (notifiableEvent == null) {
|
||||
Timber.e("Unsupported notifiable event ${eventId}")
|
||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
||||
Timber.e("--> ${event}")
|
||||
if (notifiableEvent is NotifiableMessageEvent) {
|
||||
if (TextUtils.isEmpty(notifiableEvent.senderName)) {
|
||||
notifiableEvent.senderName = data["sender_display_name"]
|
||||
?: data["sender"] ?: ""
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
if (notifiableEvent is NotifiableMessageEvent) {
|
||||
if (TextUtils.isEmpty(notifiableEvent.senderName)) {
|
||||
notifiableEvent.senderName = data["sender_display_name"]
|
||||
?: data["sender"] ?: ""
|
||||
}
|
||||
if (TextUtils.isEmpty(notifiableEvent.roomName)) {
|
||||
notifiableEvent.roomName = findRoomNameBestEffort(data, session) ?: ""
|
||||
}
|
||||
if (TextUtils.isEmpty(notifiableEvent.roomName)) {
|
||||
notifiableEvent.roomName = findRoomNameBestEffort(data, session) ?: ""
|
||||
}
|
||||
|
||||
notifiableEvent.isPushGatewayEvent = true
|
||||
notifiableEvent.matrixID = session.sessionParams.credentials.userId
|
||||
notificationDrawerManager.onNotifiableEventReceived(notifiableEvent)
|
||||
notificationDrawerManager.refreshNotificationDrawer()
|
||||
}
|
||||
|
||||
notifiableEvent.isPushGatewayEvent = true
|
||||
notifiableEvent.matrixID = session.sessionParams.credentials.userId
|
||||
notificationDrawerManager.onNotifiableEventReceived(notifiableEvent)
|
||||
notificationDrawerManager.refreshNotificationDrawer()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun findRoomNameBestEffort(data: Map<String, String>, session: Session?): String? {
|
||||
var roomName: String? = data["room_name"]
|
||||
val roomName: String? = data["room_name"]
|
||||
val roomId = data["room_id"]
|
||||
if (null == roomName && null != roomId) {
|
||||
// Try to get the room name from our store
|
||||
|
@ -281,7 +273,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
// TODO content = data.getValue("content"),
|
||||
originServerTs = System.currentTimeMillis())
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "buildEvent fails " + e.localizedMessage)
|
||||
Timber.e(e, "buildEvent fails ")
|
||||
}
|
||||
|
||||
return null
|
||||
|
|
|
@ -90,7 +90,7 @@ class AppModule(private val context: Context) {
|
|||
}
|
||||
|
||||
single {
|
||||
OutdatedEventDetector(context)
|
||||
OutdatedEventDetector()
|
||||
}
|
||||
|
||||
single {
|
||||
|
@ -98,7 +98,7 @@ class AppModule(private val context: Context) {
|
|||
}
|
||||
|
||||
single {
|
||||
NotifiableEventResolver(context)
|
||||
NotifiableEventResolver(get(), get())
|
||||
}
|
||||
|
||||
factory {
|
||||
|
|
|
@ -46,6 +46,22 @@ class NoticeEventFormatter(private val stringProvider: StringProvider) {
|
|||
}
|
||||
}
|
||||
|
||||
fun format(event: Event, senderName: String?): CharSequence? {
|
||||
return when (val type = event.getClearType()) {
|
||||
EventType.STATE_ROOM_NAME -> formatRoomNameEvent(event, senderName)
|
||||
EventType.STATE_ROOM_TOPIC -> formatRoomTopicEvent(event, senderName)
|
||||
EventType.STATE_ROOM_MEMBER -> formatRoomMemberEvent(event, senderName)
|
||||
EventType.STATE_HISTORY_VISIBILITY -> formatRoomHistoryVisibilityEvent(event, senderName)
|
||||
EventType.CALL_INVITE,
|
||||
EventType.CALL_HANGUP,
|
||||
EventType.CALL_ANSWER -> formatCallEvent(event, senderName)
|
||||
else -> {
|
||||
Timber.v("Type $type not handled by this formatter")
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatRoomNameEvent(event: Event, senderName: String?): CharSequence? {
|
||||
val content = event.getClearContent().toModel<RoomNameContent>() ?: return null
|
||||
return if (!TextUtils.isEmpty(content.name)) {
|
||||
|
|
|
@ -15,16 +15,19 @@
|
|||
*/
|
||||
package im.vector.riotredesign.features.notifications
|
||||
|
||||
import android.content.Context
|
||||
import im.vector.matrix.android.api.pushrules.rest.PushRule
|
||||
import androidx.core.app.NotificationCompat
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toContent
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.riotredesign.BuildConfig
|
||||
import im.vector.riotredesign.R
|
||||
import im.vector.riotredesign.core.preference.BingRule
|
||||
import im.vector.riotredesign.core.resources.StringProvider
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
|
||||
import timber.log.Timber
|
||||
|
||||
// TODO Remove
|
||||
|
@ -39,46 +42,44 @@ class RoomState {
|
|||
* The NotifiableEventResolver is the only aware of session/store, the NotificationDrawerManager has no knowledge of that,
|
||||
* this pattern allow decoupling between the object responsible of displaying notifications and the matrix sdk.
|
||||
*/
|
||||
class NotifiableEventResolver(val context: Context) {
|
||||
class NotifiableEventResolver(val stringProvider: StringProvider,
|
||||
val noticeEventFormatter: NoticeEventFormatter) {
|
||||
|
||||
//private val eventDisplay = RiotEventDisplay(context)
|
||||
|
||||
fun resolveEvent(event: Event/*, roomState: RoomState?, bingRule: PushRule?*/, session: Session): NotifiableEvent? {
|
||||
|
||||
|
||||
// val store = session.dataHandler.store
|
||||
// if (store == null) {
|
||||
// Log.e("## NotifiableEventResolver, unable to get store")
|
||||
// //TODO notify somehow that something did fail?
|
||||
// return null
|
||||
// }
|
||||
val roomID = event.roomId ?: return null
|
||||
val eventId = event.eventId ?: return null
|
||||
val timelineEvent = session.getRoom(roomID)?.getTimeLineEvent(eventId) ?: return null
|
||||
|
||||
when (event.getClearType()) {
|
||||
EventType.MESSAGE -> {
|
||||
return resolveMessageEvent(event, session)
|
||||
return resolveMessageEvent(timelineEvent, session)
|
||||
}
|
||||
// EventType.ENCRYPTED -> {
|
||||
// val messageEvent = resolveMessageEvent(event, bingRule, session, store)
|
||||
// messageEvent?.lockScreenVisibility = NotificationCompat.VISIBILITY_PRIVATE
|
||||
// return messageEvent
|
||||
// }
|
||||
// EventType.STATE_ROOM_MEMBER -> {
|
||||
// return resolveStateRoomEvent(event, bingRule, session, store)
|
||||
// }
|
||||
else -> {
|
||||
EventType.ENCRYPTED -> {
|
||||
val messageEvent = resolveMessageEvent(timelineEvent, session)
|
||||
messageEvent?.lockScreenVisibility = NotificationCompat.VISIBILITY_PRIVATE
|
||||
return messageEvent
|
||||
}
|
||||
EventType.STATE_ROOM_MEMBER -> {
|
||||
return resolveStateRoomEvent(event, session)
|
||||
}
|
||||
else -> {
|
||||
|
||||
//If the event can be displayed, display it as is
|
||||
// eventDisplay.getTextualDisplay(event, roomState)?.toString()?.let { body ->
|
||||
// return SimpleNotifiableEvent(
|
||||
// session.myUserId,
|
||||
// eventId = event.eventId,
|
||||
// noisy = bingRule?.notificationSound != null,
|
||||
// timestamp = event.originServerTs,
|
||||
// description = body,
|
||||
// soundName = bingRule?.notificationSound,
|
||||
// title = context.getString(R.string.notification_unknown_new_event),
|
||||
// type = event.type)
|
||||
// }
|
||||
//TODO Better event text display
|
||||
val bodyPreview = event.type
|
||||
|
||||
return SimpleNotifiableEvent(
|
||||
session.sessionParams.credentials.userId,
|
||||
eventId = event.eventId!!,
|
||||
noisy = false,//will be updated
|
||||
timestamp = event.originServerTs ?: System.currentTimeMillis(),
|
||||
description = bodyPreview,
|
||||
title = stringProvider.getString(R.string.notification_unknown_new_event),
|
||||
soundName = null,
|
||||
type = event.type)
|
||||
|
||||
|
||||
//Unsupported event
|
||||
Timber.w("NotifiableEventResolver Received an unsupported event matching a bing rule")
|
||||
|
@ -88,57 +89,55 @@ class NotifiableEventResolver(val context: Context) {
|
|||
}
|
||||
|
||||
|
||||
private fun resolveMessageEvent(event: Event, session: Session): NotifiableEvent? {
|
||||
//If we are here, that means that the event should be notified to the user, we check now how it should be presented (sound)
|
||||
// val soundName = pushRule?.notificationSound
|
||||
private fun resolveMessageEvent(event: TimelineEvent, session: Session): NotifiableEvent? {
|
||||
|
||||
//The event only contains an eventId, and roomId (type is m.room.*) , we need to get the displayable content (names, avatar, text, etc...)
|
||||
val room = session.getRoom(event.roomId!! /*roomID cannot be null (see Matrix SDK code)*/)
|
||||
val room = session.getRoom(event.root.roomId!! /*roomID cannot be null*/)
|
||||
|
||||
|
||||
if (room == null) {
|
||||
Timber.e("## Unable to resolve room for eventId [${event.eventId}] and roomID [${event.roomId}]")
|
||||
Timber.e("## Unable to resolve room for eventId [${event}]")
|
||||
// Ok room is not known in store, but we can still display something
|
||||
val body = event.content?.toModel<MessageContent>()?.body
|
||||
?: context.getString(R.string.notification_unknown_new_event)
|
||||
val roomName = context.getString(R.string.notification_unknown_room_name)
|
||||
val senderDisplayName = event.senderId ?: ""
|
||||
val body =
|
||||
event.annotations?.editSummary?.aggregatedContent?.toModel<MessageContent>()?.body
|
||||
?: event.root.getClearContent().toModel<MessageContent>()?.body
|
||||
?: stringProvider.getString(R.string.notification_unknown_new_event)
|
||||
val roomName = stringProvider.getString(R.string.notification_unknown_room_name)
|
||||
val senderDisplayName = event.senderName
|
||||
|
||||
val notifiableEvent = NotifiableMessageEvent(
|
||||
eventId = event.eventId ?: "",
|
||||
timestamp = event.originServerTs ?: 0,
|
||||
eventId = event.root.eventId!!,
|
||||
timestamp = event.root.originServerTs ?: 0,
|
||||
noisy = false,//will be updated
|
||||
senderName = senderDisplayName,
|
||||
senderId = event.senderId,
|
||||
senderId = event.root.senderId,
|
||||
body = body,
|
||||
roomId = event.roomId ?: "",
|
||||
roomId = event.root.roomId!!,
|
||||
roomName = roomName)
|
||||
|
||||
notifiableEvent.matrixID = session.sessionParams.credentials.userId
|
||||
// notifiableEvent.soundName = soundName
|
||||
|
||||
return notifiableEvent
|
||||
} else {
|
||||
val tEvent = room.getTimeLineEvent(event.eventId!!)
|
||||
val body = event.content?.toModel<MessageContent>()?.body
|
||||
?: context.getString(R.string.notification_unknown_new_event)
|
||||
val roomName = event.roomId ?: "room"
|
||||
val senderDisplayName = tEvent?.senderName ?: "?"
|
||||
val body = event.root.getClearContent().toModel<MessageContent>()?.body
|
||||
?: stringProvider.getString(R.string.notification_unknown_new_event)
|
||||
val roomName = room.roomSummary?.displayName ?: ""
|
||||
val senderDisplayName = event.senderName ?: ""
|
||||
|
||||
val notifiableEvent = NotifiableMessageEvent(
|
||||
eventId = event.eventId!!,
|
||||
timestamp = event.originServerTs ?: 0,
|
||||
eventId = event.root.eventId!!,
|
||||
timestamp = event.root.originServerTs ?: 0,
|
||||
noisy = false,//will be updated
|
||||
senderName = senderDisplayName,
|
||||
senderId = event.senderId,
|
||||
senderId = event.root.senderId,
|
||||
body = body,
|
||||
roomId = event.roomId ?: "00",
|
||||
roomId = event.root.roomId!!,
|
||||
roomName = roomName,
|
||||
roomIsDirect = true)
|
||||
roomIsDirect = room.roomSummary?.isDirect ?: false)
|
||||
|
||||
notifiableEvent.matrixID = session.sessionParams.credentials.userId
|
||||
notifiableEvent.soundName = null
|
||||
|
||||
//TODO get the avatar?
|
||||
|
||||
// val roomAvatarPath = session.mediaCache?.thumbnailCacheFile(room.avatarUrl, 50)
|
||||
// if (roomAvatarPath != null) {
|
||||
|
@ -162,21 +161,24 @@ class NotifiableEventResolver(val context: Context) {
|
|||
return notifiableEvent
|
||||
}
|
||||
}
|
||||
/*
|
||||
private fun resolveStateRoomEvent(event: Event, bingRule: BingRule?, session: MXSession, store: IMXStore): NotifiableEvent? {
|
||||
if (RoomMember.MEMBERSHIP_INVITE == event.contentAsJsonObject?.getAsJsonPrimitive("membership")?.asString) {
|
||||
val room = store.getRoom(event.roomId /*roomID cannot be null (see Matrix SDK code)*/)
|
||||
val body = eventDisplay.getTextualDisplay(event, room.state)?.toString()
|
||||
?: context.getString(R.string.notification_new_invitation)
|
||||
|
||||
|
||||
private fun resolveStateRoomEvent(event: Event, session: Session): NotifiableEvent? {
|
||||
val content = event.content?.toModel<RoomMember>() ?: return null
|
||||
val roomId = event.roomId ?: return null
|
||||
val dName = event.senderId?.let { session.getUser(it)?.displayName }
|
||||
if (Membership.INVITE == content.membership) {
|
||||
val body = noticeEventFormatter.format(event, dName)
|
||||
?: stringProvider.getString(R.string.notification_new_invitation)
|
||||
return InviteNotifiableEvent(
|
||||
session.myUserId,
|
||||
eventId = event.eventId,
|
||||
roomId = event.roomId,
|
||||
timestamp = event.originServerTs,
|
||||
noisy = bingRule?.notificationSound != null,
|
||||
title = context.getString(R.string.notification_new_invitation),
|
||||
description = body,
|
||||
soundName = bingRule?.notificationSound,
|
||||
session.sessionParams.credentials.userId,
|
||||
eventId = event.eventId!!,
|
||||
roomId = roomId,
|
||||
timestamp = event.originServerTs ?: 0,
|
||||
noisy = false,//will be set later
|
||||
title = stringProvider.getString(R.string.notification_new_invitation),
|
||||
description = body.toString(),
|
||||
soundName = null, //will be set later
|
||||
type = event.getClearType(),
|
||||
isPushGatewayEvent = false)
|
||||
} else {
|
||||
|
@ -187,6 +189,6 @@ class NotifiableEventResolver(val context: Context) {
|
|||
//TODO generic handling?
|
||||
}
|
||||
return null
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@ import android.graphics.BitmapFactory
|
|||
import android.text.TextUtils
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.Person
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.Matrix
|
||||
import im.vector.matrix.android.api.session.content.ContentUrlResolver
|
||||
import im.vector.riotredesign.BuildConfig
|
||||
import im.vector.riotredesign.R
|
||||
import im.vector.riotredesign.core.utils.SecretStoringUtils
|
||||
|
@ -36,14 +37,14 @@ import java.io.FileOutputStream
|
|||
* organise them in order to display them in the notification drawer.
|
||||
* Events can be grouped into the same notification, old (already read) events can be removed to do some cleaning.
|
||||
*/
|
||||
class NotificationDrawerManager(val context: Context, private val outdatedDetector: OutdatedEventDetector?) {
|
||||
class NotificationDrawerManager(val context: Context,
|
||||
private val outdatedDetector: OutdatedEventDetector?) {
|
||||
|
||||
|
||||
//The first time the notification drawer is refreshed, we force re-render of all notifications
|
||||
private var firstTime = true
|
||||
|
||||
private var eventList = loadEventInfo()
|
||||
private var myUserDisplayName: String = "Todo"
|
||||
private var myUserAvatarUrl: String = ""
|
||||
|
||||
private val avatarSize = context.resources.getDimensionPixelSize(R.dimen.profile_avatar_size)
|
||||
|
||||
|
@ -156,17 +157,11 @@ class NotificationDrawerManager(val context: Context, private val outdatedDetect
|
|||
|
||||
|
||||
fun refreshNotificationDrawer() {
|
||||
if (myUserDisplayName.isBlank()) {
|
||||
// TODO
|
||||
// initWithSession(Matrix.getInstance(context).defaultSession)
|
||||
}
|
||||
|
||||
if (myUserDisplayName.isBlank()) {
|
||||
// Should not happen, but myUserDisplayName cannot be blank if used to create a Person
|
||||
//TODO
|
||||
// return
|
||||
}
|
||||
|
||||
val session = Matrix.getInstance().currentSession ?: return
|
||||
val user = session.getUser(session.sessionParams.credentials.userId)
|
||||
val myUserDisplayName = user?.displayName ?: ""
|
||||
val myUserAvatarUrl = session.contentUrlResolver().resolveThumbnail(user?.avatarUrl, avatarSize, avatarSize, ContentUrlResolver.ThumbnailMethod.SCALE)
|
||||
synchronized(eventList) {
|
||||
|
||||
Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER ")
|
||||
|
|
|
@ -15,10 +15,9 @@
|
|||
*/
|
||||
package im.vector.riotredesign.features.notifications
|
||||
|
||||
import android.content.Context
|
||||
import im.vector.matrix.android.api.Matrix
|
||||
|
||||
class OutdatedEventDetector(val context: Context) {
|
||||
class OutdatedEventDetector() {
|
||||
|
||||
/**
|
||||
* Returns true if the given event is outdated.
|
||||
|
|
Loading…
Reference in New Issue