Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: View bundle patches #2065

Merged
merged 13 commits into from
Aug 24, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ import androidx.compose.ui.res.stringResource
import app.revanced.manager.R

@Composable
fun ArrowButton(modifier: Modifier = Modifier, expanded: Boolean, onClick: (() -> Unit)?) {
fun ArrowButton(
modifier: Modifier = Modifier,
expanded: Boolean,
onClick: (() -> Unit)? = null,
rotationInitial: Float = 0f,
rotationFinal: Float = 180f
Ushie marked this conversation as resolved.
Show resolved Hide resolved
) {
val description = if (expanded) R.string.collapse_content else R.string.expand_content
val rotation by animateFloatAsState(
targetValue = if (expanded) 0f else 180f,
targetValue = if (expanded) rotationInitial else rotationFinal,
label = "rotation"
)

Expand Down
Ushie marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
package app.revanced.manager.ui.component.bundle

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.outlined.Lightbulb
import androidx.compose.material3.ExperimentalMaterial3Api
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.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import app.revanced.manager.R
import app.revanced.manager.domain.bundles.PatchBundleSource
import app.revanced.manager.patcher.patch.PatchInfo
import app.revanced.manager.ui.component.ArrowButton
import app.revanced.manager.ui.component.LazyColumnWithScrollbar
import app.revanced.manager.ui.component.NotificationCard

Expand All @@ -36,13 +35,13 @@ fun BundlePatchesDialog(
bundle: PatchBundleSource,
) {
var informationCardVisible by remember { mutableStateOf(true) }
var showAllVersions by remember { mutableStateOf(false) }
var showOptions by remember { mutableStateOf(false) }
Ushie marked this conversation as resolved.
Show resolved Hide resolved
val state by bundle.state.collectAsStateWithLifecycle()

Dialog(
onDismissRequest = onDismissRequest,
properties = DialogProperties(
usePlatformDefaultWidth = false,
dismissOnBackPress = true
onDismissRequest = onDismissRequest, properties = DialogProperties(
usePlatformDefaultWidth = false, dismissOnBackPress = true
Ushie marked this conversation as resolved.
Show resolved Hide resolved
)
) {
Scaffold(
Expand All @@ -62,44 +61,204 @@ fun BundlePatchesDialog(
LazyColumnWithScrollbar(
modifier = Modifier
.fillMaxWidth()
.padding(paddingValues)
.padding(16.dp)
.padding(paddingValues),
verticalArrangement = Arrangement.spacedBy(12.dp),
contentPadding = PaddingValues(16.dp)
) {
item {
AnimatedVisibility(visible = informationCardVisible) {
NotificationCard(
icon = Icons.Outlined.Lightbulb,
NotificationCard(icon = Icons.Outlined.Lightbulb,
text = stringResource(R.string.tap_on_patches),
onDismiss = { informationCardVisible = false }
)
onDismiss = { informationCardVisible = false })
}
}

state.patchBundleOrNull()?.let { bundle ->
items(bundle.patches.size) { bundleIndex ->
val patch = bundle.patches[bundleIndex]
ListItem(
headlineContent = {
Text(
text = patch.name,
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurface
)
},
supportingContent = {
patch.description?.let {
Text(
text = it,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
PatchItem(patch,
Ushie marked this conversation as resolved.
Show resolved Hide resolved
showAllVersions,
onExpandVersions = { showAllVersions = !showAllVersions },
showOptions,
onExpandOptions = { showOptions = !showOptions })
}
}
}
}
}
}

@OptIn(ExperimentalLayoutApi::class)
@Composable
fun PatchItem(
patch: PatchInfo,
expandVersions: Boolean,
onExpandVersions: () -> Unit,
expandOptions: Boolean,
onExpandOptions: () -> Unit
) {
ElevatedCard(
modifier = Modifier
.fillMaxWidth()
.then(
if (patch.options.isNullOrEmpty()) Modifier else Modifier
.clip(RoundedCornerShape(8.dp))
.clickable { onExpandOptions() },
Ushie marked this conversation as resolved.
Show resolved Hide resolved
)
) {
Column(
modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(6.dp)
Ushie marked this conversation as resolved.
Show resolved Hide resolved
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Absolute.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = patch.name,
color = MaterialTheme.colorScheme.primary,
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold
)

if (!patch.options.isNullOrEmpty()) {
ArrowButton(expanded = expandOptions)
}
}
patch.description?.let {
Text(
text = it, style = MaterialTheme.typography.bodyMedium
Ushie marked this conversation as resolved.
Show resolved Hide resolved
)
}
Column(
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
if (!patch.compatiblePackages.isNullOrEmpty()) {
Ushie marked this conversation as resolved.
Show resolved Hide resolved
patch.compatiblePackages.forEach { compatiblePackage ->
val packageName = compatiblePackage.packageName
val versions = compatiblePackage.versions.orEmpty().reversed()
Axelen123 marked this conversation as resolved.
Show resolved Hide resolved
val itemCount = if (versions.isEmpty()) 1 else versions.size + 1
Ushie marked this conversation as resolved.
Show resolved Hide resolved

FlowRow(
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
PatchInfoChip(
modifier = Modifier.align(Alignment.CenterVertically),
text = "\uD83D\uDCE6 $packageName"
)

if (versions.isNotEmpty()) {
if (expandVersions) {
versions.forEach { version ->
PatchInfoChip(
modifier = Modifier.align(Alignment.CenterVertically),
text = "\uD83C\uDFAF $version"
)
}
} else {
PatchInfoChip(
modifier = Modifier.align(Alignment.CenterVertically),
text = "\uD83C\uDFAF ${versions.first()}"
Ushie marked this conversation as resolved.
Show resolved Hide resolved
)
}
if (versions.size > 1) {
PatchInfoChip(
onClick = onExpandVersions,
text = if (expandVersions) "Less" else "+${itemCount - 2}"
Ushie marked this conversation as resolved.
Show resolved Hide resolved
)
}
}
}
}
} else {
Row(
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalAlignment = Alignment.CenterVertically
) {
PatchInfoChip(
text = "\uD83D\uDCE6 Any package"
)
PatchInfoChip(
text = "\uD83C\uDFAF Any version"
Ushie marked this conversation as resolved.
Show resolved Hide resolved
)
HorizontalDivider()
}
}
}
if (!patch.options.isNullOrEmpty()) {
AnimatedVisibility(visible = expandOptions) {
val options = patch.options

Column {
options.forEachIndexed { i, option ->
OutlinedCard(
modifier = Modifier.fillMaxWidth(), colors = CardColors(
containerColor = Color.Transparent,
contentColor = MaterialTheme.colorScheme.onSurface,
disabledContainerColor = Color.Transparent,
disabledContentColor = MaterialTheme.colorScheme.onSurface
Ushie marked this conversation as resolved.
Show resolved Hide resolved
), shape = when {
i == 0 && options.lastIndex == 0 -> RoundedCornerShape(8.dp)
Ushie marked this conversation as resolved.
Show resolved Hide resolved
i == 0 -> RoundedCornerShape(topStart = 8.dp, topEnd = 8.dp)
i == options.lastIndex -> RoundedCornerShape(bottomStart = 8.dp, bottomEnd = 8.dp)
else -> RoundedCornerShape(0.dp)
}
) {
Column(
modifier = Modifier.padding(12.dp),
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
Text(
text = option.title,
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.primary
)
Text(
text = option.description, style = MaterialTheme.typography.bodyMedium
Ushie marked this conversation as resolved.
Show resolved Hide resolved
)
}
}
}
}
}
}
}
}
}

@Composable
fun PatchInfoChip(
modifier: Modifier = Modifier, onClick: (() -> Unit)? = null, text: String, icon: @Composable (() -> Unit)? = null
) {
val shape = RoundedCornerShape(8.0.dp)
val cardModifier = if (onClick != null) {
Modifier
.clip(shape)
.clickable(onClick = onClick)
} else {
Modifier
}

OutlinedCard(
modifier = modifier.then(cardModifier), colors = CardColors(
Ushie marked this conversation as resolved.
Show resolved Hide resolved
containerColor = Color.Transparent,
contentColor = MaterialTheme.colorScheme.onSurface,
disabledContainerColor = Color.Transparent,
disabledContentColor = MaterialTheme.colorScheme.onSurface
Ushie marked this conversation as resolved.
Show resolved Hide resolved
), shape = shape, border = BorderStroke(1.dp, MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.20f))
) {
Row(
modifier = Modifier.padding(8.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Text(
text,
overflow = TextOverflow.Ellipsis,
softWrap = false,
style = MaterialTheme.typography.labelLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
}
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[versions]
ktx = "1.13.1"
material3 = "1.2.1"
material3 = "1.3.0-beta05"
Ushie marked this conversation as resolved.
Show resolved Hide resolved
ui-tooling = "1.6.8"
viewmodel-lifecycle = "2.8.3"
splash-screen = "1.0.1"
Expand Down