mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2025-08-06 18:24:25 +08:00
Compare commits
9 Commits
build/opti
...
feat/compo
Author | SHA1 | Date | |
---|---|---|---|
a69b7ac73b | |||
ac2df7239e | |||
65bead3517 | |||
d6ff1e0b34 | |||
19908674f0 | |||
a15bb3e6b8 | |||
98722d5c24 | |||
6e4043c1e5 | |||
f30f233e71 |
5
.github/workflows/build_pull_request.yml
vendored
5
.github/workflows/build_pull_request.yml
vendored
@ -5,7 +5,6 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
- compose-dev
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
@ -14,9 +13,11 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Cache Gradle
|
- name: Cache Gradle
|
||||||
uses: burrunan/gradle-cache-action@v3
|
uses: burrunan/gradle-cache-action@v1
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
env:
|
env:
|
||||||
|
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@ -18,6 +18,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
@ -26,7 +28,7 @@ jobs:
|
|||||||
java-version: '17'
|
java-version: '17'
|
||||||
|
|
||||||
- name: Cache Gradle
|
- name: Cache Gradle
|
||||||
uses: burrunan/gradle-cache-action@v3
|
uses: burrunan/gradle-cache-action@v1
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
env:
|
env:
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
@ -82,10 +81,8 @@ android {
|
|||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlinOptions {
|
||||||
compilerOptions {
|
jvmTarget = "17"
|
||||||
jvmTarget = JvmTarget.fromTarget("17")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
@ -41,6 +40,10 @@ dependencies {
|
|||||||
// Placeholder
|
// Placeholder
|
||||||
implementation(libs.placeholder.material3)
|
implementation(libs.placeholder.material3)
|
||||||
|
|
||||||
|
// HTML Scraper
|
||||||
|
implementation(libs.skrapeit.dsl)
|
||||||
|
implementation(libs.skrapeit.parser)
|
||||||
|
|
||||||
// Coil (async image loading, network image)
|
// Coil (async image loading, network image)
|
||||||
implementation(libs.coil.compose)
|
implementation(libs.coil.compose)
|
||||||
implementation(libs.coil.appiconloader)
|
implementation(libs.coil.appiconloader)
|
||||||
@ -53,6 +56,7 @@ dependencies {
|
|||||||
// Room
|
// Room
|
||||||
implementation(libs.room.runtime)
|
implementation(libs.room.runtime)
|
||||||
implementation(libs.room.ktx)
|
implementation(libs.room.ktx)
|
||||||
|
annotationProcessor(libs.room.compiler)
|
||||||
ksp(libs.room.compiler)
|
ksp(libs.room.compiler)
|
||||||
|
|
||||||
// ReVanced
|
// ReVanced
|
||||||
@ -124,8 +128,6 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
configureEach {
|
|
||||||
}
|
|
||||||
debug {
|
debug {
|
||||||
applicationIdSuffix = ".debug"
|
applicationIdSuffix = ".debug"
|
||||||
resValue("string", "app_name", "ReVanced Manager (Debug)")
|
resValue("string", "app_name", "ReVanced Manager (Debug)")
|
||||||
@ -201,11 +203,8 @@ android {
|
|||||||
arg("room.schemaLocation", "$projectDir/schemas")
|
arg("room.schemaLocation", "$projectDir/schemas")
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlinOptions {
|
||||||
compilerOptions {
|
jvmTarget = "17"
|
||||||
jvmTarget = JvmTarget.fromTarget("17")
|
|
||||||
jvmToolchain(17)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
@ -228,6 +227,10 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvmToolchain(17)
|
||||||
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
// Needed by gradle-semantic-release-plugin.
|
// Needed by gradle-semantic-release-plugin.
|
||||||
// Tracking: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435.
|
// Tracking: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435.
|
||||||
|
7
app/proguard-rules.pro
vendored
7
app/proguard-rules.pro
vendored
@ -10,12 +10,7 @@
|
|||||||
# Required for serialization to work properly
|
# Required for serialization to work properly
|
||||||
-if @kotlinx.serialization.Serializable class **
|
-if @kotlinx.serialization.Serializable class **
|
||||||
-keepclassmembers class <1> {
|
-keepclassmembers class <1> {
|
||||||
static <1>$* Companion;
|
static <1>$Companion Companion;
|
||||||
}
|
|
||||||
-keepnames @kotlinx.serialization.internal.NamedCompanion class *
|
|
||||||
-if @kotlinx.serialization.internal.NamedCompanion class *
|
|
||||||
-keepclassmembernames class * {
|
|
||||||
static <1> *;
|
|
||||||
}
|
}
|
||||||
-if @kotlinx.serialization.Serializable class ** {
|
-if @kotlinx.serialization.Serializable class ** {
|
||||||
static **$* *;
|
static **$* *;
|
||||||
|
@ -8,6 +8,7 @@ import app.revanced.manager.util.tag
|
|||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.call.body
|
import io.ktor.client.call.body
|
||||||
import io.ktor.client.request.HttpRequestBuilder
|
import io.ktor.client.request.HttpRequestBuilder
|
||||||
|
import io.ktor.client.request.get
|
||||||
import io.ktor.client.request.prepareGet
|
import io.ktor.client.request.prepareGet
|
||||||
import io.ktor.client.request.request
|
import io.ktor.client.request.request
|
||||||
import io.ktor.client.statement.bodyAsText
|
import io.ktor.client.statement.bodyAsText
|
||||||
@ -16,6 +17,7 @@ import io.ktor.http.isSuccess
|
|||||||
import io.ktor.utils.io.ByteReadChannel
|
import io.ktor.utils.io.ByteReadChannel
|
||||||
import io.ktor.utils.io.core.isNotEmpty
|
import io.ktor.utils.io.core.isNotEmpty
|
||||||
import io.ktor.utils.io.core.readBytes
|
import io.ktor.utils.io.core.readBytes
|
||||||
|
import it.skrape.core.htmlDocument
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
@ -91,5 +93,9 @@ class HttpService(
|
|||||||
builder: HttpRequestBuilder.() -> Unit
|
builder: HttpRequestBuilder.() -> Unit
|
||||||
) = saveLocation.outputStream().use { streamTo(it, builder) }
|
) = saveLocation.outputStream().use { streamTo(it, builder) }
|
||||||
|
|
||||||
|
suspend fun getHtml(builder: HttpRequestBuilder.() -> Unit) = htmlDocument(
|
||||||
|
html = http.get(builder).bodyAsText()
|
||||||
|
)
|
||||||
|
|
||||||
class HttpException(status: HttpStatusCode) : Exception("Failed to fetch: http status: $status")
|
class HttpException(status: HttpStatusCode) : Exception("Failed to fetch: http status: $status")
|
||||||
}
|
}
|
@ -1,7 +1,6 @@
|
|||||||
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
|
||||||
@ -10,7 +9,6 @@ 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,
|
||||||
@ -24,17 +22,11 @@ fun FullscreenDialog(onDismissRequest: () -> Unit, content: @Composable () -> Un
|
|||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
properties = properties
|
properties = properties
|
||||||
) {
|
) {
|
||||||
val view = LocalView.current
|
val window = (LocalView.current.parent as DialogWindowProvider).window
|
||||||
val isDarkTheme = isSystemInDarkTheme()
|
LaunchedEffect(Unit) {
|
||||||
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()
|
||||||
|
@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.fillMaxHeight
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.LazyListItemInfo
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
@ -73,11 +74,13 @@ import app.revanced.manager.util.saver.snapshotStateListSaver
|
|||||||
import app.revanced.manager.util.saver.snapshotStateSetSaver
|
import app.revanced.manager.util.saver.snapshotStateSetSaver
|
||||||
import app.revanced.manager.util.toast
|
import app.revanced.manager.util.toast
|
||||||
import app.revanced.manager.util.transparentListItemColors
|
import app.revanced.manager.util.transparentListItemColors
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import org.koin.compose.koinInject
|
import org.koin.compose.koinInject
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
import org.koin.core.component.get
|
import org.koin.core.component.get
|
||||||
import sh.calvin.reorderable.ReorderableItem
|
import sh.calvin.reorderable.ReorderableItem
|
||||||
|
import sh.calvin.reorderable.rememberReorderableLazyColumnState
|
||||||
import sh.calvin.reorderable.rememberReorderableLazyListState
|
import sh.calvin.reorderable.rememberReorderableLazyListState
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
@ -88,28 +91,15 @@ private class OptionEditorScope<T : Any>(
|
|||||||
val option: Option<T>,
|
val option: Option<T>,
|
||||||
val openDialog: () -> Unit,
|
val openDialog: () -> Unit,
|
||||||
val dismissDialog: () -> Unit,
|
val dismissDialog: () -> Unit,
|
||||||
val selectionWarningEnabled: Boolean,
|
|
||||||
val showSelectionWarning: () -> Unit,
|
|
||||||
val value: T?,
|
val value: T?,
|
||||||
val setValue: (T?) -> Unit
|
val setValue: (T?) -> Unit,
|
||||||
) {
|
) {
|
||||||
fun submitDialog(value: T?) {
|
fun submitDialog(value: T?) {
|
||||||
setValue(value)
|
setValue(value)
|
||||||
dismissDialog()
|
dismissDialog()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkSafeguard(block: () -> Unit) {
|
fun clickAction() = editor.clickAction(this)
|
||||||
if (!option.required && selectionWarningEnabled)
|
|
||||||
showSelectionWarning()
|
|
||||||
else
|
|
||||||
block()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun clickAction() {
|
|
||||||
checkSafeguard {
|
|
||||||
editor.clickAction(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ListItemTrailingContent() = editor.ListItemTrailingContent(this)
|
fun ListItemTrailingContent() = editor.ListItemTrailingContent(this)
|
||||||
@ -123,7 +113,7 @@ private interface OptionEditor<T : Any> {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ListItemTrailingContent(scope: OptionEditorScope<T>) {
|
fun ListItemTrailingContent(scope: OptionEditorScope<T>) {
|
||||||
IconButton(onClick = { scope.checkSafeguard { clickAction(scope) } }) {
|
IconButton(onClick = { clickAction(scope) }) {
|
||||||
Icon(Icons.Outlined.Edit, stringResource(R.string.edit))
|
Icon(Icons.Outlined.Edit, stringResource(R.string.edit))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,14 +141,11 @@ private inline fun <T : Any> WithOptionEditor(
|
|||||||
option: Option<T>,
|
option: Option<T>,
|
||||||
value: T?,
|
value: T?,
|
||||||
noinline setValue: (T?) -> Unit,
|
noinline setValue: (T?) -> Unit,
|
||||||
selectionWarningEnabled: Boolean,
|
|
||||||
crossinline onDismissDialog: @DisallowComposableCalls () -> Unit = {},
|
crossinline onDismissDialog: @DisallowComposableCalls () -> Unit = {},
|
||||||
block: OptionEditorScope<T>.() -> Unit
|
block: OptionEditorScope<T>.() -> Unit
|
||||||
) {
|
) {
|
||||||
var showDialog by rememberSaveable { mutableStateOf(false) }
|
var showDialog by rememberSaveable { mutableStateOf(false) }
|
||||||
var showSelectionWarningDialog by rememberSaveable { mutableStateOf(false) }
|
val scope = remember(editor, option, value, setValue) {
|
||||||
|
|
||||||
val scope = remember(editor, option, value, setValue, selectionWarningEnabled) {
|
|
||||||
OptionEditorScope(
|
OptionEditorScope(
|
||||||
editor,
|
editor,
|
||||||
option,
|
option,
|
||||||
@ -167,18 +154,11 @@ private inline fun <T : Any> WithOptionEditor(
|
|||||||
showDialog = false
|
showDialog = false
|
||||||
onDismissDialog()
|
onDismissDialog()
|
||||||
},
|
},
|
||||||
selectionWarningEnabled,
|
|
||||||
showSelectionWarning = { showSelectionWarningDialog = true },
|
|
||||||
value,
|
value,
|
||||||
setValue
|
setValue
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showSelectionWarningDialog)
|
|
||||||
SelectionWarningDialog(
|
|
||||||
onDismiss = { showSelectionWarningDialog = false }
|
|
||||||
)
|
|
||||||
|
|
||||||
if (showDialog) scope.Dialog()
|
if (showDialog) scope.Dialog()
|
||||||
|
|
||||||
scope.block()
|
scope.block()
|
||||||
@ -189,7 +169,6 @@ fun <T : Any> OptionItem(
|
|||||||
option: Option<T>,
|
option: Option<T>,
|
||||||
value: T?,
|
value: T?,
|
||||||
setValue: (T?) -> Unit,
|
setValue: (T?) -> Unit,
|
||||||
selectionWarningEnabled: Boolean
|
|
||||||
) {
|
) {
|
||||||
val editor = remember(option.type, option.presets) {
|
val editor = remember(option.type, option.presets) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@ -202,7 +181,7 @@ fun <T : Any> OptionItem(
|
|||||||
else baseOptionEditor
|
else baseOptionEditor
|
||||||
}
|
}
|
||||||
|
|
||||||
WithOptionEditor(editor, option, value, setValue, selectionWarningEnabled) {
|
WithOptionEditor(editor, option, value, setValue) {
|
||||||
ListItem(
|
ListItem(
|
||||||
modifier = Modifier.clickable(onClick = ::clickAction),
|
modifier = Modifier.clickable(onClick = ::clickAction),
|
||||||
headlineContent = { Text(option.title) },
|
headlineContent = { Text(option.title) },
|
||||||
@ -321,7 +300,7 @@ private object StringOptionEditor : OptionEditor<String> {
|
|||||||
|
|
||||||
private abstract class NumberOptionEditor<T : Number> : OptionEditor<T> {
|
private abstract class NumberOptionEditor<T : Number> : OptionEditor<T> {
|
||||||
@Composable
|
@Composable
|
||||||
abstract fun NumberDialog(
|
protected abstract fun NumberDialog(
|
||||||
title: String,
|
title: String,
|
||||||
current: T?,
|
current: T?,
|
||||||
validator: (T?) -> Boolean,
|
validator: (T?) -> Boolean,
|
||||||
@ -375,14 +354,7 @@ private object BooleanOptionEditor : OptionEditor<Boolean> {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ListItemTrailingContent(scope: OptionEditorScope<Boolean>) {
|
override fun ListItemTrailingContent(scope: OptionEditorScope<Boolean>) {
|
||||||
HapticSwitch(
|
HapticSwitch(checked = scope.current, onCheckedChange = scope.setValue)
|
||||||
checked = scope.current,
|
|
||||||
onCheckedChange = { value ->
|
|
||||||
scope.checkSafeguard {
|
|
||||||
scope.setValue(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -421,7 +393,6 @@ private class PresetOptionEditor<T : Any>(private val innerEditor: OptionEditor<
|
|||||||
scope.option,
|
scope.option,
|
||||||
scope.value,
|
scope.value,
|
||||||
scope.setValue,
|
scope.setValue,
|
||||||
scope.selectionWarningEnabled,
|
|
||||||
onDismissDialog = scope.dismissDialog
|
onDismissDialog = scope.dismissDialog
|
||||||
) inner@{
|
) inner@{
|
||||||
var hidePresetsDialog by rememberSaveable {
|
var hidePresetsDialog by rememberSaveable {
|
||||||
@ -643,8 +614,7 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
|
|||||||
elementEditor,
|
elementEditor,
|
||||||
elementOption,
|
elementOption,
|
||||||
value = item.value,
|
value = item.value,
|
||||||
setValue = { items[index] = item.copy(value = it) },
|
setValue = { items[index] = item.copy(value = it) }
|
||||||
selectionWarningEnabled = scope.selectionWarningEnabled
|
|
||||||
) {
|
) {
|
||||||
ListItem(
|
ListItem(
|
||||||
modifier = Modifier.combinedClickable(
|
modifier = Modifier.combinedClickable(
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
package app.revanced.manager.ui.component.patches
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import app.revanced.manager.R
|
|
||||||
import app.revanced.manager.ui.component.SafeguardDialog
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SelectionWarningDialog(
|
|
||||||
onDismiss: () -> Unit
|
|
||||||
) {
|
|
||||||
SafeguardDialog(
|
|
||||||
onDismiss = onDismiss,
|
|
||||||
title = R.string.warning,
|
|
||||||
body = stringResource(R.string.selection_warning_description),
|
|
||||||
)
|
|
||||||
}
|
|
@ -73,7 +73,6 @@ import app.revanced.manager.ui.component.haptics.HapticCheckbox
|
|||||||
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
|
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
|
||||||
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.component.patches.SelectionWarningDialog
|
|
||||||
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_INCOMPATIBLE
|
||||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNIVERSAL
|
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNIVERSAL
|
||||||
@ -182,8 +181,7 @@ fun PatchesSelectorScreen(
|
|||||||
patch = patch,
|
patch = patch,
|
||||||
values = viewModel.getOptions(bundle, patch),
|
values = viewModel.getOptions(bundle, patch),
|
||||||
reset = { viewModel.resetOptions(bundle, patch) },
|
reset = { viewModel.resetOptions(bundle, patch) },
|
||||||
set = { key, value -> viewModel.setOption(bundle, patch, key, value) },
|
set = { key, value -> viewModel.setOption(bundle, patch, key, value) }
|
||||||
selectionWarningEnabled = viewModel.selectionWarningEnabled
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +215,9 @@ fun PatchesSelectorScreen(
|
|||||||
) { patch ->
|
) { patch ->
|
||||||
PatchItem(
|
PatchItem(
|
||||||
patch = patch,
|
patch = patch,
|
||||||
onOptionsDialog = { viewModel.optionsDialog = uid to patch },
|
onOptionsDialog = {
|
||||||
|
viewModel.optionsDialog = uid to patch
|
||||||
|
},
|
||||||
selected = compatible && viewModel.isSelected(
|
selected = compatible && viewModel.isSelected(
|
||||||
uid,
|
uid,
|
||||||
patch
|
patch
|
||||||
@ -472,6 +472,17 @@ fun PatchesSelectorScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun SelectionWarningDialog(
|
||||||
|
onDismiss: () -> Unit
|
||||||
|
) {
|
||||||
|
SafeguardDialog(
|
||||||
|
onDismiss = onDismiss,
|
||||||
|
title = R.string.warning,
|
||||||
|
body = stringResource(R.string.selection_warning_description),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun UniversalPatchWarningDialog(
|
private fun UniversalPatchWarningDialog(
|
||||||
onDismiss: () -> Unit
|
onDismiss: () -> Unit
|
||||||
@ -601,7 +612,6 @@ private fun OptionsDialog(
|
|||||||
reset: () -> Unit,
|
reset: () -> Unit,
|
||||||
set: (String, Any?) -> Unit,
|
set: (String, Any?) -> Unit,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
selectionWarningEnabled: Boolean
|
|
||||||
) = FullscreenDialog(onDismissRequest = onDismissRequest) {
|
) = FullscreenDialog(onDismissRequest = onDismissRequest) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
@ -632,8 +642,7 @@ private fun OptionsDialog(
|
|||||||
value = value,
|
value = value,
|
||||||
setValue = {
|
setValue = {
|
||||||
set(key, it)
|
set(key, it)
|
||||||
},
|
}
|
||||||
selectionWarningEnabled = selectionWarningEnabled
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,8 +154,7 @@ fun RequiredOptionsScreen(
|
|||||||
value = value,
|
value = value,
|
||||||
setValue = { new ->
|
setValue = { new ->
|
||||||
vm.setOption(bundle.uid, it, key, new)
|
vm.setOption(bundle.uid, it, key, new)
|
||||||
},
|
}
|
||||||
selectionWarningEnabled = vm.selectionWarningEnabled
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,8 +296,8 @@ fun ImportExportSettingsScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
headline = R.string.patch_options_reset_patches,
|
headline = R.string.patch_options_reset,
|
||||||
description = R.string.patch_options_reset_patches_description,
|
description = R.string.patch_options_reset_all,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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_patches,
|
titleResId = R.string.patch_options_reset,
|
||||||
descriptionResId = R.string.patch_options_reset_patches_dialog_description,
|
descriptionResId = R.string.patch_options_reset_dialog_description,
|
||||||
onConfirm = onConfirm,
|
onConfirm = onConfirm,
|
||||||
dialogOptionName = dialogOptionName
|
dialogOptionName = dialogOptionName
|
||||||
)
|
)
|
||||||
|
@ -95,8 +95,8 @@
|
|||||||
<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>
|
||||||
<string name="suggested_version_safeguard_confirmation">Selecting an app that is not the suggested version may cause unexpected issues.\n\nDo you want to proceed anyways?</string>
|
<string name="suggested_version_safeguard_confirmation">Selecting an app that is not the suggested version may cause unexpected issues.\n\nDo you want to proceed anyways?</string>
|
||||||
<string name="patch_selection_safeguard">Allow changing patch selection and options</string>
|
<string name="patch_selection_safeguard">Allow changing patch selection</string>
|
||||||
<string name="patch_selection_safeguard_description">Do not prevent selecting or deselecting patches and customization of options</string>
|
<string name="patch_selection_safeguard_description">Do not prevent selecting or deselecting patches</string>
|
||||||
<string name="patch_selection_safeguard_confirmation">Changing the selection of patches may cause unexpected issues.\n\nEnable anyways?</string>
|
<string name="patch_selection_safeguard_confirmation">Changing the selection of patches may cause unexpected issues.\n\nEnable anyways?</string>
|
||||||
<string name="universal_patches_safeguard">Allow using universal patches</string>
|
<string name="universal_patches_safeguard">Allow using universal patches</string>
|
||||||
<string name="universal_patches_safeguard_description">Do not prevent using universal patches</string>
|
<string name="universal_patches_safeguard_description">Do not prevent using universal patches</string>
|
||||||
@ -131,22 +131,21 @@
|
|||||||
<string name="reset_patch_options">Reset patch options</string>
|
<string name="reset_patch_options">Reset patch options</string>
|
||||||
<string name="reset_patch_options_description">Reset the stored patch options</string>
|
<string name="reset_patch_options_description">Reset the stored patch options</string>
|
||||||
<string name="reset_patch_selection_success">Patch selection has been reset</string>
|
<string name="reset_patch_selection_success">Patch selection has been reset</string>
|
||||||
<string name="patch_selection_reset_all">Reset patch selection globally</string>
|
<string name="patch_selection_reset_all">Reset all patch selection</string>
|
||||||
<string name="patch_selection_reset_all_dialog_description">You are about to reset all the patch selections. You will need to manually select each patch again.</string>
|
<string name="patch_selection_reset_all_dialog_description">You are about to reset all the patch selections. You will need to manually select each patch again.</string>
|
||||||
<string name="patch_selection_reset_all_description">Resets all the patch selections</string>
|
<string name="patch_selection_reset_all_description">Reset all the patch selections</string>
|
||||||
<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_patches">Reset patch selection (single)</string>
|
<string name="patch_selection_reset_patches">Resets patch selection for a specific patches</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_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_patches_description">Resets the patch selection for a specific collection of patches</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_patches">Reset patch options (single)</string>
|
<string name="patch_options_reset">Reset patch options</string>
|
||||||
<string name="patch_options_reset_patches_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_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_patches_description">Resets the patch options for a specific collection of patches</string>
|
<string name="patch_options_reset_all">Reset patch options for all</string>
|
||||||
<string name="patch_options_reset_all">Reset patch options globally</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>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
# Specifies the JVM arguments used for the daemon process.
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
org.gradle.jvmargs=-Xmx3072m -XX:MaxMetaspaceSize=1024m -Dfile.encoding=UTF-8
|
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
@ -25,5 +25,4 @@ android.nonFinalResIds=false
|
|||||||
# Task :app:assembleReleaseSignApk fails if this is set to true.
|
# Task :app:assembleReleaseSignApk fails if this is set to true.
|
||||||
org.gradle.configuration-cache=false
|
org.gradle.configuration-cache=false
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
org.gradle.parallel=true
|
|
||||||
version=1.25.0-dev.1
|
version=1.25.0-dev.1
|
@ -1,34 +1,35 @@
|
|||||||
[versions]
|
[versions]
|
||||||
ktx = "1.16.0"
|
ktx = "1.16.0"
|
||||||
material3 = "1.3.2"
|
material3 = "1.3.2"
|
||||||
ui-tooling = "1.8.3"
|
ui-tooling = "1.8.1"
|
||||||
viewmodel-lifecycle = "2.9.2"
|
viewmodel-lifecycle = "2.9.0"
|
||||||
splash-screen = "1.0.1"
|
splash-screen = "1.0.1"
|
||||||
activity = "1.10.1"
|
activity = "1.10.1"
|
||||||
appcompat = "1.7.1"
|
appcompat = "1.7.0"
|
||||||
preferences-datastore = "1.1.7"
|
preferences-datastore = "1.1.2"
|
||||||
work-runtime = "2.10.3"
|
work-runtime = "2.10.1"
|
||||||
compose-bom = "2025.07.00"
|
compose-bom = "2025.05.00"
|
||||||
navigation = "2.9.3"
|
navigation = "2.8.6"
|
||||||
accompanist = "0.37.3"
|
accompanist = "0.37.0"
|
||||||
placeholder = "1.1.2"
|
placeholder = "1.1.2"
|
||||||
reorderable = "2.5.1"
|
reorderable = "2.4.3"
|
||||||
serialization = "1.9.0"
|
serialization = "1.8.0"
|
||||||
collection = "0.3.8"
|
collection = "0.3.8"
|
||||||
datetime = "0.6.1"
|
datetime = "0.6.1"
|
||||||
room-version = "2.7.2"
|
room-version = "2.7.1"
|
||||||
revanced-patcher = "21.0.0"
|
revanced-patcher = "21.0.0"
|
||||||
revanced-library = "3.0.2"
|
revanced-library = "3.0.2"
|
||||||
koin = "3.5.3"
|
koin = "3.5.3"
|
||||||
ktor = "2.3.9"
|
ktor = "2.3.9"
|
||||||
markdown-renderer = "0.30.0"
|
markdown-renderer = "0.30.0"
|
||||||
fading-edges = "1.0.4"
|
fading-edges = "1.0.4"
|
||||||
kotlin = "2.2.0"
|
kotlin = "2.1.10"
|
||||||
android-gradle-plugin = "8.11.1"
|
android-gradle-plugin = "8.9.1"
|
||||||
dev-tools-gradle-plugin = "2.2.0-2.0.2"
|
dev-tools-gradle-plugin = "2.1.10-1.0.29"
|
||||||
about-libraries-gradle-plugin = "12.1.2"
|
about-libraries-gradle-plugin = "12.1.2"
|
||||||
coil = "2.7.0"
|
coil = "2.7.0"
|
||||||
app-icon-loader-coil = "1.5.0"
|
app-icon-loader-coil = "1.5.0"
|
||||||
|
skrapeit = "1.2.2"
|
||||||
libsu = "6.0.0"
|
libsu = "6.0.0"
|
||||||
scrollbars = "1.0.4"
|
scrollbars = "1.0.4"
|
||||||
enumutil = "1.1.1"
|
enumutil = "1.1.1"
|
||||||
@ -98,6 +99,10 @@ ktor-okhttp = { group = "io.ktor", name = "ktor-client-okhttp", version.ref = "k
|
|||||||
ktor-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor" }
|
ktor-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor" }
|
||||||
ktor-serialization = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor" }
|
ktor-serialization = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor" }
|
||||||
|
|
||||||
|
# HTML Scraper
|
||||||
|
skrapeit-dsl = { group = "it.skrape", name = "skrapeit-dsl", version.ref = "skrapeit" }
|
||||||
|
skrapeit-parser = { group = "it.skrape", name = "skrapeit-html-parser", version.ref = "skrapeit" }
|
||||||
|
|
||||||
# Markdown
|
# Markdown
|
||||||
markdown-renderer = { group = "com.mikepenz", name = "multiplatform-markdown-renderer-m3", version.ref = "markdown-renderer" }
|
markdown-renderer = { group = "com.mikepenz", name = "multiplatform-markdown-renderer-m3", version.ref = "markdown-renderer" }
|
||||||
|
|
||||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,7 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionSha256Sum=8fad3d78296ca518113f3d29016617c7f9367dc005f932bd9d93bf45ba46072b
|
distributionSha256Sum=61ad310d3c7d3e5da131b76bbf22b5a4c0786e9d892dae8c1658d4b484de3caa
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
2
gradlew
vendored
2
gradlew
vendored
@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright © 2015 the original authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
Reference in New Issue
Block a user