mirror of
https://github.com/CherretGit/zaprett-app.git
synced 2025-12-11 05:59:37 +05:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8c3b6de96 | ||
|
|
b832be9556 | ||
|
|
817f3a0e7d | ||
|
|
7d25f7e600 | ||
|
|
8dcb4d1997 | ||
|
|
ba2cf523bd | ||
|
|
c268ee8ccd | ||
|
|
72905f4180 | ||
|
|
a7bb250a64 |
@@ -15,8 +15,8 @@ android {
|
|||||||
applicationId = "com.cherret.zaprett"
|
applicationId = "com.cherret.zaprett"
|
||||||
minSdk = 30
|
minSdk = 30
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 13
|
versionCode = 14
|
||||||
versionName = "2.1"
|
versionName = "2.2"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
ndk {
|
ndk {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<service
|
<service
|
||||||
android:name=".QSTileService"
|
android:name=".utils.QSTileService"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/qs_name"
|
android:label="@string/qs_name"
|
||||||
android:icon="@drawable/ic_launcher_monochrome"
|
android:icon="@drawable/ic_launcher_monochrome"
|
||||||
|
|||||||
Submodule app/src/main/cpp/byedpi updated: ed76be1dad...45d8c7ec7a
@@ -2,6 +2,7 @@ package com.cherret.zaprett
|
|||||||
|
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
@@ -18,9 +19,9 @@ import androidx.activity.viewModels
|
|||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Dashboard
|
|
||||||
import androidx.compose.material.icons.filled.Dns
|
|
||||||
import androidx.compose.material.icons.filled.Home
|
import androidx.compose.material.icons.filled.Home
|
||||||
|
import androidx.compose.material.icons.filled.Lan
|
||||||
|
import androidx.compose.material.icons.filled.MultipleStop
|
||||||
import androidx.compose.material.icons.filled.Settings
|
import androidx.compose.material.icons.filled.Settings
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
@@ -30,13 +31,13 @@ import androidx.compose.material3.Scaffold
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
@@ -55,14 +56,15 @@ import com.cherret.zaprett.ui.theme.ZaprettTheme
|
|||||||
import com.cherret.zaprett.ui.viewmodel.HomeViewModel
|
import com.cherret.zaprett.ui.viewmodel.HomeViewModel
|
||||||
import com.cherret.zaprett.ui.viewmodel.HostRepoViewModel
|
import com.cherret.zaprett.ui.viewmodel.HostRepoViewModel
|
||||||
import com.cherret.zaprett.ui.viewmodel.StrategyRepoViewModel
|
import com.cherret.zaprett.ui.viewmodel.StrategyRepoViewModel
|
||||||
|
import com.cherret.zaprett.utils.checkModuleInstallation
|
||||||
import com.google.firebase.Firebase
|
import com.google.firebase.Firebase
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics
|
import com.google.firebase.analytics.FirebaseAnalytics
|
||||||
import com.google.firebase.analytics.analytics
|
import com.google.firebase.analytics.analytics
|
||||||
|
|
||||||
sealed class Screen(val route: String, @StringRes val nameResId: Int, val icon: ImageVector) {
|
sealed class Screen(val route: String, @StringRes val nameResId: Int, val icon: ImageVector) {
|
||||||
object home : Screen("home", R.string.title_home, Icons.Default.Home)
|
object home : Screen("home", R.string.title_home, Icons.Default.Home)
|
||||||
object hosts : Screen("hosts", R.string.title_hosts, Icons.Default.Dashboard)
|
object hosts : Screen("hosts", R.string.title_hosts, Icons.Default.Lan)
|
||||||
object strategies : Screen("strategies", R.string.title_strategies, Icons.Default.Dns)
|
object strategies : Screen("strategies", R.string.title_strategies, Icons.Default.MultipleStop)
|
||||||
object settings : Screen("settings", R.string.title_settings, Icons.Default.Settings)
|
object settings : Screen("settings", R.string.title_settings, Icons.Default.Settings)
|
||||||
}
|
}
|
||||||
val topLevelRoutes = listOf(Screen.home, Screen.hosts, Screen.strategies, Screen.settings)
|
val topLevelRoutes = listOf(Screen.home, Screen.hosts, Screen.strategies, Screen.settings)
|
||||||
@@ -86,6 +88,17 @@ class MainActivity : ComponentActivity() {
|
|||||||
setContent {
|
setContent {
|
||||||
ZaprettTheme {
|
ZaprettTheme {
|
||||||
val sharedPreferences = remember { getSharedPreferences("settings", MODE_PRIVATE) }
|
val sharedPreferences = remember { getSharedPreferences("settings", MODE_PRIVATE) }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
|
||||||
|
checkModuleInstallation { result ->
|
||||||
|
if (getSharedPreferences("settings", Context.MODE_PRIVATE).getBoolean("use_module", false) && !result) sharedPreferences.edit {
|
||||||
|
putBoolean(
|
||||||
|
"use_module",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
var showStoragePermissionDialog by remember { mutableStateOf(!Environment.isExternalStorageManager()) }
|
var showStoragePermissionDialog by remember { mutableStateOf(!Environment.isExternalStorageManager()) }
|
||||||
var showNotificationPermissionDialog by remember {
|
var showNotificationPermissionDialog by remember {
|
||||||
mutableStateOf(
|
mutableStateOf(
|
||||||
@@ -133,6 +146,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomBar() {
|
fun BottomBar() {
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import android.widget.Toast
|
|||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import com.cherret.zaprett.MainActivity
|
import com.cherret.zaprett.MainActivity
|
||||||
import com.cherret.zaprett.R
|
import com.cherret.zaprett.R
|
||||||
import com.cherret.zaprett.getActiveStrategy
|
import com.cherret.zaprett.utils.getActiveStrategy
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -40,6 +40,7 @@ class ByeDpiVpnService : VpnService() {
|
|||||||
super.onStartCommand(intent, flags, startId)
|
super.onStartCommand(intent, flags, startId)
|
||||||
return when (intent?.action) {
|
return when (intent?.action) {
|
||||||
"START_VPN" -> {
|
"START_VPN" -> {
|
||||||
|
startForeground(NOTIFICATION_ID, createNotification())
|
||||||
setupProxy()
|
setupProxy()
|
||||||
START_STICKY
|
START_STICKY
|
||||||
}
|
}
|
||||||
@@ -98,23 +99,14 @@ class ByeDpiVpnService : VpnService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupProxy() {
|
private fun setupProxy() {
|
||||||
if (getActiveStrategy(sharedPreferences).isNotEmpty()) {
|
try {
|
||||||
startForeground(NOTIFICATION_ID, createNotification())
|
startSocksProxy()
|
||||||
try {
|
startByeDpi()
|
||||||
startSocksProxy()
|
status = ServiceStatus.Connected
|
||||||
startByeDpi()
|
} catch (e: Exception) {
|
||||||
status = ServiceStatus.Connected
|
Log.e("proxy", "Failed to start")
|
||||||
} catch (e: Exception) {
|
status = ServiceStatus.Failed
|
||||||
Log.e("proxy", "Failed to start")
|
stopSelf()
|
||||||
status = ServiceStatus.Failed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Toast.makeText(
|
|
||||||
this@ByeDpiVpnService,
|
|
||||||
getString(R.string.toast_no_strategy_selected),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ import androidx.compose.animation.expandVertically
|
|||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.animation.shrinkVertically
|
import androidx.compose.animation.shrinkVertically
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
@@ -49,6 +51,7 @@ import androidx.compose.runtime.collectAsState
|
|||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||||
@@ -75,6 +78,7 @@ fun HomeScreen(viewModel: HomeViewModel = viewModel(), vpnLauncher: ActivityResu
|
|||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
val cardText = viewModel.cardText
|
val cardText = viewModel.cardText
|
||||||
|
val cardIcon = viewModel.cardIcon;
|
||||||
val changeLog = viewModel.changeLog
|
val changeLog = viewModel.changeLog
|
||||||
val newVersion = viewModel.newVersion
|
val newVersion = viewModel.newVersion
|
||||||
val updateAvailable = viewModel.updateAvailable
|
val updateAvailable = viewModel.updateAvailable
|
||||||
@@ -119,7 +123,7 @@ fun HomeScreen(viewModel: HomeViewModel = viewModel(), vpnLauncher: ActivityResu
|
|||||||
Column(modifier = Modifier
|
Column(modifier = Modifier
|
||||||
.padding(paddingValues)
|
.padding(paddingValues)
|
||||||
.verticalScroll(rememberScrollState())) {
|
.verticalScroll(rememberScrollState())) {
|
||||||
ServiceStatusCard(viewModel, cardText, snackbarHostState, scope)
|
ServiceStatusCard(viewModel, cardText, cardIcon, snackbarHostState, scope)
|
||||||
UpdateCard(updateAvailable) { viewModel.showUpdateDialog() }
|
UpdateCard(updateAvailable) { viewModel.showUpdateDialog() }
|
||||||
if (showUpdateDialog) {
|
if (showUpdateDialog) {
|
||||||
UpdateDialog(viewModel, changeLog.value.orEmpty(), newVersion) { viewModel.dismissUpdateDialog() }
|
UpdateDialog(viewModel, changeLog.value.orEmpty(), newVersion) { viewModel.dismissUpdateDialog() }
|
||||||
@@ -137,25 +141,40 @@ fun HomeScreen(viewModel: HomeViewModel = viewModel(), vpnLauncher: ActivityResu
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ServiceStatusCard(viewModel: HomeViewModel, cardText: MutableState<Int>, snackbarHostState: SnackbarHostState, scope: CoroutineScope) {
|
private fun ServiceStatusCard(viewModel: HomeViewModel, cardText: MutableState<Int>, cardIcon : MutableState<ImageVector>, snackbarHostState: SnackbarHostState, scope: CoroutineScope) {
|
||||||
ElevatedCard(
|
ElevatedCard(
|
||||||
elevation = CardDefaults.cardElevation(6.dp),
|
elevation = CardDefaults.cardElevation(6.dp),
|
||||||
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.primary),
|
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.primary),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(start = 10.dp, top = 25.dp, end = 10.dp)
|
.padding(start = 10.dp, top = 25.dp, end = 10.dp)
|
||||||
.width(240.dp)
|
|
||||||
.height(150.dp),
|
.height(150.dp),
|
||||||
onClick = { viewModel.onCardClick() }
|
onClick = { viewModel.onCardClick() }
|
||||||
) {
|
) {
|
||||||
Text(
|
Row (
|
||||||
text = stringResource(cardText.value),
|
|
||||||
fontFamily = FontFamily(Font(R.font.unbounded, FontWeight.Normal)),
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxSize()
|
||||||
.padding(16.dp),
|
.padding(16.dp),
|
||||||
textAlign = TextAlign.Center
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
)
|
)
|
||||||
|
{
|
||||||
|
Icon(
|
||||||
|
painter = rememberVectorPainter(cardIcon.value),
|
||||||
|
modifier = Modifier
|
||||||
|
.width(60.dp)
|
||||||
|
.height(60.dp),
|
||||||
|
contentDescription = "icon"
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = stringResource(cardText.value),
|
||||||
|
fontFamily = FontFamily(Font(R.font.unbounded, FontWeight.Normal)),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp),
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,11 @@ import com.cherret.zaprett.BuildConfig
|
|||||||
import com.cherret.zaprett.byedpi.ByeDpiVpnService
|
import com.cherret.zaprett.byedpi.ByeDpiVpnService
|
||||||
import com.cherret.zaprett.R
|
import com.cherret.zaprett.R
|
||||||
import com.cherret.zaprett.byedpi.ServiceStatus
|
import com.cherret.zaprett.byedpi.ServiceStatus
|
||||||
import com.cherret.zaprett.checkModuleInstallation
|
import com.cherret.zaprett.utils.checkModuleInstallation
|
||||||
import com.cherret.zaprett.checkRoot
|
import com.cherret.zaprett.utils.checkRoot
|
||||||
import com.cherret.zaprett.getStartOnBoot
|
import com.cherret.zaprett.utils.getStartOnBoot
|
||||||
import com.cherret.zaprett.setStartOnBoot
|
import com.cherret.zaprett.utils.setStartOnBoot
|
||||||
|
import com.cherret.zaprett.utils.stopService
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -66,7 +67,10 @@ fun SettingsScreen() {
|
|||||||
openNoRootDialog = openNoRootDialog,
|
openNoRootDialog = openNoRootDialog,
|
||||||
openNoModuleDialog = openNoModuleDialog
|
openNoModuleDialog = openNoModuleDialog
|
||||||
) { success ->
|
) { success ->
|
||||||
if (success) useModule.value = isChecked
|
if (success) {
|
||||||
|
useModule.value = isChecked
|
||||||
|
if (!isChecked) stopService { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import com.cherret.zaprett.R
|
import com.cherret.zaprett.R
|
||||||
import com.cherret.zaprett.getZaprettPath
|
import com.cherret.zaprett.utils.getZaprettPath
|
||||||
import com.cherret.zaprett.restartService
|
import com.cherret.zaprett.utils.restartService
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ import androidx.compose.runtime.mutableStateMapOf
|
|||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.cherret.zaprett.RepoItemInfo
|
import com.cherret.zaprett.utils.RepoItemInfo
|
||||||
import com.cherret.zaprett.R
|
import com.cherret.zaprett.R
|
||||||
import com.cherret.zaprett.download
|
import com.cherret.zaprett.utils.download
|
||||||
import com.cherret.zaprett.getFileSha256
|
import com.cherret.zaprett.utils.getFileSha256
|
||||||
import com.cherret.zaprett.getZaprettPath
|
import com.cherret.zaprett.utils.getZaprettPath
|
||||||
import com.cherret.zaprett.registerDownloadListenerHost
|
import com.cherret.zaprett.utils.registerDownloadListenerHost
|
||||||
import com.cherret.zaprett.restartService
|
import com.cherret.zaprett.utils.restartService
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|||||||
@@ -3,6 +3,12 @@ package com.cherret.zaprett.ui.viewmodel
|
|||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.Help
|
||||||
|
import androidx.compose.material.icons.filled.Cancel
|
||||||
|
import androidx.compose.material.icons.filled.CheckCircle
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -11,17 +17,18 @@ import androidx.lifecycle.AndroidViewModel
|
|||||||
import com.cherret.zaprett.byedpi.ByeDpiVpnService
|
import com.cherret.zaprett.byedpi.ByeDpiVpnService
|
||||||
import com.cherret.zaprett.R
|
import com.cherret.zaprett.R
|
||||||
import com.cherret.zaprett.byedpi.ServiceStatus
|
import com.cherret.zaprett.byedpi.ServiceStatus
|
||||||
import com.cherret.zaprett.download
|
import com.cherret.zaprett.utils.download
|
||||||
import com.cherret.zaprett.getBinVersion
|
import com.cherret.zaprett.utils.getActiveStrategy
|
||||||
import com.cherret.zaprett.getChangelog
|
import com.cherret.zaprett.utils.getBinVersion
|
||||||
import com.cherret.zaprett.getModuleVersion
|
import com.cherret.zaprett.utils.getChangelog
|
||||||
import com.cherret.zaprett.getStatus
|
import com.cherret.zaprett.utils.getModuleVersion
|
||||||
import com.cherret.zaprett.getUpdate
|
import com.cherret.zaprett.utils.getStatus
|
||||||
import com.cherret.zaprett.installApk
|
import com.cherret.zaprett.utils.getUpdate
|
||||||
import com.cherret.zaprett.registerDownloadListener
|
import com.cherret.zaprett.utils.installApk
|
||||||
import com.cherret.zaprett.restartService
|
import com.cherret.zaprett.utils.registerDownloadListener
|
||||||
import com.cherret.zaprett.startService
|
import com.cherret.zaprett.utils.restartService
|
||||||
import com.cherret.zaprett.stopService
|
import com.cherret.zaprett.utils.startService
|
||||||
|
import com.cherret.zaprett.utils.stopService
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
@@ -34,6 +41,8 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
val requestVpnPermission = _requestVpnPermission.asStateFlow()
|
val requestVpnPermission = _requestVpnPermission.asStateFlow()
|
||||||
var cardText = mutableIntStateOf(R.string.status_not_availible) // MVP temporarily(maybe)
|
var cardText = mutableIntStateOf(R.string.status_not_availible) // MVP temporarily(maybe)
|
||||||
private set
|
private set
|
||||||
|
var cardIcon = mutableStateOf(Icons.AutoMirrored.Filled.Help)
|
||||||
|
private set
|
||||||
|
|
||||||
var moduleVer = mutableStateOf(context.getString(R.string.unknown_text))
|
var moduleVer = mutableStateOf(context.getString(R.string.unknown_text))
|
||||||
private set
|
private set
|
||||||
@@ -77,21 +86,49 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
fun checkServiceStatus() {
|
fun checkServiceStatus() {
|
||||||
if (prefs.getBoolean("use_module", false) && prefs.getBoolean("update_on_boot", false)) {
|
if (prefs.getBoolean("use_module", false) && prefs.getBoolean("update_on_boot", false)) {
|
||||||
getStatus { isEnabled ->
|
getStatus { isEnabled ->
|
||||||
cardText.intValue = if (isEnabled) R.string.status_enabled else R.string.status_disabled
|
if (isEnabled){
|
||||||
|
cardText.value = R.string.status_enabled
|
||||||
|
cardIcon.value = Icons.Filled.CheckCircle
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cardText.value = R.string.status_disabled
|
||||||
|
cardIcon.value = Icons.Filled.Cancel
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cardText.value = if (ByeDpiVpnService.status == ServiceStatus.Connected) R.string.status_enabled else R.string.status_disabled
|
if (ByeDpiVpnService.status == ServiceStatus.Connected){
|
||||||
|
cardText.value = R.string.status_enabled
|
||||||
|
cardIcon.value = Icons.Filled.CheckCircle
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cardText.value = R.string.status_disabled
|
||||||
|
cardIcon.value = Icons.Filled.Cancel
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onCardClick() {
|
fun onCardClick() {
|
||||||
if (prefs.getBoolean("use_module", false)) {
|
if (prefs.getBoolean("use_module", false)) {
|
||||||
getStatus { isEnabled ->
|
getStatus { isEnabled ->
|
||||||
cardText.value = if (isEnabled) R.string.status_enabled else R.string.status_disabled
|
if (isEnabled){
|
||||||
|
cardText.value = R.string.status_enabled
|
||||||
|
cardIcon.value = Icons.Filled.CheckCircle
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cardText.value = R.string.status_disabled
|
||||||
|
cardIcon.value = Icons.Filled.Cancel
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cardText.value = if (ByeDpiVpnService.status == ServiceStatus.Connected) R.string.status_enabled else R.string.status_disabled
|
if (ByeDpiVpnService.status == ServiceStatus.Connected){
|
||||||
|
cardText.value = R.string.status_enabled
|
||||||
|
cardIcon.value = Icons.Filled.CheckCircle
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cardText.value = R.string.status_disabled
|
||||||
|
cardIcon.value = Icons.Filled.Cancel
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,10 +150,19 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ByeDpiVpnService.status == ServiceStatus.Disconnected || ByeDpiVpnService.status == ServiceStatus.Failed) {
|
if (ByeDpiVpnService.status == ServiceStatus.Disconnected || ByeDpiVpnService.status == ServiceStatus.Failed) {
|
||||||
scope.launch {
|
if (getActiveStrategy(prefs).isNotEmpty()) {
|
||||||
snackbarHostState.showSnackbar(context.getString(R.string.snack_starting_service))
|
scope.launch {
|
||||||
|
snackbarHostState.showSnackbar(context.getString(R.string.snack_starting_service))
|
||||||
|
}
|
||||||
|
_requestVpnPermission.value = true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
context.getString(R.string.toast_no_strategy_selected),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
}
|
}
|
||||||
_requestVpnPermission.value = true
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
|
|||||||
@@ -1,16 +1,9 @@
|
|||||||
package com.cherret.zaprett.ui.viewmodel
|
package com.cherret.zaprett.ui.viewmodel
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.lifecycle.viewModelScope
|
import com.cherret.zaprett.utils.RepoItemInfo
|
||||||
import com.cherret.zaprett.RepoItemInfo
|
import com.cherret.zaprett.utils.getAllLists
|
||||||
import com.cherret.zaprett.download
|
import com.cherret.zaprett.utils.getHostList
|
||||||
import com.cherret.zaprett.getAllLists
|
|
||||||
import com.cherret.zaprett.getHostList
|
|
||||||
import com.cherret.zaprett.getZaprettPath
|
|
||||||
import com.cherret.zaprett.registerDownloadListenerHost
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class HostRepoViewModel(application: Application): BaseRepoViewModel(application) {
|
class HostRepoViewModel(application: Application): BaseRepoViewModel(application) {
|
||||||
override fun getInstalledLists(): Array<String> = getAllLists()
|
override fun getInstalledLists(): Array<String> = getAllLists()
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ package com.cherret.zaprett.ui.viewmodel
|
|||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import com.cherret.zaprett.disableList
|
import com.cherret.zaprett.utils.disableList
|
||||||
import com.cherret.zaprett.enableList
|
import com.cherret.zaprett.utils.enableList
|
||||||
import com.cherret.zaprett.getActiveLists
|
import com.cherret.zaprett.utils.getActiveLists
|
||||||
import com.cherret.zaprett.getAllLists
|
import com.cherret.zaprett.utils.getAllLists
|
||||||
import com.cherret.zaprett.getStatus
|
import com.cherret.zaprett.utils.getStatus
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.cherret.zaprett.ui.viewmodel
|
package com.cherret.zaprett.ui.viewmodel
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import com.cherret.zaprett.RepoItemInfo
|
import com.cherret.zaprett.utils.RepoItemInfo
|
||||||
import com.cherret.zaprett.getAllByeDPIStrategies
|
import com.cherret.zaprett.utils.getAllByeDPIStrategies
|
||||||
import com.cherret.zaprett.getAllNfqwsStrategies
|
import com.cherret.zaprett.utils.getAllNfqwsStrategies
|
||||||
import com.cherret.zaprett.getStrategiesList
|
import com.cherret.zaprett.utils.getStrategiesList
|
||||||
|
|
||||||
class StrategyRepoViewModel(application: Application): BaseRepoViewModel(application) {
|
class StrategyRepoViewModel(application: Application): BaseRepoViewModel(application) {
|
||||||
override fun getInstalledLists(): Array<String> =
|
override fun getInstalledLists(): Array<String> =
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import android.content.SharedPreferences
|
|||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import com.cherret.zaprett.byedpi.ByeDpiVpnService
|
import com.cherret.zaprett.byedpi.ByeDpiVpnService
|
||||||
import com.cherret.zaprett.byedpi.ServiceStatus
|
import com.cherret.zaprett.byedpi.ServiceStatus
|
||||||
import com.cherret.zaprett.disableStrategy
|
import com.cherret.zaprett.utils.disableStrategy
|
||||||
import com.cherret.zaprett.enableStrategy
|
import com.cherret.zaprett.utils.enableStrategy
|
||||||
import com.cherret.zaprett.getActiveByeDPIStrategies
|
import com.cherret.zaprett.utils.getActiveByeDPIStrategies
|
||||||
import com.cherret.zaprett.getActiveNfqwsStrategies
|
import com.cherret.zaprett.utils.getActiveNfqwsStrategies
|
||||||
import com.cherret.zaprett.getAllByeDPIStrategies
|
import com.cherret.zaprett.utils.getAllByeDPIStrategies
|
||||||
import com.cherret.zaprett.getAllNfqwsStrategies
|
import com.cherret.zaprett.utils.getAllNfqwsStrategies
|
||||||
import com.cherret.zaprett.getStatus
|
import com.cherret.zaprett.utils.getStatus
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.cherret.zaprett
|
package com.cherret.zaprett.utils
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package com.cherret.zaprett
|
package com.cherret.zaprett.utils
|
||||||
|
|
||||||
import android.service.quicksettings.Tile
|
import android.service.quicksettings.Tile
|
||||||
import android.service.quicksettings.TileService
|
import android.service.quicksettings.TileService
|
||||||
|
import com.cherret.zaprett.R
|
||||||
|
|
||||||
class QSTileService: TileService() {
|
class QSTileService: TileService() {
|
||||||
override fun onTileAdded() {
|
override fun onTileAdded() {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.cherret.zaprett
|
package com.cherret.zaprett.utils
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.DownloadManager
|
import android.app.DownloadManager
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.cherret.zaprett
|
package com.cherret.zaprett.utils
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.DownloadManager
|
import android.app.DownloadManager
|
||||||
@@ -13,6 +13,7 @@ import android.provider.Settings
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
import com.cherret.zaprett.BuildConfig
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import okhttp3.Call
|
import okhttp3.Call
|
||||||
@@ -101,6 +102,11 @@ fun installApk(context: Context, uri: Uri) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun registerDownloadListener(context: Context, downloadId: Long, onDownloaded: (Uri) -> Unit) {// AI Generated
|
fun registerDownloadListener(context: Context, downloadId: Long, onDownloaded: (Uri) -> Unit) {// AI Generated
|
||||||
|
if (!context.packageManager.canRequestPackageInstalls()){
|
||||||
|
val packageUri = Uri.fromParts("package", context.packageName, null)
|
||||||
|
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageUri)
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
val receiver = object : BroadcastReceiver() {
|
val receiver = object : BroadcastReceiver() {
|
||||||
@SuppressLint("Range")
|
@SuppressLint("Range")
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
Reference in New Issue
Block a user