LibraryToolbar.kt 5.6 KB

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