feat: add account card animation and disconnect dialogs in settings

This commit is contained in:
Paweł Orzech 2026-03-19 14:24:21 +01:00
parent a6429f16d3
commit 5183862533
No known key found for this signature in database

View file

@ -1,5 +1,7 @@
package com.swoosh.microblog.ui.settings
import androidx.compose.animation.*
import androidx.compose.animation.core.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@ -18,6 +20,8 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.swoosh.microblog.data.AccountManager
import com.swoosh.microblog.data.api.ApiClient
import com.swoosh.microblog.ui.animation.SwooshMotion
import com.swoosh.microblog.ui.components.AnimatedDialog
import com.swoosh.microblog.ui.feed.AccountAvatar
import com.swoosh.microblog.ui.theme.ThemeMode
import com.swoosh.microblog.ui.theme.ThemeViewModel
@ -36,6 +40,9 @@ fun SettingsScreen(
val currentThemeMode = themeViewModel?.themeMode?.collectAsStateWithLifecycle()
var showDisconnectDialog by remember { mutableStateOf(false) }
var showDisconnectAllDialog by remember { mutableStateOf(false) }
Scaffold(
topBar = {
TopAppBar(
@ -74,7 +81,13 @@ fun SettingsScreen(
Text("Current Account", style = MaterialTheme.typography.titleMedium)
Spacer(modifier = Modifier.height(12.dp))
if (activeAccount != null) {
var cardVisible by remember { mutableStateOf(false) }
LaunchedEffect(Unit) { cardVisible = true }
AnimatedVisibility(
visible = cardVisible && activeAccount != null,
enter = fadeIn(SwooshMotion.quick()) + scaleIn(initialScale = 0.95f, animationSpec = SwooshMotion.quick())
) {
Card(
modifier = Modifier.fillMaxWidth()
) {
@ -84,7 +97,7 @@ fun SettingsScreen(
.padding(16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
AccountAvatar(account = activeAccount, size = 40)
AccountAvatar(account = activeAccount!!, size = 40)
Column {
Text(
text = activeAccount.name,
@ -137,19 +150,7 @@ fun SettingsScreen(
// Disconnect current account
OutlinedButton(
onClick = {
activeAccount?.let { account ->
accountManager.removeAccount(account.id)
ApiClient.reset()
val remaining = accountManager.getAccounts()
if (remaining.isEmpty()) {
onLogout()
} else {
// There are still accounts, go back to feed with the next one
onBack()
}
}
},
onClick = { showDisconnectDialog = true },
modifier = Modifier.fillMaxWidth(),
colors = ButtonDefaults.outlinedButtonColors(
contentColor = MaterialTheme.colorScheme.error
@ -163,11 +164,7 @@ fun SettingsScreen(
// Disconnect all
if (accountManager.getAccounts().size > 1) {
TextButton(
onClick = {
accountManager.clearAll()
ApiClient.reset()
onLogout()
},
onClick = { showDisconnectAllDialog = true },
modifier = Modifier.fillMaxWidth(),
colors = ButtonDefaults.textButtonColors(
contentColor = MaterialTheme.colorScheme.error
@ -178,6 +175,66 @@ fun SettingsScreen(
}
}
}
if (showDisconnectDialog) {
AnimatedDialog(onDismissRequest = { showDisconnectDialog = false }) {
Card(modifier = Modifier.padding(horizontal = 24.dp)) {
Column(modifier = Modifier.padding(24.dp)) {
Text("Disconnect Account?", style = MaterialTheme.typography.headlineSmall)
Spacer(modifier = Modifier.height(16.dp))
Text("Remove \"${activeAccount?.name ?: ""}\"? You'll need to set up again.")
Spacer(modifier = Modifier.height(24.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.End
) {
TextButton(onClick = { showDisconnectDialog = false }) { Text("Cancel") }
Spacer(modifier = Modifier.width(8.dp))
Button(
onClick = {
showDisconnectDialog = false
activeAccount?.let { account ->
accountManager.removeAccount(account.id)
ApiClient.reset()
if (accountManager.getAccounts().isEmpty()) onLogout() else onBack()
}
},
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error)
) { Text("Disconnect") }
}
}
}
}
}
if (showDisconnectAllDialog) {
AnimatedDialog(onDismissRequest = { showDisconnectAllDialog = false }) {
Card(modifier = Modifier.padding(horizontal = 24.dp)) {
Column(modifier = Modifier.padding(24.dp)) {
Text("Disconnect All?", style = MaterialTheme.typography.headlineSmall)
Spacer(modifier = Modifier.height(16.dp))
Text("Remove all accounts? You'll need to set up from scratch.")
Spacer(modifier = Modifier.height(24.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.End
) {
TextButton(onClick = { showDisconnectAllDialog = false }) { Text("Cancel") }
Spacer(modifier = Modifier.width(8.dp))
Button(
onClick = {
showDisconnectAllDialog = false
accountManager.clearAll()
ApiClient.reset()
onLogout()
},
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error)
) { Text("Disconnect All") }
}
}
}
}
}
}
@Composable