feat(accounts): add/switch account affordances + cancel add-account flow
- Drawer header: show + circle (solo) or + N pill+chevron (multi) next to avatar for immediate account switcher access; remove redundant chevron beside username - SplashScreen: accept onCancel param and render frosted Cancel pill when adding an account over an existing session - Navigation: save previousAccountPubkey before navigating to splash, restore it fully on cancel (account switch + vm reload) - AuthViewModel: add previousAccountPubkey field to support cancel-and-restore
This commit is contained in:
@@ -281,6 +281,7 @@ fun WispNavHost(
|
||||
}
|
||||
|
||||
val onAddAccount: () -> Unit = {
|
||||
authViewModel.previousAccountPubkey = authViewModel.keyRepo.getPubkeyHex()
|
||||
authViewModel.isAddingAccount = true
|
||||
feedViewModel.resetForAccountSwitch()
|
||||
walletViewModel.suspendForAccountSwitch() // disconnect only, preserve credentials
|
||||
@@ -652,7 +653,27 @@ fun WispNavHost(
|
||||
},
|
||||
onContinueWithGoogle = {
|
||||
navController.navigate(Routes.GOOGLE_AUTH)
|
||||
}
|
||||
},
|
||||
onCancel = if (authViewModel.isAddingAccount) {
|
||||
{
|
||||
val prev = authViewModel.previousAccountPubkey
|
||||
authViewModel.isAddingAccount = false
|
||||
authViewModel.previousAccountPubkey = null
|
||||
if (prev != null) {
|
||||
authViewModel.keyRepo.switchToAccount(prev)
|
||||
authViewModel.keyRepo.reloadPrefs(prev)
|
||||
}
|
||||
feedViewModel.reloadForNewAccount()
|
||||
relayViewModel.reload()
|
||||
blossomServersViewModel.reload()
|
||||
composeViewModel.reloadBlossomRepo()
|
||||
feedViewModel.initRelays()
|
||||
walletViewModel.refreshState()
|
||||
navController.navigate(Routes.LOADING) {
|
||||
popUpTo(Routes.SPLASH) { inclusive = true }
|
||||
}
|
||||
}
|
||||
} else null
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.wisp.app.ui.component
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@@ -147,6 +149,54 @@ fun WispDrawerContent(
|
||||
}) {
|
||||
ProfilePicture(url = profile?.picture, size = 64)
|
||||
}
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
val otherAccountCount = (accounts.size - 1).coerceAtLeast(0)
|
||||
if (otherAccountCount == 0) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(26.dp)
|
||||
.clip(CircleShape)
|
||||
.background(MaterialTheme.colorScheme.surfaceVariant)
|
||||
.clickable { onAddAccount() },
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Icon(
|
||||
Icons.Filled.Add,
|
||||
contentDescription = "Add account",
|
||||
modifier = Modifier.size(16.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.clickable { accountPickerExpanded = !accountPickerExpanded }
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(26.dp)
|
||||
.clip(CircleShape)
|
||||
.background(MaterialTheme.colorScheme.surfaceVariant)
|
||||
.padding(horizontal = 10.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = "+ $otherAccountCount",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
fontWeight = androidx.compose.ui.text.font.FontWeight.Bold,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.width(2.dp))
|
||||
Icon(
|
||||
if (accountPickerExpanded) Icons.Outlined.KeyboardArrowDown
|
||||
else Icons.Outlined.KeyboardArrowRight,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
IconButton(onClick = onToggleTheme) {
|
||||
Icon(
|
||||
@@ -168,7 +218,7 @@ fun WispDrawerContent(
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(enabled = accounts.size > 1 || accounts.isNotEmpty()) {
|
||||
.clickable(enabled = accounts.isNotEmpty()) {
|
||||
accountPickerExpanded = !accountPickerExpanded
|
||||
},
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
@@ -179,15 +229,6 @@ fun WispDrawerContent(
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
modifier = Modifier.weight(1f, fill = false)
|
||||
)
|
||||
if (accounts.size > 1 || accounts.isNotEmpty()) {
|
||||
Icon(
|
||||
if (accountPickerExpanded) Icons.Outlined.KeyboardArrowDown
|
||||
else Icons.Outlined.KeyboardArrowRight,
|
||||
contentDescription = stringResource(R.string.cd_switch_account),
|
||||
modifier = Modifier.size(20.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.height(2.dp))
|
||||
if (!profile?.nip05.isNullOrBlank()) {
|
||||
|
||||
@@ -17,6 +17,7 @@ import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.QrCodeScanner
|
||||
import androidx.compose.material.icons.outlined.Visibility
|
||||
@@ -84,7 +85,8 @@ fun SplashScreen(
|
||||
authViewModel: AuthViewModel,
|
||||
onAccountCreated: () -> Unit,
|
||||
onLoggedIn: () -> Unit,
|
||||
onContinueWithGoogle: () -> Unit
|
||||
onContinueWithGoogle: () -> Unit,
|
||||
onCancel: (() -> Unit)? = null
|
||||
) {
|
||||
val profilePictures by viewModel.profilePictures.collectAsState()
|
||||
val liveMetrics by viewModel.liveMetrics.collectAsState()
|
||||
@@ -146,6 +148,21 @@ fun SplashScreen(
|
||||
)
|
||||
)
|
||||
|
||||
if (onCancel != null) {
|
||||
Text(
|
||||
text = "Cancel",
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = androidx.compose.ui.graphics.Color.White,
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.padding(bottom = 120.dp)
|
||||
.clip(androidx.compose.foundation.shape.CircleShape)
|
||||
.background(androidx.compose.ui.graphics.Color.White.copy(alpha = 0.15f))
|
||||
.clickable(onClick = onCancel)
|
||||
.padding(horizontal = 28.dp, vertical = 12.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
|
||||
@@ -31,6 +31,7 @@ class AuthViewModel(app: Application) : AndroidViewModel(app) {
|
||||
val accountsFlow: StateFlow<List<AccountInfo>> = keyRepo.accountsFlow
|
||||
|
||||
var isAddingAccount: Boolean = false
|
||||
var previousAccountPubkey: String? = null
|
||||
|
||||
val isLoggedIn: Boolean get() = keyRepo.isLoggedIn()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user