Create Composable TimelineItemGroupedEventRow and extract to its own dedicated file.
This commit is contained in:
parent
062cba7a25
commit
c24925b716
2 changed files with 117 additions and 51 deletions
|
|
@ -20,13 +20,11 @@ package io.element.android.features.messages.impl.timeline
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
import androidx.compose.animation.animateContentSize
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.scaleIn
|
import androidx.compose.animation.scaleIn
|
||||||
import androidx.compose.animation.scaleOut
|
import androidx.compose.animation.scaleOut
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.BoxScope
|
import androidx.compose.foundation.layout.BoxScope
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
|
@ -42,26 +40,22 @@ import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.draw.rotate
|
import androidx.compose.ui.draw.rotate
|
||||||
import androidx.compose.ui.platform.LocalInspectionMode
|
import androidx.compose.ui.platform.LocalInspectionMode
|
||||||
import androidx.compose.ui.res.pluralStringResource
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.element.android.compound.theme.ElementTheme
|
import io.element.android.compound.theme.ElementTheme
|
||||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
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.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.TimelineItemStateEventRow
|
||||||
import io.element.android.features.messages.impl.timeline.components.TimelineItemVirtualRow
|
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.TimelineItemRoomBeginningView
|
||||||
import io.element.android.features.messages.impl.timeline.components.virtual.TimelineLoadingMoreIndicator
|
import io.element.android.features.messages.impl.timeline.components.virtual.TimelineLoadingMoreIndicator
|
||||||
import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPresenterFactories
|
import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPresenterFactories
|
||||||
|
|
@ -174,7 +168,7 @@ fun TimelineView(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun TimelineItemRow(
|
fun TimelineItemRow(
|
||||||
timelineItem: TimelineItem,
|
timelineItem: TimelineItem,
|
||||||
showReadReceipts: Boolean,
|
showReadReceipts: Boolean,
|
||||||
isLastOutgoingMessage: Boolean,
|
isLastOutgoingMessage: Boolean,
|
||||||
|
|
@ -235,49 +229,24 @@ private fun TimelineItemRow(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is TimelineItem.GroupedEvents -> {
|
is TimelineItem.GroupedEvents -> {
|
||||||
val isExpanded = rememberSaveable(key = timelineItem.identifier()) { mutableStateOf(false) }
|
TimelineItemGroupedEventRow(
|
||||||
|
timelineItem = timelineItem,
|
||||||
fun onExpandGroupClick() {
|
showReadReceipts = showReadReceipts,
|
||||||
isExpanded.value = !isExpanded.value
|
isLastOutgoingMessage = isLastOutgoingMessage,
|
||||||
}
|
highlightedItem = highlightedItem,
|
||||||
|
sessionState = sessionState,
|
||||||
Column(modifier = modifier.animateContentSize()) {
|
onClick = onClick,
|
||||||
GroupHeaderView(
|
onLongClick = onLongClick,
|
||||||
text = pluralStringResource(
|
inReplyToClick = inReplyToClick,
|
||||||
id = R.plurals.room_timeline_state_changes,
|
onUserDataClick = onUserDataClick,
|
||||||
count = timelineItem.events.size,
|
onTimestampClicked = onTimestampClicked,
|
||||||
timelineItem.events.size
|
onReactionClick = onReactionClick,
|
||||||
),
|
onReactionLongClick = onReactionLongClick,
|
||||||
isExpanded = isExpanded.value,
|
onMoreReactionsClick = onMoreReactionsClick,
|
||||||
isHighlighted = !isExpanded.value && timelineItem.events.any { it.identifier() == highlightedItem },
|
onReadReceiptClick = onReadReceiptClick,
|
||||||
onClick = ::onExpandGroupClick,
|
eventSink = eventSink,
|
||||||
)
|
modifier = modifier,
|
||||||
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 = {},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue