mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-22 06:51:51 +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:
parent
f90e1b935c
commit
d49ec41f3a
@ -1,12 +1,10 @@
|
|||||||
package eu.kanade.presentation.components
|
package eu.kanade.presentation.components
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.LocalTextStyle
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@ -36,18 +34,15 @@ fun Badge(
|
|||||||
textColor: Color = MaterialTheme.colorScheme.onSecondary,
|
textColor: Color = MaterialTheme.colorScheme.onSecondary,
|
||||||
shape: Shape = RectangleShape,
|
shape: Shape = RectangleShape,
|
||||||
) {
|
) {
|
||||||
Box(
|
Text(
|
||||||
|
text = text,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(shape)
|
.clip(shape)
|
||||||
.background(color),
|
.background(color)
|
||||||
) {
|
.padding(horizontal = 3.dp, vertical = 1.dp),
|
||||||
Text(
|
color = textColor,
|
||||||
text = text,
|
fontWeight = FontWeight.Medium,
|
||||||
modifier = Modifier.padding(horizontal = 4.dp, vertical = 2.dp),
|
maxLines = 1,
|
||||||
style = LocalTextStyle.current.copy(
|
style = MaterialTheme.typography.bodySmall,
|
||||||
color = textColor,
|
)
|
||||||
fontWeight = FontWeight.Medium,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,8 @@ fun LibraryScreen(
|
|||||||
LibraryContent(
|
LibraryContent(
|
||||||
state = presenter,
|
state = presenter,
|
||||||
contentPadding = paddingValues,
|
contentPadding = paddingValues,
|
||||||
currentPage = presenter.activeCategory,
|
currentPage = { presenter.activeCategory },
|
||||||
isLibraryEmpty = presenter.loadedManga.isEmpty(),
|
isLibraryEmpty = { presenter.loadedManga.isEmpty() },
|
||||||
showPageTabs = presenter.tabVisibility,
|
showPageTabs = presenter.tabVisibility,
|
||||||
showMangaCount = presenter.mangaCountVisibility,
|
showMangaCount = presenter.mangaCountVisibility,
|
||||||
onChangeCurrentPage = { presenter.activeCategory = it },
|
onChangeCurrentPage = { presenter.activeCategory = it },
|
||||||
|
@ -4,12 +4,12 @@ import androidx.compose.foundation.combinedClickable
|
|||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.grid.items
|
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.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
import eu.kanade.domain.manga.model.MangaCover
|
import eu.kanade.domain.manga.model.MangaCover
|
||||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||||
import eu.kanade.tachiyomi.ui.library.LibraryItem
|
import eu.kanade.tachiyomi.ui.library.LibraryItem
|
||||||
@ -81,8 +81,9 @@ fun LibraryComfortableGridItem(
|
|||||||
Text(
|
Text(
|
||||||
modifier = Modifier.padding(4.dp),
|
modifier = Modifier.padding(4.dp),
|
||||||
text = manga.title,
|
text = manga.title,
|
||||||
|
fontSize = 12.sp,
|
||||||
maxLines = 2,
|
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.layout.padding
|
||||||
import androidx.compose.foundation.lazy.grid.items
|
import androidx.compose.foundation.lazy.grid.items
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
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.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.Shadow
|
import androidx.compose.ui.graphics.Shadow
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||||
import eu.kanade.tachiyomi.ui.library.LibraryItem
|
import eu.kanade.tachiyomi.ui.library.LibraryItem
|
||||||
|
|
||||||
@ -102,10 +102,10 @@ fun LibraryCompactGridItem(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
.align(Alignment.BottomStart),
|
.align(Alignment.BottomStart),
|
||||||
|
color = Color.White,
|
||||||
|
fontSize = 12.sp,
|
||||||
maxLines = 2,
|
maxLines = 2,
|
||||||
style = LocalTextStyle.current.copy(
|
style = MaterialTheme.typography.titleSmall.copy(
|
||||||
color = Color.White,
|
|
||||||
fontWeight = FontWeight.SemiBold,
|
|
||||||
shadow = Shadow(
|
shadow = Shadow(
|
||||||
color = Color.Black,
|
color = Color.Black,
|
||||||
blurRadius = 4f,
|
blurRadius = 4f,
|
||||||
|
@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import com.google.accompanist.pager.rememberPagerState
|
import com.google.accompanist.pager.rememberPagerState
|
||||||
@ -26,8 +27,8 @@ import eu.kanade.tachiyomi.widget.EmptyView
|
|||||||
fun LibraryContent(
|
fun LibraryContent(
|
||||||
state: LibraryState,
|
state: LibraryState,
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
currentPage: Int,
|
currentPage: () -> Int,
|
||||||
isLibraryEmpty: Boolean,
|
isLibraryEmpty: () -> Boolean,
|
||||||
isDownloadOnly: Boolean,
|
isDownloadOnly: Boolean,
|
||||||
isIncognitoMode: Boolean,
|
isIncognitoMode: Boolean,
|
||||||
showPageTabs: Boolean,
|
showPageTabs: Boolean,
|
||||||
@ -42,12 +43,13 @@ fun LibraryContent(
|
|||||||
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
||||||
getLibraryForPage: @Composable (Int) -> State<List<LibraryItem>>,
|
getLibraryForPage: @Composable (Int) -> State<List<LibraryItem>>,
|
||||||
) {
|
) {
|
||||||
val categories = state.categories
|
|
||||||
val pagerState = rememberPagerState(currentPage.coerceAtMost(categories.lastIndex))
|
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.padding(contentPadding),
|
modifier = Modifier.padding(contentPadding),
|
||||||
) {
|
) {
|
||||||
|
val categories = state.categories
|
||||||
|
val coercedCurrentPage = remember { currentPage().coerceAtMost(categories.lastIndex) }
|
||||||
|
val pagerState = rememberPagerState(coercedCurrentPage)
|
||||||
|
|
||||||
if (showPageTabs && categories.size > 1) {
|
if (showPageTabs && categories.size > 1) {
|
||||||
LibraryTabs(
|
LibraryTabs(
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
@ -72,7 +74,7 @@ fun LibraryContent(
|
|||||||
|
|
||||||
SwipeRefresh(
|
SwipeRefresh(
|
||||||
state = rememberSwipeRefreshState(isRefreshing = false),
|
state = rememberSwipeRefreshState(isRefreshing = false),
|
||||||
onRefresh = { onRefresh(categories[currentPage]) },
|
onRefresh = { onRefresh(categories[currentPage()]) },
|
||||||
indicator = { s, trigger ->
|
indicator = { s, trigger ->
|
||||||
SwipeRefreshIndicator(
|
SwipeRefreshIndicator(
|
||||||
state = s,
|
state = s,
|
||||||
@ -80,7 +82,7 @@ fun LibraryContent(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
if (state.searchQuery.isNullOrEmpty() && isLibraryEmpty) {
|
if (state.searchQuery.isNullOrEmpty() && isLibraryEmpty()) {
|
||||||
val handler = LocalUriHandler.current
|
val handler = LocalUriHandler.current
|
||||||
EmptyScreen(
|
EmptyScreen(
|
||||||
R.string.information_empty_library,
|
R.string.information_empty_library,
|
||||||
|
@ -36,40 +36,43 @@ fun LibraryGridCover(
|
|||||||
data = mangaCover,
|
data = mangaCover,
|
||||||
)
|
)
|
||||||
content()
|
content()
|
||||||
BadgeGroup(
|
if (downloadCount > 0 || unreadCount > 0) {
|
||||||
modifier = Modifier
|
BadgeGroup(
|
||||||
.padding(4.dp)
|
modifier = Modifier
|
||||||
.align(Alignment.TopStart),
|
.padding(4.dp)
|
||||||
) {
|
.align(Alignment.TopStart),
|
||||||
if (downloadCount > 0) {
|
) {
|
||||||
Badge(
|
if (downloadCount > 0) {
|
||||||
text = "$downloadCount",
|
Badge(
|
||||||
color = MaterialTheme.colorScheme.tertiary,
|
text = "$downloadCount",
|
||||||
textColor = MaterialTheme.colorScheme.onTertiary,
|
color = MaterialTheme.colorScheme.tertiary,
|
||||||
)
|
textColor = MaterialTheme.colorScheme.onTertiary,
|
||||||
}
|
)
|
||||||
if (unreadCount > 0) {
|
}
|
||||||
Badge(text = "$unreadCount")
|
if (unreadCount > 0) {
|
||||||
|
Badge(text = "$unreadCount")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BadgeGroup(
|
if (isLocal || language.isNotEmpty()) {
|
||||||
modifier = Modifier
|
BadgeGroup(
|
||||||
.padding(4.dp)
|
modifier = Modifier
|
||||||
.align(Alignment.TopEnd),
|
.padding(4.dp)
|
||||||
) {
|
.align(Alignment.TopEnd),
|
||||||
if (isLocal) {
|
) {
|
||||||
Badge(
|
if (isLocal) {
|
||||||
text = stringResource(R.string.local_source_badge),
|
Badge(
|
||||||
color = MaterialTheme.colorScheme.tertiary,
|
text = stringResource(R.string.local_source_badge),
|
||||||
textColor = MaterialTheme.colorScheme.onTertiary,
|
color = MaterialTheme.colorScheme.tertiary,
|
||||||
)
|
textColor = MaterialTheme.colorScheme.onTertiary,
|
||||||
}
|
)
|
||||||
if (isLocal.not() && language.isNotEmpty()) {
|
} else if (language.isNotEmpty()) {
|
||||||
Badge(
|
Badge(
|
||||||
text = language,
|
text = language,
|
||||||
color = MaterialTheme.colorScheme.tertiary,
|
color = MaterialTheme.colorScheme.tertiary,
|
||||||
textColor = MaterialTheme.colorScheme.onTertiary,
|
textColor = MaterialTheme.colorScheme.onTertiary,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,10 @@ fun LibraryPager(
|
|||||||
state = state,
|
state = state,
|
||||||
verticalAlignment = Alignment.Top,
|
verticalAlignment = Alignment.Top,
|
||||||
) { page ->
|
) { 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 library by getLibraryForPage(page)
|
||||||
val displayMode by getDisplayModeForPage(page)
|
val displayMode by getDisplayModeForPage(page)
|
||||||
val columns by if (displayMode != DisplayModeSetting.LIST) {
|
val columns by if (displayMode != DisplayModeSetting.LIST) {
|
||||||
|
Loading…
Reference in New Issue
Block a user