diff --git a/core/resources/src/commonMain/composeResources/values/strings.xml b/core/resources/src/commonMain/composeResources/values/strings.xml
index 87268ecda..2c29ae3aa 100644
--- a/core/resources/src/commonMain/composeResources/values/strings.xml
+++ b/core/resources/src/commonMain/composeResources/values/strings.xml
@@ -1276,4 +1276,12 @@
Filter
Remove filter
Show air quality legend
+ Show message status
+ Send reply
+ Copy message
+ Select message
+ Delete message
+ React with emoji
+ Select device
+ Select network
diff --git a/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/components/DeviceListItem.kt b/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/components/DeviceListItem.kt
index a4d8ecdd8..14f4dc42b 100644
--- a/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/components/DeviceListItem.kt
+++ b/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/components/DeviceListItem.kt
@@ -17,13 +17,13 @@
package org.meshtastic.feature.connections.ui.components
import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.selection.selectable
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
@@ -41,11 +41,15 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.selected
+import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.ConnectionState
import org.meshtastic.core.resources.Res
+import org.meshtastic.core.resources.action_select_device
import org.meshtastic.core.resources.add
import org.meshtastic.core.resources.bluetooth
import org.meshtastic.core.resources.network
@@ -108,11 +112,19 @@ fun DeviceListItem(
is DeviceListEntry.Mock -> stringResource(Res.string.add)
}
+ val selectLabel = stringResource(Res.string.action_select_device)
+ val isSelected = connectionState is ConnectionState.Connected
val clickableModifier =
if (onDelete != null) {
- Modifier.combinedClickable(onClick = onSelect, onLongClick = onDelete)
+ Modifier.semantics { selected = isSelected }
+ .combinedClickable(
+ onClickLabel = selectLabel,
+ role = Role.RadioButton,
+ onClick = onSelect,
+ onLongClick = onDelete,
+ )
} else {
- Modifier.clickable(onClick = onSelect)
+ Modifier.selectable(selected = isSelected, role = Role.RadioButton, onClick = onSelect)
}
ListItem(
diff --git a/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/component/MessageActionsBottomSheet.kt b/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/component/MessageActionsBottomSheet.kt
index c4c99720c..5ffb5ea1d 100644
--- a/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/component/MessageActionsBottomSheet.kt
+++ b/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/component/MessageActionsBottomSheet.kt
@@ -36,11 +36,18 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
+import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.MessageStatus
import org.meshtastic.core.resources.Res
+import org.meshtastic.core.resources.action_copy_message
+import org.meshtastic.core.resources.action_delete_message
+import org.meshtastic.core.resources.action_react_with_emoji
+import org.meshtastic.core.resources.action_select_message
+import org.meshtastic.core.resources.action_send_reply
+import org.meshtastic.core.resources.action_show_message_status
import org.meshtastic.core.resources.copy
import org.meshtastic.core.resources.delete
import org.meshtastic.core.resources.device_metrics_label_value
@@ -55,6 +62,7 @@ import org.meshtastic.core.ui.icon.MeshtasticIcons
import org.meshtastic.core.ui.icon.Reply
import org.meshtastic.core.ui.icon.SelectAll
+@Suppress("LongMethod")
@Composable
fun MessageActionsContent(
quickEmojis: List,
@@ -83,20 +91,35 @@ fun MessageActionsContent(
Text(stringResource(Res.string.device_metrics_label_value, title, statusText.orEmpty()))
},
leadingContent = { MessageStatusIcon(status = status) },
- modifier = Modifier.clickable(onClick = onStatus),
+ modifier =
+ Modifier.clickable(
+ onClickLabel = stringResource(Res.string.action_show_message_status),
+ role = Role.Button,
+ onClick = onStatus,
+ ),
)
}
ListItem(
headlineContent = { Text(stringResource(Res.string.reply)) },
leadingContent = { Icon(MeshtasticIcons.Reply, contentDescription = stringResource(Res.string.reply)) },
- modifier = Modifier.clickable(onClick = onReply),
+ modifier =
+ Modifier.clickable(
+ onClickLabel = stringResource(Res.string.action_send_reply),
+ role = Role.Button,
+ onClick = onReply,
+ ),
)
ListItem(
headlineContent = { Text(stringResource(Res.string.copy)) },
leadingContent = { Icon(MeshtasticIcons.Copy, contentDescription = stringResource(Res.string.copy)) },
- modifier = Modifier.clickable(onClick = onCopy),
+ modifier =
+ Modifier.clickable(
+ onClickLabel = stringResource(Res.string.action_copy_message),
+ role = Role.Button,
+ onClick = onCopy,
+ ),
)
ListItem(
@@ -104,13 +127,23 @@ fun MessageActionsContent(
leadingContent = {
Icon(MeshtasticIcons.SelectAll, contentDescription = stringResource(Res.string.select))
},
- modifier = Modifier.clickable(onClick = onSelect),
+ modifier =
+ Modifier.clickable(
+ onClickLabel = stringResource(Res.string.action_select_message),
+ role = Role.Button,
+ onClick = onSelect,
+ ),
)
ListItem(
headlineContent = { Text(stringResource(Res.string.delete)) },
leadingContent = { Icon(MeshtasticIcons.Delete, contentDescription = stringResource(Res.string.delete)) },
- modifier = Modifier.clickable(onClick = onDelete),
+ modifier =
+ Modifier.clickable(
+ onClickLabel = stringResource(Res.string.action_delete_message),
+ role = Role.Button,
+ onClick = onDelete,
+ ),
)
}
}
@@ -130,7 +163,12 @@ private fun QuickEmojiRow(quickEmojis: List, onReact: (String) -> Unit,
Modifier.size(40.dp)
.clip(CircleShape)
.background(MaterialTheme.colorScheme.surfaceVariant)
- .clickable { onReact(emoji) },
+ .clickable(
+ onClickLabel = stringResource(Res.string.action_react_with_emoji),
+ role = Role.Button,
+ ) {
+ onReact(emoji)
+ },
contentAlignment = Alignment.Center,
) {
Text(text = emoji, style = MaterialTheme.typography.titleMedium)
diff --git a/feature/wifi-provision/src/commonMain/kotlin/org/meshtastic/feature/wifiprovision/ui/WifiProvisionScreen.kt b/feature/wifi-provision/src/commonMain/kotlin/org/meshtastic/feature/wifiprovision/ui/WifiProvisionScreen.kt
index 015a4e08b..397710fea 100644
--- a/feature/wifi-provision/src/commonMain/kotlin/org/meshtastic/feature/wifiprovision/ui/WifiProvisionScreen.kt
+++ b/feature/wifi-provision/src/commonMain/kotlin/org/meshtastic/feature/wifiprovision/ui/WifiProvisionScreen.kt
@@ -76,6 +76,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback
+import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
@@ -87,6 +88,7 @@ import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.meshtastic.core.resources.Res
+import org.meshtastic.core.resources.action_select_network
import org.meshtastic.core.resources.apply
import org.meshtastic.core.resources.back
import org.meshtastic.core.resources.cancel
@@ -489,7 +491,12 @@ internal fun NetworkRow(network: WifiNetwork, isSelected: Boolean, onClick: () -
}
},
colors = ListItemDefaults.colors(containerColor = containerColor),
- modifier = Modifier.clickable(onClick = onClick),
+ modifier =
+ Modifier.clickable(
+ onClickLabel = stringResource(Res.string.action_select_network),
+ role = Role.Button,
+ onClick = onClick,
+ ),
)
}