fix(#391): resolve 5 deprecation warnings (#392)

* fix(#391): resolve deprecation warnings

- Icon: Icons.Filled.ArrowForward → Icons.AutoMirrored.Filled.ArrowForward (KanbanScreen)
- Room: fallbackToDestructiveMigration() → fallbackToDestructiveMigration(false) (HermesDatabase)
- Tab: ScrollableTabRow → PrimaryScrollableTabRow (SettingsScreen)
- Clipboard: LocalClipboardManager → LocalClipboard + coroutine-scoped setText (ChatBubble: UserBubble, AssistantBubble, ToolBubble, CopyButton)
- ClickableText: pushStringAnnotation → pushLink(LinkAnnotation.Url), ClickableText → Text with native link handling (ChatBubble: RichText)

* fix(#392): replace deprecated setText with setClipEntry for new Clipboard API

---------

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-06-26 05:25:01 +03:00
1 parent b1fca60511
commit 8d3d8a11e8
4 files changed
+30 -27

No files matched your search

@@ -39,7 +39,7 @@ abstract class HermesDatabase : RoomDatabase() {
HermesDatabase::class.java,
"hermes_control.db",
).openHelperFactory(factory)
.fallbackToDestructiveMigration()
.fallbackToDestructiveMigration(false)
.build()
.also { instance = it }
}
@@ -1,5 +1,6 @@
package com.m57.hermescontrol.ui.chat
import android.content.ClipData
import android.text.format.DateFormat
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
@@ -27,7 +28,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Build
@@ -47,6 +47,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -54,14 +55,15 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.luminance
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.ClipEntry
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontFamily
@@ -82,6 +84,7 @@ import com.m57.hermescontrol.theme.ToolChipColor
import com.m57.hermescontrol.theme.ToolChipColorLight
import com.m57.hermescontrol.theme.UserBubble
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
@@ -141,7 +144,8 @@ private fun UserBubble(
isCurrentMatch: Boolean = false,
modifier: Modifier = Modifier,
) {
val clipboardManager = LocalClipboardManager.current
val clipboard = LocalClipboard.current
val scope = rememberCoroutineScope()
var showCopyButton by remember { mutableStateOf(false) }
// Auto-dismiss copy button after 4 seconds
@@ -255,7 +259,9 @@ private fun UserBubble(
) {
IconButton(
onClick = {
clipboardManager.setText(AnnotatedString(message.content))
scope.launch {
clipboard.setClipEntry(ClipEntry(ClipData.newPlainText(null, message.content)))
}
showCopyButton = false
},
modifier = Modifier.size(32.dp),
@@ -298,7 +304,8 @@ private fun AssistantBubble(
Color(0xFFE8E6EE)
}
}
val clipboardManager = LocalClipboardManager.current
val clipboard = LocalClipboard.current
val scope = rememberCoroutineScope()
var showCopyButton by remember { mutableStateOf(false) }
// Auto-dismiss copy button after 4 seconds
@@ -385,7 +392,9 @@ private fun AssistantBubble(
) {
IconButton(
onClick = {
clipboardManager.setText(AnnotatedString(message.content))
scope.launch {
clipboard.setClipEntry(ClipEntry(ClipData.newPlainText(null, message.content)))
}
showCopyButton = false
},
modifier = Modifier.size(32.dp),
@@ -706,7 +715,8 @@ private fun ToolBubble(
}
val config = ToolSchemaRegistry.getDisplayConfig(message.toolName)
val clipboardManager = LocalClipboardManager.current
val clipboard = LocalClipboard.current
val scope = rememberCoroutineScope()
var showCopyButton by remember { mutableStateOf(false) }
// Auto-dismiss copy button after 4 seconds
@@ -775,7 +785,6 @@ private fun ToolBubble(
CopyButton(
visible = showCopyButton,
textToCopy = message.content,
clipboardManager = clipboardManager,
onCopy = { showCopyButton = false },
modifier =
Modifier
@@ -806,7 +815,6 @@ private fun ToolBubble(
CopyButton(
visible = showCopyButton,
textToCopy = message.content,
clipboardManager = clipboardManager,
onCopy = { showCopyButton = false },
modifier =
Modifier
@@ -845,7 +853,6 @@ private fun ToolBubble(
CopyButton(
visible = showCopyButton,
textToCopy = message.content,
clipboardManager = clipboardManager,
onCopy = { showCopyButton = false },
modifier =
Modifier
@@ -921,10 +928,11 @@ private fun HeaderRow(
private fun CopyButton(
visible: Boolean,
textToCopy: String,
clipboardManager: androidx.compose.ui.platform.ClipboardManager,
onCopy: () -> Unit,
modifier: Modifier = Modifier,
) {
val clipboard = LocalClipboard.current
val scope = rememberCoroutineScope()
AnimatedVisibility(
visible = visible,
enter = fadeIn() + scaleIn(),
@@ -938,7 +946,9 @@ private fun CopyButton(
) {
IconButton(
onClick = {
clipboardManager.setText(AnnotatedString(textToCopy))
scope.launch {
clipboard.setClipEntry(ClipEntry(ClipData.newPlainText(null, textToCopy)))
}
onCopy()
},
modifier = Modifier.size(32.dp),
@@ -964,7 +974,6 @@ private fun RichText(
searchQuery: String = "",
isCurrentMatch: Boolean = false,
) {
val uriHandler = LocalUriHandler.current
val urlPattern = remember { Regex("""https?://[^\s)>\]\u0022\u0027]+""") }
val linkColor = MaterialTheme.colorScheme.primary
val searchHighlightColor = if (isCurrentMatch) Color(0xFFF57C00) else Color(0xFFFFF176).copy(alpha = 0.9f)
@@ -1033,7 +1042,7 @@ private fun RichText(
// URL: https://...
urlPattern.matchAt(src, i) != null -> {
val match = urlPattern.matchAt(src, i)!!
pushStringAnnotation(tag = "URL", annotation = match.value)
pushLink(LinkAnnotation.Url(match.value))
withStyle(
SpanStyle(
color = linkColor,
@@ -1064,15 +1073,9 @@ private fun RichText(
}
}
ClickableText(
Text(
text = annotated,
style = MaterialTheme.typography.bodyMedium.copy(color = textColor),
onClick = { offset: Int ->
annotated
.getStringAnnotations("URL", offset, offset)
.firstOrNull()
?.let { uriHandler.openUri(it.item) }
},
)
}
@@ -17,7 +17,7 @@ import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.ArrowForward
import androidx.compose.material.icons.automirrored.filled.ArrowForward
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CircularProgressIndicator
@@ -253,7 +253,7 @@ fun TaskCard(
if (onMoveRight != null) {
IconButton(onClick = onMoveRight) {
Icon(
imageVector = Icons.Filled.ArrowForward,
imageVector = Icons.AutoMirrored.Filled.ArrowForward,
contentDescription = stringResource(R.string.content_desc_move_right),
)
}
@@ -39,7 +39,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.ScrollableTabRow
import androidx.compose.material3.PrimaryScrollableTabRow
import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.SegmentedButtonDefaults
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
@@ -101,7 +101,7 @@ fun SettingsScreen(
Modifier
.fillMaxSize(),
) {
ScrollableTabRow(
PrimaryScrollableTabRow(
selectedTabIndex = selectedTab.ordinal,
modifier = Modifier.fillMaxWidth(),
edgePadding = 0.dp,