From 33770d87a60fe5d219224e34ff2c72447e8ba6b6 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Tue, 8 Sep 2026 22:08:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(chat):=20=E5=9B=9E=E8=BD=A6=E5=8F=91?= =?UTF-8?q?=E9=80=81=20+=20=E9=95=BF=E6=8C=89=E6=B0=94=E6=B3=A1=E5=A4=8D?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 输入框 imeAction=Send(回车即发送);长按气泡体复制原文到剪贴板并 Toast 提示。 --- .../top/yeij/cyrene/ui/chat/ChatScreen.kt | 5 +++ .../top/yeij/cyrene/ui/chat/Clipboard.kt | 32 +++++++++++++++++++ .../top/yeij/cyrene/ui/chat/MessageBubble.kt | 1 + 3 files changed, 38 insertions(+) create mode 100644 app/src/main/kotlin/top/yeij/cyrene/ui/chat/Clipboard.kt diff --git a/app/src/main/kotlin/top/yeij/cyrene/ui/chat/ChatScreen.kt b/app/src/main/kotlin/top/yeij/cyrene/ui/chat/ChatScreen.kt index 768418c..ccd8f22 100644 --- a/app/src/main/kotlin/top/yeij/cyrene/ui/chat/ChatScreen.kt +++ b/app/src/main/kotlin/top/yeij/cyrene/ui/chat/ChatScreen.kt @@ -16,6 +16,8 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -26,6 +28,7 @@ import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.initializer @@ -195,6 +198,8 @@ private fun InputBar( label = "和昔涟说点什么…", useLabelAsPlaceholder = true, maxLines = 5, + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Send), + keyboardActions = KeyboardActions(onSend = { onSend() }), modifier = Modifier.weight(1f), ) Spacer(Modifier.width(8.dp)) diff --git a/app/src/main/kotlin/top/yeij/cyrene/ui/chat/Clipboard.kt b/app/src/main/kotlin/top/yeij/cyrene/ui/chat/Clipboard.kt new file mode 100644 index 0000000..9afd758 --- /dev/null +++ b/app/src/main/kotlin/top/yeij/cyrene/ui/chat/Clipboard.kt @@ -0,0 +1,32 @@ +package top.yeij.cyrene.ui.chat + +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context +import android.widget.Toast +import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalContext + +/** + * 长按复制文本到系统剪贴板,并给一条 Toast 反馈。 + * 用框架的 ClipboardManager 而不是 Compose 的 LocalClipboardManager(后者在新版本已弃用)。 + */ +@Composable +fun Modifier.copyOnLongPress(text: String): Modifier { + if (text.isBlank()) return this + val context = LocalContext.current + return this.pointerInput(text) { + detectTapGestures( + onLongPress = { copyToClipboard(context, text) }, + ) + } +} + +private fun copyToClipboard(context: Context, text: String) { + val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + clipboard.setPrimaryClip(ClipData.newPlainText("Cyrene", text)) + Toast.makeText(context, "已复制", Toast.LENGTH_SHORT).show() +} diff --git a/app/src/main/kotlin/top/yeij/cyrene/ui/chat/MessageBubble.kt b/app/src/main/kotlin/top/yeij/cyrene/ui/chat/MessageBubble.kt index 84a9718..0ab8a9c 100644 --- a/app/src/main/kotlin/top/yeij/cyrene/ui/chat/MessageBubble.kt +++ b/app/src/main/kotlin/top/yeij/cyrene/ui/chat/MessageBubble.kt @@ -143,6 +143,7 @@ private fun BubbleBody(text: String, isUser: Boolean) { Box( modifier = Modifier .widthIn(max = 300.dp) + .copyOnLongPress(text) .background( color = if (isUser) { MiuixTheme.colorScheme.primary