android/ui: restyle the run as exit node screen

Updates tailscale/corp#18202

Restyle the run as exit node screen per UX

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
jonathan/runasexitnode
Jonathan Nobels 1 month ago
parent ccda0499a7
commit 50cc2bf8b2

@ -6,11 +6,13 @@ package com.tailscale.ipn.ui.view
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowForward
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@ -19,14 +21,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.tailscale.ipn.R
import com.tailscale.ipn.ui.theme.ts_color_light_blue
import com.tailscale.ipn.ui.util.LoadingIndicator
import com.tailscale.ipn.ui.viewModel.ExitNodePickerNav
import com.tailscale.ipn.ui.viewModel.RunExitNodeViewModel
@ -45,8 +45,9 @@ fun RunExitNodeView(
LoadingIndicator.Wrap {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp, alignment = Alignment.Top),
modifier = Modifier.padding(innerPadding).padding(16.dp).fillMaxHeight()) {
verticalArrangement =
Arrangement.spacedBy(24.dp, alignment = Alignment.CenterVertically),
modifier = Modifier.padding(innerPadding).padding(24.dp).fillMaxHeight()) {
RunExitNodeGraphic()
if (isRunningExitNode) {
@ -64,15 +65,16 @@ fun RunExitNodeView(
fontWeight = FontWeight.SemiBold)
Text(stringResource(R.string.run_exit_node_explainer))
}
Text(stringResource(R.string.run_exit_node_caution), color = Color.Red)
Text(stringResource(R.string.run_exit_node_caution))
PrimaryActionButton(onClick = { model.setRunningExitNode(!isRunningExitNode) }) {
Button(onClick = { model.setRunningExitNode(!isRunningExitNode) }) {
if (isRunningExitNode) {
Text(stringResource(R.string.stop_running_as_exit_node))
} else {
Text(stringResource(R.string.start_running_as_exit_node))
}
}
Spacer(modifier = Modifier.size(24.dp))
}
}
}
@ -82,7 +84,11 @@ fun RunExitNodeView(
fun RunExitNodeGraphic() {
@Composable
fun ArrowForward() {
Icon(Icons.AutoMirrored.Outlined.ArrowForward, "Arrow Forward", modifier = Modifier.size(24.dp))
Icon(
Icons.AutoMirrored.Outlined.ArrowForward,
"Arrow Forward",
modifier = Modifier.size(24.dp),
tint = MaterialTheme.colorScheme.onSurfaceVariant)
}
Row(
@ -92,19 +98,19 @@ fun RunExitNodeGraphic() {
Icon(
painter = painterResource(id = R.drawable.computer),
"Computer icon",
tint = ts_color_light_blue,
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.size(36.dp))
ArrowForward()
Icon(
painter = painterResource(id = R.drawable.android),
"Android icon",
tint = ts_color_light_blue,
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.size(36.dp))
ArrowForward()
Icon(
painter = painterResource(id = R.drawable.globe),
"Globe icon",
tint = ts_color_light_blue,
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.size(36.dp))
}
}

@ -116,11 +116,11 @@
<string name="mullvad_exit_nodes">Mullvad VPN</string>
<string name="best_available">Best available</string>
<string name="run_as_exit_node">Run as exit node</string>
<string name="run_this_device_as_an_exit_node">Run this device as an exit node?</string>
<string name="run_this_device_as_an_exit_node">Run as exit node?</string>
<string name="run_exit_node_explainer">Other devices in your tailnet will be able to route their internet traffic through this Android device. Make sure to approve this exit node in the admin console in order for other devices to see it.</string>
<string name="run_exit_node_caution">Caution: Running an exit node will severely impact battery life. On a metered data plan, significant cellular data charges may also apply. Always disable this feature when no longer needed.</string>
<string name="run_exit_node_caution">Running an exit node will severely impact battery life. On a metered data plan, significant cellular data charges may also apply. Always disable this feature when no longer needed.</string>
<string name="stop_running_as_exit_node">Stop running as exit node</string>
<string name="start_running_as_exit_node">Start running as exit node</string>
<string name="start_running_as_exit_node">Run as exit node</string>
<string name="running_as_exit_node">Now running as exit node</string>
<string name="run_exit_node_explainer_running">Other devices in your tailnet can now route their internet traffic through this Android device. Make sure to approve this exit node in the admin console in order for other devices to see it.</string>
<string name="enabled">Enabled</string>

Loading…
Cancel
Save