git.iko.soy/opencode-android
on 66d239c help sign in
91 lines 3.9 kB history raw
1package soy.iko.opencode.ui.chat
3import androidx.compose.foundation.clickable
4import androidx.compose.foundation.layout.Column
5import androidx.compose.foundation.layout.fillMaxWidth
6import androidx.compose.foundation.layout.heightIn
7import androidx.compose.foundation.layout.padding
8import androidx.compose.foundation.lazy.LazyColumn
9import androidx.compose.foundation.lazy.items
10import androidx.compose.material.icons.Icons
11import androidx.compose.material.icons.automirrored.filled.PlaylistPlay
12import androidx.compose.material3.CircularProgressIndicator
13import androidx.compose.material3.ExperimentalMaterial3Api
14import androidx.compose.material3.Icon
15import androidx.compose.material3.MaterialTheme
16import androidx.compose.material3.ModalBottomSheet
17import androidx.compose.material3.Text
18import androidx.compose.runtime.Composable
19import androidx.compose.ui.Alignment
20import androidx.compose.ui.Modifier
21import androidx.compose.ui.res.stringResource
22import androidx.compose.ui.semantics.Role
23import androidx.compose.ui.semantics.role
24import androidx.compose.ui.text.style.TextOverflow
25import androidx.compose.ui.unit.dp
26import androidx.compose.foundation.layout.Box
27import soy.iko.opencode.data.model.Command
28import soy.iko.opencode.R
30/** Bottom sheet that lists slash-commands; selecting one invokes it. */
31@OptIn(ExperimentalMaterial3Api::class)
32@Composable
33fun CommandPickerSheet(
34 commands: List<Command>,
35 loading: Boolean,
36 onSelect: (Command) -> Unit,
37 onDismiss: () -> Unit,
38) {
39 ModalBottomSheet(onDismissRequest = onDismiss) {
40 Text(
41 stringResource(R.string.commands),
42 style = MaterialTheme.typography.titleMedium,
43 modifier = Modifier.padding(start = 24.dp, end = 24.dp, bottom = 8.dp),
44 )
45 if (loading) {
46 Box(
47 modifier = Modifier.fillMaxWidth().padding(vertical = 24.dp),
48 contentAlignment = Alignment.Center,
49 ) {
50 CircularProgressIndicator()
51 }
52 } else if (commands.isEmpty()) {
53 Text(
54 stringResource(R.string.no_commands),
55 style = MaterialTheme.typography.bodyMedium,
56 color = MaterialTheme.colorScheme.onSurfaceVariant,
57 modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp),
58 )
59 } else {
60 LazyColumn(modifier = Modifier.fillMaxWidth().heightIn(max = 420.dp)) {
61 items(commands, key = { it.name }) { cmd ->
62 Column(
63 modifier = Modifier
64 .fillMaxWidth()
65 .clickable(role = Role.Button) { onSelect(cmd); onDismiss() }
66 .padding(horizontal = 24.dp, vertical = 12.dp),
67 ) {
68 androidx.compose.foundation.layout.Row(
69 verticalAlignment = androidx.compose.ui.Alignment.CenterVertically,
70 ) {
71 Icon(Icons.AutoMirrored.Filled.PlaylistPlay, contentDescription = null)
72 Text(
73 "/${cmd.name}",
74 style = MaterialTheme.typography.bodyLarge,
75 modifier = Modifier.padding(start = 8.dp),
76 )
77 }
78 Text(
79 cmd.displayDescription,
80 style = MaterialTheme.typography.bodySmall,
81 color = MaterialTheme.colorScheme.onSurfaceVariant,
82 maxLines = 2,
83 overflow = TextOverflow.Ellipsis,
84 modifier = Modifier.padding(start = 28.dp, top = 2.dp),
85 )
86 }
87 }
88 }
89 }
90 }