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.runtime.Composable
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.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
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
@ -22,7 +20,6 @@ import chat.revolt.api.asJanuaryProxyUrl
import chat.revolt.api.internals.ULID import chat.revolt.api.internals.ULID
import chat.revolt.api.internals.WebCompat import chat.revolt.api.internals.WebCompat
import chat.revolt.api.schemas.AutumnResource import chat.revolt.api.schemas.AutumnResource
import chat.revolt.components.generic.RemoteImage
import chat.revolt.components.generic.UserAvatar import chat.revolt.components.generic.UserAvatar
import chat.revolt.components.generic.UserAvatarWidthPlaceholder import chat.revolt.components.generic.UserAvatarWidthPlaceholder
import chat.revolt.markdown.Markdown import chat.revolt.markdown.Markdown
@ -135,6 +132,8 @@ fun Message(
} }
message.content?.let { message.content?.let {
if (message.content.isBlank()) return@let // if only an attachment is sent
Text( Text(
text = Markdown.annotate(it), text = Markdown.annotate(it),
maxLines = if (truncate) 1 else Int.MAX_VALUE, maxLines = if (truncate) 1 else Int.MAX_VALUE,
@ -143,34 +142,10 @@ fun Message(
} }
message.attachments?.let { message.attachments?.let {
if (message.attachments.isNotEmpty()) { message.attachments.forEach { attachment ->
message.attachments.forEach { attachment -> Spacer(modifier = Modifier.height(5.dp))
if (attachment.metadata?.type == "Image") { MessageAttachment(attachment) {
RemoteImage( viewAttachmentInBrowser(context, attachment)
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)
)
}
} }
} }
} }

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