MangaAppBar.kt 9.6 KB

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