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.size
11import androidx.compose.foundation.layout.widthIn
12import androidx.compose.foundation.rememberScrollState
13import androidx.compose.foundation.text.KeyboardActions
14import androidx.compose.foundation.text.KeyboardOptions
15import androidx.compose.foundation.verticalScroll
16import androidx.compose.material.icons.Icons
17import androidx.compose.material.icons.automirrored.filled.ArrowBack
18import androidx.compose.material3.Button
19import androidx.compose.material3.CircularProgressIndicator
20import androidx.compose.material3.ExperimentalMaterial3Api
21import androidx.compose.material3.Icon
22import androidx.compose.material3.IconButton
23import androidx.compose.material3.MaterialTheme
24import androidx.compose.material3.OutlinedTextField
25import androidx.compose.material3.Scaffold
26import androidx.compose.material3.Text
27import androidx.compose.material3.TopAppBar
28import androidx.compose.runtime.Composable
29import androidx.compose.runtime.getValue
30import androidx.compose.ui.Alignment
31import androidx.compose.ui.Modifier
32import androidx.compose.ui.text.input.ImeAction
33import androidx.compose.ui.text.input.KeyboardType
34import androidx.compose.ui.text.input.PasswordVisualTransformation
35import androidx.compose.ui.res.stringResource
36import androidx.compose.ui.unit.dp
37import androidx.lifecycle.compose.collectAsStateWithLifecycle
38import androidx.lifecycle.viewmodel.compose.viewModel
39import soy.iko.opencode.di.AppContainer
40import soy.iko.opencode.R
41import soy.iko.opencode.ui.vmFactory
43@OptIn(ExperimentalMaterial3Api::class)
46 container: AppContainer,
50 val vm: ServerEditViewModel =
51 viewModel(factory = vmFactory { ServerEditViewModel(container, profileId) })
52 val state by vm.state.collectAsStateWithLifecycle()
57 title = { Text(if (state.isNew) stringResource(R.string.add_server) else stringResource(R.string.edit_server)) },
59 IconButton(onClick = onDone) {
60 Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.back))
67 Box(modifier = Modifier.fillMaxSize().padding(padding), contentAlignment = Alignment.Center) {
68 CircularProgressIndicator()
75 .widthIn(max = 600.dp)
77 .verticalScroll(rememberScrollState()),
78 verticalArrangement = Arrangement.spacedBy(12.dp),
82 onValueChange = { v -> vm.update { it.copy(label = v) } },
83 label = { Text(stringResource(R.string.label_optional)) },
85 keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
86 modifier = Modifier.fillMaxWidth(),
89 value = state.baseUrl,
90 onValueChange = { v -> vm.update { it.copy(baseUrl = v) } },
91 label = { Text(stringResource(R.string.base_url)) },
92 placeholder = { Text(stringResource(R.string.base_url_hint)) },
94 keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri, imeAction = ImeAction.Next),
95 modifier = Modifier.fillMaxWidth(),
98 stringResource(R.string.auth_help),
99 style = androidx.compose.material3.MaterialTheme.typography.bodySmall,
102 value = state.username,
103 onValueChange = { v -> vm.update { it.copy(username = v) } },
104 label = { Text(stringResource(R.string.username_optional)) },
106 keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
107 modifier = Modifier.fillMaxWidth(),
110 value = state.password,
111 onValueChange = { v -> vm.update { it.copy(password = v) } },
112 label = { Text(stringResource(R.string.password_optional)) },
114 visualTransformation = PasswordVisualTransformation(),
115 keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done),
116 keyboardActions = KeyboardActions(onDone = { if (state.canSave && !state.saving) vm.save(onDone) }),
117 modifier = Modifier.fillMaxWidth(),
120 onClick = { vm.save(onDone) },
121 enabled = state.canSave && !state.saving,
122 modifier = Modifier.fillMaxWidth(),
125 CircularProgressIndicator(
126 modifier = Modifier.size(20.dp),
127 color = MaterialTheme.colorScheme.onPrimary,
130 Text(stringResource(R.string.saving), modifier = Modifier.padding(start = 8.dp))
132 Text(stringResource(R.string.save))
135 state.error?.let { message ->
138 color = androidx.compose.material3.MaterialTheme.colorScheme.error,
139 style = androidx.compose.material3.MaterialTheme.typography.bodySmall,
140 modifier = Modifier.fillMaxWidth(),
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list