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 viewModel: SettingsViewModel = hiltViewModel(),
28 val state by viewModel.state.collectAsStateWithLifecycle()
33 title = { Text("Settings") },
35 IconButton(onClick = onBack) {
36 Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
43 isRefreshing = state.isLoading,
44 onRefresh = viewModel::load,
52 .verticalScroll(rememberScrollState())
54 verticalArrangement = Arrangement.spacedBy(16.dp),
58 modifier = Modifier.fillMaxWidth(),
59 elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
61 Column(modifier = Modifier.padding(16.dp)) {
62 Row(verticalAlignment = Alignment.CenterVertically) {
65 contentDescription = "Server connection",
66 tint = MaterialTheme.colorScheme.primary,
68 Spacer(modifier = Modifier.width(8.dp))
70 text = "Server Connection",
71 style = MaterialTheme.typography.titleMedium,
72 fontWeight = FontWeight.Bold,
75 Spacer(modifier = Modifier.height(12.dp))
76 SettingsRow("URL", state.serverUrl)
77 SettingsRow("Username", state.username)
78 SettingsRow("TLS", if (state.useTls) "Enabled" else "Disabled")
82 // Loading indicator for server data
83 if (state.isLoading) {
87 .padding(vertical = 8.dp),
88 contentAlignment = Alignment.Center,
91 verticalAlignment = Alignment.CenterVertically,
92 horizontalArrangement = Arrangement.spacedBy(8.dp),
94 CircularProgressIndicator(
95 modifier = Modifier.size(16.dp),
99 text = "Loading server info...",
100 style = MaterialTheme.typography.bodySmall,
101 color = MaterialTheme.colorScheme.onSurfaceVariant,
107 // Error from loading server data
108 state.error?.let { errorText ->
110 colors = CardDefaults.cardColors(
111 containerColor = MaterialTheme.colorScheme.errorContainer,
113 modifier = Modifier.fillMaxWidth(),
116 modifier = Modifier.padding(16.dp),
117 verticalAlignment = Alignment.CenterVertically,
120 Icons.Filled.ErrorOutline,
121 contentDescription = "Error",
122 tint = MaterialTheme.colorScheme.onErrorContainer,
124 Spacer(modifier = Modifier.width(8.dp))
127 color = MaterialTheme.colorScheme.onErrorContainer,
128 style = MaterialTheme.typography.bodyMedium,
135 state.aboutInfo?.let { about ->
137 modifier = Modifier.fillMaxWidth(),
138 elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
140 Column(modifier = Modifier.padding(16.dp)) {
141 Row(verticalAlignment = Alignment.CenterVertically) {
144 contentDescription = "Server info",
145 tint = MaterialTheme.colorScheme.primary,
147 Spacer(modifier = Modifier.width(8.dp))
149 text = "Server Info",
150 style = MaterialTheme.typography.titleMedium,
151 fontWeight = FontWeight.Bold,
154 Spacer(modifier = Modifier.height(12.dp))
155 about.version?.let { SettingsRow("Version", it) }
156 about.commit?.let { SettingsRow("Commit", it.take(12)) }
157 about.mode?.let { SettingsRow("Mode", it) }
158 about.license?.get("name")?.jsonPrimitive?.contentOrNull?.let { SettingsRow("License", it) }
159 about.deploymentId?.let { SettingsRow("Deployment ID", it.take(12)) }
160 about.queryEngine?.let { SettingsRow("Query Engine", it) }
166 if (state.users.isNotEmpty()) {
168 modifier = Modifier.fillMaxWidth(),
169 elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
171 Column(modifier = Modifier.padding(16.dp)) {
172 Row(verticalAlignment = Alignment.CenterVertically) {
175 contentDescription = "Users",
176 tint = MaterialTheme.colorScheme.primary,
178 Spacer(modifier = Modifier.width(8.dp))
180 text = "Users (${state.users.size})",
181 style = MaterialTheme.typography.titleMedium,
182 fontWeight = FontWeight.Bold,
185 Spacer(modifier = Modifier.height(12.dp))
186 state.users.forEach { user ->
189 style = MaterialTheme.typography.bodyMedium,
190 modifier = Modifier.padding(vertical = 4.dp),
199 modifier = Modifier.fillMaxWidth(),
200 elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
202 Column(modifier = Modifier.padding(16.dp)) {
203 Row(verticalAlignment = Alignment.CenterVertically) {
205 Icons.Filled.PhoneAndroid,
206 contentDescription = "App info",
207 tint = MaterialTheme.colorScheme.primary,
209 Spacer(modifier = Modifier.width(8.dp))
212 style = MaterialTheme.typography.titleMedium,
213 fontWeight = FontWeight.Bold,
216 Spacer(modifier = Modifier.height(12.dp))
217 SettingsRow("App Version", BuildConfig.VERSION_NAME)
218 SettingsRow("Platform", "Android")
227private fun SettingsRow(label: String, value: String) {
231 .padding(vertical = 4.dp),
232 horizontalArrangement = Arrangement.SpaceBetween,
236 style = MaterialTheme.typography.bodyMedium,
237 color = MaterialTheme.colorScheme.onSurfaceVariant,
241 style = MaterialTheme.typography.bodyMedium,
242 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