mirror of
https://github.com/revanced/revanced-manager-compose.git
synced 2025-04-29 22:04:25 +02:00
feat: add settings to select default installer
This commit is contained in:
parent
6ca2268a34
commit
c5d859f990
@ -1,12 +1,21 @@
|
||||
package app.revanced.manager.domain.manager
|
||||
|
||||
import android.content.Context
|
||||
import app.revanced.manager.R
|
||||
import app.revanced.manager.domain.manager.base.BasePreferencesManager
|
||||
import app.revanced.manager.ui.theme.Theme
|
||||
|
||||
class PreferencesManager(
|
||||
context: Context
|
||||
) : BasePreferencesManager(context, "settings") {
|
||||
|
||||
enum class InstallerManager(val displayName: Int) {
|
||||
DEFAULT(R.string.default_installer),
|
||||
SHIZUKU(R.string.shizuku_installer),
|
||||
ROOT(R.string.root_installer),
|
||||
MAGISK(R.string.magisk_installer),
|
||||
}
|
||||
|
||||
val dynamicColor = booleanPreference("dynamic_color", true)
|
||||
val theme = enumPreference("theme", Theme.SYSTEM)
|
||||
|
||||
@ -18,6 +27,7 @@ class PreferencesManager(
|
||||
val keystorePass = stringPreference("keystore_pass", KeystoreManager.DEFAULT)
|
||||
|
||||
val preferSplits = booleanPreference("prefer_splits", false)
|
||||
val installer = enumPreference("installer", InstallerManager.DEFAULT)
|
||||
|
||||
val showAutoUpdatesDialog = booleanPreference("show_auto_updates_dialog", true)
|
||||
val managerAutoUpdates = booleanPreference("manager_auto_updates", false)
|
||||
|
@ -5,18 +5,24 @@ import android.os.Build
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Http
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.FilledTonalButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.RadioButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
@ -26,6 +32,7 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@ -33,10 +40,12 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.content.getSystemService
|
||||
import app.revanced.manager.R
|
||||
import app.revanced.manager.domain.manager.PreferencesManager
|
||||
import app.revanced.manager.ui.component.AppTopBar
|
||||
import app.revanced.manager.ui.component.GroupHeader
|
||||
import app.revanced.manager.ui.viewmodel.AdvancedSettingsViewModel
|
||||
import org.koin.androidx.compose.getViewModel
|
||||
import org.koin.compose.koinInject
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@ -44,7 +53,9 @@ fun AdvancedSettingsScreen(
|
||||
onBackClick: () -> Unit,
|
||||
vm: AdvancedSettingsViewModel = getViewModel()
|
||||
) {
|
||||
val prefs = vm.prefs
|
||||
val context = LocalContext.current
|
||||
var showInstallerPicker by rememberSaveable { mutableStateOf(false) }
|
||||
val memoryLimit = remember {
|
||||
val activityManager = context.getSystemService<ActivityManager>()!!
|
||||
context.getString(
|
||||
@ -54,6 +65,13 @@ fun AdvancedSettingsScreen(
|
||||
)
|
||||
}
|
||||
|
||||
if (showInstallerPicker) {
|
||||
InstallerPicker(
|
||||
onDismiss = { showInstallerPicker = false },
|
||||
onConfirm = { vm.setInstaller(it) }
|
||||
)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
@ -99,6 +117,26 @@ fun AdvancedSettingsScreen(
|
||||
}
|
||||
)
|
||||
|
||||
val installer by prefs.installer.getAsState()
|
||||
GroupHeader(stringResource(R.string.installer))
|
||||
ListItem(
|
||||
modifier = Modifier.clickable { showInstallerPicker = true },
|
||||
headlineContent = { Text(stringResource(R.string.installer)) },
|
||||
supportingContent = { Text(stringResource(R.string.installer_description)) },
|
||||
trailingContent = {
|
||||
FilledTonalButton(
|
||||
colors = ButtonDefaults.filledTonalButtonColors(
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer,
|
||||
),
|
||||
onClick = {
|
||||
showInstallerPicker = true
|
||||
}
|
||||
) {
|
||||
Text(stringResource(installer.displayName))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
GroupHeader(stringResource(R.string.device))
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.device_model)) },
|
||||
@ -172,4 +210,43 @@ private fun APIUrlDialog(currentUrl: String, onSubmit: (String?) -> Unit) {
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun InstallerPicker(
|
||||
onDismiss: () -> Unit,
|
||||
onConfirm: (PreferencesManager.InstallerManager) -> Unit,
|
||||
prefs: PreferencesManager = koinInject()
|
||||
) {
|
||||
var selectedInstaller by rememberSaveable { mutableStateOf(prefs.installer.getBlocking()) }
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(stringResource(R.string.installer)) },
|
||||
text = {
|
||||
Column {
|
||||
PreferencesManager.InstallerManager.values().forEach {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { selectedInstaller = it },
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
RadioButton(
|
||||
selected = selectedInstaller == it,
|
||||
onClick = { selectedInstaller = it })
|
||||
Text(stringResource(it.displayName))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
Button(onClick = {
|
||||
onConfirm(selectedInstaller)
|
||||
onDismiss()
|
||||
}) {
|
||||
Text(stringResource(R.string.apply))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package app.revanced.manager.ui.screen.settings
|
||||
|
||||
import android.os.Build
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
@ -23,7 +22,6 @@ import app.revanced.manager.ui.component.GroupHeader
|
||||
import app.revanced.manager.ui.component.settings.BooleanItem
|
||||
import app.revanced.manager.ui.theme.Theme
|
||||
import app.revanced.manager.ui.viewmodel.SettingsViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.compose.koinInject
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@ -65,7 +63,10 @@ fun GeneralSettingsScreen(
|
||||
headlineContent = { Text(stringResource(R.string.theme)) },
|
||||
supportingContent = { Text(stringResource(R.string.theme_description)) },
|
||||
trailingContent = {
|
||||
Button(
|
||||
FilledTonalButton(
|
||||
colors = ButtonDefaults.filledTonalButtonColors(
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer,
|
||||
),
|
||||
onClick = {
|
||||
showThemePicker = true
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class AdvancedSettingsViewModel(
|
||||
prefs: PreferencesManager,
|
||||
val prefs: PreferencesManager,
|
||||
private val app: Application,
|
||||
private val patchBundleRepository: PatchBundleRepository
|
||||
) : ViewModel() {
|
||||
@ -34,4 +34,8 @@ class AdvancedSettingsViewModel(
|
||||
fun resetBundles() = viewModelScope.launch {
|
||||
patchBundleRepository.reset()
|
||||
}
|
||||
|
||||
fun setInstaller(installer: PreferencesManager.InstallerManager) = viewModelScope.launch {
|
||||
prefs.installer.update(installer)
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import app.revanced.manager.domain.manager.KeystoreManager
|
||||
import app.revanced.manager.R
|
||||
import app.revanced.manager.domain.manager.PreferencesManager
|
||||
import app.revanced.manager.domain.worker.WorkerRepository
|
||||
import app.revanced.manager.patcher.worker.PatcherProgressManager
|
||||
import app.revanced.manager.patcher.worker.PatcherWorker
|
||||
@ -52,6 +53,7 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon
|
||||
private val pm: PM by inject()
|
||||
private val workerRepository: WorkerRepository by inject()
|
||||
|
||||
val prefs: PreferencesManager by inject()
|
||||
val packageName: String = input.selectedApp.packageName
|
||||
private val outputFile = File(app.cacheDir, "output.apk")
|
||||
private val signedFile = File(app.cacheDir, "signed.apk").also { if (it.exists()) it.delete() }
|
||||
@ -62,6 +64,7 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon
|
||||
var installedPackageName by mutableStateOf<String?>(null)
|
||||
private set
|
||||
val appButtonText by derivedStateOf { if (installedPackageName == null) R.string.install_app else R.string.open_app }
|
||||
private val selectedInstaller by derivedStateOf { prefs.installer.getBlocking() }
|
||||
|
||||
private val workManager = WorkManager.getInstance(app)
|
||||
|
||||
@ -124,7 +127,7 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
app.registerReceiver(installBroadcastReceiver, IntentFilter().apply {
|
||||
addAction(InstallService.APP_INSTALL_ACTION)
|
||||
@ -189,9 +192,22 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon
|
||||
isInstalling = true
|
||||
try {
|
||||
if (!signApk()) return@launch
|
||||
//
|
||||
// pm.installApp(listOf(signedFile))
|
||||
ShizukuApi.installPackage(signedFile)
|
||||
|
||||
when (selectedInstaller) {
|
||||
PreferencesManager.InstallerManager.DEFAULT -> {
|
||||
pm.installApp(listOf(signedFile))
|
||||
}
|
||||
PreferencesManager.InstallerManager.SHIZUKU -> {
|
||||
ShizukuApi.installPackage(signedFile)
|
||||
}
|
||||
PreferencesManager.InstallerManager.ROOT -> {
|
||||
// RootApi.installPackage(signedFile)
|
||||
}
|
||||
PreferencesManager.InstallerManager.MAGISK -> {
|
||||
// MagiskApi.installPackage(signedFile)
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
isInstalling = false
|
||||
}
|
||||
|
@ -233,4 +233,9 @@
|
||||
<string name="shizuku_available">Shizuku service available</string>
|
||||
<string name="shizuku_unavailable">Shizuku service not connected</string>
|
||||
<string name="home_shizuku_warning">Some functions unavailable</string>
|
||||
<string name="installer_description">Choose the default installer</string>
|
||||
<string name="default_installer">Default</string>
|
||||
<string name="shizuku_installer">Shizuku</string>
|
||||
<string name="root_installer">Root</string>
|
||||
<string name="magisk_installer">Magisk</string>
|
||||
</resources>
|
Loading…
x
Reference in New Issue
Block a user