LibraryToolbar.kt 6.2 KB

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