Hide sender info in direct rooms, and add a timeline preview for DM (#1979)

This commit is contained in:
Benoit Marty
2023-12-08 11:33:51 +01:00
parent 92101ab602
commit ed65933e80
13 changed files with 128 additions and 12 deletions

1
changelog.d/1979.misc Normal file
View File

@@ -0,0 +1 @@
Hide sender info in direct rooms

View File

@@ -178,6 +178,9 @@ class TimelinePresenter @AssistedInject constructor(
}
return TimelineState(
timelineRoomInfo = TimelineRoomInfo(
isDirect = room.isDirect
),
highlightedEventId = highlightedEventId.value,
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
paginationState = paginationState,

View File

@@ -27,6 +27,7 @@ import kotlinx.collections.immutable.ImmutableList
@Immutable
data class TimelineState(
val timelineItems: ImmutableList<TimelineItem>,
val timelineRoomInfo: TimelineRoomInfo,
val showReadReceipts: Boolean,
val highlightedEventId: EventId?,
val userHasPermissionToSendMessage: Boolean,
@@ -35,3 +36,8 @@ data class TimelineState(
val sessionState: SessionState,
val eventSink: (TimelineEvents) -> Unit
)
@Immutable
data class TimelineRoomInfo(
val isDirect: Boolean,
)

View File

@@ -47,6 +47,7 @@ import kotlin.random.Random
fun aTimelineState(timelineItems: ImmutableList<TimelineItem> = persistentListOf()) = TimelineState(
timelineItems = timelineItems,
timelineRoomInfo = aTimelineRoomInfo(),
showReadReceipts = false,
paginationState = MatrixTimeline.PaginationState(
isBackPaginating = false,
@@ -212,3 +213,9 @@ internal fun aGroupedEvents(id: Long = 0): TimelineItem.GroupedEvents {
aggregatedReadReceipts = events.flatMap { it.readReceiptState.receipts }.toImmutableList(),
)
}
internal fun aTimelineRoomInfo(
isDirect: Boolean = false,
) = TimelineRoomInfo(
isDirect = isDirect,
)

View File

@@ -118,6 +118,7 @@ fun TimelineView(
) { timelineItem ->
TimelineItemRow(
timelineItem = timelineItem,
timelineRoomInfo = state.timelineRoomInfo,
showReadReceipts = state.showReadReceipts,
isLastOutgoingMessage = (timelineItem as? TimelineItem.Event)?.isMine == true
&& state.timelineItems.first().identifier() == timelineItem.identifier(),

View File

@@ -17,17 +17,21 @@
package io.element.android.features.messages.impl.timeline.components
import androidx.compose.runtime.Composable
import io.element.android.features.messages.impl.timeline.TimelineRoomInfo
import io.element.android.features.messages.impl.timeline.aTimelineRoomInfo
import io.element.android.features.messages.impl.timeline.model.TimelineItem
// For previews
@Composable
internal fun ATimelineItemEventRow(
event: TimelineItem.Event,
timelineRoomInfo: TimelineRoomInfo = aTimelineRoomInfo(),
showReadReceipts: Boolean = false,
isLastOutgoingMessage: Boolean = false,
isHighlighted: Boolean = false,
) = TimelineItemEventRow(
event = event,
timelineRoomInfo = timelineRoomInfo,
showReadReceipts = showReadReceipts,
isLastOutgoingMessage = isLastOutgoingMessage,
isHighlighted = isHighlighted,

View File

@@ -35,17 +35,17 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.features.messages.impl.timeline.model.TimelineItemGroupPosition
import io.element.android.features.messages.impl.timeline.model.bubble.BubbleState
import io.element.android.features.messages.impl.timeline.model.bubble.BubbleStateProvider
import io.element.android.libraries.core.extensions.to01
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Surface
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.messageFromMeBackground
import io.element.android.libraries.designsystem.theme.messageFromOtherBackground
import io.element.android.compound.theme.ElementTheme
private val BUBBLE_RADIUS = 12.dp
private val BUBBLE_INCOMING_OFFSET = 16.dp
@@ -91,10 +91,10 @@ fun MessageEventBubble(
}
fun Modifier.offsetForItem(): Modifier {
return if (state.isMine) {
this
} else {
offset(x = BUBBLE_INCOMING_OFFSET)
return when {
state.isMine -> this
state.timelineRoomInfo.isDirect -> this
else -> offset(x = BUBBLE_INCOMING_OFFSET)
}
}

View File

@@ -60,6 +60,7 @@ import androidx.compose.ui.zIndex
import androidx.constraintlayout.compose.ConstrainScope
import androidx.constraintlayout.compose.ConstraintLayout
import io.element.android.compound.theme.ElementTheme
import io.element.android.features.messages.impl.timeline.TimelineRoomInfo
import io.element.android.features.messages.impl.timeline.TimelineEvents
import io.element.android.features.messages.impl.timeline.aTimelineItemEvent
import io.element.android.features.messages.impl.timeline.components.event.TimelineItemEventContentView
@@ -101,6 +102,7 @@ import kotlin.math.roundToInt
@Composable
fun TimelineItemEventRow(
event: TimelineItem.Event,
timelineRoomInfo: TimelineRoomInfo,
showReadReceipts: Boolean,
isLastOutgoingMessage: Boolean,
isHighlighted: Boolean,
@@ -164,6 +166,7 @@ fun TimelineItemEventRow(
),
event = event,
isHighlighted = isHighlighted,
timelineRoomInfo = timelineRoomInfo,
interactionSource = interactionSource,
onClick = onClick,
onLongClick = onLongClick,
@@ -181,6 +184,7 @@ fun TimelineItemEventRow(
TimelineItemEventRowContent(
event = event,
isHighlighted = isHighlighted,
timelineRoomInfo = timelineRoomInfo,
interactionSource = interactionSource,
onClick = onClick,
onLongClick = onLongClick,
@@ -234,6 +238,7 @@ private fun SwipeSensitivity(
private fun TimelineItemEventRowContent(
event: TimelineItem.Event,
isHighlighted: Boolean,
timelineRoomInfo: TimelineRoomInfo,
interactionSource: MutableInteractionSource,
onClick: () -> Unit,
onLongClick: () -> Unit,
@@ -265,7 +270,7 @@ private fun TimelineItemEventRowContent(
// Sender
val avatarStrokeSize = 3.dp
if (event.showSenderInformation) {
if (event.showSenderInformation && !timelineRoomInfo.isDirect) {
MessageSenderInformation(
event.safeSenderName,
event.senderAvatar,
@@ -285,6 +290,7 @@ private fun TimelineItemEventRowContent(
groupPosition = event.groupPosition,
isMine = event.isMine,
isHighlighted = isHighlighted,
timelineRoomInfo = timelineRoomInfo,
)
MessageEventBubble(
modifier = Modifier

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.features.messages.impl.timeline.components
import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
import io.element.android.features.messages.impl.timeline.aTimelineItemEvent
import io.element.android.features.messages.impl.timeline.aTimelineRoomInfo
import io.element.android.features.messages.impl.timeline.model.TimelineItemGroupPosition
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@PreviewsDayNight
@Composable
internal fun TimelineItemEventRowForDirectRoomPreview() = ElementPreview {
Column {
sequenceOf(false, true).forEach {
ATimelineItemEventRow(
event = aTimelineItemEvent(
isMine = it,
content = aTimelineItemTextContent().copy(
body = "A long text which will be displayed on several lines and" +
" hopefully can be manually adjusted to test different behaviors."
),
groupPosition = TimelineItemGroupPosition.First,
),
timelineRoomInfo = aTimelineRoomInfo(
isDirect = true,
),
)
ATimelineItemEventRow(
event = aTimelineItemEvent(
isMine = it,
content = aTimelineItemImageContent().copy(
aspectRatio = 5f
),
groupPosition = TimelineItemGroupPosition.Last,
),
timelineRoomInfo = aTimelineRoomInfo(
isDirect = true,
),
)
}
}
}

View File

@@ -24,8 +24,10 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.pluralStringResource
import io.element.android.features.messages.impl.R
import io.element.android.features.messages.impl.timeline.TimelineRoomInfo
import io.element.android.features.messages.impl.timeline.TimelineEvents
import io.element.android.features.messages.impl.timeline.aGroupedEvents
import io.element.android.features.messages.impl.timeline.aTimelineRoomInfo
import io.element.android.features.messages.impl.timeline.components.group.GroupHeaderView
import io.element.android.features.messages.impl.timeline.components.receipt.ReadReceiptViewState
import io.element.android.features.messages.impl.timeline.components.receipt.TimelineItemReadReceiptView
@@ -40,6 +42,7 @@ import io.element.android.libraries.matrix.api.core.UserId
@Composable
fun TimelineItemGroupedEventsRow(
timelineItem: TimelineItem.GroupedEvents,
timelineRoomInfo: TimelineRoomInfo,
showReadReceipts: Boolean,
isLastOutgoingMessage: Boolean,
highlightedItem: String?,
@@ -66,6 +69,7 @@ fun TimelineItemGroupedEventsRow(
isExpanded = isExpanded.value,
onExpandGroupClick = ::onExpandGroupClick,
timelineItem = timelineItem,
timelineRoomInfo = timelineRoomInfo,
highlightedItem = highlightedItem,
showReadReceipts = showReadReceipts,
isLastOutgoingMessage = isLastOutgoingMessage,
@@ -89,6 +93,7 @@ private fun TimelineItemGroupedEventsRowContent(
isExpanded: Boolean,
onExpandGroupClick: () -> Unit,
timelineItem: TimelineItem.GroupedEvents,
timelineRoomInfo: TimelineRoomInfo,
highlightedItem: String?,
showReadReceipts: Boolean,
isLastOutgoingMessage: Boolean,
@@ -121,6 +126,7 @@ private fun TimelineItemGroupedEventsRowContent(
timelineItem.events.forEach { subGroupEvent ->
TimelineItemRow(
timelineItem = subGroupEvent,
timelineRoomInfo = timelineRoomInfo,
showReadReceipts = showReadReceipts,
isLastOutgoingMessage = isLastOutgoingMessage,
highlightedItem = highlightedItem,
@@ -161,6 +167,7 @@ internal fun TimelineItemGroupedEventsRowContentExpandedPreview() = ElementPrevi
isExpanded = true,
onExpandGroupClick = {},
timelineItem = aGroupedEvents(),
timelineRoomInfo = aTimelineRoomInfo(),
highlightedItem = null,
showReadReceipts = true,
isLastOutgoingMessage = false,
@@ -185,6 +192,7 @@ internal fun TimelineItemGroupedEventsRowContentCollapsePreview() = ElementPrevi
isExpanded = false,
onExpandGroupClick = {},
timelineItem = aGroupedEvents(),
timelineRoomInfo = aTimelineRoomInfo(),
highlightedItem = null,
showReadReceipts = true,
isLastOutgoingMessage = false,

View File

@@ -18,6 +18,7 @@ package io.element.android.features.messages.impl.timeline.components
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import io.element.android.features.messages.impl.timeline.TimelineRoomInfo
import io.element.android.features.messages.impl.timeline.TimelineEvents
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent
@@ -29,6 +30,7 @@ import io.element.android.libraries.matrix.api.core.UserId
@Composable
internal fun TimelineItemRow(
timelineItem: TimelineItem,
timelineRoomInfo: TimelineRoomInfo,
showReadReceipts: Boolean,
isLastOutgoingMessage: Boolean,
highlightedItem: String?,
@@ -71,6 +73,7 @@ internal fun TimelineItemRow(
} else {
TimelineItemEventRow(
event = timelineItem,
timelineRoomInfo = timelineRoomInfo,
showReadReceipts = showReadReceipts,
isLastOutgoingMessage = isLastOutgoingMessage,
isHighlighted = highlightedItem == timelineItem.identifier(),
@@ -93,6 +96,7 @@ internal fun TimelineItemRow(
is TimelineItem.GroupedEvents -> {
TimelineItemGroupedEventsRow(
timelineItem = timelineItem,
timelineRoomInfo = timelineRoomInfo,
showReadReceipts = showReadReceipts,
isLastOutgoingMessage = isLastOutgoingMessage,
highlightedItem = highlightedItem,

View File

@@ -16,10 +16,12 @@
package io.element.android.features.messages.impl.timeline.model.bubble
import io.element.android.features.messages.impl.timeline.TimelineRoomInfo
import io.element.android.features.messages.impl.timeline.model.TimelineItemGroupPosition
data class BubbleState(
val groupPosition: TimelineItemGroupPosition,
val isMine: Boolean,
val isHighlighted: Boolean,
val timelineRoomInfo: TimelineRoomInfo,
)

View File

@@ -17,6 +17,8 @@
package io.element.android.features.messages.impl.timeline.model.bubble
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.messages.impl.timeline.TimelineRoomInfo
import io.element.android.features.messages.impl.timeline.aTimelineRoomInfo
import io.element.android.features.messages.impl.timeline.model.TimelineItemGroupPosition
open class BubbleStateProvider : PreviewParameterProvider<BubbleState> {
@@ -29,7 +31,11 @@ open class BubbleStateProvider : PreviewParameterProvider<BubbleState> {
).map { groupPosition ->
sequenceOf(false, true).map { isMine ->
sequenceOf(false, true).map { isHighlighted ->
BubbleState(groupPosition, isMine = isMine, isHighlighted = isHighlighted)
aBubbleState(
groupPosition = groupPosition,
isMine = isMine,
isHighlighted = isHighlighted,
)
}
}
.flatten()
@@ -37,8 +43,14 @@ open class BubbleStateProvider : PreviewParameterProvider<BubbleState> {
.flatten()
}
fun aBubbleState() = BubbleState(
groupPosition = TimelineItemGroupPosition.First,
isMine = false,
isHighlighted = false,
internal fun aBubbleState(
groupPosition: TimelineItemGroupPosition = TimelineItemGroupPosition.First,
isMine: Boolean = false,
isHighlighted: Boolean = false,
timelineRoomInfo: TimelineRoomInfo = aTimelineRoomInfo(),
) = BubbleState(
groupPosition = groupPosition,
isMine = isMine,
isHighlighted = isHighlighted,
timelineRoomInfo = timelineRoomInfo,
)