diff --git a/app/src/main/java/app/revanced/manager/domain/repository/PatchBundleRepository.kt b/app/src/main/java/app/revanced/manager/domain/repository/PatchBundleRepository.kt index e1088528..49a7b168 100644 --- a/app/src/main/java/app/revanced/manager/domain/repository/PatchBundleRepository.kt +++ b/app/src/main/java/app/revanced/manager/domain/repository/PatchBundleRepository.kt @@ -37,7 +37,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.withContext @@ -84,7 +83,7 @@ class PatchBundleRepository( .map(PatchInfo::toPatcherPatch) }.toSet() - allPatches.mostCommonCompatibleVersions(countUnusedPatches = false)[packageName] + allPatches.mostCommonCompatibleVersions(countUnusedPatches = true)[packageName] } val suggestedVersions = bundleInfoFlow.map { diff --git a/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt b/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt index 7076e122..070af2cb 100644 --- a/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt +++ b/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt @@ -39,7 +39,7 @@ import app.revanced.manager.patcher.toRemoteError import app.revanced.manager.plugin.downloader.GetScope import app.revanced.manager.plugin.downloader.PluginHostApi import app.revanced.manager.plugin.downloader.UserInteractionException -import app.revanced.manager.ui.model.SelectedApp +import app.revanced.manager.ui.model.SelectedSource import app.revanced.manager.util.Options import app.revanced.manager.util.PM import app.revanced.manager.util.PatchSelection @@ -67,7 +67,9 @@ class PatcherWorker( private val rootInstaller: RootInstaller by inject() class Args( - val input: SelectedApp, + val packageName: String, + val version: String?, + val source: SelectedSource, val output: String, val selectedPatches: PatchSelection, val options: Options, @@ -75,9 +77,7 @@ class PatcherWorker( val handleStartActivityRequest: suspend (LoadedDownloaderPlugin, Intent) -> ActivityResult, val setInputFile: suspend (File) -> Unit, val onEvent: (ProgressEvent) -> Unit, - ) { - val packageName get() = input.packageName - } + ) override suspend fun getForegroundInfo() = ForegroundInfo( @@ -142,7 +142,7 @@ class PatcherWorker( val patchedApk = fs.tempDir.resolve("patched.apk") return try { - if (args.input is SelectedApp.Installed) { + if (args.source is SelectedSource.Installed) { installedAppRepository.get(args.packageName)?.let { if (it.installType == InstallType.MOUNT) { rootInstaller.unmount(args.packageName) @@ -155,7 +155,7 @@ class PatcherWorker( plugin, data, args.packageName, - args.input.version, + args.version, prefs.suggestedVersionSafeguard.get(), !prefs.disablePatchVersionCompatCheck.get(), onDownload = { progress -> @@ -169,18 +169,10 @@ class PatcherWorker( } ).also { args.setInputFile(it) } - val inputFile = when (val selectedApp = args.input) { - is SelectedApp.Download -> { - runStep(StepId.DownloadAPK, args.onEvent) { - val (plugin, data) = downloaderPluginRepository.unwrapParceledData( - selectedApp.data - ) + val inputFile = when (val source = args.source) { + is SelectedSource.Auto -> throw Exception("Auto source is not supported in worker.") - download(plugin, data) - } - } - - is SelectedApp.Search -> { + is SelectedSource.Plugin -> { runStep(StepId.DownloadAPK, args.onEvent) { downloaderPluginRepository.loadedPluginsFlow.first() .firstNotNullOfOrNull { plugin -> @@ -206,10 +198,10 @@ class PatcherWorker( withContext(Dispatchers.IO) { plugin.get( getScope, - selectedApp.packageName, - selectedApp.version + args.packageName, + args.version ) - }?.takeIf { (_, version) -> selectedApp.version == null || version == selectedApp.version } + }?.takeIf { (_, version) -> args.version == null || version == args.version } } catch (e: UserInteractionException.Activity.NotCompleted) { throw e } catch (_: UserInteractionException) { @@ -219,8 +211,9 @@ class PatcherWorker( } } - is SelectedApp.Local -> selectedApp.file.also { args.setInputFile(it) } - is SelectedApp.Installed -> File(pm.getPackageInfo(selectedApp.packageName)!!.applicationInfo!!.sourceDir) + is SelectedSource.Downloaded -> File(source.path) + + is SelectedSource.Installed -> File(pm.getPackageInfo(args.packageName)!!.applicationInfo!!.sourceDir) } val runtime = if (prefs.useProcessRuntime.get()) { @@ -258,9 +251,10 @@ class PatcherWorker( Result.failure() } finally { patchedApk.delete() - if (args.input is SelectedApp.Local && args.input.temporary) { - args.input.file.delete() - } + // TODO +// if (args.source is SelectedApp.Local && args.source.temporary) { +// args.source.file.delete() +// } } } diff --git a/app/src/main/java/app/revanced/manager/ui/model/SelectedSource.kt b/app/src/main/java/app/revanced/manager/ui/model/SelectedSource.kt index c91ba366..aedb5bbd 100644 --- a/app/src/main/java/app/revanced/manager/ui/model/SelectedSource.kt +++ b/app/src/main/java/app/revanced/manager/ui/model/SelectedSource.kt @@ -8,5 +8,5 @@ sealed class SelectedSource : Parcelable { data object Auto : SelectedSource() data object Installed : SelectedSource() data class Downloaded(val path: String, val version: String) : SelectedSource() - data class Plugin(val plugin: String) : SelectedSource() // TODO + data class Plugin(val packageName: String?) : SelectedSource() } \ 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 c6a4cf29..c88611a5 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,7 +1,6 @@ package app.revanced.manager.ui.model.navigation import android.os.Parcelable -import app.revanced.manager.ui.model.SelectedApp import app.revanced.manager.ui.model.SelectedSource import app.revanced.manager.ui.model.SelectedVersion import app.revanced.manager.util.Options @@ -76,7 +75,9 @@ data object SelectedAppInfo : ComplexParameter data object Patcher : ComplexParameter { @Parcelize data class ViewModelParams( - val selectedApp: SelectedApp, + val packageName: String, + val version: String?, + val selectedSource: SelectedSource, val selectedPatches: PatchSelection, val options: @RawValue Options ) : Parcelable diff --git a/app/src/main/java/app/revanced/manager/ui/screen/AppSelectorScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/AppSelectorScreen.kt index f989d06c..5b775ba6 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/AppSelectorScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/AppSelectorScreen.kt @@ -83,12 +83,12 @@ fun AppSelectorScreen( } } - vm.nonSuggestedVersionDialogSubject?.let { - NonSuggestedVersionDialog( - suggestedVersion = suggestedVersions[it.packageName].orEmpty(), - onDismiss = vm::dismissNonSuggestedVersionDialog - ) - } +// vm.nonSuggestedVersionDialogSubject?.let { +// NonSuggestedVersionDialog( +// suggestedVersion = suggestedVersions[it.packageName].orEmpty(), +// onDismiss = vm::dismissNonSuggestedVersionDialog +// ) +// } if (search) SearchView( 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 787231c0..4da4fcb5 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 @@ -182,25 +182,22 @@ fun SelectedAppInfoScreen( PageItem( R.string.apk_source_selector_item, selectedSource.toString(), - onClick = { onSourceClick(packageName, versionText, selectedSource) }, + onClick = { onSourceClick(packageName, resolvedVersion, selectedSource) }, ) - error?.let { - Text( - stringResource(it.resourceId), - color = MaterialTheme.colorScheme.error, - modifier = Modifier.padding(horizontal = 16.dp) - ) - } +// error?.let { +// Text( +// stringResource(it.resourceId), +// color = MaterialTheme.colorScheme.error, +// modifier = Modifier.padding(horizontal = 16.dp) +// ) +// } - Column( + if (resolvedSource is SelectedSource.Plugin) Column( modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { - val needsInternet = resolvedSource is SelectedSource.Plugin - when { - !needsInternet -> {} !networkConnected -> { NotificationCard( isWarning = true, @@ -209,7 +206,6 @@ fun SelectedAppInfoScreen( onDismiss = null ) } - networkMetered -> { NotificationCard( isWarning = true, diff --git a/app/src/main/java/app/revanced/manager/ui/screen/SourceSelectorScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/SourceSelectorScreen.kt index 24d06d7a..6cae108b 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/SourceSelectorScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/SourceSelectorScreen.kt @@ -1,8 +1,6 @@ package app.revanced.manager.ui.screen import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons @@ -16,8 +14,12 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.style.TextOverflow import androidx.lifecycle.compose.collectAsStateWithLifecycle +import app.revanced.manager.network.downloader.DownloaderPluginState import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton import app.revanced.manager.ui.model.SelectedSource @@ -32,7 +34,10 @@ fun SourceSelectorScreen( onSave: (source: SelectedSource) -> Unit, viewModel: SourceSelectorViewModel, ) { + val context = LocalContext.current + val downloadedApps by viewModel.downloadedApps.collectAsStateWithLifecycle(emptyList()) + val plugins by viewModel.plugins.collectAsStateWithLifecycle(emptyList()) Scaffold( topBar = { @@ -49,67 +54,72 @@ fun SourceSelectorScreen( ) } ) { paddingValues -> - Column( - modifier = Modifier.padding(paddingValues) + LazyColumn ( + contentPadding = paddingValues, ) { - SourceOption( - isSelected = viewModel.selectedSource == SelectedSource.Auto, - onSelect = { viewModel.selectSource(SelectedSource.Auto) }, - headlineContent = { Text("Auto (Recommended)") }, - supportingContent = { Text("Automatically select the best available source") } - ) - - SourceOption( - isSelected = viewModel.selectedSource == SelectedSource.Plugin("any"), - onSelect = { viewModel.selectSource(SelectedSource.Plugin("any")) }, - headlineContent = { Text("Any available downloader") }, - ) - - viewModel.installedVersion?.let { installedVersion -> - HorizontalDivider() - + item { SourceOption( - isSelected = viewModel.selectedSource == SelectedSource.Installed, - onSelect = { viewModel.selectSource(SelectedSource.Installed) }, - headlineContent = { Text(installedVersion) }, - overlineContent = { Text("Installed") }, - enabled = viewModel.input.version?.let { it == installedVersion } ?: true + isSelected = viewModel.selectedSource == SelectedSource.Auto, + onSelect = { viewModel.selectSource(SelectedSource.Auto) }, + headlineContent = { Text("Auto (Recommended)") }, + supportingContent = { Text("Automatically select the best available source") } + ) + } + item { + SourceOption( + isSelected = viewModel.selectedSource == SelectedSource.Plugin(null), + onSelect = { viewModel.selectSource(SelectedSource.Plugin(null)) }, + headlineContent = { Text("Any available downloader") }, ) } - if (downloadedApps.isNotEmpty()) { - HorizontalDivider() + viewModel.installedVersion?.let { installedVersion -> + item { + HorizontalDivider() - LazyColumn { - items(downloadedApps, key = { it.version }) { app -> - SourceOption( - isSelected = (viewModel.selectedSource as? SelectedSource.Downloaded)?.version == app.version, - onSelect = { viewModel.selectDownloadedApp(app) }, - headlineContent = { Text(app.version) }, - overlineContent = { Text("Downloaded") }, - ) - } + SourceOption( + isSelected = viewModel.selectedSource == SelectedSource.Installed, + onSelect = { viewModel.selectSource(SelectedSource.Installed) }, + headlineContent = { Text(installedVersion) }, + overlineContent = { Text("Installed") }, + enabled = viewModel.input.version?.let { it == installedVersion } ?: true + ) } } - HorizontalDivider() + if (downloadedApps.isNotEmpty()) item { HorizontalDivider() } - SourceOption( - isSelected = viewModel.selectedSource == SelectedSource.Plugin("plugin-id"), - onSelect = { viewModel.selectSource(SelectedSource.Plugin("plugin-id")) }, - headlineContent = { Text("APKMirror Downloader") }, - overlineContent = { Text("Plugin") }, - ) + items(downloadedApps, key = { it.version }) { app -> + SourceOption( + isSelected = (viewModel.selectedSource as? SelectedSource.Downloaded)?.version == app.version, + onSelect = { viewModel.selectDownloadedApp(app) }, + headlineContent = { Text(app.version) }, + overlineContent = { Text("Downloaded") }, + ) + } - SourceOption( - isSelected = viewModel.selectedSource == SelectedSource.Plugin("another-plugin-id"), - onSelect = { viewModel.selectSource(SelectedSource.Plugin("another-plugin-id")) }, - headlineContent = { Text("Another Plugin") }, - overlineContent = { Text("Plugin") }, - supportingContent = { Text("Untrusted") }, - enabled = false, - ) + if (plugins.isNotEmpty()) item { HorizontalDivider() } + items(plugins, key = { it.first }) { + val packageInfo = remember { + viewModel.getPackageInfo(it.first) + } + + val label = remember { + packageInfo?.applicationInfo?.loadLabel(context.packageManager).toString() + } + + SourceOption( + isSelected = viewModel.selectedSource == SelectedSource.Plugin(it.first), + onSelect = { viewModel.selectSource(SelectedSource.Plugin(it.first)) }, + headlineContent = { Text(label, maxLines = 1, overflow = TextOverflow.Ellipsis) }, + overlineContent = { Text("Plugin") }, + enabled = it.second is DownloaderPluginState.Loaded, + supportingContent = (it.second as? DownloaderPluginState.Untrusted)?.let { { + Text("Not trusted") + } } + ) + } } } } diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/AppSelectorViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/AppSelectorViewModel.kt index cf9f1a57..f85895a5 100644 --- a/app/src/main/java/app/revanced/manager/ui/viewmodel/AppSelectorViewModel.kt +++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/AppSelectorViewModel.kt @@ -3,9 +3,6 @@ package app.revanced.manager.ui.viewmodel import android.app.Application import android.content.pm.PackageInfo import android.net.Uri -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -14,7 +11,6 @@ import androidx.lifecycle.viewmodel.compose.saveable import app.revanced.manager.R import app.revanced.manager.data.platform.Filesystem import app.revanced.manager.domain.repository.PatchBundleRepository -import app.revanced.manager.ui.model.SelectedApp import app.revanced.manager.util.PM import app.revanced.manager.util.toast import kotlinx.coroutines.Dispatchers @@ -47,14 +43,14 @@ class AppSelectorViewModel( val suggestedAppVersions = patchBundleRepository.suggestedVersions.flowOn(Dispatchers.Default) - var nonSuggestedVersionDialogSubject by mutableStateOf(null) - private set +// var nonSuggestedVersionDialogSubject by mutableStateOf(null) +// private set fun loadLabel(app: PackageInfo?) = with(pm) { app?.label() ?: "Not installed" } - fun dismissNonSuggestedVersionDialog() { - nonSuggestedVersionDialogSubject = null - } +// fun dismissNonSuggestedVersionDialog() { +// nonSuggestedVersionDialogSubject = null +// } fun handleStorageResult(uri: Uri) = viewModelScope.launch { val selectedApp = withContext(Dispatchers.IO) { 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 194f4214..7987248c 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 @@ -37,7 +37,7 @@ import app.revanced.manager.patcher.worker.PatcherWorker import app.revanced.manager.plugin.downloader.PluginHostApi import app.revanced.manager.plugin.downloader.UserInteractionException import app.revanced.manager.ui.model.InstallerModel -import app.revanced.manager.ui.model.SelectedApp +import app.revanced.manager.ui.model.SelectedSource import app.revanced.manager.ui.model.State import app.revanced.manager.ui.model.StepCategory import app.revanced.manager.ui.model.Step @@ -93,9 +93,8 @@ class PatcherViewModel( private val ackpineInstaller: PackageInstaller = get() private var installedApp: InstalledApp? = null - private val selectedApp = input.selectedApp - val packageName = selectedApp.packageName - val version = selectedApp.version + val packageName = input.packageName + val version = input.version var installedPackageName by savedStateHandle.saveable( key = "installedPackageName", @@ -160,7 +159,7 @@ class PatcherViewModel( } val steps by savedStateHandle.saveable(saver = snapshotStateListSaver()) { - generateSteps(app, input.selectedApp, input.selectedPatches).toMutableStateList() + generateSteps(app, input.selectedSource, input.selectedPatches).toMutableStateList() } val progress by derivedStateOf { @@ -178,7 +177,9 @@ class PatcherViewModel( ParcelUuid( workerRepository.launchExpedited( "patching", PatcherWorker.Args( - input.selectedApp, + input.packageName, + input.version, + input.selectedSource, outputFile.path, input.selectedPatches, input.options, @@ -257,7 +258,7 @@ class PatcherViewModel( super.onCleared() workManager.cancelWorkById(patcherWorkerId.uuid) - if (input.selectedApp is SelectedApp.Installed && installedApp?.installType == InstallType.MOUNT) { + if (input.selectedSource is SelectedSource.Installed && installedApp?.installType == InstallType.MOUNT) { GlobalScope.launch(Dispatchers.Main) { uiSafe(app, R.string.failed_to_mount, "Failed to mount") { withTimeout(Duration.ofMinutes(1L)) { @@ -381,7 +382,7 @@ class PatcherViewModel( installedAppRepository.addOrUpdate( installerPkgName, packageName, - input.selectedApp.version + input.version ?: withContext(Dispatchers.IO) { pm.getPackageInfo(outputFile)?.versionName!! }, InstallType.DEFAULT, input.selectedPatches @@ -443,7 +444,7 @@ class PatcherViewModel( } } - val inputVersion = input.selectedApp.version + val inputVersion = input.version ?: withContext(Dispatchers.IO) { inputFile?.let(pm::getPackageInfo)?.versionName } ?: throw Exception("Failed to determine input APK version") @@ -535,10 +536,10 @@ class PatcherViewModel( fun generateSteps( context: Context, - selectedApp: SelectedApp, + selectedSource: SelectedSource, selectedPatches: PatchSelection ): List = buildList { - if (selectedApp is SelectedApp.Download || selectedApp is SelectedApp.Search) + if (selectedSource is SelectedSource.Plugin) add( Step( StepId.DownloadAPK, 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 f6aee73f..daa8dbfd 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 @@ -14,7 +14,6 @@ import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi import androidx.lifecycle.viewmodel.compose.saveable import app.revanced.manager.R -import app.revanced.manager.data.room.apps.installed.InstalledApp import app.revanced.manager.domain.manager.PreferencesManager import app.revanced.manager.domain.repository.DownloaderPluginRepository import app.revanced.manager.domain.repository.InstalledAppRepository @@ -25,7 +24,6 @@ import app.revanced.manager.patcher.patch.PatchBundleInfo import app.revanced.manager.patcher.patch.PatchBundleInfo.Extensions.requiredOptionsSet import app.revanced.manager.patcher.patch.PatchBundleInfo.Extensions.toPatchSelection import app.revanced.manager.plugin.downloader.PluginHostApi -import app.revanced.manager.ui.model.SelectedApp import app.revanced.manager.ui.model.SelectedSource import app.revanced.manager.ui.model.SelectedVersion import app.revanced.manager.ui.model.navigation.Patcher @@ -201,8 +199,8 @@ class SelectedAppInfoViewModel( - var installedAppData: Pair? by mutableStateOf(null) - private set +// var installedAppData: Pair? by mutableStateOf(null) +// private set private var _selectedApp by savedStateHandle.saveable { mutableStateOf(null) @@ -229,7 +227,7 @@ class SelectedAppInfoViewModel( val errorFlow = combine(plugins, snapshotFlow { selectedApp }) { pluginsList, app -> when { - app is SelectedApp.Search && pluginsList.isEmpty() -> Error.NoPlugins +// app is SelectedApp.Search && pluginsList.isEmpty() -> Error.NoPlugins else -> null } } @@ -253,7 +251,9 @@ class SelectedAppInfoViewModel( val allowIncompatible = prefs.disablePatchVersionCompatCheck.get() val bundles = bundleInfoFlow.first() return Patcher.ViewModelParams( - SelectedApp.Installed(packageName, version = "123"), // TODO + input.packageName, + resolvedVersion.first(), + resolvedSource.first(), patchSelection.first(), getOptionsFiltered(bundles) ) @@ -287,13 +287,13 @@ class SelectedAppInfoViewModel( val installedAppDeferred = async(Dispatchers.IO) { installedAppRepository.get(packageName) } - installedAppData = - packageInfo.await()?.let { - SelectedApp.Installed( - packageName, - it.versionName!! - ) to installedAppDeferred.await() - } +// installedAppData = +// packageInfo.await()?.let { +// SelectedApp.Installed( +// packageName, +// it.versionName!! +// ) to installedAppDeferred.await() +// } } } diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/SourceSelectorViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/SourceSelectorViewModel.kt index 4dd45090..32250ce1 100644 --- a/app/src/main/java/app/revanced/manager/ui/viewmodel/SourceSelectorViewModel.kt +++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/SourceSelectorViewModel.kt @@ -7,6 +7,8 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.revanced.manager.data.room.apps.downloaded.DownloadedApp import app.revanced.manager.domain.repository.DownloadedAppRepository +import app.revanced.manager.domain.repository.DownloaderPluginRepository +import app.revanced.manager.network.downloader.DownloaderPluginState import app.revanced.manager.ui.model.SelectedSource import app.revanced.manager.ui.model.navigation.SelectedAppInfo import app.revanced.manager.util.PM @@ -19,11 +21,18 @@ class SourceSelectorViewModel( val input: SelectedAppInfo.SourceSelector.ViewModelParams ) : ViewModel(), KoinComponent { private val downloadedAppRepository: DownloadedAppRepository = get() + private val pluginRepository: DownloaderPluginRepository = get() private val pm: PM = get() val downloadedApps = downloadedAppRepository.get(input.packageName) .map { it.sortedByDescending { app -> app.version } } + val plugins = pluginRepository.pluginStates.map { plugins -> + plugins.toList().sortedByDescending { it.second is DownloaderPluginState.Loaded } + } + + fun getPackageInfo(packageName: String) = pm.getPackageInfo(packageName) + var selectedSource by mutableStateOf(input.selectedSource) private set