This commit is contained in:
bxdxnn
2026-08-24 20:04:47 +00:00
476 changed files with 945 additions and 831 deletions
@@ -132,7 +132,7 @@ data class AttachmentThumbnailInfo(
@PreviewsDayNight
@Composable
internal fun AttachmentThumbnailPreview(@PreviewParameter(AttachmentThumbnailInfoProvider::class) data: AttachmentThumbnailInfo) = ElementPreview {
internal fun AttachmentThumbnailPreview(@PreviewParameter(AttachmentThumbnailInfoPreviewParam::class) data: AttachmentThumbnailInfo) = ElementPreview {
AttachmentThumbnail(
info = data,
modifier = Modifier
@@ -11,7 +11,7 @@ package io.element.android.libraries.matrix.ui.components
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.matrix.api.media.MediaSource
open class AttachmentThumbnailInfoProvider : PreviewParameterProvider<AttachmentThumbnailInfo> {
open class AttachmentThumbnailInfoPreviewParam : PreviewParameterProvider<AttachmentThumbnailInfo> {
override val values: Sequence<AttachmentThumbnailInfo>
get() = sequenceOf(
anAttachmentThumbnailInfo(type = AttachmentThumbnailType.Image),
@@ -158,7 +158,7 @@ fun CreateDmConfirmationBottomSheet(
@Composable
internal fun CreateDmConfirmationBottomSheetPreview(
@PreviewParameter(
CreateDmConfirmationBottomSheetStateProvider::class
CreateDmConfirmationBottomSheetStatePreviewParam::class
) state: CreateDmConfirmationBottomSheetState
) = ElementPreview(fillMaxSize = true) {
CreateDmConfirmationBottomSheet(
@@ -174,7 +174,7 @@ data class CreateDmConfirmationBottomSheetState(
val isUserIdentityUnknown: Boolean,
)
class CreateDmConfirmationBottomSheetStateProvider : PreviewParameterProvider<CreateDmConfirmationBottomSheetState> {
class CreateDmConfirmationBottomSheetStatePreviewParam : PreviewParameterProvider<CreateDmConfirmationBottomSheetState> {
override val values = sequenceOf(
CreateDmConfirmationBottomSheetState(matrixUser = aMatrixUser(), isUserIdentityUnknown = false),
CreateDmConfirmationBottomSheetState(matrixUser = aMatrixUser(), isUserIdentityUnknown = true),
@@ -79,6 +79,6 @@ fun MatrixUserHeader(
@PreviewsDayNight
@Composable
internal fun MatrixUserHeaderPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) = ElementPreview {
internal fun MatrixUserHeaderPreview(@PreviewParameter(MatrixUserPreviewParam::class) matrixUser: MatrixUser) = ElementPreview {
MatrixUserHeader(matrixUser)
}
@@ -24,7 +24,7 @@ import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.user.DisplayedStatus
import io.element.android.libraries.matrix.api.user.MatrixUser
open class MatrixUserProvider : PreviewParameterProvider<MatrixUser> {
open class MatrixUserPreviewParam : PreviewParameterProvider<MatrixUser> {
override val values: Sequence<MatrixUser>
get() = sequenceOf(
aMatrixUser(),
@@ -33,7 +33,7 @@ open class MatrixUserProvider : PreviewParameterProvider<MatrixUser> {
)
}
open class MatrixUserWithAvatarProvider : PreviewParameterProvider<MatrixUser?> {
open class MatrixUserWithAvatarPreviewParam : PreviewParameterProvider<MatrixUser?> {
override val values: Sequence<MatrixUser?>
get() = sequenceOf(
aMatrixUser(displayName = USER_NAME_JOHN_DOE),
@@ -46,6 +46,6 @@ fun MatrixUserRow(
@PreviewsDayNight
@Composable
internal fun MatrixUserRowPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) = ElementPreview {
internal fun MatrixUserRowPreview(@PreviewParameter(MatrixUserPreviewParam::class) matrixUser: MatrixUser) = ElementPreview {
MatrixUserRow(matrixUser)
}
@@ -16,7 +16,7 @@ import io.element.android.libraries.matrix.ui.model.SelectRoomInfo
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
class SelectRoomInfoProvider : PreviewParameterProvider<SelectRoomInfo> {
class SelectRoomInfoPreviewParam : PreviewParameterProvider<SelectRoomInfo> {
override val values: Sequence<SelectRoomInfo>
get() = sequenceOf(
aSelectRoomInfo(roomId = RoomId("!room1:domain")),
@@ -51,7 +51,7 @@ fun SelectedRoom(
@PreviewsDayNight
@Composable
internal fun SelectedRoomPreview(
@PreviewParameter(SelectRoomInfoProvider::class) roomInfo: SelectRoomInfo
@PreviewParameter(SelectRoomInfoPreviewParam::class) roomInfo: SelectRoomInfo
) = ElementPreview {
SelectedRoom(
roomInfo = roomInfo,
@@ -62,7 +62,7 @@ internal fun SelectedRoomPreview(
@PreviewsDayNight
@Composable
internal fun SelectedRoomRtlPreview(
@PreviewParameter(SelectRoomInfoProvider::class) roomInfo: SelectRoomInfo
@PreviewParameter(SelectRoomInfoPreviewParam::class) roomInfo: SelectRoomInfo
) = CompositionLocalProvider(
LocalLayoutDirection provides LayoutDirection.Rtl,
) {
@@ -44,7 +44,7 @@ fun SelectedUser(
@PreviewsDayNight
@Composable
internal fun SelectedUserPreview(@PreviewParameter(MatrixUserWithAvatarProvider::class) user: MatrixUser) = ElementPreview {
internal fun SelectedUserPreview(@PreviewParameter(MatrixUserWithAvatarPreviewParam::class) user: MatrixUser) = ElementPreview {
SelectedUser(
matrixUser = user,
canRemove = true,
@@ -210,7 +210,7 @@ private fun SpaceRoomItemScaffold(
@Composable
@PreviewsDayNight
internal fun SpaceRoomItemViewPreview(@PreviewParameter(SpaceRoomProvider::class) spaceRoom: SpaceRoom) = ElementPreview {
internal fun SpaceRoomItemViewPreview(@PreviewParameter(SpaceRoomPreviewParam::class) spaceRoom: SpaceRoom) = ElementPreview {
SpaceRoomItemView(
spaceRoom = spaceRoom,
showUnreadIndicator = spaceRoom.state == CurrentUserMembership.INVITED,
@@ -17,7 +17,7 @@ import io.element.android.libraries.matrix.api.room.RoomType
import io.element.android.libraries.matrix.api.spaces.SpaceRoom
import io.element.android.libraries.previewutils.room.aSpaceRoom
class SpaceRoomProvider : PreviewParameterProvider<SpaceRoom> {
class SpaceRoomPreviewParam : PreviewParameterProvider<SpaceRoom> {
override val values: Sequence<SpaceRoom> = sequenceOf(
aSpaceRoom(
roomType = RoomType.Room,
@@ -32,10 +32,11 @@ import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageTy
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType
import io.element.android.libraries.matrix.api.timeline.item.event.VoiceMessageType
import io.element.android.libraries.matrix.api.user.DisplayedStatus
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentMapOf
open class InReplyToDetailsProvider : PreviewParameterProvider<InReplyToDetails> {
open class InReplyToDetailsPreviewParam : PreviewParameterProvider<InReplyToDetails> {
override val values: Sequence<InReplyToDetails>
get() = sequenceOf(
aMessageContent(
@@ -99,7 +100,7 @@ open class InReplyToDetailsProvider : PreviewParameterProvider<InReplyToDetails>
}
}
class InReplyToDetailsDisambiguatedProvider : InReplyToDetailsProvider() {
class InReplyToDetailsDisambiguatedPreviewParam : InReplyToDetailsPreviewParam() {
override val values: Sequence<InReplyToDetails>
get() = sequenceOf(
aMessageContent(
@@ -114,7 +115,7 @@ class InReplyToDetailsDisambiguatedProvider : InReplyToDetailsProvider() {
}
}
class InReplyToDetailsInformativeProvider : InReplyToDetailsProvider() {
class InReplyToDetailsInformativePreviewParam : InReplyToDetailsPreviewParam() {
override val values: Sequence<InReplyToDetails>
get() = sequenceOf(
RedactedContent(threadInfo = null),
@@ -126,7 +127,7 @@ class InReplyToDetailsInformativeProvider : InReplyToDetailsProvider() {
}
}
class InReplyToDetailsOtherProvider : InReplyToDetailsProvider() {
class InReplyToDetailsOtherPreviewParam : InReplyToDetailsPreviewParam() {
override val values: Sequence<InReplyToDetails>
get() = sequenceOf(
InReplyToDetails.Loading(eventId = EventId("\$anEventId")),
@@ -163,9 +164,10 @@ fun aProfileDetailsReady(
displayName: String? = USER_NAME_SENDER,
displayNameAmbiguous: Boolean = false,
avatarUrl: String? = null,
displayedStatus: DisplayedStatus? = null
) = ProfileDetails.Ready(
displayName = displayName,
displayNameAmbiguous = displayNameAmbiguous,
avatarUrl = avatarUrl,
displayedStatus = null,
displayedStatus = displayedStatus,
)
@@ -236,7 +236,7 @@ private fun ReplyToNotFoundContent(
@PreviewsDayNight
@Composable
internal fun InReplyToViewPreview(@PreviewParameter(provider = InReplyToDetailsProvider::class) inReplyTo: InReplyToDetails) = ElementPreview {
internal fun InReplyToViewPreview(@PreviewParameter(provider = InReplyToDetailsPreviewParam::class) inReplyTo: InReplyToDetails) = ElementPreview {
InReplyToView(
inReplyTo = inReplyTo,
hideImage = false,
@@ -9,12 +9,15 @@
package io.element.android.libraries.matrix.ui.messages.sender
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
@@ -24,7 +27,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails
import io.element.android.libraries.matrix.ui.model.toText
import io.element.android.libraries.matrix.ui.model.toEmojiText
// https://www.figma.com/file/Ni6Ii8YKtmXCKYNE90cC67/Timeline-(new)?type=design&node-id=917-80169&mode=design&t=A0CJCBbMqR8NOwUQ-0
@Composable
@@ -61,7 +64,7 @@ fun SenderName(
modifier = Modifier
.clipToBounds()
.alignByBaseline(),
text = userStatus.toText(),
text = userStatus.toEmojiText(),
style = ElementTheme.typography.fontBodyMdMedium,
color = ElementTheme.colors.textSecondary,
maxLines = 1,
@@ -134,11 +137,29 @@ private fun RowScope.SecondaryText(
@PreviewsDayNight
@Composable
internal fun SenderNamePreview(
@PreviewParameter(SenderNameDataProvider::class) senderNameData: SenderNameData,
@PreviewParameter(SenderNameDataPreviewParam::class) senderNameData: SenderNameData,
) = ElementPreview {
SenderName(
senderId = senderNameData.userId,
senderProfile = senderNameData.profileDetails,
senderNameMode = senderNameData.senderNameMode,
)
Column(
modifier = Modifier.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
sequenceOf(
SenderNameMode.Timeline(mainColor = Color.Red),
SenderNameMode.Reply,
SenderNameMode.ActionList,
).forEach { mode ->
Column {
Text(
"Rendering in mode ${mode::class.simpleName}:",
style = ElementTheme.typography.fontBodyXsRegular,
color = ElementTheme.colors.textSecondary,
)
SenderName(
senderId = senderNameData.userId,
senderProfile = senderNameData.profileDetails,
senderNameMode = mode,
)
}
}
}
}
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2024, 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.ui.messages.sender
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails
import io.element.android.libraries.matrix.api.user.DisplayedStatus
import io.element.android.libraries.matrix.api.user.UserStatus
import io.element.android.libraries.matrix.ui.messages.reply.aProfileDetailsReady
data class SenderNameData(
val userId: UserId,
val profileDetails: ProfileDetails,
)
open class SenderNameDataPreviewParam : PreviewParameterProvider<SenderNameData> {
override val values: Sequence<SenderNameData>
get() = sequenceOf(
aSenderNameData(),
aSenderNameData(
displayNameAmbiguous = true,
),
aSenderNameData(
profileDetails = ProfileDetails.Unavailable,
),
aSenderNameData(
displayName = null,
),
aSenderNameData(
displayedStatus = DisplayedStatus.UserSet(
status = UserStatus(
emoji = "😀",
text = "Should not be rendered",
),
),
),
aSenderNameData(
displayedStatus = DisplayedStatus.InCall(0L),
),
aSenderNameData(
displayNameAmbiguous = true,
displayedStatus = DisplayedStatus.UserSet(
status = UserStatus(
emoji = "😀",
text = "Should not be rendered",
),
),
),
)
}
private fun aSenderNameData(
userId: UserId = UserId("@alice:example.com"),
displayName: String? = "Alice",
displayNameAmbiguous: Boolean = false,
displayedStatus: DisplayedStatus? = null,
profileDetails: ProfileDetails = aProfileDetailsReady(
displayName = displayName,
displayNameAmbiguous = displayNameAmbiguous,
displayedStatus = displayedStatus,
)
) = SenderNameData(
userId = userId,
profileDetails = profileDetails,
)
@@ -1,61 +0,0 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2024, 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.ui.messages.sender
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails
import io.element.android.libraries.matrix.api.user.DisplayedStatus
data class SenderNameData(
val userId: UserId,
val profileDetails: ProfileDetails,
val senderNameMode: SenderNameMode,
)
open class SenderNameDataProvider : PreviewParameterProvider<SenderNameData> {
override val values: Sequence<SenderNameData>
get() = sequenceOf(
SenderNameMode.Timeline(mainColor = Color.Red),
SenderNameMode.Reply,
SenderNameMode.ActionList,
)
.flatMap { senderNameMode ->
sequenceOf(
aSenderNameData(
senderNameMode = senderNameMode,
),
aSenderNameData(
senderNameMode = senderNameMode,
displayNameAmbiguous = true,
),
SenderNameData(
senderNameMode = senderNameMode,
userId = UserId("@alice:${senderNameMode.javaClass.simpleName.lowercase()}"),
profileDetails = ProfileDetails.Unavailable,
),
)
}
}
private fun aSenderNameData(
senderNameMode: SenderNameMode,
displayNameAmbiguous: Boolean = false,
displayedStatus: DisplayedStatus? = null,
) = SenderNameData(
userId = UserId("@alice:${senderNameMode.javaClass.simpleName.lowercase()}"),
profileDetails = ProfileDetails.Ready(
displayName = "Alice ${senderNameMode.javaClass.simpleName}",
displayNameAmbiguous = displayNameAmbiguous,
avatarUrl = null,
displayedStatus = displayedStatus,
),
senderNameMode = senderNameMode,
)
@@ -30,7 +30,7 @@ sealed interface LoadingRoomState {
data class Loaded(val room: JoinedRoom) : LoadingRoomState
}
open class LoadingRoomStateProvider : PreviewParameterProvider<LoadingRoomState> {
open class LoadingRoomStatePreviewParam : PreviewParameterProvider<LoadingRoomState> {
override val values: Sequence<LoadingRoomState>
get() = sequenceOf(
LoadingRoomState.Loading,