From 5599f2ddeb077eda2ba02cf8a63ddda61167d0ac Mon Sep 17 00:00:00 2001 From: Percy Wegmann Date: Wed, 27 Mar 2024 13:29:02 -0500 Subject: [PATCH] android/ui: add back fast user switching status and clean up avatar scaling Updates #cleanup Signed-off-by: Percy Wegmann --- .../java/com/tailscale/ipn/ui/util/Lists.kt | 2 +- .../java/com/tailscale/ipn/ui/view/Avatar.kt | 3 +- .../tailscale/ipn/ui/view/UserSwitcherView.kt | 40 +++++++++---------- .../com/tailscale/ipn/ui/view/UserView.kt | 14 ++++--- 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/android/src/main/java/com/tailscale/ipn/ui/util/Lists.kt b/android/src/main/java/com/tailscale/ipn/ui/util/Lists.kt index c53364c..6fb4281 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/util/Lists.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/util/Lists.kt @@ -44,7 +44,7 @@ inline fun LazyListScope.itemsWithDividers( key = if (key != null) { index: Int -> key(items[index]) } else null, contentType = { index -> contentType(items[index]) }) { if (forceLeading && it == 0 || - forceTrailing && it == items.size - 1 || + forceTrailing && it == items.size || it > 0 && it < items.size) { Lists.ItemDivider() } diff --git a/android/src/main/java/com/tailscale/ipn/ui/view/Avatar.kt b/android/src/main/java/com/tailscale/ipn/ui/view/Avatar.kt index aef518a..0adf759 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/view/Avatar.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/view/Avatar.kt @@ -36,7 +36,8 @@ fun Avatar(profile: IpnLocal.LoginProfile?, size: Int = 50) { modifier = Modifier.size((size * .8f).dp)) profile?.UserProfile?.ProfilePicURL?.let { url -> - AsyncImage(model = url, contentDescription = null) + AsyncImage( + model = url, modifier = Modifier.size((size * 1.2f).dp), contentDescription = null) } } } diff --git a/android/src/main/java/com/tailscale/ipn/ui/view/UserSwitcherView.kt b/android/src/main/java/com/tailscale/ipn/ui/view/UserSwitcherView.kt index 5cdf600..471e8d0 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/view/UserSwitcherView.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/view/UserSwitcherView.kt @@ -5,10 +5,9 @@ package com.tailscale.ipn.ui.view import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable @@ -19,8 +18,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.tailscale.ipn.R +import com.tailscale.ipn.ui.util.Lists +import com.tailscale.ipn.ui.util.itemsWithDividers import com.tailscale.ipn.ui.util.set -import com.tailscale.ipn.ui.util.settingsRowModifier import com.tailscale.ipn.ui.viewModel.UserSwitcherViewModel @OptIn(ExperimentalMaterial3Api::class) @@ -39,17 +39,16 @@ fun UserSwitcherView(nav: BackNavigation, viewModel: UserSwitcherViewModel = vie // Show the error overlay if need be showDialog?.let { ErrorDialog(type = it, action = { viewModel.showDialog.set(null) }) } - Column(modifier = settingsRowModifier()) { + // When switch is invoked, this stores the ID of the user we're trying to switch to + // so we can decorate it with a spinner. The actual logged in user will not change + // until + // we get our first netmap update back with the new userId for SelfNode. + // (jonathan) TODO: This user switch is not immediate. We may need to represent the + // "switching users" state globally (if ipnState is insufficient) + val nextUserId = remember { mutableStateOf(null) } - // When switch is invoked, this stores the ID of the user we're trying to switch to - // so we can decorate it with a spinner. The actual logged in user will not change - // until - // we get our first netmap update back with the new userId for SelfNode. - // (jonathan) TODO: This user switch is not immediate. We may need to represent the - // "switching users" state globally (if ipnState is insufficient) - val nextUserId = remember { mutableStateOf(null) } - - users?.forEach { user -> + LazyColumn { + itemsWithDividers(users ?: emptyList()) { user -> if (user.ID == currentUser?.ID) { UserView(profile = user, actionState = UserActionState.CURRENT) } else { @@ -70,14 +69,15 @@ fun UserSwitcherView(nav: BackNavigation, viewModel: UserSwitcherViewModel = vie }) } } - SettingRow(viewModel.addProfileSetting) - } - Spacer(modifier = Modifier.height(8.dp)) - - Column(modifier = settingsRowModifier()) { - SettingRow(viewModel.loginSetting) - SettingRow(viewModel.logoutSetting) + item { + Lists.SectionDivider() + SettingRow(viewModel.addProfileSetting) + Lists.ItemDivider() + SettingRow(viewModel.loginSetting) + Lists.ItemDivider() + SettingRow(viewModel.logoutSetting) + } } } } diff --git a/android/src/main/java/com/tailscale/ipn/ui/view/UserView.kt b/android/src/main/java/com/tailscale/ipn/ui/view/UserView.kt index d88026c..aaab3e2 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/view/UserView.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/view/UserView.kt @@ -6,16 +6,11 @@ package com.tailscale.ipn.ui.view import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.material3.ListItem -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp import com.tailscale.ipn.R import com.tailscale.ipn.ui.model.IpnLocal @@ -50,7 +45,14 @@ fun UserView( supportingContent = { Text(text = profile.Name, style = MaterialTheme.typography.bodyMedium) }, - ) + trailingContent = { + when (actionState) { + UserActionState.CURRENT -> CheckedIndicator() + UserActionState.SWITCHING -> SimpleActivityIndicator(size = 26) + UserActionState.NAV -> Unit + UserActionState.NONE -> Unit + } + }) } ?: run { ListItem(