LibraryToolbar.kt 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. package eu.kanade.presentation.library.components
  2. import androidx.compose.foundation.isSystemInDarkTheme
  3. import androidx.compose.foundation.layout.Row
  4. import androidx.compose.material.icons.Icons
  5. import androidx.compose.material.icons.outlined.FilterList
  6. import androidx.compose.material.icons.outlined.FlipToBack
  7. import androidx.compose.material.icons.outlined.SelectAll
  8. import androidx.compose.material3.DropdownMenuItem
  9. import androidx.compose.material3.Icon
  10. import androidx.compose.material3.IconButton
  11. import androidx.compose.material3.LocalContentColor
  12. import androidx.compose.material3.MaterialTheme
  13. import androidx.compose.material3.Text
  14. import androidx.compose.material3.TopAppBarScrollBehavior
  15. import androidx.compose.runtime.Composable
  16. import androidx.compose.ui.Alignment
  17. import androidx.compose.ui.Modifier
  18. import androidx.compose.ui.res.stringResource
  19. import androidx.compose.ui.text.style.TextOverflow
  20. import androidx.compose.ui.unit.sp
  21. import eu.kanade.presentation.components.AppBar
  22. import eu.kanade.presentation.components.OverflowMenu
  23. import eu.kanade.presentation.components.Pill
  24. import eu.kanade.presentation.components.SearchToolbar
  25. import eu.kanade.presentation.library.LibraryState
  26. import eu.kanade.presentation.theme.active
  27. import eu.kanade.tachiyomi.R
  28. @Composable
  29. fun LibraryToolbar(
  30. state: LibraryState,
  31. title: LibraryToolbarTitle,
  32. incognitoMode: Boolean,
  33. downloadedOnlyMode: Boolean,
  34. onClickUnselectAll: () -> Unit,
  35. onClickSelectAll: () -> Unit,
  36. onClickInvertSelection: () -> Unit,
  37. onClickFilter: () -> Unit,
  38. onClickRefresh: () -> Unit,
  39. onClickOpenRandomManga: () -> Unit,
  40. scrollBehavior: TopAppBarScrollBehavior?,
  41. ) = when {
  42. state.selectionMode -> LibrarySelectionToolbar(
  43. state = state,
  44. incognitoMode = incognitoMode,
  45. downloadedOnlyMode = downloadedOnlyMode,
  46. onClickUnselectAll = onClickUnselectAll,
  47. onClickSelectAll = onClickSelectAll,
  48. onClickInvertSelection = onClickInvertSelection,
  49. )
  50. else -> LibraryRegularToolbar(
  51. title = title,
  52. hasFilters = state.hasActiveFilters,
  53. incognitoMode = incognitoMode,
  54. downloadedOnlyMode = downloadedOnlyMode,
  55. searchQuery = state.searchQuery,
  56. onChangeSearchQuery = { state.searchQuery = it },
  57. onClickFilter = onClickFilter,
  58. onClickRefresh = onClickRefresh,
  59. onClickOpenRandomManga = onClickOpenRandomManga,
  60. scrollBehavior = scrollBehavior,
  61. )
  62. }
  63. @Composable
  64. fun LibraryRegularToolbar(
  65. title: LibraryToolbarTitle,
  66. hasFilters: Boolean,
  67. incognitoMode: Boolean,
  68. downloadedOnlyMode: Boolean,
  69. searchQuery: String?,
  70. onChangeSearchQuery: (String?) -> Unit,
  71. onClickFilter: () -> Unit,
  72. onClickRefresh: () -> Unit,
  73. onClickOpenRandomManga: () -> Unit,
  74. scrollBehavior: TopAppBarScrollBehavior?,
  75. ) {
  76. val pillAlpha = if (isSystemInDarkTheme()) 0.12f else 0.08f
  77. val filterTint = if (hasFilters) MaterialTheme.colorScheme.active else LocalContentColor.current
  78. SearchToolbar(
  79. titleContent = {
  80. Row(verticalAlignment = Alignment.CenterVertically) {
  81. Text(
  82. text = title.text,
  83. maxLines = 1,
  84. modifier = Modifier.weight(1f, false),
  85. overflow = TextOverflow.Ellipsis,
  86. )
  87. if (title.numberOfManga != null) {
  88. Pill(
  89. text = "${title.numberOfManga}",
  90. color = MaterialTheme.colorScheme.onBackground.copy(alpha = pillAlpha),
  91. fontSize = 14.sp,
  92. )
  93. }
  94. }
  95. },
  96. searchQuery = searchQuery,
  97. onChangeSearchQuery = onChangeSearchQuery,
  98. actions = {
  99. IconButton(onClick = onClickFilter) {
  100. Icon(Icons.Outlined.FilterList, contentDescription = stringResource(R.string.action_filter), tint = filterTint)
  101. }
  102. OverflowMenu { closeMenu ->
  103. DropdownMenuItem(
  104. text = { Text(text = stringResource(R.string.pref_category_library_update)) },
  105. onClick = {
  106. onClickRefresh()
  107. closeMenu()
  108. },
  109. )
  110. DropdownMenuItem(
  111. text = { Text(text = stringResource(R.string.action_open_random_manga)) },
  112. onClick = {
  113. onClickOpenRandomManga()
  114. closeMenu()
  115. },
  116. )
  117. }
  118. },
  119. incognitoMode = incognitoMode,
  120. downloadedOnlyMode = downloadedOnlyMode,
  121. scrollBehavior = scrollBehavior,
  122. )
  123. }
  124. @Composable
  125. fun LibrarySelectionToolbar(
  126. state: LibraryState,
  127. incognitoMode: Boolean,
  128. downloadedOnlyMode: Boolean,
  129. onClickUnselectAll: () -> Unit,
  130. onClickSelectAll: () -> Unit,
  131. onClickInvertSelection: () -> Unit,
  132. ) {
  133. AppBar(
  134. titleContent = { Text(text = "${state.selection.size}") },
  135. actions = {
  136. IconButton(onClick = onClickSelectAll) {
  137. Icon(Icons.Outlined.SelectAll, contentDescription = stringResource(R.string.action_select_all))
  138. }
  139. IconButton(onClick = onClickInvertSelection) {
  140. Icon(Icons.Outlined.FlipToBack, contentDescription = stringResource(R.string.action_select_inverse))
  141. }
  142. },
  143. isActionMode = true,
  144. onCancelActionMode = onClickUnselectAll,
  145. incognitoMode = incognitoMode,
  146. downloadedOnlyMode = downloadedOnlyMode,
  147. )
  148. }
  149. data class LibraryToolbarTitle(
  150. val text: String,
  151. val numberOfManga: Int? = null,
  152. )