mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	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
This commit is contained in:
		| @@ -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, | ||||
|     ) | ||||
| } | ||||
|   | ||||
| @@ -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 }, | ||||
|   | ||||
| @@ -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, | ||||
|             ) | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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<Int>, | ||||
|     getLibraryForPage: @Composable (Int) -> State<List<LibraryItem>>, | ||||
| ) { | ||||
|     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, | ||||
|   | ||||
| @@ -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, | ||||
|                     ) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user