fix: Use compatible rather than support when referring to patch compatibility (#2422)

This commit is contained in:
Ushie 2025-02-12 20:40:47 +03:00 committed by GitHub
parent 1956982060
commit d5c63ead26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 91 additions and 88 deletions

View File

@ -12,34 +12,34 @@ import kotlinx.coroutines.flow.map
data class BundleInfo( data class BundleInfo(
val name: String, val name: String,
val uid: Int, val uid: Int,
val supported: List<PatchInfo>, val compatible: List<PatchInfo>,
val unsupported: List<PatchInfo>, val incompatible: List<PatchInfo>,
val universal: List<PatchInfo> val universal: List<PatchInfo>
) { ) {
val all = sequence { val all = sequence {
yieldAll(supported) yieldAll(compatible)
yieldAll(unsupported) yieldAll(incompatible)
yieldAll(universal) yieldAll(universal)
} }
val patchCount get() = supported.size + unsupported.size + universal.size val patchCount get() = compatible.size + incompatible.size + universal.size
fun patchSequence(allowUnsupported: Boolean) = if (allowUnsupported) { fun patchSequence(allowIncompatible: Boolean) = if (allowIncompatible) {
all all
} else { } else {
sequence { sequence {
yieldAll(supported) yieldAll(compatible)
yieldAll(universal) yieldAll(universal)
} }
} }
companion object Extensions { companion object Extensions {
inline fun Iterable<BundleInfo>.toPatchSelection( inline fun Iterable<BundleInfo>.toPatchSelection(
allowUnsupported: Boolean, allowIncompatible: Boolean,
condition: (Int, PatchInfo) -> Boolean condition: (Int, PatchInfo) -> Boolean
): PatchSelection = this.associate { bundle -> ): PatchSelection = this.associate { bundle ->
val patches = val patches =
bundle.patchSequence(allowUnsupported) bundle.patchSequence(allowIncompatible)
.mapNotNullTo(mutableSetOf()) { patch -> .mapNotNullTo(mutableSetOf()) { patch ->
patch.name.takeIf { patch.name.takeIf {
condition( condition(
@ -60,8 +60,8 @@ data class BundleInfo(
source.state.map { state -> source.state.map { state ->
val bundle = state.patchBundleOrNull() ?: return@map null val bundle = state.patchBundleOrNull() ?: return@map null
val supported = mutableListOf<PatchInfo>() val compatible = mutableListOf<PatchInfo>()
val unsupported = mutableListOf<PatchInfo>() val incompatible = mutableListOf<PatchInfo>()
val universal = mutableListOf<PatchInfo>() val universal = mutableListOf<PatchInfo>()
bundle.patches.filter { it.compatibleWith(packageName) }.forEach { bundle.patches.filter { it.compatibleWith(packageName) }.forEach {
@ -70,15 +70,15 @@ data class BundleInfo(
it.supports( it.supports(
packageName, packageName,
version version
) -> supported ) -> compatible
else -> unsupported else -> incompatible
} }
targetList.add(it) targetList.add(it)
} }
BundleInfo(source.getName(), source.uid, supported, unsupported, universal) BundleInfo(source.getName(), source.uid, compatible, incompatible, universal)
} }
} }

View File

@ -76,8 +76,8 @@ import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionBut
import app.revanced.manager.ui.component.haptics.HapticTab import app.revanced.manager.ui.component.haptics.HapticTab
import app.revanced.manager.ui.component.patches.OptionItem import app.revanced.manager.ui.component.patches.OptionItem
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_INCOMPATIBLE
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.util.Options import app.revanced.manager.util.Options
import app.revanced.manager.util.PatchSelection import app.revanced.manager.util.PatchSelection
import app.revanced.manager.util.isScrollingUp import app.revanced.manager.util.isScrollingUp
@ -147,9 +147,9 @@ fun PatchesSelectorScreen(
verticalArrangement = Arrangement.spacedBy(12.dp) verticalArrangement = Arrangement.spacedBy(12.dp)
) { ) {
CheckedFilterChip( CheckedFilterChip(
selected = vm.filter and SHOW_UNSUPPORTED == 0, selected = vm.filter and SHOW_INCOMPATIBLE == 0,
onClick = { vm.toggleFlag(SHOW_UNSUPPORTED) }, onClick = { vm.toggleFlag(SHOW_INCOMPATIBLE) },
label = { Text(stringResource(R.string.supported)) } label = { Text(stringResource(R.string.this_version)) }
) )
CheckedFilterChip( CheckedFilterChip(
@ -163,18 +163,18 @@ fun PatchesSelectorScreen(
} }
if (vm.compatibleVersions.isNotEmpty()) if (vm.compatibleVersions.isNotEmpty())
UnsupportedPatchDialog( IncompatiblePatchDialog(
appVersion = vm.appVersion ?: stringResource(R.string.any_version), appVersion = vm.appVersion ?: stringResource(R.string.any_version),
supportedVersions = vm.compatibleVersions, compatibleVersions = vm.compatibleVersions,
onDismissRequest = vm::dismissDialogs onDismissRequest = vm::dismissDialogs
) )
var showUnsupportedPatchesDialog by rememberSaveable { var showIncompatiblePatchesDialog by rememberSaveable {
mutableStateOf(false) mutableStateOf(false)
} }
if (showUnsupportedPatchesDialog) if (showIncompatiblePatchesDialog)
UnsupportedPatchesDialog( IncompatiblePatchesDialog(
appVersion = vm.appVersion ?: stringResource(R.string.any_version), appVersion = vm.appVersion ?: stringResource(R.string.any_version),
onDismissRequest = { showUnsupportedPatchesDialog = false } onDismissRequest = { showIncompatiblePatchesDialog = false }
) )
vm.optionsDialog?.let { (bundle, patch) -> vm.optionsDialog?.let { (bundle, patch) ->
@ -204,7 +204,7 @@ fun PatchesSelectorScreen(
uid: Int, uid: Int,
patches: List<PatchInfo>, patches: List<PatchInfo>,
visible: Boolean, visible: Boolean,
supported: Boolean, compatible: Boolean,
header: (@Composable () -> Unit)? = null header: (@Composable () -> Unit)? = null
) { ) {
if (patches.isNotEmpty() && visible) { if (patches.isNotEmpty() && visible) {
@ -224,14 +224,14 @@ fun PatchesSelectorScreen(
onOptionsDialog = { onOptionsDialog = {
vm.optionsDialog = uid to patch vm.optionsDialog = uid to patch
}, },
selected = supported && vm.isSelected( selected = compatible && vm.isSelected(
uid, uid,
patch patch
), ),
onToggle = { onToggle = {
when { when {
// Open unsupported dialog if the patch is not supported // Open incompatible dialog if the patch is not supported
!supported -> vm.openUnsupportedDialog(patch) !compatible -> vm.openIncompatibleDialog(patch)
// Show selection warning if enabled // Show selection warning if enabled
vm.selectionWarningEnabled -> showSelectionWarning = true vm.selectionWarningEnabled -> showSelectionWarning = true
@ -245,7 +245,7 @@ fun PatchesSelectorScreen(
else -> vm.togglePatch(uid, patch) else -> vm.togglePatch(uid, patch)
} }
}, },
supported = supported compatible = compatible
) )
} }
} }
@ -321,15 +321,15 @@ fun PatchesSelectorScreen(
patchList( patchList(
uid = bundle.uid, uid = bundle.uid,
patches = bundle.supported.searched(), patches = bundle.compatible.searched(),
visible = true, visible = true,
supported = true compatible = true
) )
patchList( patchList(
uid = bundle.uid, uid = bundle.uid,
patches = bundle.universal.searched(), patches = bundle.universal.searched(),
visible = vm.filter and SHOW_UNIVERSAL != 0, visible = vm.filter and SHOW_UNIVERSAL != 0,
supported = true compatible = true
) { ) {
ListHeader( ListHeader(
title = stringResource(R.string.universal_patches), title = stringResource(R.string.universal_patches),
@ -338,13 +338,13 @@ fun PatchesSelectorScreen(
patchList( patchList(
uid = bundle.uid, uid = bundle.uid,
patches = bundle.unsupported.searched(), patches = bundle.incompatible.searched(),
visible = vm.filter and SHOW_UNSUPPORTED != 0, visible = vm.filter and SHOW_INCOMPATIBLE != 0,
supported = vm.allowIncompatiblePatches compatible = vm.allowIncompatiblePatches
) { ) {
ListHeader( ListHeader(
title = stringResource(R.string.unsupported_patches), title = stringResource(R.string.incompatible_patches),
onHelpClick = { showUnsupportedPatchesDialog = true } onHelpClick = { showIncompatiblePatchesDialog = true }
) )
} }
} }
@ -427,15 +427,15 @@ fun PatchesSelectorScreen(
) { ) {
patchList( patchList(
uid = bundle.uid, uid = bundle.uid,
patches = bundle.supported, patches = bundle.compatible,
visible = true, visible = true,
supported = true compatible = true
) )
patchList( patchList(
uid = bundle.uid, uid = bundle.uid,
patches = bundle.universal, patches = bundle.universal,
visible = vm.filter and SHOW_UNIVERSAL != 0, visible = vm.filter and SHOW_UNIVERSAL != 0,
supported = true compatible = true
) { ) {
ListHeader( ListHeader(
title = stringResource(R.string.universal_patches), title = stringResource(R.string.universal_patches),
@ -443,13 +443,13 @@ fun PatchesSelectorScreen(
} }
patchList( patchList(
uid = bundle.uid, uid = bundle.uid,
patches = bundle.unsupported, patches = bundle.incompatible,
visible = vm.filter and SHOW_UNSUPPORTED != 0, visible = vm.filter and SHOW_INCOMPATIBLE != 0,
supported = vm.allowIncompatiblePatches compatible = vm.allowIncompatiblePatches
) { ) {
ListHeader( ListHeader(
title = stringResource(R.string.unsupported_patches), title = stringResource(R.string.incompatible_patches),
onHelpClick = { showUnsupportedPatchesDialog = true } onHelpClick = { showIncompatiblePatchesDialog = true }
) )
} }
} }
@ -506,24 +506,24 @@ private fun PatchItem(
onOptionsDialog: () -> Unit, onOptionsDialog: () -> Unit,
selected: Boolean, selected: Boolean,
onToggle: () -> Unit, onToggle: () -> Unit,
supported: Boolean = true compatible: Boolean = true
) = ListItem( ) = ListItem(
modifier = Modifier modifier = Modifier
.let { if (!supported) it.alpha(0.5f) else it } .let { if (!compatible) it.alpha(0.5f) else it }
.clickable(onClick = onToggle) .clickable(onClick = onToggle)
.fillMaxSize(), .fillMaxSize(),
leadingContent = { leadingContent = {
HapticCheckbox( HapticCheckbox(
checked = selected, checked = selected,
onCheckedChange = { onToggle() }, onCheckedChange = { onToggle() },
enabled = supported enabled = compatible
) )
}, },
headlineContent = { Text(patch.name) }, headlineContent = { Text(patch.name) },
supportingContent = patch.description?.let { { Text(it) } }, supportingContent = patch.description?.let { { Text(it) } },
trailingContent = { trailingContent = {
if (patch.options?.isNotEmpty() == true) { if (patch.options?.isNotEmpty() == true) {
IconButton(onClick = onOptionsDialog, enabled = supported) { IconButton(onClick = onOptionsDialog, enabled = compatible) {
Icon(Icons.Outlined.Settings, null) Icon(Icons.Outlined.Settings, null)
} }
} }
@ -559,7 +559,7 @@ fun ListHeader(
} }
@Composable @Composable
private fun UnsupportedPatchesDialog( private fun IncompatiblePatchesDialog(
appVersion: String, appVersion: String,
onDismissRequest: () -> Unit onDismissRequest: () -> Unit
) = AlertDialog( ) = AlertDialog(
@ -572,11 +572,11 @@ private fun UnsupportedPatchesDialog(
Text(stringResource(R.string.ok)) Text(stringResource(R.string.ok))
} }
}, },
title = { Text(stringResource(R.string.unsupported_patches)) }, title = { Text(stringResource(R.string.incompatible_patches)) },
text = { text = {
Text( Text(
stringResource( stringResource(
R.string.unsupported_patches_dialog, R.string.incompatible_patches_dialog,
appVersion appVersion
) )
) )
@ -584,9 +584,9 @@ private fun UnsupportedPatchesDialog(
) )
@Composable @Composable
private fun UnsupportedPatchDialog( private fun IncompatiblePatchDialog(
appVersion: String, appVersion: String,
supportedVersions: List<String>, compatibleVersions: List<String>,
onDismissRequest: () -> Unit onDismissRequest: () -> Unit
) = AlertDialog( ) = AlertDialog(
icon = { icon = {
@ -598,13 +598,13 @@ private fun UnsupportedPatchDialog(
Text(stringResource(R.string.ok)) Text(stringResource(R.string.ok))
} }
}, },
title = { Text(stringResource(R.string.unsupported_patch)) }, title = { Text(stringResource(R.string.incompatible_patch)) },
text = { text = {
Text( Text(
stringResource( stringResource(
R.string.app_not_supported, R.string.app_version_not_compatible,
appVersion, appVersion,
supportedVersions.joinToString(", ") compatibleVersions.joinToString(", ")
) )
) )
} }

View File

@ -3,11 +3,11 @@ package app.revanced.manager.ui.viewmodel
import android.app.Application import android.app.Application
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.Saver import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.SnapshotStateMap import androidx.compose.runtime.snapshots.SnapshotStateMap
import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
@ -30,15 +30,20 @@ import app.revanced.manager.util.saver.persistentMapSaver
import app.revanced.manager.util.saver.persistentSetSaver import app.revanced.manager.util.saver.persistentSetSaver
import app.revanced.manager.util.saver.snapshotStateMapSaver import app.revanced.manager.util.saver.snapshotStateMapSaver
import app.revanced.manager.util.toast import app.revanced.manager.util.toast
import kotlinx.collections.immutable.PersistentMap
import kotlinx.collections.immutable.PersistentSet
import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toPersistentMap
import kotlinx.collections.immutable.toPersistentSet
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch 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.coroutines.CoroutineStart
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
@OptIn(SavedStateHandleSaveableApi::class) @OptIn(SavedStateHandleSaveableApi::class)
class PatchesSelectorViewModel(input: SelectedApplicationInfo.PatchesSelector.ViewModelParams) : class PatchesSelectorViewModel(input: SelectedApplicationInfo.PatchesSelector.ViewModelParams) :
@ -208,8 +213,8 @@ class PatchesSelectorViewModel(input: SelectedApplicationInfo.PatchesSelector.Vi
compatibleVersions.clear() compatibleVersions.clear()
} }
fun openUnsupportedDialog(unsupportedPatch: PatchInfo) { fun openIncompatibleDialog(incompatiblePatch: PatchInfo) {
compatibleVersions.addAll(unsupportedPatch.compatiblePackages?.find { it.packageName == packageName }?.versions.orEmpty()) compatibleVersions.addAll(incompatiblePatch.compatiblePackages?.find { it.packageName == packageName }?.versions.orEmpty())
} }
fun toggleFlag(flag: Int) { fun toggleFlag(flag: Int) {
@ -217,7 +222,7 @@ class PatchesSelectorViewModel(input: SelectedApplicationInfo.PatchesSelector.Vi
} }
companion object { companion object {
const val SHOW_UNSUPPORTED = 1 // 2^0 const val SHOW_INCOMPATIBLE = 1 // 2^0
const val SHOW_UNIVERSAL = 2 // 2^1 const val SHOW_UNIVERSAL = 2 // 2^1
private val optionsSaver: Saver<PersistentOptions, Options> = snapshotStateMapSaver( private val optionsSaver: Saver<PersistentOptions, Options> = snapshotStateMapSaver(

View File

@ -30,14 +30,13 @@ import app.revanced.manager.domain.repository.PatchOptionsRepository
import app.revanced.manager.domain.repository.PatchSelectionRepository import app.revanced.manager.domain.repository.PatchSelectionRepository
import app.revanced.manager.network.downloader.LoadedDownloaderPlugin import app.revanced.manager.network.downloader.LoadedDownloaderPlugin
import app.revanced.manager.network.downloader.ParceledDownloaderData import app.revanced.manager.network.downloader.ParceledDownloaderData
import app.revanced.manager.patcher.patch.PatchInfo
import app.revanced.manager.plugin.downloader.GetScope import app.revanced.manager.plugin.downloader.GetScope
import app.revanced.manager.plugin.downloader.PluginHostApi import app.revanced.manager.plugin.downloader.PluginHostApi
import app.revanced.manager.plugin.downloader.UserInteractionException import app.revanced.manager.plugin.downloader.UserInteractionException
import app.revanced.manager.ui.model.BundleInfo import app.revanced.manager.ui.model.BundleInfo
import app.revanced.manager.ui.model.BundleInfo.Extensions.bundleInfoFlow 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.requiredOptionsSet import app.revanced.manager.ui.model.BundleInfo.Extensions.requiredOptionsSet
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.ui.model.navigation.Patcher import app.revanced.manager.ui.model.navigation.Patcher
import app.revanced.manager.ui.model.navigation.SelectedApplicationInfo import app.revanced.manager.ui.model.navigation.SelectedApplicationInfo
@ -275,25 +274,25 @@ class SelectedAppInfoViewModel(
) )
suspend fun getPatcherParams(): Patcher.ViewModelParams { suspend fun getPatcherParams(): Patcher.ViewModelParams {
val allowUnsupported = prefs.disablePatchVersionCompatCheck.get() val allowIncompatible = prefs.disablePatchVersionCompatCheck.get()
val bundles = bundleInfoFlow.first() val bundles = bundleInfoFlow.first()
return Patcher.ViewModelParams( return Patcher.ViewModelParams(
selectedApp, selectedApp,
getPatches(bundles, allowUnsupported), getPatches(bundles, allowIncompatible),
getOptionsFiltered(bundles) getOptionsFiltered(bundles)
) )
} }
fun getOptionsFiltered(bundles: List<BundleInfo>) = options.filtered(bundles) fun getOptionsFiltered(bundles: List<BundleInfo>) = options.filtered(bundles)
fun getPatches(bundles: List<BundleInfo>, allowUnsupported: Boolean) = fun getPatches(bundles: List<BundleInfo>, allowIncompatible: Boolean) =
selectionState.patches(bundles, allowUnsupported) selectionState.patches(bundles, allowIncompatible)
fun getCustomPatches( fun getCustomPatches(
bundles: List<BundleInfo>, bundles: List<BundleInfo>,
allowUnsupported: Boolean allowIncompatible: Boolean
): PatchSelection? = ): PatchSelection? =
(selectionState as? SelectionState.Customized)?.patches(bundles, allowUnsupported) (selectionState as? SelectionState.Customized)?.patches(bundles, allowIncompatible)
fun updateConfiguration(selection: PatchSelection?, options: Options) = viewModelScope.launch { fun updateConfiguration(selection: PatchSelection?, options: Options) = viewModelScope.launch {
val bundles = bundleInfoFlow.first() val bundles = bundleInfoFlow.first()
@ -343,13 +342,13 @@ class SelectedAppInfoViewModel(
} }
private sealed interface SelectionState : Parcelable { private sealed interface SelectionState : Parcelable {
fun patches(bundles: List<BundleInfo>, allowUnsupported: Boolean): PatchSelection fun patches(bundles: List<BundleInfo>, allowIncompatible: Boolean): PatchSelection
@Parcelize @Parcelize
data class Customized(val patchSelection: PatchSelection) : SelectionState { data class Customized(val patchSelection: PatchSelection) : SelectionState {
override fun patches(bundles: List<BundleInfo>, allowUnsupported: Boolean) = override fun patches(bundles: List<BundleInfo>, allowIncompatible: Boolean) =
bundles.toPatchSelection( bundles.toPatchSelection(
allowUnsupported allowIncompatible
) { uid, patch -> ) { uid, patch ->
patchSelection[uid]?.contains(patch.name) ?: false patchSelection[uid]?.contains(patch.name) ?: false
} }
@ -357,8 +356,8 @@ private sealed interface SelectionState : Parcelable {
@Parcelize @Parcelize
data object Default : SelectionState { data object Default : SelectionState {
override fun patches(bundles: List<BundleInfo>, allowUnsupported: Boolean) = override fun patches(bundles: List<BundleInfo>, allowIncompatible: Boolean) =
bundles.toPatchSelection(allowUnsupported) { _, patch -> patch.include } bundles.toPatchSelection(allowIncompatible) { _, patch -> patch.include }
} }
} }

View File

@ -87,7 +87,7 @@
<string name="theme_description">Choose between light or dark theme</string> <string name="theme_description">Choose between light or dark theme</string>
<string name="safeguards">Safeguards</string> <string name="safeguards">Safeguards</string>
<string name="patch_compat_check">Disable version compatibility check</string> <string name="patch_compat_check">Disable version compatibility check</string>
<string name="patch_compat_check_description">The check restricts patches to supported app versions</string> <string name="patch_compat_check_description">The check restricts patches to compatible app versions</string>
<string name="patch_compat_check_confirmation">Selecting incompatible patches can result in a broken app.\n\nDo you want to proceed anyways?</string> <string name="patch_compat_check_confirmation">Selecting incompatible patches can result in a broken app.\n\nDo you want to proceed anyways?</string>
<string name="suggested_version_safeguard">Require suggested app version</string> <string name="suggested_version_safeguard">Require suggested app version</string>
<string name="suggested_version_safeguard_description">Enforce selection of the suggested app version</string> <string name="suggested_version_safeguard_description">Enforce selection of the suggested app version</string>
@ -211,7 +211,7 @@
<string name="no_patched_apps_found">No patched apps found</string> <string name="no_patched_apps_found">No patched apps found</string>
<string name="tap_on_patches">Tap on the patches to get more information about them</string> <string name="tap_on_patches">Tap on the patches to get more information about them</string>
<string name="bundles_selected">%s selected</string> <string name="bundles_selected">%s selected</string>
<string name="unsupported_patches">Incompatible patches</string> <string name="incompatible_patches">Incompatible patches</string>
<string name="universal_patches">Universal patches</string> <string name="universal_patches">Universal patches</string>
<string name="patch_selection_reset_toast">Patch selection and options has been reset to recommended defaults</string> <string name="patch_selection_reset_toast">Patch selection and options has been reset to recommended defaults</string>
<string name="patch_options_reset_toast">Patch options have been reset</string> <string name="patch_options_reset_toast">Patch options have been reset</string>
@ -220,13 +220,12 @@
<string name="selection_warning_title">Stop using defaults?</string> <string name="selection_warning_title">Stop using defaults?</string>
<string name="selection_warning_description">It is recommended to use the default patch selection and options. Changing them may result in unexpected issues.\n\nYou need to turn on \"Allow changing patch selection\" in the advanced settings before toggling patches.</string> <string name="selection_warning_description">It is recommended to use the default patch selection and options. Changing them may result in unexpected issues.\n\nYou need to turn on \"Allow changing patch selection\" in the advanced settings before toggling patches.</string>
<string name="universal_patch_warning_description">Universal patches have a more generalized use and do not work as reliably as patches that target specific apps. You may encounter issues while using them.\n\nThis warning can be disabled in the advanced settings.</string> <string name="universal_patch_warning_description">Universal patches have a more generalized use and do not work as reliably as patches that target specific apps. You may encounter issues while using them.\n\nThis warning can be disabled in the advanced settings.</string>
<string name="supported">This version</string> <string name="this_version">This version</string>
<string name="universal">Any app</string> <string name="universal">Any app</string>
<string name="unsupported">Unsupported</string>
<string name="search_patches">Search patches</string> <string name="search_patches">Search patches</string>
<string name="app_not_supported">This patch is not compatible with the selected app version (%1$s).\n\nIt only supports the following version(s): %2$s.</string> <string name="app_version_not_compatible">This patch is not compatible with the selected app version (%1$s).\n\nIt is only compatible with the following version(s): %2$s.</string>
<string name="continue_with_version">Continue with this version?</string> <string name="continue_with_version">Continue with this version?</string>
<string name="version_not_supported">Not all patches support this version (%s). Do you want to continue anyway?</string> <string name="version_not_compatible">Not all patches are compatible with this version (%s). Do you want to continue anyway?</string>
<string name="download_application">Download application?</string> <string name="download_application">Download application?</string>
<string name="app_not_installed">The app you selected isn\'t installed. Do you want to download it?</string> <string name="app_not_installed">The app you selected isn\'t installed. Do you want to download it?</string>
<string name="failed_to_load_apk">Failed to load APK</string> <string name="failed_to_load_apk">Failed to load APK</string>
@ -400,7 +399,7 @@
<string name="installation_aborted_description">The installation was cancelled manually. Try again?</string> <string name="installation_aborted_description">The installation was cancelled manually. Try again?</string>
<string name="installation_blocked_description">The installation was blocked. Review your device security settings and try again.</string> <string name="installation_blocked_description">The installation was blocked. Review your device security settings and try again.</string>
<string name="installation_conflict_description">The installation was prevented by an existing installation of the app. Uninstall the installed app and try again?</string> <string name="installation_conflict_description">The installation was prevented by an existing installation of the app. Uninstall the installed app and try again?</string>
<string name="installation_incompatible_description">The app is incompatible with this device. Use an APK that is supported by this device and try again.</string> <string name="installation_incompatible_description">The app is incompatible with this device. Use an APK that is compatible by this device and try again.</string>
<string name="installation_invalid_description">The app is invalid. Uninstall the app and try again?</string> <string name="installation_invalid_description">The app is invalid. Uninstall the app and try again?</string>
<string name="installation_storage_issue_description">The app could not be installed due to insufficient storage. Free up some space and try again.</string> <string name="installation_storage_issue_description">The app could not be installed due to insufficient storage. Free up some space and try again.</string>
<string name="installation_timeout_description">The installation took too long. Try again?</string> <string name="installation_timeout_description">The installation took too long. Try again?</string>
@ -413,8 +412,8 @@
<string name="add_patch_bundle">Add patch bundle</string> <string name="add_patch_bundle">Add patch bundle</string>
<string name="bundle_url">Bundle URL</string> <string name="bundle_url">Bundle URL</string>
<string name="auto_update">Auto update</string> <string name="auto_update">Auto update</string>
<string name="unsupported_patches_dialog">These patches are not compatible with the selected app version (%1$s).\n\nClick on the patches to see more details.</string> <string name="incompatible_patches_dialog">These patches are not compatible with the selected app version (%1$s).\n\nClick on the patches to see more details.</string>
<string name="unsupported_patch">Unsupported patch</string> <string name="incompatible_patch">Incompatible patch</string>
<string name="any_version">Any</string> <string name="any_version">Any</string>
<string name="never_show_again">Never show again</string> <string name="never_show_again">Never show again</string>
<string name="show_manager_update_dialog_on_launch">Show update message on launch</string> <string name="show_manager_update_dialog_on_launch">Show update message on launch</string>