Skip to content

Commit

Permalink
feat: filter options for patches
Browse files Browse the repository at this point in the history
  • Loading branch information
CnC-Robert committed Jun 15, 2023
1 parent 535efa3 commit 6309e8b
Show file tree
Hide file tree
Showing 3 changed files with 246 additions and 116 deletions.
312 changes: 205 additions & 107 deletions app/src/main/java/app/revanced/manager/ui/screen/PatchesSelectorScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ package app.revanced.manager.ui.screen

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.pager.HorizontalPager
Expand All @@ -12,7 +17,21 @@ import androidx.compose.material.icons.filled.Build
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material3.*
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Checkbox
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FilterChip
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.ScrollableTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
Expand All @@ -24,8 +43,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import app.revanced.manager.R
import app.revanced.manager.patcher.patch.PatchInfo
import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.GroupHeader
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_SUPPORTED
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNIVERSAL
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNSUPPORTED
import app.revanced.manager.util.PatchesSelection
import kotlinx.coroutines.launch

Expand All @@ -43,27 +64,43 @@ fun PatchesSelectorScreen(

val bundles by vm.bundlesFlow.collectAsStateWithLifecycle(initialValue = emptyList())

if (vm.showUnsupportedDialog) UnsupportedDialog(onDismissRequest = vm::dismissDialogs)
if (vm.compatibleVersions.isNotEmpty())
UnsupportedDialog(
appVersion = vm.appInfo.packageInfo!!.versionName,
supportedVersions = vm.compatibleVersions,
onDismissRequest = vm::dismissDialogs
)

if (vm.showOptionsDialog) OptionsDialog(onDismissRequest = vm::dismissDialogs, onConfirm = {})

Scaffold(topBar = {
AppTopBar(title = stringResource(R.string.select_patches), onBackClick = onBackClick, actions = {
IconButton(onClick = { }) {
Icon(Icons.Outlined.HelpOutline, stringResource(R.string.help))
}
IconButton(onClick = { }) {
Icon(Icons.Outlined.Search, stringResource(R.string.search))
}
})
}, floatingActionButton = {
ExtendedFloatingActionButton(text = { Text(stringResource(R.string.patch)) },
icon = { Icon(Icons.Default.Build, null) },
onClick = { onPatchClick(vm.generateSelection()) })
}) { paddingValues ->
Column(Modifier.fillMaxSize().padding(paddingValues)) {
Scaffold(
topBar = {
AppTopBar(
title = stringResource(R.string.select_patches),
onBackClick = onBackClick,
actions = {
IconButton(onClick = { }) {
Icon(Icons.Outlined.HelpOutline, stringResource(R.string.help))
}
IconButton(onClick = { }) {
Icon(Icons.Outlined.Search, stringResource(R.string.search))
}
}
)
},
floatingActionButton = {
ExtendedFloatingActionButton(text = { Text(stringResource(R.string.patch)) },
icon = { Icon(Icons.Default.Build, null) },
onClick = { onPatchClick(vm.generateSelection()) })
}
) { paddingValues ->
Column(
Modifier
.fillMaxSize()
.padding(paddingValues)
) {
if (bundles.size > 1) {
TabRow(
ScrollableTabRow(
selectedTabIndex = pagerState.currentPage,
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp)
) {
Expand All @@ -85,54 +122,95 @@ fun PatchesSelectorScreen(
userScrollEnabled = true,
pageContent = { index ->

val (bundleName, supportedPatches, unsupportedPatches) = bundles[index]

LazyColumn(
modifier = Modifier.fillMaxSize()
) {
items(
items = supportedPatches
) { patch ->
PatchItem(
patch = patch,
onOptionsDialog = vm::openOptionsDialog,
onToggle = {
vm.togglePatch(bundleName, patch)
},
selected = vm.isSelected(bundleName, patch),
supported = true
val (bundleName, supportedPatches, unsupportedPatches, universalPatches) = bundles[index]

Column {

Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 10.dp, vertical = 2.dp),
horizontalArrangement = Arrangement.spacedBy(5.dp)
) {
FilterChip(
selected = vm.filter and SHOW_SUPPORTED != 0,
onClick = { vm.toggleFlag(SHOW_SUPPORTED) },
label = { Text(stringResource(R.string.supported)) }
)

FilterChip(
selected = vm.filter and SHOW_UNIVERSAL != 0,
onClick = { vm.toggleFlag(SHOW_UNIVERSAL) },
label = { Text(stringResource(R.string.universal)) }
)

FilterChip(
selected = vm.filter and SHOW_UNSUPPORTED != 0,
onClick = { vm.toggleFlag(SHOW_UNSUPPORTED) },
label = { Text(stringResource(R.string.unsupported)) }
)
}

if (unsupportedPatches.isNotEmpty()) {
item {
Row(
modifier = Modifier.fillMaxWidth().padding(horizontal = 14.dp).padding(end = 10.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
GroupHeader(stringResource(R.string.unsupported_patches), Modifier.padding(0.dp))
IconButton(onClick = vm::openUnsupportedDialog) {
Icon(
Icons.Outlined.HelpOutline, stringResource(R.string.help)
)
}
LazyColumn(
modifier = Modifier.fillMaxSize()
) {
if (supportedPatches.isNotEmpty() && (vm.filter and SHOW_SUPPORTED != 0 || vm.filter == 0)) {

items(
items = supportedPatches,
key = { it.name }
) { patch ->
PatchItem(
patch = patch,
onOptionsDialog = vm::openOptionsDialog,
onToggle = { vm.togglePatch(bundleName, patch) },
selected = vm.isSelected(bundleName, patch)
)
}
}
}

items(
items = unsupportedPatches,
// key = { it.name }
) { patch ->
PatchItem(
patch = patch,
onOptionsDialog = vm::openOptionsDialog,
onToggle = {
vm.togglePatch(bundleName, patch)
},
selected = vm.isSelected(bundleName, patch),
supported = allowUnsupported
)
if (universalPatches.isNotEmpty() && (vm.filter and SHOW_UNIVERSAL != 0 || vm.filter == 0)) {
item {
ListHeader(
title = stringResource(R.string.universal_patches),
onHelpClick = { }
)
}

items(
items = universalPatches,
key = { it.name }
) { patch ->
PatchItem(
patch = patch,
onOptionsDialog = vm::openOptionsDialog,
onToggle = { vm.togglePatch(bundleName, patch) },
selected = vm.isSelected(bundleName, patch)
)
}
}

if (unsupportedPatches.isNotEmpty() && (vm.filter and SHOW_UNSUPPORTED != 0 || vm.filter == 0)) {
item {
ListHeader(
title = stringResource(R.string.unsupported_patches),
onHelpClick = { vm.openUnsupportedDialog(unsupportedPatches) }
)
}

items(
items = unsupportedPatches,
key = { it.name }
) { patch ->
PatchItem(
patch = patch,
onOptionsDialog = vm::openOptionsDialog,
onToggle = { vm.togglePatch(bundleName, patch) },
selected = vm.isSelected(bundleName, patch),
supported = allowUnsupported
)
}
}
}
}
}
Expand All @@ -147,68 +225,88 @@ fun PatchItem(
onOptionsDialog: () -> Unit,
selected: Boolean,
onToggle: () -> Unit,
supported: Boolean
supported: Boolean = true
) = ListItem(
modifier = Modifier
.let { if (!supported) it.alpha(0.5f) else it }
.clickable(enabled = supported, onClick = onToggle)
.fillMaxSize(),
leadingContent = {
Checkbox(
checked = selected,
onCheckedChange = null,
enabled = supported
)
},
headlineContent = { Text(patch.name) },
supportingContent = patch.description?.let { { Text(it) } },
trailingContent = {
if (patch.options?.isNotEmpty() == true) {
IconButton(onClick = onOptionsDialog, enabled = supported) {
Icon(Icons.Outlined.Settings, null)
}
}
}
)

@Composable
fun ListHeader(
title: String,
onHelpClick: (() -> Unit)? = null
) {
ListItem(
modifier = Modifier
.let { if (!supported) it.alpha(0.5f) else it }
.clickable(enabled = supported, onClick = onToggle),
leadingContent = {
Checkbox(
checked = selected,
onCheckedChange = {
onToggle()
},
enabled = supported
)
},
headlineContent = {
Text(patch.name)
},
supportingContent = {
Text(patch.description ?: "")
Text(
text = title,
color = MaterialTheme.colorScheme.primary,
style = MaterialTheme.typography.labelLarge
)
},
trailingContent = {
if (patch.options?.isNotEmpty() == true) {
IconButton(onClick = onOptionsDialog, enabled = supported) {
Icon(Icons.Outlined.Settings, null)
}
trailingContent = onHelpClick?.let { {
IconButton(onClick = onHelpClick) {
Icon(
Icons.Outlined.HelpOutline,
stringResource(R.string.help)
)
}
}
} }
)
}

@Composable
fun UnsupportedDialog(
appVersion: String,
supportedVersions: List<String>,
onDismissRequest: () -> Unit
) {
val appVersion = "1.1.0"
val supportedVersions =
listOf("1.1.1", "1.2.0", "1.1.1", "1.2.0", "1.1.1", "1.2.0", "1.1.1", "1.2.0", "1.1.1", "1.2.0")

AlertDialog(modifier = Modifier.padding(vertical = 45.dp),
onDismissRequest = onDismissRequest,
confirmButton = {
TextButton(onClick = onDismissRequest) {
Text(stringResource(R.string.ok))
}
},
title = { Text(stringResource(R.string.unsupported_app)) },
text = { Text(stringResource(R.string.app_not_supported, appVersion, supportedVersions.joinToString(", "))) })
}
) = AlertDialog(
onDismissRequest = onDismissRequest,
confirmButton = {
TextButton(onClick = onDismissRequest) {
Text(stringResource(R.string.ok))
}
},
title = { Text(stringResource(R.string.unsupported_app)) },
text = { Text(stringResource(R.string.app_not_supported, appVersion, supportedVersions.joinToString(", "))) }
)

@Composable
fun OptionsDialog(
onDismissRequest: () -> Unit, onConfirm: () -> Unit
) {
AlertDialog(onDismissRequest = onDismissRequest, confirmButton = {
Button(onClick = {
) = AlertDialog(
onDismissRequest = onDismissRequest,
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(stringResource(R.string.cancel))
}
},
confirmButton = {
TextButton(onClick = {
onConfirm()
onDismissRequest()
}) {
Text(stringResource(R.string.apply))
}
}, title = { Text(stringResource(R.string.options)) }, text = {
Text("You really thought these would exist?")
})
}
},
title = { Text(stringResource(R.string.options)) },
text = { Text("You really thought these would exist?") }
)
Loading

0 comments on commit 6309e8b

Please sign in to comment.