Merge remote-tracking branch 'origin/develop' into feature/fre/start_chat_search_matrixid
This commit is contained in:
commit
0cd8c3f93c
86 changed files with 1443 additions and 273 deletions
|
|
@ -80,9 +80,9 @@ import io.element.android.libraries.designsystem.theme.components.Text
|
|||
import io.element.android.libraries.designsystem.theme.components.TextField
|
||||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||
import io.element.android.libraries.designsystem.theme.components.onTabOrEnterKeyFocusNext
|
||||
import io.element.android.libraries.matrix.api.auth.AuthenticationException
|
||||
import io.element.android.libraries.testtags.TestTags
|
||||
import io.element.android.libraries.testtags.testTag
|
||||
import org.matrix.rustcomponents.sdk.AuthenticationException
|
||||
import io.element.android.libraries.ui.strings.R as StringR
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalTextApi::class)
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
package io.element.android.features.login.impl.error
|
||||
|
||||
import io.element.android.libraries.matrix.api.auth.AuthErrorCode
|
||||
import io.element.android.libraries.matrix.api.auth.AuthenticationException
|
||||
import io.element.android.libraries.matrix.api.auth.errorCode
|
||||
import org.matrix.rustcomponents.sdk.AuthenticationException
|
||||
import io.element.android.libraries.ui.strings.R.string as StringR
|
||||
|
||||
fun loginError(
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import io.element.android.features.login.impl.util.LoginConstants
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.core.data.tryOrNull
|
||||
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.api.auth.MatrixHomeServerDetails
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
|
@ -71,15 +70,14 @@ class LoginRootPresenter @Inject constructor(private val authenticationService:
|
|||
private fun CoroutineScope.submit(homeserver: String, formState: LoginFormState, loggedInState: MutableState<LoggedInState>) = launch {
|
||||
loggedInState.value = LoggedInState.LoggingIn
|
||||
//TODO rework the setHomeserver flow
|
||||
tryOrNull {
|
||||
authenticationService.setHomeserver(homeserver)
|
||||
}
|
||||
try {
|
||||
val sessionId = authenticationService.login(formState.login.trim(), formState.password.trim())
|
||||
loggedInState.value = LoggedInState.LoggedIn(sessionId)
|
||||
} catch (failure: Throwable) {
|
||||
loggedInState.value = LoggedInState.ErrorLoggingIn(failure)
|
||||
}
|
||||
authenticationService.setHomeserver(homeserver)
|
||||
authenticationService.login(formState.login.trim(), formState.password)
|
||||
.onSuccess { sessionId ->
|
||||
loggedInState.value = LoggedInState.LoggedIn(sessionId)
|
||||
}
|
||||
.onFailure { failure ->
|
||||
loggedInState.value = LoggedInState.ErrorLoggingIn(failure)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateFormState(formState: MutableState<LoginFormState>, updateLambda: LoginFormState.() -> LoginFormState) {
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@
|
|||
package io.element.android.features.login.impl.error
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.matrix.api.auth.AuthenticationException
|
||||
import io.element.android.libraries.ui.strings.R
|
||||
import org.junit.Test
|
||||
import org.matrix.rustcomponents.sdk.AuthenticationException
|
||||
|
||||
class ErrorFormatterTests {
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextContent
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -81,7 +82,7 @@ internal fun aTimelineItemEvent(
|
|||
return TimelineItem.Event(
|
||||
id = randomId,
|
||||
eventId = EventId(randomId),
|
||||
senderId = "@senderId",
|
||||
senderId = UserId("@senderId"),
|
||||
senderAvatar = AvatarData("@senderId", "sender"),
|
||||
content = content,
|
||||
reactionsState = TimelineItemReactions(
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import org.matrix.rustcomponents.sdk.EncryptedMessage
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
|
||||
|
||||
@Composable
|
||||
fun TimelineItemEncryptedView(
|
||||
|
|
@ -53,7 +53,7 @@ internal fun TimelineItemEncryptedViewDarkPreview() =
|
|||
private fun ContentToPreview() {
|
||||
TimelineItemEncryptedView(
|
||||
content = TimelineItemEncryptedContent(
|
||||
encryptedMessage = EncryptedMessage.Unknown,
|
||||
data = UnableToDecryptContent.Data.Unknown
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,20 @@
|
|||
package io.element.android.features.messages.impl.timeline.factories.event
|
||||
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import org.matrix.rustcomponents.sdk.TimelineItemContentKind
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseMessageLikeContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseStateContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileChangeContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.StateContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.StickerContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.UnknownContent
|
||||
import javax.inject.Inject
|
||||
|
||||
typealias RustTimelineItemContent = org.matrix.rustcomponents.sdk.TimelineItemContent
|
||||
|
||||
class TimelineItemContentFactory @Inject constructor(
|
||||
private val messageFactory: TimelineItemContentMessageFactory,
|
||||
private val redactedMessageFactory: TimelineItemContentRedactedFactory,
|
||||
|
|
@ -34,17 +43,18 @@ class TimelineItemContentFactory @Inject constructor(
|
|||
private val failedToParseStateFactory: TimelineItemContentFailedToParseStateFactory
|
||||
) {
|
||||
|
||||
fun create(itemContent: RustTimelineItemContent): TimelineItemEventContent {
|
||||
return when (val kind = itemContent.kind()) {
|
||||
is TimelineItemContentKind.Message -> messageFactory.create(itemContent.asMessage())
|
||||
is TimelineItemContentKind.RedactedMessage -> redactedMessageFactory.create(kind)
|
||||
is TimelineItemContentKind.Sticker -> stickerFactory.create(kind)
|
||||
is TimelineItemContentKind.UnableToDecrypt -> utdFactory.create(kind)
|
||||
is TimelineItemContentKind.RoomMembership -> roomMembershipFactory.create(kind)
|
||||
is TimelineItemContentKind.ProfileChange -> profileChangeFactory.create(kind)
|
||||
is TimelineItemContentKind.State -> stateFactory.create(kind)
|
||||
is TimelineItemContentKind.FailedToParseMessageLike -> failedToParseMessageFactory.create(kind)
|
||||
is TimelineItemContentKind.FailedToParseState -> failedToParseStateFactory.create(kind)
|
||||
fun create(itemContent: EventContent): TimelineItemEventContent {
|
||||
return when (itemContent) {
|
||||
is FailedToParseMessageLikeContent -> failedToParseMessageFactory.create(itemContent)
|
||||
is FailedToParseStateContent -> failedToParseStateFactory.create(itemContent)
|
||||
is MessageContent -> messageFactory.create(itemContent)
|
||||
is ProfileChangeContent -> profileChangeFactory.create(itemContent)
|
||||
is RedactedContent -> redactedMessageFactory.create(itemContent)
|
||||
is RoomMembershipContent -> roomMembershipFactory.create(itemContent)
|
||||
is StateContent -> stateFactory.create(itemContent)
|
||||
is StickerContent -> stickerFactory.create(itemContent)
|
||||
is UnableToDecryptContent -> utdFactory.create(itemContent)
|
||||
is UnknownContent -> TimelineItemUnknownContent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ package io.element.android.features.messages.impl.timeline.factories.event
|
|||
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
|
||||
import org.matrix.rustcomponents.sdk.TimelineItemContentKind
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseMessageLikeContent
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemContentFailedToParseMessageFactory @Inject constructor() {
|
||||
|
||||
fun create(kind: TimelineItemContentKind.FailedToParseMessageLike): TimelineItemEventContent {
|
||||
fun create(failedToParseMessageLike: FailedToParseMessageLikeContent): TimelineItemEventContent {
|
||||
return TimelineItemUnknownContent
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ package io.element.android.features.messages.impl.timeline.factories.event
|
|||
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
|
||||
import org.matrix.rustcomponents.sdk.TimelineItemContentKind
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseStateContent
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemContentFailedToParseStateFactory @Inject constructor() {
|
||||
|
||||
fun create(kind: TimelineItemContentKind.FailedToParseState): TimelineItemEventContent {
|
||||
fun create(failedToParseState: FailedToParseStateContent): TimelineItemEventContent {
|
||||
return TimelineItemUnknownContent
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,43 +24,46 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
|
||||
import io.element.android.features.messages.impl.timeline.util.toHtmlDocument
|
||||
import io.element.android.libraries.matrix.api.media.MediaResolver
|
||||
import org.matrix.rustcomponents.sdk.Message
|
||||
import org.matrix.rustcomponents.sdk.MessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.ImageMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.NoticeMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemContentMessageFactory @Inject constructor() {
|
||||
|
||||
fun create(contentAsMessage: Message?): TimelineItemEventContent {
|
||||
return when (val messageType = contentAsMessage?.msgtype()) {
|
||||
is MessageType.Emote -> TimelineItemEmoteContent(
|
||||
body = messageType.content.body,
|
||||
htmlDocument = messageType.content.formatted?.toHtmlDocument()
|
||||
fun create(content: MessageContent): TimelineItemEventContent {
|
||||
return when (val messageType = content.type) {
|
||||
is EmoteMessageType -> TimelineItemEmoteContent(
|
||||
body = messageType.body,
|
||||
htmlDocument = messageType.formatted?.toHtmlDocument()
|
||||
)
|
||||
is MessageType.Image -> {
|
||||
val height = messageType.content.info?.height?.toFloat()
|
||||
val width = messageType.content.info?.width?.toFloat()
|
||||
is ImageMessageType -> {
|
||||
val height = messageType.info?.height?.toFloat()
|
||||
val width = messageType.info?.width?.toFloat()
|
||||
val aspectRatio = if (height != null && width != null) {
|
||||
width / height
|
||||
} else {
|
||||
0.7f
|
||||
}
|
||||
TimelineItemImageContent(
|
||||
body = messageType.content.body,
|
||||
body = messageType.body,
|
||||
imageMeta = MediaResolver.Meta(
|
||||
source = messageType.content.source,
|
||||
url = messageType.url,
|
||||
kind = MediaResolver.Kind.Content
|
||||
),
|
||||
blurhash = messageType.content.info?.blurhash,
|
||||
blurhash = messageType.info?.blurhash,
|
||||
aspectRatio = aspectRatio
|
||||
)
|
||||
}
|
||||
is MessageType.Notice -> TimelineItemNoticeContent(
|
||||
body = messageType.content.body,
|
||||
htmlDocument = messageType.content.formatted?.toHtmlDocument()
|
||||
is NoticeMessageType -> TimelineItemNoticeContent(
|
||||
body = messageType.body,
|
||||
htmlDocument = messageType.formatted?.toHtmlDocument()
|
||||
)
|
||||
is MessageType.Text -> TimelineItemTextContent(
|
||||
body = messageType.content.body,
|
||||
htmlDocument = messageType.content.formatted?.toHtmlDocument()
|
||||
is TextMessageType -> TimelineItemTextContent(
|
||||
body = messageType.body,
|
||||
htmlDocument = messageType.formatted?.toHtmlDocument()
|
||||
)
|
||||
else -> TimelineItemUnknownContent
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ package io.element.android.features.messages.impl.timeline.factories.event
|
|||
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
|
||||
import org.matrix.rustcomponents.sdk.TimelineItemContentKind
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileChangeContent
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemContentProfileChangeFactory @Inject constructor() {
|
||||
|
||||
fun create(kind: TimelineItemContentKind.ProfileChange): TimelineItemEventContent {
|
||||
fun create(content: ProfileChangeContent): TimelineItemEventContent {
|
||||
return TimelineItemUnknownContent
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ package io.element.android.features.messages.impl.timeline.factories.event
|
|||
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent
|
||||
import org.matrix.rustcomponents.sdk.TimelineItemContentKind
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemContentRedactedFactory @Inject constructor() {
|
||||
|
||||
fun create(kind: TimelineItemContentKind.RedactedMessage): TimelineItemEventContent {
|
||||
fun create(content: RedactedContent): TimelineItemEventContent {
|
||||
return TimelineItemRedactedContent
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ package io.element.android.features.messages.impl.timeline.factories.event
|
|||
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
|
||||
import org.matrix.rustcomponents.sdk.TimelineItemContentKind
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemContentRoomMembershipFactory @Inject constructor() {
|
||||
|
||||
fun create(kind: TimelineItemContentKind.RoomMembership): TimelineItemEventContent {
|
||||
fun create(content: RoomMembershipContent): TimelineItemEventContent {
|
||||
return TimelineItemUnknownContent
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ package io.element.android.features.messages.impl.timeline.factories.event
|
|||
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
|
||||
import org.matrix.rustcomponents.sdk.TimelineItemContentKind
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.StateContent
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemContentStateFactory @Inject constructor() {
|
||||
|
||||
fun create(kind: TimelineItemContentKind.State): TimelineItemEventContent {
|
||||
fun create(content: StateContent): TimelineItemEventContent {
|
||||
return TimelineItemUnknownContent
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ package io.element.android.features.messages.impl.timeline.factories.event
|
|||
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
|
||||
import org.matrix.rustcomponents.sdk.TimelineItemContentKind
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.StickerContent
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemContentStickerFactory @Inject constructor() {
|
||||
|
||||
fun create(kind: TimelineItemContentKind.Sticker): TimelineItemEventContent {
|
||||
fun create(content: StickerContent): TimelineItemEventContent {
|
||||
return TimelineItemUnknownContent
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@
|
|||
|
||||
package io.element.android.features.messages.impl.timeline.factories.event
|
||||
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent
|
||||
import org.matrix.rustcomponents.sdk.TimelineItemContentKind
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemContentUTDFactory @Inject constructor() {
|
||||
|
||||
fun create(kind: TimelineItemContentKind.UnableToDecrypt): TimelineItemEventContent {
|
||||
return TimelineItemEncryptedContent(kind.msg)
|
||||
fun create(content: UnableToDecryptContent): TimelineItemEventContent {
|
||||
return TimelineItemEncryptedContent(content.data)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItemReac
|
|||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import org.matrix.rustcomponents.sdk.ProfileTimelineDetails
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemEventFactory @Inject constructor(
|
||||
|
|
@ -36,13 +36,13 @@ class TimelineItemEventFactory @Inject constructor(
|
|||
index: Int,
|
||||
timelineItems: List<MatrixTimelineItem>,
|
||||
): TimelineItem.Event {
|
||||
val currentSender = currentTimelineItem.event.sender()
|
||||
val currentSender = currentTimelineItem.event.sender
|
||||
val groupPosition =
|
||||
computeGroupPosition(currentTimelineItem, timelineItems, index)
|
||||
val senderDisplayName: String?
|
||||
val senderAvatarUrl: String?
|
||||
|
||||
when (val senderProfile = currentTimelineItem.event.senderProfile()) {
|
||||
when (val senderProfile = currentTimelineItem.event.senderProfile) {
|
||||
ProfileTimelineDetails.Unavailable,
|
||||
ProfileTimelineDetails.Pending,
|
||||
is ProfileTimelineDetails.Error -> {
|
||||
|
|
@ -56,8 +56,8 @@ class TimelineItemEventFactory @Inject constructor(
|
|||
}
|
||||
|
||||
val senderAvatarData = AvatarData(
|
||||
id = currentSender,
|
||||
name = senderDisplayName ?: currentSender,
|
||||
id = currentSender.value,
|
||||
name = senderDisplayName ?: currentSender.value,
|
||||
url = senderAvatarUrl,
|
||||
size = AvatarSize.SMALL
|
||||
)
|
||||
|
|
@ -67,15 +67,15 @@ class TimelineItemEventFactory @Inject constructor(
|
|||
senderId = currentSender,
|
||||
senderDisplayName = senderDisplayName,
|
||||
senderAvatar = senderAvatarData,
|
||||
content = contentFactory.create(currentTimelineItem.event.content()),
|
||||
isMine = currentTimelineItem.event.isOwn(),
|
||||
content = contentFactory.create(currentTimelineItem.event.content),
|
||||
isMine = currentTimelineItem.event.isOwn,
|
||||
groupPosition = groupPosition,
|
||||
reactionsState = currentTimelineItem.computeReactionsState()
|
||||
)
|
||||
}
|
||||
|
||||
private fun MatrixTimelineItem.Event.computeReactionsState(): TimelineItemReactions {
|
||||
val aggregatedReactions = event.reactions().orEmpty().map {
|
||||
val aggregatedReactions = event.reactions.map {
|
||||
AggregatedReaction(key = it.key, count = it.count.toString(), isHighlighted = false)
|
||||
}
|
||||
return TimelineItemReactions(aggregatedReactions.toImmutableList())
|
||||
|
|
@ -90,9 +90,9 @@ class TimelineItemEventFactory @Inject constructor(
|
|||
timelineItems.getOrNull(index - 1) as? MatrixTimelineItem.Event
|
||||
val nextTimelineItem =
|
||||
timelineItems.getOrNull(index + 1) as? MatrixTimelineItem.Event
|
||||
val currentSender = currentTimelineItem.event.sender()
|
||||
val previousSender = prevTimelineItem?.event?.sender()
|
||||
val nextSender = nextTimelineItem?.event?.sender()
|
||||
val currentSender = currentTimelineItem.event.sender
|
||||
val previousSender = prevTimelineItem?.event?.sender
|
||||
val nextSender = nextTimelineItem?.event?.sender
|
||||
|
||||
return when {
|
||||
previousSender != currentSender && nextSender == currentSender -> TimelineItemGroupPosition.First
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@ package io.element.android.features.messages.impl.timeline.factories.virtual
|
|||
import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemDaySeparatorModel
|
||||
import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemVirtualModel
|
||||
import io.element.android.libraries.dateformatter.api.DaySeparatorFormatter
|
||||
import org.matrix.rustcomponents.sdk.VirtualTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemDaySeparatorFactory @Inject constructor(private val daySeparatorFormatter: DaySeparatorFormatter) {
|
||||
|
||||
fun create(virtualItem: VirtualTimelineItem.DayDivider): TimelineItemVirtualModel {
|
||||
val formattedDate = daySeparatorFormatter.format(virtualItem.ts.toLong())
|
||||
val formattedDate = daySeparatorFormatter.format(virtualItem.timestamp)
|
||||
return TimelineItemDaySeparatorModel(
|
||||
formattedDate = formattedDate
|
||||
)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import io.element.android.features.messages.impl.timeline.model.virtual.Timeline
|
|||
import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemUnknownVirtualModel
|
||||
import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemVirtualModel
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import org.matrix.rustcomponents.sdk.VirtualTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemVirtualFactory @Inject constructor(
|
||||
|
|
|
|||
|
|
@ -21,11 +21,12 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemVirtualModel
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
|
||||
@Immutable
|
||||
sealed interface TimelineItem {
|
||||
|
||||
fun identifier(): String = when(this){
|
||||
fun identifier(): String = when (this) {
|
||||
is Event -> id
|
||||
is Virtual -> id
|
||||
}
|
||||
|
|
@ -40,7 +41,7 @@ sealed interface TimelineItem {
|
|||
data class Event(
|
||||
val id: String,
|
||||
val eventId: EventId? = null,
|
||||
val senderId: String,
|
||||
val senderId: UserId,
|
||||
val senderDisplayName: String?,
|
||||
val senderAvatar: AvatarData,
|
||||
val content: TimelineItemEventContent,
|
||||
|
|
@ -52,6 +53,6 @@ sealed interface TimelineItem {
|
|||
|
||||
val showSenderInformation = groupPosition.isNew() && !isMine
|
||||
|
||||
val safeSenderName: String = senderDisplayName ?: senderId
|
||||
val safeSenderName: String = senderDisplayName ?: senderId.value
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
package io.element.android.features.messages.impl.timeline.model.event
|
||||
|
||||
import org.matrix.rustcomponents.sdk.EncryptedMessage
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
|
||||
|
||||
data class TimelineItemEncryptedContent(
|
||||
val encryptedMessage: EncryptedMessage
|
||||
val data: UnableToDecryptContent.Data
|
||||
) : TimelineItemEventContent
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
package io.element.android.features.messages.impl.timeline.model.event
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
|
||||
import org.jsoup.Jsoup
|
||||
import org.matrix.rustcomponents.sdk.EncryptedMessage
|
||||
|
||||
class TimelineItemEventContentProvider : PreviewParameterProvider<TimelineItemEventContent> {
|
||||
override val values = sequenceOf(
|
||||
|
|
@ -49,7 +49,7 @@ fun aTimelineItemEmoteContent() = TimelineItemEmoteContent(
|
|||
)
|
||||
|
||||
fun aTimelineItemEncryptedContent() = TimelineItemEncryptedContent(
|
||||
encryptedMessage = EncryptedMessage.Unknown
|
||||
data = UnableToDecryptContent.Data.Unknown
|
||||
)
|
||||
|
||||
fun aTimelineItemNoticeContent() = TimelineItemNoticeContent(
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ open class TimelineItemImageContentProvider : PreviewParameterProvider<TimelineI
|
|||
|
||||
fun aTimelineItemImageContent() = TimelineItemImageContent(
|
||||
body = "a body",
|
||||
imageMeta = MediaResolver.Meta(source = null, kind = MediaResolver.Kind.Content),
|
||||
imageMeta = MediaResolver.Meta(url = null, kind = MediaResolver.Kind.Content),
|
||||
blurhash = null,
|
||||
aspectRatio = 0.5f,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@
|
|||
|
||||
package io.element.android.features.messages.impl.timeline.util
|
||||
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.FormattedBody
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageFormat
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import org.matrix.rustcomponents.sdk.FormattedBody
|
||||
import org.matrix.rustcomponents.sdk.MessageFormat
|
||||
|
||||
fun FormattedBody.toHtmlDocument(): Document? {
|
||||
return takeIf { it.format == MessageFormat.HTML }?.body?.let { formattedBody ->
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ private fun aMessageEvent(
|
|||
) = TimelineItem.Event(
|
||||
id = AN_EVENT_ID.value,
|
||||
eventId = AN_EVENT_ID,
|
||||
senderId = A_USER_ID.value,
|
||||
senderId = A_USER_ID,
|
||||
senderDisplayName = A_USER_NAME,
|
||||
senderAvatar = AvatarData(A_USER_ID.value, A_USER_NAME),
|
||||
content = content,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ internal fun aMessageEvent(
|
|||
) = TimelineItem.Event(
|
||||
id = AN_EVENT_ID.value,
|
||||
eventId = AN_EVENT_ID,
|
||||
senderId = A_USER_ID.value,
|
||||
senderId = A_USER_ID,
|
||||
senderDisplayName = A_USER_NAME,
|
||||
senderAvatar = AvatarData(A_USER_ID.value, A_USER_NAME),
|
||||
content = content,
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class RoomListPresenter @Inject constructor(
|
|||
}
|
||||
var filter by rememberSaveable { mutableStateOf("") }
|
||||
val roomSummaries by client
|
||||
.roomSummaryDataSource()
|
||||
.roomSummaryDataSource
|
||||
.roomSummaries()
|
||||
.collectAsState()
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ class RoomListPresenter @Inject constructor(
|
|||
// Safe to give bigger size than room list
|
||||
val extendedRangeEnd = range.last + midExtendedRangeSize
|
||||
val extendedRange = IntRange(extendedRangeStart, extendedRangeEnd)
|
||||
client.roomSummaryDataSource().setSlidingSyncRange(extendedRange)
|
||||
client.roomSummaryDataSource.setSlidingSyncRange(extendedRange)
|
||||
}
|
||||
|
||||
private suspend fun mapRoomSummaries(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue