Compare commits

..

1 Commits

Author SHA1 Message Date
4ea8411f3f refactor: Rename settings screens for consistency 2025-05-14 10:19:07 +02:00
21 changed files with 143 additions and 372 deletions

View File

@ -164,7 +164,7 @@ private fun ReVancedManager(vm: MainViewModel) {
} }
} }
}, },
viewModel = koinViewModel { parametersOf(it.getComplexArg<Patcher.ViewModelParams>()) } vm = koinViewModel { parametersOf(it.getComplexArg<Patcher.ViewModelParams>()) }
) )
} }

View File

@ -3,7 +3,6 @@ package app.revanced.manager.domain.manager
import android.content.Context import android.content.Context
import app.revanced.manager.domain.manager.base.BasePreferencesManager import app.revanced.manager.domain.manager.base.BasePreferencesManager
import app.revanced.manager.ui.theme.Theme import app.revanced.manager.ui.theme.Theme
import app.revanced.manager.util.isDebuggable
class PreferencesManager( class PreferencesManager(
context: Context context: Context
@ -29,6 +28,4 @@ class PreferencesManager(
val suggestedVersionSafeguard = booleanPreference("suggested_version_safeguard", true) val suggestedVersionSafeguard = booleanPreference("suggested_version_safeguard", true)
val acknowledgedDownloaderPlugins = stringSetPreference("acknowledged_downloader_plugins", emptySet()) val acknowledgedDownloaderPlugins = stringSetPreference("acknowledged_downloader_plugins", emptySet())
val showDeveloperSettings = booleanPreference("show_developer_settings", context.isDebuggable)
} }

View File

@ -1,41 +0,0 @@
package app.revanced.manager.ui.component
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import app.revanced.manager.R
@Composable
fun ConfirmDialog(
onDismiss: () -> Unit,
onConfirm: () -> Unit,
title: String,
description: String,
icon: ImageVector
) {
AlertDialog(
onDismissRequest = onDismiss,
dismissButton = {
TextButton(onDismiss) {
Text(stringResource(R.string.cancel))
}
},
confirmButton = {
TextButton(
onClick = {
onConfirm()
onDismiss()
}
) {
Text(stringResource(R.string.confirm))
}
},
title = { Text(title) },
icon = { Icon(icon, null) },
text = { Text(description) }
)
}

View File

@ -16,6 +16,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import app.revanced.manager.R import app.revanced.manager.R
import app.revanced.manager.ui.component.bundle.BundleTopBar import app.revanced.manager.ui.component.bundle.BundleTopBar
@ -24,8 +26,12 @@ import app.revanced.manager.ui.component.bundle.BundleTopBar
fun ExceptionViewerDialog(text: String, onDismiss: () -> Unit) { fun ExceptionViewerDialog(text: String, onDismiss: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
FullscreenDialog( Dialog(
onDismissRequest = onDismiss, onDismissRequest = onDismiss,
properties = DialogProperties(
usePlatformDefaultWidth = false,
dismissOnBackPress = true
)
) { ) {
Scaffold( Scaffold(
topBar = { topBar = {

View File

@ -1,34 +0,0 @@
package app.revanced.manager.ui.component
import android.view.WindowManager
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.compose.ui.window.DialogWindowProvider
private val properties = DialogProperties(
usePlatformDefaultWidth = false,
dismissOnBackPress = true,
decorFitsSystemWindows = false,
)
@Composable
fun FullscreenDialog(onDismissRequest: () -> Unit, content: @Composable () -> Unit) {
Dialog(
onDismissRequest = onDismissRequest,
properties = properties
) {
val window = (LocalView.current.parent as DialogWindowProvider).window
LaunchedEffect(Unit) {
window.statusBarColor = Color.Transparent.toArgb()
window.navigationBarColor = Color.Transparent.toArgb()
window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
}
content()
}
}

View File

@ -12,6 +12,8 @@ import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import app.revanced.manager.R import app.revanced.manager.R
import app.revanced.manager.data.platform.NetworkInfo import app.revanced.manager.data.platform.NetworkInfo
@ -21,7 +23,6 @@ import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.asRemote
import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.isDefault import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.isDefault
import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.nameState import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.nameState
import app.revanced.manager.ui.component.ExceptionViewerDialog import app.revanced.manager.ui.component.ExceptionViewerDialog
import app.revanced.manager.ui.component.FullscreenDialog
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.compose.koinInject import org.koin.compose.koinInject
@ -55,8 +56,12 @@ fun BundleInformationDialog(
) )
} }
FullscreenDialog( Dialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
properties = DialogProperties(
usePlatformDefaultWidth = false,
dismissOnBackPress = true
)
) { ) {
val bundleName by bundle.nameState val bundleName by bundle.nameState

View File

@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.ErrorOutline import androidx.compose.material.icons.outlined.ErrorOutline
import androidx.compose.material.icons.outlined.Warning import androidx.compose.material.icons.outlined.Warning
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -27,9 +26,8 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import app.revanced.manager.R import app.revanced.manager.R
import app.revanced.manager.domain.bundles.PatchBundleSource import app.revanced.manager.domain.bundles.PatchBundleSource
import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.nameState
import app.revanced.manager.ui.component.ConfirmDialog
import app.revanced.manager.ui.component.haptics.HapticCheckbox import app.revanced.manager.ui.component.haptics.HapticCheckbox
import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.nameState
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@ -44,7 +42,6 @@ fun BundleItem(
toggleSelection: (Boolean) -> Unit, toggleSelection: (Boolean) -> Unit,
) { ) {
var viewBundleDialogPage by rememberSaveable { mutableStateOf(false) } var viewBundleDialogPage by rememberSaveable { mutableStateOf(false) }
var showDeleteConfirmationDialog by rememberSaveable { mutableStateOf(false) }
val state by bundle.state.collectAsStateWithLifecycle() val state by bundle.state.collectAsStateWithLifecycle()
val version by remember(bundle) { val version by remember(bundle) {
@ -55,25 +52,15 @@ fun BundleItem(
if (viewBundleDialogPage) { if (viewBundleDialogPage) {
BundleInformationDialog( BundleInformationDialog(
onDismissRequest = { viewBundleDialogPage = false }, onDismissRequest = { viewBundleDialogPage = false },
onDeleteRequest = { showDeleteConfirmationDialog = true }, onDeleteRequest = {
viewBundleDialogPage = false
onDelete()
},
bundle = bundle, bundle = bundle,
onUpdate = onUpdate, onUpdate = onUpdate,
) )
} }
if (showDeleteConfirmationDialog) {
ConfirmDialog(
onDismiss = { showDeleteConfirmationDialog = false },
onConfirm = {
onDelete()
viewBundleDialogPage = false
},
title = stringResource(R.string.bundle_delete_single_dialog_title),
description = stringResource(R.string.bundle_delete_single_dialog_description, name),
icon = Icons.Outlined.Delete
)
}
ListItem( ListItem(
modifier = Modifier modifier = Modifier
.height(64.dp) .height(64.dp)

View File

@ -22,12 +22,13 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import app.revanced.manager.R import app.revanced.manager.R
import app.revanced.manager.domain.bundles.PatchBundleSource import app.revanced.manager.domain.bundles.PatchBundleSource
import app.revanced.manager.patcher.patch.PatchInfo import app.revanced.manager.patcher.patch.PatchInfo
import app.revanced.manager.ui.component.ArrowButton import app.revanced.manager.ui.component.ArrowButton
import app.revanced.manager.ui.component.FullscreenDialog
import app.revanced.manager.ui.component.LazyColumnWithScrollbar import app.revanced.manager.ui.component.LazyColumnWithScrollbar
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@ -40,8 +41,12 @@ fun BundlePatchesDialog(
var showOptions by rememberSaveable { mutableStateOf(false) } var showOptions by rememberSaveable { mutableStateOf(false) }
val state by bundle.state.collectAsStateWithLifecycle() val state by bundle.state.collectAsStateWithLifecycle()
FullscreenDialog( Dialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
properties = DialogProperties(
usePlatformDefaultWidth = false,
dismissOnBackPress = true
)
) { ) {
Scaffold( Scaffold(
topBar = { topBar = {

View File

@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListItemInfo
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
@ -56,13 +55,13 @@ import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties
import app.revanced.manager.R import app.revanced.manager.R
import app.revanced.manager.data.platform.Filesystem import app.revanced.manager.data.platform.Filesystem
import app.revanced.manager.patcher.patch.Option import app.revanced.manager.patcher.patch.Option
import app.revanced.manager.ui.component.AlertDialogExtended import app.revanced.manager.ui.component.AlertDialogExtended
import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.FloatInputDialog import app.revanced.manager.ui.component.FloatInputDialog
import app.revanced.manager.ui.component.FullscreenDialog
import app.revanced.manager.ui.component.IntInputDialog import app.revanced.manager.ui.component.IntInputDialog
import app.revanced.manager.ui.component.LongInputDialog import app.revanced.manager.ui.component.LongInputDialog
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
@ -74,17 +73,16 @@ import app.revanced.manager.util.saver.snapshotStateListSaver
import app.revanced.manager.util.saver.snapshotStateSetSaver import app.revanced.manager.util.saver.snapshotStateSetSaver
import app.revanced.manager.util.toast import app.revanced.manager.util.toast
import app.revanced.manager.util.transparentListItemColors import app.revanced.manager.util.transparentListItemColors
import kotlinx.coroutines.CoroutineScope
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import org.koin.compose.koinInject import org.koin.compose.koinInject
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.get import org.koin.core.component.get
import sh.calvin.reorderable.ReorderableItem import sh.calvin.reorderable.ReorderableItem
import sh.calvin.reorderable.rememberReorderableLazyColumnState import sh.calvin.reorderable.rememberReorderableLazyColumnState
import sh.calvin.reorderable.rememberReorderableLazyListState
import java.io.Serializable import java.io.Serializable
import kotlin.random.Random import kotlin.random.Random
import kotlin.reflect.typeOf import kotlin.reflect.typeOf
import androidx.compose.ui.window.Dialog as ComposeDialog
private class OptionEditorScope<T : Any>( private class OptionEditorScope<T : Any>(
private val editor: OptionEditor<T>, private val editor: OptionEditor<T>,
@ -499,8 +497,7 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
val lazyListState = rememberLazyListState() val lazyListState = rememberLazyListState()
val reorderableLazyColumnState = val reorderableLazyColumnState =
// Update the list rememberReorderableLazyColumnState(lazyListState) { from, to ->
rememberReorderableLazyListState(lazyListState) { from, to ->
// Update the list // Update the list
items.add(to.index, items.removeAt(from.index)) items.add(to.index, items.removeAt(from.index))
} }
@ -527,8 +524,12 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
scope.submitDialog(items.mapNotNull { it.value }) scope.submitDialog(items.mapNotNull { it.value })
} }
FullscreenDialog( ComposeDialog(
onDismissRequest = back, onDismissRequest = back,
properties = DialogProperties(
usePlatformDefaultWidth = false,
dismissOnBackPress = true
),
) { ) {
Scaffold( Scaffold(
topBar = { topBar = {

View File

@ -23,9 +23,10 @@ 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.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import app.revanced.manager.R import app.revanced.manager.R
import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.FullscreenDialog
import app.revanced.manager.ui.component.GroupHeader import app.revanced.manager.ui.component.GroupHeader
import app.revanced.manager.ui.component.LazyColumnWithScrollbar import app.revanced.manager.ui.component.LazyColumnWithScrollbar
import app.revanced.manager.util.saver.PathSaver import app.revanced.manager.util.saver.PathSaver
@ -47,8 +48,12 @@ fun PathSelectorDialog(root: Path, onSelect: (Path?) -> Unit) {
currentDirectory.listDirectoryEntries().filter(Path::isReadable).partition(Path::isDirectory) currentDirectory.listDirectoryEntries().filter(Path::isReadable).partition(Path::isDirectory)
} }
FullscreenDialog( Dialog(
onDismissRequest = { onSelect(null) }, onDismissRequest = { onSelect(null) },
properties = DialogProperties(
usePlatformDefaultWidth = false,
dismissOnBackPress = true
)
) { ) {
Scaffold( Scaffold(
topBar = { topBar = {

View File

@ -11,7 +11,6 @@ import kotlinx.coroutines.flow.map
*/ */
data class BundleInfo( data class BundleInfo(
val name: String, val name: String,
val version: String?,
val uid: Int, val uid: Int,
val compatible: List<PatchInfo>, val compatible: List<PatchInfo>,
val incompatible: List<PatchInfo>, val incompatible: List<PatchInfo>,
@ -79,7 +78,7 @@ data class BundleInfo(
targetList.add(it) targetList.add(it)
} }
BundleInfo(source.getName(), source.currentVersion(), source.uid, compatible, incompatible, universal) BundleInfo(source.getName(), source.uid, compatible, incompatible, universal)
} }
} }

View File

@ -21,7 +21,6 @@ import androidx.compose.material.icons.filled.BatteryAlert
import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.outlined.Apps import androidx.compose.material.icons.outlined.Apps
import androidx.compose.material.icons.outlined.BugReport import androidx.compose.material.icons.outlined.BugReport
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.DeleteOutline import androidx.compose.material.icons.outlined.DeleteOutline
import androidx.compose.material.icons.outlined.Download import androidx.compose.material.icons.outlined.Download
import androidx.compose.material.icons.outlined.Refresh import androidx.compose.material.icons.outlined.Refresh
@ -63,7 +62,6 @@ import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.AutoUpdatesDialog import app.revanced.manager.ui.component.AutoUpdatesDialog
import app.revanced.manager.ui.component.AvailableUpdateDialog import app.revanced.manager.ui.component.AvailableUpdateDialog
import app.revanced.manager.ui.component.NotificationCard import app.revanced.manager.ui.component.NotificationCard
import app.revanced.manager.ui.component.ConfirmDialog
import app.revanced.manager.ui.component.bundle.BundleTopBar import app.revanced.manager.ui.component.bundle.BundleTopBar
import app.revanced.manager.ui.component.bundle.ImportPatchBundleDialog import app.revanced.manager.ui.component.bundle.ImportPatchBundleDialog
import app.revanced.manager.ui.component.haptics.HapticFloatingActionButton import app.revanced.manager.ui.component.haptics.HapticFloatingActionButton
@ -156,20 +154,6 @@ fun DashboardScreen(
} }
) )
var showDeleteConfirmationDialog by rememberSaveable { mutableStateOf(false) }
if (showDeleteConfirmationDialog) {
ConfirmDialog(
onDismiss = { showDeleteConfirmationDialog = false },
onConfirm = {
vm.selectedSources.forEach { if (!it.isDefault) vm.delete(it) }
vm.cancelSourceSelection()
},
title = stringResource(R.string.bundle_delete_multiple_dialog_title),
description = stringResource(R.string.bundle_delete_multiple_dialog_description),
icon = Icons.Outlined.Delete
)
}
Scaffold( Scaffold(
topBar = { topBar = {
if (bundlesSelectable) { if (bundlesSelectable) {
@ -185,7 +169,8 @@ fun DashboardScreen(
actions = { actions = {
IconButton( IconButton(
onClick = { onClick = {
showDeleteConfirmationDialog = true vm.selectedSources.forEach { if (!it.isDefault) vm.delete(it) }
vm.cancelSourceSelection()
} }
) { ) {
Icon( Icon(

View File

@ -17,7 +17,6 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.OpenInNew import androidx.compose.material.icons.automirrored.outlined.OpenInNew
import androidx.compose.material.icons.outlined.Cancel
import androidx.compose.material.icons.outlined.FileDownload import androidx.compose.material.icons.outlined.FileDownload
import androidx.compose.material.icons.outlined.PostAdd import androidx.compose.material.icons.outlined.PostAdd
import androidx.compose.material.icons.outlined.Save import androidx.compose.material.icons.outlined.Save
@ -46,7 +45,6 @@ import app.revanced.manager.R
import app.revanced.manager.data.room.apps.installed.InstallType import app.revanced.manager.data.room.apps.installed.InstallType
import app.revanced.manager.ui.component.AppScaffold import app.revanced.manager.ui.component.AppScaffold
import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.ConfirmDialog
import app.revanced.manager.ui.component.InstallerStatusDialog import app.revanced.manager.ui.component.InstallerStatusDialog
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
import app.revanced.manager.ui.component.patcher.InstallPickerDialog import app.revanced.manager.ui.component.patcher.InstallPickerDialog
@ -60,23 +58,25 @@ import app.revanced.manager.util.EventEffect
@Composable @Composable
fun PatcherScreen( fun PatcherScreen(
onBackClick: () -> Unit, onBackClick: () -> Unit,
viewModel: PatcherViewModel vm: PatcherViewModel
) { ) {
fun leaveScreen() {
vm.onBack()
onBackClick()
}
BackHandler(onBack = ::leaveScreen)
val context = LocalContext.current val context = LocalContext.current
val exportApkLauncher = val exportApkLauncher =
rememberLauncherForActivityResult(CreateDocument(APK_MIMETYPE), viewModel::export) rememberLauncherForActivityResult(CreateDocument(APK_MIMETYPE), vm::export)
val patcherSucceeded by viewModel.patcherSucceeded.observeAsState(null) val patcherSucceeded by vm.patcherSucceeded.observeAsState(null)
val canInstall by remember { derivedStateOf { patcherSucceeded == true && (viewModel.installedPackageName != null || !viewModel.isInstalling) } } val canInstall by remember { derivedStateOf { patcherSucceeded == true && (vm.installedPackageName != null || !vm.isInstalling) } }
var showInstallPicker by rememberSaveable { mutableStateOf(false) } var showInstallPicker by rememberSaveable { mutableStateOf(false) }
var showDismissConfirmationDialog by rememberSaveable { mutableStateOf(false) }
BackHandler(onBack = { showDismissConfirmationDialog = true })
val steps by remember { val steps by remember {
derivedStateOf { derivedStateOf {
viewModel.steps.groupBy { it.category } vm.steps.groupBy { it.category }
} }
} }
@ -93,47 +93,34 @@ fun PatcherScreen(
if (showInstallPicker) if (showInstallPicker)
InstallPickerDialog( InstallPickerDialog(
onDismiss = { showInstallPicker = false }, onDismiss = { showInstallPicker = false },
onConfirm = viewModel::install onConfirm = vm::install
) )
if (showDismissConfirmationDialog) { vm.packageInstallerStatus?.let {
ConfirmDialog( InstallerStatusDialog(it, vm, vm::dismissPackageInstallerDialog)
onDismiss = { showDismissConfirmationDialog = false },
onConfirm = {
viewModel.onBack()
onBackClick()
},
title = stringResource(R.string.patcher_stop_confirm_title),
description = stringResource(R.string.patcher_stop_confirm_description),
icon = Icons.Outlined.Cancel
)
}
viewModel.packageInstallerStatus?.let {
InstallerStatusDialog(it, viewModel, viewModel::dismissPackageInstallerDialog)
} }
val activityLauncher = rememberLauncherForActivityResult( val activityLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult(), contract = ActivityResultContracts.StartActivityForResult(),
onResult = viewModel::handleActivityResult onResult = vm::handleActivityResult
) )
EventEffect(flow = viewModel.launchActivityFlow) { intent -> EventEffect(flow = vm.launchActivityFlow) { intent ->
activityLauncher.launch(intent) activityLauncher.launch(intent)
} }
viewModel.activityPromptDialog?.let { title -> vm.activityPromptDialog?.let { title ->
AlertDialog( AlertDialog(
onDismissRequest = viewModel::rejectInteraction, onDismissRequest = vm::rejectInteraction,
confirmButton = { confirmButton = {
TextButton( TextButton(
onClick = viewModel::allowInteraction onClick = vm::allowInteraction
) { ) {
Text(stringResource(R.string.continue_)) Text(stringResource(R.string.continue_))
} }
}, },
dismissButton = { dismissButton = {
TextButton( TextButton(
onClick = viewModel::rejectInteraction onClick = vm::rejectInteraction
) { ) {
Text(stringResource(R.string.cancel)) Text(stringResource(R.string.cancel))
} }
@ -150,20 +137,20 @@ fun PatcherScreen(
AppTopBar( AppTopBar(
title = stringResource(R.string.patcher), title = stringResource(R.string.patcher),
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
onBackClick = { showDismissConfirmationDialog = true } onBackClick = ::leaveScreen
) )
}, },
bottomBar = { bottomBar = {
BottomAppBar( BottomAppBar(
actions = { actions = {
IconButton( IconButton(
onClick = { exportApkLauncher.launch("${viewModel.packageName}_${viewModel.version}_revanced_patched.apk") }, onClick = { exportApkLauncher.launch("${vm.packageName}_${vm.version}_revanced_patched.apk") },
enabled = patcherSucceeded == true enabled = patcherSucceeded == true
) { ) {
Icon(Icons.Outlined.Save, stringResource(id = R.string.save_apk)) Icon(Icons.Outlined.Save, stringResource(id = R.string.save_apk))
} }
IconButton( IconButton(
onClick = { viewModel.exportLogs(context) }, onClick = { vm.exportLogs(context) },
enabled = patcherSucceeded != null enabled = patcherSucceeded != null
) { ) {
Icon(Icons.Outlined.PostAdd, stringResource(id = R.string.save_logs)) Icon(Icons.Outlined.PostAdd, stringResource(id = R.string.save_logs))
@ -174,11 +161,11 @@ fun PatcherScreen(
HapticExtendedFloatingActionButton( HapticExtendedFloatingActionButton(
text = { text = {
Text( Text(
stringResource(if (viewModel.installedPackageName == null) R.string.install_app else R.string.open_app) stringResource(if (vm.installedPackageName == null) R.string.install_app else R.string.open_app)
) )
}, },
icon = { icon = {
viewModel.installedPackageName?.let { vm.installedPackageName?.let {
Icon( Icon(
Icons.AutoMirrored.Outlined.OpenInNew, Icons.AutoMirrored.Outlined.OpenInNew,
stringResource(R.string.open_app) stringResource(R.string.open_app)
@ -189,10 +176,10 @@ fun PatcherScreen(
) )
}, },
onClick = { onClick = {
if (viewModel.installedPackageName == null) if (vm.installedPackageName == null)
if (viewModel.isDeviceRooted()) showInstallPicker = true if (vm.isDeviceRooted()) showInstallPicker = true
else viewModel.install(InstallType.DEFAULT) else vm.install(InstallType.DEFAULT)
else viewModel.open() else vm.open()
} }
) )
} }
@ -206,7 +193,7 @@ fun PatcherScreen(
.fillMaxSize() .fillMaxSize()
) { ) {
LinearProgressIndicator( LinearProgressIndicator(
progress = { viewModel.progress }, progress = { vm.progress },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
@ -222,8 +209,8 @@ fun PatcherScreen(
Steps( Steps(
category = category, category = category,
steps = steps, steps = steps,
stepCount = if (category == StepCategory.PATCHING) viewModel.patchesProgress else null, stepCount = if (category == StepCategory.PATCHING) vm.patchesProgress else null,
stepProgressProvider = viewModel stepProgressProvider = vm
) )
} }
} }

View File

@ -60,13 +60,14 @@ import androidx.compose.ui.draw.rotate
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import app.revanced.manager.R import app.revanced.manager.R
import app.revanced.manager.patcher.patch.Option import app.revanced.manager.patcher.patch.Option
import app.revanced.manager.patcher.patch.PatchInfo import app.revanced.manager.patcher.patch.PatchInfo
import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.CheckedFilterChip import app.revanced.manager.ui.component.CheckedFilterChip
import app.revanced.manager.ui.component.FullscreenDialog
import app.revanced.manager.ui.component.LazyColumnWithScrollbar import app.revanced.manager.ui.component.LazyColumnWithScrollbar
import app.revanced.manager.ui.component.SafeguardDialog import app.revanced.manager.ui.component.SafeguardDialog
import app.revanced.manager.ui.component.SearchBar import app.revanced.manager.ui.component.SearchBar
@ -368,22 +369,14 @@ fun PatchesSelectorScreen(
Icon(Icons.Outlined.Restore, stringResource(R.string.reset)) Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
} }
HapticExtendedFloatingActionButton( HapticExtendedFloatingActionButton(
text = { text = { Text(stringResource(R.string.save_with_count, selectedPatchCount)) },
Text(
stringResource(
R.string.save_with_count,
selectedPatchCount
)
)
},
icon = { icon = {
Icon( Icon(
imageVector = Icons.Outlined.Save, imageVector = Icons.Outlined.Save,
contentDescription = stringResource(R.string.save) contentDescription = stringResource(R.string.save)
) )
}, },
expanded = patchLazyListStates.getOrNull(pagerState.currentPage)?.isScrollingUp expanded = patchLazyListStates.getOrNull(pagerState.currentPage)?.isScrollingUp ?: true,
?: true,
onClick = { onClick = {
onSave(vm.getCustomSelection(), vm.getOptions()) onSave(vm.getCustomSelection(), vm.getOptions())
} }
@ -412,19 +405,7 @@ fun PatchesSelectorScreen(
) )
} }
}, },
text = { text = { Text(bundle.name) },
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(
text = bundle.name,
style = MaterialTheme.typography.bodyMedium
)
Text(
text = bundle.version!!,
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
},
selectedContentColor = MaterialTheme.colorScheme.primary, selectedContentColor = MaterialTheme.colorScheme.primary,
unselectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant unselectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant
) )
@ -637,7 +618,13 @@ private fun OptionsDialog(
reset: () -> Unit, reset: () -> Unit,
set: (String, Any?) -> Unit, set: (String, Any?) -> Unit,
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
) = FullscreenDialog(onDismissRequest = onDismissRequest) { ) = Dialog(
onDismissRequest = onDismissRequest,
properties = DialogProperties(
usePlatformDefaultWidth = false,
dismissOnBackPress = true
)
) {
Scaffold( Scaffold(
topBar = { topBar = {
AppTopBar( AppTopBar(

View File

@ -1,6 +1,5 @@
package app.revanced.manager.ui.screen package app.revanced.manager.ui.screen
import androidx.annotation.StringRes
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -8,79 +7,55 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.* import androidx.compose.material.icons.outlined.*
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import app.revanced.manager.R 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.AppTopBar
import app.revanced.manager.ui.component.ColumnWithScrollbar import app.revanced.manager.ui.component.ColumnWithScrollbar
import app.revanced.manager.ui.component.settings.SettingsListItem import app.revanced.manager.ui.component.settings.SettingsListItem
import app.revanced.manager.ui.model.navigation.Settings import app.revanced.manager.ui.model.navigation.Settings
import org.koin.compose.koinInject
private data class Section( private val settingsSections = listOf(
@StringRes val name: Int, Triple(
@StringRes val description: Int, R.string.general,
val image: ImageVector, R.string.general_description,
val destination: Settings.Destination, Icons.Outlined.Settings
) to Settings.General,
Triple(
R.string.updates,
R.string.updates_description,
Icons.Outlined.Update
) to Settings.Updates,
Triple(
R.string.downloads,
R.string.downloads_description,
Icons.Outlined.Download
) to Settings.Downloads,
Triple(
R.string.import_export,
R.string.import_export_description,
Icons.Outlined.SwapVert
) to Settings.ImportExport,
Triple(
R.string.advanced,
R.string.advanced_description,
Icons.Outlined.Tune
) to Settings.Advanced,
Triple(
R.string.developer_options,
R.string.developer_options_description,
Icons.Outlined.Code
) to Settings.Developer,
Triple(
R.string.about,
R.string.app_name,
Icons.Outlined.Info
) to Settings.About,
) )
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun SettingsScreen(onBackClick: () -> Unit, navigate: (Settings.Destination) -> Unit) { fun SettingsScreen(onBackClick: () -> Unit, navigate: (Settings.Destination) -> Unit) {
val prefs: PreferencesManager = koinInject()
val showDeveloperSettings by prefs.showDeveloperSettings.getAsState()
val settingsSections = remember(showDeveloperSettings) {
listOfNotNull(
Section(
R.string.general,
R.string.general_description,
Icons.Outlined.Settings,
Settings.General
),
Section(
R.string.updates,
R.string.updates_description,
Icons.Outlined.Update,
Settings.Updates
),
Section(
R.string.downloads,
R.string.downloads_description,
Icons.Outlined.Download,
Settings.Downloads
),
Section(
R.string.import_export,
R.string.import_export_description,
Icons.Outlined.SwapVert,
Settings.ImportExport
),
Section(
R.string.advanced,
R.string.advanced_description,
Icons.Outlined.Tune,
Settings.Advanced
),
Section(
R.string.about,
R.string.app_name,
Icons.Outlined.Info,
Settings.About
),
Section(
R.string.developer_options,
R.string.developer_options_description,
Icons.Outlined.Code,
Settings.Developer
).takeIf { showDeveloperSettings }
)
}
Scaffold( Scaffold(
topBar = { topBar = {
AppTopBar( AppTopBar(
@ -94,12 +69,12 @@ fun SettingsScreen(onBackClick: () -> Unit, navigate: (Settings.Destination) ->
.padding(paddingValues) .padding(paddingValues)
.fillMaxSize() .fillMaxSize()
) { ) {
settingsSections.forEach { (name, description, icon, destination) -> settingsSections.forEach { (titleDescIcon, destination) ->
SettingsListItem( SettingsListItem(
modifier = Modifier.clickable { navigate(destination) }, modifier = Modifier.clickable { navigate(destination) },
headlineContent = stringResource(name), headlineContent = stringResource(titleDescIcon.first),
supportingContent = stringResource(description), supportingContent = stringResource(titleDescIcon.second),
leadingContent = { Icon(icon, null) } leadingContent = { Icon(titleDescIcon.third, null) }
) )
} }
} }

View File

@ -23,26 +23,16 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember 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.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.hideFromAccessibility
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import app.revanced.manager.BuildConfig import app.revanced.manager.BuildConfig
import app.revanced.manager.R import app.revanced.manager.R
@ -52,7 +42,6 @@ import app.revanced.manager.ui.component.ColumnWithScrollbar
import app.revanced.manager.ui.component.settings.SettingsListItem import app.revanced.manager.ui.component.settings.SettingsListItem
import app.revanced.manager.ui.model.navigation.Settings import app.revanced.manager.ui.model.navigation.Settings
import app.revanced.manager.ui.viewmodel.AboutViewModel import app.revanced.manager.ui.viewmodel.AboutViewModel
import app.revanced.manager.ui.viewmodel.AboutViewModel.Companion.DEVELOPER_OPTIONS_TAPS
import app.revanced.manager.ui.viewmodel.AboutViewModel.Companion.getSocialIcon import app.revanced.manager.ui.viewmodel.AboutViewModel.Companion.getSocialIcon
import app.revanced.manager.util.openUrl import app.revanced.manager.util.openUrl
import app.revanced.manager.util.toast import app.revanced.manager.util.toast
@ -120,8 +109,7 @@ fun AboutSettingsScreen(
} }
val listItems = listOfNotNull( val listItems = listOfNotNull(
Triple( Triple(stringResource(R.string.submit_feedback),
stringResource(R.string.submit_feedback),
stringResource(R.string.submit_feedback_description), stringResource(R.string.submit_feedback_description),
third = { third = {
context.openUrl("https://github.com/ReVanced/revanced-manager/issues/new/choose") context.openUrl("https://github.com/ReVanced/revanced-manager/issues/new/choose")
@ -146,35 +134,6 @@ fun AboutSettingsScreen(
) )
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val snackbarHostState = remember { SnackbarHostState() }
val showDeveloperSettings by viewModel.showDeveloperSettings.getAsState()
var developerTaps by rememberSaveable { mutableIntStateOf(0) }
LaunchedEffect(developerTaps) {
if (developerTaps == 0) return@LaunchedEffect
if (showDeveloperSettings) {
snackbarHostState.showSnackbar(context.getString(R.string.developer_options_already_enabled))
developerTaps = 0
return@LaunchedEffect
}
val remaining = DEVELOPER_OPTIONS_TAPS - developerTaps
if (remaining > 0) {
snackbarHostState.showSnackbar(
context.getString(
R.string.developer_options_taps,
remaining
),
duration = SnackbarDuration.Long
)
} else if (remaining == 0) {
viewModel.showDeveloperSettings.update(true)
snackbarHostState.showSnackbar(context.getString(R.string.developer_options_enabled))
}
// Reset the counter
developerTaps = 0
}
Scaffold( Scaffold(
topBar = { topBar = {
@ -184,9 +143,6 @@ fun AboutSettingsScreen(
onBackClick = onBackClick onBackClick = onBackClick
) )
}, },
snackbarHost = {
SnackbarHost(hostState = snackbarHostState)
},
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
) { paddingValues -> ) { paddingValues ->
ColumnWithScrollbar( ColumnWithScrollbar(
@ -197,11 +153,9 @@ fun AboutSettingsScreen(
verticalArrangement = Arrangement.spacedBy(16.dp) verticalArrangement = Arrangement.spacedBy(16.dp)
) { ) {
Image( Image(
modifier = Modifier modifier = Modifier.padding(top = 16.dp),
.padding(top = 16.dp)
.clickable { developerTaps += 1 },
painter = icon, painter = icon,
contentDescription = stringResource(R.string.app_name) contentDescription = null
) )
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
@ -209,11 +163,7 @@ fun AboutSettingsScreen(
) { ) {
Text( Text(
stringResource(R.string.app_name), stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineSmall, style = MaterialTheme.typography.headlineSmall
modifier = Modifier.semantics {
// Icon already has this information for the purpose of being clickable.
hideFromAccessibility()
}
) )
Text( Text(
text = stringResource(R.string.version) + " " + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")", text = stringResource(R.string.version) + " " + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")",

View File

@ -12,14 +12,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import app.revanced.manager.R 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.AppTopBar
import app.revanced.manager.ui.component.GroupHeader import app.revanced.manager.ui.component.GroupHeader
import app.revanced.manager.ui.component.settings.BooleanItem
import app.revanced.manager.ui.component.settings.SettingsListItem import app.revanced.manager.ui.component.settings.SettingsListItem
import app.revanced.manager.ui.viewmodel.DeveloperOptionsViewModel import app.revanced.manager.ui.viewmodel.DeveloperOptionsViewModel
import org.koin.androidx.compose.koinViewModel import org.koin.androidx.compose.koinViewModel
import org.koin.compose.koinInject
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@ -28,7 +25,6 @@ fun DeveloperSettingsScreen(
vm: DeveloperOptionsViewModel = koinViewModel() vm: DeveloperOptionsViewModel = koinViewModel()
) { ) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val prefs: PreferencesManager = koinInject()
Scaffold( Scaffold(
topBar = { topBar = {
@ -41,13 +37,6 @@ fun DeveloperSettingsScreen(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
) { paddingValues -> ) { paddingValues ->
Column(modifier = Modifier.padding(paddingValues)) { Column(modifier = Modifier.padding(paddingValues)) {
GroupHeader(stringResource(R.string.manager))
BooleanItem(
preference = prefs.showDeveloperSettings,
headline = R.string.developer_options,
description = R.string.developer_options_description,
)
GroupHeader(stringResource(R.string.patch_bundles_section)) GroupHeader(stringResource(R.string.patch_bundles_section))
SettingsListItem( SettingsListItem(
headlineContent = stringResource(R.string.patch_bundles_force_download), headlineContent = stringResource(R.string.patch_bundles_force_download),

View File

@ -9,7 +9,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -44,7 +43,6 @@ import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.ExceptionViewerDialog import app.revanced.manager.ui.component.ExceptionViewerDialog
import app.revanced.manager.ui.component.GroupHeader import app.revanced.manager.ui.component.GroupHeader
import app.revanced.manager.ui.component.LazyColumnWithScrollbar import app.revanced.manager.ui.component.LazyColumnWithScrollbar
import app.revanced.manager.ui.component.ConfirmDialog
import app.revanced.manager.ui.component.haptics.HapticCheckbox import app.revanced.manager.ui.component.haptics.HapticCheckbox
import app.revanced.manager.ui.component.settings.SettingsListItem import app.revanced.manager.ui.component.settings.SettingsListItem
import app.revanced.manager.ui.viewmodel.DownloadsViewModel import app.revanced.manager.ui.viewmodel.DownloadsViewModel
@ -61,17 +59,6 @@ fun DownloadsSettingsScreen(
val downloadedApps by viewModel.downloadedApps.collectAsStateWithLifecycle(emptyList()) val downloadedApps by viewModel.downloadedApps.collectAsStateWithLifecycle(emptyList())
val pluginStates by viewModel.downloaderPluginStates.collectAsStateWithLifecycle() val pluginStates by viewModel.downloaderPluginStates.collectAsStateWithLifecycle()
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
var showDeleteConfirmationDialog by rememberSaveable { mutableStateOf(false) }
if (showDeleteConfirmationDialog) {
ConfirmDialog(
onDismiss = { showDeleteConfirmationDialog = false },
onConfirm = { viewModel.deleteApps() },
title = stringResource(R.string.downloader_plugin_delete_apps_title),
description = stringResource(R.string.downloader_plugin_delete_apps_description),
icon = Icons.Outlined.Delete
)
}
Scaffold( Scaffold(
topBar = { topBar = {
@ -81,7 +68,7 @@ fun DownloadsSettingsScreen(
onBackClick = onBackClick, onBackClick = onBackClick,
actions = { actions = {
if (viewModel.appSelection.isNotEmpty()) { if (viewModel.appSelection.isNotEmpty()) {
IconButton(onClick = { showDeleteConfirmationDialog = true }) { IconButton(onClick = { viewModel.deleteApps() }) {
Icon(Icons.Default.Delete, stringResource(R.string.delete)) Icon(Icons.Default.Delete, stringResource(R.string.delete))
} }
} }

View File

@ -8,7 +8,6 @@ import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import app.revanced.manager.data.platform.NetworkInfo import app.revanced.manager.data.platform.NetworkInfo
import app.revanced.manager.domain.manager.PreferencesManager
import app.revanced.manager.network.api.ReVancedAPI import app.revanced.manager.network.api.ReVancedAPI
import app.revanced.manager.network.dto.ReVancedDonationLink import app.revanced.manager.network.dto.ReVancedDonationLink
import app.revanced.manager.network.dto.ReVancedSocial import app.revanced.manager.network.dto.ReVancedSocial
@ -28,7 +27,6 @@ import kotlinx.coroutines.withContext
class AboutViewModel( class AboutViewModel(
private val reVancedAPI: ReVancedAPI, private val reVancedAPI: ReVancedAPI,
private val network: NetworkInfo, private val network: NetworkInfo,
prefs: PreferencesManager,
) : ViewModel() { ) : ViewModel() {
var socials by mutableStateOf(emptyList<ReVancedSocial>()) var socials by mutableStateOf(emptyList<ReVancedSocial>())
private set private set
@ -39,8 +37,6 @@ class AboutViewModel(
val isConnected: Boolean val isConnected: Boolean
get() = network.isConnected() get() = network.isConnected()
val showDeveloperSettings = prefs.showDeveloperSettings
init { init {
viewModelScope.launch { viewModelScope.launch {
if (!isConnected) { if (!isConnected) {
@ -57,8 +53,6 @@ class AboutViewModel(
} }
companion object { companion object {
const val DEVELOPER_OPTIONS_TAPS = 5
private val socialIcons = mapOf( private val socialIcons = mapOf(
"Discord" to FontAwesomeIcons.Brands.Discord, "Discord" to FontAwesomeIcons.Brands.Discord,
"GitHub" to FontAwesomeIcons.Brands.Github, "GitHub" to FontAwesomeIcons.Brands.Github,

View File

@ -143,8 +143,6 @@
<string name="downloader_plugin_trust_dialog_title">Trust plugin?</string> <string name="downloader_plugin_trust_dialog_title">Trust plugin?</string>
<string name="downloader_plugin_revoke_trust_dialog_title">Revoke trust?</string> <string name="downloader_plugin_revoke_trust_dialog_title">Revoke trust?</string>
<string name="downloader_plugin_trust_dialog_body">Package name: %1$s\nSignature (SHA-256): %2$s</string> <string name="downloader_plugin_trust_dialog_body">Package name: %1$s\nSignature (SHA-256): %2$s</string>
<string name="downloader_plugin_delete_apps_title">Delete selected apps</string>
<string name="downloader_plugin_delete_apps_description">Are you sure you want to delete the selected apps?</string>
<string name="downloader_settings_no_apps">No downloaded apps found</string> <string name="downloader_settings_no_apps">No downloaded apps found</string>
<string name="search_apps">Search apps…</string> <string name="search_apps">Search apps…</string>
@ -303,8 +301,6 @@
<string name="patcher_step_write_patched">Write patched APK file</string> <string name="patcher_step_write_patched">Write patched APK file</string>
<string name="patcher_step_sign_apk">Sign patched APK file</string> <string name="patcher_step_sign_apk">Sign patched APK file</string>
<string name="patcher_notification_message">Patching in progress…</string> <string name="patcher_notification_message">Patching in progress…</string>
<string name="patcher_stop_confirm_title">Stop patcher</string>
<string name="patcher_stop_confirm_description">Are you sure you want to stop the patching process?</string>
<string name="execute_patches">Execute patches</string> <string name="execute_patches">Execute patches</string>
<string name="executing_patch">Execute %s</string> <string name="executing_patch">Execute %s</string>
<string name="failed_to_execute_patch">Failed to execute %s</string> <string name="failed_to_execute_patch">Failed to execute %s</string>
@ -340,17 +336,9 @@
<string name="bundle_view_patches">View patches</string> <string name="bundle_view_patches">View patches</string>
<string name="bundle_view_patches_any_version">Any version</string> <string name="bundle_view_patches_any_version">Any version</string>
<string name="bundle_view_patches_any_package">Any package</string> <string name="bundle_view_patches_any_package">Any package</string>
<string name="bundle_delete_single_dialog_title">Delete bundle</string>
<string name="bundle_delete_multiple_dialog_title">Delete bundles</string>
<string name="bundle_delete_single_dialog_description">Are you sure you want to delete the bundle \"%s\"?</string>
<string name="bundle_delete_multiple_dialog_description">Are you sure you want to delete the selected bundles?</string>
<string name="about_revanced_manager">About ReVanced Manager</string> <string name="about_revanced_manager">About ReVanced Manager</string>
<string name="revanced_manager_description">ReVanced Manager is an application designed to work with ReVanced Patcher, which allows for long-lasting patches to be created for Android apps. The patching system is designed to automatically work with new versions of apps with minimal maintenance.</string> <string name="revanced_manager_description">ReVanced Manager is an application designed to work with ReVanced Patcher, which allows for long-lasting patches to be created for Android apps. The patching system is designed to automatically work with new versions of apps with minimal maintenance.</string>
<string name="developer_options_taps">%d taps remaining</string>
<string name="developer_options_enabled">Developer options enabled</string>
<string name="developer_options_already_enabled">Developer options are already enabled</string>
<string name="update_available">An update is available</string> <string name="update_available">An update is available</string>
<string name="current_version">Current version: %s</string> <string name="current_version">Current version: %s</string>
<string name="new_version">New version: %s</string> <string name="new_version">New version: %s</string>
@ -437,5 +425,4 @@
<string name="show_manager_update_dialog_on_launch_description">Shows a popup notification whenever there is a new update available on launch.</string> <string name="show_manager_update_dialog_on_launch_description">Shows a popup notification whenever there is a new update available on launch.</string>
<string name="failed_to_import_keystore">Failed to import keystore</string> <string name="failed_to_import_keystore">Failed to import keystore</string>
<string name="export">Export</string> <string name="export">Export</string>
<string name="confirm">Confirm</string>
</resources> </resources>

View File

@ -1,22 +1,22 @@
[versions] [versions]
ktx = "1.16.0" ktx = "1.15.0"
material3 = "1.3.2" material3 = "1.3.1"
ui-tooling = "1.8.1" ui-tooling = "1.7.7"
viewmodel-lifecycle = "2.9.0" viewmodel-lifecycle = "2.8.7"
splash-screen = "1.0.1" splash-screen = "1.0.1"
activity = "1.10.1" activity = "1.10.0"
appcompat = "1.7.0" appcompat = "1.7.0"
preferences-datastore = "1.1.2" preferences-datastore = "1.1.2"
work-runtime = "2.10.1" work-runtime = "2.10.0"
compose-bom = "2025.05.00" compose-bom = "2025.01.01"
navigation = "2.9.0" navigation = "2.8.6"
accompanist = "0.37.0" accompanist = "0.37.0"
placeholder = "1.1.2" placeholder = "1.1.2"
reorderable = "2.4.3" reorderable = "2.4.3"
serialization = "1.8.0" serialization = "1.8.0"
collection = "0.3.8" collection = "0.3.8"
datetime = "0.6.1" datetime = "0.6.1"
room-version = "2.7.1" room-version = "2.6.1"
revanced-patcher = "21.0.0" revanced-patcher = "21.0.0"
revanced-library = "3.0.2" revanced-library = "3.0.2"
plugin-api = "1.0.0" plugin-api = "1.0.0"
@ -25,7 +25,7 @@ ktor = "2.3.9"
markdown-renderer = "0.30.0" markdown-renderer = "0.30.0"
fading-edges = "1.0.4" fading-edges = "1.0.4"
kotlin = "2.1.10" kotlin = "2.1.10"
android-gradle-plugin = "8.9.1" android-gradle-plugin = "8.8.0"
dev-tools-gradle-plugin = "2.1.10-1.0.29" dev-tools-gradle-plugin = "2.1.10-1.0.29"
about-libraries-gradle-plugin = "11.5.0" about-libraries-gradle-plugin = "11.5.0"
coil = "2.7.0" coil = "2.7.0"