Media: some ui improvements

This commit is contained in:
ganfra
2023-05-17 16:20:31 +02:00
parent d36bc58e60
commit 07cb3854f8
8 changed files with 81 additions and 52 deletions

View File

@@ -45,8 +45,8 @@ class AttachmentsPreviewNode @AssistedInject constructor(
@Composable
override fun View(modifier: Modifier) {
val state = presenter.present()
ElementTheme(darkTheme = true) {
val state = presenter.present()
AttachmentsPreviewView(
state = state,
onDismiss = this::navigateUp,

View File

@@ -22,14 +22,14 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -70,7 +70,10 @@ fun AttachmentsPreviewView(
}
Scaffold(modifier) {
Box {
Box(
modifier = Modifier.padding(it),
contentAlignment = Alignment.Center
) {
AttachmentPreviewContent(
attachment = state.attachment,
onSendClicked = ::postSendAttachment,
@@ -115,11 +118,10 @@ private fun AttachmentPreviewContent(
onDismiss: () -> Unit
) {
Column(
modifier = Modifier.fillMaxWidth(),
modifier = Modifier
.fillMaxSize()
.padding(top = 24.dp)
) {
Spacer(
modifier = Modifier.height(80.dp)
)
Box(
modifier = Modifier
.fillMaxWidth()

View File

@@ -49,8 +49,8 @@ class MediaViewerNode @AssistedInject constructor(
@Composable
override fun View(modifier: Modifier) {
val state = presenter.present()
ElementTheme(darkTheme = true) {
val state = presenter.present()
MediaViewerView(
state = state,
modifier = modifier

View File

@@ -41,7 +41,7 @@ import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.ui.strings.R.string as StringR
import io.element.android.libraries.ui.strings.R as StringR
@Composable
fun MediaViewerView(
@@ -62,7 +62,7 @@ fun MediaViewerView(
) {
when (state.downloadedMedia) {
is Async.Success -> LocalMediaView(state.downloadedMedia.state)
is Async.Failure -> ErrorView("Error while downloading", ::onRetry)
is Async.Failure -> ErrorView(stringResource(id = StringR.string.error_unknown), ::onRetry)
else -> CircularProgressIndicator(
strokeWidth = 2.dp,
)
@@ -82,11 +82,11 @@ private fun ErrorView(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(text = errorMessage)
Spacer(modifier = Modifier.size(8.dp))
Spacer(modifier = Modifier.size(16.dp))
Button(
onClick = onRetry
) {
Text(text = stringResource(id = StringR.action_retry))
Text(text = stringResource(id = StringR.string.action_retry))
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.event
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.heightIn
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import kotlin.math.min
@Composable
fun TimelineItemAspectRatioBox(
height: Int?,
aspectRatio: Float,
modifier: Modifier = Modifier,
content: @Composable BoxScope.() -> Unit,
) {
val maxHeight = min(300, height ?: 0)
Box(
modifier = modifier
.heightIn(max = maxHeight.dp)
.aspectRatio(aspectRatio),
content = content
)
}

View File

@@ -16,37 +16,31 @@
package io.element.android.features.messages.impl.timeline.components.event
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.features.messages.impl.timeline.components.blurhash.BlurHashAsyncImage
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContentProvider
import io.element.android.libraries.designsystem.components.blurhash.BlurHashAsyncImage
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.matrix.ui.media.MediaRequestData
import kotlin.math.min
@Composable
fun TimelineItemImageView(
content: TimelineItemImageContent,
modifier: Modifier = Modifier,
) {
val maxHeight = min(300, content.height ?: Int.MAX_VALUE)
Box(
TimelineItemAspectRatioBox(
height = content.height,
aspectRatio = content.aspectRatio,
modifier = modifier
.heightIn(max = maxHeight.dp)
.aspectRatio(content.aspectRatio),
contentAlignment = Alignment.Center,
) {
BlurHashAsyncImage(
modifier = Modifier.fillMaxSize(),
blurHash = content.blurhash,
model = MediaRequestData(content.mediaSource, MediaRequestData.Kind.Content),
contentScale = ContentScale.Fit,

View File

@@ -17,9 +17,7 @@
package io.element.android.features.messages.impl.timeline.components.event
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@@ -29,29 +27,26 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.features.messages.impl.timeline.components.blurhash.BlurHashAsyncImage
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContentProvider
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent
import io.element.android.libraries.designsystem.components.blurhash.BlurHashAsyncImage
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.matrix.ui.media.MediaRequestData
import kotlin.math.min
@Composable
fun TimelineItemVideoView(
content: TimelineItemVideoContent,
modifier: Modifier = Modifier,
) {
val maxHeight = min(300, content.height ?: Int.MAX_VALUE)
Box(
TimelineItemAspectRatioBox(
height = content.height,
aspectRatio = content.aspectRatio,
modifier = modifier
.heightIn(max = maxHeight.dp)
.aspectRatio(content.aspectRatio),
contentAlignment = Alignment.Center,
) {
BlurHashAsyncImage(
modifier = Modifier.fillMaxSize(),
blurHash = content.blurhash,
model = MediaRequestData(content.thumbnailSource, MediaRequestData.Kind.Content),
contentScale = ContentScale.Fit,
@@ -59,9 +54,9 @@ fun TimelineItemVideoView(
Image(
painterResource(id = androidx.media3.ui.R.drawable.exo_ic_play_circle_filled),
contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground)
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
modifier = Modifier.align(Alignment.Center),
)
}
}

View File

@@ -41,13 +41,7 @@ class TimelineItemContentMessageFactory @Inject constructor() {
htmlDocument = messageType.formatted?.toHtmlDocument()
)
is ImageMessageType -> {
val height = messageType.info?.height?.toFloat()
val width = messageType.info?.width?.toFloat()
val aspectRatio = if (height != null && width != null) {
width / height
} else {
0.7f
}
val aspectRatio = aspectRatioOf(messageType.info?.width, messageType.info?.height)
TimelineItemImageContent(
body = messageType.body,
height = messageType.info?.height?.toInt(),
@@ -59,13 +53,7 @@ class TimelineItemContentMessageFactory @Inject constructor() {
)
}
is VideoMessageType -> {
val height = messageType.info?.height?.toFloat()
val width = messageType.info?.width?.toFloat()
val aspectRatio = if (height != null && width != null) {
width / height
} else {
0.7f
}
val aspectRatio = aspectRatioOf(messageType.info?.width, messageType.info?.height)
TimelineItemVideoContent(
body = messageType.body,
thumbnailSource = messageType.info?.thumbnailSource,
@@ -89,4 +77,12 @@ class TimelineItemContentMessageFactory @Inject constructor() {
else -> TimelineItemUnknownContent
}
}
private fun aspectRatioOf(width: Long?, height: Long?): Float {
return if (height != null && width != null) {
width.toFloat() / height.toFloat()
} else {
0.7f
}
}
}