mirror of
https://github.com/CherretGit/zaprett-app.git
synced 2025-12-10 05:29:37 +05:00
Compare commits
2 Commits
b5e3d256a6
...
80f5934060
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80f5934060 | ||
|
|
0065b8a92b |
21
.idea/appInsightsSettings.xml
generated
21
.idea/appInsightsSettings.xml
generated
@@ -2,5 +2,26 @@
|
||||
<project version="4">
|
||||
<component name="AppInsightsSettings">
|
||||
<option name="selectedTabId" value="Android Vitals" />
|
||||
<option name="tabSettings">
|
||||
<map>
|
||||
<entry key="Firebase Crashlytics">
|
||||
<value>
|
||||
<InsightsFilterSettings>
|
||||
<option name="connection">
|
||||
<ConnectionSetting>
|
||||
<option name="appId" value="com.cherret.zaprett" />
|
||||
<option name="mobileSdkAppId" value="1:1005804036856:android:e7db5546b8bb4daf91510d" />
|
||||
<option name="projectId" value="zaprett-app" />
|
||||
<option name="projectNumber" value="1005804036856" />
|
||||
</ConnectionSetting>
|
||||
</option>
|
||||
<option name="signal" value="SIGNAL_UNSPECIFIED" />
|
||||
<option name="timeIntervalDays" value="THIRTY_DAYS" />
|
||||
<option name="visibilityType" value="ALL" />
|
||||
</InsightsFilterSettings>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@@ -209,7 +209,7 @@ class MainActivity : ComponentActivity() {
|
||||
startDestination = Screen.home.route,
|
||||
Modifier.padding(innerPadding)
|
||||
) {
|
||||
composable(Screen.home.route) { HomeScreen(viewModel = viewModel, vpnPermissionLauncher) }
|
||||
composable(Screen.home.route) { HomeScreen(viewModel = viewModel,vpnPermissionLauncher) }
|
||||
composable(Screen.hosts.route) { HostsScreen(navController) }
|
||||
composable(Screen.strategies.route) { StrategyScreen(navController) }
|
||||
composable(Screen.ipsets.route) { IpsetsScreen(navController) }
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package com.cherret.zaprett.ui.screen
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.net.VpnService
|
||||
import android.os.Build
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.expandVertically
|
||||
@@ -65,12 +69,15 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
import com.cherret.zaprett.BuildConfig
|
||||
import com.cherret.zaprett.R
|
||||
import com.cherret.zaprett.data.ServiceStatusUI
|
||||
import com.cherret.zaprett.ui.viewmodel.HomeViewModel
|
||||
import dev.jeziellago.compose.markdowntext.MarkdownText
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.serialization.SerializationException
|
||||
import java.io.IOException
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -89,6 +96,7 @@ fun HomeScreen(viewModel: HomeViewModel = viewModel(), vpnLauncher: ActivityResu
|
||||
val nfqwsVer = viewModel.nfqwsVer;
|
||||
val byedpiVer = viewModel.byedpiVer;
|
||||
val serviceMode = viewModel.serviceMode
|
||||
val error by viewModel.errorFlow.collectAsState()
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.checkForUpdate()
|
||||
viewModel.checkServiceStatus()
|
||||
@@ -107,6 +115,37 @@ fun HomeScreen(viewModel: HomeViewModel = viewModel(), vpnLauncher: ActivityResu
|
||||
}
|
||||
}
|
||||
|
||||
if (error.isNotEmpty()) {
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
viewModel.clearError()
|
||||
},
|
||||
title = { Text(stringResource(R.string.error_text)) },
|
||||
text = {
|
||||
Text(stringResource(R.string.error_unknown))
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = {
|
||||
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip: ClipData = ClipData.newPlainText("Error log", error)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S) {
|
||||
Toast.makeText(context, context.getString(R.string.log_copied), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}) {
|
||||
Text(stringResource(R.string.btn_copy_log))
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
viewModel.clearError()
|
||||
}) {
|
||||
Text(stringResource(R.string.btn_continue))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
|
||||
@@ -45,6 +45,9 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||
private val _serviceStatus = MutableStateFlow(ServiceStatusUI())
|
||||
val serviceStatus: StateFlow<ServiceStatusUI> = _serviceStatus.asStateFlow()
|
||||
|
||||
private val _errorFlow = MutableStateFlow("")
|
||||
val errorFlow = _errorFlow.asStateFlow()
|
||||
|
||||
var moduleVer = mutableStateOf(context.getString(R.string.unknown_text))
|
||||
private set
|
||||
|
||||
@@ -129,7 +132,10 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||
)
|
||||
)
|
||||
}
|
||||
if (!isEnabled) startService {}
|
||||
if (!isEnabled) startService { error ->
|
||||
_errorFlow.value = error
|
||||
onCardClick()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ByeDpiVpnService.status == ServiceStatus.Disconnected || ByeDpiVpnService.status == ServiceStatus.Failed) {
|
||||
@@ -169,7 +175,10 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||
)
|
||||
)
|
||||
}
|
||||
if (isEnabled) stopService {}
|
||||
if (isEnabled) stopService { error ->
|
||||
_errorFlow.value = error
|
||||
onCardClick()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ByeDpiVpnService.status == ServiceStatus.Connected) {
|
||||
@@ -192,7 +201,10 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
fun onBtnRestart(snackbarHostState: SnackbarHostState, scope: CoroutineScope) {
|
||||
if (prefs.getBoolean("use_module", false)) {
|
||||
restartService {}
|
||||
restartService { error ->
|
||||
_errorFlow.value = error
|
||||
onCardClick()
|
||||
}
|
||||
scope.launch {
|
||||
snackbarHostState.showSnackbar(context.getString(R.string.snack_reload))
|
||||
}
|
||||
@@ -242,6 +254,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||
}
|
||||
}
|
||||
|
||||
// unused?
|
||||
fun parseArgs(ip: String, port: String, lines: List<String>): Array<String> {
|
||||
val regex = Regex("""--?\S+(?:=(?:[^"'\s]+|"[^"]*"|'[^']*'))?|[^\s]+""")
|
||||
val parsedArgs = lines
|
||||
@@ -249,4 +262,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||
return arrayOf("ciadpi", "--ip", ip, "--port", port) + parsedArgs
|
||||
}
|
||||
|
||||
fun clearError() {
|
||||
_errorFlow.value = ""
|
||||
}
|
||||
}
|
||||
@@ -75,21 +75,31 @@ fun getStatus(callback: (Boolean) -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
fun startService(callback: (Boolean) -> Unit) {
|
||||
Shell.cmd("zaprett start").submit { result ->
|
||||
callback(result.isSuccess)
|
||||
fun startService(callback: (String) -> Unit) {
|
||||
Shell.cmd("zaprett start 2>&1").submit { result ->
|
||||
callback(
|
||||
if (result.isSuccess) ""
|
||||
else result.out.joinToString("\n")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun stopService(callback: (Boolean) -> Unit) {
|
||||
Shell.cmd("zaprett stop").submit { result ->
|
||||
callback(result.isSuccess)
|
||||
|
||||
fun stopService(callback: (String) -> Unit) {
|
||||
Shell.cmd("zaprett stop 2>&1").submit { result ->
|
||||
callback(
|
||||
if (result.isSuccess) ""
|
||||
else result.out.joinToString("\n")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun restartService(callback: (Boolean) -> Unit) {
|
||||
Shell.cmd("zaprett restart").submit { result ->
|
||||
callback(result.isSuccess)
|
||||
fun restartService(callback: (String) -> Unit) {
|
||||
Shell.cmd("zaprett restart 2>&1").submit { result ->
|
||||
callback(
|
||||
if (result.isSuccess) ""
|
||||
else result.out.joinToString("\n")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user