Properly fix #8720 (#8797)

* Partially revert "Move library page EmptyScreens into list/grids"

This partially reverts commit 376bbeb724.

* Properly fix issue 8720
This commit is contained in:
AntsyLich 2022-12-24 21:02:38 +06:00 committed by GitHub
parent 94a410f50f
commit 3251fb36c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 176 additions and 161 deletions

View File

@ -14,6 +14,12 @@ import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
/** /**
* @param refreshing Whether the layout is currently refreshing
* @param onRefresh Lambda which is invoked when a swipe to refresh gesture is completed.
* @param enabled Whether the the layout should react to swipe gestures or not.
* @param indicatorPadding Content padding for the indicator, to inset the indicator in if required.
* @param content The content containing a vertically scrollable composable.
*
* Code reference: [Accompanist SwipeRefresh](https://github.com/google/accompanist/blob/677bc4ca0ee74677a8ba73793d04d85fe4ab55fb/swiperefresh/src/main/java/com/google/accompanist/swiperefresh/SwipeRefresh.kt#L265-L283) * Code reference: [Accompanist SwipeRefresh](https://github.com/google/accompanist/blob/677bc4ca0ee74677a8ba73793d04d85fe4ab55fb/swiperefresh/src/main/java/com/google/accompanist/swiperefresh/SwipeRefresh.kt#L265-L283)
*/ */
@Composable @Composable

View File

@ -0,0 +1,26 @@
package eu.kanade.presentation.library.components
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.zIndex
import eu.kanade.tachiyomi.R
@Composable
fun GlobalSearchItem(
searchQuery: String,
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
TextButton(
modifier = modifier,
onClick = onClick,
) {
Text(
text = stringResource(R.string.action_global_search_query, searchQuery),
modifier = Modifier.zIndex(99f),
)
}
}

View File

@ -5,17 +5,12 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyGridScope import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import eu.kanade.presentation.components.CommonMangaItemDefaults import eu.kanade.presentation.components.CommonMangaItemDefaults
import eu.kanade.presentation.components.FastScrollLazyVerticalGrid import eu.kanade.presentation.components.FastScrollLazyVerticalGrid
import eu.kanade.presentation.util.plus import eu.kanade.presentation.util.plus
import eu.kanade.tachiyomi.R
@Composable @Composable
fun LazyLibraryGrid( fun LazyLibraryGrid(
@ -43,12 +38,10 @@ fun LazyGridScope.globalSearchItem(
span = { GridItemSpan(maxLineSpan) }, span = { GridItemSpan(maxLineSpan) },
contentType = { "library_global_search_item" }, contentType = { "library_global_search_item" },
) { ) {
TextButton(onClick = onGlobalSearchClicked) { GlobalSearchItem(
Text( searchQuery = searchQuery,
text = stringResource(R.string.action_global_search_query, searchQuery!!), onClick = onGlobalSearchClicked,
modifier = Modifier.zIndex(99f), )
)
}
} }
} }
} }

View File

@ -2,7 +2,6 @@ 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,7 +22,6 @@ 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(),
@ -32,48 +30,39 @@ fun LibraryComfortableGrid(
) { ) {
globalSearchItem(searchQuery, onGlobalSearchClicked) globalSearchItem(searchQuery, onGlobalSearchClicked)
if (items.isEmpty()) { items(
item( items = items,
span = { GridItemSpan(maxLineSpan) }, contentType = { "library_comfortable_grid_item" },
contentType = "library_comfortable_grid_empty", ) { libraryItem ->
) { val manga = libraryItem.libraryManga.manga
LibraryPagerEmptyScreen(searchQuery, hasActiveFilters, contentPadding) MangaComfortableGridItem(
} isSelected = selection.fastAny { it.id == libraryItem.libraryManga.id },
} else { title = manga.title,
items( coverData = MangaCover(
items = items, mangaId = manga.id,
contentType = { "library_comfortable_grid_item" }, sourceId = manga.source,
) { libraryItem -> isMangaFavorite = manga.favorite,
val manga = libraryItem.libraryManga.manga url = manga.thumbnailUrl,
MangaComfortableGridItem( lastModified = manga.coverLastModified,
isSelected = selection.fastAny { it.id == libraryItem.libraryManga.id }, ),
title = manga.title, coverBadgeStart = {
coverData = MangaCover( DownloadsBadge(count = libraryItem.downloadCount.toInt())
mangaId = manga.id, UnreadBadge(count = libraryItem.unreadCount.toInt())
sourceId = manga.source, },
isMangaFavorite = manga.favorite, coverBadgeEnd = {
url = manga.thumbnailUrl, LanguageBadge(
lastModified = manga.coverLastModified, isLocal = libraryItem.isLocal,
), sourceLanguage = libraryItem.sourceLanguage,
coverBadgeStart = { )
DownloadsBadge(count = libraryItem.downloadCount.toInt()) },
UnreadBadge(count = libraryItem.unreadCount.toInt()) onLongClick = { onLongClick(libraryItem.libraryManga) },
}, onClick = { onClick(libraryItem.libraryManga) },
coverBadgeEnd = { onClickContinueReading = if (onClickContinueReading != null) {
LanguageBadge( { onClickContinueReading(libraryItem.libraryManga) }
isLocal = libraryItem.isLocal, } else {
sourceLanguage = libraryItem.sourceLanguage, null
) },
}, )
onLongClick = { onLongClick(libraryItem.libraryManga) },
onClick = { onClick(libraryItem.libraryManga) },
onClickContinueReading = if (onClickContinueReading != null) {
{ onClickContinueReading(libraryItem.libraryManga) }
} else {
null
},
)
}
} }
} }
} }

View File

@ -2,7 +2,6 @@ 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
@ -24,7 +23,6 @@ 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(),
@ -33,48 +31,39 @@ fun LibraryCompactGrid(
) { ) {
globalSearchItem(searchQuery, onGlobalSearchClicked) globalSearchItem(searchQuery, onGlobalSearchClicked)
if (items.isEmpty()) { items(
item( items = items,
span = { GridItemSpan(maxLineSpan) }, contentType = { "library_compact_grid_item" },
contentType = "library_compact_grid_empty", ) { libraryItem ->
) { val manga = libraryItem.libraryManga.manga
LibraryPagerEmptyScreen(searchQuery, hasActiveFilters, contentPadding) MangaCompactGridItem(
} isSelected = selection.fastAny { it.id == libraryItem.libraryManga.id },
} else { title = manga.title.takeIf { showTitle },
items( coverData = MangaCover(
items = items, mangaId = manga.id,
contentType = { "library_compact_grid_item" }, sourceId = manga.source,
) { libraryItem -> isMangaFavorite = manga.favorite,
val manga = libraryItem.libraryManga.manga url = manga.thumbnailUrl,
MangaCompactGridItem( lastModified = manga.coverLastModified,
isSelected = selection.fastAny { it.id == libraryItem.libraryManga.id }, ),
title = manga.title.takeIf { showTitle }, coverBadgeStart = {
coverData = MangaCover( DownloadsBadge(count = libraryItem.downloadCount.toInt())
mangaId = manga.id, UnreadBadge(count = libraryItem.unreadCount.toInt())
sourceId = manga.source, },
isMangaFavorite = manga.favorite, coverBadgeEnd = {
url = manga.thumbnailUrl, LanguageBadge(
lastModified = manga.coverLastModified, isLocal = libraryItem.isLocal,
), sourceLanguage = libraryItem.sourceLanguage,
coverBadgeStart = { )
DownloadsBadge(count = libraryItem.downloadCount.toInt()) },
UnreadBadge(count = libraryItem.unreadCount.toInt()) onLongClick = { onLongClick(libraryItem.libraryManga) },
}, onClick = { onClick(libraryItem.libraryManga) },
coverBadgeEnd = { onClickContinueReading = if (onClickContinueReading != null) {
LanguageBadge( { onClickContinueReading(libraryItem.libraryManga) }
isLocal = libraryItem.isLocal, } else {
sourceLanguage = libraryItem.sourceLanguage, null
) },
}, )
onLongClick = { onLongClick(libraryItem.libraryManga) },
onClick = { onClick(libraryItem.libraryManga) },
onClickContinueReading = if (onClickContinueReading != null) {
{ onClickContinueReading(libraryItem.libraryManga) }
} else {
null
},
)
}
} }
} }
} }

View File

@ -4,20 +4,15 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastAny import androidx.compose.ui.util.fastAny
import androidx.compose.ui.zIndex
import eu.kanade.domain.library.model.LibraryManga import eu.kanade.domain.library.model.LibraryManga
import eu.kanade.domain.manga.model.MangaCover import eu.kanade.domain.manga.model.MangaCover
import eu.kanade.presentation.components.FastScrollLazyColumn import eu.kanade.presentation.components.FastScrollLazyColumn
import eu.kanade.presentation.components.MangaListItem import eu.kanade.presentation.components.MangaListItem
import eu.kanade.presentation.util.plus import eu.kanade.presentation.util.plus
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.LibraryItem import eu.kanade.tachiyomi.ui.library.LibraryItem
@Composable @Composable
@ -30,7 +25,6 @@ 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(),
@ -38,57 +32,45 @@ fun LibraryList(
) { ) {
item { item {
if (!searchQuery.isNullOrEmpty()) { if (!searchQuery.isNullOrEmpty()) {
TextButton( GlobalSearchItem(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
searchQuery = searchQuery,
onClick = onGlobalSearchClicked, onClick = onGlobalSearchClicked,
) {
Text(
text = stringResource(R.string.action_global_search_query, searchQuery),
modifier = Modifier.zIndex(99f),
)
}
}
}
if (items.isEmpty()) {
item(
contentType = "library_list_empty",
) {
LibraryPagerEmptyScreen(searchQuery, hasActiveFilters, contentPadding)
}
} else {
items(
items = items,
contentType = { "library_list_item" },
) { libraryItem ->
val manga = libraryItem.libraryManga.manga
MangaListItem(
isSelected = selection.fastAny { it.id == libraryItem.libraryManga.id },
title = manga.title,
coverData = MangaCover(
mangaId = manga.id,
sourceId = manga.source,
isMangaFavorite = manga.favorite,
url = manga.thumbnailUrl,
lastModified = manga.coverLastModified,
),
badge = {
DownloadsBadge(count = libraryItem.downloadCount.toInt())
UnreadBadge(count = libraryItem.unreadCount.toInt())
LanguageBadge(
isLocal = libraryItem.isLocal,
sourceLanguage = libraryItem.sourceLanguage,
)
},
onLongClick = { onLongClick(libraryItem.libraryManga) },
onClick = { onClick(libraryItem.libraryManga) },
onClickContinueReading = if (onClickContinueReading != null) {
{ onClickContinueReading(libraryItem.libraryManga) }
} else {
null
},
) )
} }
} }
items(
items = items,
contentType = { "library_list_item" },
) { libraryItem ->
val manga = libraryItem.libraryManga.manga
MangaListItem(
isSelected = selection.fastAny { it.id == libraryItem.libraryManga.id },
title = manga.title,
coverData = MangaCover(
mangaId = manga.id,
sourceId = manga.source,
isMangaFavorite = manga.favorite,
url = manga.thumbnailUrl,
lastModified = manga.coverLastModified,
),
badge = {
DownloadsBadge(count = libraryItem.downloadCount.toInt())
UnreadBadge(count = libraryItem.unreadCount.toInt())
LanguageBadge(
isLocal = libraryItem.isLocal,
sourceLanguage = libraryItem.sourceLanguage,
)
},
onLongClick = { onLongClick(libraryItem.libraryManga) },
onClick = { onClick(libraryItem.libraryManga) },
onClickContinueReading = if (onClickContinueReading != null) {
{ onClickContinueReading(libraryItem.libraryManga) }
} else {
null
},
)
}
} }
} }

View File

@ -1,9 +1,13 @@
package eu.kanade.presentation.library.components package eu.kanade.presentation.library.components
import android.content.res.Configuration import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
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.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -11,12 +15,14 @@ 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.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.dp
import eu.kanade.core.prefs.PreferenceMutableState import eu.kanade.core.prefs.PreferenceMutableState
import eu.kanade.domain.library.model.LibraryDisplayMode import eu.kanade.domain.library.model.LibraryDisplayMode
import eu.kanade.domain.library.model.LibraryManga import eu.kanade.domain.library.model.LibraryManga
import eu.kanade.presentation.components.EmptyScreen import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.HorizontalPager import eu.kanade.presentation.components.HorizontalPager
import eu.kanade.presentation.components.PagerState import eu.kanade.presentation.components.PagerState
import eu.kanade.presentation.util.plus
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.LibraryItem import eu.kanade.tachiyomi.ui.library.LibraryItem
@ -48,6 +54,16 @@ fun LibraryPager(
} }
val library = getLibraryForPage(page) val library = getLibraryForPage(page)
if (library.isEmpty()) {
LibraryPagerEmptyScreen(
searchQuery = searchQuery,
hasActiveFilters = hasActiveFilters,
contentPadding = contentPadding,
onGlobalSearchClicked = onGlobalSearchClicked,
)
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
@ -69,7 +85,6 @@ fun LibraryPager(
onClickContinueReading = onClickContinueReading, onClickContinueReading = onClickContinueReading,
searchQuery = searchQuery, searchQuery = searchQuery,
onGlobalSearchClicked = onGlobalSearchClicked, onGlobalSearchClicked = onGlobalSearchClicked,
hasActiveFilters = hasActiveFilters,
) )
} }
LibraryDisplayMode.CompactGrid, LibraryDisplayMode.CoverOnlyGrid -> { LibraryDisplayMode.CompactGrid, LibraryDisplayMode.CoverOnlyGrid -> {
@ -84,7 +99,6 @@ fun LibraryPager(
onClickContinueReading = onClickContinueReading, onClickContinueReading = onClickContinueReading,
searchQuery = searchQuery, searchQuery = searchQuery,
onGlobalSearchClicked = onGlobalSearchClicked, onGlobalSearchClicked = onGlobalSearchClicked,
hasActiveFilters = hasActiveFilters,
) )
} }
LibraryDisplayMode.ComfortableGrid -> { LibraryDisplayMode.ComfortableGrid -> {
@ -98,7 +112,6 @@ fun LibraryPager(
onClickContinueReading = onClickContinueReading, onClickContinueReading = onClickContinueReading,
searchQuery = searchQuery, searchQuery = searchQuery,
onGlobalSearchClicked = onGlobalSearchClicked, onGlobalSearchClicked = onGlobalSearchClicked,
hasActiveFilters = hasActiveFilters,
) )
} }
} }
@ -106,10 +119,11 @@ fun LibraryPager(
} }
@Composable @Composable
internal fun LibraryPagerEmptyScreen( private fun LibraryPagerEmptyScreen(
searchQuery: String?, searchQuery: String?,
hasActiveFilters: Boolean, hasActiveFilters: Boolean,
contentPadding: PaddingValues, contentPadding: PaddingValues,
onGlobalSearchClicked: () -> Unit,
) { ) {
val msg = when { val msg = when {
!searchQuery.isNullOrEmpty() -> R.string.no_results_found !searchQuery.isNullOrEmpty() -> R.string.no_results_found
@ -117,9 +131,25 @@ internal fun LibraryPagerEmptyScreen(
else -> R.string.information_no_manga_category else -> R.string.information_no_manga_category
} }
// TODO: vertically center this better Column(
EmptyScreen( modifier = Modifier
textResource = msg, .padding(contentPadding + PaddingValues(8.dp))
modifier = Modifier.padding(contentPadding), .fillMaxSize()
) .verticalScroll(rememberScrollState()),
) {
if (!searchQuery.isNullOrEmpty()) {
GlobalSearchItem(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.CenterHorizontally),
searchQuery = searchQuery,
onClick = onGlobalSearchClicked,
)
}
EmptyScreen(
textResource = msg,
modifier = Modifier.weight(1f),
)
}
} }