You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
4.8 KiB
Kotlin
128 lines
4.8 KiB
Kotlin
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package com.tailscale.ipn
|
|
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.content.RestrictionsManager
|
|
import android.net.Uri
|
|
import android.os.Bundle
|
|
import androidx.activity.ComponentActivity
|
|
import androidx.activity.compose.setContent
|
|
import androidx.lifecycle.lifecycleScope
|
|
import androidx.navigation.NavType
|
|
import androidx.navigation.compose.NavHost
|
|
import androidx.navigation.compose.composable
|
|
import androidx.navigation.compose.rememberNavController
|
|
import androidx.navigation.navArgument
|
|
import com.tailscale.ipn.mdm.MDMSettings
|
|
import com.tailscale.ipn.ui.service.IpnManager
|
|
import com.tailscale.ipn.ui.theme.AppTheme
|
|
import com.tailscale.ipn.ui.view.AboutView
|
|
import com.tailscale.ipn.ui.view.BugReportView
|
|
import com.tailscale.ipn.ui.view.ExitNodePicker
|
|
import com.tailscale.ipn.ui.view.MainView
|
|
import com.tailscale.ipn.ui.view.MainViewNavigation
|
|
import com.tailscale.ipn.ui.view.PeerDetails
|
|
import com.tailscale.ipn.ui.view.Settings
|
|
import com.tailscale.ipn.ui.view.SettingsNav
|
|
import com.tailscale.ipn.ui.viewModel.BugReportViewModel
|
|
import com.tailscale.ipn.ui.viewModel.ExitNodePickerViewModel
|
|
import com.tailscale.ipn.ui.viewModel.MainViewModel
|
|
import com.tailscale.ipn.ui.viewModel.PeerDetailsViewModel
|
|
import com.tailscale.ipn.ui.viewModel.SettingsViewModel
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.launch
|
|
|
|
|
|
class MainActivity : ComponentActivity() {
|
|
private val manager = IpnManager(lifecycleScope)
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
|
|
setContent {
|
|
AppTheme {
|
|
val navController = rememberNavController()
|
|
NavHost(navController = navController, startDestination = "main") {
|
|
val mainViewNav = MainViewNavigation(
|
|
onNavigateToSettings = { navController.navigate("settings") },
|
|
onNavigateToPeerDetails = {
|
|
navController.navigate("peerDetails/${it.StableID}")
|
|
},
|
|
onNavigateToExitNodes = { navController.navigate("exitNodes") }
|
|
)
|
|
|
|
val settingsNav = SettingsNav(
|
|
onNavigateToBugReport = { navController.navigate("bugReport") },
|
|
onNavigateToAbout = { navController.navigate("about") }
|
|
|
|
)
|
|
|
|
composable("main") {
|
|
MainView(
|
|
viewModel = MainViewModel(manager.model, manager),
|
|
navigation = mainViewNav
|
|
)
|
|
}
|
|
composable("settings") {
|
|
Settings(SettingsViewModel(manager.model, manager, settingsNav))
|
|
}
|
|
composable("exitNodes") {
|
|
ExitNodePicker(ExitNodePickerViewModel(manager.model))
|
|
}
|
|
composable(
|
|
"peerDetails/{nodeId}",
|
|
arguments = listOf(navArgument("nodeId") { type = NavType.StringType })
|
|
) {
|
|
PeerDetails(
|
|
PeerDetailsViewModel(
|
|
manager.model, nodeId = it.arguments?.getString("nodeId")
|
|
?: ""
|
|
)
|
|
)
|
|
}
|
|
composable("bugReport") {
|
|
BugReportView(BugReportViewModel(manager.apiClient))
|
|
}
|
|
composable("about") {
|
|
AboutView()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
init {
|
|
// Watch the model's browseToURL and launch the browser when it changes
|
|
// This will trigger the login flow
|
|
lifecycleScope.launch {
|
|
manager.model.browseToURL.collect { url ->
|
|
url?.let {
|
|
Dispatchers.Main.run {
|
|
login(it)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun login(url: String) {
|
|
// (jonathan) TODO: This is functional, but the navigation doesn't quite work
|
|
// as expected. There's probably a better built in way to do this. This will
|
|
// unblock in dev for the time being though.
|
|
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
|
startActivity(browserIntent)
|
|
}
|
|
|
|
|
|
override fun onResume() {
|
|
super.onResume()
|
|
val restrictionsManager =
|
|
this.getSystemService(Context.RESTRICTIONS_SERVICE) as RestrictionsManager
|
|
manager.mdmSettings = MDMSettings(restrictionsManager)
|
|
}
|
|
}
|
|
|