Move library page EmptyScreens into list/grids
It does look awkward due to the lack of filled height within those list/grids though. Fixes #8720 Fixes #8721
This commit is contained in:
parent
0e2bdb7863
commit
376bbeb724
@ -22,12 +22,9 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.layout.Layout
|
|
||||||
import androidx.compose.ui.layout.layoutId
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.util.fastFirstOrNull
|
|
||||||
import eu.kanade.presentation.theme.TachiyomiTheme
|
import eu.kanade.presentation.theme.TachiyomiTheme
|
||||||
import eu.kanade.presentation.util.ThemePreviews
|
import eu.kanade.presentation.util.ThemePreviews
|
||||||
import eu.kanade.presentation.util.secondaryItemAlpha
|
import eu.kanade.presentation.util.secondaryItemAlpha
|
||||||
@ -54,13 +51,12 @@ fun EmptyScreen(
|
|||||||
actions: List<EmptyScreenAction>? = null,
|
actions: List<EmptyScreenAction>? = null,
|
||||||
) {
|
) {
|
||||||
val face = remember { getRandomErrorFace() }
|
val face = remember { getRandomErrorFace() }
|
||||||
Layout(
|
|
||||||
content = {
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.layoutId("face")
|
.fillMaxSize()
|
||||||
.padding(horizontal = 24.dp),
|
.padding(horizontal = 24.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = face,
|
text = face,
|
||||||
@ -74,15 +70,14 @@ fun EmptyScreen(
|
|||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
)
|
)
|
||||||
}
|
|
||||||
if (!actions.isNullOrEmpty()) {
|
if (!actions.isNullOrEmpty()) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.layoutId("actions")
|
|
||||||
.padding(
|
.padding(
|
||||||
top = 24.dp,
|
top = 24.dp,
|
||||||
start = horizontalPadding,
|
start = 24.dp,
|
||||||
end = horizontalPadding,
|
end = 24.dp,
|
||||||
),
|
),
|
||||||
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||||
) {
|
) {
|
||||||
@ -96,27 +91,6 @@ fun EmptyScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
modifier = modifier.fillMaxSize(),
|
|
||||||
) { measurables, constraints ->
|
|
||||||
val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)
|
|
||||||
val facePlaceable = measurables.fastFirstOrNull { it.layoutId == "face" }!!
|
|
||||||
.measure(looseConstraints)
|
|
||||||
val actionsPlaceable = measurables.fastFirstOrNull { it.layoutId == "actions" }
|
|
||||||
?.measure(looseConstraints)
|
|
||||||
|
|
||||||
layout(constraints.maxWidth, constraints.maxHeight) {
|
|
||||||
val faceY = (constraints.maxHeight - facePlaceable.height) / 2
|
|
||||||
facePlaceable.placeRelative(
|
|
||||||
x = (constraints.maxWidth - facePlaceable.width) / 2,
|
|
||||||
y = faceY,
|
|
||||||
)
|
|
||||||
|
|
||||||
actionsPlaceable?.placeRelative(
|
|
||||||
x = (constraints.maxWidth - actionsPlaceable.width) / 2,
|
|
||||||
y = faceY + facePlaceable.height,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,8 +161,6 @@ data class EmptyScreenAction(
|
|||||||
val onClick: () -> Unit,
|
val onClick: () -> Unit,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val horizontalPadding = 24.dp
|
|
||||||
|
|
||||||
private val ERROR_FACES = listOf(
|
private val ERROR_FACES = listOf(
|
||||||
"(・o・;)",
|
"(・o・;)",
|
||||||
"Σ(ಠ_ಠ)",
|
"Σ(ಠ_ಠ)",
|
||||||
|
@ -2,6 +2,7 @@ package eu.kanade.presentation.library.components
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.lazy.grid.GridItemSpan
|
||||||
import androidx.compose.foundation.lazy.grid.items
|
import androidx.compose.foundation.lazy.grid.items
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@ -22,6 +23,7 @@ fun LibraryComfortableGrid(
|
|||||||
onClickContinueReading: ((LibraryManga) -> Unit)?,
|
onClickContinueReading: ((LibraryManga) -> Unit)?,
|
||||||
searchQuery: String?,
|
searchQuery: String?,
|
||||||
onGlobalSearchClicked: () -> Unit,
|
onGlobalSearchClicked: () -> Unit,
|
||||||
|
hasActiveFilters: Boolean,
|
||||||
) {
|
) {
|
||||||
LazyLibraryGrid(
|
LazyLibraryGrid(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
@ -30,6 +32,14 @@ fun LibraryComfortableGrid(
|
|||||||
) {
|
) {
|
||||||
globalSearchItem(searchQuery, onGlobalSearchClicked)
|
globalSearchItem(searchQuery, onGlobalSearchClicked)
|
||||||
|
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
item(
|
||||||
|
span = { GridItemSpan(maxLineSpan) },
|
||||||
|
contentType = "library_comfortable_grid_empty",
|
||||||
|
) {
|
||||||
|
LibraryPagerEmptyScreen(searchQuery, hasActiveFilters, contentPadding)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
items(
|
items(
|
||||||
items = items,
|
items = items,
|
||||||
contentType = { "library_comfortable_grid_item" },
|
contentType = { "library_comfortable_grid_item" },
|
||||||
@ -65,4 +75,5 @@ fun LibraryComfortableGrid(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package eu.kanade.presentation.library.components
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.lazy.grid.GridItemSpan
|
||||||
import androidx.compose.foundation.lazy.grid.items
|
import androidx.compose.foundation.lazy.grid.items
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@ -23,6 +24,7 @@ fun LibraryCompactGrid(
|
|||||||
onClickContinueReading: ((LibraryManga) -> Unit)?,
|
onClickContinueReading: ((LibraryManga) -> Unit)?,
|
||||||
searchQuery: String?,
|
searchQuery: String?,
|
||||||
onGlobalSearchClicked: () -> Unit,
|
onGlobalSearchClicked: () -> Unit,
|
||||||
|
hasActiveFilters: Boolean,
|
||||||
) {
|
) {
|
||||||
LazyLibraryGrid(
|
LazyLibraryGrid(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
@ -31,6 +33,14 @@ fun LibraryCompactGrid(
|
|||||||
) {
|
) {
|
||||||
globalSearchItem(searchQuery, onGlobalSearchClicked)
|
globalSearchItem(searchQuery, onGlobalSearchClicked)
|
||||||
|
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
item(
|
||||||
|
span = { GridItemSpan(maxLineSpan) },
|
||||||
|
contentType = "library_compact_grid_empty",
|
||||||
|
) {
|
||||||
|
LibraryPagerEmptyScreen(searchQuery, hasActiveFilters, contentPadding)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
items(
|
items(
|
||||||
items = items,
|
items = items,
|
||||||
contentType = { "library_compact_grid_item" },
|
contentType = { "library_compact_grid_item" },
|
||||||
@ -66,4 +76,5 @@ fun LibraryCompactGrid(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ fun LibraryList(
|
|||||||
onClickContinueReading: ((LibraryManga) -> Unit)?,
|
onClickContinueReading: ((LibraryManga) -> Unit)?,
|
||||||
searchQuery: String?,
|
searchQuery: String?,
|
||||||
onGlobalSearchClicked: () -> Unit,
|
onGlobalSearchClicked: () -> Unit,
|
||||||
|
hasActiveFilters: Boolean,
|
||||||
) {
|
) {
|
||||||
FastScrollLazyColumn(
|
FastScrollLazyColumn(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
@ -49,6 +50,13 @@ fun LibraryList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
item(
|
||||||
|
contentType = "library_list_empty",
|
||||||
|
) {
|
||||||
|
LibraryPagerEmptyScreen(searchQuery, hasActiveFilters, contentPadding)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
items(
|
items(
|
||||||
items = items,
|
items = items,
|
||||||
contentType = { "library_list_item" },
|
contentType = { "library_list_item" },
|
||||||
@ -82,4 +90,5 @@ fun LibraryList(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,11 +48,6 @@ fun LibraryPager(
|
|||||||
}
|
}
|
||||||
val library = getLibraryForPage(page)
|
val library = getLibraryForPage(page)
|
||||||
|
|
||||||
if (library.isEmpty()) {
|
|
||||||
LibraryPagerEmptyScreen(searchQuery, hasActiveFilters, contentPadding)
|
|
||||||
return@HorizontalPager
|
|
||||||
}
|
|
||||||
|
|
||||||
val displayMode = getDisplayModeForPage(page)
|
val displayMode = getDisplayModeForPage(page)
|
||||||
val columns by if (displayMode != LibraryDisplayMode.List) {
|
val columns by if (displayMode != LibraryDisplayMode.List) {
|
||||||
val configuration = LocalConfiguration.current
|
val configuration = LocalConfiguration.current
|
||||||
@ -74,6 +69,7 @@ fun LibraryPager(
|
|||||||
onClickContinueReading = onClickContinueReading,
|
onClickContinueReading = onClickContinueReading,
|
||||||
searchQuery = searchQuery,
|
searchQuery = searchQuery,
|
||||||
onGlobalSearchClicked = onGlobalSearchClicked,
|
onGlobalSearchClicked = onGlobalSearchClicked,
|
||||||
|
hasActiveFilters = hasActiveFilters,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
LibraryDisplayMode.CompactGrid, LibraryDisplayMode.CoverOnlyGrid -> {
|
LibraryDisplayMode.CompactGrid, LibraryDisplayMode.CoverOnlyGrid -> {
|
||||||
@ -88,6 +84,7 @@ fun LibraryPager(
|
|||||||
onClickContinueReading = onClickContinueReading,
|
onClickContinueReading = onClickContinueReading,
|
||||||
searchQuery = searchQuery,
|
searchQuery = searchQuery,
|
||||||
onGlobalSearchClicked = onGlobalSearchClicked,
|
onGlobalSearchClicked = onGlobalSearchClicked,
|
||||||
|
hasActiveFilters = hasActiveFilters,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
LibraryDisplayMode.ComfortableGrid -> {
|
LibraryDisplayMode.ComfortableGrid -> {
|
||||||
@ -101,6 +98,7 @@ fun LibraryPager(
|
|||||||
onClickContinueReading = onClickContinueReading,
|
onClickContinueReading = onClickContinueReading,
|
||||||
searchQuery = searchQuery,
|
searchQuery = searchQuery,
|
||||||
onGlobalSearchClicked = onGlobalSearchClicked,
|
onGlobalSearchClicked = onGlobalSearchClicked,
|
||||||
|
hasActiveFilters = hasActiveFilters,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +106,7 @@ fun LibraryPager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun LibraryPagerEmptyScreen(
|
internal fun LibraryPagerEmptyScreen(
|
||||||
searchQuery: String?,
|
searchQuery: String?,
|
||||||
hasActiveFilters: Boolean,
|
hasActiveFilters: Boolean,
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
@ -119,6 +117,7 @@ private fun LibraryPagerEmptyScreen(
|
|||||||
else -> R.string.information_no_manga_category
|
else -> R.string.information_no_manga_category
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: vertically center this better
|
||||||
EmptyScreen(
|
EmptyScreen(
|
||||||
textResource = msg,
|
textResource = msg,
|
||||||
modifier = Modifier.padding(contentPadding),
|
modifier = Modifier.padding(contentPadding),
|
||||||
|
@ -212,20 +212,19 @@ private fun SearchResult(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Crossfade(targetState = result) {
|
Crossfade(targetState = result) {
|
||||||
|
when {
|
||||||
|
it == null -> {}
|
||||||
|
it.isEmpty() -> {
|
||||||
|
EmptyScreen(stringResource(R.string.no_results_found))
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = modifier.fillMaxSize(),
|
modifier = modifier.fillMaxSize(),
|
||||||
state = listState,
|
state = listState,
|
||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding,
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
when {
|
items(
|
||||||
it == null -> {
|
|
||||||
/* Don't show anything just yet */
|
|
||||||
}
|
|
||||||
// No result
|
|
||||||
it.isEmpty() -> item { EmptyScreen(stringResource(R.string.no_results_found)) }
|
|
||||||
// Show result list
|
|
||||||
else -> items(
|
|
||||||
items = it,
|
items = it,
|
||||||
key = { i -> i.hashCode() },
|
key = { i -> i.hashCode() },
|
||||||
) { item ->
|
) { item ->
|
||||||
@ -254,6 +253,7 @@ private fun SearchResult(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
Loading…
Reference in New Issue
Block a user