small fixes, added vpn permission request before selection

This commit is contained in:
white
2025-10-14 20:31:05 +03:00
parent c49cce1de4
commit 2954cef0a6
5 changed files with 39 additions and 6 deletions

View File

@@ -240,7 +240,7 @@ class MainActivity : ComponentActivity() {
} }
} }
composable("debugScreen") { DebugScreen(navController) } composable("debugScreen") { DebugScreen(navController) }
composable("selectionScreen") { StrategySelectionScreen(navController) } composable("selectionScreen") { StrategySelectionScreen(navController, vpnPermissionLauncher) }
} }
} }
} }

View File

@@ -205,7 +205,7 @@ fun StrategySelectionItem(strategy : StrategyCheckResult, prefs : SharedPreferen
) )
FilledTonalIconButton( FilledTonalIconButton(
onClick = { onClick = {
disableStrategy(getActiveStrategy(prefs)[0], prefs) if (getActiveStrategy(prefs).isNotEmpty()) disableStrategy(getActiveStrategy(prefs)[0], prefs)
enableStrategy(strategy.path, prefs) enableStrategy(strategy.path, prefs)
scope.launch { scope.launch {
snackbarHostState.showSnackbar( snackbarHostState.showSnackbar(

View File

@@ -1,6 +1,9 @@
package com.cherret.zaprett.ui.screen package com.cherret.zaprett.ui.screen
import android.content.Context.MODE_PRIVATE import android.content.Context.MODE_PRIVATE
import android.content.Intent
import android.net.VpnService
import androidx.activity.result.ActivityResultLauncher
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@@ -33,29 +36,46 @@ import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.cherret.zaprett.R import com.cherret.zaprett.R
import com.cherret.zaprett.byedpi.ByeDpiVpnService
import com.cherret.zaprett.ui.component.StrategySelectionItem import com.cherret.zaprett.ui.component.StrategySelectionItem
import com.cherret.zaprett.ui.viewmodel.StrategySelectionViewModel import com.cherret.zaprett.ui.viewmodel.StrategySelectionViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun StrategySelectionScreen(navController: NavController, viewModel : StrategySelectionViewModel = viewModel()){ fun StrategySelectionScreen(navController: NavController, vpnLauncher: ActivityResultLauncher<Intent>, viewModel : StrategySelectionViewModel = viewModel()){
val snackbarHostState = remember { SnackbarHostState() } val snackbarHostState = remember { SnackbarHostState() }
val strategyStates = viewModel.strategyStates val strategyStates = viewModel.strategyStates
val context = LocalContext.current val context = LocalContext.current
val prefs = context.getSharedPreferences("settings", MODE_PRIVATE) val prefs = context.getSharedPreferences("settings", MODE_PRIVATE)
var showDialog = remember { mutableStateOf(false) } var showDialog = remember { mutableStateOf(false) }
val requestVpnPermission by viewModel.requestVpnPermission.collectAsState()
if (showDialog.value) { if (showDialog.value) {
InfoAlert { showDialog.value = false } InfoAlert { showDialog.value = false }
} }
LaunchedEffect(requestVpnPermission) {
if (requestVpnPermission) {
val intent = VpnService.prepare(context)
if (intent != null) {
vpnLauncher.launch(intent)
} else {
viewModel.startVpn()
viewModel.clearVpnPermissionRequest()
}
}
}
Scaffold( Scaffold(
topBar = { topBar = {
TopAppBar( TopAppBar(

View File

@@ -28,7 +28,7 @@ class IpsetViewModel(application: Application): BaseListsViewModel(application)
override fun deleteItem(item: String, snackbarHostState: SnackbarHostState, scope: CoroutineScope) { override fun deleteItem(item: String, snackbarHostState: SnackbarHostState, scope: CoroutineScope) {
val wasChecked = checked[item] == true val wasChecked = checked[item] == true
disableList(item, sharedPreferences) disableIpset(item, sharedPreferences)
val success = File(item).delete() val success = File(item).delete()
if (success) refresh() if (success) refresh()
if (sharedPreferences.getBoolean("use_module", false)) { if (sharedPreferences.getBoolean("use_module", false)) {

View File

@@ -5,6 +5,7 @@ import android.content.Context.MODE_PRIVATE
import android.content.Intent import android.content.Intent
import android.util.Log import android.util.Log
import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateListOf
import androidx.core.content.ContextCompat
import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.AndroidViewModel
import com.cherret.zaprett.R import com.cherret.zaprett.R
import com.cherret.zaprett.byedpi.ByeDpiVpnService import com.cherret.zaprett.byedpi.ByeDpiVpnService
@@ -22,6 +23,8 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@@ -36,6 +39,9 @@ class StrategySelectionViewModel(application: Application) : AndroidViewModel(ap
.build() .build()
val context = application val context = application
private val _requestVpnPermission = MutableStateFlow(false)
val requestVpnPermission = _requestVpnPermission.asStateFlow()
val strategyStates = mutableStateListOf<StrategyCheckResult>() val strategyStates = mutableStateListOf<StrategyCheckResult>()
init { init {
@@ -124,9 +130,10 @@ class StrategySelectionViewModel(application: Application) : AndroidViewModel(ap
}) })
delay(300L) delay(300L)
} }
context.startService(Intent(context, ByeDpiVpnService::class.java).apply { _requestVpnPermission.value = true
/*context.startService(Intent(context, ByeDpiVpnService::class.java).apply {
action = "START_VPN" action = "START_VPN"
}) })*/
val connected = withTimeoutOrNull(10_000L) { val connected = withTimeoutOrNull(10_000L) {
while (ByeDpiVpnService.status != ServiceStatus.Connected) { while (ByeDpiVpnService.status != ServiceStatus.Connected) {
@@ -158,4 +165,10 @@ class StrategySelectionViewModel(application: Application) : AndroidViewModel(ap
strategyStates.clear() strategyStates.clear()
strategyStates.addAll(sorted) strategyStates.addAll(sorted)
} }
fun startVpn() {
ContextCompat.startForegroundService(context, Intent(context, ByeDpiVpnService::class.java).apply { action = "START_VPN" })
}
fun clearVpnPermissionRequest() {
_requestVpnPermission.value = false
}
} }