From 758cc4fad4206a13e5268f5065d7c1919091e2ec Mon Sep 17 00:00:00 2001 From: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Date: Sat, 30 Jul 2022 22:47:27 +0700 Subject: [PATCH] Library category page performance fixes (#7650) * Don't compose category page unnecessarily * Remove unnecessary library pager recompose Defer and remember the "currentPage" state read since it's only needed when the pager is composed for the first time. * Badge opts * Sync text style with previous impl Also avoid reallocating by using copy (cherry picked from commit d49ec41f3a68574601d5d773382045fdbc6624d8) # Conflicts: # app/src/main/java/eu/kanade/presentation/library/components/LibraryGridCover.kt --- .../kanade/presentation/components/Badges.kt | 23 ++--- .../presentation/library/LibraryScreen.kt | 4 +- .../components/LibraryComfortableGrid.kt | 7 +- .../library/components/LibraryCompactGrid.kt | 10 +-- .../library/components/LibraryContent.kt | 16 ++-- .../library/components/LibraryGridCover.kt | 87 +++++++++++-------- .../library/components/LibraryPager.kt | 4 + 7 files changed, 82 insertions(+), 69 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/components/Badges.kt b/app/src/main/java/eu/kanade/presentation/components/Badges.kt index d15a06640..7bc79e0cb 100644 --- a/app/src/main/java/eu/kanade/presentation/components/Badges.kt +++ b/app/src/main/java/eu/kanade/presentation/components/Badges.kt @@ -1,12 +1,10 @@ package eu.kanade.presentation.components import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -36,18 +34,15 @@ fun Badge( textColor: Color = MaterialTheme.colorScheme.onSecondary, shape: Shape = RectangleShape, ) { - Box( + Text( + text = text, modifier = Modifier .clip(shape) - .background(color), - ) { - Text( - text = text, - modifier = Modifier.padding(horizontal = 4.dp, vertical = 2.dp), - style = LocalTextStyle.current.copy( - color = textColor, - fontWeight = FontWeight.Medium, - ), - ) - } + .background(color) + .padding(horizontal = 3.dp, vertical = 1.dp), + color = textColor, + fontWeight = FontWeight.Medium, + maxLines = 1, + style = MaterialTheme.typography.bodySmall, + ) } diff --git a/app/src/main/java/eu/kanade/presentation/library/LibraryScreen.kt b/app/src/main/java/eu/kanade/presentation/library/LibraryScreen.kt index 92ddb6b8c..340efcbb8 100644 --- a/app/src/main/java/eu/kanade/presentation/library/LibraryScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/library/LibraryScreen.kt @@ -77,8 +77,8 @@ fun LibraryScreen( LibraryContent( state = presenter, contentPadding = paddingValues, - currentPage = presenter.activeCategory, - isLibraryEmpty = presenter.loadedManga.isEmpty(), + currentPage = { presenter.activeCategory }, + isLibraryEmpty = { presenter.loadedManga.isEmpty() }, showPageTabs = presenter.tabVisibility, showMangaCount = presenter.mangaCountVisibility, onChangeCurrentPage = { presenter.activeCategory = it }, diff --git a/app/src/main/java/eu/kanade/presentation/library/components/LibraryComfortableGrid.kt b/app/src/main/java/eu/kanade/presentation/library/components/LibraryComfortableGrid.kt index 77758526a..adcf55f84 100644 --- a/app/src/main/java/eu/kanade/presentation/library/components/LibraryComfortableGrid.kt +++ b/app/src/main/java/eu/kanade/presentation/library/components/LibraryComfortableGrid.kt @@ -4,12 +4,12 @@ import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.grid.items -import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import eu.kanade.domain.manga.model.MangaCover import eu.kanade.tachiyomi.data.database.models.LibraryManga import eu.kanade.tachiyomi.ui.library.LibraryItem @@ -94,8 +94,9 @@ fun LibraryComfortableGridItem( Text( modifier = Modifier.padding(4.dp), text = manga.title, + fontSize = 12.sp, maxLines = 2, - style = LocalTextStyle.current.copy(fontWeight = FontWeight.SemiBold), + style = MaterialTheme.typography.titleSmall, ) } } diff --git a/app/src/main/java/eu/kanade/presentation/library/components/LibraryCompactGrid.kt b/app/src/main/java/eu/kanade/presentation/library/components/LibraryCompactGrid.kt index a6d6676fb..03be60f62 100644 --- a/app/src/main/java/eu/kanade/presentation/library/components/LibraryCompactGrid.kt +++ b/app/src/main/java/eu/kanade/presentation/library/components/LibraryCompactGrid.kt @@ -8,7 +8,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -17,8 +17,8 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shadow -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import eu.kanade.tachiyomi.data.database.models.LibraryManga import eu.kanade.tachiyomi.ui.library.LibraryItem @@ -118,10 +118,10 @@ fun LibraryCompactGridItem( modifier = Modifier .padding(8.dp) .align(Alignment.BottomStart), + color = Color.White, + fontSize = 12.sp, maxLines = 2, - style = LocalTextStyle.current.copy( - color = Color.White, - fontWeight = FontWeight.SemiBold, + style = MaterialTheme.typography.titleSmall.copy( shadow = Shadow( color = Color.Black, blurRadius = 4f, diff --git a/app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt b/app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt index a5efc3262..00791b6a7 100644 --- a/app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt +++ b/app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.State +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalUriHandler import com.google.accompanist.pager.rememberPagerState @@ -26,8 +27,8 @@ import eu.kanade.tachiyomi.widget.EmptyView fun LibraryContent( state: LibraryState, contentPadding: PaddingValues, - currentPage: Int, - isLibraryEmpty: Boolean, + currentPage: () -> Int, + isLibraryEmpty: () -> Boolean, isDownloadOnly: Boolean, isIncognitoMode: Boolean, showPageTabs: Boolean, @@ -45,12 +46,13 @@ fun LibraryContent( onOpenReader: (LibraryManga) -> Unit, // SY <-- ) { - val categories = state.categories - val pagerState = rememberPagerState(currentPage.coerceAtMost(categories.lastIndex)) - Column( modifier = Modifier.padding(contentPadding), ) { + val categories = state.categories + val coercedCurrentPage = remember { currentPage().coerceAtMost(categories.lastIndex) } + val pagerState = rememberPagerState(coercedCurrentPage) + if (showPageTabs && categories.size > 1) { LibraryTabs( state = pagerState, @@ -75,7 +77,7 @@ fun LibraryContent( SwipeRefresh( state = rememberSwipeRefreshState(isRefreshing = false), - onRefresh = { onRefresh(categories[currentPage]) }, + onRefresh = { onRefresh(categories[currentPage()]) }, indicator = { s, trigger -> SwipeRefreshIndicator( state = s, @@ -83,7 +85,7 @@ fun LibraryContent( ) }, ) { - if (state.searchQuery.isNullOrEmpty() && isLibraryEmpty) { + if (state.searchQuery.isNullOrEmpty() && isLibraryEmpty()) { val handler = LocalUriHandler.current EmptyScreen( R.string.information_empty_library, diff --git a/app/src/main/java/eu/kanade/presentation/library/components/LibraryGridCover.kt b/app/src/main/java/eu/kanade/presentation/library/components/LibraryGridCover.kt index 7664d17c3..7e0ffc9f7 100644 --- a/app/src/main/java/eu/kanade/presentation/library/components/LibraryGridCover.kt +++ b/app/src/main/java/eu/kanade/presentation/library/components/LibraryGridCover.kt @@ -42,55 +42,63 @@ fun LibraryGridCover( data = mangaCover, ) content() - BadgeGroup( - modifier = Modifier - .padding(4.dp) - .align(Alignment.TopStart), - ) { - if (downloadCount > 0) { - Badge( - text = "$downloadCount", - color = MaterialTheme.colorScheme.tertiary, - textColor = MaterialTheme.colorScheme.onTertiary, - ) - } - if (unreadCount > 0) { - Badge(text = "$unreadCount") - } - } - // SY --> - Column( - Modifier.align(Alignment.TopEnd), - horizontalAlignment = Alignment.End, - ) { - // SY <-- + if (downloadCount > 0 || unreadCount > 0) { BadgeGroup( modifier = Modifier - .padding(4.dp), + .padding(4.dp) + .align(Alignment.TopStart), ) { - if (isLocal) { + if (downloadCount > 0) { Badge( - text = stringResource(R.string.local_source_badge), + text = "$downloadCount", color = MaterialTheme.colorScheme.tertiary, textColor = MaterialTheme.colorScheme.onTertiary, ) } - if (isLocal.not() && language.isNotEmpty()) { - Badge( - text = language, - color = MaterialTheme.colorScheme.tertiary, - textColor = MaterialTheme.colorScheme.onTertiary, - ) + if (unreadCount > 0) { + Badge(text = "$unreadCount") } } - // SY --> - if (showPlayButton && playButtonPosition == PlayButtonPosition.Top) { - StartReadingButton(onOpenReader = onOpenReader) - } } - if (showPlayButton && playButtonPosition == PlayButtonPosition.Bottom) { + if (isLocal || language.isNotEmpty()) { + // SY --> + Column( + Modifier.align(Alignment.TopEnd), + horizontalAlignment = Alignment.End, + ) { + // SY <-- + BadgeGroup( + modifier = Modifier + .padding(4.dp), + ) { + if (isLocal) { + Badge( + text = stringResource(R.string.local_source_badge), + color = MaterialTheme.colorScheme.tertiary, + textColor = MaterialTheme.colorScheme.onTertiary, + ) + } else if (language.isNotEmpty()) { + Badge( + text = language, + color = MaterialTheme.colorScheme.tertiary, + textColor = MaterialTheme.colorScheme.onTertiary, + ) + } + } + // SY --> + if (showPlayButton && playButtonPosition == PlayButtonPosition.Top) { + StartReadingButton(onOpenReader = onOpenReader) + } + } + if (showPlayButton && playButtonPosition == PlayButtonPosition.Bottom) { + StartReadingButton( + Modifier.align(playButtonPosition.alignment), + onOpenReader = onOpenReader, + ) + } + } else if (showPlayButton) { StartReadingButton( - Modifier.align(Alignment.BottomEnd), + modifier = Modifier.align(playButtonPosition.alignment), onOpenReader = onOpenReader, ) } @@ -98,4 +106,7 @@ fun LibraryGridCover( } } -enum class PlayButtonPosition { Top, Bottom } +enum class PlayButtonPosition(val alignment: Alignment) { + Top(Alignment.TopEnd), + Bottom(Alignment.BottomEnd) +} diff --git a/app/src/main/java/eu/kanade/presentation/library/components/LibraryPager.kt b/app/src/main/java/eu/kanade/presentation/library/components/LibraryPager.kt index ecbbb3feb..972a98054 100644 --- a/app/src/main/java/eu/kanade/presentation/library/components/LibraryPager.kt +++ b/app/src/main/java/eu/kanade/presentation/library/components/LibraryPager.kt @@ -39,6 +39,10 @@ fun LibraryPager( state = state, verticalAlignment = Alignment.Top, ) { page -> + if (page !in ((state.currentPage - 1)..(state.currentPage + 1))) { + // To make sure only one offscreen page is being composed + return@HorizontalPager + } val library by getLibraryForPage(page) val displayMode by getDisplayModeForPage(page) val columns by if (displayMode != DisplayModeSetting.LIST) {