MangaSmallAppBar.kt 10 KB

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