From 09cca9ab2678b1d051421045113a919f6f6ce425 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Dec 2023 11:33:51 +0100 Subject: [PATCH] Hide sender info in direct rooms, and add a timeline preview for DM (#1979) --- changelog.d/1979.misc | 1 + .../impl/timeline/TimelinePresenter.kt | 3 + .../messages/impl/timeline/TimelineState.kt | 6 ++ .../impl/timeline/TimelineStateProvider.kt | 7 +++ .../messages/impl/timeline/TimelineView.kt | 1 + .../components/ATimelineItemEventRow.kt | 4 ++ .../timeline/components/MessageEventBubble.kt | 12 ++-- .../components/TimelineItemEventRow.kt | 8 ++- ...imelineItemEventRowForDirectRoomPreview.kt | 62 +++++++++++++++++++ .../TimelineItemGroupedEventsRow.kt | 8 +++ .../timeline/components/TimelineItemRow.kt | 4 ++ .../impl/timeline/model/bubble/BubbleState.kt | 2 + .../model/bubble/BubbleStateProvider.kt | 22 +++++-- 13 files changed, 128 insertions(+), 12 deletions(-) create mode 100644 changelog.d/1979.misc create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRowForDirectRoomPreview.kt diff --git a/changelog.d/1979.misc b/changelog.d/1979.misc new file mode 100644 index 0000000000..623a422481 --- /dev/null +++ b/changelog.d/1979.misc @@ -0,0 +1 @@ +Hide sender info in direct rooms diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index a2e9858d9f..9d000b18e0 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -178,6 +178,9 @@ class TimelinePresenter @AssistedInject constructor( } return TimelineState( + timelineRoomInfo = TimelineRoomInfo( + isDirect = room.isDirect + ), highlightedEventId = highlightedEventId.value, userHasPermissionToSendMessage = userHasPermissionToSendMessage, paginationState = paginationState, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt index 36fa6d33d2..d334aebf8c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt @@ -27,6 +27,7 @@ import kotlinx.collections.immutable.ImmutableList @Immutable data class TimelineState( val timelineItems: ImmutableList, + 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, +) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt index 8616ecbc8f..63d8f0ed01 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt @@ -47,6 +47,7 @@ import kotlin.random.Random fun aTimelineState(timelineItems: ImmutableList = 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, +) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt index 44f8fce876..bc285b0bc5 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt @@ -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(), diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt index 6cd28c7f94..a2a0ae5f4e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt @@ -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, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt index a395f963dc..5132aa5621 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt @@ -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) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index 0a76523016..efacd350a6 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -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 diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRowForDirectRoomPreview.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRowForDirectRoomPreview.kt new file mode 100644 index 0000000000..4443c00f3d --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRowForDirectRoomPreview.kt @@ -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, + ), + ) + } + } +} + diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt index b09581016e..d52795c052 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt @@ -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, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt index f77319259b..92dbbe46b6 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt @@ -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, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleState.kt index 1912aac668..4f1fc3c546 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleState.kt @@ -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, ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleStateProvider.kt index fbcbcc5454..9c50a73a6b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleStateProvider.kt @@ -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 { @@ -29,7 +31,11 @@ open class BubbleStateProvider : PreviewParameterProvider { ).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 { .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, )