LibraryContent.kt 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package eu.kanade.presentation.library.components
  2. import androidx.compose.foundation.layout.Column
  3. import androidx.compose.foundation.layout.PaddingValues
  4. import androidx.compose.foundation.layout.calculateEndPadding
  5. import androidx.compose.foundation.layout.calculateStartPadding
  6. import androidx.compose.foundation.layout.padding
  7. import androidx.compose.runtime.Composable
  8. import androidx.compose.runtime.LaunchedEffect
  9. import androidx.compose.runtime.State
  10. import androidx.compose.runtime.getValue
  11. import androidx.compose.runtime.mutableStateOf
  12. import androidx.compose.runtime.remember
  13. import androidx.compose.runtime.rememberCoroutineScope
  14. import androidx.compose.runtime.setValue
  15. import androidx.compose.ui.Modifier
  16. import androidx.compose.ui.platform.LocalLayoutDirection
  17. import com.google.accompanist.pager.rememberPagerState
  18. import eu.kanade.core.prefs.PreferenceMutableState
  19. import eu.kanade.domain.category.model.Category
  20. import eu.kanade.domain.library.model.LibraryDisplayMode
  21. import eu.kanade.domain.library.model.LibraryManga
  22. import eu.kanade.presentation.components.SwipeRefresh
  23. import eu.kanade.presentation.library.LibraryState
  24. import eu.kanade.tachiyomi.ui.library.LibraryItem
  25. import kotlinx.coroutines.delay
  26. import kotlinx.coroutines.launch
  27. import kotlin.time.Duration.Companion.seconds
  28. @Composable
  29. fun LibraryContent(
  30. state: LibraryState,
  31. contentPadding: PaddingValues,
  32. currentPage: () -> Int,
  33. isLibraryEmpty: Boolean,
  34. showPageTabs: Boolean,
  35. showMangaCount: Boolean,
  36. onChangeCurrentPage: (Int) -> Unit,
  37. onMangaClicked: (Long) -> Unit,
  38. onToggleSelection: (LibraryManga) -> Unit,
  39. onToggleRangeSelection: (LibraryManga) -> Unit,
  40. onRefresh: (Category?) -> Boolean,
  41. onGlobalSearchClicked: () -> Unit,
  42. getNumberOfMangaForCategory: @Composable (Long) -> State<Int?>,
  43. getDisplayModeForPage: @Composable (Int) -> LibraryDisplayMode,
  44. getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
  45. getLibraryForPage: @Composable (Int) -> List<LibraryItem>,
  46. showDownloadBadges: Boolean,
  47. showUnreadBadges: Boolean,
  48. showLocalBadges: Boolean,
  49. showLanguageBadges: Boolean,
  50. isDownloadOnly: Boolean,
  51. isIncognitoMode: Boolean,
  52. ) {
  53. Column(
  54. modifier = Modifier.padding(
  55. top = contentPadding.calculateTopPadding(),
  56. start = contentPadding.calculateStartPadding(LocalLayoutDirection.current),
  57. end = contentPadding.calculateEndPadding(LocalLayoutDirection.current),
  58. ),
  59. ) {
  60. val categories = state.categories
  61. val coercedCurrentPage = remember { currentPage().coerceAtMost(categories.lastIndex) }
  62. val pagerState = rememberPagerState(coercedCurrentPage)
  63. val scope = rememberCoroutineScope()
  64. var isRefreshing by remember(pagerState.currentPage) { mutableStateOf(false) }
  65. if (isLibraryEmpty.not() && showPageTabs && categories.size > 1) {
  66. LibraryTabs(
  67. state = pagerState,
  68. categories = categories,
  69. showMangaCount = showMangaCount,
  70. getNumberOfMangaForCategory = getNumberOfMangaForCategory,
  71. isDownloadOnly = isDownloadOnly,
  72. isIncognitoMode = isIncognitoMode,
  73. )
  74. }
  75. val onClickManga = { manga: LibraryManga ->
  76. if (state.selectionMode.not()) {
  77. onMangaClicked(manga.manga.id)
  78. } else {
  79. onToggleSelection(manga)
  80. }
  81. }
  82. val onLongClickManga = { manga: LibraryManga ->
  83. onToggleRangeSelection(manga)
  84. }
  85. SwipeRefresh(
  86. refreshing = isRefreshing,
  87. onRefresh = {
  88. val started = onRefresh(categories[currentPage()])
  89. if (!started) return@SwipeRefresh
  90. scope.launch {
  91. // Fake refresh status but hide it after a second as it's a long running task
  92. isRefreshing = true
  93. delay(1.seconds)
  94. isRefreshing = false
  95. }
  96. },
  97. enabled = state.selectionMode.not(),
  98. ) {
  99. LibraryPager(
  100. state = pagerState,
  101. contentPadding = PaddingValues(bottom = contentPadding.calculateBottomPadding()),
  102. pageCount = categories.size,
  103. selectedManga = state.selection,
  104. getDisplayModeForPage = getDisplayModeForPage,
  105. getColumnsForOrientation = getColumnsForOrientation,
  106. getLibraryForPage = getLibraryForPage,
  107. showDownloadBadges = showDownloadBadges,
  108. showUnreadBadges = showUnreadBadges,
  109. showLocalBadges = showLocalBadges,
  110. showLanguageBadges = showLanguageBadges,
  111. onClickManga = onClickManga,
  112. onLongClickManga = onLongClickManga,
  113. onGlobalSearchClicked = onGlobalSearchClicked,
  114. searchQuery = state.searchQuery,
  115. )
  116. }
  117. LaunchedEffect(pagerState.currentPage) {
  118. onChangeCurrentPage(pagerState.currentPage)
  119. }
  120. }
  121. }