1package com.parseable.android.ui.screens.settings
3import androidx.lifecycle.ViewModel
4import androidx.lifecycle.viewModelScope
5import com.parseable.android.data.model.AboutInfo
6import com.parseable.android.data.model.ApiResult
7import com.parseable.android.data.repository.ParseableRepository
8import com.parseable.android.data.repository.SettingsRepository
9import dagger.hilt.android.lifecycle.HiltViewModel
10import kotlinx.coroutines.CancellationException
11import kotlinx.coroutines.async
12import kotlinx.coroutines.coroutineScope
13import kotlinx.coroutines.flow.MutableStateFlow
14import kotlinx.coroutines.flow.StateFlow
15import kotlinx.coroutines.flow.asStateFlow
16import kotlinx.coroutines.flow.first
17import kotlinx.coroutines.flow.update
18import kotlinx.coroutines.launch
19import kotlinx.serialization.json.jsonPrimitive
20import javax.inject.Inject
22data class SettingsState(
23 val serverUrl: String = "",
24 val username: String = "",
25 val useTls: Boolean = true,
26 val aboutInfo: AboutInfo? = null,
27 val users: List<String> = emptyList(),
28 val isLoading: Boolean = false,
29 val error: String? = null,
33class SettingsViewModel @Inject constructor(
34 private val settingsRepository: SettingsRepository,
35 private val repository: ParseableRepository,
38 private val _state = MutableStateFlow(SettingsState())
39 val state: StateFlow<SettingsState> = _state.asStateFlow()
46 viewModelScope.launch {
47 _state.update { it.copy(isLoading = true, error = null) }
49 val config = settingsRepository.serverConfig.first()
51 // Show server info immediately
54 serverUrl = config?.serverUrl ?: it.serverUrl,
55 username = config?.username ?: it.username,
56 useTls = config?.useTls ?: it.useTls,
61 val (aboutResult, usersResult) = coroutineScope {
62 val aboutDeferred = async { repository.getAbout() }
63 val usersDeferred = async { repository.listUsers() }
64 aboutDeferred.await() to usersDeferred.await()
67 val userNames = (usersResult as? ApiResult.Success)?.data?.mapNotNull { obj ->
69 obj["id"]?.jsonPrimitive?.content
70 ?: obj["username"]?.jsonPrimitive?.content
71 } catch (_: IllegalStateException) {
76 val errors = listOfNotNull(
77 (aboutResult as? ApiResult.Error)?.userMessage,
78 (usersResult as? ApiResult.Error)?.userMessage,
79 ).distinct().joinToString("\n").ifEmpty { null }
83 aboutInfo = (aboutResult as? ApiResult.Success)?.data,
89 } catch (e: CancellationException) {
90 _state.update { it.copy(isLoading = false) }
92 } catch (e: Exception) {
94 it.copy(isLoading = false, error = e.message ?: "Failed to load settings")
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