mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-17 19:58:57 +03:00
supporting images in the room notifications 15:40:32
- downloads and exports any images whilst resolving the notification event
This commit is contained in:
parent
4597cb3816
commit
8cc68e16d2
6 changed files with 64 additions and 15 deletions
|
@ -66,3 +66,7 @@ fun String?.insertBeforeLast(insert: String, delimiter: String = "."): String {
|
|||
replaceRange(idx, idx, insert)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified R> Any?.takeAs(): R? {
|
||||
return takeIf { it is R } as R?
|
||||
}
|
||||
|
|
|
@ -15,8 +15,10 @@
|
|||
*/
|
||||
package im.vector.app.features.notifications
|
||||
|
||||
import android.net.Uri
|
||||
import im.vector.app.BuildConfig
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.takeAs
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.displayname.getBestName
|
||||
import im.vector.app.features.home.room.detail.timeline.format.DisplayableEventFormatter
|
||||
|
@ -31,9 +33,11 @@ import org.matrix.android.sdk.api.session.events.model.isEdition
|
|||
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.model.message.MessageWithAttachmentContent
|
||||
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.api.session.room.timeline.getLastMessageContent
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
|
||||
import timber.log.Timber
|
||||
|
@ -49,11 +53,12 @@ import javax.inject.Inject
|
|||
class NotifiableEventResolver @Inject constructor(
|
||||
private val stringProvider: StringProvider,
|
||||
private val noticeEventFormatter: NoticeEventFormatter,
|
||||
private val displayableEventFormatter: DisplayableEventFormatter) {
|
||||
private val displayableEventFormatter: DisplayableEventFormatter
|
||||
) {
|
||||
|
||||
// private val eventDisplay = RiotEventDisplay(context)
|
||||
|
||||
fun resolveEvent(event: Event/*, roomState: RoomState?, bingRule: PushRule?*/, session: Session, isNoisy: Boolean): NotifiableEvent? {
|
||||
suspend fun resolveEvent(event: Event/*, roomState: RoomState?, bingRule: PushRule?*/, session: Session, isNoisy: Boolean): NotifiableEvent? {
|
||||
val roomID = event.roomId ?: return null
|
||||
val eventId = event.eventId ?: return null
|
||||
if (event.getClearType() == EventType.STATE_ROOM_MEMBER) {
|
||||
|
@ -89,7 +94,7 @@ class NotifiableEventResolver @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun resolveInMemoryEvent(session: Session, event: Event, canBeReplaced: Boolean): NotifiableEvent? {
|
||||
suspend fun resolveInMemoryEvent(session: Session, event: Event, canBeReplaced: Boolean): NotifiableEvent? {
|
||||
if (event.getClearType() != EventType.MESSAGE) return null
|
||||
|
||||
// Ignore message edition
|
||||
|
@ -120,7 +125,7 @@ class NotifiableEventResolver @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun resolveMessageEvent(event: TimelineEvent, session: Session, canBeReplaced: Boolean, isNoisy: Boolean): NotifiableEvent {
|
||||
private suspend fun resolveMessageEvent(event: TimelineEvent, session: Session, canBeReplaced: Boolean, isNoisy: Boolean): 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*/)
|
||||
|
||||
|
@ -140,6 +145,7 @@ class NotifiableEventResolver @Inject constructor(
|
|||
senderName = senderDisplayName,
|
||||
senderId = event.root.senderId,
|
||||
body = body.toString(),
|
||||
imageUri = event.fetchImageIfPresent(session),
|
||||
roomId = event.root.roomId!!,
|
||||
roomName = roomName,
|
||||
matrixID = session.myUserId
|
||||
|
@ -173,6 +179,7 @@ class NotifiableEventResolver @Inject constructor(
|
|||
senderName = senderDisplayName,
|
||||
senderId = event.root.senderId,
|
||||
body = body,
|
||||
imageUri = event.fetchImageIfPresent(session),
|
||||
roomId = event.root.roomId!!,
|
||||
roomName = roomName,
|
||||
roomIsDirect = room.roomSummary()?.isDirect ?: false,
|
||||
|
@ -192,6 +199,22 @@ class NotifiableEventResolver @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun TimelineEvent.fetchImageIfPresent(session: Session): Uri? {
|
||||
return when {
|
||||
root.isEncrypted() && root.mxDecryptionResult == null -> null
|
||||
root.getClearType() == EventType.MESSAGE -> downloadAndExportImage(session)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun TimelineEvent.downloadAndExportImage(session: Session): Uri? {
|
||||
return getLastMessageContent()?.takeAs<MessageWithAttachmentContent>()?.let { imageMessage ->
|
||||
val fileService = session.fileService()
|
||||
fileService.downloadFile(imageMessage)
|
||||
fileService.getTemporarySharableURI(imageMessage)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveStateRoomEvent(event: Event, session: Session, canBeReplaced: Boolean, isNoisy: Boolean): NotifiableEvent? {
|
||||
val content = event.content?.toModel<RoomMemberContent>() ?: return null
|
||||
val roomId = event.roomId ?: return null
|
||||
|
@ -224,3 +247,4 @@ class NotifiableEventResolver @Inject constructor(
|
|||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package im.vector.app.features.notifications
|
||||
|
||||
import android.net.Uri
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
|
||||
data class NotifiableMessageEvent(
|
||||
|
@ -26,6 +27,7 @@ data class NotifiableMessageEvent(
|
|||
val senderName: String?,
|
||||
val senderId: String?,
|
||||
val body: String?,
|
||||
val imageUri: Uri?,
|
||||
val roomId: String,
|
||||
val roomName: String?,
|
||||
val roomIsDirect: Boolean = false,
|
||||
|
|
|
@ -138,6 +138,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
|||
?: context?.getString(R.string.notification_sender_me),
|
||||
senderId = session.myUserId,
|
||||
body = message,
|
||||
imageUri = null,
|
||||
roomId = room.roomId,
|
||||
roomName = room.roomSummary()?.displayName ?: room.roomId,
|
||||
roomIsDirect = room.roomSummary()?.isDirect == true,
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
|
||||
package im.vector.app.features.notifications
|
||||
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.pushrules.PushEvents
|
||||
import org.matrix.android.sdk.api.pushrules.PushRuleService
|
||||
import org.matrix.android.sdk.api.pushrules.getActions
|
||||
|
@ -31,21 +36,24 @@ class PushRuleTriggerListener @Inject constructor(
|
|||
) : PushRuleService.PushRuleListener {
|
||||
|
||||
private var session: Session? = null
|
||||
private val scope: CoroutineScope = CoroutineScope(SupervisorJob())
|
||||
|
||||
override fun onEvents(pushEvents: PushEvents) {
|
||||
session?.let { session ->
|
||||
val notifiableEvents = createNotifiableEvents(pushEvents, session)
|
||||
notificationDrawerManager.updateEvents { queuedEvents ->
|
||||
notifiableEvents.forEach { notifiableEvent ->
|
||||
queuedEvents.onNotifiableEventReceived(notifiableEvent)
|
||||
scope.launch {
|
||||
session?.let { session ->
|
||||
val notifiableEvents = createNotifiableEvents(pushEvents, session)
|
||||
notificationDrawerManager.updateEvents { queuedEvents ->
|
||||
notifiableEvents.forEach { notifiableEvent ->
|
||||
queuedEvents.onNotifiableEventReceived(notifiableEvent)
|
||||
}
|
||||
queuedEvents.syncRoomEvents(roomsLeft = pushEvents.roomsLeft, roomsJoined = pushEvents.roomsJoined)
|
||||
queuedEvents.markRedacted(pushEvents.redactedEventIds)
|
||||
}
|
||||
queuedEvents.syncRoomEvents(roomsLeft = pushEvents.roomsLeft, roomsJoined = pushEvents.roomsJoined)
|
||||
queuedEvents.markRedacted(pushEvents.redactedEventIds)
|
||||
}
|
||||
} ?: Timber.e("Called without active session")
|
||||
} ?: Timber.e("Called without active session")
|
||||
}
|
||||
}
|
||||
|
||||
private fun createNotifiableEvents(pushEvents: PushEvents, session: Session): List<NotifiableEvent> {
|
||||
private suspend fun createNotifiableEvents(pushEvents: PushEvents, session: Session): List<NotifiableEvent> {
|
||||
return pushEvents.matchedEvents.mapNotNull { (event, pushRule) ->
|
||||
Timber.v("Push rule match for event ${event.eventId}")
|
||||
val action = pushRule.getActions().toNotificationAction()
|
||||
|
@ -67,6 +75,7 @@ class PushRuleTriggerListener @Inject constructor(
|
|||
}
|
||||
|
||||
fun stop() {
|
||||
scope.coroutineContext.cancelChildren(CancellationException("PushRuleTriggerListener stopping"))
|
||||
session?.removePushRuleListener(this)
|
||||
session = null
|
||||
notificationDrawerManager.clearAllEvents()
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.features.notifications
|
|||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.Person
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
|
@ -103,6 +104,7 @@ class RoomGroupMessageCreator @Inject constructor(
|
|||
|
||||
private fun NotificationCompat.MessagingStyle.addMessagesFromEvents(events: List<NotifiableMessageEvent>) {
|
||||
events.forEach { event ->
|
||||
Log.e("!!!", "event: $event")
|
||||
val senderPerson = if (event.outGoingMessage) {
|
||||
null
|
||||
} else {
|
||||
|
@ -114,7 +116,14 @@ class RoomGroupMessageCreator @Inject constructor(
|
|||
}
|
||||
when {
|
||||
event.isSmartReplyError() -> addMessage(stringProvider.getString(R.string.notification_inline_reply_failed), event.timestamp, senderPerson)
|
||||
else -> addMessage(event.body, event.timestamp, senderPerson)
|
||||
else -> {
|
||||
val message = NotificationCompat.MessagingStyle.Message(event.body, event.timestamp, senderPerson).also { message ->
|
||||
event.imageUri?.let {
|
||||
message.setData("image/", it)
|
||||
}
|
||||
}
|
||||
addMessage(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue