diff --git a/android/src/main/java/com/tailscale/ipn/ui/theme/Theme.kt b/android/src/main/java/com/tailscale/ipn/ui/theme/Theme.kt
index f71b608..6957b6f 100644
--- a/android/src/main/java/com/tailscale/ipn/ui/theme/Theme.kt
+++ b/android/src/main/java/com/tailscale/ipn/ui/theme/Theme.kt
@@ -55,10 +55,10 @@ private val LightColors =
lightColorScheme(
primary = Color(0xFF4B70CC), // blue-500
onPrimary = Color(0xFFFFFFFF), // white
- // primaryContainer = Color(0xFFF0F5FF), // blue-0
- primaryContainer = Color(0xFF6D94EC), // blue-400
- // onPrimaryContainer = Color(0xFF3E5DB3), // blue-600
- onPrimaryContainer = Color(0xFFFFFFFF), // white,
+ primaryContainer = Color(0xFFF0F5FF), // blue-0
+ // primaryContainer = Color(0xFF6D94EC), // blue-400
+ onPrimaryContainer = Color(0xFF3E5DB3), // blue-600
+ // onPrimaryContainer = Color(0xFFFFFFFF), // white,
error = Color(0xFFB22C30), // red-500
onError = Color(0xFFFFFFFF), // white
errorContainer = Color(0xFFFEF6F3), // red-0
@@ -209,8 +209,8 @@ val ColorScheme.secondaryButton: ButtonColors
get() {
val defaults = ButtonDefaults.buttonColors()
return ButtonColors(
- containerColor = MaterialTheme.colorScheme.primaryContainer,
- contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
+ containerColor = Color(0xFF6D94EC), // blue-400
+ contentColor = Color(0xFFFFFFFF), // white
disabledContainerColor = defaults.disabledContainerColor,
disabledContentColor = defaults.disabledContentColor)
}
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 256b19d..9b5502c 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
@@ -26,7 +26,7 @@ object Lists {
@Composable
fun ItemDivider() {
- HorizontalDivider(color = MaterialTheme.colorScheme.surfaceContainer)
+ HorizontalDivider(color = MaterialTheme.colorScheme.outlineVariant)
}
}
diff --git a/android/src/main/java/com/tailscale/ipn/ui/view/ExitNodePicker.kt b/android/src/main/java/com/tailscale/ipn/ui/view/ExitNodePicker.kt
index 6e0735a..6d21c9e 100644
--- a/android/src/main/java/com/tailscale/ipn/ui/view/ExitNodePicker.kt
+++ b/android/src/main/java/com/tailscale/ipn/ui/view/ExitNodePicker.kt
@@ -3,7 +3,6 @@
package com.tailscale.ipn.ui.view
-import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
@@ -11,7 +10,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Check
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
@@ -33,49 +31,50 @@ import com.tailscale.ipn.ui.viewModel.ExitNodePickerViewModel
import com.tailscale.ipn.ui.viewModel.ExitNodePickerViewModelFactory
import com.tailscale.ipn.ui.viewModel.selected
-@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@Composable
fun ExitNodePicker(
nav: ExitNodePickerNav,
model: ExitNodePickerViewModel = viewModel(factory = ExitNodePickerViewModelFactory(nav))
) {
LoadingIndicator.Wrap {
- Scaffold(
- topBar = { Header(R.string.choose_exit_node, onBack = nav.onNavigateBack) },
- bottomBar = { SettingRow(model.allowLANAccessSetting) }) { innerPadding ->
- val tailnetExitNodes = model.tailnetExitNodes.collectAsState().value
- val mullvadExitNodesByCountryCode =
- model.mullvadExitNodesByCountryCode.collectAsState().value
- val mullvadExitNodeCount = model.mullvadExitNodeCount.collectAsState().value
- val anyActive = model.anyActive.collectAsState()
+ Scaffold(topBar = { Header(R.string.choose_exit_node, onBack = nav.onNavigateBack) }) {
+ innerPadding ->
+ val tailnetExitNodes = model.tailnetExitNodes.collectAsState().value
+ val mullvadExitNodesByCountryCode = model.mullvadExitNodesByCountryCode.collectAsState().value
+ val mullvadExitNodeCount = model.mullvadExitNodeCount.collectAsState().value
+ val anyActive = model.anyActive.collectAsState()
- LazyColumn(modifier = Modifier.padding(innerPadding)) {
- stickyHeader {
- ExitNodeItem(
- model,
- ExitNodePickerViewModel.ExitNode(
- label = stringResource(R.string.none),
- online = true,
- selected = !anyActive.value,
- ))
- Lists.ItemDivider()
- RunAsExitNodeItem(nav = nav, viewModel = model)
- }
+ LazyColumn(modifier = Modifier.padding(innerPadding)) {
+ item(key = "header") {
+ ExitNodeItem(
+ model,
+ ExitNodePickerViewModel.ExitNode(
+ label = stringResource(R.string.none),
+ online = true,
+ selected = !anyActive.value,
+ ))
+ Lists.ItemDivider()
+ RunAsExitNodeItem(nav = nav, viewModel = model)
+ }
- item(key = "divider1") { Lists.SectionDivider() }
+ item(key = "divider1") { Lists.SectionDivider() }
- itemsWithDividers(tailnetExitNodes, key = { it.id!! }) { node ->
- ExitNodeItem(model, node)
- }
+ itemsWithDividers(tailnetExitNodes, key = { it.id!! }) { node -> ExitNodeItem(model, node) }
- if (mullvadExitNodeCount > 0) {
- item(key = "mullvad") {
- Lists.SectionDivider()
- MullvadItem(nav, mullvadExitNodeCount, mullvadExitNodesByCountryCode.selected)
- }
- }
+ if (mullvadExitNodeCount > 0) {
+ item(key = "mullvad") {
+ Lists.SectionDivider()
+ MullvadItem(nav, mullvadExitNodeCount, mullvadExitNodesByCountryCode.selected)
}
}
+
+ // TODO: make sure this actually works, and if not, leave it out for now
+ item(key = "allowLANAccess") {
+ Lists.SectionDivider()
+ SettingRow(model.allowLANAccessSetting)
+ }
+ }
+ }
}
}
@@ -146,7 +145,7 @@ fun RunAsExitNodeItem(nav: ExitNodePickerNav, viewModel: ExitNodePickerViewModel
stringResource(id = R.string.run_as_exit_node),
style = MaterialTheme.typography.bodyMedium)
},
- trailingContent = {
+ supportingContent = {
if (isRunningExitNode) {
Text(stringResource(R.string.enabled))
} else {
diff --git a/android/src/main/java/com/tailscale/ipn/ui/view/MullvadExitNodePicker.kt b/android/src/main/java/com/tailscale/ipn/ui/view/MullvadExitNodePicker.kt
index 5e5784c..a31063e 100644
--- a/android/src/main/java/com/tailscale/ipn/ui/view/MullvadExitNodePicker.kt
+++ b/android/src/main/java/com/tailscale/ipn/ui/view/MullvadExitNodePicker.kt
@@ -51,7 +51,7 @@ fun MullvadExitNodePicker(
online = bestAvailableNode.online,
selected = false,
))
- Lists.ItemDivider()
+ Lists.SectionDivider()
}
}
diff --git a/android/src/main/java/com/tailscale/ipn/ui/view/SharedViews.kt b/android/src/main/java/com/tailscale/ipn/ui/view/SharedViews.kt
index 21685bf..bc64897 100644
--- a/android/src/main/java/com/tailscale/ipn/ui/view/SharedViews.kt
+++ b/android/src/main/java/com/tailscale/ipn/ui/view/SharedViews.kt
@@ -42,7 +42,7 @@ fun Header(@StringRes title: Int = 0, titleText: String? = null, onBack: (() ->
@Composable
fun BackArrow(action: () -> Unit) {
- Box(modifier = Modifier.padding(start = 15.dp, end = 20.dp)) {
+ Box(modifier = Modifier.padding(start = 8.dp, end = 8.dp)) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, null, modifier = Modifier.clickable { action() })
}
}
diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml
index d371083..ffb08ea 100644
--- a/android/src/main/res/values/strings.xml
+++ b/android/src/main/res/values/strings.xml
@@ -91,19 +91,19 @@
Unable to add a new profile. Please try again.
- Choose Exit Node
- Mullvad Exit Nodes
- Tailnet Exit Nodes
+ Choose exit node
+ Mullvad exit nodes
+ Tailnet exit nodes
Mullvad VPN
- Best Available
- Run as Exit Node
+ Best available
+ Run as exit node
Run this device as an exit node?
- 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.
+ 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.
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.
- Stop Running as Exit Node
- Start Running as Exit Node
- Now Running as Exit Node
- 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.
+ Stop running as exit node
+ Start running as exit node
+ Now running as exit node
+ 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.
Enabled
Disabled
Disable