diff --git a/android/src/main/java/com/tailscale/ipn/ui/view/LoginQRView.kt b/android/src/main/java/com/tailscale/ipn/ui/view/LoginQRView.kt index b3f465d..03ea17e 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/view/LoginQRView.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/view/LoginQRView.kt @@ -40,6 +40,7 @@ fun LoginQRView(onDismiss: () -> Unit = {}, model: LoginQRViewModel = viewModel( Surface(color = MaterialTheme.colorScheme.scrim, modifier = Modifier.fillMaxSize()) { Dialog(onDismissRequest = onDismiss) { val image by model.qrCode.collectAsState() + val numCode by model.numCode.collectAsState() Column( modifier = @@ -65,6 +66,12 @@ fun LoginQRView(onDismiss: () -> Unit = {}, model: LoginQRViewModel = viewModel( modifier = Modifier.fillMaxSize()) } } + numCode?.let { it -> + Text( + text = stringResource(R.string.enter_code_to_connect_to_tailnet, it), + style = MaterialTheme.typography.titleMedium, + color = MaterialTheme.colorScheme.onSurface) + } Button(onClick = onDismiss) { Text(text = stringResource(R.string.dismiss)) } } } @@ -76,5 +83,6 @@ fun LoginQRView(onDismiss: () -> Unit = {}, model: LoginQRViewModel = viewModel( fun LoginQRViewPreview() { val vm = LoginQRViewModel() vm.qrCode.set(vm.generateQRCode("https://tailscale.com", 200, 0)) + vm.numCode.set("123456789") AppTheme { LoginQRView({}, vm) } } diff --git a/android/src/main/java/com/tailscale/ipn/ui/viewModel/LoginQRViewModel.kt b/android/src/main/java/com/tailscale/ipn/ui/viewModel/LoginQRViewModel.kt index a3c5dcf..34d88df 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/viewModel/LoginQRViewModel.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/viewModel/LoginQRViewModel.kt @@ -20,12 +20,28 @@ import kotlinx.coroutines.launch class LoginQRViewModel : IpnViewModel() { + val numCode: StateFlow = MutableStateFlow(null) val qrCode: StateFlow = MutableStateFlow(null) init { viewModelScope.launch { Notifier.browseToURL.collect { url -> - url?.let { qrCode.set(generateQRCode(url, 200, 0)) } ?: run { qrCode.set(null) } + url?.let { + qrCode.set(generateQRCode(url, 200, 0)) + // Extract the string after "https://login.tailscale.com/a/" + val prefix = "https://login.tailscale.com/a/" + val code = + if (it.startsWith(prefix)) { + it.removePrefix(prefix) + } else { + null + } + numCode.set(code) + } + ?: run { + qrCode.set(null) + numCode.set(null) + } } } } diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml index fb69053..da43495 100644 --- a/android/src/main/res/values/strings.xml +++ b/android/src/main/res/values/strings.xml @@ -244,6 +244,7 @@ Tailscale is a mesh VPN for securely connecting your devices. All connections are device-to-device, so we never see your data. We collect and use your email address and name, as well as your device name, OS version, and IP address in order to help you to connect your devices and manage your settings. We log when you are connected to your network. Scan this QR code to log in to your tailnet + or enter this code in the admin console: %1$s VPN is not ready to start