feat: Improve patch bundle screen (#2070)

This commit is contained in:
Ushie 2024-08-17 01:58:43 +03:00 committed by GitHub
parent 747017a5f9
commit edb4e421e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 103 additions and 121 deletions

View file

@ -2,37 +2,33 @@ package app.revanced.manager.ui.component.bundle
import android.webkit.URLUtil
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowRight
import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material.icons.outlined.Extension
import androidx.compose.material.icons.outlined.Inventory2
import androidx.compose.material.icons.outlined.Sell
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import app.revanced.manager.R
import app.revanced.manager.ui.component.ColumnWithScrollbar
import app.revanced.manager.ui.component.TextInputDialog
import app.revanced.manager.util.isDebuggable
@Composable
fun BaseBundleDialog(
modifier: Modifier = Modifier,
isDefault: Boolean,
name: String?,
onNameChange: ((String) -> Unit)? = null,
remoteUrl: String?,
onRemoteUrlChange: ((String) -> Unit)? = null,
patchCount: Int,
@ -40,39 +36,66 @@ fun BaseBundleDialog(
autoUpdate: Boolean,
onAutoUpdateChange: (Boolean) -> Unit,
onPatchesClick: () -> Unit,
onBundleTypeClick: () -> Unit = {},
extraFields: @Composable ColumnScope.() -> Unit = {}
) {
ColumnWithScrollbar(
modifier = Modifier
.fillMaxWidth()
.then(modifier)
.then(modifier),
) {
if (name != null) {
var showNameInputDialog by rememberSaveable {
mutableStateOf(false)
}
if (showNameInputDialog) {
TextInputDialog(
initial = name,
title = stringResource(R.string.bundle_input_name),
onDismissRequest = {
showNameInputDialog = false
},
onConfirm = {
showNameInputDialog = false
onNameChange?.invoke(it)
},
validator = {
it.length in 1..19
}
Column(
modifier = Modifier.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.Start),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Outlined.Inventory2,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(32.dp)
)
name?.let {
Text(
text = it,
style = MaterialTheme.typography.titleLarge.copy(fontWeight = FontWeight(800)),
color = MaterialTheme.colorScheme.primary,
)
}
}
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier
.fillMaxWidth()
.padding(start = 2.dp)
) {
version?.let {
Tag(Icons.Outlined.Sell, it)
}
Tag(Icons.Outlined.Extension, patchCount.toString())
}
}
HorizontalDivider(
modifier = Modifier.padding(horizontal = 16.dp),
color = MaterialTheme.colorScheme.outlineVariant
)
if (remoteUrl != null) {
BundleListItem(
headlineText = stringResource(R.string.bundle_input_name),
supportingText = name.ifEmpty { stringResource(R.string.field_not_set) },
modifier = Modifier.clickable(enabled = onNameChange != null) {
showNameInputDialog = true
headlineText = stringResource(R.string.bundle_auto_update),
supportingText = stringResource(R.string.bundle_auto_update_description),
trailingContent = {
Switch(
checked = autoUpdate,
onCheckedChange = onAutoUpdateChange
)
},
modifier = Modifier.clickable {
onAutoUpdateChange(!autoUpdate)
}
)
}
@ -99,81 +122,59 @@ fun BaseBundleDialog(
}
BundleListItem(
modifier = Modifier.clickable(enabled = onRemoteUrlChange != null) {
showUrlInputDialog = true
},
headlineText = stringResource(R.string.bundle_input_source_url),
supportingText = url.ifEmpty { stringResource(R.string.field_not_set) }
)
}
extraFields()
if (remoteUrl != null) {
BundleListItem(
headlineText = stringResource(R.string.bundle_auto_update),
supportingText = stringResource(R.string.bundle_auto_update_description),
trailingContent = {
Switch(
checked = autoUpdate,
onCheckedChange = onAutoUpdateChange
)
},
modifier = Modifier.clickable {
onAutoUpdateChange(!autoUpdate)
}
)
}
BundleListItem(
headlineText = stringResource(R.string.bundle_type),
supportingText = stringResource(R.string.bundle_type_description),
modifier = Modifier.clickable {
onBundleTypeClick()
}
) {
FilledTonalButton(
onClick = onBundleTypeClick,
content = {
if (remoteUrl == null) {
Text(stringResource(R.string.local))
} else {
Text(stringResource(R.string.remote))
modifier = Modifier.clickable(
enabled = onRemoteUrlChange != null,
onClick = {
showUrlInputDialog = true
}
),
headlineText = stringResource(R.string.bundle_input_source_url),
supportingText = url.ifEmpty {
stringResource(R.string.field_not_set)
}
)
}
if (version != null || patchCount > 0) {
Text(
text = stringResource(R.string.information),
modifier = Modifier.padding(
horizontal = 16.dp,
vertical = 12.dp
),
style = MaterialTheme.typography.labelLarge,
color = MaterialTheme.colorScheme.primary,
)
}
val patchesClickable = LocalContext.current.isDebuggable && patchCount > 0
val patchesClickable = patchCount > 0
BundleListItem(
headlineText = stringResource(R.string.patches),
supportingText = pluralStringResource(R.plurals.bundle_patches_available, patchCount, patchCount),
modifier = Modifier.clickable(enabled = patchesClickable, onClick = onPatchesClick)
supportingText = stringResource(R.string.bundle_view_patches),
modifier = Modifier.clickable(
enabled = patchesClickable,
onClick = onPatchesClick
)
) {
if (patchesClickable)
if (patchesClickable) {
Icon(
Icons.AutoMirrored.Outlined.ArrowRight,
stringResource(R.string.patches)
)
}
}
version?.let {
BundleListItem(
headlineText = stringResource(R.string.version),
supportingText = it,
)
}
extraFields()
}
}
@Composable
private fun Tag(
icon: ImageVector,
text: String
) {
Row(
horizontalArrangement = Arrangement.spacedBy(6.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = icon,
contentDescription = null,
modifier = Modifier.size(16.dp),
tint = MaterialTheme.colorScheme.outline,
)
Text(
text,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.outline,
)
}
}

View file

@ -11,18 +11,9 @@ import androidx.compose.material.icons.automirrored.outlined.ArrowRight
import androidx.compose.material.icons.outlined.DeleteOutline
import androidx.compose.material.icons.outlined.Share
import androidx.compose.material.icons.outlined.Update
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
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.rememberCoroutineScope
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
@ -78,7 +69,7 @@ fun BundleInformationDialog(
Scaffold(
topBar = {
BundleTopBar(
title = bundleName,
title = stringResource(R.string.patch_bundle_field),
onBackClick = onDismissRequest,
backIcon = {
Icon(
@ -111,7 +102,6 @@ fun BundleInformationDialog(
modifier = Modifier.padding(paddingValues),
isDefault = bundle.isDefault,
name = bundleName,
onNameChange = { composableScope.launch { bundle.setName(it) } },
remoteUrl = bundle.asRemoteOrNull?.endpoint,
patchCount = patchCount,
version = props?.versionInfo?.patches,

View file

@ -11,8 +11,4 @@
<plurals name="selected_count">
<item quantity="other">%d selected</item>
</plurals>
<plurals name="bundle_patches_available">
<item quantity="one">%d patch available</item>
<item quantity="other">%d patches available</item>
</plurals>
</resources>

View file

@ -145,7 +145,6 @@
<string name="close">Close</string>
<string name="system">System</string>
<string name="light">Light</string>
<string name="information">Information</string>
<string name="dark">Dark</string>
<string name="appearance">Appearance</string>
<string name="downloaded_apps">Downloaded apps</string>
@ -181,8 +180,6 @@
<string name="tab_bundles">Patch bundles</string>
<string name="delete">Delete</string>
<string name="refresh">Refresh</string>
<string name="remote">Remote</string>
<string name="local">Local</string>
<string name="continue_anyways">Continue anyways</string>
<string name="download_another_version">Download another version</string>
<string name="download_app">Download app</string>
@ -302,14 +299,12 @@
<string name="submit_feedback_description">Help us improve this application</string>
<string name="developer_options">Developer options</string>
<string name="developer_options_description">Options for debugging issues</string>
<string name="bundle_input_name">Name</string>
<string name="bundle_input_source_url">Source URL</string>
<string name="bundle_update_success">Successfully updated %s</string>
<string name="bundle_update_unavailable">No update available for %s</string>
<string name="bundle_auto_update">Auto update</string>
<string name="bundle_auto_update_description">Automatically update this bundle when ReVanced starts</string>
<string name="bundle_type">Bundle type</string>
<string name="bundle_type_description">Choose the type of bundle you want</string>
<string name="bundle_view_patches">View patches</string>
<string name="about_revanced_manager">About ReVanced Manager</string>
<string name="revanced_manager_description">ReVanced Manager is an application designed to work with ReVanced Patcher, which allows for long-lasting patches to be created for Android apps. The patching system is designed to automatically work with new versions of apps with minimal maintenance.</string>
<string name="update_available">An update is available</string>