mirror of
https://github.com/revanced/revanced-manager
synced 2024-05-14 13:56:57 +02:00
refactor: fix terminology and wording related to patches (#1623)
This commit is contained in:
parent
36c8f59d6f
commit
c0f3d02e6f
@ -107,11 +107,11 @@ class MainActivity : ComponentActivity() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
is Destination.InstalledApplicationInfo -> InstalledAppInfoScreen(
|
is Destination.InstalledApplicationInfo -> InstalledAppInfoScreen(
|
||||||
onPatchClick = { packageName, patchesSelection ->
|
onPatchClick = { packageName, patchSelection ->
|
||||||
navController.navigate(
|
navController.navigate(
|
||||||
Destination.VersionSelector(
|
Destination.VersionSelector(
|
||||||
packageName,
|
packageName,
|
||||||
patchesSelection
|
patchSelection
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -142,14 +142,14 @@ class MainActivity : ComponentActivity() {
|
|||||||
navController.navigate(
|
navController.navigate(
|
||||||
Destination.SelectedApplicationInfo(
|
Destination.SelectedApplicationInfo(
|
||||||
selectedApp,
|
selectedApp,
|
||||||
destination.patchesSelection,
|
destination.patchSelection,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
viewModel = getComposeViewModel {
|
viewModel = getComposeViewModel {
|
||||||
parametersOf(
|
parametersOf(
|
||||||
destination.packageName,
|
destination.packageName,
|
||||||
destination.patchesSelection
|
destination.patchSelection
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -167,7 +167,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
parametersOf(
|
parametersOf(
|
||||||
SelectedAppInfoViewModel.Params(
|
SelectedAppInfoViewModel.Params(
|
||||||
destination.selectedApp,
|
destination.selectedApp,
|
||||||
destination.patchesSelection
|
destination.patchSelection
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import app.revanced.manager.data.room.AppDatabase
|
|||||||
import app.revanced.manager.data.room.apps.installed.AppliedPatch
|
import app.revanced.manager.data.room.apps.installed.AppliedPatch
|
||||||
import app.revanced.manager.data.room.apps.installed.InstallType
|
import app.revanced.manager.data.room.apps.installed.InstallType
|
||||||
import app.revanced.manager.data.room.apps.installed.InstalledApp
|
import app.revanced.manager.data.room.apps.installed.InstalledApp
|
||||||
import app.revanced.manager.util.PatchesSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
|
|
||||||
class InstalledAppRepository(
|
class InstalledAppRepository(
|
||||||
@ -16,7 +16,7 @@ class InstalledAppRepository(
|
|||||||
|
|
||||||
suspend fun get(packageName: String) = dao.get(packageName)
|
suspend fun get(packageName: String) = dao.get(packageName)
|
||||||
|
|
||||||
suspend fun getAppliedPatches(packageName: String): PatchesSelection =
|
suspend fun getAppliedPatches(packageName: String): PatchSelection =
|
||||||
dao.getPatchesSelection(packageName).mapValues { (_, patches) -> patches.toSet() }
|
dao.getPatchesSelection(packageName).mapValues { (_, patches) -> patches.toSet() }
|
||||||
|
|
||||||
suspend fun addOrUpdate(
|
suspend fun addOrUpdate(
|
||||||
@ -24,7 +24,7 @@ class InstalledAppRepository(
|
|||||||
originalPackageName: String,
|
originalPackageName: String,
|
||||||
version: String,
|
version: String,
|
||||||
installType: InstallType,
|
installType: InstallType,
|
||||||
patchesSelection: PatchesSelection
|
patchSelection: PatchSelection
|
||||||
) {
|
) {
|
||||||
dao.upsertApp(
|
dao.upsertApp(
|
||||||
InstalledApp(
|
InstalledApp(
|
||||||
@ -33,7 +33,7 @@ class InstalledAppRepository(
|
|||||||
version = version,
|
version = version,
|
||||||
installType = installType
|
installType = installType
|
||||||
),
|
),
|
||||||
patchesSelection.flatMap { (uid, patches) ->
|
patchSelection.flatMap { (uid, patches) ->
|
||||||
patches.map { patch ->
|
patches.map { patch ->
|
||||||
AppliedPatch(
|
AppliedPatch(
|
||||||
packageName = currentPackageName,
|
packageName = currentPackageName,
|
||||||
|
@ -33,7 +33,7 @@ import app.revanced.manager.ui.model.SelectedApp
|
|||||||
import app.revanced.manager.ui.model.State
|
import app.revanced.manager.ui.model.State
|
||||||
import app.revanced.manager.util.Options
|
import app.revanced.manager.util.Options
|
||||||
import app.revanced.manager.util.PM
|
import app.revanced.manager.util.PM
|
||||||
import app.revanced.manager.util.PatchesSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
import app.revanced.manager.util.tag
|
import app.revanced.manager.util.tag
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
@ -59,7 +59,7 @@ class PatcherWorker(
|
|||||||
data class Args(
|
data class Args(
|
||||||
val input: SelectedApp,
|
val input: SelectedApp,
|
||||||
val output: String,
|
val output: String,
|
||||||
val selectedPatches: PatchesSelection,
|
val selectedPatches: PatchSelection,
|
||||||
val options: Options,
|
val options: Options,
|
||||||
val logger: ManagerLogger,
|
val logger: ManagerLogger,
|
||||||
val downloadProgress: MutableStateFlow<Pair<Float, Float>?>,
|
val downloadProgress: MutableStateFlow<Pair<Float, Float>?>,
|
||||||
|
@ -89,7 +89,7 @@ fun BundleItem(
|
|||||||
supportingContent = {
|
supportingContent = {
|
||||||
state.patchBundleOrNull()?.patches?.size?.let { patchCount ->
|
state.patchBundleOrNull()?.patches?.size?.let { patchCount ->
|
||||||
Text(
|
Text(
|
||||||
text = pluralStringResource(R.plurals.patches_count, patchCount, patchCount),
|
text = pluralStringResource(R.plurals.patch_count, patchCount, patchCount),
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
)
|
)
|
||||||
|
@ -4,7 +4,7 @@ import android.os.Parcelable
|
|||||||
import app.revanced.manager.data.room.apps.installed.InstalledApp
|
import app.revanced.manager.data.room.apps.installed.InstalledApp
|
||||||
import app.revanced.manager.ui.model.SelectedApp
|
import app.revanced.manager.ui.model.SelectedApp
|
||||||
import app.revanced.manager.util.Options
|
import app.revanced.manager.util.Options
|
||||||
import app.revanced.manager.util.PatchesSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import kotlinx.parcelize.RawValue
|
import kotlinx.parcelize.RawValue
|
||||||
|
|
||||||
@ -23,12 +23,12 @@ sealed interface Destination : Parcelable {
|
|||||||
data class Settings(val startDestination: SettingsDestination = SettingsDestination.Settings) : Destination
|
data class Settings(val startDestination: SettingsDestination = SettingsDestination.Settings) : Destination
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class VersionSelector(val packageName: String, val patchesSelection: PatchesSelection? = null) : Destination
|
data class VersionSelector(val packageName: String, val patchSelection: PatchSelection? = null) : Destination
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class SelectedApplicationInfo(val selectedApp: SelectedApp, val patchesSelection: PatchesSelection? = null) : Destination
|
data class SelectedApplicationInfo(val selectedApp: SelectedApp, val patchSelection: PatchSelection? = null) : Destination
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class Patcher(val selectedApp: SelectedApp, val selectedPatches: PatchesSelection, val options: @RawValue Options) : Destination
|
data class Patcher(val selectedApp: SelectedApp, val selectedPatches: PatchSelection, val options: @RawValue Options) : Destination
|
||||||
|
|
||||||
}
|
}
|
@ -3,7 +3,7 @@ package app.revanced.manager.ui.destination
|
|||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import app.revanced.manager.ui.model.SelectedApp
|
import app.revanced.manager.ui.model.SelectedApp
|
||||||
import app.revanced.manager.util.Options
|
import app.revanced.manager.util.Options
|
||||||
import app.revanced.manager.util.PatchesSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import kotlinx.parcelize.RawValue
|
import kotlinx.parcelize.RawValue
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ sealed interface SelectedAppInfoDestination : Parcelable {
|
|||||||
data object Main : SelectedAppInfoDestination
|
data object Main : SelectedAppInfoDestination
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class PatchesSelector(val app: SelectedApp, val currentSelection: PatchesSelection?, val options: @RawValue Options) : SelectedAppInfoDestination
|
data class PatchesSelector(val app: SelectedApp, val currentSelection: PatchSelection?, val options: @RawValue Options) : SelectedAppInfoDestination
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data object VersionSelector: SelectedAppInfoDestination
|
data object VersionSelector: SelectedAppInfoDestination
|
||||||
|
@ -2,7 +2,7 @@ package app.revanced.manager.ui.model
|
|||||||
|
|
||||||
import app.revanced.manager.domain.repository.PatchBundleRepository
|
import app.revanced.manager.domain.repository.PatchBundleRepository
|
||||||
import app.revanced.manager.patcher.patch.PatchInfo
|
import app.revanced.manager.patcher.patch.PatchInfo
|
||||||
import app.revanced.manager.util.PatchesSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
import app.revanced.manager.util.flatMapLatestAndCombine
|
import app.revanced.manager.util.flatMapLatestAndCombine
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ data class BundleInfo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object Extensions {
|
companion object Extensions {
|
||||||
inline fun Iterable<BundleInfo>.toPatchSelection(allowUnsupported: Boolean, condition: (Int, PatchInfo) -> Boolean): PatchesSelection = this.associate { bundle ->
|
inline fun Iterable<BundleInfo>.toPatchSelection(allowUnsupported: Boolean, condition: (Int, PatchInfo) -> Boolean): PatchSelection = this.associate { bundle ->
|
||||||
val patches =
|
val patches =
|
||||||
bundle.patchSequence(allowUnsupported)
|
bundle.patchSequence(allowUnsupported)
|
||||||
.mapNotNullTo(mutableSetOf()) { patch ->
|
.mapNotNullTo(mutableSetOf()) { patch ->
|
||||||
|
@ -111,7 +111,7 @@ fun AppSelectorScreen(
|
|||||||
{
|
{
|
||||||
Text(
|
Text(
|
||||||
pluralStringResource(
|
pluralStringResource(
|
||||||
R.plurals.patches_count,
|
R.plurals.patch_count,
|
||||||
it,
|
it,
|
||||||
it
|
it
|
||||||
)
|
)
|
||||||
@ -199,7 +199,7 @@ fun AppSelectorScreen(
|
|||||||
{
|
{
|
||||||
Text(
|
Text(
|
||||||
pluralStringResource(
|
pluralStringResource(
|
||||||
R.plurals.patches_count,
|
R.plurals.patch_count,
|
||||||
it,
|
it,
|
||||||
it
|
it
|
||||||
)
|
)
|
||||||
|
@ -29,6 +29,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.pluralStringResource
|
import androidx.compose.ui.res.pluralStringResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@ -40,15 +41,18 @@ import app.revanced.manager.ui.component.ColumnWithScrollbar
|
|||||||
import app.revanced.manager.ui.component.SegmentedButton
|
import app.revanced.manager.ui.component.SegmentedButton
|
||||||
import app.revanced.manager.ui.component.settings.SettingsListItem
|
import app.revanced.manager.ui.component.settings.SettingsListItem
|
||||||
import app.revanced.manager.ui.viewmodel.InstalledAppInfoViewModel
|
import app.revanced.manager.ui.viewmodel.InstalledAppInfoViewModel
|
||||||
import app.revanced.manager.util.PatchesSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
|
import app.revanced.manager.util.toast
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun InstalledAppInfoScreen(
|
fun InstalledAppInfoScreen(
|
||||||
onPatchClick: (packageName: String, patchesSelection: PatchesSelection) -> Unit,
|
onPatchClick: (packageName: String, patchSelection: PatchSelection) -> Unit,
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
viewModel: InstalledAppInfoViewModel
|
viewModel: InstalledAppInfoViewModel
|
||||||
) {
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
SideEffect {
|
SideEffect {
|
||||||
viewModel.onBackClick = onBackClick
|
viewModel.onBackClick = onBackClick
|
||||||
}
|
}
|
||||||
@ -142,12 +146,12 @@ fun InstalledAppInfoScreen(
|
|||||||
modifier = Modifier.padding(vertical = 16.dp)
|
modifier = Modifier.padding(vertical = 16.dp)
|
||||||
) {
|
) {
|
||||||
SettingsListItem(
|
SettingsListItem(
|
||||||
modifier = Modifier.clickable { },
|
modifier = Modifier.clickable { context.toast("Not implemented yet!") },
|
||||||
headlineContent = stringResource(R.string.applied_patches),
|
headlineContent = stringResource(R.string.applied_patches),
|
||||||
supportingContent =
|
supportingContent =
|
||||||
(viewModel.appliedPatches?.values?.sumOf { it.size } ?: 0).let {
|
(viewModel.appliedPatches?.values?.sumOf { it.size } ?: 0).let {
|
||||||
pluralStringResource(
|
pluralStringResource(
|
||||||
id = R.plurals.applied_patches,
|
id = R.plurals.patch_count,
|
||||||
it,
|
it,
|
||||||
it
|
it
|
||||||
)
|
)
|
||||||
|
@ -68,14 +68,14 @@ import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW
|
|||||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNIVERSAL
|
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNIVERSAL
|
||||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNSUPPORTED
|
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNSUPPORTED
|
||||||
import app.revanced.manager.util.Options
|
import app.revanced.manager.util.Options
|
||||||
import app.revanced.manager.util.PatchesSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.compose.rememberKoinInject
|
import org.koin.compose.rememberKoinInject
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun PatchesSelectorScreen(
|
fun PatchesSelectorScreen(
|
||||||
onSave: (PatchesSelection?, Options) -> Unit,
|
onSave: (PatchSelection?, Options) -> Unit,
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
vm: PatchesSelectorViewModel
|
vm: PatchesSelectorViewModel
|
||||||
) {
|
) {
|
||||||
@ -105,13 +105,13 @@ fun PatchesSelectorScreen(
|
|||||||
modifier = Modifier.padding(horizontal = 24.dp)
|
modifier = Modifier.padding(horizontal = 24.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.patches_selector_sheet_filter_title),
|
text = stringResource(R.string.patch_selector_sheet_filter_title),
|
||||||
style = MaterialTheme.typography.headlineSmall,
|
style = MaterialTheme.typography.headlineSmall,
|
||||||
modifier = Modifier.padding(bottom = 16.dp)
|
modifier = Modifier.padding(bottom = 16.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.patches_selector_sheet_filter_compat_title),
|
text = stringResource(R.string.patch_selector_sheet_filter_compat_title),
|
||||||
style = MaterialTheme.typography.titleMedium
|
style = MaterialTheme.typography.titleMedium
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ import app.revanced.manager.ui.model.SelectedApp
|
|||||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel
|
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel
|
||||||
import app.revanced.manager.ui.viewmodel.SelectedAppInfoViewModel
|
import app.revanced.manager.ui.viewmodel.SelectedAppInfoViewModel
|
||||||
import app.revanced.manager.util.Options
|
import app.revanced.manager.util.Options
|
||||||
import app.revanced.manager.util.PatchesSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
import app.revanced.manager.util.toast
|
import app.revanced.manager.util.toast
|
||||||
import dev.olshevski.navigation.reimagined.AnimatedNavHost
|
import dev.olshevski.navigation.reimagined.AnimatedNavHost
|
||||||
import dev.olshevski.navigation.reimagined.NavBackHandler
|
import dev.olshevski.navigation.reimagined.NavBackHandler
|
||||||
@ -44,7 +44,7 @@ import org.koin.core.parameter.parametersOf
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SelectedAppInfoScreen(
|
fun SelectedAppInfoScreen(
|
||||||
onPatchClick: (SelectedApp, PatchesSelection, Options) -> Unit,
|
onPatchClick: (SelectedApp, PatchSelection, Options) -> Unit,
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
vm: SelectedAppInfoViewModel
|
vm: SelectedAppInfoViewModel
|
||||||
) {
|
) {
|
||||||
|
@ -159,7 +159,7 @@ fun SelectedAppItem(
|
|||||||
else -> null
|
else -> null
|
||||||
},
|
},
|
||||||
trailingContent = patchCount?.let { {
|
trailingContent = patchCount?.let { {
|
||||||
Text(pluralStringResource(R.plurals.patches_count, it, it))
|
Text(pluralStringResource(R.plurals.patch_count, it, it))
|
||||||
} },
|
} },
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clickable(enabled = !alreadyPatched && enabled, onClick = onClick)
|
.clickable(enabled = !alreadyPatched && enabled, onClick = onClick)
|
||||||
|
@ -131,22 +131,22 @@ fun ImportExportSettingsScreen(
|
|||||||
description = R.string.regenerate_keystore_description
|
description = R.string.regenerate_keystore_description
|
||||||
)
|
)
|
||||||
|
|
||||||
GroupHeader(stringResource(R.string.patches_selection))
|
GroupHeader(stringResource(R.string.patches))
|
||||||
GroupItem(
|
GroupItem(
|
||||||
onClick = vm::importSelection,
|
onClick = vm::importSelection,
|
||||||
headline = R.string.restore_patches_selection,
|
headline = R.string.import_patch_selection,
|
||||||
description = R.string.restore_patches_selection_description
|
description = R.string.import_patch_selection_description
|
||||||
)
|
)
|
||||||
GroupItem(
|
GroupItem(
|
||||||
onClick = vm::exportSelection,
|
onClick = vm::exportSelection,
|
||||||
headline = R.string.backup_patches_selection,
|
headline = R.string.export_patch_selection,
|
||||||
description = R.string.backup_patches_selection_description
|
description = R.string.export_patch_selection_description
|
||||||
)
|
)
|
||||||
// TODO: allow resetting selection for specific bundle or package name.
|
// TODO: allow resetting selection for specific bundle or package name.
|
||||||
GroupItem(
|
GroupItem(
|
||||||
onClick = vm::resetSelection,
|
onClick = vm::resetSelection,
|
||||||
headline = R.string.clear_patches_selection,
|
headline = R.string.reset_patch_selection,
|
||||||
description = R.string.clear_patches_selection_description
|
description = R.string.reset_patch_selection_description
|
||||||
)
|
)
|
||||||
|
|
||||||
var showPackageSelector by rememberSaveable {
|
var showPackageSelector by rememberSaveable {
|
||||||
@ -158,7 +158,7 @@ fun ImportExportSettingsScreen(
|
|||||||
|
|
||||||
if (showPackageSelector)
|
if (showPackageSelector)
|
||||||
PackageSelector(packages = packagesWithOptions) { selected ->
|
PackageSelector(packages = packagesWithOptions) { selected ->
|
||||||
selected?.let(vm::clearOptionsForPackage)
|
selected?.let(vm::resetOptionsForPackage)
|
||||||
|
|
||||||
showPackageSelector = false
|
showPackageSelector = false
|
||||||
}
|
}
|
||||||
@ -170,23 +170,22 @@ fun ImportExportSettingsScreen(
|
|||||||
showBundleSelector = false
|
showBundleSelector = false
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupHeader(stringResource(R.string.patch_options))
|
|
||||||
// TODO: patch options import/export.
|
// TODO: patch options import/export.
|
||||||
|
GroupItem(
|
||||||
|
onClick = vm::resetOptions,
|
||||||
|
headline = R.string.patch_options_reset_all,
|
||||||
|
description = R.string.patch_options_reset_all_description,
|
||||||
|
)
|
||||||
GroupItem(
|
GroupItem(
|
||||||
onClick = { showPackageSelector = true },
|
onClick = { showPackageSelector = true },
|
||||||
headline = R.string.patch_options_clear_package,
|
headline = R.string.patch_options_reset_package,
|
||||||
description = R.string.patch_options_clear_package_description
|
description = R.string.patch_options_reset_package_description
|
||||||
)
|
)
|
||||||
if (patchBundles.size > 1)
|
if (patchBundles.size > 1)
|
||||||
GroupItem(
|
GroupItem(
|
||||||
onClick = { showBundleSelector = true },
|
onClick = { showBundleSelector = true },
|
||||||
headline = R.string.patch_options_clear_bundle,
|
headline = R.string.patch_options_reset_bundle,
|
||||||
description = R.string.patch_options_clear_bundle_description,
|
description = R.string.patch_options_reset_bundle_description,
|
||||||
)
|
|
||||||
GroupItem(
|
|
||||||
onClick = vm::resetOptions,
|
|
||||||
headline = R.string.patch_options_clear_all,
|
|
||||||
description = R.string.patch_options_clear_all_description,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ class ImportExportViewModel(
|
|||||||
|
|
||||||
val packagesWithOptions = optionsRepository.getPackagesWithSavedOptions()
|
val packagesWithOptions = optionsRepository.getPackagesWithSavedOptions()
|
||||||
|
|
||||||
fun clearOptionsForPackage(packageName: String) = viewModelScope.launch {
|
fun resetOptionsForPackage(packageName: String) = viewModelScope.launch {
|
||||||
optionsRepository.clearOptionsForPackage(packageName)
|
optionsRepository.clearOptionsForPackage(packageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,8 +163,8 @@ class ImportExportViewModel(
|
|||||||
override val activityArg = JSON_MIMETYPE
|
override val activityArg = JSON_MIMETYPE
|
||||||
override suspend fun execute(bundleUid: Int, location: Uri) = uiSafe(
|
override suspend fun execute(bundleUid: Int, location: Uri) = uiSafe(
|
||||||
app,
|
app,
|
||||||
R.string.restore_patches_selection_fail,
|
R.string.import_patch_selection_fail,
|
||||||
"Failed to restore patches selection"
|
"Failed to restore patch selection"
|
||||||
) {
|
) {
|
||||||
val selection = withContext(Dispatchers.IO) {
|
val selection = withContext(Dispatchers.IO) {
|
||||||
contentResolver.openInputStream(location)!!.use {
|
contentResolver.openInputStream(location)!!.use {
|
||||||
@ -181,8 +181,8 @@ class ImportExportViewModel(
|
|||||||
override val activityArg = "selection.json"
|
override val activityArg = "selection.json"
|
||||||
override suspend fun execute(bundleUid: Int, location: Uri) = uiSafe(
|
override suspend fun execute(bundleUid: Int, location: Uri) = uiSafe(
|
||||||
app,
|
app,
|
||||||
R.string.backup_patches_selection_fail,
|
R.string.export_patch_selection_fail,
|
||||||
"Failed to backup patches selection"
|
"Failed to backup patch selection"
|
||||||
) {
|
) {
|
||||||
val selection = selectionRepository.export(bundleUid)
|
val selection = selectionRepository.export(bundleUid)
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import app.revanced.manager.domain.installer.RootInstaller
|
|||||||
import app.revanced.manager.domain.repository.InstalledAppRepository
|
import app.revanced.manager.domain.repository.InstalledAppRepository
|
||||||
import app.revanced.manager.service.UninstallService
|
import app.revanced.manager.service.UninstallService
|
||||||
import app.revanced.manager.util.PM
|
import app.revanced.manager.util.PM
|
||||||
import app.revanced.manager.util.PatchesSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
import app.revanced.manager.util.simpleMessage
|
import app.revanced.manager.util.simpleMessage
|
||||||
import app.revanced.manager.util.tag
|
import app.revanced.manager.util.tag
|
||||||
import app.revanced.manager.util.toast
|
import app.revanced.manager.util.toast
|
||||||
@ -43,7 +43,7 @@ class InstalledAppInfoViewModel(
|
|||||||
|
|
||||||
var appInfo: PackageInfo? by mutableStateOf(null)
|
var appInfo: PackageInfo? by mutableStateOf(null)
|
||||||
private set
|
private set
|
||||||
var appliedPatches: PatchesSelection? by mutableStateOf(null)
|
var appliedPatches: PatchSelection? by mutableStateOf(null)
|
||||||
var isMounted by mutableStateOf(rootInstaller.isAppMounted(installedApp.currentPackageName))
|
var isMounted by mutableStateOf(rootInstaller.isAppMounted(installedApp.currentPackageName))
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import app.revanced.manager.ui.model.BundleInfo.Extensions.bundleInfoFlow
|
|||||||
import app.revanced.manager.ui.model.BundleInfo.Extensions.toPatchSelection
|
import app.revanced.manager.ui.model.BundleInfo.Extensions.toPatchSelection
|
||||||
import app.revanced.manager.ui.model.SelectedApp
|
import app.revanced.manager.ui.model.SelectedApp
|
||||||
import app.revanced.manager.util.Options
|
import app.revanced.manager.util.Options
|
||||||
import app.revanced.manager.util.PatchesSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
import app.revanced.manager.util.saver.Nullable
|
import app.revanced.manager.util.saver.Nullable
|
||||||
import app.revanced.manager.util.saver.nullableSaver
|
import app.revanced.manager.util.saver.nullableSaver
|
||||||
import app.revanced.manager.util.saver.persistentMapSaver
|
import app.revanced.manager.util.saver.persistentMapSaver
|
||||||
@ -36,7 +36,6 @@ import kotlinx.coroutines.launch
|
|||||||
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 kotlinx.collections.immutable.*
|
import kotlinx.collections.immutable.*
|
||||||
import java.util.Optional
|
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
@OptIn(SavedStateHandleSaveableApi::class)
|
@OptIn(SavedStateHandleSaveableApi::class)
|
||||||
@ -72,11 +71,11 @@ class PatchesSelectorViewModel(input: Params) : ViewModel(), KoinComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var hasModifiedSelection = false
|
private var hasModifiedSelection = false
|
||||||
private var customPatchesSelection: PersistentPatchesSelection? by savedStateHandle.saveable(
|
private var customPatchSelection: PersistentPatchSelection? by savedStateHandle.saveable(
|
||||||
key = "selection",
|
key = "selection",
|
||||||
stateSaver = patchesSaver,
|
stateSaver = selectionSaver,
|
||||||
) {
|
) {
|
||||||
mutableStateOf(input.currentSelection?.toPersistentPatchesSelection())
|
mutableStateOf(input.currentSelection?.toPersistentPatchSelection())
|
||||||
}
|
}
|
||||||
|
|
||||||
private val patchOptions: PersistentOptions by savedStateHandle.saveable(
|
private val patchOptions: PersistentOptions by savedStateHandle.saveable(
|
||||||
@ -98,12 +97,12 @@ class PatchesSelectorViewModel(input: Params) : ViewModel(), KoinComponent {
|
|||||||
var filter by mutableIntStateOf(SHOW_SUPPORTED or SHOW_UNIVERSAL or SHOW_UNSUPPORTED)
|
var filter by mutableIntStateOf(SHOW_SUPPORTED or SHOW_UNIVERSAL or SHOW_UNSUPPORTED)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private suspend fun generateDefaultSelection(): PersistentPatchesSelection {
|
private suspend fun generateDefaultSelection(): PersistentPatchSelection {
|
||||||
val bundles = bundlesFlow.first()
|
val bundles = bundlesFlow.first()
|
||||||
val generatedSelection =
|
val generatedSelection =
|
||||||
bundles.toPatchSelection(allowExperimental) { _, patch -> patch.include }
|
bundles.toPatchSelection(allowExperimental) { _, patch -> patch.include }
|
||||||
|
|
||||||
return generatedSelection.toPersistentPatchesSelection()
|
return generatedSelection.toPersistentPatchSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun selectionIsValid(bundles: List<BundleInfo>) = bundles.any { bundle ->
|
fun selectionIsValid(bundles: List<BundleInfo>) = bundles.any { bundle ->
|
||||||
@ -112,14 +111,14 @@ class PatchesSelectorViewModel(input: Params) : ViewModel(), KoinComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isSelected(bundle: Int, patch: PatchInfo) = customPatchesSelection?.let { selection ->
|
fun isSelected(bundle: Int, patch: PatchInfo) = customPatchSelection?.let { selection ->
|
||||||
selection[bundle]?.contains(patch.name) ?: false
|
selection[bundle]?.contains(patch.name) ?: false
|
||||||
} ?: patch.include
|
} ?: patch.include
|
||||||
|
|
||||||
fun togglePatch(bundle: Int, patch: PatchInfo) = viewModelScope.launch {
|
fun togglePatch(bundle: Int, patch: PatchInfo) = viewModelScope.launch {
|
||||||
hasModifiedSelection = true
|
hasModifiedSelection = true
|
||||||
|
|
||||||
val selection = customPatchesSelection ?: generateDefaultSelection()
|
val selection = customPatchSelection ?: generateDefaultSelection()
|
||||||
val newPatches = selection[bundle]?.let { patches ->
|
val newPatches = selection[bundle]?.let { patches ->
|
||||||
if (patch.name in patches)
|
if (patch.name in patches)
|
||||||
patches.remove(patch.name)
|
patches.remove(patch.name)
|
||||||
@ -127,7 +126,7 @@ class PatchesSelectorViewModel(input: Params) : ViewModel(), KoinComponent {
|
|||||||
patches.add(patch.name)
|
patches.add(patch.name)
|
||||||
} ?: persistentSetOf(patch.name)
|
} ?: persistentSetOf(patch.name)
|
||||||
|
|
||||||
customPatchesSelection = selection.put(bundle, newPatches)
|
customPatchSelection = selection.put(bundle, newPatches)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun confirmSelectionWarning(dismissPermanently: Boolean) {
|
fun confirmSelectionWarning(dismissPermanently: Boolean) {
|
||||||
@ -149,15 +148,15 @@ class PatchesSelectorViewModel(input: Params) : ViewModel(), KoinComponent {
|
|||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
patchOptions.clear()
|
patchOptions.clear()
|
||||||
customPatchesSelection = null
|
customPatchSelection = null
|
||||||
hasModifiedSelection = false
|
hasModifiedSelection = false
|
||||||
app.toast(app.getString(R.string.patch_selection_reset_toast))
|
app.toast(app.getString(R.string.patch_selection_reset_toast))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCustomSelection(): PatchesSelection? {
|
fun getCustomSelection(): PatchSelection? {
|
||||||
// Convert persistent collections to standard hash collections because persistent collections are not parcelable.
|
// Convert persistent collections to standard hash collections because persistent collections are not parcelable.
|
||||||
|
|
||||||
return customPatchesSelection?.mapValues { (_, v) -> v.toSet() }
|
return customPatchSelection?.mapValues { (_, v) -> v.toSet() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getOptions(): Options {
|
fun getOptions(): Options {
|
||||||
@ -211,20 +210,20 @@ class PatchesSelectorViewModel(input: Params) : ViewModel(), KoinComponent {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val patchesSaver: Saver<PersistentPatchesSelection?, Nullable<PatchesSelection>> =
|
private val selectionSaver: Saver<PersistentPatchSelection?, Nullable<PatchSelection>> =
|
||||||
nullableSaver(persistentMapSaver(valueSaver = persistentSetSaver()))
|
nullableSaver(persistentMapSaver(valueSaver = persistentSetSaver()))
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Params(
|
data class Params(
|
||||||
val app: SelectedApp,
|
val app: SelectedApp,
|
||||||
val currentSelection: PatchesSelection?,
|
val currentSelection: PatchSelection?,
|
||||||
val options: Options,
|
val options: Options,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Versions of other types, but utilizing persistent/observable collection types.
|
// Versions of other types, but utilizing persistent/observable collection types.
|
||||||
private typealias PersistentOptions = SnapshotStateMap<Int, PersistentMap<String, PersistentMap<String, Any?>>>
|
private typealias PersistentOptions = SnapshotStateMap<Int, PersistentMap<String, PersistentMap<String, Any?>>>
|
||||||
private typealias PersistentPatchesSelection = PersistentMap<Int, PersistentSet<String>>
|
private typealias PersistentPatchSelection = PersistentMap<Int, PersistentSet<String>>
|
||||||
|
|
||||||
private fun PatchesSelection.toPersistentPatchesSelection(): PersistentPatchesSelection =
|
private fun PatchSelection.toPersistentPatchSelection(): PersistentPatchSelection =
|
||||||
mapValues { (_, v) -> v.toPersistentSet() }.toPersistentMap()
|
mapValues { (_, v) -> v.toPersistentSet() }.toPersistentMap()
|
@ -20,7 +20,7 @@ import app.revanced.manager.ui.model.BundleInfo.Extensions.toPatchSelection
|
|||||||
import app.revanced.manager.ui.model.SelectedApp
|
import app.revanced.manager.ui.model.SelectedApp
|
||||||
import app.revanced.manager.util.Options
|
import app.revanced.manager.util.Options
|
||||||
import app.revanced.manager.util.PM
|
import app.revanced.manager.util.PM
|
||||||
import app.revanced.manager.util.PatchesSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@ -109,11 +109,11 @@ class SelectedAppInfoViewModel(input: Params) : ViewModel(), KoinComponent {
|
|||||||
fun getCustomPatches(
|
fun getCustomPatches(
|
||||||
bundles: List<BundleInfo>,
|
bundles: List<BundleInfo>,
|
||||||
allowUnsupported: Boolean
|
allowUnsupported: Boolean
|
||||||
): PatchesSelection? =
|
): PatchSelection? =
|
||||||
(selectionState as? SelectionState.Customized)?.patches(bundles, allowUnsupported)
|
(selectionState as? SelectionState.Customized)?.patches(bundles, allowUnsupported)
|
||||||
|
|
||||||
fun updateConfiguration(
|
fun updateConfiguration(
|
||||||
selection: PatchesSelection?,
|
selection: PatchSelection?,
|
||||||
options: Options,
|
options: Options,
|
||||||
bundles: List<BundleInfo>
|
bundles: List<BundleInfo>
|
||||||
) {
|
) {
|
||||||
@ -135,7 +135,7 @@ class SelectedAppInfoViewModel(input: Params) : ViewModel(), KoinComponent {
|
|||||||
|
|
||||||
data class Params(
|
data class Params(
|
||||||
val app: SelectedApp,
|
val app: SelectedApp,
|
||||||
val patches: PatchesSelection?,
|
val patches: PatchSelection?,
|
||||||
)
|
)
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
@ -165,15 +165,15 @@ class SelectedAppInfoViewModel(input: Params) : ViewModel(), KoinComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private sealed interface SelectionState : Parcelable {
|
private sealed interface SelectionState : Parcelable {
|
||||||
fun patches(bundles: List<BundleInfo>, allowUnsupported: Boolean): PatchesSelection
|
fun patches(bundles: List<BundleInfo>, allowUnsupported: Boolean): PatchSelection
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class Customized(val patchesSelection: PatchesSelection) : SelectionState {
|
data class Customized(val patchSelection: PatchSelection) : SelectionState {
|
||||||
override fun patches(bundles: List<BundleInfo>, allowUnsupported: Boolean) =
|
override fun patches(bundles: List<BundleInfo>, allowUnsupported: Boolean) =
|
||||||
bundles.toPatchSelection(
|
bundles.toPatchSelection(
|
||||||
allowUnsupported
|
allowUnsupported
|
||||||
) { uid, patch ->
|
) { uid, patch ->
|
||||||
patchesSelection[uid]?.contains(patch.name) ?: false
|
patchSelection[uid]?.contains(patch.name) ?: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ import java.time.format.DateTimeFormatter
|
|||||||
import java.time.format.DateTimeParseException
|
import java.time.format.DateTimeParseException
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
typealias PatchesSelection = Map<Int, Set<String>>
|
typealias PatchSelection = Map<Int, Set<String>>
|
||||||
typealias Options = Map<Int, Map<String, Map<String, Any?>>>
|
typealias Options = Map<Int, Map<String, Map<String, Any?>>>
|
||||||
|
|
||||||
val Context.isDebuggable get() = 0 != applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE
|
val Context.isDebuggable get() = 0 != applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<plurals name="patches_count">
|
<plurals name="patch_count">
|
||||||
<item quantity="one">%d patch</item>
|
<item quantity="one">%d patch</item>
|
||||||
<item quantity="other">%d patches</item>
|
<item quantity="other">%d patches</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="applied_patches">
|
|
||||||
<item quantity="one">%d applied patch</item>
|
|
||||||
<item quantity="other">%d applied patches</item>
|
|
||||||
</plurals>
|
|
||||||
<plurals name="patches_applied">
|
<plurals name="patches_applied">
|
||||||
<item quantity="one">Applied %d patch</item>
|
<item quantity="one">Applied %d patch</item>
|
||||||
<item quantity="other">Applied %d patches</item>
|
<item quantity="other">Applied %d patches</item>
|
||||||
|
@ -83,22 +83,20 @@
|
|||||||
<string name="regenerate_keystore">Regenerate keystore</string>
|
<string name="regenerate_keystore">Regenerate keystore</string>
|
||||||
<string name="regenerate_keystore_description">Generate a new keystore</string>
|
<string name="regenerate_keystore_description">Generate a new keystore</string>
|
||||||
<string name="regenerate_keystore_success">The keystore has been successfully replaced</string>
|
<string name="regenerate_keystore_success">The keystore has been successfully replaced</string>
|
||||||
<string name="patches_selection">Patches selection</string>
|
<string name="import_patch_selection">Import patch selection</string>
|
||||||
<string name="restore_patches_selection">Restore patches selections</string>
|
<string name="import_patch_selection_description">Import patch selection from a JSON file</string>
|
||||||
<string name="restore_patches_selection_description">Restore patches selection from a file</string>
|
<string name="import_patch_selection_fail">Could not import patch selection: %s</string>
|
||||||
<string name="restore_patches_selection_fail">Failed to restore patches selection: %s</string>
|
<string name="export_patch_selection">Export patch selection</string>
|
||||||
<string name="backup_patches_selection">Backup patches selections</string>
|
<string name="export_patch_selection_description">Export patch selection from a JSON file</string>
|
||||||
<string name="backup_patches_selection_description">Backup patches selection to a file</string>
|
<string name="export_patch_selection_fail">Could not export patch selection: %s</string>
|
||||||
<string name="backup_patches_selection_fail">Failed to backup patches selection: %s</string>
|
<string name="reset_patch_selection">Reset patch selection</string>
|
||||||
<string name="clear_patches_selection">Clear patches selection</string>
|
<string name="reset_patch_selection_description">Reset the stored patch selection</string>
|
||||||
<string name="clear_patches_selection_description">Clear all patches selection</string>
|
<string name="patch_options_reset_package">Reset patch options for app</string>
|
||||||
<string name="patch_options">Patch options</string>
|
<string name="patch_options_reset_package_description">Resets patch options for a single app</string>
|
||||||
<string name="patch_options_clear_package">Clear patch options for package</string>
|
<string name="patch_options_reset_bundle">Resets patch options for bundle</string>
|
||||||
<string name="patch_options_clear_package_description">Resets patch options for a single package</string>
|
<string name="patch_options_reset_bundle_description">Resets patch options for all patches in a bundle</string>
|
||||||
<string name="patch_options_clear_bundle">Clear patch options for bundle</string>
|
<string name="patch_options_reset_all">Reset patch options</string>
|
||||||
<string name="patch_options_clear_bundle_description">Resets patch options for all patches in a bundle</string>
|
<string name="patch_options_reset_all_description">Resets all patch options</string>
|
||||||
<string name="patch_options_clear_all">Clear all patch options</string>
|
|
||||||
<string name="patch_options_clear_all_description">Resets all patch options</string>
|
|
||||||
<string name="prefer_splits">Prefer split APK\'s</string>
|
<string name="prefer_splits">Prefer split APK\'s</string>
|
||||||
<string name="prefer_splits_description">Prefer split APK\'s instead of full APK\'s</string>
|
<string name="prefer_splits_description">Prefer split APK\'s instead of full APK\'s</string>
|
||||||
<string name="prefer_universal">Prefer universal APK\'s</string>
|
<string name="prefer_universal">Prefer universal APK\'s</string>
|
||||||
@ -211,8 +209,8 @@
|
|||||||
<string name="downloadable_versions">Downloadable versions</string>
|
<string name="downloadable_versions">Downloadable versions</string>
|
||||||
<string name="already_patched">Already patched</string>
|
<string name="already_patched">Already patched</string>
|
||||||
|
|
||||||
<string name="patches_selector_sheet_filter_title">Filter</string>
|
<string name="patch_selector_sheet_filter_title">Filter</string>
|
||||||
<string name="patches_selector_sheet_filter_compat_title">Compatibility</string>
|
<string name="patch_selector_sheet_filter_compat_title">Compatibility</string>
|
||||||
|
|
||||||
<string name="string_option_icon_description">Edit</string>
|
<string name="string_option_icon_description">Edit</string>
|
||||||
<string name="string_option_menu_description">More options</string>
|
<string name="string_option_menu_description">More options</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user