mirror of
https://github.com/meowarex/rl-mobile.git
synced 2026-08-27 14:37:45 +10:00
Manager UI Updates & New patch logic <3
This commit is contained in:
+3
-4
@@ -150,15 +150,13 @@ class PatchingScreenModel(
|
||||
.toUnsafeImmutable()
|
||||
mainThread { steps = newSteps }
|
||||
|
||||
// Intentionally delay to show the state change of the first step when it runs in the UI.
|
||||
// Without this, on a fast internet connection the step just immediately shows as "Success".
|
||||
// Tiny delay so the first step's progress is visible on fast connections
|
||||
delay(400)
|
||||
|
||||
// Execute all the steps and catch any errors
|
||||
val error = when (val error = runner.executeAll()) {
|
||||
null -> {
|
||||
// If install step is marked skipped then the installation was manually aborted
|
||||
// and if so, immediately close install screen
|
||||
// Skipped install step means user aborted, close screen
|
||||
if (runner.getStep<InstallStep>().state == StepState.Skipped) {
|
||||
mutableState.value = PatchingScreenState.CloseScreen
|
||||
|
||||
@@ -215,6 +213,7 @@ class PatchingScreenModel(
|
||||
R.string.fun_fact_10,
|
||||
R.string.fun_fact_11,
|
||||
R.string.fun_fact_12,
|
||||
R.string.fun_fact_13,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+41
-14
@@ -8,37 +8,64 @@ enum class KnownPatch(
|
||||
@StringRes val titleRes: Int,
|
||||
@StringRes val descRes: Int,
|
||||
val requires: List<KnownPatch> = emptyList(),
|
||||
val disables: List<KnownPatch> = emptyList(),
|
||||
) {
|
||||
// Dependency-first order (later refs need backward resolution)
|
||||
LyricsDisableCover(
|
||||
fileNames = listOf("lyrics-disable-cover.patch"),
|
||||
titleRes = R.string.patch_lyrics_disable_cover_title,
|
||||
descRes = R.string.patch_lyrics_disable_cover_desc,
|
||||
),
|
||||
LyricsProgressPill(
|
||||
LyricsReplaceLyricsButton(
|
||||
fileNames = listOf(
|
||||
"lyrics-progress-pill.patch",
|
||||
"lyrics-fade-region.patch",
|
||||
"lyrics-active-line-only.patch",
|
||||
),
|
||||
titleRes = R.string.patch_lyrics_progress_pill_title,
|
||||
descRes = R.string.patch_lyrics_progress_pill_desc,
|
||||
requires = listOf(LyricsDisableCover),
|
||||
),
|
||||
LyricsReplaceLyricButton(
|
||||
fileNames = listOf(
|
||||
"lyrics-replace-lyric-button-1-remove.patch",
|
||||
"lyrics-replace-lyric-button-2-sparkle.patch",
|
||||
"lyrics-replace-lyrics-button.patch",
|
||||
"lyrics-sparkle-conditional-visibility.patch",
|
||||
),
|
||||
titleRes = R.string.patch_lyrics_replace_button_title,
|
||||
descRes = R.string.patch_lyrics_replace_button_desc,
|
||||
),
|
||||
LyricsReplaceShareButton(
|
||||
fileNames = listOf("lyrics-replace-share-button.patch"),
|
||||
titleRes = R.string.patch_lyrics_replace_share_button_title,
|
||||
descRes = R.string.patch_lyrics_replace_share_button_desc,
|
||||
),
|
||||
PlayerBackdrop(
|
||||
fileNames = listOf("player-backdrop.patch"),
|
||||
titleRes = R.string.patch_player_backdrop_title,
|
||||
descRes = R.string.patch_player_backdrop_desc,
|
||||
),
|
||||
DebugMenuUnlock(
|
||||
fileNames = listOf("debug-menu-unlock.patch"),
|
||||
titleRes = R.string.patch_debug_menu_unlock_title,
|
||||
descRes = R.string.patch_debug_menu_unlock_desc,
|
||||
),
|
||||
LyricsProgressPill(
|
||||
fileNames = listOf(
|
||||
"lyrics-progress-pill.patch",
|
||||
"lyrics-fade-region.patch",
|
||||
),
|
||||
titleRes = R.string.patch_lyrics_progress_pill_title,
|
||||
descRes = R.string.patch_lyrics_progress_pill_desc,
|
||||
requires = listOf(LyricsDisableCover, LyricsReplaceShareButton),
|
||||
),
|
||||
EnableLegacyUi(
|
||||
fileNames = listOf("enable-legacy-ui.patch"),
|
||||
titleRes = R.string.patch_enable_legacy_ui_title,
|
||||
descRes = R.string.patch_enable_legacy_ui_desc,
|
||||
requires = listOf(DebugMenuUnlock),
|
||||
disables = listOf(
|
||||
LyricsDisableCover,
|
||||
LyricsReplaceLyricsButton,
|
||||
LyricsReplaceShareButton,
|
||||
PlayerBackdrop,
|
||||
LyricsProgressPill,
|
||||
),
|
||||
);
|
||||
|
||||
companion object {
|
||||
val All: List<KnownPatch> = entries.sortedBy { it.fileNames.first() }
|
||||
// Alphabetical by first filename, but pin DebugMenuUnlock to the bottom
|
||||
val All: List<KnownPatch> = entries.sortedWith(
|
||||
compareBy({ it == DebugMenuUnlock }, { it.fileNames.first() })
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+17
-29
@@ -18,7 +18,6 @@ class PatchOptionsModel(
|
||||
private val context: Context,
|
||||
private val prefs: PreferencesManager,
|
||||
) : ScreenModel {
|
||||
// ---------- Package name state ----------
|
||||
var packageName by mutableStateOf(prefilledOptions.packageName)
|
||||
private set
|
||||
|
||||
@@ -30,7 +29,6 @@ class PatchOptionsModel(
|
||||
fetchPkgNameStateDebounced()
|
||||
}
|
||||
|
||||
// ---------- App name state ----------
|
||||
var appName by mutableStateOf(prefilledOptions.appName)
|
||||
private set
|
||||
|
||||
@@ -42,7 +40,6 @@ class PatchOptionsModel(
|
||||
appNameIsError = newAppName.length !in (1..150)
|
||||
}
|
||||
|
||||
// ---------- Debuggable state ----------
|
||||
var debuggable by mutableStateOf(prefilledOptions.debuggable)
|
||||
private set
|
||||
|
||||
@@ -50,7 +47,6 @@ class PatchOptionsModel(
|
||||
debuggable = value
|
||||
}
|
||||
|
||||
// ---------- Patch selection state ----------
|
||||
var disabledPatches by mutableStateOf(prefilledOptions.disabledPatches)
|
||||
private set
|
||||
|
||||
@@ -58,38 +54,33 @@ class PatchOptionsModel(
|
||||
patch.fileNames.none { it in disabledPatches }
|
||||
|
||||
fun setPatchEnabled(patch: KnownPatch, enabled: Boolean) {
|
||||
val units = if (enabled) {
|
||||
fun closure(seed: KnownPatch, step: (KnownPatch) -> List<KnownPatch>): Set<KnownPatch> =
|
||||
buildSet {
|
||||
fun addWithDeps(p: KnownPatch) {
|
||||
if (add(p)) p.requires.forEach(::addWithDeps)
|
||||
}
|
||||
addWithDeps(patch)
|
||||
fun walk(p: KnownPatch) { if (add(p)) step(p).forEach(::walk) }
|
||||
walk(seed)
|
||||
}
|
||||
|
||||
val enableUnits: Set<KnownPatch>
|
||||
val disableUnits: Set<KnownPatch>
|
||||
if (enabled) {
|
||||
enableUnits = closure(patch) { it.requires }
|
||||
disableUnits = enableUnits.flatMap { it.disables }
|
||||
.flatMapTo(mutableSetOf()) { d ->
|
||||
closure(d) { dep -> KnownPatch.All.filter { dep in it.requires } }
|
||||
}
|
||||
} else {
|
||||
buildSet {
|
||||
fun addWithDependents(p: KnownPatch) {
|
||||
if (add(p)) {
|
||||
KnownPatch.All
|
||||
.filter { p in it.requires }
|
||||
.forEach(::addWithDependents)
|
||||
}
|
||||
}
|
||||
addWithDependents(patch)
|
||||
}
|
||||
enableUnits = emptySet()
|
||||
disableUnits = closure(patch) { p -> KnownPatch.All.filter { p in it.requires } }
|
||||
}
|
||||
|
||||
val affectedFiles = units.flatMap { it.fileNames }.toSet()
|
||||
disabledPatches = if (enabled) {
|
||||
disabledPatches - affectedFiles
|
||||
} else {
|
||||
disabledPatches + affectedFiles
|
||||
}
|
||||
val enableFiles = enableUnits.flatMap { it.fileNames }.toSet()
|
||||
val disableFiles = disableUnits.flatMap { it.fileNames }.toSet()
|
||||
disabledPatches = (disabledPatches - enableFiles) + disableFiles
|
||||
}
|
||||
|
||||
val enabledPatchCount: Int
|
||||
get() = KnownPatch.All.count { isPatchEnabled(it) }
|
||||
|
||||
// ---------- Custom components state ----------
|
||||
var customInjector by mutableStateOf<PatchComponent?>(null)
|
||||
private set
|
||||
var customPatches by mutableStateOf<PatchComponent?>(null)
|
||||
@@ -113,7 +104,6 @@ class PatchOptionsModel(
|
||||
)
|
||||
}
|
||||
|
||||
// ---------- Config generation ----------
|
||||
val isConfigValid by derivedStateOf {
|
||||
val invalidChecks = arrayOf(
|
||||
packageNameState == PackageNameState.Invalid,
|
||||
@@ -136,11 +126,9 @@ class PatchOptionsModel(
|
||||
)
|
||||
}
|
||||
|
||||
// ---------- Other ----------
|
||||
val isDevMode: Boolean
|
||||
get() = prefs.devMode
|
||||
|
||||
// A throttled variant of fetchPkgNameState()
|
||||
private val fetchPkgNameStateDebounced: () -> Unit =
|
||||
screenModelScope.debounce(100L, function = ::fetchPkgNameState)
|
||||
|
||||
|
||||
+1
@@ -1,5 +1,6 @@
|
||||
package com.meowarex.rlmobile.ui.screens.patchopts.components
|
||||
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.foundation.background
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ fun InstallersDialog(
|
||||
}
|
||||
|
||||
InstallerSetting.Intent -> {
|
||||
// We don't know whether this device supports this method until we try.
|
||||
// don't know whether this device supports this method
|
||||
}
|
||||
|
||||
InstallerSetting.Shizuku -> {
|
||||
|
||||
+1
-1
@@ -147,7 +147,7 @@ class UpdaterViewModel(
|
||||
// Fetch releases from GitHub (60s local cache)
|
||||
val releases = github.getManagerReleases().getOrThrow()
|
||||
|
||||
// Find the latest release — version is parsed from the release title (e.g. "v1.0.5")
|
||||
// Find the latest release by parsed version
|
||||
val (version, release, apkUrl) = releases
|
||||
.mapNotNull { release ->
|
||||
val version = SemVer.parseOrNull(release.name?.removePrefix("v") ?: "")
|
||||
|
||||
Reference in New Issue
Block a user