git.iko.soy/opencode-android
on 3e723a1 help sign in
135 lines 5.9 kB history raw
1package soy.iko.opencode.ui.server
3import androidx.compose.foundation.layout.Arrangement
4import androidx.compose.foundation.layout.Box
5import androidx.compose.foundation.layout.Column
6import androidx.compose.foundation.layout.fillMaxSize
7import androidx.compose.foundation.layout.fillMaxWidth
8import androidx.compose.foundation.layout.imePadding
9import androidx.compose.foundation.layout.padding
10import androidx.compose.foundation.layout.widthIn
11import androidx.compose.foundation.rememberScrollState
12import androidx.compose.foundation.text.KeyboardActions
13import androidx.compose.foundation.text.KeyboardOptions
14import androidx.compose.foundation.verticalScroll
15import androidx.compose.material.icons.Icons
16import androidx.compose.material.icons.automirrored.filled.ArrowBack
17import androidx.compose.material3.Button
18import androidx.compose.material3.CircularProgressIndicator
19import androidx.compose.material3.ExperimentalMaterial3Api
20import androidx.compose.material3.Icon
21import androidx.compose.material3.IconButton
22import androidx.compose.material3.OutlinedTextField
23import androidx.compose.material3.Scaffold
24import androidx.compose.material3.Text
25import androidx.compose.material3.TopAppBar
26import androidx.compose.runtime.Composable
27import androidx.compose.runtime.getValue
28import androidx.compose.ui.Alignment
29import androidx.compose.ui.Modifier
30import androidx.compose.ui.text.input.ImeAction
31import androidx.compose.ui.text.input.KeyboardType
32import androidx.compose.ui.text.input.PasswordVisualTransformation
33import androidx.compose.ui.res.stringResource
34import androidx.compose.ui.unit.dp
35import androidx.lifecycle.compose.collectAsStateWithLifecycle
36import androidx.lifecycle.viewmodel.compose.viewModel
37import soy.iko.opencode.di.AppContainer
38import soy.iko.opencode.R
39import soy.iko.opencode.ui.vmFactory
41@OptIn(ExperimentalMaterial3Api::class)
42@Composable
43fun ServerEditScreen(
44 container: AppContainer,
45 profileId: String?,
46 onDone: () -> Unit,
47) {
48 val vm: ServerEditViewModel =
49 viewModel(factory = vmFactory { ServerEditViewModel(container, profileId) })
50 val state by vm.state.collectAsStateWithLifecycle()
52 Scaffold(
53 topBar = {
54 TopAppBar(
55 title = { Text(if (state.isNew) stringResource(R.string.add_server) else stringResource(R.string.edit_server)) },
56 navigationIcon = {
57 IconButton(onClick = onDone) {
58 Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.back))
59 }
60 },
61 )
62 },
63 ) { padding ->
64 if (!state.loaded) {
65 Box(modifier = Modifier.fillMaxSize().padding(padding), contentAlignment = Alignment.Center) {
66 CircularProgressIndicator()
67 }
68 } else {
69 Column(
70 modifier = Modifier
71 .padding(padding)
72 .imePadding()
73 .widthIn(max = 600.dp)
74 .padding(16.dp)
75 .verticalScroll(rememberScrollState()),
76 verticalArrangement = Arrangement.spacedBy(12.dp),
77 ) {
78 OutlinedTextField(
79 value = state.label,
80 onValueChange = { v -> vm.update { it.copy(label = v) } },
81 label = { Text(stringResource(R.string.label_optional)) },
82 singleLine = true,
83 keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
84 modifier = Modifier.fillMaxWidth(),
85 )
86 OutlinedTextField(
87 value = state.baseUrl,
88 onValueChange = { v -> vm.update { it.copy(baseUrl = v) } },
89 label = { Text(stringResource(R.string.base_url)) },
90 placeholder = { Text(stringResource(R.string.base_url_hint)) },
91 singleLine = true,
92 keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri, imeAction = ImeAction.Next),
93 modifier = Modifier.fillMaxWidth(),
94 )
95 Text(
96 stringResource(R.string.auth_help),
97 style = androidx.compose.material3.MaterialTheme.typography.bodySmall,
98 )
99 OutlinedTextField(
100 value = state.username,
101 onValueChange = { v -> vm.update { it.copy(username = v) } },
102 label = { Text(stringResource(R.string.username_optional)) },
103 singleLine = true,
104 keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
105 modifier = Modifier.fillMaxWidth(),
106 )
107 OutlinedTextField(
108 value = state.password,
109 onValueChange = { v -> vm.update { it.copy(password = v) } },
110 label = { Text(stringResource(R.string.password_optional)) },
111 singleLine = true,
112 visualTransformation = PasswordVisualTransformation(),
113 keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done),
114 keyboardActions = KeyboardActions(onDone = { if (state.canSave) vm.save(onDone) }),
115 modifier = Modifier.fillMaxWidth(),
116 )
117 Button(
118 onClick = { vm.save(onDone) },
119 enabled = state.canSave,
120 modifier = Modifier.fillMaxWidth(),
121 ) {
122 Text(stringResource(R.string.save))
123 }
124 state.error?.let { message ->
125 Text(
126 message,
127 color = androidx.compose.material3.MaterialTheme.colorScheme.error,
128 style = androidx.compose.material3.MaterialTheme.typography.bodySmall,
129 modifier = Modifier.fillMaxWidth(),
130 )
131 }
132 }
133 }
134 }