Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ class DownloaderRepository(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) Api30ResourceImpl(File(apkPath))
else OldResourceImpl(resources)

val packageLabel = with(pm) { packageInfo.label() }

return DownloaderPackage(
classNames.map { className ->
val downloader = classLoader
Expand All @@ -176,6 +178,7 @@ class DownloaderRepository(

LoadedDownloader(
packageName,
packageLabel,
className,
resources.getString(downloader.name),
scopeImpl,
Expand All @@ -185,7 +188,7 @@ class DownloaderRepository(
classLoader,
resourceImpl,
packageInfo.packageName,
with(pm) { packageInfo.label() },
packageLabel,
packageInfo.versionName.orEmpty()
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import app.revanced.manager.downloader.Scope

class LoadedDownloader(
val packageName: String,
val packageLabel: String,
val className: String,
val name: String,
val scopeImpl: Scope,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import androidx.annotation.StringRes
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
Expand All @@ -15,15 +14,14 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.AutoFixHigh
import androidx.compose.material.icons.outlined.WarningAmber
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.HorizontalDivider
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.material3.TextButton
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
Expand All @@ -46,10 +44,10 @@ import app.revanced.manager.data.platform.NetworkInfo
import app.revanced.manager.network.downloader.LoadedDownloader
import app.revanced.manager.patcher.patch.PatchBundleInfo
import app.revanced.manager.patcher.patch.PatchInfo
import app.revanced.manager.ui.component.AlertDialogExtended
import app.revanced.manager.ui.component.AppInfo
import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.ColumnWithScrollbar
import app.revanced.manager.ui.component.FullscreenDialog
import app.revanced.manager.ui.component.LoadingIndicator
import app.revanced.manager.ui.component.NotificationCard
import app.revanced.manager.ui.component.NotificationCardType
Expand Down Expand Up @@ -165,7 +163,7 @@ fun SelectedAppInfoScreen(
}

val error by vm.errorFlow.collectAsStateWithLifecycle(null)
val downloaders by vm.downloaders.collectAsStateWithLifecycle(emptyList())
val downloaders by vm.downloaders.collectAsStateWithLifecycle(emptyMap())

val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())

Expand Down Expand Up @@ -298,17 +296,18 @@ fun SelectedAppInfoScreen(
)
}
)
PageItem(
R.string.version,
selectedVersionLabel,
warningDescription = if (showVersionCompatibilityWarning) {
stringResource(R.string.version_compatibility_warning)
} else {
null
},
enabled = versionOptions.unrestricted || versionOptions.versions.isNotEmpty(),
onClick = { showVersionSelector = true }
)
if (versionOptions.versions.isNotEmpty()) {
PageItem(
R.string.version,
selectedVersionLabel,
warningDescription = if (showVersionCompatibilityWarning) {
stringResource(R.string.version_compatibility_warning)
} else {
null
},
onClick = { showVersionSelector = true }
)
}
val autoSourceSubtitle = run {
val resolved = vm.resolveAutoSource(vm.selectedApp.version)
when {
Expand All @@ -325,8 +324,10 @@ fun SelectedAppInfoScreen(
is SelectedApp.Installed -> stringResource(R.string.apk_source_installed)
is SelectedApp.Download -> stringResource(
R.string.apk_source_downloader,
downloaders.find { it.packageName == app.data.downloaderPackageName && it.name == app.data.downloaderClassName }?.name
?: app.data.downloaderPackageName
downloaders.values
.flatten()
.find { it.className == app.data.downloaderClassName }
?.packageLabel ?: app.data.downloaderPackageName
)

is SelectedApp.Local -> stringResource(R.string.apk_source_local)
Expand Down Expand Up @@ -373,15 +374,13 @@ fun SelectedAppInfoScreen(
private fun PageItem(
@StringRes title: Int,
description: String,
enabled: Boolean = true,
warningDescription: String? = null,
warningColor: Color = Color.Unspecified,
onClick: () -> Unit
) {
ListItem(
modifier = Modifier
.clickable(enabled = enabled, onClick = onClick)
.enabled(enabled)
.clickable(onClick = onClick)
.padding(start = 8.dp),
headlineContent = {
Text(
Expand Down Expand Up @@ -463,7 +462,7 @@ private fun PatchInfo.versionConstraintFor(packageName: String): Set<String>? {
return pkg.versions?.toSet()?.takeIf { it.isNotEmpty() }
}

@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
private fun VersionSelectorDialog(
selectedVersion: String?,
Expand All @@ -472,17 +471,16 @@ private fun VersionSelectorDialog(
onDismissRequest: () -> Unit,
onSelect: (String?) -> Unit
) {
AlertDialogExtended(
onDismissRequest = onDismissRequest,
confirmButton = {
TextButton(onClick = onDismissRequest, shapes = ButtonDefaults.shapes()) {
Text(stringResource(R.string.cancel))
FullscreenDialog(onDismissRequest) {
Scaffold(
topBar = {
AppTopBar(
title = stringResource(R.string.version),
onBackClick = onDismissRequest
)
}
},
title = { Text(stringResource(R.string.version)) },
textHorizontalPadding = PaddingValues(horizontal = 0.dp),
text = {
LazyColumn {
) { paddingValues ->
LazyColumn(modifier = Modifier.padding(paddingValues)) {
if (allowAnyVersion) {
item(key = "any") {
ListItem(
Expand Down Expand Up @@ -515,13 +513,13 @@ private fun VersionSelectorDialog(
}
}
}
)
}
}

@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
private fun AppSourceSelectorDialog(
downloaders: List<LoadedDownloader>,
downloaders: Map<String, List<LoadedDownloader>>,
downloadedApps: List<SelectedApp.Local>,
activeSearchJob: LoadedDownloader?,
requiredVersion: String?,
Expand All @@ -534,77 +532,106 @@ private fun AppSourceSelectorDialog(
) {
val canSelect = activeSearchJob == null

AlertDialogExtended(
onDismissRequest = onDismissRequest,
confirmButton = {
TextButton(onClick = onDismissRequest, shapes = ButtonDefaults.shapes()) {
Text(stringResource(R.string.cancel))
val hasDownloaded = downloadedApps.any {
requiredVersion == null || it.version == requiredVersion
}
val hasAutoSource =
downloaders.isNotEmpty() ||
hasDownloaded ||
autoSelection is SelectedApp.Installed

FullscreenDialog(onDismissRequest) {
Scaffold(
topBar = {
AppTopBar(
title = stringResource(R.string.app_source_dialog_title),
onBackClick = onDismissRequest
)
}
},
title = { Text(stringResource(R.string.app_source_dialog_title)) },
textHorizontalPadding = PaddingValues(horizontal = 0.dp),
text = {
LazyColumn {
item(key = "auto") {
val hasDownloader = downloaders.isNotEmpty()
val hasDownloaded =
downloadedApps.any { app -> requiredVersion == null || app.version == requiredVersion }
val hasAutoSource =
hasDownloader || hasDownloaded || autoSelection is SelectedApp.Installed
) { paddingValues ->
LazyColumn(Modifier.padding(paddingValues)) {
item("auto") {
ListItem(
modifier = Modifier
.clickable(enabled = canSelect && hasAutoSource) { onSelectAuto() }
.clickable(
enabled = canSelect && hasAutoSource,
onClick = onSelectAuto
)
.enabled(hasAutoSource),
headlineContent = { Text(stringResource(R.string.app_source_dialog_option_auto)) },
headlineContent = {
Text(stringResource(R.string.app_source_dialog_option_auto))
},
supportingContent = {
Text(
if (hasAutoSource)
stringResource(R.string.app_source_dialog_option_auto_description)
else
stringResource(R.string.app_source_dialog_option_auto_unavailable)
stringResource(
if (hasAutoSource)
R.string.app_source_dialog_option_auto_description
else
R.string.app_source_dialog_option_auto_unavailable
)
)
},
colors = transparentListItemColors
)
}

items(
downloadedApps,
key = { "downloaded_${it.version}" }
) { app ->
val usable = requiredVersion == null || app.version == requiredVersion
item("storage") {
ListItem(
modifier = Modifier
.clickable(enabled = canSelect && usable) { onSelect(app) }
.enabled(usable),
headlineContent = { Text(stringResource(R.string.apk_source_downloaded)) },
supportingContent = { Text(app.version) },
modifier = Modifier.clickable(onClick = onSelectFromStorage),
headlineContent = { Text(stringResource(R.string.select_from_storage)) },
supportingContent = { Text(stringResource(R.string.select_from_storage_description)) },
colors = transparentListItemColors
)
}

items(downloaders) { downloader ->
ListItem(
modifier = Modifier.clickable(enabled = canSelect) {
onSelectDownloader(
downloader
)
},
headlineContent = { Text(downloader.name) },
trailingContent = (@Composable { LoadingIndicator() }).takeIf { activeSearchJob == downloader },
colors = transparentListItemColors
)
if (downloadedApps.isNotEmpty()) {
item { HorizontalDivider() }

items(downloadedApps, key = { it.version }) { app ->
val usable =
requiredVersion == null || app.version == requiredVersion

ListItem(
modifier = Modifier
.clickable(enabled = canSelect && usable) { onSelect(app) }
.enabled(usable),
headlineContent = { Text(app.packageName) },
supportingContent = { Text(app.version) },
overlineContent = {
Text(stringResource(R.string.source_selector_category_downloaded))
},
colors = transparentListItemColors
)
}
}

item(key = "storage") {
ListItem(
modifier = Modifier.clickable { onSelectFromStorage() },
headlineContent = { Text(stringResource(R.string.select_from_storage)) },
supportingContent = { Text(stringResource(R.string.select_from_storage_description)) },
colors = transparentListItemColors
)
if (downloaders.isNotEmpty()) {
item { HorizontalDivider() }

downloaders.forEach { (name, list) ->
items(list) { downloader ->
ListItem(
modifier = Modifier.clickable(enabled = canSelect) {
onSelectDownloader(downloader)
},
headlineContent = { Text(downloader.name) },
trailingContent = {
if (activeSearchJob == downloader) {
LoadingIndicator()
}
},
overlineContent = {
Text(name)
},
supportingContent = {
if (!requiredVersion.isNullOrEmpty()) Text("${autoSelection.packageName} ${autoSelection.version}")
},
colors = transparentListItemColors
)
}
}
}
}
}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
Expand All @@ -83,7 +84,9 @@ class SelectedAppInfoViewModel(
private val pm: PM = get()
private val savedStateHandle: SavedStateHandle = get()
val prefs: PreferencesManager = get()
val downloaders = downloaderRepository.loadedDownloadersFlow
val downloaders = downloaderRepository.loadedDownloadersFlow.map { list ->
list.groupBy { it.packageLabel }
}
val allDownloaders = downloaderRepository.downloaderSources
val packageName = input.app.packageName

Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ Tap them for more details.</string>

<string name="sideeffect_restart">Restart the app to see changes</string>
<string name="sideeffect_no_network">You’re offline. Check your internet connection.</string>
<string name="source_selector_category_downloaded">Previously downloaded</string>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "previously" is misleading here. I assume once cache is cleared, the apps would disappear. Just say "Downloaded" maybe?


<plurals name="patch_count">
<item quantity="one">%d patch</item>
Expand Down