chore: eliminate all Kotlin compiler warnings in main source (#877)
* chore: eliminate all Kotlin compiler warnings in main source * test(chat): fix cross-class coroutine leaks poisoning the unit suite - ChatUpdateCommandTest: inject FakeSlashUsageStore — the real DataStore store inits on real IO threads with a relaxed-mock app (cacheDir NPE) and leaks an uncaught exception into the next runTest class. - ChatUpdateCommandTest + SlashCommandDispatchRpcTest: mock ProfileSwitchCoordinator.switched (ChatViewModelTest pattern) — VMs otherwise park collectors on the singleton flow that crash later classes (ProfileSwitchCoordinatorTest) on stale-Main resumption. Full suite: 944 tests, 0 failures (was 2 flaky per run). --------- Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
1 parent
b05cffa9c4
commit
1e6e248891
14 files changed
+88
-38
No files matched your search
@@ -135,7 +135,7 @@ private fun BillingContent(
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
) {
|
||||
Text(
|
||||
text = state.errorMessage ?: "",
|
||||
text = state.errorMessage,
|
||||
modifier = Modifier.padding(12.dp),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onErrorContainer,
|
||||
@@ -152,7 +152,7 @@ private fun BillingContent(
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
) {
|
||||
Text(
|
||||
text = state.actionMessage ?: "",
|
||||
text = state.actionMessage,
|
||||
modifier = Modifier.padding(12.dp),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
@@ -207,7 +207,7 @@ private fun PlanCard(subscription: SubscriptionCurrent) {
|
||||
}
|
||||
if (subscription.pending_downgrade_display != null) {
|
||||
Text(
|
||||
text = subscription.pending_downgrade_display ?: "",
|
||||
text = subscription.pending_downgrade_display,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(top = 4.dp),
|
||||
|
||||
@@ -2890,7 +2890,7 @@ class ChatViewModel(
|
||||
if (lastAssistantIdx >= 0) {
|
||||
val target = mapped[lastAssistantIdx]
|
||||
if (target.reasoningText.isBlank()) {
|
||||
mapped[lastAssistantIdx] = target.copy(reasoningText = pendingReasoning!!)
|
||||
mapped[lastAssistantIdx] = target.copy(reasoningText = pendingReasoning)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.InsertDriveFile
|
||||
import androidx.compose.material.icons.automirrored.filled.Send
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.InsertDriveFile
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Icon
|
||||
@@ -405,7 +405,7 @@ fun AttachmentChip(
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
} else {
|
||||
Icon(
|
||||
imageVector = Icons.Default.InsertDriveFile,
|
||||
imageVector = Icons.AutoMirrored.Filled.InsertDriveFile,
|
||||
contentDescription = attachment.name,
|
||||
modifier = Modifier.size(24.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
|
||||
@@ -90,7 +90,7 @@ object ToolViewBuilder {
|
||||
raw = firstString(parseMaybeObject(value), listOf("context"))
|
||||
}
|
||||
|
||||
return compactPreview(raw ?: "", max)
|
||||
return compactPreview(raw, max)
|
||||
}
|
||||
|
||||
private fun contextValue(value: JsonElement?): String {
|
||||
@@ -1328,8 +1328,8 @@ object ToolViewBuilder {
|
||||
val elements = result?.get("elements") as? JsonArray
|
||||
if (elements != null) {
|
||||
val mode = firstString(result, listOf("mode"))
|
||||
val width = intValue(result?.get("width"))
|
||||
val height = intValue(result?.get("height"))
|
||||
val width = intValue(result.get("width"))
|
||||
val height = intValue(result.get("height"))
|
||||
val modePart = mode.takeIf { it.isNotEmpty() }?.let { " ($it)" } ?: ""
|
||||
val sizePart = if (width != null && height != null) " ${width}x$height" else ""
|
||||
return "${elements.size} elements$modePart$sizePart"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package com.m57.hermescontrol.ui.keys
|
||||
|
||||
import android.content.ClipData
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.clickable
|
||||
@@ -29,6 +30,7 @@ import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.outlined.OpenInNew
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.Clear
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
@@ -41,7 +43,6 @@ import androidx.compose.material.icons.outlined.Build
|
||||
import androidx.compose.material.icons.outlined.ContentCopy
|
||||
import androidx.compose.material.icons.outlined.Folder
|
||||
import androidx.compose.material.icons.outlined.Forum
|
||||
import androidx.compose.material.icons.outlined.OpenInNew
|
||||
import androidx.compose.material.icons.outlined.SmartToy
|
||||
import androidx.compose.material.icons.outlined.Tune
|
||||
import androidx.compose.material3.AlertDialog
|
||||
@@ -66,11 +67,13 @@ 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
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.platform.ClipEntry
|
||||
import androidx.compose.ui.platform.LocalClipboard
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
@@ -97,6 +100,7 @@ import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||
import com.m57.hermescontrol.ui.common.StatusBadge
|
||||
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
private const val FILTER_ALL = "ALL"
|
||||
|
||||
@@ -527,8 +531,9 @@ private fun EnvVarCard(
|
||||
val isRevealed = revealedValue != null
|
||||
var editedValue by remember(config, revealedValue) { mutableStateOf(revealedValue ?: "") }
|
||||
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
val clipboard = LocalClipboard.current
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
val displayValue =
|
||||
if (isRevealed) {
|
||||
@@ -645,7 +650,7 @@ private fun EnvVarCard(
|
||||
}.padding(vertical = 2.dp),
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.OpenInNew,
|
||||
imageVector = Icons.AutoMirrored.Outlined.OpenInNew,
|
||||
contentDescription = stringResource(R.string.keys_action_open_url),
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(14.dp),
|
||||
@@ -759,7 +764,10 @@ private fun EnvVarCard(
|
||||
}
|
||||
if (isRevealed && !revealedValue.isNullOrEmpty()) {
|
||||
IconButton(onClick = {
|
||||
clipboardManager.setText(AnnotatedString(revealedValue))
|
||||
val text = AnnotatedString(revealedValue)
|
||||
scope.launch {
|
||||
clipboard.setClipEntry(ClipEntry(ClipData.newPlainText(null, text)))
|
||||
}
|
||||
onShowToast(copiedMessage)
|
||||
}) {
|
||||
Icon(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.m57.hermescontrol.ui.profiles
|
||||
|
||||
import android.content.ClipData
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -41,11 +42,13 @@ 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
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.platform.ClipEntry
|
||||
import androidx.compose.ui.platform.LocalClipboard
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
@@ -64,6 +67,7 @@ import com.m57.hermescontrol.ui.common.ToastEffect
|
||||
import com.m57.hermescontrol.ui.model.components.ModelPickerDialog
|
||||
import com.m57.hermescontrol.ui.profiles.components.ProfileBuilderView
|
||||
import com.m57.hermescontrol.ui.profiles.components.validateProfileName
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -91,7 +95,8 @@ fun ProfilesScreen(
|
||||
var setupCmdProfileName by remember { mutableStateOf<String?>(null) }
|
||||
var copiedSetupCmd by remember { mutableStateOf(false) }
|
||||
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
val clipboard = LocalClipboard.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
var isBuildingProfile by remember { mutableStateOf(false) }
|
||||
|
||||
@@ -839,7 +844,8 @@ fun ProfilesScreen(
|
||||
if (!state.isLoadingSetupCommand && state.setupCommand != null) {
|
||||
Button(
|
||||
onClick = {
|
||||
clipboardManager.setText(AnnotatedString(state.setupCommand.orEmpty()))
|
||||
val text = AnnotatedString(state.setupCommand.orEmpty())
|
||||
scope.launch { clipboard.setClipEntry(ClipEntry(ClipData.newPlainText(null, text))) }
|
||||
copiedSetupCmd = true
|
||||
},
|
||||
) {
|
||||
|
||||
@@ -288,7 +288,7 @@ class ToolsetDetailViewModel : ViewModel(), ToastHost {
|
||||
state.copy(
|
||||
postSetup =
|
||||
state.postSetup?.copy(
|
||||
lines = data.lines ?: state.postSetup?.lines ?: emptyList(),
|
||||
lines = data.lines ?: state.postSetup.lines,
|
||||
running = data.running == true,
|
||||
exitCode = data.exit_code,
|
||||
),
|
||||
|
||||
Reference in new issue
Block a user