mirror of
https://github.com/revanced/revanced-manager
synced 2024-05-14 13:56:57 +02:00
229 lines
8.2 KiB
Kotlin
229 lines
8.2 KiB
Kotlin
package app.revanced.manager.ui.screen
|
|
|
|
import android.content.pm.PackageInfo
|
|
import androidx.annotation.StringRes
|
|
import androidx.compose.foundation.clickable
|
|
import androidx.compose.foundation.layout.Column
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.material.icons.Icons
|
|
import androidx.compose.material.icons.automirrored.outlined.ArrowRight
|
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
import androidx.compose.material3.Icon
|
|
import androidx.compose.material3.ListItem
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.Scaffold
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.derivedStateOf
|
|
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.res.stringResource
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|
import app.revanced.manager.R
|
|
import app.revanced.manager.ui.component.AppInfo
|
|
import app.revanced.manager.ui.component.AppTopBar
|
|
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
|
|
import app.revanced.manager.ui.viewmodel.SelectedAppInfoViewModel
|
|
import app.revanced.manager.util.Options
|
|
import app.revanced.manager.util.PatchesSelection
|
|
import app.revanced.manager.util.toast
|
|
import dev.olshevski.navigation.reimagined.AnimatedNavHost
|
|
import dev.olshevski.navigation.reimagined.NavBackHandler
|
|
import dev.olshevski.navigation.reimagined.navigate
|
|
import dev.olshevski.navigation.reimagined.pop
|
|
import dev.olshevski.navigation.reimagined.rememberNavController
|
|
import org.koin.androidx.compose.getViewModel
|
|
import org.koin.core.parameter.parametersOf
|
|
|
|
@Composable
|
|
fun SelectedAppInfoScreen(
|
|
onPatchClick: (SelectedApp, PatchesSelection, Options) -> Unit,
|
|
onBackClick: () -> Unit,
|
|
vm: SelectedAppInfoViewModel
|
|
) {
|
|
val context = LocalContext.current
|
|
|
|
val packageName = vm.selectedApp.packageName
|
|
val version = vm.selectedApp.version
|
|
val bundles by remember(packageName, version) {
|
|
vm.bundlesRepo.bundleInfoFlow(packageName, version)
|
|
}.collectAsStateWithLifecycle(initialValue = emptyList())
|
|
|
|
val allowExperimental by vm.prefs.allowExperimental.getAsState()
|
|
val patches by remember {
|
|
derivedStateOf {
|
|
vm.getPatches(bundles, allowExperimental)
|
|
}
|
|
}
|
|
val selectedPatchCount by remember {
|
|
derivedStateOf {
|
|
patches.values.sumOf { it.size }
|
|
}
|
|
}
|
|
val availablePatchCount by remember {
|
|
derivedStateOf {
|
|
bundles.sumOf { it.patchCount }
|
|
}
|
|
}
|
|
|
|
val navController =
|
|
rememberNavController<SelectedAppInfoDestination>(startDestination = SelectedAppInfoDestination.Main)
|
|
|
|
NavBackHandler(controller = navController)
|
|
|
|
AnimatedNavHost(controller = navController) { destination ->
|
|
when (destination) {
|
|
is SelectedAppInfoDestination.Main -> SelectedAppInfoScreen(
|
|
onPatchClick = patchClick@{
|
|
if (selectedPatchCount == 0) {
|
|
context.toast(context.getString(R.string.no_patches_selected))
|
|
|
|
return@patchClick
|
|
}
|
|
onPatchClick(
|
|
vm.selectedApp,
|
|
patches,
|
|
vm.getOptionsFiltered(bundles)
|
|
)
|
|
},
|
|
onPatchSelectorClick = {
|
|
navController.navigate(
|
|
SelectedAppInfoDestination.PatchesSelector(
|
|
vm.selectedApp,
|
|
vm.getCustomPatches(
|
|
bundles,
|
|
allowExperimental
|
|
),
|
|
vm.options
|
|
)
|
|
)
|
|
},
|
|
onVersionSelectorClick = {
|
|
navController.navigate(SelectedAppInfoDestination.VersionSelector)
|
|
},
|
|
onBackClick = onBackClick,
|
|
availablePatchCount = availablePatchCount,
|
|
selectedPatchCount = selectedPatchCount,
|
|
packageName = packageName,
|
|
version = version,
|
|
packageInfo = vm.selectedAppInfo,
|
|
)
|
|
|
|
is SelectedAppInfoDestination.VersionSelector -> VersionSelectorScreen(
|
|
onBackClick = navController::pop,
|
|
onAppClick = {
|
|
vm.selectedApp = it
|
|
navController.pop()
|
|
},
|
|
viewModel = getViewModel { parametersOf(packageName) }
|
|
)
|
|
|
|
is SelectedAppInfoDestination.PatchesSelector -> PatchesSelectorScreen(
|
|
onSave = { patches, options ->
|
|
vm.updateConfiguration(patches, options, bundles)
|
|
navController.pop()
|
|
},
|
|
onBackClick = navController::pop,
|
|
vm = getViewModel {
|
|
parametersOf(
|
|
PatchesSelectorViewModel.Params(
|
|
destination.app,
|
|
destination.currentSelection,
|
|
destination.options,
|
|
)
|
|
)
|
|
}
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@OptIn(ExperimentalMaterial3Api::class)
|
|
@Composable
|
|
private fun SelectedAppInfoScreen(
|
|
onPatchClick: () -> Unit,
|
|
onPatchSelectorClick: () -> Unit,
|
|
onVersionSelectorClick: () -> Unit,
|
|
onBackClick: () -> Unit,
|
|
availablePatchCount: Int,
|
|
selectedPatchCount: Int,
|
|
packageName: String,
|
|
version: String,
|
|
packageInfo: PackageInfo?,
|
|
) {
|
|
Scaffold(
|
|
topBar = {
|
|
AppTopBar(
|
|
title = stringResource(R.string.app_info),
|
|
onBackClick = onBackClick
|
|
)
|
|
}
|
|
) { paddingValues ->
|
|
Column(
|
|
modifier = Modifier
|
|
.fillMaxSize()
|
|
.padding(paddingValues)
|
|
) {
|
|
AppInfo(packageInfo, placeholderLabel = packageName) {
|
|
Text(
|
|
stringResource(R.string.selected_app_meta, version, availablePatchCount),
|
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
style = MaterialTheme.typography.bodyMedium,
|
|
)
|
|
}
|
|
|
|
PageItem(R.string.patch, stringResource(R.string.patch_item_description), onPatchClick)
|
|
|
|
Text(
|
|
stringResource(R.string.advanced),
|
|
color = MaterialTheme.colorScheme.primary,
|
|
style = MaterialTheme.typography.labelLarge,
|
|
modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp)
|
|
)
|
|
|
|
PageItem(
|
|
R.string.patch_selector_item,
|
|
stringResource(R.string.patch_selector_item_description, selectedPatchCount),
|
|
onPatchSelectorClick
|
|
)
|
|
PageItem(
|
|
R.string.version_selector_item,
|
|
stringResource(R.string.version_selector_item_description, version),
|
|
onVersionSelectorClick
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
private fun PageItem(@StringRes title: Int, description: String, onClick: () -> Unit) {
|
|
ListItem(
|
|
modifier = Modifier
|
|
.clickable(onClick = onClick)
|
|
.padding(start = 8.dp),
|
|
headlineContent = {
|
|
Text(
|
|
stringResource(title),
|
|
color = MaterialTheme.colorScheme.onSurface,
|
|
style = MaterialTheme.typography.titleLarge
|
|
)
|
|
},
|
|
supportingContent = {
|
|
Text(
|
|
description,
|
|
color = MaterialTheme.colorScheme.outline,
|
|
style = MaterialTheme.typography.bodyMedium
|
|
)
|
|
},
|
|
trailingContent = {
|
|
Icon(Icons.AutoMirrored.Outlined.ArrowRight, null)
|
|
}
|
|
)
|
|
} |