feat: revamp attachment display

This commit is contained in:
Infi 2023-03-04 01:54:51 +01:00
parent 96fb9f8983
commit af92c95a82
4 changed files with 135 additions and 33 deletions

View File

@ -9,8 +9,6 @@ import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
@ -22,7 +20,6 @@ import chat.revolt.api.asJanuaryProxyUrl
import chat.revolt.api.internals.ULID
import chat.revolt.api.internals.WebCompat
import chat.revolt.api.schemas.AutumnResource
import chat.revolt.components.generic.RemoteImage
import chat.revolt.components.generic.UserAvatar
import chat.revolt.components.generic.UserAvatarWidthPlaceholder
import chat.revolt.markdown.Markdown
@ -135,6 +132,8 @@ fun Message(
}
message.content?.let {
if (message.content.isBlank()) return@let // if only an attachment is sent
Text(
text = Markdown.annotate(it),
maxLines = if (truncate) 1 else Int.MAX_VALUE,
@ -143,34 +142,10 @@ fun Message(
}
message.attachments?.let {
if (message.attachments.isNotEmpty()) {
message.attachments.forEach { attachment ->
if (attachment.metadata?.type == "Image") {
RemoteImage(
url = "$REVOLT_FILES/attachments/${attachment.id}/image.png",
modifier = Modifier
.padding(top = 5.dp)
.clickable {
viewAttachmentInBrowser(context, attachment)
},
width = attachment.metadata.width?.toInt() ?: 0,
height = attachment.metadata.height?.toInt() ?: 0,
contentScale = ContentScale.Fit,
description = "Attached image ${attachment.filename}"
)
} else {
Text(
text = attachment.filename ?: "Attachment",
fontWeight = FontWeight.Medium,
modifier = Modifier
.clip(MaterialTheme.shapes.medium)
.clickable {
viewAttachmentInBrowser(context, attachment)
}
.background(MaterialTheme.colorScheme.surface)
.padding(8.dp)
)
}
message.attachments.forEach { attachment ->
Spacer(modifier = Modifier.height(5.dp))
MessageAttachment(attachment) {
viewAttachmentInBrowser(context, attachment)
}
}
}

View File

@ -0,0 +1,115 @@
package chat.revolt.components.chat
import android.text.format.Formatter
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.Icon
import androidx.compose.material.LocalContentColor
import androidx.compose.material.Text
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import chat.revolt.R
import chat.revolt.api.REVOLT_FILES
import chat.revolt.api.schemas.AutumnResource
import chat.revolt.components.generic.RemoteImage
@Composable
fun FileAttachment(attachment: AutumnResource) {
val context = LocalContext.current
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
Row(
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp))
.padding(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
painter = painterResource(id = R.drawable.ic_file_24dp),
contentDescription = null,
)
Spacer(modifier = Modifier.width(8.dp))
Column {
Text(
text = attachment.filename ?: "File",
maxLines = 1,
fontWeight = FontWeight.Bold,
)
Text(
text = Formatter.formatShortFileSize(context, attachment.size ?: 0),
maxLines = 1,
color = LocalContentColor.current.copy(alpha = 0.7f),
fontWeight = FontWeight.Normal,
)
}
}
}
}
@Composable
fun ImageAttachment(attachment: AutumnResource) {
val url = "$REVOLT_FILES/attachments/${attachment.id}/${attachment.filename}"
RemoteImage(
url = url,
contentScale = ContentScale.Fit,
modifier = Modifier
.fillMaxWidth()
.aspectRatio(attachment.metadata!!.width!!.toFloat() / attachment.metadata.height!!.toFloat()),
description = attachment.filename ?: "Image",
)
}
@Composable
fun VideoAttachment(attachment: AutumnResource) {
// FIXME Use ExoPlayer to play videos.
FileAttachment(attachment)
}
@Composable
fun AudioAttachment(attachment: AutumnResource) {
// FIXME Use ExoPlayer to play audio.
FileAttachment(attachment)
}
@Composable
fun TextAttachment(attachment: AutumnResource) {
// FIXME Write bespoke viewer for text attachments.
FileAttachment(attachment)
}
@Composable
fun MessageAttachment(attachment: AutumnResource, onAttachmentClick: (AutumnResource) -> Unit) {
Box(
modifier = Modifier
.clip(MaterialTheme.shapes.medium)
.clickable { onAttachmentClick(attachment) }
) {
if (attachment.metadata?.type == null) {
FileAttachment(attachment)
return
}
when (attachment.metadata.type) {
"Image" -> ImageAttachment(attachment)
"Video" -> VideoAttachment(attachment)
"Audio" -> AudioAttachment(attachment)
"Text" -> TextAttachment(attachment)
else -> FileAttachment(attachment)
}
}
}

View File

@ -22,6 +22,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import chat.revolt.R
@ -76,10 +77,12 @@ fun MessageField(
interactionSource = remember { MutableInteractionSource() },
placeholder = {
Text(
stringResource(
text = stringResource(
id = placeholderResource,
channelName
)
),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
},
colors = TextFieldDefaults.textFieldColors(

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M13,9V3.5L18.5,9M6,2C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6Z" />
</vector>