Merge branch 'develop' into feature/fga/update-rust-sdk-0.1.29-again
This commit is contained in:
commit
9e5a3d14e5
225 changed files with 1635 additions and 815 deletions
|
|
@ -28,19 +28,19 @@ class NotificationMapper {
|
|||
private val timelineEventMapper = TimelineEventMapper()
|
||||
|
||||
fun map(notificationItem: NotificationItem): NotificationData {
|
||||
return notificationItem.use {
|
||||
return notificationItem.use { item ->
|
||||
NotificationData(
|
||||
senderId = UserId(it.event.senderId()),
|
||||
eventId = EventId(it.event.eventId()),
|
||||
roomId = RoomId(it.roomInfo.id),
|
||||
senderAvatarUrl = it.senderInfo.avatarUrl,
|
||||
senderDisplayName = it.senderInfo.displayName,
|
||||
roomAvatarUrl = it.roomInfo.avatarUrl,
|
||||
roomDisplayName = it.roomInfo.displayName,
|
||||
isDirect = it.roomInfo.isDirect,
|
||||
isEncrypted = it.roomInfo.isEncrypted.orFalse(),
|
||||
isNoisy = it.isNoisy,
|
||||
event = it.event.use { event -> timelineEventMapper.map(event) }
|
||||
senderId = UserId(item.event.senderId()),
|
||||
eventId = EventId(item.event.eventId()),
|
||||
roomId = RoomId(item.roomInfo.id),
|
||||
senderAvatarUrl = item.senderInfo.avatarUrl,
|
||||
senderDisplayName = item.senderInfo.displayName,
|
||||
roomAvatarUrl = item.roomInfo.avatarUrl ?: item.senderInfo.avatarUrl.takeIf { item.roomInfo.isDirect },
|
||||
roomDisplayName = item.roomInfo.displayName,
|
||||
isDirect = item.roomInfo.isDirect,
|
||||
isEncrypted = item.roomInfo.isEncrypted.orFalse(),
|
||||
isNoisy = item.isNoisy,
|
||||
event = item.event.use { event -> timelineEventMapper.map(event) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ class RustNotificationService(
|
|||
filterByPushRules: Boolean,
|
||||
): Result<NotificationData?> {
|
||||
return runCatching {
|
||||
client.getNotificationItem(roomId.value, eventId.value, filterByPushRules)?.use(notificationMapper::map)
|
||||
val item = client.getNotificationItem(roomId.value, eventId.value, filterByPushRules)
|
||||
item?.use(notificationMapper::map)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,11 @@
|
|||
|
||||
package io.element.android.libraries.matrix.impl.notification
|
||||
|
||||
import io.element.android.libraries.matrix.api.notification.NotificationContent
|
||||
import io.element.android.libraries.matrix.api.notification.NotificationEvent
|
||||
import io.element.android.libraries.matrix.impl.room.RoomMemberMapper
|
||||
import io.element.android.libraries.matrix.impl.timeline.item.event.EventMessageMapper
|
||||
import org.matrix.rustcomponents.sdk.MessageLikeEventContent
|
||||
import org.matrix.rustcomponents.sdk.MessageType
|
||||
import org.matrix.rustcomponents.sdk.StateEventContent
|
||||
import org.matrix.rustcomponents.sdk.TimelineEvent
|
||||
import org.matrix.rustcomponents.sdk.TimelineEventType
|
||||
|
|
@ -38,71 +40,62 @@ class TimelineEventMapper @Inject constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun TimelineEventType.toContent(): String {
|
||||
private fun TimelineEventType.toContent(): NotificationContent {
|
||||
return when (this) {
|
||||
is TimelineEventType.MessageLike -> content.toContent()
|
||||
is TimelineEventType.State -> content.toContent()
|
||||
}
|
||||
}
|
||||
|
||||
private fun StateEventContent.toContent(): String {
|
||||
private fun StateEventContent.toContent(): NotificationContent.StateEvent {
|
||||
return when (this) {
|
||||
StateEventContent.PolicyRuleRoom -> "PolicyRuleRoom"
|
||||
StateEventContent.PolicyRuleServer -> "PolicyRuleServer"
|
||||
StateEventContent.PolicyRuleUser -> "PolicyRuleUser"
|
||||
StateEventContent.RoomAliases -> "RoomAliases"
|
||||
StateEventContent.RoomAvatar -> "RoomAvatar"
|
||||
StateEventContent.RoomCanonicalAlias -> "RoomCanonicalAlias"
|
||||
StateEventContent.RoomCreate -> "RoomCreate"
|
||||
StateEventContent.RoomEncryption -> "RoomEncryption"
|
||||
StateEventContent.RoomGuestAccess -> "RoomGuestAccess"
|
||||
StateEventContent.RoomHistoryVisibility -> "RoomHistoryVisibility"
|
||||
StateEventContent.RoomJoinRules -> "RoomJoinRules"
|
||||
is StateEventContent.RoomMemberContent -> "$userId is now $membershipState"
|
||||
StateEventContent.RoomName -> "RoomName"
|
||||
StateEventContent.RoomPinnedEvents -> "RoomPinnedEvents"
|
||||
StateEventContent.RoomPowerLevels -> "RoomPowerLevels"
|
||||
StateEventContent.RoomServerAcl -> "RoomServerAcl"
|
||||
StateEventContent.RoomThirdPartyInvite -> "RoomThirdPartyInvite"
|
||||
StateEventContent.RoomTombstone -> "RoomTombstone"
|
||||
StateEventContent.RoomTopic -> "RoomTopic"
|
||||
StateEventContent.SpaceChild -> "SpaceChild"
|
||||
StateEventContent.SpaceParent -> "SpaceParent"
|
||||
StateEventContent.PolicyRuleRoom -> NotificationContent.StateEvent.PolicyRuleRoom
|
||||
StateEventContent.PolicyRuleServer -> NotificationContent.StateEvent.PolicyRuleServer
|
||||
StateEventContent.PolicyRuleUser -> NotificationContent.StateEvent.PolicyRuleUser
|
||||
StateEventContent.RoomAliases -> NotificationContent.StateEvent.RoomAliases
|
||||
StateEventContent.RoomAvatar -> NotificationContent.StateEvent.RoomAvatar
|
||||
StateEventContent.RoomCanonicalAlias -> NotificationContent.StateEvent.RoomCanonicalAlias
|
||||
StateEventContent.RoomCreate -> NotificationContent.StateEvent.RoomCreate
|
||||
StateEventContent.RoomEncryption -> NotificationContent.StateEvent.RoomEncryption
|
||||
StateEventContent.RoomGuestAccess -> NotificationContent.StateEvent.RoomGuestAccess
|
||||
StateEventContent.RoomHistoryVisibility -> NotificationContent.StateEvent.RoomHistoryVisibility
|
||||
StateEventContent.RoomJoinRules -> NotificationContent.StateEvent.RoomJoinRules
|
||||
is StateEventContent.RoomMemberContent -> {
|
||||
NotificationContent.StateEvent.RoomMemberContent(userId, RoomMemberMapper.mapMembership(membershipState))
|
||||
}
|
||||
StateEventContent.RoomName -> NotificationContent.StateEvent.RoomName
|
||||
StateEventContent.RoomPinnedEvents -> NotificationContent.StateEvent.RoomPinnedEvents
|
||||
StateEventContent.RoomPowerLevels -> NotificationContent.StateEvent.RoomPowerLevels
|
||||
StateEventContent.RoomServerAcl -> NotificationContent.StateEvent.RoomServerAcl
|
||||
StateEventContent.RoomThirdPartyInvite -> NotificationContent.StateEvent.RoomThirdPartyInvite
|
||||
StateEventContent.RoomTombstone -> NotificationContent.StateEvent.RoomTombstone
|
||||
StateEventContent.RoomTopic -> NotificationContent.StateEvent.RoomTopic
|
||||
StateEventContent.SpaceChild -> NotificationContent.StateEvent.SpaceChild
|
||||
StateEventContent.SpaceParent -> NotificationContent.StateEvent.SpaceParent
|
||||
}
|
||||
}
|
||||
|
||||
private fun MessageLikeEventContent.toContent(): String {
|
||||
private fun MessageLikeEventContent.toContent(): NotificationContent.MessageLike {
|
||||
return use {
|
||||
when (it) {
|
||||
MessageLikeEventContent.CallAnswer -> "CallAnswer"
|
||||
MessageLikeEventContent.CallCandidates -> "CallCandidates"
|
||||
MessageLikeEventContent.CallHangup -> "CallHangup"
|
||||
MessageLikeEventContent.CallInvite -> "CallInvite"
|
||||
MessageLikeEventContent.KeyVerificationAccept -> "KeyVerificationAccept"
|
||||
MessageLikeEventContent.KeyVerificationCancel -> "KeyVerificationCancel"
|
||||
MessageLikeEventContent.KeyVerificationDone -> "KeyVerificationDone"
|
||||
MessageLikeEventContent.KeyVerificationKey -> "KeyVerificationKey"
|
||||
MessageLikeEventContent.KeyVerificationMac -> "KeyVerificationMac"
|
||||
MessageLikeEventContent.KeyVerificationReady -> "KeyVerificationReady"
|
||||
MessageLikeEventContent.KeyVerificationStart -> "KeyVerificationStart"
|
||||
is MessageLikeEventContent.ReactionContent -> "Reacted to ${it.relatedEventId.take(8)}…"
|
||||
MessageLikeEventContent.RoomEncrypted -> "RoomEncrypted"
|
||||
is MessageLikeEventContent.RoomMessage -> it.messageType.toContent()
|
||||
MessageLikeEventContent.RoomRedaction -> "RoomRedaction"
|
||||
MessageLikeEventContent.Sticker -> "Sticker"
|
||||
MessageLikeEventContent.CallAnswer -> NotificationContent.MessageLike.CallAnswer
|
||||
MessageLikeEventContent.CallCandidates -> NotificationContent.MessageLike.CallCandidates
|
||||
MessageLikeEventContent.CallHangup -> NotificationContent.MessageLike.CallHangup
|
||||
MessageLikeEventContent.CallInvite -> NotificationContent.MessageLike.CallInvite
|
||||
MessageLikeEventContent.KeyVerificationAccept -> NotificationContent.MessageLike.KeyVerificationAccept
|
||||
MessageLikeEventContent.KeyVerificationCancel -> NotificationContent.MessageLike.KeyVerificationCancel
|
||||
MessageLikeEventContent.KeyVerificationDone -> NotificationContent.MessageLike.KeyVerificationDone
|
||||
MessageLikeEventContent.KeyVerificationKey -> NotificationContent.MessageLike.KeyVerificationKey
|
||||
MessageLikeEventContent.KeyVerificationMac -> NotificationContent.MessageLike.KeyVerificationMac
|
||||
MessageLikeEventContent.KeyVerificationReady -> NotificationContent.MessageLike.KeyVerificationReady
|
||||
MessageLikeEventContent.KeyVerificationStart -> NotificationContent.MessageLike.KeyVerificationStart
|
||||
is MessageLikeEventContent.ReactionContent -> NotificationContent.MessageLike.ReactionContent(it.relatedEventId)
|
||||
MessageLikeEventContent.RoomEncrypted -> NotificationContent.MessageLike.RoomEncrypted
|
||||
is MessageLikeEventContent.RoomMessage -> {
|
||||
NotificationContent.MessageLike.RoomMessage(EventMessageMapper().mapMessageType(it.messageType))
|
||||
}
|
||||
MessageLikeEventContent.RoomRedaction -> NotificationContent.MessageLike.RoomRedaction
|
||||
MessageLikeEventContent.Sticker -> NotificationContent.MessageLike.Sticker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun MessageType.toContent(): String {
|
||||
return when (this) {
|
||||
is MessageType.Audio -> content.use { it.body }
|
||||
is MessageType.Emote -> content.body
|
||||
is MessageType.File -> content.use { it.body }
|
||||
is MessageType.Image -> content.use { it.body }
|
||||
is MessageType.Location -> content.body
|
||||
is MessageType.Notice -> content.body
|
||||
is MessageType.Text -> content.body
|
||||
is MessageType.Video -> content.use { it.body }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,23 +24,30 @@ import kotlinx.coroutines.flow.SharingStarted
|
|||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import org.matrix.rustcomponents.sdk.RoomListService
|
||||
import org.matrix.rustcomponents.sdk.RoomListServiceState
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
class RustSyncService(
|
||||
private val roomListService: RoomListService,
|
||||
sessionCoroutineScope: CoroutineScope
|
||||
) : SyncService {
|
||||
|
||||
private val isSyncing = AtomicBoolean(false)
|
||||
|
||||
override fun startSync() = runCatching {
|
||||
if (!roomListService.isSyncing()) {
|
||||
if (isSyncing.compareAndSet(false, true)) {
|
||||
Timber.v("Start sync")
|
||||
roomListService.sync()
|
||||
}
|
||||
}
|
||||
|
||||
override fun stopSync() = runCatching {
|
||||
if (roomListService.isSyncing()) {
|
||||
if (isSyncing.compareAndSet(true, false)) {
|
||||
Timber.v("Stop sync")
|
||||
roomListService.stopSync()
|
||||
}
|
||||
}
|
||||
|
|
@ -49,6 +56,10 @@ class RustSyncService(
|
|||
roomListService
|
||||
.stateFlow()
|
||||
.map(RoomListServiceState::toSyncState)
|
||||
.onEach { state ->
|
||||
Timber.v("Sync state=$state")
|
||||
isSyncing.set(state == SyncState.Syncing)
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.stateIn(sessionCoroutineScope, SharingStarted.WhileSubscribed(), SyncState.Idle)
|
||||
.stateIn(sessionCoroutineScope, SharingStarted.Eagerly, SyncState.Idle)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,48 +33,17 @@ import io.element.android.libraries.matrix.api.timeline.item.event.UnknownMessag
|
|||
import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType
|
||||
import io.element.android.libraries.matrix.impl.media.map
|
||||
import org.matrix.rustcomponents.sdk.Message
|
||||
import org.matrix.rustcomponents.sdk.MessageType
|
||||
import org.matrix.rustcomponents.sdk.ProfileDetails
|
||||
import org.matrix.rustcomponents.sdk.RepliedToEventDetails
|
||||
import org.matrix.rustcomponents.sdk.use
|
||||
import org.matrix.rustcomponents.sdk.FormattedBody as RustFormattedBody
|
||||
import org.matrix.rustcomponents.sdk.MessageFormat as RustMessageFormat
|
||||
import org.matrix.rustcomponents.sdk.MessageType as RustMessageType
|
||||
|
||||
class EventMessageMapper {
|
||||
|
||||
fun map(message: Message): MessageContent = message.use {
|
||||
val type = it.msgtype().use { type ->
|
||||
when (type) {
|
||||
is MessageType.Audio -> {
|
||||
AudioMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
|
||||
}
|
||||
is MessageType.File -> {
|
||||
FileMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
|
||||
}
|
||||
is MessageType.Image -> {
|
||||
ImageMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
|
||||
}
|
||||
is MessageType.Location -> {
|
||||
LocationMessageType(type.content.body, type.content.geoUri, type.content.description)
|
||||
}
|
||||
is MessageType.Notice -> {
|
||||
NoticeMessageType(type.content.body, type.content.formatted?.map())
|
||||
}
|
||||
is MessageType.Text -> {
|
||||
TextMessageType(type.content.body, type.content.formatted?.map())
|
||||
}
|
||||
is MessageType.Emote -> {
|
||||
EmoteMessageType(type.content.body, type.content.formatted?.map())
|
||||
}
|
||||
is MessageType.Video -> {
|
||||
VideoMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
|
||||
}
|
||||
null -> {
|
||||
UnknownMessageType
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
val type = it.msgtype().use(this::mapMessageType)
|
||||
val inReplyToId = it.inReplyTo()?.eventId?.let(::EventId)
|
||||
val inReplyToEvent: InReplyTo? = (it.inReplyTo()?.event)?.use { details ->
|
||||
when (details) {
|
||||
|
|
@ -99,6 +68,34 @@ class EventMessageMapper {
|
|||
type = type
|
||||
)
|
||||
}
|
||||
|
||||
fun mapMessageType(type: RustMessageType?) = when (type) {
|
||||
is RustMessageType.Audio -> {
|
||||
AudioMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
|
||||
}
|
||||
is RustMessageType.File -> {
|
||||
FileMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
|
||||
}
|
||||
is RustMessageType.Image -> {
|
||||
ImageMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
|
||||
}
|
||||
is RustMessageType.Notice -> {
|
||||
NoticeMessageType(type.content.body, type.content.formatted?.map())
|
||||
}
|
||||
is RustMessageType.Text -> {
|
||||
TextMessageType(type.content.body, type.content.formatted?.map())
|
||||
}
|
||||
is RustMessageType.Emote -> {
|
||||
EmoteMessageType(type.content.body, type.content.formatted?.map())
|
||||
}
|
||||
is RustMessageType.Video -> {
|
||||
VideoMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
|
||||
}
|
||||
is RustMessageType.Location -> {
|
||||
LocationMessageType(type.content.body, type.content.geoUri, type.content.description)
|
||||
}
|
||||
null -> UnknownMessageType
|
||||
}
|
||||
}
|
||||
|
||||
private fun RustFormattedBody.map(): FormattedBody = FormattedBody(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue