Abrarul8541 commited on
Commit
892f900
·
verified ·
1 Parent(s): 83baf04

Phase 1/4: terminal-style console UI (CLI mode)

Browse files
app/src/main/java/io/github/abrarul/modularai/ConsoleActivity.kt ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package io.github.abrarul.modularai
2
+
3
+ import android.os.Bundle
4
+ import androidx.activity.ComponentActivity
5
+ import androidx.activity.compose.setContent
6
+ import androidx.compose.foundation.background
7
+ import androidx.compose.foundation.layout.*
8
+ import androidx.compose.foundation.lazy.LazyColumn
9
+ import androidx.compose.foundation.lazy.items
10
+ import androidx.compose.foundation.lazy.rememberLazyListState
11
+ import androidx.compose.material3.*
12
+ import androidx.compose.runtime.*
13
+ import androidx.compose.ui.Modifier
14
+ import androidx.compose.ui.graphics.Color
15
+ import androidx.compose.ui.text.font.FontFamily
16
+ import androidx.compose.ui.unit.dp
17
+ import androidx.compose.ui.unit.sp
18
+ import androidx.lifecycle.lifecycleScope
19
+ import io.github.abrarul.modularai.cli.Cli
20
+ import kotlinx.coroutines.launch
21
+
22
+ class ConsoleActivity : ComponentActivity() {
23
+ private val cli by lazy { Cli(this) }
24
+ private val lines = mutableStateListOf("ModularAI console. Type 'help'.")
25
+
26
+ private fun append(s: String) = runOnUiThread {
27
+ lines.add(s)
28
+ while (lines.size > 2000) lines.removeAt(0)
29
+ }
30
+
31
+ override fun onCreate(savedInstanceState: Bundle?) {
32
+ super.onCreate(savedInstanceState)
33
+ setContent {
34
+ MaterialTheme(colorScheme = darkColorScheme()) {
35
+ var input by remember { mutableStateOf("") }
36
+ var busy by remember { mutableStateOf(false) }
37
+ val history = remember { mutableStateListOf<String>() }
38
+ var hIdx by remember { mutableIntStateOf(0) }
39
+ val list = rememberLazyListState()
40
+ LaunchedEffect(lines.size) { if (lines.isNotEmpty()) list.scrollToItem(lines.size - 1) }
41
+
42
+ fun run() {
43
+ val cmd = input.trim()
44
+ if (cmd.isEmpty() || busy) return
45
+ input = ""; history.add(cmd); hIdx = history.size
46
+ append("$ $cmd")
47
+ busy = true
48
+ lifecycleScope.launch {
49
+ cli.exec(cmd, ::append)
50
+ busy = false
51
+ }
52
+ }
53
+
54
+ Column(Modifier.fillMaxSize().background(Color(0xFF0B0F14)).statusBarsPadding().navigationBarsPadding().imePadding()) {
55
+ LazyColumn(Modifier.weight(1f).padding(horizontal = 8.dp), state = list) {
56
+ items(lines) { Text(it, fontFamily = FontFamily.Monospace, fontSize = 12.sp, color = Color(0xFFD6E2F0)) }
57
+ }
58
+ Row(Modifier.fillMaxWidth().padding(8.dp)) {
59
+ OutlinedTextField(
60
+ value = input, onValueChange = { input = it },
61
+ modifier = Modifier.weight(1f), singleLine = true,
62
+ placeholder = { Text(if (busy) "running..." else "command") }
63
+ )
64
+ Spacer(Modifier.width(6.dp))
65
+ Button(onClick = { if (hIdx > 0) { hIdx--; input = history[hIdx] } }, enabled = history.isNotEmpty()) { Text("^") }
66
+ Spacer(Modifier.width(6.dp))
67
+ Button(onClick = ::run, enabled = !busy) { Text("Run") }
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }