Add Preview for timeline items.
This commit is contained in:
parent
3cde7d5356
commit
53c8d3ff7c
11 changed files with 265 additions and 39 deletions
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.timeline.components
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CornerSize
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
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.sp
|
||||
import io.element.android.features.messages.timeline.model.AggregatedReaction
|
||||
import io.element.android.features.messages.timeline.model.AggregatedReactionProvider
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.components.Surface
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
|
||||
@Composable
|
||||
fun MessagesReactionButton(reaction: AggregatedReaction, modifier: Modifier = Modifier) {
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
color = MaterialTheme.colorScheme.surfaceVariant,
|
||||
border = BorderStroke(2.dp, MaterialTheme.colorScheme.background),
|
||||
shape = RoundedCornerShape(corner = CornerSize(12.dp)),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(vertical = 5.dp, horizontal = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
// TODO `reaction.isHighlighted` is not used.
|
||||
Text(text = reaction.key, fontSize = 12.sp)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text(text = reaction.count, color = MaterialTheme.colorScheme.secondary, fontSize = 12.sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun MessagesReactionButtonLightPreview(@PreviewParameter(AggregatedReactionProvider::class) reaction: AggregatedReaction) =
|
||||
ElementPreviewLight { ContentToPreview(reaction) }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun MessagesReactionButtonDarkPreview(@PreviewParameter(AggregatedReactionProvider::class) reaction: AggregatedReaction) =
|
||||
ElementPreviewDark { ContentToPreview(reaction) }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview(reaction: AggregatedReaction) {
|
||||
MessagesReactionButton(reaction)
|
||||
}
|
||||
|
|
@ -20,7 +20,11 @@ import androidx.compose.material.icons.Icons
|
|||
import androidx.compose.material.icons.filled.Warning
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import io.element.android.features.messages.timeline.model.content.TimelineItemEncryptedContent
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import org.matrix.rustcomponents.sdk.EncryptedMessage
|
||||
|
||||
@Composable
|
||||
fun TimelineItemEncryptedView(
|
||||
|
|
@ -34,3 +38,22 @@ fun TimelineItemEncryptedView(
|
|||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun TimelineItemEncryptedViewLightPreview() =
|
||||
ElementPreviewLight { ContentToPreview() }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun TimelineItemEncryptedViewDarkPreview() =
|
||||
ElementPreviewDark { ContentToPreview() }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview() {
|
||||
TimelineItemEncryptedView(
|
||||
content = TimelineItemEncryptedContent(
|
||||
encryptedMessage = EncryptedMessage.Unknown,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,15 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.graphics.painter.ColorPainter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import coil.compose.AsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import io.element.android.features.messages.timeline.model.content.TimelineItemImageContent
|
||||
import io.element.android.features.messages.timeline.model.content.TimelineItemImageContentProvider
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.preview.debugPlaceholderBackground
|
||||
|
||||
@Composable
|
||||
fun TimelineItemImageView(
|
||||
|
|
@ -48,7 +54,7 @@ fun TimelineItemImageView(
|
|||
.aspectRatio(content.aspectRatio),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
var isLoading = rememberSaveable(content.imageMeta) { mutableStateOf(true) }
|
||||
val isLoading = rememberSaveable(content.imageMeta) { mutableStateOf(true) }
|
||||
val context = LocalContext.current
|
||||
val model = ImageRequest.Builder(context)
|
||||
.data(content.imageMeta)
|
||||
|
|
@ -57,9 +63,24 @@ fun TimelineItemImageView(
|
|||
AsyncImage(
|
||||
model = model,
|
||||
contentDescription = null,
|
||||
placeholder = ColorPainter(MaterialTheme.colorScheme.surfaceVariant),
|
||||
placeholder = debugPlaceholderBackground(ColorPainter(MaterialTheme.colorScheme.surfaceVariant)),
|
||||
contentScale = ContentScale.Crop,
|
||||
onSuccess = { isLoading.value = false },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun TimelineItemImageViewLightPreview(@PreviewParameter(TimelineItemImageContentProvider::class) content: TimelineItemImageContent) =
|
||||
ElementPreviewLight { ContentToPreview(content) }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun TimelineItemImageViewDarkPreview(@PreviewParameter(TimelineItemImageContentProvider::class) content: TimelineItemImageContent) =
|
||||
ElementPreviewDark { ContentToPreview(content) }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview(content: TimelineItemImageContent) {
|
||||
TimelineItemImageView(content)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,11 +65,11 @@ fun TimelineItemInformativeView(
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun MatrixUserRowLightPreview() = ElementPreviewLight { ContentToPreview() }
|
||||
internal fun TimelineItemInformativeViewLightPreview() = ElementPreviewLight { ContentToPreview() }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun MatrixUserRowDarkPreview() = ElementPreviewDark { ContentToPreview() }
|
||||
internal fun TimelineItemInformativeViewDarkPreview() = ElementPreviewDark { ContentToPreview() }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview() {
|
||||
|
|
|
|||
|
|
@ -16,24 +16,16 @@
|
|||
|
||||
package io.element.android.features.messages.timeline.components
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CornerSize
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.google.accompanist.flowlayout.FlowRow
|
||||
import io.element.android.features.messages.timeline.model.AggregatedReaction
|
||||
import io.element.android.features.messages.timeline.model.AggregatedReactionProvider
|
||||
import io.element.android.features.messages.timeline.model.TimelineItemReactions
|
||||
import io.element.android.libraries.designsystem.theme.components.Surface
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
||||
@Composable
|
||||
fun TimelineItemReactionsView(
|
||||
|
|
@ -52,21 +44,22 @@ fun TimelineItemReactionsView(
|
|||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun MessagesReactionButton(reaction: AggregatedReaction, modifier: Modifier = Modifier) {
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
color = MaterialTheme.colorScheme.surfaceVariant,
|
||||
border = BorderStroke(2.dp, MaterialTheme.colorScheme.background),
|
||||
shape = RoundedCornerShape(corner = CornerSize(12.dp)),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(vertical = 5.dp, horizontal = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(text = reaction.key, fontSize = 12.sp)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text(text = reaction.count, color = MaterialTheme.colorScheme.secondary, fontSize = 12.sp)
|
||||
}
|
||||
}
|
||||
internal fun TimelineItemReactionsViewLightPreview() =
|
||||
ElementPreviewLight { ContentToPreview() }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun TimelineItemReactionsViewDarkPreview() =
|
||||
ElementPreviewDark { ContentToPreview() }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview() {
|
||||
TimelineItemReactionsView(
|
||||
reactionsState = TimelineItemReactions(
|
||||
// Use values from AggregatedReactionProvider
|
||||
reactions = AggregatedReactionProvider().values.toPersistentList()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@ import androidx.compose.material.icons.Icons
|
|||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import io.element.android.features.messages.timeline.model.content.TimelineItemRedactedContent
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
|
||||
@Composable
|
||||
fun TimelineItemRedactedView(
|
||||
|
|
@ -34,3 +37,18 @@ fun TimelineItemRedactedView(
|
|||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun TimelineItemRedactedViewLightPreview() =
|
||||
ElementPreviewLight { ContentToPreview() }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun TimelineItemRedactedViewDarkPreview() =
|
||||
ElementPreviewDark { ContentToPreview() }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview() {
|
||||
TimelineItemRedactedView(TimelineItemRedactedContent)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@ import androidx.compose.material.icons.Icons
|
|||
import androidx.compose.material.icons.filled.Info
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import io.element.android.features.messages.timeline.model.content.TimelineItemUnknownContent
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
|
||||
@Composable
|
||||
fun TimelineItemUnknownView(
|
||||
|
|
@ -34,3 +37,18 @@ fun TimelineItemUnknownView(
|
|||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun TimelineItemUnknownViewLightPreview() =
|
||||
ElementPreviewLight { ContentToPreview() }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun TimelineItemUnknownViewDarkPreview() =
|
||||
ElementPreviewDark { ContentToPreview() }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview() {
|
||||
TimelineItemUnknownView(TimelineItemUnknownContent)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.timeline.model
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
||||
open class AggregatedReactionProvider : PreviewParameterProvider<AggregatedReaction> {
|
||||
override val values: Sequence<AggregatedReaction>
|
||||
get() = sequenceOf(
|
||||
aAggregatedReaction(),
|
||||
aAggregatedReaction().copy(count = "88"),
|
||||
aAggregatedReaction().copy(isHighlighted = true),
|
||||
aAggregatedReaction().copy(count = "88", isHighlighted = true),
|
||||
)
|
||||
}
|
||||
|
||||
fun aAggregatedReaction() = AggregatedReaction(
|
||||
key = "👍",
|
||||
count = "1", // TODO Why is it a String?
|
||||
isHighlighted = false,
|
||||
)
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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.timeline.model.content
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.matrix.media.MediaResolver
|
||||
|
||||
open class TimelineItemImageContentProvider : PreviewParameterProvider<TimelineItemImageContent> {
|
||||
override val values: Sequence<TimelineItemImageContent>
|
||||
get() = sequenceOf(
|
||||
aTimelineItemImageContent(),
|
||||
aTimelineItemImageContent().copy(aspectRatio = 1.0f),
|
||||
aTimelineItemImageContent().copy(aspectRatio = 1.5f),
|
||||
)
|
||||
}
|
||||
|
||||
fun aTimelineItemImageContent() = TimelineItemImageContent(
|
||||
body = "a body",
|
||||
imageMeta = MediaResolver.Meta(source = null, kind = MediaResolver.Kind.Content),
|
||||
blurhash = null,
|
||||
aspectRatio = 0.5f,
|
||||
)
|
||||
|
|
@ -18,6 +18,7 @@ package io.element.android.libraries.designsystem.preview
|
|||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import io.element.android.libraries.designsystem.R
|
||||
|
|
@ -27,14 +28,21 @@ import io.element.android.libraries.designsystem.R
|
|||
* but it does not render in preview. In the meantime, you can use this trick to have image.
|
||||
*/
|
||||
@Composable
|
||||
fun debugPlaceholder(@DrawableRes debugPreview: Int) = if (LocalInspectionMode.current) {
|
||||
fun debugPlaceholder(
|
||||
@DrawableRes debugPreview: Int,
|
||||
nonDebugPainter: Painter? = null,
|
||||
) = if (LocalInspectionMode.current) {
|
||||
painterResource(id = debugPreview)
|
||||
} else {
|
||||
null
|
||||
nonDebugPainter
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun debugPlaceholderBackground() = debugPlaceholder(debugPreview = R.drawable.sample_background)
|
||||
fun debugPlaceholderBackground(nonDebugPainter: Painter? = null): Painter? {
|
||||
return debugPlaceholder(debugPreview = R.drawable.sample_background, nonDebugPainter)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun debugPlaceholderAvatar() = debugPlaceholder(debugPreview = R.drawable.sample_avatar)
|
||||
fun debugPlaceholderAvatar(nonDebugPainter: Painter? = null): Painter? {
|
||||
return debugPlaceholder(debugPreview = R.drawable.sample_avatar, nonDebugPainter)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,12 +89,12 @@ fun MatrixUserRow(
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
fun MatrixUserRowLightPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) =
|
||||
internal fun MatrixUserRowLightPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) =
|
||||
ElementPreviewLight { ContentToPreview(matrixUser) }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun MatrixUserRowDarkPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) =
|
||||
internal fun MatrixUserRowDarkPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) =
|
||||
ElementPreviewDark { ContentToPreview(matrixUser) }
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue