LibraryPager.kt 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package eu.kanade.presentation.library.components
  2. import android.content.res.Configuration
  3. import androidx.compose.foundation.layout.Column
  4. import androidx.compose.foundation.layout.PaddingValues
  5. import androidx.compose.foundation.layout.fillMaxSize
  6. import androidx.compose.foundation.layout.fillMaxWidth
  7. import androidx.compose.foundation.layout.padding
  8. import androidx.compose.foundation.pager.PagerState
  9. import androidx.compose.foundation.rememberScrollState
  10. import androidx.compose.foundation.verticalScroll
  11. import androidx.compose.runtime.Composable
  12. import androidx.compose.runtime.getValue
  13. import androidx.compose.runtime.mutableIntStateOf
  14. import androidx.compose.runtime.remember
  15. import androidx.compose.ui.Alignment
  16. import androidx.compose.ui.Modifier
  17. import androidx.compose.ui.platform.LocalConfiguration
  18. import androidx.compose.ui.unit.dp
  19. import eu.kanade.core.preference.PreferenceMutableState
  20. import eu.kanade.tachiyomi.R
  21. import eu.kanade.tachiyomi.ui.library.LibraryItem
  22. import tachiyomi.domain.library.model.LibraryDisplayMode
  23. import tachiyomi.domain.library.model.LibraryManga
  24. import tachiyomi.presentation.core.components.HorizontalPager
  25. import tachiyomi.presentation.core.screens.EmptyScreen
  26. import tachiyomi.presentation.core.util.plus
  27. @Composable
  28. fun LibraryPager(
  29. state: PagerState,
  30. contentPadding: PaddingValues,
  31. hasActiveFilters: Boolean,
  32. selectedManga: List<LibraryManga>,
  33. searchQuery: String?,
  34. onGlobalSearchClicked: () -> Unit,
  35. getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>,
  36. getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
  37. getLibraryForPage: (Int) -> List<LibraryItem>,
  38. onClickManga: (LibraryManga) -> Unit,
  39. onLongClickManga: (LibraryManga) -> Unit,
  40. onClickContinueReading: ((LibraryManga) -> Unit)?,
  41. ) {
  42. HorizontalPager(
  43. modifier = Modifier.fillMaxSize(),
  44. state = state,
  45. verticalAlignment = Alignment.Top,
  46. ) { page ->
  47. if (page !in ((state.currentPage - 1)..(state.currentPage + 1))) {
  48. // To make sure only one offscreen page is being composed
  49. return@HorizontalPager
  50. }
  51. val library = getLibraryForPage(page)
  52. if (library.isEmpty()) {
  53. LibraryPagerEmptyScreen(
  54. searchQuery = searchQuery,
  55. hasActiveFilters = hasActiveFilters,
  56. contentPadding = contentPadding,
  57. onGlobalSearchClicked = onGlobalSearchClicked,
  58. )
  59. return@HorizontalPager
  60. }
  61. val displayMode by getDisplayMode(page)
  62. val columns by if (displayMode != LibraryDisplayMode.List) {
  63. val configuration = LocalConfiguration.current
  64. val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
  65. remember(isLandscape) { getColumnsForOrientation(isLandscape) }
  66. } else {
  67. remember { mutableIntStateOf(0) }
  68. }
  69. when (displayMode) {
  70. LibraryDisplayMode.List -> {
  71. LibraryList(
  72. items = library,
  73. contentPadding = contentPadding,
  74. selection = selectedManga,
  75. onClick = onClickManga,
  76. onLongClick = onLongClickManga,
  77. onClickContinueReading = onClickContinueReading,
  78. searchQuery = searchQuery,
  79. onGlobalSearchClicked = onGlobalSearchClicked,
  80. )
  81. }
  82. LibraryDisplayMode.CompactGrid, LibraryDisplayMode.CoverOnlyGrid -> {
  83. LibraryCompactGrid(
  84. items = library,
  85. showTitle = displayMode is LibraryDisplayMode.CompactGrid,
  86. columns = columns,
  87. contentPadding = contentPadding,
  88. selection = selectedManga,
  89. onClick = onClickManga,
  90. onLongClick = onLongClickManga,
  91. onClickContinueReading = onClickContinueReading,
  92. searchQuery = searchQuery,
  93. onGlobalSearchClicked = onGlobalSearchClicked,
  94. )
  95. }
  96. LibraryDisplayMode.ComfortableGrid -> {
  97. LibraryComfortableGrid(
  98. items = library,
  99. columns = columns,
  100. contentPadding = contentPadding,
  101. selection = selectedManga,
  102. onClick = onClickManga,
  103. onLongClick = onLongClickManga,
  104. onClickContinueReading = onClickContinueReading,
  105. searchQuery = searchQuery,
  106. onGlobalSearchClicked = onGlobalSearchClicked,
  107. )
  108. }
  109. }
  110. }
  111. }
  112. @Composable
  113. private fun LibraryPagerEmptyScreen(
  114. searchQuery: String?,
  115. hasActiveFilters: Boolean,
  116. contentPadding: PaddingValues,
  117. onGlobalSearchClicked: () -> Unit,
  118. ) {
  119. val msg = when {
  120. !searchQuery.isNullOrEmpty() -> R.string.no_results_found
  121. hasActiveFilters -> R.string.error_no_match
  122. else -> R.string.information_no_manga_category
  123. }
  124. Column(
  125. modifier = Modifier
  126. .padding(contentPadding + PaddingValues(8.dp))
  127. .fillMaxSize()
  128. .verticalScroll(rememberScrollState()),
  129. ) {
  130. if (!searchQuery.isNullOrEmpty()) {
  131. GlobalSearchItem(
  132. modifier = Modifier
  133. .fillMaxWidth()
  134. .align(Alignment.CenterHorizontally),
  135. searchQuery = searchQuery,
  136. onClick = onGlobalSearchClicked,
  137. )
  138. }
  139. EmptyScreen(
  140. textResource = msg,
  141. modifier = Modifier.weight(1f),
  142. )
  143. }
  144. }