feat: show upload progress for attachments and tweaks
Signed-off-by: Infi <wingit@geist.ga>
This commit is contained in:
parent
75c7ec95a4
commit
21c2556eb1
|
|
@ -1,15 +1,27 @@
|
|||
package chat.revolt.components.screens.chat
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ProgressIndicatorDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
|
@ -23,44 +35,57 @@ import java.io.File
|
|||
fun AttachmentManager(
|
||||
attachments: List<FileArgs>,
|
||||
uploading: Boolean,
|
||||
uploadProgress: Float = 0f,
|
||||
onRemove: (FileArgs) -> Unit,
|
||||
) {
|
||||
Row(
|
||||
val animatedProgress by animateFloatAsState(
|
||||
targetValue = uploadProgress,
|
||||
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec,
|
||||
label = "Upload progress"
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp))
|
||||
.horizontalScroll(rememberScrollState())
|
||||
.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||
) {
|
||||
AnimatedVisibility(uploading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.padding(4.dp),
|
||||
color = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.7f)
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.horizontalScroll(rememberScrollState())
|
||||
.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||
) {
|
||||
|
||||
attachments.forEach { attachment ->
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(4.dp)
|
||||
.clip(MaterialTheme.shapes.small)
|
||||
.clickable {
|
||||
onRemove(attachment)
|
||||
}
|
||||
.background(
|
||||
color = MaterialTheme.colorScheme.background,
|
||||
shape = MaterialTheme.shapes.small
|
||||
)
|
||||
.padding(8.dp)
|
||||
) {
|
||||
Text(attachment.filename, maxLines = 1)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Icon(
|
||||
Icons.Default.Close,
|
||||
contentDescription = stringResource(R.string.remove_attachment_alt)
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
}
|
||||
}
|
||||
|
||||
attachments.forEach { attachment ->
|
||||
Row(
|
||||
AnimatedVisibility(visible = uploading) {
|
||||
LinearProgressIndicator(
|
||||
progress = animatedProgress,
|
||||
modifier = Modifier
|
||||
.padding(4.dp)
|
||||
.clip(MaterialTheme.shapes.small)
|
||||
.clickable {
|
||||
onRemove(attachment)
|
||||
}
|
||||
.background(
|
||||
color = MaterialTheme.colorScheme.background,
|
||||
shape = MaterialTheme.shapes.small
|
||||
)
|
||||
.padding(8.dp)
|
||||
) {
|
||||
Text(attachment.filename, maxLines = 1)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Icon(
|
||||
Icons.Default.Close,
|
||||
contentDescription = stringResource(R.string.remove_attachment_alt)
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -385,7 +385,8 @@ fun ChannelScreen(
|
|||
AttachmentManager(
|
||||
attachments = viewModel.pendingAttachments,
|
||||
uploading = viewModel.isSendingMessage,
|
||||
onRemove = { viewModel.pendingAttachments.remove(it) }
|
||||
uploadProgress = viewModel.pendingUploadProgress,
|
||||
onRemove = { viewModel.pendingAttachments.remove(it) },
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ package chat.revolt.screens.chat.views.channel
|
|||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||
import androidx.compose.runtime.toMutableStateList
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import chat.revolt.api.RevoltAPI
|
||||
|
|
@ -55,9 +56,11 @@ class ChannelScreenViewModel : ViewModel() {
|
|||
var pendingReplies = mutableStateListOf<SendMessageReply>()
|
||||
var pendingAttachments = mutableStateListOf<FileArgs>()
|
||||
|
||||
var pendingUploadProgress by mutableFloatStateOf(0f)
|
||||
|
||||
private fun popAttachmentBatch() {
|
||||
pendingAttachments =
|
||||
pendingAttachments.drop(MAX_ATTACHMENTS_PER_MESSAGE) as SnapshotStateList<FileArgs>
|
||||
pendingAttachments.drop(MAX_ATTACHMENTS_PER_MESSAGE).toMutableStateList()
|
||||
}
|
||||
|
||||
private fun setRenderableMessages(messages: List<Message>) {
|
||||
|
|
@ -142,14 +145,20 @@ class ChannelScreenViewModel : ViewModel() {
|
|||
|
||||
viewModelScope.launch {
|
||||
val attachmentIds = arrayListOf<String>()
|
||||
val takenAttachments = pendingAttachments.take(MAX_ATTACHMENTS_PER_MESSAGE)
|
||||
val totalTaken = takenAttachments.size
|
||||
|
||||
pendingAttachments.take(MAX_ATTACHMENTS_PER_MESSAGE).forEach {
|
||||
takenAttachments.forEachIndexed { index, it ->
|
||||
try {
|
||||
val id = uploadToAutumn(
|
||||
it.file,
|
||||
it.filename,
|
||||
"attachments",
|
||||
ContentType.parse(it.contentType)
|
||||
ContentType.parse(it.contentType),
|
||||
onProgress = { current, total ->
|
||||
pendingUploadProgress =
|
||||
((current.toFloat() / total.toFloat()) / totalTaken.toFloat()) + (index.toFloat() / totalTaken.toFloat())
|
||||
}
|
||||
)
|
||||
Log.d("ChannelScreen", "Uploaded attachment with id $id")
|
||||
attachmentIds.add(id)
|
||||
|
|
@ -168,6 +177,8 @@ class ChannelScreenViewModel : ViewModel() {
|
|||
|
||||
pendingMessageContent = ""
|
||||
hasNoMoreMessages = false
|
||||
isSendingMessage = false
|
||||
pendingUploadProgress = 0f
|
||||
popAttachmentBatch()
|
||||
clearInReplyTo()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue