Browse Source

Dedupe common LazyColumn with action at bottom layout

arkon 1 year ago
parent
commit
1cdaa761b7

+ 13 - 35
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) },
                                 )
                             }
                         }

+ 24 - 54
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(),
-            ) {
-                LazyColumn(
-                    modifier = Modifier.weight(1f),
-                ) {
-                    if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) {
-                        item {
-                            WarningBanner(MR.strings.restore_miui_warning)
+            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)
                     }
-
+                },
+            ) {
+                if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) {
                     item {
-                        SectionCard(MR.strings.label_library) {
-                            Options(BackupOptions.libraryOptions, state, model)
-                        }
+                        WarningBanner(MR.strings.restore_miui_warning)
                     }
+                }
 
-                    item {
-                        SectionCard(MR.strings.label_settings) {
-                            Options(BackupOptions.settingsOptions, state, model)
-                        }
+                item {
+                    SectionCard(MR.strings.label_library) {
+                        Options(BackupOptions.libraryOptions, state, model)
                     }
                 }
 
-                HorizontalDivider()
-
-                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),
             )
         }
     }

+ 26 - 50
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 (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.canRestore) {
+                    item {
+                        SectionCard {
+                            RestoreOptions.options.forEach { option ->
+                                LabeledCheckbox(
+                                    label = stringResource(option.label),
+                                    checked = option.getter(state.options),
+                                    onCheckedChange = {
+                                        model.toggle(option.setter, it)
+                                    },
+                                )
                             }
                         }
                     }
-
-                    if (state.error != null) {
-                        errorMessageItem(state.error)
-                    }
                 }
 
-                HorizontalDivider()
-
-                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)
                 }
             }
         }

+ 52 - 0
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,
+            )
+        }
+    }
+}

+ 2 - 1
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(