From b824f5857062babb2303c5f912d678784ba4ca0d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 28 Nov 2023 11:45:28 +0100 Subject: [PATCH] Create Composable TimelineItemGroupedEventRow and extract to its own dedicated file. --- .../messages/impl/timeline/TimelineView.kt | 71 ++++---------- .../components/TimelineItemGroupedEventRow.kt | 97 +++++++++++++++++++ 2 files changed, 117 insertions(+), 51 deletions(-) create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventRow.kt 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 99274a6b7b..c2530156c7 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 @@ -20,13 +20,11 @@ package io.element.android.features.messages.impl.timeline import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.ExperimentalAnimationApi -import androidx.compose.animation.animateContentSize import androidx.compose.animation.core.tween import androidx.compose.animation.scaleIn import androidx.compose.animation.scaleOut import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding @@ -42,26 +40,22 @@ import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.rotate import androidx.compose.ui.platform.LocalInspectionMode -import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons -import io.element.android.features.messages.impl.R import io.element.android.features.messages.impl.timeline.components.TimelineItemEventRow +import io.element.android.features.messages.impl.timeline.components.TimelineItemGroupedEventRow import io.element.android.features.messages.impl.timeline.components.TimelineItemStateEventRow import io.element.android.features.messages.impl.timeline.components.TimelineItemVirtualRow -import io.element.android.features.messages.impl.timeline.components.group.GroupHeaderView import io.element.android.features.messages.impl.timeline.components.virtual.TimelineItemRoomBeginningView import io.element.android.features.messages.impl.timeline.components.virtual.TimelineLoadingMoreIndicator import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPresenterFactories @@ -174,7 +168,7 @@ fun TimelineView( } @Composable -private fun TimelineItemRow( +fun TimelineItemRow( timelineItem: TimelineItem, showReadReceipts: Boolean, isLastOutgoingMessage: Boolean, @@ -235,49 +229,24 @@ private fun TimelineItemRow( } } is TimelineItem.GroupedEvents -> { - val isExpanded = rememberSaveable(key = timelineItem.identifier()) { mutableStateOf(false) } - - fun onExpandGroupClick() { - isExpanded.value = !isExpanded.value - } - - Column(modifier = modifier.animateContentSize()) { - GroupHeaderView( - text = pluralStringResource( - id = R.plurals.room_timeline_state_changes, - count = timelineItem.events.size, - timelineItem.events.size - ), - isExpanded = isExpanded.value, - isHighlighted = !isExpanded.value && timelineItem.events.any { it.identifier() == highlightedItem }, - onClick = ::onExpandGroupClick, - ) - if (isExpanded.value) { - Column { - timelineItem.events.forEach { subGroupEvent -> - TimelineItemRow( - timelineItem = subGroupEvent, - showReadReceipts = showReadReceipts, - isLastOutgoingMessage = isLastOutgoingMessage, - highlightedItem = highlightedItem, - sessionState = sessionState, - userHasPermissionToSendMessage = false, - onClick = onClick, - onLongClick = onLongClick, - inReplyToClick = inReplyToClick, - onUserDataClick = onUserDataClick, - onTimestampClicked = onTimestampClicked, - onReactionClick = onReactionClick, - onReactionLongClick = onReactionLongClick, - onMoreReactionsClick = onMoreReactionsClick, - onReadReceiptClick = onReadReceiptClick, - eventSink = eventSink, - onSwipeToReply = {}, - ) - } - } - } - } + TimelineItemGroupedEventRow( + timelineItem = timelineItem, + showReadReceipts = showReadReceipts, + isLastOutgoingMessage = isLastOutgoingMessage, + highlightedItem = highlightedItem, + sessionState = sessionState, + onClick = onClick, + onLongClick = onLongClick, + inReplyToClick = inReplyToClick, + onUserDataClick = onUserDataClick, + onTimestampClicked = onTimestampClicked, + onReactionClick = onReactionClick, + onReactionLongClick = onReactionLongClick, + onMoreReactionsClick = onMoreReactionsClick, + onReadReceiptClick = onReadReceiptClick, + eventSink = eventSink, + modifier = modifier, + ) } } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventRow.kt new file mode 100644 index 0000000000..9b45a7d51a --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventRow.kt @@ -0,0 +1,97 @@ +/* + * 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.animation.animateContentSize +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +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.TimelineEvents +import io.element.android.features.messages.impl.timeline.TimelineItemRow +import io.element.android.features.messages.impl.timeline.components.group.GroupHeaderView +import io.element.android.features.messages.impl.timeline.model.TimelineItem +import io.element.android.features.messages.impl.timeline.session.SessionState +import io.element.android.libraries.matrix.api.core.EventId +import io.element.android.libraries.matrix.api.core.UserId + +@Composable +fun TimelineItemGroupedEventRow( + timelineItem: TimelineItem.GroupedEvents, + showReadReceipts: Boolean, + isLastOutgoingMessage: Boolean, + highlightedItem: String?, + sessionState: SessionState, + onClick: (TimelineItem.Event) -> Unit, + onLongClick: (TimelineItem.Event) -> Unit, + inReplyToClick: (EventId) -> Unit, + onUserDataClick: (UserId) -> Unit, + onTimestampClicked: (TimelineItem.Event) -> Unit, + onReactionClick: (key: String, TimelineItem.Event) -> Unit, + onReactionLongClick: (key: String, TimelineItem.Event) -> Unit, + onMoreReactionsClick: (TimelineItem.Event) -> Unit, + onReadReceiptClick: (TimelineItem.Event) -> Unit, + eventSink: (TimelineEvents) -> Unit, + modifier: Modifier = Modifier +) { + val isExpanded = rememberSaveable(key = timelineItem.identifier()) { mutableStateOf(false) } + + fun onExpandGroupClick() { + isExpanded.value = !isExpanded.value + } + + Column(modifier = modifier.animateContentSize()) { + GroupHeaderView( + text = pluralStringResource( + id = R.plurals.room_timeline_state_changes, + count = timelineItem.events.size, + timelineItem.events.size + ), + isExpanded = isExpanded.value, + isHighlighted = !isExpanded.value && timelineItem.events.any { it.identifier() == highlightedItem }, + onClick = ::onExpandGroupClick, + ) + if (isExpanded.value) { + Column { + timelineItem.events.forEach { subGroupEvent -> + TimelineItemRow( + timelineItem = subGroupEvent, + showReadReceipts = showReadReceipts, + isLastOutgoingMessage = isLastOutgoingMessage, + highlightedItem = highlightedItem, + sessionState = sessionState, + userHasPermissionToSendMessage = false, + onClick = onClick, + onLongClick = onLongClick, + inReplyToClick = inReplyToClick, + onUserDataClick = onUserDataClick, + onTimestampClicked = onTimestampClicked, + onReactionClick = onReactionClick, + onReactionLongClick = onReactionLongClick, + onMoreReactionsClick = onMoreReactionsClick, + onReadReceiptClick = onReadReceiptClick, + eventSink = eventSink, + onSwipeToReply = {}, + ) + } + } + } + } +}