From 1cdaa761b7b7d08eaf2f1d829de1c998e75c7c2c Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 30 Dec 2023 20:07:45 -0500 Subject: [PATCH] Dedupe common LazyColumn with action at bottom layout --- .../screen/advanced/ClearDatabaseScreen.kt | 48 +++-------- .../screen/data/CreateBackupScreen.kt | 82 ++++++------------- .../screen/data/RestoreBackupScreen.kt | 82 +++++++------------ .../core/components/LazyColumnWithAction.kt | 52 ++++++++++++ .../core/components/SectionCard.kt | 3 +- 5 files changed, 122 insertions(+), 145 deletions(-) create mode 100644 presentation-core/src/main/java/tachiyomi/presentation/core/components/LazyColumnWithAction.kt diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/advanced/ClearDatabaseScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/advanced/ClearDatabaseScreen.kt index cec3caafc..9ab8473dd 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/advanced/ClearDatabaseScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/advanced/ClearDatabaseScreen.kt @@ -3,19 +3,14 @@ package eu.kanade.presentation.more.settings.screen.advanced import androidx.compose.foundation.clickable 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.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.FlipToBack import androidx.compose.material.icons.outlined.SelectAll import androidx.compose.material3.AlertDialog -import androidx.compose.material3.Button import androidx.compose.material3.Checkbox -import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -50,6 +45,7 @@ import tachiyomi.domain.source.interactor.GetSourcesWithNonLibraryManga import tachiyomi.domain.source.model.Source import tachiyomi.domain.source.model.SourceWithCount import tachiyomi.i18n.MR +import tachiyomi.presentation.core.components.LazyColumnWithAction import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.screens.EmptyScreen @@ -114,7 +110,7 @@ class ClearDatabaseScreen : Screen() { onClick = model::selectAll, ), AppBar.Action( - title = stringResource(MR.strings.action_select_all), + title = stringResource(MR.strings.action_select_inverse), icon = Icons.Outlined.FlipToBack, onClick = model::invertSelection, ), @@ -132,36 +128,18 @@ class ClearDatabaseScreen : Screen() { modifier = Modifier.padding(contentPadding), ) } else { - Column( - modifier = Modifier - .padding(contentPadding) - .fillMaxSize(), + LazyColumnWithAction( + contentPadding = contentPadding, + actionLabel = stringResource(MR.strings.action_delete), + actionEnabled = s.selection.isNotEmpty(), + onClickAction = model::showConfirmation, ) { - LazyColumn( - modifier = Modifier.weight(1f), - ) { - items(s.items) { sourceWithCount -> - ClearDatabaseItem( - source = sourceWithCount.source, - count = sourceWithCount.count, - isSelected = s.selection.contains(sourceWithCount.id), - onClickSelect = { model.toggleSelection(sourceWithCount.source) }, - ) - } - } - - HorizontalDivider() - - Button( - modifier = Modifier - .padding(horizontal = 16.dp, vertical = 8.dp) - .fillMaxWidth(), - onClick = model::showConfirmation, - enabled = s.selection.isNotEmpty(), - ) { - Text( - text = stringResource(MR.strings.action_delete), - color = MaterialTheme.colorScheme.onPrimary, + items(s.items) { sourceWithCount -> + ClearDatabaseItem( + source = sourceWithCount.source, + count = sourceWithCount.count, + isSelected = s.selection.contains(sourceWithCount.id), + onClickSelect = { model.toggleSelection(sourceWithCount.source) }, ) } } diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/CreateBackupScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/CreateBackupScreen.kt index 4e221a7b5..20cd8d4e3 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/CreateBackupScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/CreateBackupScreen.kt @@ -6,23 +6,12 @@ import android.content.Intent import android.net.Uri import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope -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.material3.Button -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.rememberScreenModel import cafe.adriel.voyager.navigator.LocalNavigator @@ -39,9 +28,9 @@ import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.flow.update import tachiyomi.i18n.MR import tachiyomi.presentation.core.components.LabeledCheckbox +import tachiyomi.presentation.core.components.LazyColumnWithAction import tachiyomi.presentation.core.components.SectionCard import tachiyomi.presentation.core.components.material.Scaffold -import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.i18n.stringResource class CreateBackupScreen : Screen() { @@ -76,55 +65,37 @@ class CreateBackupScreen : Screen() { ) }, ) { contentPadding -> - Column( - modifier = Modifier - .padding(contentPadding) - .fillMaxSize(), + LazyColumnWithAction( + contentPadding = contentPadding, + actionLabel = stringResource(MR.strings.action_create), + onClickAction = { + if (!BackupCreateJob.isManualJobRunning(context)) { + try { + chooseBackupDir.launch(BackupCreator.getFilename()) + } catch (e: ActivityNotFoundException) { + context.toast(MR.strings.file_picker_error) + } + } else { + context.toast(MR.strings.backup_in_progress) + } + }, ) { - LazyColumn( - modifier = Modifier.weight(1f), - ) { - if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) { - item { - WarningBanner(MR.strings.restore_miui_warning) - } - } - + if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) { item { - SectionCard(MR.strings.label_library) { - Options(BackupOptions.libraryOptions, state, model) - } - } - - item { - SectionCard(MR.strings.label_settings) { - Options(BackupOptions.settingsOptions, state, model) - } + WarningBanner(MR.strings.restore_miui_warning) } } - HorizontalDivider() + item { + SectionCard(MR.strings.label_library) { + Options(BackupOptions.libraryOptions, state, model) + } + } - Button( - modifier = Modifier - .padding(horizontal = 16.dp, vertical = 8.dp) - .fillMaxWidth(), - onClick = { - if (!BackupCreateJob.isManualJobRunning(context)) { - try { - chooseBackupDir.launch(BackupCreator.getFilename()) - } catch (e: ActivityNotFoundException) { - context.toast(MR.strings.file_picker_error) - } - } else { - context.toast(MR.strings.backup_in_progress) - } - }, - ) { - Text( - text = stringResource(MR.strings.action_create), - color = MaterialTheme.colorScheme.onPrimary, - ) + item { + SectionCard(MR.strings.label_settings) { + Options(BackupOptions.settingsOptions, state, model) + } } } } @@ -144,7 +115,6 @@ class CreateBackupScreen : Screen() { model.toggle(option.setter, it) }, enabled = option.enabled(state.options), - modifier = Modifier.padding(horizontal = MaterialTheme.padding.medium), ) } } diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/RestoreBackupScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/RestoreBackupScreen.kt index 43a1b3650..f5fe02973 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/RestoreBackupScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/RestoreBackupScreen.kt @@ -4,14 +4,9 @@ import android.content.Context import android.net.Uri import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -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.LazyListScope import androidx.compose.foundation.text.selection.SelectionContainer -import androidx.compose.material3.Button -import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -24,7 +19,6 @@ import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.withStyle -import androidx.compose.ui.unit.dp import androidx.core.net.toUri import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.rememberScreenModel @@ -41,6 +35,7 @@ import kotlinx.coroutines.flow.update import tachiyomi.core.util.lang.anyEnabled import tachiyomi.i18n.MR import tachiyomi.presentation.core.components.LabeledCheckbox +import tachiyomi.presentation.core.components.LazyColumnWithAction import tachiyomi.presentation.core.components.SectionCard import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.padding @@ -66,58 +61,39 @@ class RestoreBackupScreen( ) }, ) { contentPadding -> - Column( - modifier = Modifier - .padding(contentPadding) - .fillMaxSize(), + LazyColumnWithAction( + contentPadding = contentPadding, + actionLabel = stringResource(MR.strings.action_restore), + actionEnabled = state.canRestore && state.options.anyEnabled(), + onClickAction = { + model.startRestore() + navigator.pop() + }, ) { - LazyColumn( - modifier = Modifier.weight(1f), - ) { - if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) { - item { - WarningBanner(MR.strings.restore_miui_warning) - } - } - - if (state.canRestore) { - item { - SectionCard { - RestoreOptions.options.forEach { option -> - LabeledCheckbox( - label = stringResource(option.label), - checked = option.getter(state.options), - onCheckedChange = { - model.toggle(option.setter, it) - }, - modifier = Modifier.padding(horizontal = MaterialTheme.padding.medium), - ) - } - } - } - } - - if (state.error != null) { - errorMessageItem(state.error) + if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) { + item { + WarningBanner(MR.strings.restore_miui_warning) } } - HorizontalDivider() + if (state.canRestore) { + item { + SectionCard { + RestoreOptions.options.forEach { option -> + LabeledCheckbox( + label = stringResource(option.label), + checked = option.getter(state.options), + onCheckedChange = { + model.toggle(option.setter, it) + }, + ) + } + } + } + } - Button( - modifier = Modifier - .padding(horizontal = 16.dp, vertical = 8.dp) - .fillMaxWidth(), - enabled = state.canRestore && state.options.anyEnabled(), - onClick = { - model.startRestore() - navigator.pop() - }, - ) { - Text( - text = stringResource(MR.strings.action_restore), - color = MaterialTheme.colorScheme.onPrimary, - ) + if (state.error != null) { + errorMessageItem(state.error) } } } diff --git a/presentation-core/src/main/java/tachiyomi/presentation/core/components/LazyColumnWithAction.kt b/presentation-core/src/main/java/tachiyomi/presentation/core/components/LazyColumnWithAction.kt new file mode 100644 index 000000000..de2f7636b --- /dev/null +++ b/presentation-core/src/main/java/tachiyomi/presentation/core/components/LazyColumnWithAction.kt @@ -0,0 +1,52 @@ +package tachiyomi.presentation.core.components + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +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.LazyListScope +import androidx.compose.material3.Button +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@Composable +fun LazyColumnWithAction( + contentPadding: PaddingValues, + actionLabel: String, + onClickAction: () -> Unit, + modifier: Modifier = Modifier, + actionEnabled: Boolean = true, + content: LazyListScope.() -> Unit, +) { + Column( + modifier = modifier + .padding(contentPadding) + .fillMaxSize(), + ) { + LazyColumn( + modifier = Modifier.weight(1f), + content = content, + ) + + HorizontalDivider() + + Button( + modifier = Modifier + .padding(horizontal = 16.dp, vertical = 8.dp) + .fillMaxWidth(), + enabled = actionEnabled, + onClick = onClickAction, + ) { + Text( + text = actionLabel, + color = MaterialTheme.colorScheme.onPrimary, + ) + } + } +} diff --git a/presentation-core/src/main/java/tachiyomi/presentation/core/components/SectionCard.kt b/presentation-core/src/main/java/tachiyomi/presentation/core/components/SectionCard.kt index 2cbd6e7dc..f40fcdfb6 100644 --- a/presentation-core/src/main/java/tachiyomi/presentation/core/components/SectionCard.kt +++ b/presentation-core/src/main/java/tachiyomi/presentation/core/components/SectionCard.kt @@ -1,6 +1,7 @@ package tachiyomi.presentation.core.components import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyItemScope @@ -16,7 +17,7 @@ import tachiyomi.presentation.core.i18n.stringResource @Composable fun LazyItemScope.SectionCard( titleRes: StringResource? = null, - content: @Composable () -> Unit, + content: @Composable ColumnScope.() -> Unit, ) { if (titleRes != null) { Text(