git.iko.soy/opencode-android
on 8865a77 help sign in
96 lines 4.0 kB history raw
1package soy.iko.opencode.ui.settings
3import androidx.compose.foundation.layout.Arrangement
4import androidx.compose.foundation.layout.Column
5import androidx.compose.foundation.layout.fillMaxWidth
6import androidx.compose.foundation.layout.padding
7import androidx.compose.foundation.selection.selectable
8import androidx.compose.material.icons.Icons
9import androidx.compose.material.icons.automirrored.filled.ArrowBack
10import androidx.compose.material3.ExperimentalMaterial3Api
11import androidx.compose.material3.HorizontalDivider
12import androidx.compose.material3.Icon
13import androidx.compose.material3.IconButton
14import androidx.compose.material3.MaterialTheme
15import androidx.compose.material3.RadioButton
16import androidx.compose.material3.Scaffold
17import androidx.compose.material3.Text
18import androidx.compose.material3.TopAppBar
19import androidx.compose.runtime.Composable
20import androidx.compose.runtime.getValue
21import androidx.compose.runtime.rememberCoroutineScope
22import androidx.compose.ui.Alignment
23import androidx.compose.ui.Modifier
24import androidx.compose.ui.unit.dp
25import androidx.lifecycle.compose.collectAsStateWithLifecycle
26import kotlinx.coroutines.launch
27import soy.iko.opencode.data.repo.ThemeMode
28import soy.iko.opencode.di.AppContainer
30@OptIn(ExperimentalMaterial3Api::class)
31@Composable
32fun SettingsScreen(container: AppContainer, onBack: () -> Unit) {
33 val scope = rememberCoroutineScope()
34 val themeMode by container.settingsStore.themeMode.collectAsStateWithLifecycle(initialValue = ThemeMode.SYSTEM)
35 val activeProfile = container.activeConnection.collectAsStateWithLifecycle().value?.profile
37 Scaffold(
38 topBar = {
39 TopAppBar(
40 title = { Text("Settings") },
41 navigationIcon = {
42 IconButton(onClick = onBack) {
43 Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
44 }
45 },
46 )
47 },
48 ) { padding ->
49 Column(modifier = Modifier.padding(padding).padding(16.dp)) {
50 Text("Appearance", style = MaterialTheme.typography.titleSmall, color = MaterialTheme.colorScheme.primary)
51 ThemeMode.entries.forEach { mode ->
52 Row(
53 mode = mode,
54 selected = themeMode == mode,
55 onSelect = { scope.launch { container.settingsStore.setThemeMode(mode) } },
56 )
57 }
59 HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
61 Text("Connection", style = MaterialTheme.typography.titleSmall, color = MaterialTheme.colorScheme.primary)
62 if (activeProfile != null) {
63 Text(activeProfile.displayLabel, modifier = Modifier.padding(top = 8.dp))
64 Text(
65 activeProfile.baseUrl + if (activeProfile.hasAuth) " • Basic auth" else "",
66 style = MaterialTheme.typography.bodySmall,
67 color = MaterialTheme.colorScheme.onSurfaceVariant,
68 )
69 } else {
70 Text(
71 "Not connected.",
72 modifier = Modifier.padding(top = 8.dp),
73 color = MaterialTheme.colorScheme.onSurfaceVariant,
74 )
75 }
76 }
77 }
80@Composable
81private fun Row(mode: ThemeMode, selected: Boolean, onSelect: () -> Unit) {
82 androidx.compose.foundation.layout.Row(
83 modifier = Modifier
84 .fillMaxWidth()
85 .selectable(selected = selected, onClick = onSelect)
86 .padding(vertical = 8.dp),
87 horizontalArrangement = Arrangement.spacedBy(8.dp),
88 verticalAlignment = Alignment.CenterVertically,
89 ) {
90 RadioButton(selected = selected, onClick = onSelect)
91 Text(
92 mode.name.lowercase().replaceFirstChar { it.uppercase() },
93 style = MaterialTheme.typography.bodyLarge,
94 )
95 }