mirror of
https://github.com/element-hq/element-android
synced 2024-11-23 18:05:36 +03:00
Get Event after a Push for a faster notification display in some conditions
This commit is contained in:
parent
af023669ba
commit
96153fe92a
14 changed files with 234 additions and 41 deletions
|
@ -17,6 +17,7 @@ Improvements 🙌:
|
|||
- Add better support for empty room name fallback (#3106)
|
||||
- Room list improvements (paging)
|
||||
- Fix quick click action (#3127)
|
||||
- Get Event after a Push for a faster notification display in some conditions
|
||||
|
||||
Bugfix 🐛:
|
||||
- Fix bad theme change for the MainActivity
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.matrix.android.sdk.api.session.call.CallSignalingService
|
|||
import org.matrix.android.sdk.api.session.content.ContentUploadStateTracker
|
||||
import org.matrix.android.sdk.api.session.content.ContentUrlResolver
|
||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||
import org.matrix.android.sdk.api.session.events.EventService
|
||||
import org.matrix.android.sdk.api.session.file.ContentDownloadStateTracker
|
||||
import org.matrix.android.sdk.api.session.file.FileService
|
||||
import org.matrix.android.sdk.api.session.group.GroupService
|
||||
|
@ -68,6 +69,7 @@ interface Session :
|
|||
SignOutService,
|
||||
FilterService,
|
||||
TermsService,
|
||||
EventService,
|
||||
ProfileService,
|
||||
PushRuleService,
|
||||
PushersService,
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2021 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.api.session.events
|
||||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
|
||||
interface EventService {
|
||||
|
||||
/**
|
||||
* Ask the homeserver for an event content. The SDK will try to decrypt it if it is possible
|
||||
* The result will not be stored into cache
|
||||
*/
|
||||
suspend fun getEvent(roomId: String, eventId: String): Event
|
||||
}
|
|
@ -38,16 +38,21 @@ internal fun isEventRead(realmConfiguration: RealmConfiguration,
|
|||
Realm.getInstance(realmConfiguration).use { realm ->
|
||||
val liveChunk = ChunkEntity.findLastForwardChunkOfRoom(realm, roomId) ?: return@use
|
||||
val eventToCheck = liveChunk.timelineEvents.find(eventId)
|
||||
isEventRead = if (eventToCheck == null || eventToCheck.root?.sender == userId) {
|
||||
true
|
||||
} else {
|
||||
val readReceipt = ReadReceiptEntity.where(realm, roomId, userId).findFirst()
|
||||
?: return@use
|
||||
val readReceiptIndex = liveChunk.timelineEvents.find(readReceipt.eventId)?.displayIndex
|
||||
?: Int.MIN_VALUE
|
||||
val eventToCheckIndex = eventToCheck.displayIndex
|
||||
isEventRead = when {
|
||||
eventToCheck == null -> {
|
||||
// This can happen in case of fast lane Event
|
||||
false
|
||||
}
|
||||
eventToCheck.root?.sender == userId -> true
|
||||
else -> {
|
||||
val readReceipt = ReadReceiptEntity.where(realm, roomId, userId).findFirst()
|
||||
?: return@use
|
||||
val readReceiptIndex = liveChunk.timelineEvents.find(readReceipt.eventId)?.displayIndex
|
||||
?: Int.MIN_VALUE
|
||||
val eventToCheckIndex = eventToCheck.displayIndex
|
||||
|
||||
eventToCheckIndex <= readReceiptIndex
|
||||
eventToCheckIndex <= readReceiptIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.matrix.android.sdk.api.session.call.CallSignalingService
|
|||
import org.matrix.android.sdk.api.session.content.ContentUploadStateTracker
|
||||
import org.matrix.android.sdk.api.session.content.ContentUrlResolver
|
||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||
import org.matrix.android.sdk.api.session.events.EventService
|
||||
import org.matrix.android.sdk.api.session.file.ContentDownloadStateTracker
|
||||
import org.matrix.android.sdk.api.session.file.FileService
|
||||
import org.matrix.android.sdk.api.session.group.GroupService
|
||||
|
@ -114,6 +115,7 @@ internal class DefaultSession @Inject constructor(
|
|||
private val accountDataService: Lazy<AccountDataService>,
|
||||
private val _sharedSecretStorageService: Lazy<SharedSecretStorageService>,
|
||||
private val accountService: Lazy<AccountService>,
|
||||
private val eventService: Lazy<EventService>,
|
||||
private val defaultIdentityService: DefaultIdentityService,
|
||||
private val integrationManagerService: IntegrationManagerService,
|
||||
private val thirdPartyService: Lazy<ThirdPartyService>,
|
||||
|
@ -129,6 +131,7 @@ internal class DefaultSession @Inject constructor(
|
|||
FilterService by filterService.get(),
|
||||
PushRuleService by pushRuleService.get(),
|
||||
PushersService by pushersService.get(),
|
||||
EventService by eventService.get(),
|
||||
TermsService by termsService.get(),
|
||||
InitialSyncProgressService by initialSyncProgressService.get(),
|
||||
SecureStorageService by secureStorageService.get(),
|
||||
|
|
|
@ -32,10 +32,11 @@ import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
|
|||
import org.matrix.android.sdk.api.auth.data.SessionParams
|
||||
import org.matrix.android.sdk.api.auth.data.sessionId
|
||||
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
|
||||
import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.accountdata.AccountDataService
|
||||
import org.matrix.android.sdk.api.session.events.EventService
|
||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
|
||||
import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
|
||||
import org.matrix.android.sdk.api.session.securestorage.SecureStorageService
|
||||
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
|
||||
|
@ -75,6 +76,7 @@ import org.matrix.android.sdk.internal.network.token.AccessTokenProvider
|
|||
import org.matrix.android.sdk.internal.network.token.HomeserverAccessTokenProvider
|
||||
import org.matrix.android.sdk.internal.session.call.CallEventProcessor
|
||||
import org.matrix.android.sdk.internal.session.download.DownloadProgressInterceptor
|
||||
import org.matrix.android.sdk.internal.session.events.DefaultEventService
|
||||
import org.matrix.android.sdk.internal.session.homeserver.DefaultHomeServerCapabilitiesService
|
||||
import org.matrix.android.sdk.internal.session.identity.DefaultIdentityService
|
||||
import org.matrix.android.sdk.internal.session.initsync.DefaultInitialSyncProgressService
|
||||
|
@ -357,6 +359,9 @@ internal abstract class SessionModule {
|
|||
@Binds
|
||||
abstract fun bindAccountDataService(service: DefaultAccountDataService): AccountDataService
|
||||
|
||||
@Binds
|
||||
abstract fun bindEventService(service: DefaultEventService): EventService
|
||||
|
||||
@Binds
|
||||
abstract fun bindSharedSecretStorageService(service: DefaultSharedSecretStorageService): SharedSecretStorageService
|
||||
|
||||
|
|
|
@ -21,9 +21,11 @@ import org.matrix.android.sdk.api.session.events.model.Event
|
|||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.internal.database.model.EventInsertType
|
||||
import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
|
||||
import org.matrix.android.sdk.internal.session.SessionScope
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@SessionScope
|
||||
internal class CallEventProcessor @Inject constructor(private val callSignalingHandler: CallSignalingHandler)
|
||||
: EventInsertLiveProcessor {
|
||||
|
||||
|
@ -51,6 +53,15 @@ internal class CallEventProcessor @Inject constructor(private val callSignalingH
|
|||
eventsToPostProcess.add(event)
|
||||
}
|
||||
|
||||
fun shouldProcessFastLane(eventType: String): Boolean {
|
||||
return eventType == EventType.CALL_INVITE
|
||||
}
|
||||
|
||||
suspend fun processFastLane(event: Event) {
|
||||
eventsToPostProcess.add(event)
|
||||
onPostProcess()
|
||||
}
|
||||
|
||||
override suspend fun onPostProcess() {
|
||||
eventsToPostProcess.forEach {
|
||||
dispatchToCallSignalingHandlerIfNeeded(it)
|
||||
|
@ -60,7 +71,7 @@ internal class CallEventProcessor @Inject constructor(private val callSignalingH
|
|||
|
||||
private fun dispatchToCallSignalingHandlerIfNeeded(event: Event) {
|
||||
val now = System.currentTimeMillis()
|
||||
// TODO might check if an invite is not closed (hangup/answsered) in the same event batch?
|
||||
// TODO might check if an invite is not closed (hangup/answered) in the same event batch?
|
||||
event.roomId ?: return Unit.also {
|
||||
Timber.w("Event with no room id ${event.eventId}")
|
||||
}
|
||||
|
|
|
@ -56,25 +56,25 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
|
|||
|
||||
fun onCallEvent(event: Event) {
|
||||
when (event.getClearType()) {
|
||||
EventType.CALL_ANSWER -> {
|
||||
EventType.CALL_ANSWER -> {
|
||||
handleCallAnswerEvent(event)
|
||||
}
|
||||
EventType.CALL_INVITE -> {
|
||||
EventType.CALL_INVITE -> {
|
||||
handleCallInviteEvent(event)
|
||||
}
|
||||
EventType.CALL_HANGUP -> {
|
||||
EventType.CALL_HANGUP -> {
|
||||
handleCallHangupEvent(event)
|
||||
}
|
||||
EventType.CALL_REJECT -> {
|
||||
EventType.CALL_REJECT -> {
|
||||
handleCallRejectEvent(event)
|
||||
}
|
||||
EventType.CALL_CANDIDATES -> {
|
||||
EventType.CALL_CANDIDATES -> {
|
||||
handleCallCandidatesEvent(event)
|
||||
}
|
||||
EventType.CALL_SELECT_ANSWER -> {
|
||||
handleCallSelectAnswerEvent(event)
|
||||
}
|
||||
EventType.CALL_NEGOTIATE -> {
|
||||
EventType.CALL_NEGOTIATE -> {
|
||||
handleCallNegotiateEvent(event)
|
||||
}
|
||||
}
|
||||
|
@ -168,6 +168,14 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
|
|||
return
|
||||
}
|
||||
val content = event.getClearContent().toModel<CallInviteContent>() ?: return
|
||||
|
||||
content.callId ?: return
|
||||
if (activeCallHandler.getCallWithId(content.callId) != null) {
|
||||
// Call is already known, maybe due to fast lane. Ignore
|
||||
Timber.d("Ignoring already known call invite")
|
||||
return
|
||||
}
|
||||
|
||||
val incomingCall = mxCallFactory.createIncomingCall(
|
||||
roomId = event.roomId,
|
||||
opponentUserId = event.senderId,
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2021 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.session.events
|
||||
|
||||
import org.matrix.android.sdk.api.session.events.EventService
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.internal.session.call.CallEventProcessor
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.GetEventTask
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultEventService @Inject constructor(
|
||||
private val getEventTask: GetEventTask,
|
||||
private val callEventProcessor: CallEventProcessor
|
||||
) : EventService {
|
||||
|
||||
override suspend fun getEvent(roomId: String, eventId: String): Event {
|
||||
val event = getEventTask.execute(GetEventTask.Params(roomId, eventId))
|
||||
|
||||
// Fast lane to the call event processors: try to make the incoming call ring faster
|
||||
if (callEventProcessor.shouldProcessFastLane(event.getClearType())) {
|
||||
callEventProcessor.processFastLane(event)
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
}
|
|
@ -79,9 +79,11 @@ import org.matrix.android.sdk.internal.session.room.tags.DefaultDeleteTagFromRoo
|
|||
import org.matrix.android.sdk.internal.session.room.tags.DeleteTagFromRoomTask
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.DefaultFetchTokenAndPaginateTask
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.DefaultGetContextOfEventTask
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.DefaultGetEventTask
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.DefaultPaginationTask
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.FetchTokenAndPaginateTask
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.GetContextOfEventTask
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.GetEventTask
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.PaginationTask
|
||||
import org.matrix.android.sdk.internal.session.room.typing.DefaultSendTypingTask
|
||||
import org.matrix.android.sdk.internal.session.room.typing.SendTypingTask
|
||||
|
@ -228,4 +230,7 @@ internal abstract class RoomModule {
|
|||
|
||||
@Binds
|
||||
abstract fun bindPeekRoomTask(task: DefaultPeekRoomTask): PeekRoomTask
|
||||
|
||||
@Binds
|
||||
abstract fun bindGetEventTask(task: DefaultGetEventTask): GetEventTask
|
||||
}
|
||||
|
|
|
@ -16,28 +16,49 @@
|
|||
|
||||
package org.matrix.android.sdk.internal.session.room.timeline
|
||||
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.internal.crypto.EventDecryptor
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
|
||||
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
|
||||
import org.matrix.android.sdk.internal.network.executeRequest
|
||||
import org.matrix.android.sdk.internal.session.room.RoomAPI
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO Add parent task
|
||||
|
||||
internal class GetEventTask @Inject constructor(
|
||||
private val roomAPI: RoomAPI,
|
||||
private val globalErrorReceiver: GlobalErrorReceiver
|
||||
) : Task<GetEventTask.Params, Event> {
|
||||
|
||||
internal data class Params(
|
||||
internal interface GetEventTask : Task<GetEventTask.Params, Event> {
|
||||
data class Params(
|
||||
val roomId: String,
|
||||
val eventId: String
|
||||
val eventId: String,
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun execute(params: Params): Event {
|
||||
return executeRequest(globalErrorReceiver) {
|
||||
internal class DefaultGetEventTask @Inject constructor(
|
||||
private val roomAPI: RoomAPI,
|
||||
private val globalErrorReceiver: GlobalErrorReceiver,
|
||||
private val eventDecryptor: EventDecryptor
|
||||
) : GetEventTask {
|
||||
|
||||
override suspend fun execute(params: GetEventTask.Params): Event {
|
||||
val event = executeRequest(globalErrorReceiver) {
|
||||
roomAPI.getEvent(params.roomId, params.eventId)
|
||||
}
|
||||
|
||||
// Try to decrypt the Event
|
||||
if (event.isEncrypted()) {
|
||||
tryOrNull(message = "Unable to decrypt the event") {
|
||||
eventDecryptor.decryptEvent(event, "")
|
||||
}
|
||||
?.let { result ->
|
||||
event.mxDecryptionResult = OlmDecryptionResult(
|
||||
payload = result.clearEvent,
|
||||
senderKey = result.senderCurve25519Key,
|
||||
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,9 @@ import im.vector.app.features.notifications.NotificationUtils
|
|||
import im.vector.app.features.notifications.SimpleNotifiableEvent
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import im.vector.app.push.fcm.FcmHelper
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.pushrules.Action
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
|
@ -56,6 +59,8 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
private lateinit var activeSessionHolder: ActiveSessionHolder
|
||||
private lateinit var vectorPreferences: VectorPreferences
|
||||
|
||||
private val coroutineScope = CoroutineScope(SupervisorJob())
|
||||
|
||||
// UI handler
|
||||
private val mUIHandler by lazy {
|
||||
Handler(Looper.getMainLooper())
|
||||
|
@ -78,6 +83,11 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
* @param message the message
|
||||
*/
|
||||
override fun onMessageReceived(message: RemoteMessage) {
|
||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
||||
Timber.d("## onMessageReceived() %s", message.data.toString())
|
||||
}
|
||||
Timber.d("## onMessageReceived() from FCM with priority %s", message.priority)
|
||||
|
||||
// Diagnostic Push
|
||||
if (message.data["event_id"] == PushersManager.TEST_EVENT_ID) {
|
||||
val intent = Intent(NotificationUtils.PUSH_ACTION)
|
||||
|
@ -90,14 +100,10 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
return
|
||||
}
|
||||
|
||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
||||
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)) {
|
||||
// we are in foreground, let the sync do the things?
|
||||
Timber.v("PUSH received in a foreground state, ignore")
|
||||
Timber.d("PUSH received in a foreground state, ignore")
|
||||
} else {
|
||||
onMessageReceivedInternal(message.data)
|
||||
}
|
||||
|
@ -140,7 +146,9 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
private fun onMessageReceivedInternal(data: Map<String, String>) {
|
||||
try {
|
||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
||||
Timber.i("## onMessageReceivedInternal() : $data")
|
||||
Timber.d("## onMessageReceivedInternal() : $data")
|
||||
} else {
|
||||
Timber.d("## onMessageReceivedInternal() : $data")
|
||||
}
|
||||
|
||||
// update the badge counter
|
||||
|
@ -156,9 +164,13 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
val roomId = data["room_id"]
|
||||
|
||||
if (isEventAlreadyKnown(eventId, roomId)) {
|
||||
Timber.i("Ignoring push, event already known")
|
||||
Timber.d("Ignoring push, event already known")
|
||||
} else {
|
||||
Timber.v("Requesting background sync")
|
||||
// Try to get the Event content faster
|
||||
Timber.d("Requesting event in fast lane")
|
||||
getEventFastLane(session, roomId, eventId)
|
||||
|
||||
Timber.d("Requesting background sync")
|
||||
session.requireBackgroundSync()
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +179,32 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun getEventFastLane(session: Session, roomId: String?, eventId: String?) {
|
||||
roomId?.takeIf { it.isNotEmpty() } ?: return
|
||||
eventId?.takeIf { it.isNotEmpty() } ?: return
|
||||
|
||||
// If the room is currently displayed, we will not show a notification, so no need to get the Event faster
|
||||
if (notificationDrawerManager.shouldIgnoreMessageEventInRoom(roomId)) {
|
||||
return
|
||||
}
|
||||
|
||||
coroutineScope.launch {
|
||||
Timber.d("Fast lane: start request")
|
||||
val event = session.getEvent(roomId, eventId)
|
||||
|
||||
val resolvedEvent = notifiableEventResolver.resolveInMemoryEvent(session, event)
|
||||
|
||||
// TODO Test the Event against the push rules
|
||||
resolvedEvent
|
||||
?.also { Timber.d("Fast lane: notify drawer") }
|
||||
?.let {
|
||||
it.isPushGatewayEvent = true
|
||||
notificationDrawerManager.onNotifiableEventReceived(it)
|
||||
notificationDrawerManager.refreshNotificationDrawer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if the event was not yet received
|
||||
// a previous catchup might have already retrieved the notified event
|
||||
private fun isEventAlreadyKnown(eventId: String?, roomId: String?): Boolean {
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType
|
|||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||
import org.matrix.android.sdk.api.session.room.sender.SenderInfo
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||
import org.matrix.android.sdk.api.session.room.timeline.getEditedEventId
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
|
||||
|
@ -42,9 +43,10 @@ import javax.inject.Inject
|
|||
* 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 @Inject constructor(private val stringProvider: StringProvider,
|
||||
private val noticeEventFormatter: NoticeEventFormatter,
|
||||
private val displayableEventFormatter: DisplayableEventFormatter) {
|
||||
class NotifiableEventResolver @Inject constructor(
|
||||
private val stringProvider: StringProvider,
|
||||
private val noticeEventFormatter: NoticeEventFormatter,
|
||||
private val displayableEventFormatter: DisplayableEventFormatter) {
|
||||
|
||||
// private val eventDisplay = RiotEventDisplay(context)
|
||||
|
||||
|
@ -84,6 +86,28 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
|
|||
}
|
||||
}
|
||||
|
||||
fun resolveInMemoryEvent(session: Session, event: Event): NotifiableEvent? {
|
||||
if (event.getClearType() != EventType.MESSAGE) return null
|
||||
|
||||
// TODO Ignore message edition
|
||||
val user = session.getUser(event.senderId!!) ?: return null
|
||||
|
||||
val timelineEvent = TimelineEvent(
|
||||
root = event,
|
||||
localId = -1,
|
||||
eventId = event.eventId!!,
|
||||
displayIndex = 0,
|
||||
senderInfo = SenderInfo(
|
||||
userId = user.userId,
|
||||
displayName = user.getBestName(),
|
||||
isUniqueDisplayName = true,
|
||||
avatarUrl = user.avatarUrl
|
||||
)
|
||||
)
|
||||
|
||||
return resolveMessageEvent(timelineEvent, session)
|
||||
}
|
||||
|
||||
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.root.roomId!! /*roomID cannot be null*/)
|
||||
|
|
|
@ -89,7 +89,9 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
// If we support multi session, event list should be per userId
|
||||
// Currently only manage single session
|
||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
||||
Timber.v("%%%%%%%% onNotifiableEventReceived $notifiableEvent")
|
||||
Timber.d("onNotifiableEventReceived(): $notifiableEvent")
|
||||
} else {
|
||||
Timber.d("onNotifiableEventReceived(): is push: ${notifiableEvent.isPushGatewayEvent}")
|
||||
}
|
||||
synchronized(eventList) {
|
||||
val existing = eventList.firstOrNull { it.eventId == notifiableEvent.eventId }
|
||||
|
@ -550,7 +552,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
return bitmapLoader.getRoomBitmap(roomAvatarPath)
|
||||
}
|
||||
|
||||
private fun shouldIgnoreMessageEventInRoom(roomId: String?): Boolean {
|
||||
fun shouldIgnoreMessageEventInRoom(roomId: String?): Boolean {
|
||||
return currentRoomId != null && roomId == currentRoomId
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue