1package com.parseable.android.ui.screens.settings
3import androidx.compose.foundation.layout.*
4import androidx.compose.foundation.rememberScrollState
5import androidx.compose.foundation.verticalScroll
6import androidx.compose.material.icons.Icons
7import androidx.compose.material.icons.automirrored.filled.ArrowBack
8import androidx.compose.material.icons.filled.*
9import androidx.compose.material3.*
10import androidx.compose.material3.pulltorefresh.PullToRefreshBox
11import androidx.compose.runtime.*
12import androidx.compose.ui.Alignment
13import androidx.compose.ui.Modifier
14import androidx.compose.ui.text.font.FontWeight
15import androidx.compose.ui.unit.dp
16import androidx.hilt.navigation.compose.hiltViewModel
17import androidx.lifecycle.compose.collectAsStateWithLifecycle
18import com.parseable.android.BuildConfig
19import kotlinx.serialization.json.contentOrNull
20import kotlinx.serialization.json.jsonPrimitive
22@OptIn(ExperimentalMaterial3Api::class)
26 onAboutClick: () -> Unit,
27 viewModel: SettingsViewModel = hiltViewModel(),
29 val state by viewModel.state.collectAsStateWithLifecycle()
34 title = { Text("Settings") },
36 IconButton(onClick = onBack) {
37 Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
44 isRefreshing = state.isLoading,
45 onRefresh = viewModel::load,
53 .verticalScroll(rememberScrollState())
55 verticalArrangement = Arrangement.spacedBy(16.dp),
59 modifier = Modifier.fillMaxWidth(),
60 elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
62 Column(modifier = Modifier.padding(16.dp)) {
63 Row(verticalAlignment = Alignment.CenterVertically) {
66 contentDescription = "Server connection",
67 tint = MaterialTheme.colorScheme.primary,
69 Spacer(modifier = Modifier.width(8.dp))
71 text = "Server Connection",
72 style = MaterialTheme.typography.titleMedium,
73 fontWeight = FontWeight.Bold,
76 Spacer(modifier = Modifier.height(12.dp))
77 SettingsRow("URL", state.serverUrl)
78 SettingsRow("Username", state.username)
79 SettingsRow("TLS", if (state.useTls) "Enabled" else "Disabled")
83 // Loading indicator for server data
84 if (state.isLoading) {
88 .padding(vertical = 8.dp),
89 contentAlignment = Alignment.Center,
92 verticalAlignment = Alignment.CenterVertically,
93 horizontalArrangement = Arrangement.spacedBy(8.dp),
95 CircularProgressIndicator(
96 modifier = Modifier.size(16.dp),
100 text = "Loading server info...",
101 style = MaterialTheme.typography.bodySmall,
102 color = MaterialTheme.colorScheme.onSurfaceVariant,
108 // Error from loading server data
109 state.error?.let { errorText ->
111 colors = CardDefaults.cardColors(
112 containerColor = MaterialTheme.colorScheme.errorContainer,
114 modifier = Modifier.fillMaxWidth(),
117 modifier = Modifier.padding(16.dp),
118 verticalAlignment = Alignment.CenterVertically,
121 Icons.Filled.ErrorOutline,
122 contentDescription = "Error",
123 tint = MaterialTheme.colorScheme.onErrorContainer,
125 Spacer(modifier = Modifier.width(8.dp))
128 color = MaterialTheme.colorScheme.onErrorContainer,
129 style = MaterialTheme.typography.bodyMedium,
136 state.aboutInfo?.let { about ->
138 modifier = Modifier.fillMaxWidth(),
139 elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
141 Column(modifier = Modifier.padding(16.dp)) {
142 Row(verticalAlignment = Alignment.CenterVertically) {
145 contentDescription = "Server info",
146 tint = MaterialTheme.colorScheme.primary,
148 Spacer(modifier = Modifier.width(8.dp))
150 text = "Server Info",
151 style = MaterialTheme.typography.titleMedium,
152 fontWeight = FontWeight.Bold,
155 Spacer(modifier = Modifier.height(12.dp))
156 about.version?.let { SettingsRow("Version", it) }
157 about.commit?.let { SettingsRow("Commit", it.take(12)) }
158 about.mode?.let { SettingsRow("Mode", it) }
159 about.license?.get("name")?.jsonPrimitive?.contentOrNull?.let { SettingsRow("License", it) }
160 about.deploymentId?.let { SettingsRow("Deployment ID", it.take(12)) }
161 about.queryEngine?.let { SettingsRow("Query Engine", it) }
167 if (state.users.isNotEmpty()) {
169 modifier = Modifier.fillMaxWidth(),
170 elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
172 Column(modifier = Modifier.padding(16.dp)) {
173 Row(verticalAlignment = Alignment.CenterVertically) {
176 contentDescription = "Users",
177 tint = MaterialTheme.colorScheme.primary,
179 Spacer(modifier = Modifier.width(8.dp))
181 text = "Users (${state.users.size})",
182 style = MaterialTheme.typography.titleMedium,
183 fontWeight = FontWeight.Bold,
186 Spacer(modifier = Modifier.height(12.dp))
187 state.users.forEach { user ->
190 style = MaterialTheme.typography.bodyMedium,
191 modifier = Modifier.padding(vertical = 4.dp),
200 modifier = Modifier.fillMaxWidth(),
201 elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
203 Column(modifier = Modifier.padding(16.dp)) {
204 Row(verticalAlignment = Alignment.CenterVertically) {
206 Icons.Filled.PhoneAndroid,
207 contentDescription = "App info",
208 tint = MaterialTheme.colorScheme.primary,
210 Spacer(modifier = Modifier.width(8.dp))
213 style = MaterialTheme.typography.titleMedium,
214 fontWeight = FontWeight.Bold,
217 Spacer(modifier = Modifier.height(12.dp))
218 SettingsRow("App Version", BuildConfig.VERSION_NAME)
219 SettingsRow("Platform", "Android")
225 onClick = onAboutClick,
226 modifier = Modifier.fillMaxWidth(),
227 elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
233 verticalAlignment = Alignment.CenterVertically,
237 contentDescription = "About",
238 tint = MaterialTheme.colorScheme.primary,
240 Spacer(modifier = Modifier.width(8.dp))
243 style = MaterialTheme.typography.titleMedium,
244 fontWeight = FontWeight.Bold,
245 modifier = Modifier.weight(1f),
248 Icons.Filled.ChevronRight,
249 contentDescription = null,
250 tint = MaterialTheme.colorScheme.onSurfaceVariant,
260private fun SettingsRow(label: String, value: String) {
264 .padding(vertical = 4.dp),
265 horizontalArrangement = Arrangement.SpaceBetween,
269 style = MaterialTheme.typography.bodyMedium,
270 color = MaterialTheme.colorScheme.onSurfaceVariant,
274 style = MaterialTheme.typography.bodyMedium,
275 fontWeight = FontWeight.Medium,
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