package soy.iko.opencode.ui.server import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.layout.Arrangement import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import soy.iko.opencode.di.AppContainer import soy.iko.opencode.ui.vmFactory @OptIn(ExperimentalMaterial3Api::class) @Composable fun ServerEditScreen( container: AppContainer, profileId: String?, onDone: () -> Unit, ) { val vm: ServerEditViewModel = viewModel(factory = vmFactory { ServerEditViewModel(container, profileId) }) val state by vm.state.collectAsStateWithLifecycle() Scaffold( topBar = { TopAppBar( title = { Text(if (state.isNew) "Add server" else "Edit server") }, navigationIcon = { IconButton(onClick = onDone) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back") } }, ) }, ) { padding -> Column( modifier = Modifier .padding(padding) .padding(16.dp) .verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(12.dp), ) { OutlinedTextField( value = state.label, onValueChange = { v -> vm.update { it.copy(label = v) } }, label = { Text("Label (optional)") }, singleLine = true, modifier = Modifier.fillMaxWidth(), ) OutlinedTextField( value = state.baseUrl, onValueChange = { v -> vm.update { it.copy(baseUrl = v) } }, label = { Text("Base URL") }, placeholder = { Text("http://192.168.1.10:4096") }, singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri), modifier = Modifier.fillMaxWidth(), ) Text( "Auth is optional — only needed if the server runs with OPENCODE_SERVER_PASSWORD. " + "Username defaults to \"opencode\".", style = androidx.compose.material3.MaterialTheme.typography.bodySmall, ) OutlinedTextField( value = state.username, onValueChange = { v -> vm.update { it.copy(username = v) } }, label = { Text("Username (optional)") }, singleLine = true, modifier = Modifier.fillMaxWidth(), ) OutlinedTextField( value = state.password, onValueChange = { v -> vm.update { it.copy(password = v) } }, label = { Text("Password (optional)") }, singleLine = true, visualTransformation = PasswordVisualTransformation(), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), modifier = Modifier.fillMaxWidth(), ) Button( onClick = { vm.save(onDone) }, enabled = state.canSave, modifier = Modifier.fillMaxWidth(), ) { Text("Save") } } } }