mirror of
https://github.com/ouchadam/small-talk.git
synced 2025-02-22 23:19:22 +01:00
fixing images causing decryption errors
- introduces a dedicated encrypted room event type
This commit is contained in:
parent
14a8b94496
commit
f47a44063b
@ -105,6 +105,19 @@ sealed class RoomEvent {
|
|||||||
abstract val author: RoomMember
|
abstract val author: RoomMember
|
||||||
abstract val meta: MessageMeta
|
abstract val meta: MessageMeta
|
||||||
|
|
||||||
|
data class Encrypted(
|
||||||
|
override val eventId: EventId,
|
||||||
|
override val utcTimestamp: Long,
|
||||||
|
override val author: RoomMember,
|
||||||
|
override val meta: MessageMeta,
|
||||||
|
) : RoomEvent() {
|
||||||
|
|
||||||
|
val time: String by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||||
|
val instant = Instant.ofEpochMilli(utcTimestamp)
|
||||||
|
ZonedDateTime.ofInstant(instant, DEFAULT_ZONE).toLocalTime().format(MESSAGE_TIME_FORMAT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data class Message(
|
data class Message(
|
||||||
override val eventId: EventId,
|
override val eventId: EventId,
|
||||||
override val utcTimestamp: Long,
|
override val utcTimestamp: Long,
|
||||||
|
@ -198,6 +198,7 @@ private fun ColumnScope.RoomContent(self: UserId, state: RoomState, replyActions
|
|||||||
is RoomEvent.Image -> MessageImage(it as BubbleContent<RoomEvent.Image>)
|
is RoomEvent.Image -> MessageImage(it as BubbleContent<RoomEvent.Image>)
|
||||||
is RoomEvent.Message -> TextBubbleContent(it as BubbleContent<RoomEvent.Message>)
|
is RoomEvent.Message -> TextBubbleContent(it as BubbleContent<RoomEvent.Message>)
|
||||||
is RoomEvent.Reply -> ReplyBubbleContent(it as BubbleContent<RoomEvent.Reply>)
|
is RoomEvent.Reply -> ReplyBubbleContent(it as BubbleContent<RoomEvent.Reply>)
|
||||||
|
is RoomEvent.Encrypted -> EncryptedBubbleContent(it as BubbleContent<RoomEvent.Encrypted>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -445,6 +446,54 @@ private fun TextBubbleContent(content: BubbleContent<RoomEvent.Message>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun EncryptedBubbleContent(content: BubbleContent<RoomEvent.Encrypted>) {
|
||||||
|
Box(modifier = Modifier.padding(start = 6.dp)) {
|
||||||
|
Box(
|
||||||
|
Modifier
|
||||||
|
.padding(4.dp)
|
||||||
|
.clip(content.shape)
|
||||||
|
.background(content.background)
|
||||||
|
.height(IntrinsicSize.Max),
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
Modifier
|
||||||
|
.padding(8.dp)
|
||||||
|
.width(IntrinsicSize.Max)
|
||||||
|
.defaultMinSize(minWidth = 50.dp)
|
||||||
|
) {
|
||||||
|
if (content.isNotSelf) {
|
||||||
|
Text(
|
||||||
|
fontSize = 11.sp,
|
||||||
|
text = content.message.author.displayName ?: content.message.author.id.value,
|
||||||
|
maxLines = 1,
|
||||||
|
color = content.textColor()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = "Encrypted message",
|
||||||
|
color = content.textColor(),
|
||||||
|
fontSize = 15.sp,
|
||||||
|
modifier = Modifier.wrapContentSize(),
|
||||||
|
textAlign = TextAlign.Start,
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
Row(horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
|
||||||
|
Text(
|
||||||
|
fontSize = 9.sp,
|
||||||
|
text = "${content.message.time}",
|
||||||
|
textAlign = TextAlign.End,
|
||||||
|
color = content.textColor(),
|
||||||
|
modifier = Modifier.wrapContentSize()
|
||||||
|
)
|
||||||
|
SendStatus(content.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ReplyBubbleContent(content: BubbleContent<RoomEvent.Reply>) {
|
private fun ReplyBubbleContent(content: BubbleContent<RoomEvent.Reply>) {
|
||||||
Box(modifier = Modifier.padding(start = 6.dp)) {
|
Box(modifier = Modifier.padding(start = 6.dp)) {
|
||||||
@ -511,6 +560,16 @@ private fun ReplyBubbleContent(content: BubbleContent<RoomEvent.Reply>) {
|
|||||||
is RoomEvent.Reply -> {
|
is RoomEvent.Reply -> {
|
||||||
// TODO - a reply to a reply
|
// TODO - a reply to a reply
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is RoomEvent.Encrypted -> {
|
||||||
|
Text(
|
||||||
|
text = "Encrypted message",
|
||||||
|
color = content.textColor().copy(alpha = 0.8f),
|
||||||
|
fontSize = 14.sp,
|
||||||
|
modifier = Modifier.wrapContentSize(),
|
||||||
|
textAlign = TextAlign.Start,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,6 +613,16 @@ private fun ReplyBubbleContent(content: BubbleContent<RoomEvent.Reply>) {
|
|||||||
is RoomEvent.Reply -> {
|
is RoomEvent.Reply -> {
|
||||||
// TODO - a reply to a reply
|
// TODO - a reply to a reply
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is RoomEvent.Encrypted -> {
|
||||||
|
Text(
|
||||||
|
text = "Encrypted message",
|
||||||
|
color = content.textColor(),
|
||||||
|
fontSize = 15.sp,
|
||||||
|
modifier = Modifier.wrapContentSize(),
|
||||||
|
textAlign = TextAlign.Start,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(2.dp))
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
@ -97,6 +97,7 @@ internal class MessengerViewModel(
|
|||||||
is RoomEvent.Image -> TODO()
|
is RoomEvent.Image -> TODO()
|
||||||
is RoomEvent.Reply -> TODO()
|
is RoomEvent.Reply -> TODO()
|
||||||
is RoomEvent.Message -> it.content
|
is RoomEvent.Message -> it.content
|
||||||
|
is RoomEvent.Encrypted -> error("Should never happen")
|
||||||
},
|
},
|
||||||
eventId = it.eventId,
|
eventId = it.eventId,
|
||||||
timestampUtc = it.utcTimestamp,
|
timestampUtc = it.utcTimestamp,
|
||||||
|
@ -6,19 +6,14 @@ import app.dapk.st.matrix.common.RoomMember
|
|||||||
class RoomEventsToNotifiableMapper {
|
class RoomEventsToNotifiableMapper {
|
||||||
|
|
||||||
fun map(events: List<RoomEvent>): List<Notifiable> {
|
fun map(events: List<RoomEvent>): List<Notifiable> {
|
||||||
return events.map {
|
return events.map { Notifiable(content = it.toNotifiableContent(), it.utcTimestamp, it.author) }
|
||||||
when (it) {
|
|
||||||
is RoomEvent.Image -> Notifiable(content = it.toNotifiableContent(), it.utcTimestamp, it.author)
|
|
||||||
is RoomEvent.Message -> Notifiable(content = it.toNotifiableContent(), it.utcTimestamp, it.author)
|
|
||||||
is RoomEvent.Reply -> Notifiable(content = it.toNotifiableContent(), it.utcTimestamp, it.author)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun RoomEvent.toNotifiableContent(): String = when (this) {
|
private fun RoomEvent.toNotifiableContent(): String = when (this) {
|
||||||
is RoomEvent.Image -> "\uD83D\uDCF7"
|
is RoomEvent.Image -> "\uD83D\uDCF7"
|
||||||
is RoomEvent.Message -> this.content
|
is RoomEvent.Message -> this.content
|
||||||
is RoomEvent.Reply -> this.message.toNotifiableContent()
|
is RoomEvent.Reply -> this.message.toNotifiableContent()
|
||||||
|
is RoomEvent.Encrypted -> "Encrypted message"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ internal class LocalEchoMapper(private val metaMapper: MetaMapper) {
|
|||||||
is RoomEvent.Message -> this.copy(meta = metaMapper.toMeta(echo))
|
is RoomEvent.Message -> this.copy(meta = metaMapper.toMeta(echo))
|
||||||
is RoomEvent.Reply -> this.copy(message = this.message.mergeWith(echo))
|
is RoomEvent.Reply -> this.copy(message = this.message.mergeWith(echo))
|
||||||
is RoomEvent.Image -> this.copy(meta = metaMapper.toMeta(echo))
|
is RoomEvent.Image -> this.copy(meta = metaMapper.toMeta(echo))
|
||||||
|
is RoomEvent.Encrypted -> this.copy(meta = metaMapper.toMeta(echo))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +90,7 @@ fun MatrixRoomEvent.engine(): RoomEvent = when (this) {
|
|||||||
is MatrixRoomEvent.Image -> RoomEvent.Image(this.eventId, this.utcTimestamp, this.imageMeta.engine(), this.author, this.meta.engine(), this.edited)
|
is MatrixRoomEvent.Image -> RoomEvent.Image(this.eventId, this.utcTimestamp, this.imageMeta.engine(), this.author, this.meta.engine(), this.edited)
|
||||||
is MatrixRoomEvent.Message -> RoomEvent.Message(this.eventId, this.utcTimestamp, this.content, this.author, this.meta.engine(), this.edited, this.redacted)
|
is MatrixRoomEvent.Message -> RoomEvent.Message(this.eventId, this.utcTimestamp, this.content, this.author, this.meta.engine(), this.edited, this.redacted)
|
||||||
is MatrixRoomEvent.Reply -> RoomEvent.Reply(this.message.engine(), this.replyingTo.engine())
|
is MatrixRoomEvent.Reply -> RoomEvent.Reply(this.message.engine(), this.replyingTo.engine())
|
||||||
|
is MatrixRoomEvent.Encrypted -> RoomEvent.Encrypted(this.eventId, this.utcTimestamp, this.author, this.meta.engine())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MatrixRoomEvent.Image.ImageMeta.engine() = RoomEvent.Image.ImageMeta(
|
fun MatrixRoomEvent.Image.ImageMeta.engine() = RoomEvent.Image.ImageMeta(
|
||||||
|
@ -77,13 +77,12 @@ interface MessageService : MatrixService {
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Meta(
|
data class Meta(
|
||||||
val height: Int,
|
@SerialName("height") val height: Int,
|
||||||
val width: Int,
|
@SerialName("width") val width: Int,
|
||||||
val size: Long,
|
@SerialName("size") val size: Long,
|
||||||
val fileName: String,
|
@SerialName("file_name") val fileName: String,
|
||||||
val mimeType: String,
|
@SerialName("mime_type") val mimeType: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,18 +24,19 @@ sealed class RoomEvent {
|
|||||||
abstract val utcTimestamp: Long
|
abstract val utcTimestamp: Long
|
||||||
abstract val author: RoomMember
|
abstract val author: RoomMember
|
||||||
abstract val meta: MessageMeta
|
abstract val meta: MessageMeta
|
||||||
|
abstract val redacted: Boolean
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("message")
|
@SerialName("encrypted")
|
||||||
data class Message(
|
data class Encrypted(
|
||||||
@SerialName("event_id") override val eventId: EventId,
|
@SerialName("event_id") override val eventId: EventId,
|
||||||
@SerialName("timestamp") override val utcTimestamp: Long,
|
@SerialName("timestamp") override val utcTimestamp: Long,
|
||||||
@SerialName("content") val content: String,
|
@SerialName("content") val content: String,
|
||||||
@SerialName("author") override val author: RoomMember,
|
@SerialName("author") override val author: RoomMember,
|
||||||
@SerialName("meta") override val meta: MessageMeta,
|
@SerialName("meta") override val meta: MessageMeta,
|
||||||
@SerialName("encrypted_content") val encryptedContent: MegOlmV1? = null,
|
@SerialName("encrypted_content") val encryptedContent: MegOlmV1,
|
||||||
@SerialName("edited") val edited: Boolean = false,
|
@SerialName("edited") val edited: Boolean = false,
|
||||||
@SerialName("redacted") val redacted: Boolean = false,
|
@SerialName("redacted") override val redacted: Boolean = false,
|
||||||
) : RoomEvent() {
|
) : RoomEvent() {
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@ -52,6 +53,24 @@ sealed class RoomEvent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@SerialName("message")
|
||||||
|
data class Message(
|
||||||
|
@SerialName("event_id") override val eventId: EventId,
|
||||||
|
@SerialName("timestamp") override val utcTimestamp: Long,
|
||||||
|
@SerialName("content") val content: String,
|
||||||
|
@SerialName("author") override val author: RoomMember,
|
||||||
|
@SerialName("meta") override val meta: MessageMeta,
|
||||||
|
@SerialName("edited") val edited: Boolean = false,
|
||||||
|
@SerialName("redacted") override val redacted: Boolean = false,
|
||||||
|
) : RoomEvent() {
|
||||||
|
|
||||||
|
val time: String by unsafeLazy {
|
||||||
|
val instant = Instant.ofEpochMilli(utcTimestamp)
|
||||||
|
ZonedDateTime.ofInstant(instant, DEFAULT_ZONE).toLocalTime().format(MESSAGE_TIME_FORMAT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("reply")
|
@SerialName("reply")
|
||||||
data class Reply(
|
data class Reply(
|
||||||
@ -63,6 +82,7 @@ sealed class RoomEvent {
|
|||||||
override val utcTimestamp: Long = message.utcTimestamp
|
override val utcTimestamp: Long = message.utcTimestamp
|
||||||
override val author: RoomMember = message.author
|
override val author: RoomMember = message.author
|
||||||
override val meta: MessageMeta = message.meta
|
override val meta: MessageMeta = message.meta
|
||||||
|
override val redacted: Boolean = message.redacted
|
||||||
|
|
||||||
val replyingToSelf = replyingTo.author == message.author
|
val replyingToSelf = replyingTo.author == message.author
|
||||||
|
|
||||||
@ -80,8 +100,8 @@ sealed class RoomEvent {
|
|||||||
@SerialName("image_meta") val imageMeta: ImageMeta,
|
@SerialName("image_meta") val imageMeta: ImageMeta,
|
||||||
@SerialName("author") override val author: RoomMember,
|
@SerialName("author") override val author: RoomMember,
|
||||||
@SerialName("meta") override val meta: MessageMeta,
|
@SerialName("meta") override val meta: MessageMeta,
|
||||||
@SerialName("encrypted_content") val encryptedContent: Message.MegOlmV1? = null,
|
|
||||||
@SerialName("edited") val edited: Boolean = false,
|
@SerialName("edited") val edited: Boolean = false,
|
||||||
|
@SerialName("redacted") override val redacted: Boolean = false,
|
||||||
) : RoomEvent() {
|
) : RoomEvent() {
|
||||||
|
|
||||||
val time: String by unsafeLazy {
|
val time: String by unsafeLazy {
|
||||||
|
@ -3,6 +3,8 @@ package app.dapk.st.matrix.sync.internal.room
|
|||||||
import app.dapk.st.matrix.common.*
|
import app.dapk.st.matrix.common.*
|
||||||
import app.dapk.st.matrix.sync.RoomEvent
|
import app.dapk.st.matrix.sync.RoomEvent
|
||||||
import app.dapk.st.matrix.sync.internal.request.ApiTimelineEvent
|
import app.dapk.st.matrix.sync.internal.request.ApiTimelineEvent
|
||||||
|
import app.dapk.st.matrix.sync.internal.request.ApiTimelineEvent.TimelineMessage.Content.Image
|
||||||
|
import app.dapk.st.matrix.sync.internal.request.ApiTimelineEvent.TimelineMessage.Content.Text
|
||||||
import app.dapk.st.matrix.sync.internal.request.DecryptedContent
|
import app.dapk.st.matrix.sync.internal.request.DecryptedContent
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
@ -17,56 +19,60 @@ internal class RoomEventsDecrypter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun decryptEvent(event: RoomEvent, userCredentials: UserCredentials): RoomEvent = when (event) {
|
private suspend fun decryptEvent(event: RoomEvent, userCredentials: UserCredentials): RoomEvent = when (event) {
|
||||||
is RoomEvent.Message -> event.decrypt()
|
is RoomEvent.Encrypted -> event.decrypt(userCredentials)
|
||||||
|
is RoomEvent.Message -> event
|
||||||
is RoomEvent.Reply -> RoomEvent.Reply(
|
is RoomEvent.Reply -> RoomEvent.Reply(
|
||||||
message = decryptEvent(event.message, userCredentials),
|
message = decryptEvent(event.message, userCredentials),
|
||||||
replyingTo = decryptEvent(event.replyingTo, userCredentials),
|
replyingTo = decryptEvent(event.replyingTo, userCredentials),
|
||||||
)
|
)
|
||||||
is RoomEvent.Image -> event.decrypt(userCredentials)
|
|
||||||
|
is RoomEvent.Image -> event
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun RoomEvent.Image.decrypt(userCredentials: UserCredentials) = when (this.encryptedContent) {
|
private suspend fun RoomEvent.Encrypted.decrypt(userCredentials: UserCredentials) = when (val result = this.decryptContent()) {
|
||||||
null -> this
|
is DecryptionResult.Failed -> this.also { logger.crypto("Failed to decrypt ${it.eventId}") }
|
||||||
else -> when (val result = messageDecrypter.decrypt(this.encryptedContent.toModel())) {
|
is DecryptionResult.Success -> when (val model = result.payload.toModel()) {
|
||||||
is DecryptionResult.Failed -> this.also { logger.crypto("Failed to decrypt ${it.eventId}") }
|
DecryptedContent.Ignored -> this
|
||||||
is DecryptionResult.Success -> when (val model = result.payload.toModel()) {
|
is DecryptedContent.TimelineText -> when (val content = model.content) {
|
||||||
DecryptedContent.Ignored -> this
|
ApiTimelineEvent.TimelineMessage.Content.Ignored -> this
|
||||||
is DecryptedContent.TimelineText -> {
|
is Image -> createImageEvent(content, userCredentials)
|
||||||
val content = model.content as ApiTimelineEvent.TimelineMessage.Content.Image
|
is Text -> createMessageEvent(content)
|
||||||
this.copy(
|
|
||||||
imageMeta = RoomEvent.Image.ImageMeta(
|
|
||||||
width = content.info?.width,
|
|
||||||
height = content.info?.height,
|
|
||||||
url = content.file?.url?.convertMxUrToUrl(userCredentials.homeServer) ?: content.url!!.convertMxUrToUrl(userCredentials.homeServer),
|
|
||||||
keys = content.file?.let { RoomEvent.Image.ImageMeta.Keys(it.key.k, it.iv, it.v, it.hashes) }
|
|
||||||
),
|
|
||||||
encryptedContent = null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun RoomEvent.Message.decrypt() = when (this.encryptedContent) {
|
private suspend fun RoomEvent.Encrypted.decryptContent() = messageDecrypter.decrypt(this.encryptedContent.toModel())
|
||||||
null -> this
|
|
||||||
else -> when (val result = messageDecrypter.decrypt(this.encryptedContent.toModel())) {
|
private fun RoomEvent.Encrypted.createMessageEvent(content: Text) = RoomEvent.Message(
|
||||||
is DecryptionResult.Failed -> this.also { logger.crypto("Failed to decrypt ${it.eventId}") }
|
eventId = this.eventId,
|
||||||
is DecryptionResult.Success -> when (val model = result.payload.toModel()) {
|
utcTimestamp = this.utcTimestamp,
|
||||||
DecryptedContent.Ignored -> this
|
author = this.author,
|
||||||
is DecryptedContent.TimelineText -> this.copyWithDecryptedContent(model)
|
meta = this.meta,
|
||||||
}
|
edited = this.edited,
|
||||||
}
|
redacted = this.redacted,
|
||||||
}
|
content = content.body ?: ""
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun RoomEvent.Encrypted.createImageEvent(content: Image, userCredentials: UserCredentials) = RoomEvent.Image(
|
||||||
|
eventId = this.eventId,
|
||||||
|
utcTimestamp = this.utcTimestamp,
|
||||||
|
author = this.author,
|
||||||
|
meta = this.meta,
|
||||||
|
edited = this.edited,
|
||||||
|
redacted = this.redacted,
|
||||||
|
imageMeta = RoomEvent.Image.ImageMeta(
|
||||||
|
width = content.info?.width,
|
||||||
|
height = content.info?.height,
|
||||||
|
url = content.file?.url?.convertMxUrToUrl(userCredentials.homeServer) ?: content.url!!.convertMxUrToUrl(userCredentials.homeServer),
|
||||||
|
keys = content.file?.let { RoomEvent.Image.ImageMeta.Keys(it.key.k, it.iv, it.v, it.hashes) }
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
private fun JsonString.toModel() = json.decodeFromString(DecryptedContent.serializer(), this.value)
|
private fun JsonString.toModel() = json.decodeFromString(DecryptedContent.serializer(), this.value)
|
||||||
|
|
||||||
private fun RoomEvent.Message.copyWithDecryptedContent(decryptedContent: DecryptedContent.TimelineText) = this.copy(
|
|
||||||
content = (decryptedContent.content as ApiTimelineEvent.TimelineMessage.Content.Text).body ?: "",
|
|
||||||
encryptedContent = null
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun RoomEvent.Message.MegOlmV1.toModel() = EncryptedMessageContent.MegOlmV1(
|
private fun RoomEvent.Encrypted.MegOlmV1.toModel() = EncryptedMessageContent.MegOlmV1(
|
||||||
this.cipherText,
|
this.cipherText,
|
||||||
this.deviceId,
|
this.deviceId,
|
||||||
this.senderKey,
|
this.senderKey,
|
||||||
|
@ -51,11 +51,7 @@ class RoomDataSource(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun RoomEvent.redact() = when (this) {
|
private fun RoomEvent.redact() = RoomEvent.Message(this.eventId, this.utcTimestamp, "Redacted", this.author, this.meta, redacted = true)
|
||||||
is RoomEvent.Image -> RoomEvent.Message(this.eventId, this.utcTimestamp, "Redacted", this.author, this.meta, redacted = true)
|
|
||||||
is RoomEvent.Message -> RoomEvent.Message(this.eventId, this.utcTimestamp, "Redacted", this.author, this.meta, redacted = true)
|
|
||||||
is RoomEvent.Reply -> RoomEvent.Message(this.eventId, this.utcTimestamp, "Redacted", this.author, this.meta, redacted = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun RoomState.replaceEvent(old: RoomEvent, new: RoomEvent): RoomState {
|
private fun RoomState.replaceEvent(old: RoomEvent, new: RoomEvent): RoomState {
|
||||||
val updatedEvents = this.events.toMutableList().apply {
|
val updatedEvents = this.events.toMutableList().apply {
|
||||||
|
@ -24,13 +24,13 @@ internal class RoomEventCreator(
|
|||||||
suspend fun ApiTimelineEvent.Encrypted.toRoomEvent(roomId: RoomId): RoomEvent? {
|
suspend fun ApiTimelineEvent.Encrypted.toRoomEvent(roomId: RoomId): RoomEvent? {
|
||||||
return when (this.encryptedContent) {
|
return when (this.encryptedContent) {
|
||||||
is ApiEncryptedContent.MegOlmV1 -> {
|
is ApiEncryptedContent.MegOlmV1 -> {
|
||||||
RoomEvent.Message(
|
RoomEvent.Encrypted(
|
||||||
eventId = this.eventId,
|
eventId = this.eventId,
|
||||||
author = roomMembersService.find(roomId, this.senderId)!!,
|
author = roomMembersService.find(roomId, this.senderId)!!,
|
||||||
utcTimestamp = this.utcTimestamp,
|
utcTimestamp = this.utcTimestamp,
|
||||||
meta = MessageMeta.FromServer,
|
meta = MessageMeta.FromServer,
|
||||||
content = "Encrypted message",
|
content = "Encrypted message",
|
||||||
encryptedContent = RoomEvent.Message.MegOlmV1(
|
encryptedContent = RoomEvent.Encrypted.MegOlmV1(
|
||||||
this.encryptedContent.cipherText,
|
this.encryptedContent.cipherText,
|
||||||
this.encryptedContent.deviceId,
|
this.encryptedContent.deviceId,
|
||||||
this.encryptedContent.senderKey,
|
this.encryptedContent.senderKey,
|
||||||
@ -38,6 +38,7 @@ internal class RoomEventCreator(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is ApiEncryptedContent.OlmV1 -> errorTracker.nullAndTrack(IllegalStateException("unexpected encryption, got OlmV1 for a room event"))
|
is ApiEncryptedContent.OlmV1 -> errorTracker.nullAndTrack(IllegalStateException("unexpected encryption, got OlmV1 for a room event"))
|
||||||
ApiEncryptedContent.Unknown -> errorTracker.nullAndTrack(IllegalStateException("unknown room event encryption"))
|
ApiEncryptedContent.Unknown -> errorTracker.nullAndTrack(IllegalStateException("unknown room event encryption"))
|
||||||
}
|
}
|
||||||
@ -79,6 +80,7 @@ internal class TimelineEventMapper(
|
|||||||
is RoomEvent.Message -> relationEvent
|
is RoomEvent.Message -> relationEvent
|
||||||
is RoomEvent.Reply -> relationEvent.message
|
is RoomEvent.Reply -> relationEvent.message
|
||||||
is RoomEvent.Image -> relationEvent
|
is RoomEvent.Image -> relationEvent
|
||||||
|
is RoomEvent.Encrypted -> relationEvent
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -110,12 +112,19 @@ internal class TimelineEventMapper(
|
|||||||
is RoomEvent.Image -> original.message
|
is RoomEvent.Image -> original.message
|
||||||
is RoomEvent.Message -> original.message.edited(incomingEdit)
|
is RoomEvent.Message -> original.message.edited(incomingEdit)
|
||||||
is RoomEvent.Reply -> original.message
|
is RoomEvent.Reply -> original.message
|
||||||
|
is RoomEvent.Encrypted -> original.message
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
is RoomEvent.Image -> {
|
is RoomEvent.Image -> {
|
||||||
// can't edit images
|
// can't edit images
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is RoomEvent.Encrypted -> {
|
||||||
|
// can't edit encrypted messages
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,11 +136,13 @@ internal class TimelineEventMapper(
|
|||||||
utcTimestamp = incomingEdit.utcTimestamp,
|
utcTimestamp = incomingEdit.utcTimestamp,
|
||||||
edited = true,
|
edited = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
is ApiTimelineEvent.TimelineMessage.Content.Text -> original.toTextMessage(
|
is ApiTimelineEvent.TimelineMessage.Content.Text -> original.toTextMessage(
|
||||||
utcTimestamp = incomingEdit.utcTimestamp,
|
utcTimestamp = incomingEdit.utcTimestamp,
|
||||||
content = incomingEdit.asTextContent().body?.removePrefix(" * ")?.trim() ?: "redacted",
|
content = incomingEdit.asTextContent().body?.removePrefix(" * ")?.trim() ?: "redacted",
|
||||||
edited = true,
|
edited = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
ApiTimelineEvent.TimelineMessage.Content.Ignored -> null
|
ApiTimelineEvent.TimelineMessage.Content.Ignored -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,4 +81,5 @@ private fun RoomEvent.toTextContent(): String = when (this) {
|
|||||||
is RoomEvent.Image -> "\uD83D\uDCF7"
|
is RoomEvent.Image -> "\uD83D\uDCF7"
|
||||||
is RoomEvent.Message -> this.content
|
is RoomEvent.Message -> this.content
|
||||||
is RoomEvent.Reply -> this.message.toTextContent()
|
is RoomEvent.Reply -> this.message.toTextContent()
|
||||||
|
is RoomEvent.Encrypted -> "Encrypted message"
|
||||||
}
|
}
|
@ -43,6 +43,7 @@ internal class UnreadEventsProcessor(
|
|||||||
is RoomEvent.Message -> it.author.id == selfId
|
is RoomEvent.Message -> it.author.id == selfId
|
||||||
is RoomEvent.Reply -> it.message.author.id == selfId
|
is RoomEvent.Reply -> it.message.author.id == selfId
|
||||||
is RoomEvent.Image -> it.author.id == selfId
|
is RoomEvent.Image -> it.author.id == selfId
|
||||||
|
is RoomEvent.Encrypted -> it.author.id == selfId
|
||||||
}
|
}
|
||||||
}.map { it.eventId }
|
}.map { it.eventId }
|
||||||
roomStore.insertUnread(overview.roomId, eventsFromOthers)
|
roomStore.insertUnread(overview.roomId, eventsFromOthers)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user