feat: loading masking and further error handling for profile settings

Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
Infi 2023-12-09 20:32:13 +01:00
parent 331d7d2b68
commit d4f994ebf4
1 changed files with 145 additions and 106 deletions

View File

@ -13,11 +13,13 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Check
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@ -29,6 +31,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -56,12 +59,14 @@ import javax.inject.Inject
@Suppress("StaticFieldLeak") @Suppress("StaticFieldLeak")
class ProfileSettingsScreenViewModel @Inject constructor(@ApplicationContext val context: Context) : class ProfileSettingsScreenViewModel @Inject constructor(@ApplicationContext val context: Context) :
ViewModel() { ViewModel() {
var isLoading by mutableStateOf(true)
var pfpModel by mutableStateOf<Any?>(null) var pfpModel by mutableStateOf<Any?>(null)
var currentProfile by mutableStateOf<Profile?>(null) var currentProfile by mutableStateOf<Profile?>(null)
var pendingProfile by mutableStateOf<Profile?>(null) var pendingProfile by mutableStateOf<Profile?>(null)
var backgroundModel by mutableStateOf<Any?>(null) var backgroundModel by mutableStateOf<Any?>(null)
var uploadProgress by mutableFloatStateOf(0f) var uploadProgress by mutableFloatStateOf(0f)
var uploadError by mutableStateOf<String?>(null) var uploadError by mutableStateOf<String?>(null)
var bioError by mutableStateOf<String?>(null)
init { init {
RevoltAPI.selfId?.let { self -> RevoltAPI.selfId?.let { self ->
@ -75,6 +80,8 @@ class ProfileSettingsScreenViewModel @Inject constructor(@ApplicationContext val
} }
pendingProfile = currentProfile!!.copy() pendingProfile = currentProfile!!.copy()
isLoading = false
} }
} }
@ -203,13 +210,18 @@ class ProfileSettingsScreenViewModel @Inject constructor(@ApplicationContext val
} }
fun saveBio() { fun saveBio() {
bioError = null
viewModelScope.launch { viewModelScope.launch {
try {
patchSelf(bio = pendingProfile?.content) patchSelf(bio = pendingProfile?.content)
fetchUserProfile(RevoltAPI.selfId!!).let { fetchUserProfile(RevoltAPI.selfId!!).let {
currentProfile = it currentProfile = it
pendingProfile = it pendingProfile = it
} }
} catch (e: Exception) {
bioError = e.message
}
} }
} }
} }
@ -238,6 +250,19 @@ fun ProfileSettingsScreen(
.fillMaxSize() .fillMaxSize()
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
) { ) {
if (viewModel.isLoading) {
Column(
modifier = Modifier
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
CircularProgressIndicator(
modifier = Modifier
.size(48.dp)
)
}
} else {
RevoltAPI.userCache[RevoltAPI.selfId]?.let { RevoltAPI.userCache[RevoltAPI.selfId]?.let {
RawUserOverview( RawUserOverview(
it, it,
@ -338,6 +363,19 @@ fun ProfileSettingsScreen(
}, },
) )
AnimatedVisibility(visible = viewModel.bioError != null) {
Spacer(Modifier.height(8.dp))
Text(
text = viewModel.bioError ?: "",
style = MaterialTheme.typography.labelLarge.copy(
color = MaterialTheme.colorScheme.error
),
modifier = Modifier
.padding(start = 20.dp, end = 20.dp, top = 20.dp, bottom = 0.dp)
)
}
Spacer(Modifier.height(8.dp)) Spacer(Modifier.height(8.dp))
TextButton( TextButton(
@ -363,3 +401,4 @@ fun ProfileSettingsScreen(
} }
} }
} }
}