Use Compose on Clear Database screen (#7639)

This commit is contained in:
Andreas
2022-07-30 17:51:47 +02:00
committed by GitHub
parent 4774deb1ef
commit 99ac30e59f
16 changed files with 354 additions and 325 deletions

View File

@@ -0,0 +1,57 @@
package eu.kanade.presentation.more.settings.database
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.more.settings.database.components.ClearDatabaseContent
import eu.kanade.presentation.more.settings.database.components.ClearDatabaseDeleteDialog
import eu.kanade.presentation.more.settings.database.components.ClearDatabaseFloatingActionButton
import eu.kanade.presentation.more.settings.database.components.ClearDatabaseToolbar
import eu.kanade.presentation.util.plus
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.setting.database.ClearDatabasePresenter
import eu.kanade.tachiyomi.util.system.toast
@Composable
fun ClearDatabaseScreen(
presenter: ClearDatabasePresenter,
navigateUp: () -> Unit,
) {
val context = LocalContext.current
Scaffold(
topBar = {
ClearDatabaseToolbar(
state = presenter,
navigateUp = navigateUp,
onClickSelectAll = { presenter.selectAll() },
onClickInvertSelection = { presenter.invertSelection() },
)
},
floatingActionButton = {
ClearDatabaseFloatingActionButton(
isVisible = presenter.selection.isNotEmpty(),
onClickDelete = {
presenter.dialog = ClearDatabasePresenter.Dialog.Delete(presenter.selection)
},
)
},
) { paddingValues ->
ClearDatabaseContent(
state = presenter,
contentPadding = paddingValues,
onClickSelection = { source ->
presenter.toggleSelection(source)
},
)
}
if (presenter.dialog is ClearDatabasePresenter.Dialog.Delete) {
ClearDatabaseDeleteDialog(
onDismissRequest = { presenter.dialog = null },
onDelete = {
presenter.removeMangaBySourceId((presenter.dialog as ClearDatabasePresenter.Dialog.Delete).sourceIds)
presenter.clearSelection()
context.toast(R.string.clear_database_completed)
},
)
}
}

View File

@@ -0,0 +1,28 @@
package eu.kanade.presentation.more.settings.database
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import eu.kanade.domain.source.model.SourceWithCount
import eu.kanade.tachiyomi.ui.setting.database.ClearDatabasePresenter
@Stable
interface ClearDatabaseState {
val items: List<SourceWithCount>
val selection: List<Long>
val isEmpty: Boolean
var dialog: ClearDatabasePresenter.Dialog?
}
fun ClearDatabaseState(): ClearDatabaseState {
return ClearDatabaseStateImpl()
}
class ClearDatabaseStateImpl : ClearDatabaseState {
override var items: List<SourceWithCount> by mutableStateOf(emptyList())
override var selection: List<Long> by mutableStateOf(emptyList())
override val isEmpty: Boolean by derivedStateOf { items.isEmpty() }
override var dialog: ClearDatabasePresenter.Dialog? by mutableStateOf(null)
}

View File

@@ -0,0 +1,41 @@
package eu.kanade.presentation.more.settings.database.components
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import eu.kanade.domain.source.model.Source
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.FastScrollLazyColumn
import eu.kanade.presentation.more.settings.database.ClearDatabaseState
import eu.kanade.presentation.util.plus
import eu.kanade.tachiyomi.R
@Composable
fun ClearDatabaseContent(
state: ClearDatabaseState,
contentPadding: PaddingValues,
onClickSelection: (Source) -> Unit,
) {
Crossfade(targetState = state.isEmpty.not()) { _state ->
when (_state) {
true -> FastScrollLazyColumn(
contentPadding = contentPadding + WindowInsets.navigationBars.asPaddingValues(),
) {
items(state.items) { sourceWithCount ->
ClearDatabaseItem(
source = sourceWithCount.source,
count = sourceWithCount.count,
isSelected = state.selection.contains(sourceWithCount.id),
onClickSelect = { onClickSelection(sourceWithCount.source) },
)
}
}
false -> EmptyScreen(message = stringResource(id = R.string.database_clean))
}
}
}

View File

@@ -0,0 +1,31 @@
package eu.kanade.presentation.more.settings.database.components
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.TextButton
import eu.kanade.tachiyomi.R
@Composable
fun ClearDatabaseDeleteDialog(
onDismissRequest: () -> Unit,
onDelete: () -> Unit,
) {
AlertDialog(
onDismissRequest = onDismissRequest,
confirmButton = {
TextButton(onClick = onDelete) {
Text(text = stringResource(id = android.R.string.ok))
}
},
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = android.R.string.cancel))
}
},
text = {
Text(text = stringResource(id = R.string.clear_database_confirmation))
},
)
}

View File

@@ -0,0 +1,38 @@
package eu.kanade.presentation.more.settings.database.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.ExtendedFloatingActionButton
import eu.kanade.tachiyomi.R
@Composable
fun ClearDatabaseFloatingActionButton(
isVisible: Boolean,
onClickDelete: () -> Unit,
) {
AnimatedVisibility(
visible = isVisible,
enter = fadeIn(),
exit = fadeOut(),
) {
ExtendedFloatingActionButton(
modifier = Modifier.navigationBarsPadding(),
text = {
Text(text = stringResource(id = R.string.action_delete))
},
icon = {
Icon(Icons.Outlined.Delete, contentDescription = "")
},
onClick = onClickDelete,
)
}
}

View File

@@ -0,0 +1,53 @@
package eu.kanade.presentation.more.settings.database.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Checkbox
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import eu.kanade.domain.source.model.Source
import eu.kanade.presentation.browse.components.SourceIcon
import eu.kanade.presentation.util.selectedBackground
import eu.kanade.tachiyomi.R
@Composable
fun ClearDatabaseItem(
source: Source,
count: Long,
isSelected: Boolean,
onClickSelect: () -> Unit,
) {
Row(
modifier = Modifier
.selectedBackground(isSelected)
.clickable(onClick = onClickSelect)
.padding(horizontal = 8.dp)
.height(56.dp),
verticalAlignment = Alignment.CenterVertically,
) {
SourceIcon(source = source)
Column(
modifier = Modifier
.padding(start = 8.dp)
.weight(1f),
) {
Text(
text = source.nameWithLanguage,
style = MaterialTheme.typography.bodyMedium,
)
Text(text = stringResource(id = R.string.clear_database_source_item_count, count))
}
Checkbox(
checked = isSelected,
onCheckedChange = { onClickSelect() },
)
}
}

View File

@@ -0,0 +1,42 @@
package eu.kanade.presentation.more.settings.database.components
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.FlipToBack
import androidx.compose.material.icons.outlined.SelectAll
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.more.settings.database.ClearDatabaseState
import eu.kanade.tachiyomi.R
@Composable
fun ClearDatabaseToolbar(
state: ClearDatabaseState,
navigateUp: () -> Unit,
onClickSelectAll: () -> Unit,
onClickInvertSelection: () -> Unit,
) {
AppBar(
title = stringResource(id = R.string.pref_clear_database),
navigateUp = navigateUp,
actions = {
if (state.isEmpty.not()) {
AppBarActions(
actions = listOf(
AppBar.Action(
title = stringResource(id = R.string.action_select_all),
icon = Icons.Outlined.SelectAll,
onClick = onClickSelectAll,
),
AppBar.Action(
title = stringResource(id = R.string.action_select_all),
icon = Icons.Outlined.FlipToBack,
onClick = onClickInvertSelection,
),
),
)
}
},
)
}