Preview for Timeline Event - WIP
This commit is contained in:
parent
224f11b8bc
commit
c51eb4823c
6 changed files with 139 additions and 9 deletions
|
|
@ -24,17 +24,19 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.layout.LastBaseline
|
import androidx.compose.ui.layout.LastBaseline
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.compose.ui.zIndex
|
import androidx.compose.ui.zIndex
|
||||||
import com.airbnb.mvrx.compose.collectAsState
|
import com.airbnb.mvrx.compose.collectAsState
|
||||||
import com.airbnb.mvrx.compose.mavericksViewModel
|
import com.airbnb.mvrx.compose.mavericksViewModel
|
||||||
import io.element.android.x.core.compose.LogCompositions
|
import io.element.android.x.core.compose.LogCompositions
|
||||||
|
import io.element.android.x.core.compose.PairCombinedPreviewParameter
|
||||||
import io.element.android.x.core.data.StableCharSequence
|
import io.element.android.x.core.data.StableCharSequence
|
||||||
import io.element.android.x.designsystem.components.avatar.AvatarData
|
import io.element.android.x.designsystem.components.avatar.AvatarData
|
||||||
import io.element.android.x.features.messages.components.*
|
import io.element.android.x.features.messages.components.*
|
||||||
import io.element.android.x.features.messages.model.MessagesTimelineItemState
|
import io.element.android.x.features.messages.model.*
|
||||||
import io.element.android.x.features.messages.model.MessagesViewState
|
|
||||||
import io.element.android.x.features.messages.model.content.*
|
import io.element.android.x.features.messages.model.content.*
|
||||||
import io.element.android.x.features.messages.textcomposer.MessageComposerViewModel
|
import io.element.android.x.features.messages.textcomposer.MessageComposerViewModel
|
||||||
import io.element.android.x.features.messages.textcomposer.MessageComposerViewState
|
import io.element.android.x.features.messages.textcomposer.MessageComposerViewState
|
||||||
|
|
@ -42,6 +44,7 @@ import io.element.android.x.textcomposer.TextComposer
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import java.lang.Math.random
|
||||||
|
|
||||||
private val COMPOSER_HEIGHT = 112.dp
|
private val COMPOSER_HEIGHT = 112.dp
|
||||||
|
|
||||||
|
|
@ -253,11 +256,11 @@ fun MessagesTopAppBar(
|
||||||
fun TimelineItems(
|
fun TimelineItems(
|
||||||
lazyListState: LazyListState,
|
lazyListState: LazyListState,
|
||||||
timelineItems: List<MessagesTimelineItemState>,
|
timelineItems: List<MessagesTimelineItemState>,
|
||||||
hasMoreToLoad: Boolean,
|
|
||||||
onClick: (MessagesTimelineItemState.MessageEvent) -> Unit,
|
|
||||||
onLongClick: ((MessagesTimelineItemState.MessageEvent)) -> Unit,
|
|
||||||
onReachedLoadMore: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
hasMoreToLoad: Boolean = false,
|
||||||
|
onClick: (MessagesTimelineItemState.MessageEvent) -> Unit = {},
|
||||||
|
onLongClick: ((MessagesTimelineItemState.MessageEvent)) -> Unit = {},
|
||||||
|
onReachedLoadMore: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
Box(modifier = modifier.fillMaxWidth()) {
|
Box(modifier = modifier.fillMaxWidth()) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
|
|
@ -385,6 +388,7 @@ fun MessageEventRow(
|
||||||
content = messageEvent.content,
|
content = messageEvent.content,
|
||||||
modifier = contentModifier
|
modifier = contentModifier
|
||||||
)
|
)
|
||||||
|
else -> TODO() /* compiler issue ? */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MessagesReactionsView(
|
MessagesReactionsView(
|
||||||
|
|
@ -502,4 +506,76 @@ internal fun MessagesLoadingMoreIndicator() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MessagesItemGroupPositionToMessagesTimelineItemContentProvider :
|
||||||
|
PairCombinedPreviewParameter<MessagesItemGroupPosition, MessagesTimelineItemContent>(
|
||||||
|
MessagesItemGroupPositionProvider() to MessagesTimelineItemContentProvider()
|
||||||
|
)
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
private fun TimelineItemsPreview(
|
||||||
|
@PreviewParameter(MessagesTimelineItemContentProvider::class)
|
||||||
|
content: MessagesTimelineItemContent
|
||||||
|
) {
|
||||||
|
TimelineItems(
|
||||||
|
lazyListState = LazyListState(),
|
||||||
|
timelineItems = listOf(
|
||||||
|
// 3 items (First Middle Last) with isMine = false
|
||||||
|
createMessageEvent(
|
||||||
|
isMine = false,
|
||||||
|
content = content,
|
||||||
|
groupPosition = MessagesItemGroupPosition.First
|
||||||
|
),
|
||||||
|
createMessageEvent(
|
||||||
|
isMine = false,
|
||||||
|
content = content,
|
||||||
|
groupPosition = MessagesItemGroupPosition.Middle
|
||||||
|
),
|
||||||
|
createMessageEvent(
|
||||||
|
isMine = false,
|
||||||
|
content = content,
|
||||||
|
groupPosition = MessagesItemGroupPosition.Last
|
||||||
|
),
|
||||||
|
// 3 items (First Middle Last) with isMine = true
|
||||||
|
createMessageEvent(
|
||||||
|
isMine = true,
|
||||||
|
content = content,
|
||||||
|
groupPosition = MessagesItemGroupPosition.First
|
||||||
|
),
|
||||||
|
createMessageEvent(
|
||||||
|
isMine = true,
|
||||||
|
content = content,
|
||||||
|
groupPosition = MessagesItemGroupPosition.Middle
|
||||||
|
),
|
||||||
|
createMessageEvent(
|
||||||
|
isMine = true,
|
||||||
|
content = content,
|
||||||
|
groupPosition = MessagesItemGroupPosition.Last
|
||||||
|
),
|
||||||
|
),
|
||||||
|
hasMoreToLoad = true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createMessageEvent(
|
||||||
|
isMine: Boolean,
|
||||||
|
content: MessagesTimelineItemContent,
|
||||||
|
groupPosition: MessagesItemGroupPosition
|
||||||
|
): MessagesTimelineItemState {
|
||||||
|
return MessagesTimelineItemState.MessageEvent(
|
||||||
|
id = random().toString(),
|
||||||
|
senderId = "senderId",
|
||||||
|
senderAvatar = AvatarData("sender"),
|
||||||
|
content = content,
|
||||||
|
reactionsState = MessagesItemReactionState(
|
||||||
|
listOf(
|
||||||
|
AggregatedReaction("👍", "1")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
isMine = isMine,
|
||||||
|
senderDisplayName = "sender",
|
||||||
|
groupPosition = groupPosition,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package io.element.android.x.features.messages.model
|
package io.element.android.x.features.messages.model
|
||||||
|
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
|
|
||||||
sealed interface MessagesItemGroupPosition {
|
sealed interface MessagesItemGroupPosition {
|
||||||
object First : MessagesItemGroupPosition
|
object First : MessagesItemGroupPosition
|
||||||
object Middle : MessagesItemGroupPosition
|
object Middle : MessagesItemGroupPosition
|
||||||
|
|
@ -12,3 +14,12 @@ sealed interface MessagesItemGroupPosition {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class MessagesItemGroupPositionProvider : PreviewParameterProvider<MessagesItemGroupPosition> {
|
||||||
|
override val values = sequenceOf(
|
||||||
|
MessagesItemGroupPosition.First,
|
||||||
|
MessagesItemGroupPosition.Middle,
|
||||||
|
MessagesItemGroupPosition.Last,
|
||||||
|
MessagesItemGroupPosition.None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,7 @@ sealed interface MessagesTimelineItemState {
|
||||||
) : MessagesTimelineItemState
|
) : MessagesTimelineItemState
|
||||||
|
|
||||||
data class MessageEvent(
|
data class MessageEvent(
|
||||||
val id: String = "",
|
val id: String,
|
||||||
val senderId: String,
|
val senderId: String,
|
||||||
val senderDisplayName: String?,
|
val senderDisplayName: String?,
|
||||||
val senderAvatar: AvatarData,
|
val senderAvatar: AvatarData,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,31 @@
|
||||||
package io.element.android.x.features.messages.model.content
|
package io.element.android.x.features.messages.model.content
|
||||||
|
|
||||||
sealed interface MessagesTimelineItemContent
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
|
import org.matrix.rustcomponents.sdk.EncryptedMessage
|
||||||
|
import org.matrix.rustcomponents.sdk.FormattedBody
|
||||||
|
import org.matrix.rustcomponents.sdk.MessageFormat
|
||||||
|
|
||||||
|
sealed interface MessagesTimelineItemContent
|
||||||
|
|
||||||
|
class MessagesTimelineItemContentProvider : PreviewParameterProvider<MessagesTimelineItemContent> {
|
||||||
|
override val values = sequenceOf(
|
||||||
|
MessagesTimelineItemEmoteContent(
|
||||||
|
body = "Emote",
|
||||||
|
formattedBody = FormattedBody(MessageFormat.HTML, "Formatted emote")
|
||||||
|
),
|
||||||
|
MessagesTimelineItemEncryptedContent(
|
||||||
|
encryptedMessage = EncryptedMessage.Unknown
|
||||||
|
),
|
||||||
|
// TODO MessagesTimelineItemImageContent(),
|
||||||
|
MessagesTimelineItemNoticeContent(
|
||||||
|
body = "Notice",
|
||||||
|
formattedBody = FormattedBody(MessageFormat.HTML, "Formatted notice")
|
||||||
|
),
|
||||||
|
MessagesTimelineItemRedactedContent,
|
||||||
|
MessagesTimelineItemTextContent(
|
||||||
|
body = "Text",
|
||||||
|
formattedBody = FormattedBody(MessageFormat.HTML, "Formatted text")
|
||||||
|
),
|
||||||
|
MessagesTimelineItemUnknownContent,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.library'
|
id 'com.android.library'
|
||||||
id 'org.jetbrains.kotlin.android'
|
id 'org.jetbrains.kotlin.android'
|
||||||
|
id 'io.element.android-compose'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package io.element.android.x.core.compose
|
||||||
|
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
|
|
||||||
|
open class PairCombinedPreviewParameter<T1, T2>(
|
||||||
|
private val provider: Pair<PreviewParameterProvider<T1>, PreviewParameterProvider<T2>>
|
||||||
|
) : PreviewParameterProvider<Pair<T1, T2>> {
|
||||||
|
override val values: Sequence<Pair<T1, T2>>
|
||||||
|
get() = provider.first.values.flatMap { first ->
|
||||||
|
provider.second.values.map { second ->
|
||||||
|
first to second
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue