Enable forwarding from all attachment types
This commit is contained in:
@@ -2510,7 +2510,7 @@ private fun MaterialsMediaCell(
|
||||
private fun MaterialsFileList(items: List<ChatAttachmentItem>, vm: QMaxViewModel) {
|
||||
LazyColumn(Modifier.fillMaxSize()) {
|
||||
items(items, key = { it.attachment.id }) { item ->
|
||||
FileAttachment(item.attachment, vm)
|
||||
FileAttachment(item.attachment, vm, onLongPress = {})
|
||||
HorizontalDivider(color = Color(0xFFE7EEF3))
|
||||
}
|
||||
}
|
||||
@@ -2521,7 +2521,7 @@ private fun MaterialsVoiceList(items: List<ChatAttachmentItem>, session: QMaxSes
|
||||
LazyColumn(Modifier.fillMaxSize()) {
|
||||
items(items, key = { it.attachment.id }) { item ->
|
||||
val url = "${session.serverUrl.trimEnd('/')}${item.attachment.downloadPath}"
|
||||
VoiceAttachment(item.attachment, url, session.accessToken)
|
||||
VoiceAttachment(item.attachment, url, session.accessToken, onLongPress = {})
|
||||
HorizontalDivider(color = Color(0xFFE7EEF3))
|
||||
}
|
||||
}
|
||||
@@ -2645,7 +2645,8 @@ private fun MessageRow(
|
||||
session = session,
|
||||
vm = vm,
|
||||
imagePreviewSources = imagePreviewSources,
|
||||
mediaShape = shape
|
||||
mediaShape = shape,
|
||||
onLongPress = { actionsOpen = true }
|
||||
)
|
||||
} else {
|
||||
sortedAttachments.forEach { attachment ->
|
||||
@@ -2654,7 +2655,8 @@ private fun MessageRow(
|
||||
session = session,
|
||||
vm = vm,
|
||||
imagePreviewSources = imagePreviewSources,
|
||||
mediaShape = shape
|
||||
mediaShape = shape,
|
||||
onLongPress = { actionsOpen = true }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2936,7 +2938,8 @@ private fun MediaAlbumGrid(
|
||||
session: QMaxSession,
|
||||
vm: QMaxViewModel,
|
||||
imagePreviewSources: List<String>,
|
||||
mediaShape: RoundedCornerShape
|
||||
mediaShape: RoundedCornerShape,
|
||||
onLongPress: () -> Unit
|
||||
) {
|
||||
val visible = attachments.take(4)
|
||||
val extraCount = (attachments.size - visible.size).coerceAtLeast(0)
|
||||
@@ -2956,6 +2959,7 @@ private fun MediaAlbumGrid(
|
||||
vm = vm,
|
||||
imagePreviewSources = imagePreviewSources,
|
||||
extraCount = extraCount.takeIf { index == visible.lastIndex },
|
||||
onLongPress = onLongPress,
|
||||
modifier = Modifier.weight(1f).aspectRatio(1f)
|
||||
)
|
||||
}
|
||||
@@ -2967,6 +2971,7 @@ private fun MediaAlbumGrid(
|
||||
vm = vm,
|
||||
imagePreviewSources = imagePreviewSources,
|
||||
extraCount = null,
|
||||
onLongPress = onLongPress,
|
||||
modifier = Modifier.fillMaxWidth().aspectRatio(1.85f)
|
||||
)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(2.dp)) {
|
||||
@@ -2977,6 +2982,7 @@ private fun MediaAlbumGrid(
|
||||
vm = vm,
|
||||
imagePreviewSources = imagePreviewSources,
|
||||
extraCount = extraCount.takeIf { index == 1 },
|
||||
onLongPress = onLongPress,
|
||||
modifier = Modifier.weight(1f).aspectRatio(1f)
|
||||
)
|
||||
}
|
||||
@@ -2993,6 +2999,7 @@ private fun MediaAlbumGrid(
|
||||
vm = vm,
|
||||
imagePreviewSources = imagePreviewSources,
|
||||
extraCount = extraCount.takeIf { isLastVisibleCell },
|
||||
onLongPress = onLongPress,
|
||||
modifier = Modifier.weight(1f).aspectRatio(1f)
|
||||
)
|
||||
}
|
||||
@@ -3007,12 +3014,14 @@ private fun MediaAlbumGrid(
|
||||
}
|
||||
|
||||
@Composable
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
private fun MediaAlbumCell(
|
||||
attachment: AttachmentDto,
|
||||
session: QMaxSession,
|
||||
vm: QMaxViewModel,
|
||||
imagePreviewSources: List<String>,
|
||||
extraCount: Int?,
|
||||
onLongPress: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val url = rememberAttachmentUrl(session, attachment)
|
||||
@@ -3037,7 +3046,10 @@ private fun MediaAlbumCell(
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.clickable { vm.openImage(previewSource, imagePreviewSources) },
|
||||
.combinedClickable(
|
||||
onClick = { vm.openImage(previewSource, imagePreviewSources) },
|
||||
onLongClick = onLongPress
|
||||
),
|
||||
onSuccess = {
|
||||
imageLoaded = true
|
||||
imageFailed = false
|
||||
@@ -3091,26 +3103,29 @@ private fun AttachmentView(
|
||||
session: QMaxSession,
|
||||
vm: QMaxViewModel,
|
||||
imagePreviewSources: List<String>,
|
||||
mediaShape: RoundedCornerShape
|
||||
mediaShape: RoundedCornerShape,
|
||||
onLongPress: () -> Unit
|
||||
) {
|
||||
val url = rememberAttachmentUrl(session, attachment)
|
||||
val state by vm.state
|
||||
val cachedImagePath = state.cachedImagePaths[attachment.id]
|
||||
when {
|
||||
attachment.isContactAttachment() -> ContactAttachment(attachment, vm)
|
||||
attachment.isContactAttachment() -> ContactAttachment(attachment, vm, onLongPress)
|
||||
attachment.isEmojiAttachment() -> EmojiAttachment(
|
||||
attachment,
|
||||
url,
|
||||
session.accessToken,
|
||||
cachedImagePath,
|
||||
vm
|
||||
vm,
|
||||
onLongPress
|
||||
)
|
||||
attachment.isStickerAttachment() -> StickerAttachment(
|
||||
attachment,
|
||||
url,
|
||||
session.accessToken,
|
||||
cachedImagePath,
|
||||
vm
|
||||
vm,
|
||||
onLongPress
|
||||
)
|
||||
attachment.isImageAttachment() -> ImageAttachment(
|
||||
attachment,
|
||||
@@ -3119,21 +3134,24 @@ private fun AttachmentView(
|
||||
cachedImagePath,
|
||||
vm,
|
||||
imagePreviewSources,
|
||||
mediaShape
|
||||
mediaShape,
|
||||
onLongPress
|
||||
)
|
||||
attachment.isVideoAttachment() -> VideoAttachment(attachment, url, session.accessToken)
|
||||
attachment.isVoiceAttachment() || attachment.isAudioAttachment() -> VoiceAttachment(attachment, url, session.accessToken)
|
||||
else -> FileAttachment(attachment, vm)
|
||||
attachment.isVideoAttachment() -> VideoAttachment(attachment, url, session.accessToken, onLongPress)
|
||||
attachment.isVoiceAttachment() || attachment.isAudioAttachment() -> VoiceAttachment(attachment, url, session.accessToken, onLongPress)
|
||||
else -> FileAttachment(attachment, vm, onLongPress)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
private fun StickerAttachment(
|
||||
attachment: AttachmentDto,
|
||||
url: String,
|
||||
token: String,
|
||||
cachedImagePath: String?,
|
||||
vm: QMaxViewModel
|
||||
vm: QMaxViewModel,
|
||||
onLongPress: () -> Unit
|
||||
) {
|
||||
LaunchedEffect(attachment.id, url) {
|
||||
vm.cacheImage(attachment)
|
||||
@@ -3145,7 +3163,10 @@ private fun StickerAttachment(
|
||||
modifier = Modifier
|
||||
.size(156.dp)
|
||||
.clip(RoundedCornerShape(6.dp))
|
||||
.clickable { vm.openImage(cachedImagePath ?: url, listOf(cachedImagePath ?: url)) },
|
||||
.combinedClickable(
|
||||
onClick = { vm.openImage(cachedImagePath ?: url, listOf(cachedImagePath ?: url)) },
|
||||
onLongClick = onLongPress
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
AsyncImage(
|
||||
@@ -3168,13 +3189,15 @@ private fun StickerAttachment(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
private fun EmojiAttachment(
|
||||
attachment: AttachmentDto,
|
||||
url: String,
|
||||
token: String,
|
||||
cachedImagePath: String?,
|
||||
vm: QMaxViewModel
|
||||
vm: QMaxViewModel,
|
||||
onLongPress: () -> Unit
|
||||
) {
|
||||
LaunchedEffect(attachment.id, url) {
|
||||
vm.cacheImage(attachment)
|
||||
@@ -3185,10 +3208,16 @@ private fun EmojiAttachment(
|
||||
model = model,
|
||||
contentDescription = attachment.fileName,
|
||||
contentScale = ContentScale.Fit,
|
||||
modifier = Modifier.size(emojiSize)
|
||||
modifier = Modifier
|
||||
.size(emojiSize)
|
||||
.combinedClickable(
|
||||
onClick = {},
|
||||
onLongClick = onLongPress
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
private fun ImageAttachment(
|
||||
attachment: AttachmentDto,
|
||||
@@ -3197,7 +3226,8 @@ private fun ImageAttachment(
|
||||
cachedImagePath: String?,
|
||||
vm: QMaxViewModel,
|
||||
imagePreviewSources: List<String>,
|
||||
mediaShape: RoundedCornerShape
|
||||
mediaShape: RoundedCornerShape,
|
||||
onLongPress: () -> Unit
|
||||
) {
|
||||
LaunchedEffect(attachment.id, url) {
|
||||
vm.cacheImage(attachment)
|
||||
@@ -3213,7 +3243,10 @@ private fun ImageAttachment(
|
||||
.aspectRatio(aspectRatio)
|
||||
.clip(mediaShape)
|
||||
.background(Color(0xFFE1E8ED))
|
||||
.clickable { vm.openImage(previewSource, imagePreviewSources) }
|
||||
.combinedClickable(
|
||||
onClick = { vm.openImage(previewSource, imagePreviewSources) },
|
||||
onLongClick = onLongPress
|
||||
)
|
||||
) {
|
||||
AsyncImage(
|
||||
model = model,
|
||||
@@ -3283,14 +3316,19 @@ private fun MediaImagePlaceholder(failed: Boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
private fun VideoAttachment(attachment: AttachmentDto, url: String, token: String) {
|
||||
private fun VideoAttachment(attachment: AttachmentDto, url: String, token: String, onLongPress: () -> Unit) {
|
||||
val player = rememberAuthorizedPlayer(url = url, token = token)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(16f / 9f)
|
||||
.background(Color.Black)
|
||||
.combinedClickable(
|
||||
onClick = {},
|
||||
onLongClick = onLongPress
|
||||
)
|
||||
) {
|
||||
AndroidView(
|
||||
factory = { context ->
|
||||
@@ -3321,11 +3359,23 @@ private fun VideoAttachment(attachment: AttachmentDto, url: String, token: Strin
|
||||
)
|
||||
}
|
||||
}
|
||||
Surface(
|
||||
color = Color(0x99000000),
|
||||
shape = CircleShape,
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopEnd)
|
||||
.padding(6.dp)
|
||||
) {
|
||||
IconButton(onClick = onLongPress, modifier = Modifier.size(36.dp)) {
|
||||
Icon(Icons.AutoMirrored.Filled.Forward, contentDescription = "Переслать", tint = Color.White)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun VoiceAttachment(attachment: AttachmentDto, url: String, token: String) {
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
private fun VoiceAttachment(attachment: AttachmentDto, url: String, token: String, onLongPress: () -> Unit) {
|
||||
val player = rememberAuthorizedPlayer(url = url, token = token)
|
||||
var isPlaying by remember { mutableStateOf(false) }
|
||||
var position by remember { mutableStateOf(0L) }
|
||||
@@ -3343,6 +3393,10 @@ private fun VoiceAttachment(attachment: AttachmentDto, url: String, token: Strin
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.combinedClickable(
|
||||
onClick = {},
|
||||
onLongClick = onLongPress
|
||||
)
|
||||
.padding(horizontal = 2.dp, vertical = 2.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
@@ -3398,15 +3452,19 @@ private fun VoiceAttachment(attachment: AttachmentDto, url: String, token: Strin
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
private fun ContactAttachment(attachment: AttachmentDto, vm: QMaxViewModel) {
|
||||
private fun ContactAttachment(attachment: AttachmentDto, vm: QMaxViewModel, onLongPress: () -> Unit) {
|
||||
val title = attachment.displayFileName()
|
||||
.removeSuffix(".vcf")
|
||||
.ifBlank { "\u041a\u043e\u043d\u0442\u0430\u043a\u0442" }
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { vm.openAttachment(attachment) }
|
||||
.combinedClickable(
|
||||
onClick = { vm.openAttachment(attachment) },
|
||||
onLongClick = onLongPress
|
||||
)
|
||||
.padding(horizontal = 4.dp, vertical = 7.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
@@ -3438,8 +3496,9 @@ private fun ContactAttachment(attachment: AttachmentDto, vm: QMaxViewModel) {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
private fun FileAttachment(attachment: AttachmentDto, vm: QMaxViewModel) {
|
||||
private fun FileAttachment(attachment: AttachmentDto, vm: QMaxViewModel, onLongPress: () -> Unit) {
|
||||
val title = attachment.displayFileName()
|
||||
val subtitle = if (attachment.fileSizeBytes > 0L) {
|
||||
"${formatFileSize(attachment.fileSizeBytes)} \u2022 \u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043a\u0440\u044b\u0442\u044c"
|
||||
@@ -3449,7 +3508,10 @@ private fun FileAttachment(attachment: AttachmentDto, vm: QMaxViewModel) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { vm.openAttachment(attachment) }
|
||||
.combinedClickable(
|
||||
onClick = { vm.openAttachment(attachment) },
|
||||
onLongClick = onLongPress
|
||||
)
|
||||
.padding(horizontal = 4.dp, vertical = 6.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user