diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4246598d..de997d72 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -177,9 +177,6 @@ dependencies { implementation(libs.koin.compose.navigation) implementation(libs.koin.workmanager) - // Compose Navigation - implementation(libs.reimagined.navigation) - // Licenses implementation(libs.about.libraries) diff --git a/app/src/main/java/app/revanced/manager/MainActivity.kt b/app/src/main/java/app/revanced/manager/MainActivity.kt index 0bda88a9..0f519119 100644 --- a/app/src/main/java/app/revanced/manager/MainActivity.kt +++ b/app/src/main/java/app/revanced/manager/MainActivity.kt @@ -1,6 +1,7 @@ package app.revanced.manager import android.os.Bundle +import android.os.Parcelable import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge @@ -26,14 +27,12 @@ import app.revanced.manager.ui.screen.settings.update.UpdatesSettingsScreen import app.revanced.manager.ui.theme.ReVancedManagerTheme import app.revanced.manager.ui.theme.Theme import app.revanced.manager.ui.viewmodel.MainViewModel -import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel import app.revanced.manager.ui.viewmodel.SelectedAppInfoViewModel import app.revanced.manager.util.EventEffect import org.koin.androidx.compose.koinViewModel import org.koin.androidx.compose.navigation.koinNavViewModel import org.koin.core.parameter.parametersOf -import org.koin.androidx.compose.koinViewModel as getComposeViewModel -import org.koin.androidx.viewmodel.ext.android.getViewModel as getAndroidViewModel +import org.koin.androidx.viewmodel.ext.android.getViewModel as getActivityViewModel class MainActivity : ComponentActivity() { @ExperimentalAnimationApi @@ -44,7 +43,7 @@ class MainActivity : ComponentActivity() { enableEdgeToEdge() installSplashScreen() - val vm: MainViewModel = getAndroidViewModel() + val vm: MainViewModel = getActivityViewModel() vm.importLegacySettings(this) setContent { @@ -66,7 +65,10 @@ private fun ReVancedManager(vm: MainViewModel) { val navController = rememberNavController() EventEffect(vm.appSelectFlow) { app -> - // navController.navigate(SelectedApplicationInfo(app)) + navController.navigateComplex( + SelectedApplicationInfo, + SelectedApplicationInfo.ViewModelParams(app) + ) } NavHost( @@ -77,16 +79,12 @@ private fun ReVancedManager(vm: MainViewModel) { DashboardScreen( onSettingsClick = { navController.navigate(Settings) }, onAppSelectorClick = { - println("before: ${navController.currentBackStackEntry?.id}") navController.navigate(AppSelector) - println("after: ${navController.currentBackStackEntry?.id}") }, onUpdateClick = { navController.navigate(Update()) - // navController.navigate(Destination.Settings(SettingsDestination.Update())) }, onDownloaderPluginClick = { - // navController.navigate(Destination.Settings(SettingsDestination.Downloads)) navController.navigate(Settings.Downloads) }, onAppClick = { installedApp -> @@ -101,7 +99,7 @@ private fun ReVancedManager(vm: MainViewModel) { InstalledAppInfoScreen( onPatchClick = vm::selectApp, onBackClick = navController::popBackStack, - viewModel = getComposeViewModel { parametersOf(data.packageName) } + viewModel = koinViewModel { parametersOf(data.packageName) } ) } @@ -123,45 +121,43 @@ private fun ReVancedManager(vm: MainViewModel) { } } }, - vm = koinViewModel { parametersOf(it.toRoute()) } + vm = koinViewModel { parametersOf(it.getComplexArg()) } ) } navigation(startDestination = SelectedApplicationInfo.Main) { composable { val parentBackStackEntry = navController.navGraphEntry(it) - val data = parentBackStackEntry.toRoute() + val data = + parentBackStackEntry.getComplexArg() SelectedAppInfoScreen( onBackClick = navController::popBackStack, onPatchClick = { app, patches, options -> - // navController.navigate(Patcher(app, patches, options)) + navController.navigateComplex( + Patcher, + Patcher.ViewModelParams(app, patches, options) + ) }, onPatchSelectorClick = { app, patches, options -> - /* - navController.navigate( - SelectedApplicationInfo.PatchesSelector( + navController.navigateComplex( + SelectedApplicationInfo.PatchesSelector, + SelectedApplicationInfo.PatchesSelector.ViewModelParams( app, patches, options ) - )*/ + ) }, vm = koinNavViewModel(viewModelStoreOwner = parentBackStackEntry) { - parametersOf( - SelectedAppInfoViewModel.Params( - data.selectedApp, - data.patchSelection - ) - ) + parametersOf(data) } ) } - composable( - // typeMap = mapOf(typeOf() to SelectedApplicationInfo.PatchesSelector.navType) - ) { - val data = it.toRoute() + composable { + val data = + it.getComplexArg() val selectedAppInfoVm = koinNavViewModel( viewModelStoreOwner = navController.navGraphEntry(it) ) @@ -172,15 +168,7 @@ private fun ReVancedManager(vm: MainViewModel) { selectedAppInfoVm.updateConfiguration(patches, options) navController.popBackStack() }, - vm = koinViewModel { - parametersOf( - PatchesSelectorViewModel.Params( - data.app, - data.currentSelection, - data.options, - ) - ) - } + vm = koinViewModel { parametersOf(data) } ) } } @@ -243,82 +231,16 @@ private fun ReVancedManager(vm: MainViewModel) { } } -@Composable -private fun NavController.navGraphEntry(entry: NavBackStackEntry) = remember(entry) { - getBackStackEntry(entry.destination.parent!!) +private fun > NavController.navigateComplex( + route: R, + data: T +) { + navigate(route) + getBackStackEntry(route).savedStateHandle["args"] = data } -/* - val navController = - rememberNavController(startDestination = Destination.Dashboard) - NavBackHandler(navController) +private fun NavBackStackEntry.getComplexArg() = savedStateHandle.get("args")!! - EventEffect(vm.appSelectFlow) { app -> - navController.navigate(Destination.SelectedApplicationInfo(app)) - } - - AnimatedNavHost( - controller = navController - ) { destination -> - when (destination) { - is Destination.Dashboard -> DashboardScreen( - onSettingsClick = { navController.navigate(Destination.Settings()) }, - onAppSelectorClick = { navController.navigate(Destination.AppSelector) }, - onUpdateClick = { - navController.navigate(Destination.Settings(SettingsDestination.Update())) - }, - onDownloaderPluginClick = { - navController.navigate(Destination.Settings(SettingsDestination.Downloads)) - }, - onAppClick = { installedApp -> - navController.navigate( - Destination.InstalledApplicationInfo( - installedApp - ) - ) - } - ) - - is Destination.InstalledApplicationInfo -> InstalledAppInfoScreen( - onPatchClick = vm::selectApp, - onBackClick = { navController.pop() }, - viewModel = getComposeViewModel { parametersOf(destination.installedApp) } - ) - - is Destination.Settings -> SettingsScreen( - onBackClick = { navController.pop() }, - startDestination = destination.startDestination - ) - - is Destination.AppSelector -> AppSelectorScreen( - onSelect = vm::selectApp, - onStorageSelect = vm::selectApp, - onBackClick = { navController.pop() } - ) - - is Destination.SelectedApplicationInfo -> SelectedAppInfoScreen( - onPatchClick = { app, patches, options -> - navController.navigate( - Destination.Patcher( - app, patches, options - ) - ) - }, - onBackClick = navController::pop, - vm = getComposeViewModel { - parametersOf( - SelectedAppInfoViewModel.Params( - destination.selectedApp, - destination.patchSelection - ) - ) - } - ) - - is Destination.Patcher -> PatcherScreen( - onBackClick = { navController.popUpTo { it is Destination.Dashboard } }, - vm = getComposeViewModel { parametersOf(destination) } - ) - } - } - */ \ No newline at end of file +@Composable +private fun NavController.navGraphEntry(entry: NavBackStackEntry) = + remember(entry) { getBackStackEntry(entry.destination.parent!!.id) } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/ui/destination/Destination.kt b/app/src/main/java/app/revanced/manager/ui/destination/Destination.kt deleted file mode 100644 index f45020c6..00000000 --- a/app/src/main/java/app/revanced/manager/ui/destination/Destination.kt +++ /dev/null @@ -1,31 +0,0 @@ -package app.revanced.manager.ui.destination - -import android.os.Parcelable -import app.revanced.manager.data.room.apps.installed.InstalledApp -import app.revanced.manager.ui.model.SelectedApp -import app.revanced.manager.util.Options -import app.revanced.manager.util.PatchSelection -import kotlinx.parcelize.Parcelize -import kotlinx.parcelize.RawValue - -sealed interface Destination : Parcelable { - - @Parcelize - data object Dashboard : Destination - - // @Parcelize - // data class InstalledApplicationInfo(val installedApp: InstalledApp) : Destination - - @Parcelize - data object AppSelector : Destination - - @Parcelize - data class Settings(val startDestination: SettingsDestination = SettingsDestination.Settings) : Destination - - @Parcelize - data class SelectedApplicationInfo(val selectedApp: SelectedApp, val patchSelection: PatchSelection? = null) : Destination - - @Parcelize - data class Patcher(val selectedApp: SelectedApp, val selectedPatches: PatchSelection, val options: @RawValue Options) : Destination - -} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/ui/destination/SelectedAppInfoDestination.kt b/app/src/main/java/app/revanced/manager/ui/destination/SelectedAppInfoDestination.kt deleted file mode 100644 index 9a1f3e29..00000000 --- a/app/src/main/java/app/revanced/manager/ui/destination/SelectedAppInfoDestination.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.manager.ui.destination - -import android.os.Parcelable -import app.revanced.manager.ui.model.SelectedApp -import app.revanced.manager.util.Options -import app.revanced.manager.util.PatchSelection -import kotlinx.parcelize.Parcelize -import kotlinx.parcelize.RawValue - -sealed interface SelectedAppInfoDestination : Parcelable { - @Parcelize - data object Main : SelectedAppInfoDestination - - @Parcelize - data class PatchesSelector(val app: SelectedApp, val currentSelection: PatchSelection?, val options: @RawValue Options) : SelectedAppInfoDestination -} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/ui/destination/SettingsDestination.kt b/app/src/main/java/app/revanced/manager/ui/destination/SettingsDestination.kt deleted file mode 100644 index e62ab4f4..00000000 --- a/app/src/main/java/app/revanced/manager/ui/destination/SettingsDestination.kt +++ /dev/null @@ -1,43 +0,0 @@ -package app.revanced.manager.ui.destination - -import android.os.Parcelable -import kotlinx.parcelize.Parcelize - -sealed interface SettingsDestination : Parcelable { - - @Parcelize - data object Settings : SettingsDestination - - @Parcelize - data object General : SettingsDestination - - @Parcelize - data object Advanced : SettingsDestination - - @Parcelize - data object Updates : SettingsDestination - - @Parcelize - data object Downloads : SettingsDestination - - @Parcelize - data object ImportExport : SettingsDestination - - @Parcelize - data object About : SettingsDestination - - @Parcelize - data class Update(val downloadOnScreenEntry: Boolean = false) : SettingsDestination - - @Parcelize - data object Changelogs : SettingsDestination - - @Parcelize - data object Contributors: SettingsDestination - - @Parcelize - data object Licenses: SettingsDestination - - @Parcelize - data object DeveloperOptions: SettingsDestination -} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/ui/model/navigation/Nav.kt b/app/src/main/java/app/revanced/manager/ui/model/navigation/Nav.kt index 6ee30516..77dd86c0 100644 --- a/app/src/main/java/app/revanced/manager/ui/model/navigation/Nav.kt +++ b/app/src/main/java/app/revanced/manager/ui/model/navigation/Nav.kt @@ -1,8 +1,11 @@ package app.revanced.manager.ui.model.navigation +import android.os.Parcelable import app.revanced.manager.ui.model.SelectedApp import app.revanced.manager.util.Options import app.revanced.manager.util.PatchSelection +import kotlinx.parcelize.Parcelize +import kotlinx.parcelize.RawValue import kotlinx.serialization.Serializable /* @@ -28,6 +31,8 @@ sealed interface Destination : Parcelable { }*/ +interface ComplexParameter + @Serializable object Dashboard @@ -41,40 +46,35 @@ data class InstalledApplicationInfo(val packageName: String) data class Update(val downloadOnScreenEntry: Boolean = false) @Serializable -data class SelectedApplicationInfo( - val h: Int = 0, - // val selectedApp: SelectedApp, - // val patchSelection: PatchSelection? = null -) { - val patchSelection: PatchSelection? get() = TODO() - val selectedApp: SelectedApp get() = TODO() +data object SelectedApplicationInfo : ComplexParameter { + @Parcelize + data class ViewModelParams( + val app: SelectedApp, + val patches: PatchSelection? = null + ) : Parcelable @Serializable object Main @Serializable - data class PatchesSelector( - val h: Int, - //val app: SelectedApp, - // val currentSelection: PatchSelection?, - // val options: Options - ) { - val app: SelectedApp get() = TODO() - val currentSelection: PatchSelection? get() = TODO() - val options: Options get() = TODO() + data object PatchesSelector : ComplexParameter { + @Parcelize + data class ViewModelParams( + val app: SelectedApp, + val currentSelection: PatchSelection?, + val options: @RawValue Options, + ) : Parcelable } } @Serializable -data class Patcher( - val h: Int = 0, - //val selectedApp: SelectedApp, - // val selectedPatches: PatchSelection, - // val options: Options -) { - val selectedApp: SelectedApp get() = TODO() - val options: Options get() = TODO() - val selectedPatches: PatchSelection get() = TODO() +data object Patcher : ComplexParameter { + @Parcelize + data class ViewModelParams( + val selectedApp: SelectedApp, + val selectedPatches: PatchSelection, + val options: @RawValue Options + ) : Parcelable } @Serializable diff --git a/app/src/main/java/app/revanced/manager/ui/screen/SelectedAppInfoScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/SelectedAppInfoScreen.kt index 0ca71cc9..d0a8040d 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/SelectedAppInfoScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/SelectedAppInfoScreen.kt @@ -32,7 +32,6 @@ import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.ColumnWithScrollbar import app.revanced.manager.ui.component.LoadingIndicator import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton -import app.revanced.manager.ui.destination.SelectedAppInfoDestination import app.revanced.manager.ui.model.BundleInfo.Extensions.bundleInfoFlow import app.revanced.manager.ui.model.SelectedApp import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/PatcherViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/PatcherViewModel.kt index 17ef0aef..4ca53667 100644 --- a/app/src/main/java/app/revanced/manager/ui/viewmodel/PatcherViewModel.kt +++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/PatcherViewModel.kt @@ -39,7 +39,6 @@ import app.revanced.manager.plugin.downloader.PluginHostApi import app.revanced.manager.plugin.downloader.UserInteractionException import app.revanced.manager.service.InstallService import app.revanced.manager.service.UninstallService -import app.revanced.manager.ui.destination.Destination import app.revanced.manager.ui.model.InstallerModel import app.revanced.manager.ui.model.ProgressKey import app.revanced.manager.ui.model.SelectedApp @@ -70,11 +69,10 @@ import org.koin.core.component.inject import java.io.File import java.nio.file.Files import java.time.Duration -import java.util.UUID @OptIn(SavedStateHandleSaveableApi::class, PluginHostApi::class) class PatcherViewModel( - private val input: Patcher + private val input: Patcher.ViewModelParams ) : ViewModel(), KoinComponent, StepProgressProvider, InstallerModel { private val app: Application by inject() private val fs: Filesystem by inject() diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/PatchesSelectorViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/PatchesSelectorViewModel.kt index b2986fbb..ff815266 100644 --- a/app/src/main/java/app/revanced/manager/ui/viewmodel/PatchesSelectorViewModel.kt +++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/PatchesSelectorViewModel.kt @@ -23,6 +23,7 @@ import app.revanced.manager.ui.model.BundleInfo import app.revanced.manager.ui.model.BundleInfo.Extensions.bundleInfoFlow import app.revanced.manager.ui.model.BundleInfo.Extensions.toPatchSelection import app.revanced.manager.ui.model.SelectedApp +import app.revanced.manager.ui.model.navigation.SelectedApplicationInfo import app.revanced.manager.util.Options import app.revanced.manager.util.PatchSelection import app.revanced.manager.util.saver.Nullable @@ -40,7 +41,7 @@ import kotlinx.coroutines.flow.map @Stable @OptIn(SavedStateHandleSaveableApi::class) -class PatchesSelectorViewModel(input: Params) : ViewModel(), KoinComponent { +class PatchesSelectorViewModel(input: SelectedApplicationInfo.PatchesSelector.ViewModelParams) : ViewModel(), KoinComponent { private val app: Application = get() private val savedStateHandle: SavedStateHandle = get() private val prefs: PreferencesManager = get() @@ -214,12 +215,6 @@ class PatchesSelectorViewModel(input: Params) : ViewModel(), KoinComponent { private val selectionSaver: Saver> = nullableSaver(persistentMapSaver(valueSaver = persistentSetSaver())) } - - data class Params( - val app: SelectedApp, - val currentSelection: PatchSelection?, - val options: Options, - ) } // Versions of other types, but utilizing persistent/observable collection types. diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/SelectedAppInfoViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/SelectedAppInfoViewModel.kt index 23f13685..cdf87267 100644 --- a/app/src/main/java/app/revanced/manager/ui/viewmodel/SelectedAppInfoViewModel.kt +++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/SelectedAppInfoViewModel.kt @@ -36,6 +36,7 @@ import app.revanced.manager.ui.model.BundleInfo import app.revanced.manager.ui.model.BundleInfo.Extensions.bundleInfoFlow import app.revanced.manager.ui.model.BundleInfo.Extensions.toPatchSelection import app.revanced.manager.ui.model.SelectedApp +import app.revanced.manager.ui.model.navigation.SelectedApplicationInfo import app.revanced.manager.util.Options import app.revanced.manager.util.PM import app.revanced.manager.util.PatchSelection @@ -58,7 +59,9 @@ import org.koin.core.component.KoinComponent import org.koin.core.component.get @OptIn(SavedStateHandleSaveableApi::class, PluginHostApi::class) -class SelectedAppInfoViewModel(input: Params) : ViewModel(), KoinComponent { +class SelectedAppInfoViewModel( + input: SelectedApplicationInfo.ViewModelParams +) : ViewModel(), KoinComponent { private val app: Application = get() val bundlesRepo: PatchBundleRepository = get() private val bundleRepository: PatchBundleRepository = get() @@ -285,11 +288,6 @@ class SelectedAppInfoViewModel(input: Params) : ViewModel(), KoinComponent { } } - data class Params( - val app: SelectedApp, - val patches: PatchSelection?, - ) - enum class Error(@StringRes val resourceId: Int) { NoPlugins(R.string.downloader_no_plugins_available) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 979f2802..08cbb2d3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,7 +9,7 @@ appcompat = "1.7.0" preferences-datastore = "1.1.1" work-runtime = "2.10.0" compose-bom = "2024.12.01" -navigation = "2.8.4" +navigation = "2.8.5" accompanist = "0.34.0" placeholder = "1.1.2" reorderable = "1.5.2" @@ -19,9 +19,7 @@ datetime = "0.6.0" room-version = "2.6.1" revanced-patcher = "21.0.0" revanced-library = "3.0.2" -koin-version = "3.5.3" -koin-version-compose = "3.5.3" -reimagined-navigation = "1.5.0" +koin = "3.5.3" ktor = "2.3.9" markdown-renderer = "0.22.0" fading-edges = "1.0.4" @@ -87,13 +85,10 @@ revanced-patcher = { group = "app.revanced", name = "revanced-patcher", version. revanced-library = { group = "app.revanced", name = "revanced-library", version.ref = "revanced-library" } # Koin -koin-android = { group = "io.insert-koin", name = "koin-android", version.ref = "koin-version" } -koin-compose = { group = "io.insert-koin", name = "koin-androidx-compose", version.ref = "koin-version-compose" } -koin-compose-navigation = { group = "io.insert-koin", name = "koin-androidx-compose-navigation", version.ref = "koin-version-compose" } -koin-workmanager = { group = "io.insert-koin", name = "koin-androidx-workmanager", version.ref = "koin-version" } - -# Compose Navigation -reimagined-navigation = { group = "dev.olshevski.navigation", name = "reimagined", version.ref = "reimagined-navigation" } +koin-android = { group = "io.insert-koin", name = "koin-android", version.ref = "koin" } +koin-compose = { group = "io.insert-koin", name = "koin-androidx-compose", version.ref = "koin" } +koin-compose-navigation = { group = "io.insert-koin", name = "koin-androidx-compose-navigation", version.ref = "koin" } +koin-workmanager = { group = "io.insert-koin", name = "koin-androidx-workmanager", version.ref = "koin" } # About Libraries about-libraries = { group = "com.mikepenz", name = "aboutlibraries-compose", version.ref = "about-libraries-gradle-plugin" }