package com.jihe.punchnet import android.app.Application import android.content.Context import android.content.Intent import android.net.VpnService import android.os.Build import android.os.Bundle import android.util.Log import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.annotation.StringRes import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.navigation.compose.rememberNavController import com.jihe.punchnet.data.ButtonState import com.jihe.punchnet.data.ButtonViewModel import com.jihe.punchnet.data.RouteViewModel import com.jihe.punchnet.data.ServiceViewModel import com.jihe.punchnet.screen.MainApp import com.jihe.punchnet.ui.theme.PunchnetTheme import kotlinx.coroutines.flow.onEach class PunchnetApp: Application() { val buttonModel: ButtonViewModel by lazy { ViewModelProvider.AndroidViewModelFactory.getInstance(this) .create(ButtonViewModel::class.java) } } class MainActivity : ComponentActivity() { private val TAG = "MainActivity" private val viewModel: RouteViewModel by viewModels { object: ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { return RouteViewModel(application) as T } } } private val serviceModel: ServiceViewModel by viewModels { object: ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { return ServiceViewModel(application) as T } } } /* val buttonModel: ButtonViewModel by viewModels { object: ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { return ButtonViewModel(application) as T } } } */ /* fun prepareAndStartVPN() { val intent = VpnService.prepare(this) if (intent != null) { vpnPermissionLauncher.launch(intent) } else { startVpnService(this) } } */ /* private fun startVpnService(context: Context) { val intent = Intent(context, PunchnetService::class.java) intent.putExtra("argument", PunchnetServiceArgument( "", arrayOf( RouteInfo( "192.168.80.0/24", "10.211.188.2" ) ) )) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(intent) } else { startService(intent) } Toast.makeText(this, "VPN service started", Toast.LENGTH_SHORT).show() } */ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Initialize AppAuthRepository for Split Tunneling com.jihe.punchnet.data.AppAuthRepository.init(this) enableEdgeToEdge() Log.d("DIR", "filesdir = ${this.filesDir}") val buttonModel = ButtonViewModel() buttonModel.updateState(ButtonState.ButtonStopped) setContent { PunchnetTheme { MainApp(buttonModel, serviceModel, viewModel, rememberNavController()) /* Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> StartStop( R.string.start_vpn, R.string.stop_vpn, onStart = { prepareAndStartVPN() }, onStop = { // stopVpnService() }, modifier = Modifier.padding(innerPadding) ) } */ } } } } @Composable fun StartStop( @StringRes start_name_id: Int, @StringRes stop_name_id: Int, onStart: ()->Unit, onStop: ()->Unit, modifier: Modifier = Modifier, ) { val start_text = stringResource(start_name_id) val stop_text = stringResource(stop_name_id) var button_state by rememberSaveable { mutableStateOf(false) } var button_text by rememberSaveable() { mutableStateOf(start_text) } Button( modifier = modifier, onClick = { button_state = !button_state if (button_state) { onStart() button_text = stop_text } else { Log.d("STOP", "call on stop") onStop() button_text = start_text } } ) { Text ( text = button_text ) } } @Composable fun Greeting(name: String, modifier: Modifier = Modifier) { Text( text = "Hello $name!", modifier = modifier ) } @Preview(showBackground = true) @Composable fun GreetingPreview() { PunchnetTheme { Greeting("Android") } }