MangaToolbar.kt 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. package eu.kanade.presentation.manga.components
  2. import androidx.compose.foundation.layout.Box
  3. import androidx.compose.foundation.layout.Column
  4. import androidx.compose.foundation.layout.WindowInsets
  5. import androidx.compose.foundation.layout.statusBars
  6. import androidx.compose.material.icons.Icons
  7. import androidx.compose.material.icons.outlined.ArrowBack
  8. import androidx.compose.material.icons.outlined.Close
  9. import androidx.compose.material.icons.outlined.Download
  10. import androidx.compose.material.icons.outlined.FilterList
  11. import androidx.compose.material.icons.outlined.FlipToBack
  12. import androidx.compose.material.icons.outlined.MoreVert
  13. import androidx.compose.material.icons.outlined.SelectAll
  14. import androidx.compose.material3.DropdownMenuItem
  15. import androidx.compose.material3.Icon
  16. import androidx.compose.material3.IconButton
  17. import androidx.compose.material3.LocalContentColor
  18. import androidx.compose.material3.MaterialTheme
  19. import androidx.compose.material3.Text
  20. import androidx.compose.material3.TopAppBar
  21. import androidx.compose.material3.TopAppBarDefaults
  22. import androidx.compose.material3.surfaceColorAtElevation
  23. import androidx.compose.runtime.Composable
  24. import androidx.compose.runtime.mutableStateOf
  25. import androidx.compose.runtime.remember
  26. import androidx.compose.ui.Modifier
  27. import androidx.compose.ui.draw.alpha
  28. import androidx.compose.ui.res.stringResource
  29. import androidx.compose.ui.text.style.TextOverflow
  30. import androidx.compose.ui.unit.dp
  31. import eu.kanade.presentation.components.AppStateBanners
  32. import eu.kanade.presentation.components.DropdownMenu
  33. import eu.kanade.presentation.manga.DownloadAction
  34. import eu.kanade.presentation.theme.active
  35. import eu.kanade.tachiyomi.R
  36. @Composable
  37. fun MangaToolbar(
  38. modifier: Modifier = Modifier,
  39. title: String,
  40. titleAlphaProvider: () -> Float,
  41. backgroundAlphaProvider: () -> Float = titleAlphaProvider,
  42. hasFilters: Boolean,
  43. incognitoMode: Boolean,
  44. downloadedOnlyMode: Boolean,
  45. onBackClicked: () -> Unit,
  46. onClickFilter: () -> Unit,
  47. onClickShare: (() -> Unit)?,
  48. onClickDownload: ((DownloadAction) -> Unit)?,
  49. onClickEditCategory: (() -> Unit)?,
  50. onClickMigrate: (() -> Unit)?,
  51. // For action mode
  52. actionModeCounter: Int,
  53. onSelectAll: () -> Unit,
  54. onInvertSelection: () -> Unit,
  55. ) {
  56. Column(
  57. modifier = modifier,
  58. ) {
  59. val isActionMode = actionModeCounter > 0
  60. TopAppBar(
  61. title = {
  62. Text(
  63. text = if (isActionMode) actionModeCounter.toString() else title,
  64. maxLines = 1,
  65. overflow = TextOverflow.Ellipsis,
  66. modifier = Modifier.alpha(if (isActionMode) 1f else titleAlphaProvider()),
  67. )
  68. },
  69. navigationIcon = {
  70. IconButton(onClick = onBackClicked) {
  71. Icon(
  72. imageVector = if (isActionMode) Icons.Outlined.Close else Icons.Outlined.ArrowBack,
  73. contentDescription = stringResource(R.string.abc_action_bar_up_description),
  74. )
  75. }
  76. },
  77. actions = {
  78. if (isActionMode) {
  79. IconButton(onClick = onSelectAll) {
  80. Icon(
  81. imageVector = Icons.Outlined.SelectAll,
  82. contentDescription = stringResource(R.string.action_select_all),
  83. )
  84. }
  85. IconButton(onClick = onInvertSelection) {
  86. Icon(
  87. imageVector = Icons.Outlined.FlipToBack,
  88. contentDescription = stringResource(R.string.action_select_inverse),
  89. )
  90. }
  91. } else {
  92. if (onClickDownload != null) {
  93. val (downloadExpanded, onDownloadExpanded) = remember { mutableStateOf(false) }
  94. Box {
  95. IconButton(onClick = { onDownloadExpanded(!downloadExpanded) }) {
  96. Icon(
  97. imageVector = Icons.Outlined.Download,
  98. contentDescription = stringResource(R.string.manga_download),
  99. )
  100. }
  101. val onDismissRequest = { onDownloadExpanded(false) }
  102. DropdownMenu(
  103. expanded = downloadExpanded,
  104. onDismissRequest = onDismissRequest,
  105. ) {
  106. DropdownMenuItem(
  107. text = { Text(text = stringResource(R.string.download_1)) },
  108. onClick = {
  109. onClickDownload(DownloadAction.NEXT_1_CHAPTER)
  110. onDismissRequest()
  111. },
  112. )
  113. DropdownMenuItem(
  114. text = { Text(text = stringResource(R.string.download_5)) },
  115. onClick = {
  116. onClickDownload(DownloadAction.NEXT_5_CHAPTERS)
  117. onDismissRequest()
  118. },
  119. )
  120. DropdownMenuItem(
  121. text = { Text(text = stringResource(R.string.download_10)) },
  122. onClick = {
  123. onClickDownload(DownloadAction.NEXT_10_CHAPTERS)
  124. onDismissRequest()
  125. },
  126. )
  127. DropdownMenuItem(
  128. text = { Text(text = stringResource(R.string.download_custom)) },
  129. onClick = {
  130. onClickDownload(DownloadAction.CUSTOM)
  131. onDismissRequest()
  132. },
  133. )
  134. DropdownMenuItem(
  135. text = { Text(text = stringResource(R.string.download_unread)) },
  136. onClick = {
  137. onClickDownload(DownloadAction.UNREAD_CHAPTERS)
  138. onDismissRequest()
  139. },
  140. )
  141. DropdownMenuItem(
  142. text = { Text(text = stringResource(R.string.download_all)) },
  143. onClick = {
  144. onClickDownload(DownloadAction.ALL_CHAPTERS)
  145. onDismissRequest()
  146. },
  147. )
  148. }
  149. }
  150. }
  151. val filterTint = if (hasFilters) MaterialTheme.colorScheme.active else LocalContentColor.current
  152. IconButton(onClick = onClickFilter) {
  153. Icon(Icons.Outlined.FilterList, contentDescription = stringResource(R.string.action_filter), tint = filterTint)
  154. }
  155. if (onClickEditCategory != null && onClickMigrate != null) {
  156. val (moreExpanded, onMoreExpanded) = remember { mutableStateOf(false) }
  157. Box {
  158. IconButton(onClick = { onMoreExpanded(!moreExpanded) }) {
  159. Icon(
  160. imageVector = Icons.Outlined.MoreVert,
  161. contentDescription = stringResource(R.string.abc_action_menu_overflow_description),
  162. )
  163. }
  164. val onDismissRequest = { onMoreExpanded(false) }
  165. DropdownMenu(
  166. expanded = moreExpanded,
  167. onDismissRequest = onDismissRequest,
  168. ) {
  169. DropdownMenuItem(
  170. text = { Text(text = stringResource(R.string.action_edit_categories)) },
  171. onClick = {
  172. onClickEditCategory()
  173. onDismissRequest()
  174. },
  175. )
  176. DropdownMenuItem(
  177. text = { Text(text = stringResource(R.string.action_migrate)) },
  178. onClick = {
  179. onClickMigrate()
  180. onDismissRequest()
  181. },
  182. )
  183. if (onClickShare != null) {
  184. DropdownMenuItem(
  185. text = { Text(text = stringResource(R.string.action_share)) },
  186. onClick = {
  187. onClickShare()
  188. onDismissRequest()
  189. },
  190. )
  191. }
  192. }
  193. }
  194. }
  195. }
  196. },
  197. windowInsets = WindowInsets.statusBars,
  198. colors = TopAppBarDefaults.smallTopAppBarColors(
  199. containerColor = MaterialTheme.colorScheme
  200. .surfaceColorAtElevation(3.dp)
  201. .copy(alpha = if (isActionMode) 1f else backgroundAlphaProvider()),
  202. ),
  203. )
  204. AppStateBanners(downloadedOnlyMode, incognitoMode)
  205. }
  206. }