| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 | 
							- package eu.kanade.presentation.manga.components
 
- import androidx.compose.animation.AnimatedVisibility
 
- import androidx.compose.animation.core.animateFloatAsState
 
- import androidx.compose.animation.core.tween
 
- import androidx.compose.animation.expandVertically
 
- import androidx.compose.animation.fadeIn
 
- import androidx.compose.animation.fadeOut
 
- import androidx.compose.animation.shrinkVertically
 
- import androidx.compose.foundation.combinedClickable
 
- import androidx.compose.foundation.interaction.MutableInteractionSource
 
- import androidx.compose.foundation.layout.Arrangement
 
- import androidx.compose.foundation.layout.Column
 
- import androidx.compose.foundation.layout.Row
 
- import androidx.compose.foundation.layout.RowScope
 
- import androidx.compose.foundation.layout.WindowInsets
 
- import androidx.compose.foundation.layout.WindowInsetsSides
 
- import androidx.compose.foundation.layout.asPaddingValues
 
- import androidx.compose.foundation.layout.navigationBars
 
- import androidx.compose.foundation.layout.only
 
- import androidx.compose.foundation.layout.padding
 
- import androidx.compose.foundation.layout.size
 
- import androidx.compose.foundation.layout.windowInsetsPadding
 
- import androidx.compose.foundation.shape.ZeroCornerSize
 
- import androidx.compose.material.icons.Icons
 
- import androidx.compose.material.icons.automirrored.outlined.Label
 
- import androidx.compose.material.icons.outlined.BookmarkAdd
 
- import androidx.compose.material.icons.outlined.BookmarkRemove
 
- import androidx.compose.material.icons.outlined.Delete
 
- import androidx.compose.material.icons.outlined.DoneAll
 
- import androidx.compose.material.icons.outlined.Download
 
- import androidx.compose.material.icons.outlined.Label
 
- import androidx.compose.material.icons.outlined.RemoveDone
 
- import androidx.compose.material.ripple.rememberRipple
 
- import androidx.compose.material3.Icon
 
- import androidx.compose.material3.MaterialTheme
 
- import androidx.compose.material3.Surface
 
- import androidx.compose.material3.Text
 
- import androidx.compose.runtime.Composable
 
- import androidx.compose.runtime.getValue
 
- import androidx.compose.runtime.mutableStateListOf
 
- import androidx.compose.runtime.mutableStateOf
 
- import androidx.compose.runtime.remember
 
- import androidx.compose.runtime.rememberCoroutineScope
 
- import androidx.compose.runtime.setValue
 
- import androidx.compose.ui.Alignment
 
- import androidx.compose.ui.Modifier
 
- import androidx.compose.ui.graphics.vector.ImageVector
 
- import androidx.compose.ui.hapticfeedback.HapticFeedbackType
 
- import androidx.compose.ui.platform.LocalHapticFeedback
 
- import androidx.compose.ui.res.vectorResource
 
- import androidx.compose.ui.text.style.TextOverflow
 
- import androidx.compose.ui.unit.dp
 
- import eu.kanade.presentation.components.DownloadDropdownMenu
 
- import eu.kanade.presentation.manga.DownloadAction
 
- import eu.kanade.tachiyomi.R
 
- import kotlinx.coroutines.Job
 
- import kotlinx.coroutines.delay
 
- import kotlinx.coroutines.isActive
 
- import kotlinx.coroutines.launch
 
- import tachiyomi.i18n.MR
 
- import tachiyomi.presentation.core.i18n.localize
 
- import kotlin.time.Duration.Companion.seconds
 
- @Composable
 
- fun MangaBottomActionMenu(
 
-     visible: Boolean,
 
-     modifier: Modifier = Modifier,
 
-     onBookmarkClicked: (() -> Unit)? = null,
 
-     onRemoveBookmarkClicked: (() -> Unit)? = null,
 
-     onMarkAsReadClicked: (() -> Unit)? = null,
 
-     onMarkAsUnreadClicked: (() -> Unit)? = null,
 
-     onMarkPreviousAsReadClicked: (() -> Unit)? = null,
 
-     onDownloadClicked: (() -> Unit)? = null,
 
-     onDeleteClicked: (() -> Unit)? = null,
 
- ) {
 
-     AnimatedVisibility(
 
-         visible = visible,
 
-         enter = expandVertically(expandFrom = Alignment.Bottom),
 
-         exit = shrinkVertically(shrinkTowards = Alignment.Bottom),
 
-     ) {
 
-         val scope = rememberCoroutineScope()
 
-         Surface(
 
-             modifier = modifier,
 
-             shape = MaterialTheme.shapes.large.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),
 
-             tonalElevation = 3.dp,
 
-         ) {
 
-             val haptic = LocalHapticFeedback.current
 
-             val confirm = remember { mutableStateListOf(false, false, false, false, false, false, false) }
 
-             var resetJob: Job? = remember { null }
 
-             val onLongClickItem: (Int) -> Unit = { toConfirmIndex ->
 
-                 haptic.performHapticFeedback(HapticFeedbackType.LongPress)
 
-                 (0..<7).forEach { i -> confirm[i] = i == toConfirmIndex }
 
-                 resetJob?.cancel()
 
-                 resetJob = scope.launch {
 
-                     delay(1.seconds)
 
-                     if (isActive) confirm[toConfirmIndex] = false
 
-                 }
 
-             }
 
-             Row(
 
-                 modifier = Modifier
 
-                     .padding(
 
-                         WindowInsets.navigationBars
 
-                             .only(WindowInsetsSides.Bottom)
 
-                             .asPaddingValues(),
 
-                     )
 
-                     .padding(horizontal = 8.dp, vertical = 12.dp),
 
-             ) {
 
-                 if (onBookmarkClicked != null) {
 
-                     Button(
 
-                         title = localize(MR.strings.action_bookmark),
 
-                         icon = Icons.Outlined.BookmarkAdd,
 
-                         toConfirm = confirm[0],
 
-                         onLongClick = { onLongClickItem(0) },
 
-                         onClick = onBookmarkClicked,
 
-                     )
 
-                 }
 
-                 if (onRemoveBookmarkClicked != null) {
 
-                     Button(
 
-                         title = localize(MR.strings.action_remove_bookmark),
 
-                         icon = Icons.Outlined.BookmarkRemove,
 
-                         toConfirm = confirm[1],
 
-                         onLongClick = { onLongClickItem(1) },
 
-                         onClick = onRemoveBookmarkClicked,
 
-                     )
 
-                 }
 
-                 if (onMarkAsReadClicked != null) {
 
-                     Button(
 
-                         title = localize(MR.strings.action_mark_as_read),
 
-                         icon = Icons.Outlined.DoneAll,
 
-                         toConfirm = confirm[2],
 
-                         onLongClick = { onLongClickItem(2) },
 
-                         onClick = onMarkAsReadClicked,
 
-                     )
 
-                 }
 
-                 if (onMarkAsUnreadClicked != null) {
 
-                     Button(
 
-                         title = localize(MR.strings.action_mark_as_unread),
 
-                         icon = Icons.Outlined.RemoveDone,
 
-                         toConfirm = confirm[3],
 
-                         onLongClick = { onLongClickItem(3) },
 
-                         onClick = onMarkAsUnreadClicked,
 
-                     )
 
-                 }
 
-                 if (onMarkPreviousAsReadClicked != null) {
 
-                     Button(
 
-                         title = localize(MR.strings.action_mark_previous_as_read),
 
-                         icon = ImageVector.vectorResource(R.drawable.ic_done_prev_24dp),
 
-                         toConfirm = confirm[4],
 
-                         onLongClick = { onLongClickItem(4) },
 
-                         onClick = onMarkPreviousAsReadClicked,
 
-                     )
 
-                 }
 
-                 if (onDownloadClicked != null) {
 
-                     Button(
 
-                         title = localize(MR.strings.action_download),
 
-                         icon = Icons.Outlined.Download,
 
-                         toConfirm = confirm[5],
 
-                         onLongClick = { onLongClickItem(5) },
 
-                         onClick = onDownloadClicked,
 
-                     )
 
-                 }
 
-                 if (onDeleteClicked != null) {
 
-                     Button(
 
-                         title = localize(MR.strings.action_delete),
 
-                         icon = Icons.Outlined.Delete,
 
-                         toConfirm = confirm[6],
 
-                         onLongClick = { onLongClickItem(6) },
 
-                         onClick = onDeleteClicked,
 
-                     )
 
-                 }
 
-             }
 
-         }
 
-     }
 
- }
 
- @Composable
 
- private fun RowScope.Button(
 
-     title: String,
 
-     icon: ImageVector,
 
-     toConfirm: Boolean,
 
-     onLongClick: () -> Unit,
 
-     onClick: () -> Unit,
 
-     content: (@Composable () -> Unit)? = null,
 
- ) {
 
-     val animatedWeight by animateFloatAsState(if (toConfirm) 2f else 1f)
 
-     Column(
 
-         modifier = Modifier
 
-             .size(48.dp)
 
-             .weight(animatedWeight)
 
-             .combinedClickable(
 
-                 interactionSource = remember { MutableInteractionSource() },
 
-                 indication = rememberRipple(bounded = false),
 
-                 onLongClick = onLongClick,
 
-                 onClick = onClick,
 
-             ),
 
-         verticalArrangement = Arrangement.Center,
 
-         horizontalAlignment = Alignment.CenterHorizontally,
 
-     ) {
 
-         Icon(
 
-             imageVector = icon,
 
-             contentDescription = title,
 
-         )
 
-         AnimatedVisibility(
 
-             visible = toConfirm,
 
-             enter = expandVertically(expandFrom = Alignment.Top) + fadeIn(),
 
-             exit = shrinkVertically(shrinkTowards = Alignment.Top) + fadeOut(),
 
-         ) {
 
-             Text(
 
-                 text = title,
 
-                 overflow = TextOverflow.Visible,
 
-                 maxLines = 1,
 
-                 style = MaterialTheme.typography.labelSmall,
 
-             )
 
-         }
 
-         content?.invoke()
 
-     }
 
- }
 
- @Composable
 
- fun LibraryBottomActionMenu(
 
-     visible: Boolean,
 
-     modifier: Modifier = Modifier,
 
-     onChangeCategoryClicked: () -> Unit,
 
-     onMarkAsReadClicked: () -> Unit,
 
-     onMarkAsUnreadClicked: () -> Unit,
 
-     onDownloadClicked: ((DownloadAction) -> Unit)?,
 
-     onDeleteClicked: () -> Unit,
 
- ) {
 
-     AnimatedVisibility(
 
-         visible = visible,
 
-         enter = expandVertically(animationSpec = tween(delayMillis = 300)),
 
-         exit = shrinkVertically(animationSpec = tween()),
 
-     ) {
 
-         val scope = rememberCoroutineScope()
 
-         Surface(
 
-             modifier = modifier,
 
-             shape = MaterialTheme.shapes.large.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),
 
-             tonalElevation = 3.dp,
 
-         ) {
 
-             val haptic = LocalHapticFeedback.current
 
-             val confirm = remember { mutableStateListOf(false, false, false, false, false) }
 
-             var resetJob: Job? = remember { null }
 
-             val onLongClickItem: (Int) -> Unit = { toConfirmIndex ->
 
-                 haptic.performHapticFeedback(HapticFeedbackType.LongPress)
 
-                 (0..<5).forEach { i -> confirm[i] = i == toConfirmIndex }
 
-                 resetJob?.cancel()
 
-                 resetJob = scope.launch {
 
-                     delay(1.seconds)
 
-                     if (isActive) confirm[toConfirmIndex] = false
 
-                 }
 
-             }
 
-             Row(
 
-                 modifier = Modifier
 
-                     .windowInsetsPadding(
 
-                         WindowInsets.navigationBars
 
-                             .only(WindowInsetsSides.Bottom),
 
-                     )
 
-                     .padding(horizontal = 8.dp, vertical = 12.dp),
 
-             ) {
 
-                 Button(
 
-                     title = localize(MR.strings.action_move_category),
 
-                     icon = Icons.AutoMirrored.Outlined.Label,
 
-                     toConfirm = confirm[0],
 
-                     onLongClick = { onLongClickItem(0) },
 
-                     onClick = onChangeCategoryClicked,
 
-                 )
 
-                 Button(
 
-                     title = localize(MR.strings.action_mark_as_read),
 
-                     icon = Icons.Outlined.DoneAll,
 
-                     toConfirm = confirm[1],
 
-                     onLongClick = { onLongClickItem(1) },
 
-                     onClick = onMarkAsReadClicked,
 
-                 )
 
-                 Button(
 
-                     title = localize(MR.strings.action_mark_as_unread),
 
-                     icon = Icons.Outlined.RemoveDone,
 
-                     toConfirm = confirm[2],
 
-                     onLongClick = { onLongClickItem(2) },
 
-                     onClick = onMarkAsUnreadClicked,
 
-                 )
 
-                 if (onDownloadClicked != null) {
 
-                     var downloadExpanded by remember { mutableStateOf(false) }
 
-                     Button(
 
-                         title = localize(MR.strings.action_download),
 
-                         icon = Icons.Outlined.Download,
 
-                         toConfirm = confirm[3],
 
-                         onLongClick = { onLongClickItem(3) },
 
-                         onClick = { downloadExpanded = !downloadExpanded },
 
-                     ) {
 
-                         val onDismissRequest = { downloadExpanded = false }
 
-                         DownloadDropdownMenu(
 
-                             expanded = downloadExpanded,
 
-                             onDismissRequest = onDismissRequest,
 
-                             onDownloadClicked = onDownloadClicked,
 
-                         )
 
-                     }
 
-                 }
 
-                 Button(
 
-                     title = localize(MR.strings.action_delete),
 
-                     icon = Icons.Outlined.Delete,
 
-                     toConfirm = confirm[4],
 
-                     onLongClick = { onLongClickItem(4) },
 
-                     onClick = onDeleteClicked,
 
-                 )
 
-             }
 
-         }
 
-     }
 
- }
 
 
  |