diff --git a/android/src/main/java/com/tailscale/ipn/ui/util/AppVersion.kt b/android/src/main/java/com/tailscale/ipn/ui/util/AppVersion.kt new file mode 100644 index 0000000..fb042fb --- /dev/null +++ b/android/src/main/java/com/tailscale/ipn/ui/util/AppVersion.kt @@ -0,0 +1,20 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package com.tailscale.ipn.ui.util + +import com.tailscale.ipn.BuildConfig + +class AppVersion { + companion object { + // Returns the short version of the build version, which is what users typically expect. + // For instance, if the build version is "1.75.80-t8fdffb8da-g2daeee584df", + // this function returns "1.75.80". + fun Short(): String { + // Split the full version string by hyphen (-) + val parts = BuildConfig.VERSION_NAME.split("-") + // Return only the part before the first hyphen + return parts[0] + } + } +} diff --git a/android/src/main/java/com/tailscale/ipn/ui/view/AboutView.kt b/android/src/main/java/com/tailscale/ipn/ui/view/AboutView.kt index 7640b6c..fb0c098 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/view/AboutView.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/view/AboutView.kt @@ -33,6 +33,7 @@ import com.tailscale.ipn.BuildConfig import com.tailscale.ipn.R import com.tailscale.ipn.ui.Links import com.tailscale.ipn.ui.theme.logoBackground +import com.tailscale.ipn.ui.util.AppVersion @Composable fun AboutView(backToSettings: BackNavigation) { @@ -69,9 +70,14 @@ fun AboutView(backToSettings: BackNavigation) { Text( modifier = Modifier.clickable { + // When users tap on the version number, the extended version string + // (including commit hashes) is copied to the clipboard. + // This may be useful for debugging purposes... localClipboardManager.setText(AnnotatedString(BuildConfig.VERSION_NAME)) }, - text = "${stringResource(R.string.version)} ${BuildConfig.VERSION_NAME}", + // ... but we always display the short version in the UI to avoid user + // confusion. + text = "${stringResource(R.string.version)} ${AppVersion.Short()}", fontWeight = MaterialTheme.typography.bodyMedium.fontWeight, fontSize = MaterialTheme.typography.bodyMedium.fontSize) } diff --git a/android/src/main/java/com/tailscale/ipn/ui/view/SettingsView.kt b/android/src/main/java/com/tailscale/ipn/ui/view/SettingsView.kt index d83f50d..c425417 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/view/SettingsView.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/view/SettingsView.kt @@ -39,6 +39,7 @@ import com.tailscale.ipn.ui.viewModel.SettingsNav import com.tailscale.ipn.ui.viewModel.SettingsViewModel import com.tailscale.ipn.ui.viewModel.VpnViewModel import com.tailscale.ipn.ui.notifier.Notifier +import com.tailscale.ipn.ui.util.AppVersion @Composable fun SettingsView(settingsNav: SettingsNav, viewModel: SettingsViewModel = viewModel(), vpnViewModel: VpnViewModel = viewModel()) { @@ -112,7 +113,7 @@ fun SettingsView(settingsNav: SettingsNav, viewModel: SettingsViewModel = viewMo Lists.ItemDivider() Setting.Text( R.string.about_tailscale, - subtitle = "${stringResource(id = R.string.version)} ${BuildConfig.VERSION_NAME}", + subtitle = "${stringResource(id = R.string.version)} ${AppVersion.Short()}", onClick = settingsNav.onNavigateToAbout) // TODO: put a heading for the debug section 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 34d88df..7499fc0 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 @@ -22,21 +22,26 @@ class LoginQRViewModel : IpnViewModel() { val numCode: StateFlow = MutableStateFlow(null) val qrCode: StateFlow = MutableStateFlow(null) + // Remove this once changes to admin console allowing input code to be entered are made. + val codeEnabled = false init { viewModelScope.launch { Notifier.browseToURL.collect { url -> 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) + + if (codeEnabled) { + // 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)