Skip to content

Commit

Permalink
android/ui: use compose getValue syntactic sugar consistently (#367)
Browse files Browse the repository at this point in the history
Updates #cleanup

"by stateFlow" is syntactic sugar for" = stateFlow.value" and is more
idiomatic.  There should be no functional difference here.  Just\
changed where it can be for consistency.

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
  • Loading branch information
barnstar authored May 17, 2024
1 parent 999c6f2 commit b37492a
Show file tree
Hide file tree
Showing 16 changed files with 79 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
Expand Down Expand Up @@ -40,7 +41,7 @@ object LoadingIndicator {
contentAlignment = Alignment.Center,
) {
content()
val isLoading = loading.collectAsState().value
val isLoading by loading.collectAsState()
if (isLoading) {
Box(Modifier.clickable {}.matchParentSize().background(Color.Gray.copy(alpha = 0.0f)))

Expand All @@ -54,7 +55,8 @@ object LoadingIndicator {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally) {
TailscaleLogoView(true, usesOnBackgroundColors = false, Modifier.size(72.dp).alpha(0.4f))
TailscaleLogoView(
true, usesOnBackgroundColors = false, Modifier.size(72.dp).alpha(0.4f))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
Expand All @@ -36,7 +37,7 @@ import com.tailscale.ipn.ui.viewModel.BugReportViewModel
@Composable
fun BugReportView(backToSettings: BackNavigation, model: BugReportViewModel = viewModel()) {
val handler = LocalUriHandler.current
val bugReportID = model.bugReportID.collectAsState().value
val bugReportID by model.bugReportID.collectAsState()

Scaffold(topBar = { Header(R.string.bug_report_title, onBack = backToSettings) }) { innerPadding
->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fun LoginWithCustomControlURLView(
onBack = backToSettings,
)
}) { innerPadding ->
val error = viewModel.errorDialog.collectAsState().value
val error by viewModel.errorDialog.collectAsState()
val strings =
LoginViewStrings(
title = stringResource(id = R.string.custom_control_menu),
Expand Down Expand Up @@ -85,7 +85,7 @@ fun LoginWithAuthKeyView(
onBack = backToSettings,
)
}) { innerPadding ->
val error = viewModel.errorDialog.collectAsState().value
val error by viewModel.errorDialog.collectAsState()
val strings =
LoginViewStrings(
title = stringResource(id = R.string.auth_key_title),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
Expand Down Expand Up @@ -41,15 +42,15 @@ fun DNSSettingsView(
backToSettings: BackNavigation,
model: DNSSettingsViewModel = viewModel(factory = DNSSettingsViewModelFactory())
) {
val state: DNSEnablementState = model.enablementState.collectAsState().value
val state: DNSEnablementState by model.enablementState.collectAsState()
val resolvers = model.dnsConfig.collectAsState().value?.Resolvers ?: emptyList()
val domains = model.dnsConfig.collectAsState().value?.Domains ?: emptyList()
val routes: List<ViewableRoute> =
model.dnsConfig.collectAsState().value?.Routes?.mapNotNull { entry ->
entry.value?.let { resolvers -> ViewableRoute(name = entry.key, resolvers) } ?: run { null }
} ?: emptyList()
val useCorpDNS = Notifier.prefs.collectAsState().value?.CorpDNS == true
val dnsSettingsMDMDisposition = MDMSettings.useTailscaleDNSSettings.flow.collectAsState().value
val dnsSettingsMDMDisposition by MDMSettings.useTailscaleDNSSettings.flow.collectAsState()

Scaffold(topBar = { Header(R.string.dns_settings, onBack = backToSettings) }) { innerPadding ->
LoadingIndicator.Wrap {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
Expand All @@ -42,14 +43,13 @@ fun ExitNodePicker(
LoadingIndicator.Wrap {
Scaffold(topBar = { Header(R.string.choose_exit_node, onBack = nav.onNavigateBackHome) }) {
innerPadding ->
val tailnetExitNodes = model.tailnetExitNodes.collectAsState().value
val mullvadExitNodesByCountryCode = model.mullvadExitNodesByCountryCode.collectAsState().value
val mullvadExitNodeCount = model.mullvadExitNodeCount.collectAsState().value
val anyActive = model.anyActive.collectAsState()
val tailnetExitNodes by model.tailnetExitNodes.collectAsState()
val mullvadExitNodesByCountryCode by model.mullvadExitNodesByCountryCode.collectAsState()
val mullvadExitNodeCount by model.mullvadExitNodeCount.collectAsState()
val anyActive by model.anyActive.collectAsState()
val allowLANAccess = Notifier.prefs.collectAsState().value?.ExitNodeAllowLANAccess == true
val showRunAsExitNode = MDMSettings.runExitNode.flow.collectAsState().value
val allowLanAccessMDMDisposition =
MDMSettings.exitNodeAllowLANAccess.flow.collectAsState().value
val showRunAsExitNode by MDMSettings.runExitNode.flow.collectAsState()
val allowLanAccessMDMDisposition by MDMSettings.exitNodeAllowLANAccess.flow.collectAsState()

LazyColumn(modifier = Modifier.padding(innerPadding)) {
item(key = "header") {
Expand All @@ -58,7 +58,7 @@ fun ExitNodePicker(
ExitNodePickerViewModel.ExitNode(
label = stringResource(R.string.none),
online = true,
selected = !anyActive.value,
selected = !anyActive,
))

if (showRunAsExitNode == ShowHide.Show) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
Expand All @@ -38,7 +39,7 @@ import com.tailscale.ipn.ui.viewModel.LoginQRViewModel
fun LoginQRView(onDismiss: () -> Unit = {}, model: LoginQRViewModel = viewModel()) {
Surface(color = MaterialTheme.colorScheme.scrim, modifier = Modifier.fillMaxSize()) {
Dialog(onDismissRequest = onDismiss) {
val image = model.qrCode.collectAsState()
val image by model.qrCode.collectAsState()

Column(
modifier =
Expand All @@ -57,7 +58,7 @@ fun LoginQRView(onDismiss: () -> Unit = {}, model: LoginQRViewModel = viewModel(
.background(MaterialTheme.colorScheme.onSurface)
.fillMaxWidth(),
contentAlignment = Alignment.Center) {
image.value?.let {
image?.let {
Image(
bitmap = it,
contentDescription = "Scan to login",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
Expand All @@ -38,7 +39,7 @@ fun MDMSettingsDebugView(backToSettings: BackNavigation, model: IpnViewModel = v

@Composable
fun MDMSettingView(setting: MDMSetting<*>) {
val value = setting.flow.collectAsState().value
val value by setting.flow.collectAsState()
ListItem(
headlineContent = { Text(setting.localizedTitle, maxLines = 3) },
supportingContent = {
Expand Down
32 changes: 15 additions & 17 deletions android/src/main/java/com/tailscale/ipn/ui/view/MainView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
Expand All @@ -62,7 +62,6 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.tailscale.ipn.R
import com.tailscale.ipn.mdm.MDMSettings
Expand All @@ -89,7 +88,6 @@ import com.tailscale.ipn.ui.util.PeerSet
import com.tailscale.ipn.ui.util.flag
import com.tailscale.ipn.ui.util.itemsWithDividers
import com.tailscale.ipn.ui.viewModel.MainViewModel
import android.util.Log

// Navigation actions for the MainView
data class MainViewNavigation(
Expand All @@ -105,14 +103,14 @@ fun MainView(
navigation: MainViewNavigation,
viewModel: MainViewModel
) {

LoadingIndicator.Wrap {
Scaffold(contentWindowInsets = WindowInsets.Companion.statusBars) { paddingInsets ->
Column(
modifier = Modifier.fillMaxWidth().padding(paddingInsets),
verticalArrangement = Arrangement.Center) {
// Assume VPN has been prepared. Whether or not it has been prepared cannot be known until permission has been granted to prepare the VPN.
val isPrepared by viewModel.vpnPrepared.collectAsState(initial=true)
// Assume VPN has been prepared. Whether or not it has been prepared cannot be known
// until permission has been granted to prepare the VPN.
val isPrepared by viewModel.vpnPrepared.collectAsState(initial = true)
val isOn by viewModel.vpnToggleState.collectAsState(initial = false)
val state by viewModel.ipnState.collectAsState(initial = Ipn.State.NoState)
val user by viewModel.loggedInUser.collectAsState(initial = null)
Expand Down Expand Up @@ -195,8 +193,8 @@ fun MainView(
{ viewModel.toggleVpn() },
{ viewModel.login() },
loginAtUrl,
netmap?.SelfNode,
{viewModel.showVPNPermissionLauncherIfUnauthorized()})
netmap?.SelfNode,
{ viewModel.showVPNPermissionLauncherIfUnauthorized() })
}
}
}
Expand All @@ -206,17 +204,17 @@ fun MainView(

@Composable
fun ExitNodeStatus(navAction: () -> Unit, viewModel: MainViewModel) {
val maybePrefs = viewModel.prefs.collectAsState()
val netmap = viewModel.netmap.collectAsState()
val maybePrefs by viewModel.prefs.collectAsState()
val netmap by viewModel.netmap.collectAsState()

// There's nothing to render if we haven't loaded the prefs yet
val prefs = maybePrefs.value ?: return
val prefs = maybePrefs ?: return

// The activeExitNode is the source of truth. The selectedExitNode is only relevant if we
// don't have an active node.
val chosenExitNodeId = prefs.activeExitNodeID ?: prefs.selectedExitNodeID

val exitNodePeer = chosenExitNodeId?.let { id -> netmap.value?.Peers?.find { it.StableID == id } }
val exitNodePeer = chosenExitNodeId?.let { id -> netmap?.Peers?.find { it.StableID == id } }
val location = exitNodePeer?.Hostinfo?.Location
val name = exitNodePeer?.ComputedName

Expand Down Expand Up @@ -319,15 +317,15 @@ fun ConnectView(
if (!isPrepared) {
showVPNPermissionLauncherIfUnauthorized()
}
}
}
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth()) {
Column(
modifier = Modifier.padding(8.dp).fillMaxWidth(0.7f).fillMaxHeight(),
verticalArrangement = Arrangement.spacedBy(8.dp, alignment = Alignment.CenterVertically),
horizontalAlignment = Alignment.CenterHorizontally,
) {
if (!isPrepared) {
if (!isPrepared) {
TailscaleLogoView(modifier = Modifier.size(50.dp))
Spacer(modifier = Modifier.size(1.dp))
Text(
Expand Down Expand Up @@ -426,10 +424,10 @@ fun PeerList(
onNavigateToPeerDetails: (Tailcfg.Node) -> Unit,
onSearch: (String) -> Unit
) {
val peerList = viewModel.peers.collectAsState(initial = emptyList<PeerSet>())
val peerList by viewModel.peers.collectAsState(initial = emptyList<PeerSet>())
val searchTermStr by viewModel.searchTerm.collectAsState(initial = "")
val showNoResults =
remember { derivedStateOf { searchTermStr.isNotEmpty() && peerList.value.isEmpty() } }.value
remember { derivedStateOf { searchTermStr.isNotEmpty() && peerList.isEmpty() } }.value

val netmap = viewModel.netmap.collectAsState()

Expand Down Expand Up @@ -490,7 +488,7 @@ fun PeerList(
}

var first = true
peerList.value.forEach { peerSet ->
peerList.forEach { peerSet ->
if (!first) {
item(key = "user_divider_${peerSet.user?.ID ?: 0L}") { Lists.ItemDivider() }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
Expand All @@ -29,10 +30,10 @@ fun MullvadExitNodePicker(
nav: ExitNodePickerNav,
model: ExitNodePickerViewModel = viewModel(factory = ExitNodePickerViewModelFactory(nav))
) {
val mullvadExitNodes = model.mullvadExitNodesByCountryCode.collectAsState()
val bestAvailableByCountry = model.mullvadBestAvailableByCountry.collectAsState()
val mullvadExitNodes by model.mullvadExitNodesByCountryCode.collectAsState()
val bestAvailableByCountry by model.mullvadBestAvailableByCountry.collectAsState()

mullvadExitNodes.value[countryCode]?.toList()?.let { nodes ->
mullvadExitNodes[countryCode]?.toList()?.let { nodes ->
val any = nodes.first()

LoadingIndicator.Wrap {
Expand All @@ -44,7 +45,7 @@ fun MullvadExitNodePicker(
}) { innerPadding ->
LazyColumn(modifier = Modifier.padding(innerPadding)) {
if (nodes.size > 1) {
val bestAvailableNode = bestAvailableByCountry.value[countryCode]!!
val bestAvailableNode = bestAvailableByCountry[countryCode]!!
item {
ExitNodeItem(
model,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
Expand All @@ -40,11 +41,11 @@ fun MullvadExitNodePickerList(
topBar = {
Header(R.string.choose_mullvad_exit_node, onBack = nav.onNavigateBackToExitNodes)
}) { innerPadding ->
val mullvadExitNodes = model.mullvadExitNodesByCountryCode.collectAsState()
val mullvadExitNodes by model.mullvadExitNodesByCountryCode.collectAsState()

LazyColumn(modifier = Modifier.padding(innerPadding)) {
val sortedCountries =
mullvadExitNodes.value.entries.toList().sortedBy {
mullvadExitNodes.entries.toList().sortedBy {
it.value.first().country.lowercase()
}
itemsWithDividers(sortedCountries) { (countryCode, nodes) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
Expand All @@ -39,7 +40,7 @@ fun RunExitNodeView(
nav: ExitNodePickerNav,
model: RunExitNodeViewModel = viewModel(factory = RunExitNodeViewModelFactory())
) {
val isRunningExitNode = model.isRunningExitNode.collectAsState().value
val isRunningExitNode by model.isRunningExitNode.collectAsState()

Scaffold(
topBar = { Header(R.string.run_as_exit_node, onBack = nav.onNavigateBackToExitNodes) }) {
Expand All @@ -49,7 +50,11 @@ fun RunExitNodeView(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement =
Arrangement.spacedBy(24.dp, alignment = Alignment.CenterVertically),
modifier = Modifier.padding(innerPadding).padding(24.dp).fillMaxHeight().verticalScroll(rememberScrollState())) {
modifier =
Modifier.padding(innerPadding)
.padding(24.dp)
.fillMaxHeight()
.verticalScroll(rememberScrollState())) {
RunExitNodeGraphic()

if (isRunningExitNode) {
Expand Down
Loading

0 comments on commit b37492a

Please sign in to comment.