99
1010package com.nextcloud.client.assistant.chat
1111
12+ import android.content.ClipData
1213import androidx.compose.animation.core.LinearEasing
1314import androidx.compose.animation.core.RepeatMode
1415import androidx.compose.animation.core.animateFloat
@@ -17,6 +18,7 @@ import androidx.compose.animation.core.rememberInfiniteTransition
1718import androidx.compose.animation.core.tween
1819import androidx.compose.foundation.Image
1920import androidx.compose.foundation.background
21+ import androidx.compose.foundation.combinedClickable
2022import androidx.compose.foundation.layout.Arrangement
2123import androidx.compose.foundation.layout.Box
2224import androidx.compose.foundation.layout.Column
@@ -36,18 +38,26 @@ import androidx.compose.foundation.shape.CircleShape
3638import androidx.compose.foundation.shape.RoundedCornerShape
3739import androidx.compose.material3.Button
3840import androidx.compose.material3.CircularProgressIndicator
41+ import androidx.compose.material3.DropdownMenu
42+ import androidx.compose.material3.DropdownMenuItem
3943import androidx.compose.material3.Icon
4044import androidx.compose.material3.MaterialTheme
4145import androidx.compose.material3.Text
4246import androidx.compose.runtime.Composable
4347import androidx.compose.runtime.LaunchedEffect
4448import androidx.compose.runtime.collectAsState
4549import androidx.compose.runtime.getValue
50+ import androidx.compose.runtime.mutableStateOf
51+ import androidx.compose.runtime.remember
52+ import androidx.compose.runtime.rememberCoroutineScope
53+ import androidx.compose.runtime.setValue
4654import androidx.compose.ui.Alignment
4755import androidx.compose.ui.Modifier
4856import androidx.compose.ui.draw.clip
4957import androidx.compose.ui.draw.scale
5058import androidx.compose.ui.layout.ContentScale
59+ import androidx.compose.ui.platform.LocalClipboard
60+ import androidx.compose.ui.platform.toClipEntry
5161import androidx.compose.ui.res.colorResource
5262import androidx.compose.ui.res.painterResource
5363import androidx.compose.ui.res.stringResource
@@ -60,6 +70,7 @@ import com.nextcloud.utils.TimeConstants
6070import com.nextcloud.utils.extensions.time
6171import com.owncloud.android.R
6272import com.owncloud.android.lib.resources.assistant.chat.model.ChatMessage
73+ import kotlinx.coroutines.launch
6374import java.time.Instant
6475
6576private val MIN_CHAT_HEIGHT = 60 .dp
@@ -342,6 +353,10 @@ private fun TypingAnimation() {
342353
343354@Composable
344355private fun AssistantMessageItem (message : ChatMessage ) {
356+ var showMenu by remember { mutableStateOf(false ) }
357+ val clipboard = LocalClipboard .current
358+ val scope = rememberCoroutineScope()
359+
345360 Box (
346361 modifier = Modifier
347362 .padding(vertical = 12 .dp)
@@ -375,15 +390,39 @@ private fun AssistantMessageItem(message: ChatMessage) {
375390 )
376391 )
377392 .background(color = colorResource(R .color.bg_message_bubble))
393+ .combinedClickable(
394+ onClick = {},
395+ onLongClick = { showMenu = true }
396+ )
378397 ) {
379398 MessageTextItem (message)
399+ DropdownMenu (
400+ expanded = showMenu,
401+ onDismissRequest = { showMenu = false }
402+ ) {
403+ DropdownMenuItem (
404+ text = { Text (stringResource(R .string.common_copy)) },
405+ onClick = {
406+ scope.launch {
407+ clipboard.setClipEntry(
408+ ClipData .newPlainText(null , message.content).toClipEntry()
409+ )
410+ }
411+ showMenu = false
412+ }
413+ )
414+ }
380415 }
381416 }
382417 }
383418}
384419
385420@Composable
386421private fun UserMessageItem (message : ChatMessage ) {
422+ var showMenu by remember { mutableStateOf(false ) }
423+ val clipboard = LocalClipboard .current
424+ val scope = rememberCoroutineScope()
425+
387426 Box (
388427 modifier = Modifier
389428 .padding(vertical = 12 .dp)
@@ -402,8 +441,28 @@ private fun UserMessageItem(message: ChatMessage) {
402441 )
403442 )
404443 .background(color = colorResource(R .color.bg_message_bubble))
444+ .combinedClickable(
445+ onClick = {},
446+ onLongClick = { showMenu = true }
447+ )
405448 ) {
406449 MessageTextItem (message)
450+ DropdownMenu (
451+ expanded = showMenu,
452+ onDismissRequest = { showMenu = false }
453+ ) {
454+ DropdownMenuItem (
455+ text = { Text (stringResource(R .string.common_copy)) },
456+ onClick = {
457+ scope.launch {
458+ clipboard.setClipEntry(
459+ ClipData .newPlainText(null , message.content).toClipEntry()
460+ )
461+ }
462+ showMenu = false
463+ }
464+ )
465+ }
407466 }
408467 }
409468}
0 commit comments