From d49ec41f3a68574601d5d773382045fdbc6624d8 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 --- .../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 | 67 ++++++++++--------- .../library/components/LibraryPager.kt | 4 ++ 7 files changed, 68 insertions(+), 63 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 d15a06640c..7bc79e0cb6 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 1f7baaa8c8..841ecd4fb4 100644 --- a/app/src/main/java/eu/kanade/presentation/library/LibraryScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/library/LibraryScreen.kt @@ -61,8 +61,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 849406fa03..23e089a838 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 @@ -81,8 +81,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 0d47c4f4f5..8d588d7303 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 @@ -102,10 +102,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 a42f65d111..d8fc19e2db 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, @@ -42,12 +43,13 @@ fun LibraryContent( getColumnsForOrientation: (Boolean) -> PreferenceMutableState, getLibraryForPage: @Composable (Int) -> State>, ) { - 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, @@ -72,7 +74,7 @@ fun LibraryContent( SwipeRefresh( state = rememberSwipeRefreshState(isRefreshing = false), - onRefresh = { onRefresh(categories[currentPage]) }, + onRefresh = { onRefresh(categories[currentPage()]) }, indicator = { s, trigger -> SwipeRefreshIndicator( state = s, @@ -80,7 +82,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 b67b1f50af..79bdda245e 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 @@ -36,40 +36,43 @@ 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") + if (downloadCount > 0 || unreadCount > 0) { + 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") + } } } - BadgeGroup( - modifier = Modifier - .padding(4.dp) - .align(Alignment.TopEnd), - ) { - if (isLocal) { - Badge( - text = stringResource(R.string.local_source_badge), - 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 (isLocal || language.isNotEmpty()) { + BadgeGroup( + modifier = Modifier + .padding(4.dp) + .align(Alignment.TopEnd), + ) { + 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, + ) + } } } } 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 b2934eed6a..432a6f47f7 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 @@ -36,6 +36,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) {