mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2025-07-15 01:05:27 +08:00
Compare commits
16 Commits
build/spot
...
compose-de
Author | SHA1 | Date | |
---|---|---|---|
b51d1ee47a | |||
7148ee66f8 | |||
f7a4ae5791 | |||
cb2dbbee24 | |||
578dcce9b6 | |||
8c6c0f3c76 | |||
979a2dc410 | |||
baa9122a88 | |||
b70fc03bc7 | |||
83fc7f131a | |||
8e4a9088ea | |||
7ee2b1a026 | |||
40c99ab4dc | |||
1752fae9d9 | |||
d264a2a363 | |||
a5e909cfc8 |
@ -1,23 +0,0 @@
|
|||||||
[*.{kt,kts}]
|
|
||||||
end_of_line = lf
|
|
||||||
ij_kotlin_allow_trailing_comma = false
|
|
||||||
ij_kotlin_allow_trailing_comma_on_call_site = false
|
|
||||||
ij_kotlin_imports_layout = *
|
|
||||||
ij_kotlin_indent_before_arrow_on_new_line = false
|
|
||||||
ij_kotlin_line_break_after_multiline_when_entry = true
|
|
||||||
ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**
|
|
||||||
indent_size = 4
|
|
||||||
indent_style = space
|
|
||||||
insert_final_newline = true
|
|
||||||
ktlint_annotation_handle_annotations_with_parameters_same_as_annotations_without_parameters = [unset]
|
|
||||||
ktlint_argument_list_wrapping_ignore_when_parameter_count_greater_or_equal_than = 8
|
|
||||||
ktlint_chain_method_rule_force_multiline_when_chain_operator_count_greater_or_equal_than = 4
|
|
||||||
ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = unset
|
|
||||||
ktlint_code_style = android_studio
|
|
||||||
ktlint_enum_entry_name_casing = upper_or_camel_cases
|
|
||||||
ktlint_function_naming_ignore_when_annotated_with = [unset]
|
|
||||||
ktlint_function_signature_body_expression_wrapping = default
|
|
||||||
ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = unset
|
|
||||||
ktlint_ignore_back_ticked_identifier = false
|
|
||||||
ktlint_property_naming_constant_naming = screaming_snake_case
|
|
||||||
max_line_length = 100
|
|
5
.github/workflows/build_pull_request.yml
vendored
5
.github/workflows/build_pull_request.yml
vendored
@ -19,11 +19,6 @@ jobs:
|
|||||||
- name: Cache Gradle
|
- name: Cache Gradle
|
||||||
uses: burrunan/gradle-cache-action@v1
|
uses: burrunan/gradle-cache-action@v1
|
||||||
|
|
||||||
- name: Spotless Check
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: ./gradlew spotlessCheck --no-daemon
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
@ -15,7 +15,7 @@ class LocalPatchBundle(name: String, id: Int, directory: File) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
reload()?.also {
|
reload()?.also {
|
||||||
saveVersionHash(it.readManifestAttribute("Version"))
|
saveVersionHash(it.patchBundleManifestAttributes?.version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,11 +34,11 @@ sealed class PatchBundleSource(initialName: String, val uid: Int, directory: Fil
|
|||||||
|
|
||||||
private val _nameFlow = MutableStateFlow(initialName)
|
private val _nameFlow = MutableStateFlow(initialName)
|
||||||
val nameFlow =
|
val nameFlow =
|
||||||
_nameFlow.map { it.ifEmpty { app.getString(if (isDefault) R.string.bundle_name_default else R.string.bundle_name_fallback) } }
|
_nameFlow.map { it.ifEmpty { app.getString(if (isDefault) R.string.patches_name_default else R.string.patches_name_fallback) } }
|
||||||
|
|
||||||
suspend fun getName() = nameFlow.first()
|
suspend fun getName() = nameFlow.first()
|
||||||
|
|
||||||
val versionFlow = state.map { it.patchBundleOrNull()?.readManifestAttribute("Version") }
|
val versionFlow = state.map { it.patchBundleOrNull()?.patchBundleManifestAttributes?.version }
|
||||||
val patchCountFlow = state.map { it.patchBundleOrNull()?.patches?.size ?: 0 }
|
val patchCountFlow = state.map { it.patchBundleOrNull()?.patches?.size ?: 0 }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,7 +74,7 @@ sealed class PatchBundleSource(initialName: String, val uid: Int, directory: Fil
|
|||||||
val bundle = newState.patchBundleOrNull()
|
val bundle = newState.patchBundleOrNull()
|
||||||
// Try to read the name from the patch bundle manifest if the bundle does not have a name.
|
// Try to read the name from the patch bundle manifest if the bundle does not have a name.
|
||||||
if (bundle != null && _nameFlow.value.isEmpty()) {
|
if (bundle != null && _nameFlow.value.isEmpty()) {
|
||||||
bundle.readManifestAttribute("Name")?.let { setName(it) }
|
bundle.patchBundleManifestAttributes?.name?.let { setName(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
return bundle
|
return bundle
|
||||||
|
@ -50,7 +50,7 @@ sealed class RemotePatchBundle(name: String, id: Int, directory: File, val endpo
|
|||||||
suspend fun setAutoUpdate(value: Boolean) = configRepository.setAutoUpdate(uid, value)
|
suspend fun setAutoUpdate(value: Boolean) = configRepository.setAutoUpdate(uid, value)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val updateFailMsg = "Failed to update patch bundle(s)"
|
const val updateFailMsg = "Failed to update patches"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,8 @@ class DownloadedAppRepository(
|
|||||||
data: Parcelable,
|
data: Parcelable,
|
||||||
expectedPackageName: String,
|
expectedPackageName: String,
|
||||||
expectedVersion: String?,
|
expectedVersion: String?,
|
||||||
|
appCompatibilityCheck: Boolean,
|
||||||
|
patchesCompatibilityCheck: Boolean,
|
||||||
onDownload: suspend (downloadProgress: Pair<Long, Long?>) -> Unit,
|
onDownload: suspend (downloadProgress: Pair<Long, Long?>) -> Unit,
|
||||||
): File {
|
): File {
|
||||||
// Converted integers cannot contain / or .. unlike the package name or version, so they are safer to use here.
|
// Converted integers cannot contain / or .. unlike the package name or version, so they are safer to use here.
|
||||||
@ -96,7 +98,12 @@ class DownloadedAppRepository(
|
|||||||
val pkgInfo =
|
val pkgInfo =
|
||||||
pm.getPackageInfo(targetFile.toFile()) ?: error("Downloaded APK file is invalid")
|
pm.getPackageInfo(targetFile.toFile()) ?: error("Downloaded APK file is invalid")
|
||||||
if (pkgInfo.packageName != expectedPackageName) error("Downloaded APK has the wrong package name. Expected: $expectedPackageName, Actual: ${pkgInfo.packageName}")
|
if (pkgInfo.packageName != expectedPackageName) error("Downloaded APK has the wrong package name. Expected: $expectedPackageName, Actual: ${pkgInfo.packageName}")
|
||||||
if (expectedVersion != null && pkgInfo.versionName != expectedVersion) error("Downloaded APK has the wrong version. Expected: $expectedVersion, Actual: ${pkgInfo.versionName}")
|
expectedVersion?.let {
|
||||||
|
if (
|
||||||
|
pkgInfo.versionName != expectedVersion &&
|
||||||
|
(appCompatibilityCheck || patchesCompatibilityCheck)
|
||||||
|
) error("The selected app version ($pkgInfo.versionName) doesn't match the suggested version. Please use the suggested version ($expectedVersion), or adjust your settings by disabling \"Require suggested app version\" and enabling \"Disable version compatibility check\".")
|
||||||
|
}
|
||||||
|
|
||||||
// Delete the previous copy (if present).
|
// Delete the previous copy (if present).
|
||||||
dao.get(pkgInfo.packageName, pkgInfo.versionName!!)?.directory?.let {
|
dao.get(pkgInfo.packageName, pkgInfo.versionName!!)?.directory?.let {
|
||||||
|
@ -165,7 +165,7 @@ class PatchBundleRepository(
|
|||||||
getBundlesByType<RemotePatchBundle>().forEach { it.downloadLatest() }
|
getBundlesByType<RemotePatchBundle>().forEach { it.downloadLatest() }
|
||||||
|
|
||||||
suspend fun updateCheck() =
|
suspend fun updateCheck() =
|
||||||
uiSafe(app, R.string.source_download_fail, "Failed to update bundles") {
|
uiSafe(app, R.string.patches_download_fail, "Failed to update bundles") {
|
||||||
coroutineScope {
|
coroutineScope {
|
||||||
if (!networkInfo.isSafe()) {
|
if (!networkInfo.isSafe()) {
|
||||||
Log.d(tag, "Skipping update check because the network is down or metered.")
|
Log.d(tag, "Skipping update check because the network is down or metered.")
|
||||||
|
@ -8,6 +8,17 @@ import java.io.File
|
|||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.jar.JarFile
|
import java.util.jar.JarFile
|
||||||
|
|
||||||
|
class PatchBundleManifestAttributes(
|
||||||
|
val name: String?,
|
||||||
|
val version: String?,
|
||||||
|
val description: String?,
|
||||||
|
val source: String?,
|
||||||
|
val author: String?,
|
||||||
|
val contact: String?,
|
||||||
|
val website: String?,
|
||||||
|
val license: String?
|
||||||
|
)
|
||||||
|
|
||||||
class PatchBundle(val patchesJar: File) {
|
class PatchBundle(val patchesJar: File) {
|
||||||
private val loader = object : Iterable<Patch<*>> {
|
private val loader = object : Iterable<Patch<*>> {
|
||||||
private fun load(): Iterable<Patch<*>> {
|
private fun load(): Iterable<Patch<*>> {
|
||||||
@ -36,7 +47,20 @@ class PatchBundle(val patchesJar: File) {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun readManifestAttribute(name: String) = manifest?.mainAttributes?.getValue(name)
|
val patchBundleManifestAttributes = if(manifest != null)
|
||||||
|
PatchBundleManifestAttributes(
|
||||||
|
name = readManifestAttribute("name"),
|
||||||
|
version = readManifestAttribute("version"),
|
||||||
|
description = readManifestAttribute("description"),
|
||||||
|
source = readManifestAttribute("source"),
|
||||||
|
author = readManifestAttribute("author"),
|
||||||
|
contact = readManifestAttribute("contact"),
|
||||||
|
website = readManifestAttribute("website"),
|
||||||
|
license = readManifestAttribute("license")
|
||||||
|
) else
|
||||||
|
null
|
||||||
|
|
||||||
|
private fun readManifestAttribute(name: String) = manifest?.mainAttributes?.getValue(name)?.takeIf { it.isNotBlank() } // If empty, set it to null instead.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load all patches compatible with the specified package.
|
* Load all patches compatible with the specified package.
|
||||||
@ -53,4 +77,4 @@ class PatchBundle(val patchesJar: File) {
|
|||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,9 @@ import android.os.Parcelable
|
|||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.activity.result.ActivityResult
|
import androidx.activity.result.ActivityResult
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.work.ForegroundInfo
|
import androidx.work.ForegroundInfo
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
|
import app.revanced.manager.MainActivity
|
||||||
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.data.room.apps.installed.InstallType
|
import app.revanced.manager.data.room.apps.installed.InstallType
|
||||||
@ -88,22 +88,25 @@ class PatcherWorker(
|
|||||||
)
|
)
|
||||||
|
|
||||||
private fun createNotification(): Notification {
|
private fun createNotification(): Notification {
|
||||||
val notificationIntent = Intent(applicationContext, PatcherWorker::class.java)
|
val notificationIntent = Intent(applicationContext, MainActivity::class.java).apply {
|
||||||
val pendingIntent: PendingIntent = PendingIntent.getActivity(
|
flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||||
|
}
|
||||||
|
val pendingIntent = PendingIntent.getActivity(
|
||||||
applicationContext, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
|
applicationContext, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
val channel = NotificationChannel(
|
val channel = NotificationChannel(
|
||||||
"revanced-patcher-patching", "Patching", NotificationManager.IMPORTANCE_HIGH
|
"revanced-patcher-patching", "Patching", NotificationManager.IMPORTANCE_LOW
|
||||||
)
|
)
|
||||||
val notificationManager =
|
val notificationManager =
|
||||||
ContextCompat.getSystemService(applicationContext, NotificationManager::class.java)
|
applicationContext.getSystemService(NotificationManager::class.java)
|
||||||
notificationManager!!.createNotificationChannel(channel)
|
notificationManager.createNotificationChannel(channel)
|
||||||
return Notification.Builder(applicationContext, channel.id)
|
return Notification.Builder(applicationContext, channel.id)
|
||||||
.setContentTitle(applicationContext.getText(R.string.app_name))
|
.setContentTitle(applicationContext.getText(R.string.patcher_notification_title))
|
||||||
.setContentText(applicationContext.getText(R.string.patcher_notification_message))
|
.setContentText(applicationContext.getText(R.string.patcher_notification_text))
|
||||||
.setLargeIcon(Icon.createWithResource(applicationContext, R.drawable.ic_notification))
|
|
||||||
.setSmallIcon(Icon.createWithResource(applicationContext, R.drawable.ic_notification))
|
.setSmallIcon(Icon.createWithResource(applicationContext, R.drawable.ic_notification))
|
||||||
.setContentIntent(pendingIntent).build()
|
.setContentIntent(pendingIntent)
|
||||||
|
.setCategory(Notification.CATEGORY_SERVICE)
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
@ -158,6 +161,8 @@ class PatcherWorker(
|
|||||||
data,
|
data,
|
||||||
args.packageName,
|
args.packageName,
|
||||||
args.input.version,
|
args.input.version,
|
||||||
|
prefs.suggestedVersionSafeguard.get(),
|
||||||
|
!prefs.disablePatchVersionCompatCheck.get(),
|
||||||
onDownload = args.onDownloadProgress
|
onDownload = args.onDownloadProgress
|
||||||
).also {
|
).also {
|
||||||
args.setInputFile(it)
|
args.setInputFile(it)
|
||||||
|
@ -30,7 +30,7 @@ fun ExceptionViewerDialog(text: String, onDismiss: () -> Unit) {
|
|||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
BundleTopBar(
|
BundleTopBar(
|
||||||
title = stringResource(R.string.bundle_error),
|
title = stringResource(R.string.patches_error),
|
||||||
onBackClick = onDismiss,
|
onBackClick = onDismiss,
|
||||||
backIcon = {
|
backIcon = {
|
||||||
Icon(
|
Icon(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package app.revanced.manager.ui.component
|
package app.revanced.manager.ui.component
|
||||||
|
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
@ -9,6 +10,7 @@ import androidx.compose.ui.platform.LocalView
|
|||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
import androidx.compose.ui.window.DialogWindowProvider
|
import androidx.compose.ui.window.DialogWindowProvider
|
||||||
|
import androidx.core.view.WindowCompat
|
||||||
|
|
||||||
private val properties = DialogProperties(
|
private val properties = DialogProperties(
|
||||||
usePlatformDefaultWidth = false,
|
usePlatformDefaultWidth = false,
|
||||||
@ -22,11 +24,17 @@ fun FullscreenDialog(onDismissRequest: () -> Unit, content: @Composable () -> Un
|
|||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
properties = properties
|
properties = properties
|
||||||
) {
|
) {
|
||||||
val window = (LocalView.current.parent as DialogWindowProvider).window
|
val view = LocalView.current
|
||||||
LaunchedEffect(Unit) {
|
val isDarkTheme = isSystemInDarkTheme()
|
||||||
|
LaunchedEffect(isDarkTheme) {
|
||||||
|
val window = (view.parent as DialogWindowProvider).window
|
||||||
window.statusBarColor = Color.Transparent.toArgb()
|
window.statusBarColor = Color.Transparent.toArgb()
|
||||||
window.navigationBarColor = Color.Transparent.toArgb()
|
window.navigationBarColor = Color.Transparent.toArgb()
|
||||||
window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
|
window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
|
||||||
|
|
||||||
|
val insetsController = WindowCompat.getInsetsController(window, view)
|
||||||
|
insetsController.isAppearanceLightStatusBars = !isDarkTheme
|
||||||
|
insetsController.isAppearanceLightNavigationBars = !isDarkTheme
|
||||||
}
|
}
|
||||||
|
|
||||||
content()
|
content()
|
||||||
|
@ -2,13 +2,26 @@ package app.revanced.manager.ui.component.bundle
|
|||||||
|
|
||||||
import android.webkit.URLUtil
|
import android.webkit.URLUtil
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.outlined.ArrowRight
|
import androidx.compose.material.icons.automirrored.outlined.ArrowRight
|
||||||
import androidx.compose.material.icons.outlined.Extension
|
import androidx.compose.material.icons.automirrored.outlined.Send
|
||||||
import androidx.compose.material.icons.outlined.Inventory2
|
import androidx.compose.material.icons.outlined.Commit
|
||||||
|
import androidx.compose.material.icons.outlined.Description
|
||||||
|
import androidx.compose.material.icons.outlined.Gavel
|
||||||
|
import androidx.compose.material.icons.outlined.Language
|
||||||
|
import androidx.compose.material.icons.outlined.Person
|
||||||
import androidx.compose.material.icons.outlined.Sell
|
import androidx.compose.material.icons.outlined.Sell
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@ -17,10 +30,11 @@ 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.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
|
import app.revanced.manager.patcher.patch.PatchBundleManifestAttributes
|
||||||
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
||||||
import app.revanced.manager.ui.component.TextInputDialog
|
import app.revanced.manager.ui.component.TextInputDialog
|
||||||
import app.revanced.manager.ui.component.haptics.HapticSwitch
|
import app.revanced.manager.ui.component.haptics.HapticSwitch
|
||||||
@ -29,12 +43,12 @@ import app.revanced.manager.ui.component.haptics.HapticSwitch
|
|||||||
fun BaseBundleDialog(
|
fun BaseBundleDialog(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
isDefault: Boolean,
|
isDefault: Boolean,
|
||||||
name: String?,
|
|
||||||
remoteUrl: String?,
|
remoteUrl: String?,
|
||||||
onRemoteUrlChange: ((String) -> Unit)? = null,
|
onRemoteUrlChange: ((String) -> Unit)? = null,
|
||||||
patchCount: Int,
|
patchCount: Int,
|
||||||
version: String?,
|
version: String?,
|
||||||
autoUpdate: Boolean,
|
autoUpdate: Boolean,
|
||||||
|
bundleManifestAttributes: PatchBundleManifestAttributes?,
|
||||||
onAutoUpdateChange: (Boolean) -> Unit,
|
onAutoUpdateChange: (Boolean) -> Unit,
|
||||||
onPatchesClick: () -> Unit,
|
onPatchesClick: () -> Unit,
|
||||||
extraFields: @Composable ColumnScope.() -> Unit = {}
|
extraFields: @Composable ColumnScope.() -> Unit = {}
|
||||||
@ -48,35 +62,26 @@ fun BaseBundleDialog(
|
|||||||
modifier = Modifier.padding(16.dp),
|
modifier = Modifier.padding(16.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
) {
|
) {
|
||||||
Row(
|
version?.let {
|
||||||
modifier = Modifier.fillMaxWidth(),
|
Tag(Icons.Outlined.Sell, it)
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.Start),
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Outlined.Inventory2,
|
|
||||||
contentDescription = null,
|
|
||||||
tint = MaterialTheme.colorScheme.primary,
|
|
||||||
modifier = Modifier.size(32.dp)
|
|
||||||
)
|
|
||||||
name?.let {
|
|
||||||
Text(
|
|
||||||
text = it,
|
|
||||||
style = MaterialTheme.typography.titleLarge.copy(fontWeight = FontWeight(800)),
|
|
||||||
color = MaterialTheme.colorScheme.primary,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Row(
|
bundleManifestAttributes?.description?.let {
|
||||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
Tag(Icons.Outlined.Description, it)
|
||||||
modifier = Modifier
|
}
|
||||||
.fillMaxWidth()
|
bundleManifestAttributes?.source?.let {
|
||||||
.padding(start = 2.dp)
|
Tag(Icons.Outlined.Commit, it)
|
||||||
) {
|
}
|
||||||
version?.let {
|
bundleManifestAttributes?.author?.let {
|
||||||
Tag(Icons.Outlined.Sell, it)
|
Tag(Icons.Outlined.Person, it)
|
||||||
}
|
}
|
||||||
Tag(Icons.Outlined.Extension, patchCount.toString())
|
bundleManifestAttributes?.contact?.let {
|
||||||
|
Tag(Icons.AutoMirrored.Outlined.Send, it)
|
||||||
|
}
|
||||||
|
bundleManifestAttributes?.website?.let {
|
||||||
|
Tag(Icons.Outlined.Language, it, isUrl = true)
|
||||||
|
}
|
||||||
|
bundleManifestAttributes?.license?.let {
|
||||||
|
Tag(Icons.Outlined.Gavel, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,8 +92,8 @@ fun BaseBundleDialog(
|
|||||||
|
|
||||||
if (remoteUrl != null) {
|
if (remoteUrl != null) {
|
||||||
BundleListItem(
|
BundleListItem(
|
||||||
headlineText = stringResource(R.string.bundle_auto_update),
|
headlineText = stringResource(R.string.auto_update),
|
||||||
supportingText = stringResource(R.string.bundle_auto_update_description),
|
supportingText = stringResource(R.string.auto_update_description),
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
HapticSwitch(
|
HapticSwitch(
|
||||||
checked = autoUpdate,
|
checked = autoUpdate,
|
||||||
@ -108,7 +113,7 @@ fun BaseBundleDialog(
|
|||||||
if (showUrlInputDialog) {
|
if (showUrlInputDialog) {
|
||||||
TextInputDialog(
|
TextInputDialog(
|
||||||
initial = url,
|
initial = url,
|
||||||
title = stringResource(R.string.bundle_input_source_url),
|
title = stringResource(R.string.patches_url),
|
||||||
onDismissRequest = { showUrlInputDialog = false },
|
onDismissRequest = { showUrlInputDialog = false },
|
||||||
onConfirm = {
|
onConfirm = {
|
||||||
showUrlInputDialog = false
|
showUrlInputDialog = false
|
||||||
@ -129,7 +134,7 @@ fun BaseBundleDialog(
|
|||||||
showUrlInputDialog = true
|
showUrlInputDialog = true
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
headlineText = stringResource(R.string.bundle_input_source_url),
|
headlineText = stringResource(R.string.patches_url),
|
||||||
supportingText = url.ifEmpty {
|
supportingText = url.ifEmpty {
|
||||||
stringResource(R.string.field_not_set)
|
stringResource(R.string.field_not_set)
|
||||||
}
|
}
|
||||||
@ -139,7 +144,7 @@ fun BaseBundleDialog(
|
|||||||
val patchesClickable = patchCount > 0
|
val patchesClickable = patchCount > 0
|
||||||
BundleListItem(
|
BundleListItem(
|
||||||
headlineText = stringResource(R.string.patches),
|
headlineText = stringResource(R.string.patches),
|
||||||
supportingText = stringResource(R.string.bundle_view_patches),
|
supportingText = stringResource(R.string.view_patches),
|
||||||
modifier = Modifier.clickable(
|
modifier = Modifier.clickable(
|
||||||
enabled = patchesClickable,
|
enabled = patchesClickable,
|
||||||
onClick = onPatchesClick
|
onClick = onPatchesClick
|
||||||
@ -160,22 +165,34 @@ fun BaseBundleDialog(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun Tag(
|
private fun Tag(
|
||||||
icon: ImageVector,
|
icon: ImageVector,
|
||||||
text: String
|
text: String,
|
||||||
|
isUrl: Boolean = false
|
||||||
) {
|
) {
|
||||||
|
val uriHandler = LocalUriHandler.current
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = if (isUrl) {
|
||||||
|
Modifier
|
||||||
|
.clickable {
|
||||||
|
try {
|
||||||
|
uriHandler.openUri(text)
|
||||||
|
} catch (_: Exception) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Modifier,
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = icon,
|
imageVector = icon,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier.size(16.dp),
|
modifier = Modifier.size(16.dp)
|
||||||
tint = MaterialTheme.colorScheme.outline,
|
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text,
|
text,
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
color = MaterialTheme.colorScheme.outline,
|
color = if(isUrl) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -44,13 +44,14 @@ fun BundleInformationDialog(
|
|||||||
}.collectAsStateWithLifecycle(null)
|
}.collectAsStateWithLifecycle(null)
|
||||||
val patchCount by bundle.patchCountFlow.collectAsStateWithLifecycle(0)
|
val patchCount by bundle.patchCountFlow.collectAsStateWithLifecycle(0)
|
||||||
val version by bundle.versionFlow.collectAsStateWithLifecycle(null)
|
val version by bundle.versionFlow.collectAsStateWithLifecycle(null)
|
||||||
|
val bundleManifestAttributes = state.patchBundleOrNull()?.patchBundleManifestAttributes
|
||||||
|
|
||||||
if (viewCurrentBundlePatches) {
|
if (viewCurrentBundlePatches) {
|
||||||
BundlePatchesDialog(
|
BundlePatchesDialog(
|
||||||
onDismissRequest = {
|
onDismissRequest = {
|
||||||
viewCurrentBundlePatches = false
|
viewCurrentBundlePatches = false
|
||||||
},
|
},
|
||||||
bundle = bundle,
|
bundle = bundle
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ fun BundleInformationDialog(
|
|||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
BundleTopBar(
|
BundleTopBar(
|
||||||
title = stringResource(R.string.patch_bundle_field),
|
title = bundleName,
|
||||||
onBackClick = onDismissRequest,
|
onBackClick = onDismissRequest,
|
||||||
backIcon = {
|
backIcon = {
|
||||||
Icon(
|
Icon(
|
||||||
@ -94,11 +95,11 @@ fun BundleInformationDialog(
|
|||||||
BaseBundleDialog(
|
BaseBundleDialog(
|
||||||
modifier = Modifier.padding(paddingValues),
|
modifier = Modifier.padding(paddingValues),
|
||||||
isDefault = bundle.isDefault,
|
isDefault = bundle.isDefault,
|
||||||
name = bundleName,
|
|
||||||
remoteUrl = bundle.asRemoteOrNull?.endpoint,
|
remoteUrl = bundle.asRemoteOrNull?.endpoint,
|
||||||
patchCount = patchCount,
|
patchCount = patchCount,
|
||||||
version = version,
|
version = version,
|
||||||
autoUpdate = props?.autoUpdate == true,
|
autoUpdate = props?.autoUpdate == true,
|
||||||
|
bundleManifestAttributes = bundleManifestAttributes,
|
||||||
onAutoUpdateChange = {
|
onAutoUpdateChange = {
|
||||||
composableScope.launch {
|
composableScope.launch {
|
||||||
bundle.asRemoteOrNull?.setAutoUpdate(it)
|
bundle.asRemoteOrNull?.setAutoUpdate(it)
|
||||||
@ -118,8 +119,8 @@ fun BundleInformationDialog(
|
|||||||
)
|
)
|
||||||
|
|
||||||
BundleListItem(
|
BundleListItem(
|
||||||
headlineText = stringResource(R.string.bundle_error),
|
headlineText = stringResource(R.string.patches_error),
|
||||||
supportingText = stringResource(R.string.bundle_error_description),
|
supportingText = stringResource(R.string.patches_error_description),
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.AutoMirrored.Outlined.ArrowRight,
|
Icons.AutoMirrored.Outlined.ArrowRight,
|
||||||
@ -132,8 +133,8 @@ fun BundleInformationDialog(
|
|||||||
|
|
||||||
if (state is PatchBundleSource.State.Missing && !isLocal) {
|
if (state is PatchBundleSource.State.Missing && !isLocal) {
|
||||||
BundleListItem(
|
BundleListItem(
|
||||||
headlineText = stringResource(R.string.bundle_error),
|
headlineText = stringResource(R.string.patches_error),
|
||||||
supportingText = stringResource(R.string.bundle_not_downloaded),
|
supportingText = stringResource(R.string.patches_not_downloaded),
|
||||||
modifier = Modifier.clickable(onClick = onUpdate)
|
modifier = Modifier.clickable(onClick = onUpdate)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,8 @@ fun BundleItem(
|
|||||||
onDelete()
|
onDelete()
|
||||||
viewBundleDialogPage = false
|
viewBundleDialogPage = false
|
||||||
},
|
},
|
||||||
title = stringResource(R.string.bundle_delete_single_dialog_title),
|
title = stringResource(R.string.delete),
|
||||||
description = stringResource(R.string.bundle_delete_single_dialog_description, name),
|
description = stringResource(R.string.patches_delete_single_dialog_description, name),
|
||||||
icon = Icons.Outlined.Delete
|
icon = Icons.Outlined.Delete
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -100,8 +100,8 @@ fun BundleItem(
|
|||||||
Row {
|
Row {
|
||||||
val icon = remember(state) {
|
val icon = remember(state) {
|
||||||
when (state) {
|
when (state) {
|
||||||
is PatchBundleSource.State.Failed -> Icons.Outlined.ErrorOutline to R.string.bundle_error
|
is PatchBundleSource.State.Failed -> Icons.Outlined.ErrorOutline to R.string.patches_error
|
||||||
is PatchBundleSource.State.Missing -> Icons.Outlined.Warning to R.string.bundle_missing
|
is PatchBundleSource.State.Missing -> Icons.Outlined.Warning to R.string.patches_missing
|
||||||
is PatchBundleSource.State.Loaded -> null
|
is PatchBundleSource.State.Loaded -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ fun BundlePatchesDialog(
|
|||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
BundleTopBar(
|
BundleTopBar(
|
||||||
title = stringResource(R.string.bundle_patches),
|
title = stringResource(R.string.patches),
|
||||||
onBackClick = onDismissRequest,
|
onBackClick = onDismissRequest,
|
||||||
backIcon = {
|
backIcon = {
|
||||||
Icon(
|
Icon(
|
||||||
@ -133,10 +133,10 @@ fun PatchItem(
|
|||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
PatchInfoChip(
|
PatchInfoChip(
|
||||||
text = "$PACKAGE_ICON ${stringResource(R.string.bundle_view_patches_any_package)}"
|
text = "$PACKAGE_ICON ${stringResource(R.string.patches_view_any_package)}"
|
||||||
)
|
)
|
||||||
PatchInfoChip(
|
PatchInfoChip(
|
||||||
text = "$VERSION_ICON ${stringResource(R.string.bundle_view_patches_any_version)}"
|
text = "$VERSION_ICON ${stringResource(R.string.patches_view_any_version)}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -13,14 +13,14 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
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.domain.bundles.PatchBundleSource
|
import app.revanced.manager.domain.bundles.PatchBundleSource
|
||||||
import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.nameState
|
import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.nameState
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@ -50,7 +50,7 @@ fun BundleSelector(bundles: List<PatchBundleSource>, onFinish: (PatchBundleSourc
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = "Select bundle",
|
text = stringResource(R.string.select),
|
||||||
style = MaterialTheme.typography.titleLarge,
|
style = MaterialTheme.typography.titleLarge,
|
||||||
color = MaterialTheme.colorScheme.onSurface
|
color = MaterialTheme.colorScheme.onSurface
|
||||||
)
|
)
|
||||||
|
@ -77,7 +77,7 @@ fun ImportPatchBundleDialog(
|
|||||||
AlertDialogExtended(
|
AlertDialogExtended(
|
||||||
onDismissRequest = onDismiss,
|
onDismissRequest = onDismiss,
|
||||||
title = {
|
title = {
|
||||||
Text(stringResource(if (currentStep == 0) R.string.select else R.string.add_patch_bundle))
|
Text(stringResource(if (currentStep == 0) R.string.select else R.string.add_patches))
|
||||||
},
|
},
|
||||||
text = {
|
text = {
|
||||||
steps[currentStep]()
|
steps[currentStep]()
|
||||||
@ -126,7 +126,7 @@ fun SelectBundleTypeStep(
|
|||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.padding(horizontal = 24.dp),
|
modifier = Modifier.padding(horizontal = 24.dp),
|
||||||
text = stringResource(R.string.select_bundle_type_dialog_description)
|
text = stringResource(R.string.select_patches_type_dialog_description)
|
||||||
)
|
)
|
||||||
Column {
|
Column {
|
||||||
ListItem(
|
ListItem(
|
||||||
@ -136,7 +136,7 @@ fun SelectBundleTypeStep(
|
|||||||
),
|
),
|
||||||
headlineContent = { Text(stringResource(R.string.enter_url)) },
|
headlineContent = { Text(stringResource(R.string.enter_url)) },
|
||||||
overlineContent = { Text(stringResource(R.string.recommended)) },
|
overlineContent = { Text(stringResource(R.string.recommended)) },
|
||||||
supportingContent = { Text(stringResource(R.string.remote_bundle_description)) },
|
supportingContent = { Text(stringResource(R.string.remote_patches_description)) },
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
HapticRadioButton(
|
HapticRadioButton(
|
||||||
selected = bundleType == BundleType.Remote,
|
selected = bundleType == BundleType.Remote,
|
||||||
@ -152,7 +152,7 @@ fun SelectBundleTypeStep(
|
|||||||
onClick = { onBundleTypeSelected(BundleType.Local) }
|
onClick = { onBundleTypeSelected(BundleType.Local) }
|
||||||
),
|
),
|
||||||
headlineContent = { Text(stringResource(R.string.select_from_storage)) },
|
headlineContent = { Text(stringResource(R.string.select_from_storage)) },
|
||||||
supportingContent = { Text(stringResource(R.string.local_bundle_description)) },
|
supportingContent = { Text(stringResource(R.string.local_patches_description)) },
|
||||||
overlineContent = { },
|
overlineContent = { },
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
HapticRadioButton(
|
HapticRadioButton(
|
||||||
@ -185,7 +185,7 @@ fun ImportBundleStep(
|
|||||||
) {
|
) {
|
||||||
ListItem(
|
ListItem(
|
||||||
headlineContent = {
|
headlineContent = {
|
||||||
Text(stringResource(R.string.patch_bundle_field))
|
Text(stringResource(R.string.patches))
|
||||||
},
|
},
|
||||||
supportingContent = { Text(stringResource(if (patchBundle != null) R.string.file_field_set else R.string.file_field_not_set)) },
|
supportingContent = { Text(stringResource(if (patchBundle != null) R.string.file_field_set else R.string.file_field_not_set)) },
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
@ -206,11 +206,11 @@ fun ImportBundleStep(
|
|||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = remoteUrl,
|
value = remoteUrl,
|
||||||
onValueChange = onRemoteUrlChange,
|
onValueChange = onRemoteUrlChange,
|
||||||
label = { Text(stringResource(R.string.bundle_url)) }
|
label = { Text(stringResource(R.string.patches_url)) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.padding(horizontal = 8.dp)
|
modifier = Modifier.padding(horizontal = 8.dp, vertical = 5.dp)
|
||||||
) {
|
) {
|
||||||
ListItem(
|
ListItem(
|
||||||
modifier = Modifier.clickable(
|
modifier = Modifier.clickable(
|
||||||
|
@ -9,6 +9,7 @@ import androidx.compose.material3.SwitchDefaults
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HapticSwitch(
|
fun HapticSwitch(
|
||||||
@ -20,16 +21,19 @@ fun HapticSwitch(
|
|||||||
colors: SwitchColors = SwitchDefaults.colors(),
|
colors: SwitchColors = SwitchDefaults.colors(),
|
||||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||||
) {
|
) {
|
||||||
|
val view = LocalView.current
|
||||||
Switch(
|
Switch(
|
||||||
checked = checked,
|
checked = checked,
|
||||||
onCheckedChange = { newChecked ->
|
onCheckedChange = { newChecked ->
|
||||||
val useNewConstants = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
|
val useNewConstants = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
|
||||||
when {
|
val hapticFeedbackType = when {
|
||||||
newChecked && useNewConstants -> HapticFeedbackConstants.TOGGLE_ON
|
newChecked && useNewConstants -> HapticFeedbackConstants.TOGGLE_ON
|
||||||
newChecked -> HapticFeedbackConstants.VIRTUAL_KEY
|
newChecked -> HapticFeedbackConstants.VIRTUAL_KEY
|
||||||
!newChecked && useNewConstants -> HapticFeedbackConstants.TOGGLE_OFF
|
!newChecked && useNewConstants -> HapticFeedbackConstants.TOGGLE_OFF
|
||||||
!newChecked -> HapticFeedbackConstants.CLOCK_TICK
|
!newChecked -> HapticFeedbackConstants.CLOCK_TICK
|
||||||
|
else -> {HapticFeedbackConstants.VIRTUAL_KEY}
|
||||||
}
|
}
|
||||||
|
view.performHapticFeedback(hapticFeedbackType)
|
||||||
onCheckedChange(newChecked)
|
onCheckedChange(newChecked)
|
||||||
},
|
},
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
@ -23,8 +23,6 @@ data class BundleInfo(
|
|||||||
yieldAll(universal)
|
yieldAll(universal)
|
||||||
}
|
}
|
||||||
|
|
||||||
val patchCount get() = compatible.size + incompatible.size + universal.size
|
|
||||||
|
|
||||||
fun patchSequence(allowIncompatible: Boolean) = if (allowIncompatible) {
|
fun patchSequence(allowIncompatible: Boolean) = if (allowIncompatible) {
|
||||||
all
|
all
|
||||||
} else {
|
} else {
|
||||||
@ -79,7 +77,7 @@ data class BundleInfo(
|
|||||||
targetList.add(it)
|
targetList.add(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
BundleInfo(source.getName(), bundle.readManifestAttribute("Version"), source.uid, compatible, incompatible, universal)
|
BundleInfo(source.getName(), bundle.patchBundleManifestAttributes?.version, source.uid, compatible, incompatible, universal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ enum class DashboardPage(
|
|||||||
val icon: ImageVector
|
val icon: ImageVector
|
||||||
) {
|
) {
|
||||||
DASHBOARD(R.string.tab_apps, Icons.Outlined.Apps),
|
DASHBOARD(R.string.tab_apps, Icons.Outlined.Apps),
|
||||||
BUNDLES(R.string.tab_bundles, Icons.Outlined.Source),
|
BUNDLES(R.string.tab_patches, Icons.Outlined.Source),
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("BatteryLife")
|
@SuppressLint("BatteryLife")
|
||||||
@ -93,7 +93,7 @@ fun DashboardScreen(
|
|||||||
onDownloaderPluginClick: () -> Unit,
|
onDownloaderPluginClick: () -> Unit,
|
||||||
onAppClick: (String) -> Unit
|
onAppClick: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
val bundlesSelectable by remember { derivedStateOf { vm.selectedSources.size > 0 } }
|
val bundlesSelectable by remember { derivedStateOf { vm.selectedSources.isNotEmpty() } }
|
||||||
val availablePatches by vm.availablePatches.collectAsStateWithLifecycle(0)
|
val availablePatches by vm.availablePatches.collectAsStateWithLifecycle(0)
|
||||||
val showNewDownloaderPluginsNotification by vm.newDownloaderPluginsAvailable.collectAsStateWithLifecycle(
|
val showNewDownloaderPluginsNotification by vm.newDownloaderPluginsAvailable.collectAsStateWithLifecycle(
|
||||||
false
|
false
|
||||||
@ -164,8 +164,8 @@ fun DashboardScreen(
|
|||||||
vm.selectedSources.forEach { if (!it.isDefault) vm.delete(it) }
|
vm.selectedSources.forEach { if (!it.isDefault) vm.delete(it) }
|
||||||
vm.cancelSourceSelection()
|
vm.cancelSourceSelection()
|
||||||
},
|
},
|
||||||
title = stringResource(R.string.bundle_delete_multiple_dialog_title),
|
title = stringResource(R.string.delete),
|
||||||
description = stringResource(R.string.bundle_delete_multiple_dialog_description),
|
description = stringResource(R.string.patches_delete_multiple_dialog_description),
|
||||||
icon = Icons.Outlined.Delete
|
icon = Icons.Outlined.Delete
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ fun DashboardScreen(
|
|||||||
topBar = {
|
topBar = {
|
||||||
if (bundlesSelectable) {
|
if (bundlesSelectable) {
|
||||||
BundleTopBar(
|
BundleTopBar(
|
||||||
title = stringResource(R.string.bundles_selected, vm.selectedSources.size),
|
title = stringResource(R.string.patches_selected, vm.selectedSources.size),
|
||||||
onBackClick = vm::cancelSourceSelection,
|
onBackClick = vm::cancelSourceSelection,
|
||||||
backIcon = {
|
backIcon = {
|
||||||
Icon(
|
Icon(
|
||||||
@ -239,7 +239,7 @@ fun DashboardScreen(
|
|||||||
when (pagerState.currentPage) {
|
when (pagerState.currentPage) {
|
||||||
DashboardPage.DASHBOARD.ordinal -> {
|
DashboardPage.DASHBOARD.ordinal -> {
|
||||||
if (availablePatches < 1) {
|
if (availablePatches < 1) {
|
||||||
androidContext.toast(androidContext.getString(R.string.patches_unavailable))
|
androidContext.toast(androidContext.getString(R.string.no_patch_found))
|
||||||
composableScope.launch {
|
composableScope.launch {
|
||||||
pagerState.animateScrollToPage(
|
pagerState.animateScrollToPage(
|
||||||
DashboardPage.BUNDLES.ordinal
|
DashboardPage.BUNDLES.ordinal
|
||||||
|
@ -389,6 +389,7 @@ fun PatchesSelectorScreen(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(paddingValues)
|
.padding(paddingValues)
|
||||||
|
.padding(top = 16.dp)
|
||||||
) {
|
) {
|
||||||
if (bundles.size > 1) {
|
if (bundles.size > 1) {
|
||||||
ScrollableTabRow(
|
ScrollableTabRow(
|
||||||
|
@ -48,13 +48,13 @@ fun DeveloperSettingsScreen(
|
|||||||
description = R.string.developer_options_description,
|
description = R.string.developer_options_description,
|
||||||
)
|
)
|
||||||
|
|
||||||
GroupHeader(stringResource(R.string.patch_bundles_section))
|
GroupHeader(stringResource(R.string.patches))
|
||||||
SettingsListItem(
|
SettingsListItem(
|
||||||
headlineContent = stringResource(R.string.patch_bundles_force_download),
|
headlineContent = stringResource(R.string.patches_force_download),
|
||||||
modifier = Modifier.clickable(onClick = vm::redownloadBundles)
|
modifier = Modifier.clickable(onClick = vm::redownloadBundles)
|
||||||
)
|
)
|
||||||
SettingsListItem(
|
SettingsListItem(
|
||||||
headlineContent = stringResource(R.string.patch_bundles_reset),
|
headlineContent = stringResource(R.string.patches_reset),
|
||||||
modifier = Modifier.clickable(onClick = vm::redownloadBundles)
|
modifier = Modifier.clickable(onClick = vm::redownloadBundles)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -240,8 +240,8 @@ fun ImportExportSettingsScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
headline = R.string.patch_selection_reset_bundle,
|
headline = R.string.patch_selection_reset_patches,
|
||||||
description = R.string.patch_selection_reset_bundle_description
|
description = R.string.patch_selection_reset_patches_description
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,8 +296,8 @@ fun ImportExportSettingsScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
headline = R.string.patch_options_reset_bundle,
|
headline = R.string.patch_options_reset,
|
||||||
description = R.string.patch_options_reset_bundle_description,
|
description = R.string.patch_options_reset_all,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import androidx.compose.ui.res.stringResource
|
|||||||
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.ColumnWithScrollbar
|
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
||||||
|
import app.revanced.manager.ui.component.GroupHeader
|
||||||
import app.revanced.manager.ui.component.settings.BooleanItem
|
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.UpdatesSettingsViewModel
|
import app.revanced.manager.ui.viewmodel.UpdatesSettingsViewModel
|
||||||
@ -50,6 +51,8 @@ fun UpdatesSettingsScreen(
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(paddingValues)
|
.padding(paddingValues)
|
||||||
) {
|
) {
|
||||||
|
GroupHeader(stringResource(R.string.manager))
|
||||||
|
|
||||||
SettingsListItem(
|
SettingsListItem(
|
||||||
modifier = Modifier.clickable {
|
modifier = Modifier.clickable {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
|
@ -135,13 +135,13 @@ class DashboardViewModel(
|
|||||||
|
|
||||||
uiSafe(
|
uiSafe(
|
||||||
app,
|
app,
|
||||||
R.string.source_download_fail,
|
R.string.patches_download_fail,
|
||||||
RemotePatchBundle.updateFailMsg
|
RemotePatchBundle.updateFailMsg
|
||||||
) {
|
) {
|
||||||
if (bundle.update())
|
if (bundle.update())
|
||||||
app.toast(app.getString(R.string.bundle_update_success, bundle.getName()))
|
app.toast(app.getString(R.string.patches_update_success, bundle.getName()))
|
||||||
else
|
else
|
||||||
app.toast(app.getString(R.string.bundle_update_unavailable, bundle.getName()))
|
app.toast(app.getString(R.string.patches_update_unavailable, bundle.getName()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,7 +16,7 @@ class DeveloperOptionsViewModel(
|
|||||||
private val patchBundleRepository: PatchBundleRepository
|
private val patchBundleRepository: PatchBundleRepository
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
fun redownloadBundles() = viewModelScope.launch {
|
fun redownloadBundles() = viewModelScope.launch {
|
||||||
uiSafe(app, R.string.source_download_fail, RemotePatchBundle.updateFailMsg) {
|
uiSafe(app, R.string.patches_download_fail, RemotePatchBundle.updateFailMsg) {
|
||||||
patchBundleRepository.redownloadRemoteBundles()
|
patchBundleRepository.redownloadRemoteBundles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,8 @@ sealed class ResetDialogState(
|
|||||||
)
|
)
|
||||||
|
|
||||||
class PatchSelectionBundle(dialogOptionName: String, onConfirm: () -> Unit) : ResetDialogState(
|
class PatchSelectionBundle(dialogOptionName: String, onConfirm: () -> Unit) : ResetDialogState(
|
||||||
titleResId = R.string.patch_selection_reset_bundle,
|
titleResId = R.string.patch_selection_reset_patches,
|
||||||
descriptionResId = R.string.patch_selection_reset_bundle_dialog_description,
|
descriptionResId = R.string.patch_selection_reset_patches_dialog_description,
|
||||||
onConfirm = onConfirm,
|
onConfirm = onConfirm,
|
||||||
dialogOptionName = dialogOptionName
|
dialogOptionName = dialogOptionName
|
||||||
)
|
)
|
||||||
@ -81,8 +81,8 @@ sealed class ResetDialogState(
|
|||||||
)
|
)
|
||||||
|
|
||||||
class PatchOptionBundle(dialogOptionName: String, onConfirm: () -> Unit) : ResetDialogState(
|
class PatchOptionBundle(dialogOptionName: String, onConfirm: () -> Unit) : ResetDialogState(
|
||||||
titleResId = R.string.patch_options_reset_bundle,
|
titleResId = R.string.patch_options_reset,
|
||||||
descriptionResId = R.string.patch_options_reset_bundle_dialog_description,
|
descriptionResId = R.string.patch_options_reset_dialog_description,
|
||||||
onConfirm = onConfirm,
|
onConfirm = onConfirm,
|
||||||
dialogOptionName = dialogOptionName
|
dialogOptionName = dialogOptionName
|
||||||
)
|
)
|
||||||
|
@ -14,26 +14,24 @@
|
|||||||
<string name="dashboard">Dashboard</string>
|
<string name="dashboard">Dashboard</string>
|
||||||
<string name="settings">Settings</string>
|
<string name="settings">Settings</string>
|
||||||
<string name="select_app">Select an app</string>
|
<string name="select_app">Select an app</string>
|
||||||
<string name="patches_selected">%1$d/%2$d selected</string>
|
<string name="patches_count_selected">%1$d/%2$d selected</string>
|
||||||
|
|
||||||
<string name="new_downloader_plugins_notification">New downloader plugins available. Click here to configure them.</string>
|
<string name="new_downloader_plugins_notification">New downloader plugins available. Click here to configure them.</string>
|
||||||
<string name="unsupported_architecture_warning">Patching on this device architecture is unsupported and will most likely fail.</string>
|
<string name="unsupported_architecture_warning">Patching on this device architecture is unsupported and will most likely fail.</string>
|
||||||
|
|
||||||
<string name="import_">Import</string>
|
<string name="import_">Import</string>
|
||||||
<string name="import_bundle">Import patch bundle</string>
|
<string name="import_patches">Import patches</string>
|
||||||
<string name="bundle_patches">Bundle patches</string>
|
|
||||||
<string name="patch_bundle_field">Patch bundle</string>
|
|
||||||
<string name="file_field_set">Selected</string>
|
<string name="file_field_set">Selected</string>
|
||||||
<string name="file_field_not_set">Not selected</string>
|
<string name="file_field_not_set">Not selected</string>
|
||||||
|
|
||||||
<string name="field_not_set">Not set</string>
|
<string name="field_not_set">Not set</string>
|
||||||
|
|
||||||
<string name="bundle_missing">Missing</string>
|
<string name="patches_missing">Missing</string>
|
||||||
<string name="bundle_error">Error</string>
|
<string name="patches_error">Error</string>
|
||||||
<string name="bundle_error_description">Bundle could not be loaded. Click to view the error</string>
|
<string name="patches_error_description">Patches could not be loaded. Click to view the error</string>
|
||||||
<string name="bundle_not_downloaded">Bundle has not been downloaded. Click here to download it</string>
|
<string name="patches_not_downloaded">Patches has not been downloaded. Click here to download it</string>
|
||||||
<string name="bundle_name_default">Default</string>
|
<string name="patches_name_default">Patches</string>
|
||||||
<string name="bundle_name_fallback">Unnamed</string>
|
<string name="patches_name_fallback">Unnamed</string>
|
||||||
|
|
||||||
<string name="android_11_bug_dialog_title">Android 11 bug</string>
|
<string name="android_11_bug_dialog_title">Android 11 bug</string>
|
||||||
<string name="android_11_bug_dialog_description">The app installation permission must be granted ahead of time to avoid a bug in the Android 11 system that will negatively affect the user experience.</string>
|
<string name="android_11_bug_dialog_description">The app installation permission must be granted ahead of time to avoid a bug in the Android 11 system that will negatively affect the user experience.</string>
|
||||||
@ -139,16 +137,15 @@
|
|||||||
<string name="patch_selection_reset_package">Reset patch selection for app</string>
|
<string name="patch_selection_reset_package">Reset patch selection for app</string>
|
||||||
<string name="patch_selection_reset_package_dialog_description">You are about to reset the patch selection for the app \"%s\". You will have to manually select each patch again.</string>
|
<string name="patch_selection_reset_package_dialog_description">You are about to reset the patch selection for the app \"%s\". You will have to manually select each patch again.</string>
|
||||||
<string name="patch_selection_reset_package_description">Resets patch selection for a single app</string>
|
<string name="patch_selection_reset_package_description">Resets patch selection for a single app</string>
|
||||||
<string name="patch_selection_reset_bundle">Resets patch selection for bundle</string>
|
<string name="patch_selection_reset_patches">Resets patch selection for a specific patches</string>
|
||||||
<string name="patch_selection_reset_bundle_dialog_description">You are about to reset the patch selection for the bundle \"%s\". You will have to manually select each patch again.</string>
|
<string name="patch_selection_reset_patches_dialog_description">You are about to reset the patch selection for \"%s\". You will have to manually select each patch again.</string>
|
||||||
<string name="patch_selection_reset_bundle_description">Resets the patch selection for all patches in a bundle</string>
|
<string name="patch_selection_reset_patches_description">Resets the patch selection for a specific patches</string>
|
||||||
<string name="patch_options_reset_package">Reset patch options for app</string>
|
<string name="patch_options_reset_package">Reset patch options for app</string>
|
||||||
<string name="patch_options_reset_package_dialog_description">You are about to reset the patch options for the app \"%s\". You will have to reapply each option again.</string>
|
<string name="patch_options_reset_package_dialog_description">You are about to reset the patch options for the app \"%s\". You will have to reapply each option again.</string>
|
||||||
<string name="patch_options_reset_package_description">Resets patch options for a single app</string>
|
<string name="patch_options_reset_package_description">Resets patch options for a single app</string>
|
||||||
<string name="patch_options_reset_bundle">Resets patch options for bundle</string>
|
<string name="patch_options_reset">Reset patch options</string>
|
||||||
<string name="patch_options_reset_bundle_dialog_description">You are about to reset the patch options for the bundle \"%s\". You will have to reapply each option again.</string>
|
<string name="patch_options_reset_dialog_description">You are about to reset the patch options for \"%s\". You will have to reapply each option again.</string>
|
||||||
<string name="patch_options_reset_bundle_description">Resets patch options for all patches in a bundle</string>
|
<string name="patch_options_reset_all">Reset patch options for all</string>
|
||||||
<string name="patch_options_reset_all">Reset patch options</string>
|
|
||||||
<string name="patch_options_reset_all_dialog_description">You are about to reset patch options. You will have to reapply each option again.</string>
|
<string name="patch_options_reset_all_dialog_description">You are about to reset patch options. You will have to reapply each option again.</string>
|
||||||
<string name="patch_options_reset_all_description">Resets all patch options</string>
|
<string name="patch_options_reset_all_description">Resets all patch options</string>
|
||||||
<string name="downloader_plugins">Plugins</string>
|
<string name="downloader_plugins">Plugins</string>
|
||||||
@ -164,7 +161,7 @@
|
|||||||
|
|
||||||
<string name="search_apps">Search apps…</string>
|
<string name="search_apps">Search apps…</string>
|
||||||
<string name="loading_body">Loading…</string>
|
<string name="loading_body">Loading…</string>
|
||||||
<string name="downloading_patches">Downloading patch bundle…</string>
|
<string name="downloading_patches">Downloading patches…</string>
|
||||||
|
|
||||||
<string name="options">Options</string>
|
<string name="options">Options</string>
|
||||||
<string name="ok">OK</string>
|
<string name="ok">OK</string>
|
||||||
@ -202,8 +199,8 @@
|
|||||||
<string name="debug_logs_export_success">Exported logs</string>
|
<string name="debug_logs_export_success">Exported logs</string>
|
||||||
<string name="api_url">API URL</string>
|
<string name="api_url">API URL</string>
|
||||||
<string name="api_url_description">The API used to download necessary files.</string>
|
<string name="api_url_description">The API used to download necessary files.</string>
|
||||||
<string name="api_url_dialog_title">Set custom API URL</string>
|
<string name="api_url_dialog_title">Change API URL</string>
|
||||||
<string name="api_url_dialog_description">Set the API URL of ReVanced Manager. ReVanced Manager uses the API to download patches and updates.</string>
|
<string name="api_url_dialog_description">Change the API URL of ReVanced Manager. ReVanced Manager uses the API to download patches and updates.</string>
|
||||||
<string name="api_url_dialog_warning">ReVanced Manager connects to the API to download patches and updates. Make sure that you trust it.</string>
|
<string name="api_url_dialog_warning">ReVanced Manager connects to the API to download patches and updates. Make sure that you trust it.</string>
|
||||||
<string name="api_url_dialog_save">Set</string>
|
<string name="api_url_dialog_save">Set</string>
|
||||||
<string name="api_url_dialog_reset">Reset API URL</string>
|
<string name="api_url_dialog_reset">Reset API URL</string>
|
||||||
@ -213,26 +210,25 @@
|
|||||||
<string name="device_architectures">CPU Architectures</string>
|
<string name="device_architectures">CPU Architectures</string>
|
||||||
<string name="device_memory_limit">Memory limits</string>
|
<string name="device_memory_limit">Memory limits</string>
|
||||||
<string name="device_memory_limit_format">%1$dMB (Normal) - %2$dMB (Large)</string>
|
<string name="device_memory_limit_format">%1$dMB (Normal) - %2$dMB (Large)</string>
|
||||||
<string name="patch_bundles_section">Patch bundles</string>
|
<string name="patches_force_download">Force download all patches</string>
|
||||||
<string name="patch_bundles_force_download">Force download all patch bundles</string>
|
<string name="patches_reset">Reset patches</string>
|
||||||
<string name="patch_bundles_reset">Reset patch bundles</string>
|
|
||||||
<string name="patching">Patching</string>
|
<string name="patching">Patching</string>
|
||||||
<string name="signing">Signing</string>
|
<string name="signing">Signing</string>
|
||||||
<string name="storage">Storage</string>
|
<string name="storage">Storage</string>
|
||||||
<string name="patches_unavailable">No patches are available. Check your bundles</string>
|
<string name="no_patch_found">No patch can be found. Check your patches</string>
|
||||||
<string name="tab_apps">Apps</string>
|
<string name="tab_apps">Apps</string>
|
||||||
<string name="tab_bundles">Patch bundles</string>
|
<string name="tab_patches">Patches</string>
|
||||||
<string name="delete">Delete</string>
|
<string name="delete">Delete</string>
|
||||||
<string name="refresh">Refresh</string>
|
<string name="refresh">Refresh</string>
|
||||||
<string name="continue_anyways">Continue anyways</string>
|
<string name="continue_anyways">Continue anyways</string>
|
||||||
<string name="download_another_version">Download another version</string>
|
<string name="download_another_version">Download another version</string>
|
||||||
<string name="download_app">Download app</string>
|
<string name="download_app">Download app</string>
|
||||||
<string name="download_apk">Download APK file</string>
|
<string name="download_apk">Download APK file</string>
|
||||||
<string name="source_download_fail">Failed to download patch bundle: %s</string>
|
<string name="patches_download_fail">Failed to download patches: %s</string>
|
||||||
<string name="source_replace_fail">Failed to load updated patch bundle: %s</string>
|
<string name="patches_replace_fail">Failed to load updated patches: %s</string>
|
||||||
<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="patches_selected">%s selected</string>
|
||||||
<string name="incompatible_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>
|
||||||
@ -317,7 +313,8 @@
|
|||||||
<string name="patcher_step_group_saving">Saving</string>
|
<string name="patcher_step_group_saving">Saving</string>
|
||||||
<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_title">Patching in progress…</string>
|
||||||
|
<string name="patcher_notification_text">Tap to return to the patcher</string>
|
||||||
<string name="patcher_stop_confirm_title">Stop patcher</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="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>
|
||||||
@ -347,19 +344,13 @@
|
|||||||
<string name="submit_feedback_description">Help us improve this application</string>
|
<string name="submit_feedback_description">Help us improve this application</string>
|
||||||
<string name="developer_options">Developer options</string>
|
<string name="developer_options">Developer options</string>
|
||||||
<string name="developer_options_description">Options for debugging issues</string>
|
<string name="developer_options_description">Options for debugging issues</string>
|
||||||
<string name="bundle_input_source_url">Source URL</string>
|
<string name="patches_update_success">Successfully updated %s</string>
|
||||||
<string name="bundle_update_success">Successfully updated %s</string>
|
<string name="patches_update_unavailable">No update available for %s</string>
|
||||||
<string name="bundle_update_unavailable">No update available for %s</string>
|
<string name="view_patches">View patches</string>
|
||||||
<string name="bundle_auto_update">Auto update</string>
|
<string name="patches_view_any_version">Any version</string>
|
||||||
<string name="bundle_auto_update_description">Automatically update this bundle when ReVanced starts</string>
|
<string name="patches_view_any_package">Any package</string>
|
||||||
<string name="bundle_view_patches">View patches</string>
|
<string name="patches_delete_single_dialog_description">Are you sure you want to delete \"%s\"?</string>
|
||||||
<string name="bundle_view_patches_any_version">Any version</string>
|
<string name="patches_delete_multiple_dialog_description">Are you sure you want to delete the selected patches?</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 Android application that uses ReVanced Patcher to patch Android apps. It allows you to download and patch apps with custom patches, and manage the patching process.</string>
|
<string name="revanced_manager_description">ReVanced Manager is an Android application that uses ReVanced Patcher to patch Android apps. It allows you to download and patch apps with custom patches, and manage the patching process.</string>
|
||||||
@ -389,7 +380,7 @@
|
|||||||
<string name="save_with_count">Save (%1$s)</string>
|
<string name="save_with_count">Save (%1$s)</string>
|
||||||
<string name="update">Update</string>
|
<string name="update">Update</string>
|
||||||
<string name="empty">Empty</string>
|
<string name="empty">Empty</string>
|
||||||
<string name="installing_message">Tap on <b>Update</b> when prompted. \n ReVanced Manager will close when updating.</string>
|
<string name="installing_message">Tap on <b>Update</b> when prompted.\nReVanced Manager will close when updating.</string>
|
||||||
<string name="no_changelogs_found">No changelogs found</string>
|
<string name="no_changelogs_found">No changelogs found</string>
|
||||||
<string name="just_now">Just now</string>
|
<string name="just_now">Just now</string>
|
||||||
<string name="minutes_ago">%sm ago</string>
|
<string name="minutes_ago">%sm ago</string>
|
||||||
@ -413,10 +404,9 @@
|
|||||||
<string name="no_contributors_found">No contributors found</string>
|
<string name="no_contributors_found">No contributors found</string>
|
||||||
<string name="select">Select</string>
|
<string name="select">Select</string>
|
||||||
<string name="select_deselect_all">Select or deselect all</string>
|
<string name="select_deselect_all">Select or deselect all</string>
|
||||||
<string name="select_bundle_type_dialog_title">Add new bundle</string>
|
<string name="select_patches_type_dialog_description">Add new patches from URL or local files</string>
|
||||||
<string name="select_bundle_type_dialog_description">Add a new bundle from a URL or storage</string>
|
<string name="local_patches_description">Add patches from local storage.</string>
|
||||||
<string name="local_bundle_description">Import local files from your storage, does not automatically update</string>
|
<string name="remote_patches_description">Add patches from URL. Patches can automatically update.</string>
|
||||||
<string name="remote_bundle_description">Import remote files from a URL, can automatically update</string>
|
|
||||||
<string name="recommended">Recommended</string>
|
<string name="recommended">Recommended</string>
|
||||||
|
|
||||||
<string name="installation_failed_dialog_title">Installation failed</string>
|
<string name="installation_failed_dialog_title">Installation failed</string>
|
||||||
@ -441,9 +431,10 @@
|
|||||||
<string name="about_device">About device</string>
|
<string name="about_device">About device</string>
|
||||||
<string name="enter_url">Enter URL</string>
|
<string name="enter_url">Enter URL</string>
|
||||||
<string name="next">Next</string>
|
<string name="next">Next</string>
|
||||||
<string name="add_patch_bundle">Add patch bundle</string>
|
|
||||||
<string name="bundle_url">Bundle URL</string>
|
|
||||||
<string name="auto_update">Auto update</string>
|
<string name="auto_update">Auto update</string>
|
||||||
|
<string name="add_patches">Add patches</string>
|
||||||
|
<string name="auto_update_description">Automatically update when a new version is available</string>
|
||||||
|
<string name="patches_url">Patches URL</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="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="incompatible_patch">Incompatible patch</string>
|
<string name="incompatible_patch">Incompatible patch</string>
|
||||||
<string name="any_version">Any</string>
|
<string name="any_version">Any</string>
|
||||||
|
@ -7,12 +7,4 @@ plugins {
|
|||||||
alias(libs.plugins.kotlin.parcelize) apply false
|
alias(libs.plugins.kotlin.parcelize) apply false
|
||||||
alias(libs.plugins.about.libraries) apply false
|
alias(libs.plugins.about.libraries) apply false
|
||||||
alias(libs.plugins.compose.compiler) apply false
|
alias(libs.plugins.compose.compiler) apply false
|
||||||
alias(libs.plugins.spotless)
|
|
||||||
}
|
|
||||||
|
|
||||||
spotless {
|
|
||||||
kotlin {
|
|
||||||
target("app/src/*/java/**/*.kt", "api/src/*/kotlin/**/*.kt")
|
|
||||||
ktlint().setEditorConfigPath("$projectDir/.editorconfig")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,6 @@ compose-icons = "1.2.4"
|
|||||||
kotlin-process = "1.5.1"
|
kotlin-process = "1.5.1"
|
||||||
hidden-api-stub = "4.3.3"
|
hidden-api-stub = "4.3.3"
|
||||||
binary-compatibility-validator = "0.17.0"
|
binary-compatibility-validator = "0.17.0"
|
||||||
spotless-gradle-plugin = "7.0.4"
|
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
# AndroidX Core
|
# AndroidX Core
|
||||||
@ -145,4 +144,3 @@ compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "
|
|||||||
devtools = { id = "com.google.devtools.ksp", version.ref = "dev-tools-gradle-plugin" }
|
devtools = { id = "com.google.devtools.ksp", version.ref = "dev-tools-gradle-plugin" }
|
||||||
about-libraries = { id = "com.mikepenz.aboutlibraries.plugin", version.ref = "about-libraries-gradle-plugin" }
|
about-libraries = { id = "com.mikepenz.aboutlibraries.plugin", version.ref = "about-libraries-gradle-plugin" }
|
||||||
binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binary-compatibility-validator" }
|
binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binary-compatibility-validator" }
|
||||||
spotless = { id = "com.diffplug.spotless", version.ref = "spotless-gradle-plugin" }
|
|
||||||
|
Reference in New Issue
Block a user