123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- package eu.kanade.presentation.manga.components
- import android.graphics.Bitmap
- import android.graphics.drawable.BitmapDrawable
- import android.os.Build
- import androidx.compose.foundation.background
- import androidx.compose.foundation.layout.Box
- import androidx.compose.foundation.layout.Row
- import androidx.compose.foundation.layout.Spacer
- import androidx.compose.foundation.layout.fillMaxSize
- import androidx.compose.foundation.layout.fillMaxWidth
- import androidx.compose.foundation.layout.navigationBarsPadding
- import androidx.compose.foundation.layout.padding
- import androidx.compose.material.icons.Icons
- import androidx.compose.material.icons.outlined.Close
- import androidx.compose.material.icons.outlined.Edit
- import androidx.compose.material.icons.outlined.Save
- import androidx.compose.material.icons.outlined.Share
- import androidx.compose.material3.DropdownMenuItem
- import androidx.compose.material3.Icon
- import androidx.compose.material3.IconButton
- import androidx.compose.material3.MaterialTheme
- import androidx.compose.material3.SnackbarHost
- import androidx.compose.material3.SnackbarHostState
- import androidx.compose.material3.Text
- import androidx.compose.runtime.Composable
- import androidx.compose.runtime.getValue
- import androidx.compose.runtime.mutableStateOf
- import androidx.compose.runtime.remember
- import androidx.compose.runtime.setValue
- import androidx.compose.ui.Modifier
- import androidx.compose.ui.draw.clip
- import androidx.compose.ui.graphics.Color
- import androidx.compose.ui.platform.LocalDensity
- import androidx.compose.ui.unit.DpOffset
- import androidx.compose.ui.unit.dp
- import androidx.compose.ui.viewinterop.AndroidView
- import androidx.compose.ui.window.Dialog
- import androidx.compose.ui.window.DialogProperties
- import androidx.core.view.updatePadding
- import coil.imageLoader
- import coil.request.CachePolicy
- import coil.request.ImageRequest
- import coil.size.Size
- import eu.kanade.presentation.components.AppBar
- import eu.kanade.presentation.components.AppBarActions
- import eu.kanade.presentation.components.DropdownMenu
- import eu.kanade.presentation.manga.EditCoverAction
- import eu.kanade.tachiyomi.ui.reader.viewer.ReaderPageImageView
- import kotlinx.collections.immutable.persistentListOf
- import tachiyomi.domain.manga.model.Manga
- import tachiyomi.i18n.MR
- import tachiyomi.presentation.core.components.material.Scaffold
- import tachiyomi.presentation.core.i18n.localize
- import tachiyomi.presentation.core.util.clickableNoIndication
- @Composable
- fun MangaCoverDialog(
- coverDataProvider: () -> Manga,
- isCustomCover: Boolean,
- snackbarHostState: SnackbarHostState,
- onShareClick: () -> Unit,
- onSaveClick: () -> Unit,
- onEditClick: ((EditCoverAction) -> Unit)?,
- onDismissRequest: () -> Unit,
- ) {
- Dialog(
- onDismissRequest = onDismissRequest,
- properties = DialogProperties(
- usePlatformDefaultWidth = false,
- decorFitsSystemWindows = false, // Doesn't work https://issuetracker.google.com/issues/246909281
- ),
- ) {
- Scaffold(
- snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
- containerColor = Color.Transparent,
- bottomBar = {
- Row(
- modifier = Modifier
- .fillMaxWidth()
- .padding(4.dp)
- .navigationBarsPadding(),
- ) {
- ActionsPill {
- IconButton(onClick = onDismissRequest) {
- Icon(
- imageVector = Icons.Outlined.Close,
- contentDescription = localize(MR.strings.action_close),
- )
- }
- }
- Spacer(modifier = Modifier.weight(1f))
- ActionsPill {
- AppBarActions(
- actions = persistentListOf(
- AppBar.Action(
- title = localize(MR.strings.action_share),
- icon = Icons.Outlined.Share,
- onClick = onShareClick,
- ),
- AppBar.Action(
- title = localize(MR.strings.action_save),
- icon = Icons.Outlined.Save,
- onClick = onSaveClick,
- ),
- ),
- )
- if (onEditClick != null) {
- Box {
- var expanded by remember { mutableStateOf(false) }
- IconButton(
- onClick = {
- if (isCustomCover) {
- expanded = true
- } else {
- onEditClick(EditCoverAction.EDIT)
- }
- },
- ) {
- Icon(
- imageVector = Icons.Outlined.Edit,
- contentDescription = localize(MR.strings.action_edit_cover),
- )
- }
- DropdownMenu(
- expanded = expanded,
- onDismissRequest = { expanded = false },
- offset = DpOffset(8.dp, 0.dp),
- ) {
- DropdownMenuItem(
- text = { Text(text = localize(MR.strings.action_edit)) },
- onClick = {
- onEditClick(EditCoverAction.EDIT)
- expanded = false
- },
- )
- DropdownMenuItem(
- text = { Text(text = localize(MR.strings.action_delete)) },
- onClick = {
- onEditClick(EditCoverAction.DELETE)
- expanded = false
- },
- )
- }
- }
- }
- }
- }
- },
- ) { contentPadding ->
- val statusBarPaddingPx = with(LocalDensity.current) { contentPadding.calculateTopPadding().roundToPx() }
- val bottomPaddingPx = with(LocalDensity.current) { contentPadding.calculateBottomPadding().roundToPx() }
- Box(
- modifier = Modifier
- .fillMaxSize()
- .clickableNoIndication(onClick = onDismissRequest),
- ) {
- AndroidView(
- factory = {
- ReaderPageImageView(it).apply {
- onViewClicked = onDismissRequest
- clipToPadding = false
- clipChildren = false
- }
- },
- update = { view ->
- val request = ImageRequest.Builder(view.context)
- .data(coverDataProvider())
- .size(Size.ORIGINAL)
- .memoryCachePolicy(CachePolicy.DISABLED)
- .target { drawable ->
- // Copy bitmap in case it came from memory cache
- // Because SSIV needs to thoroughly read the image
- val copy = (drawable as? BitmapDrawable)?.let {
- val config = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- Bitmap.Config.HARDWARE
- } else {
- Bitmap.Config.ARGB_8888
- }
- BitmapDrawable(
- view.context.resources,
- it.bitmap.copy(config, false),
- )
- } ?: drawable
- view.setImage(copy, ReaderPageImageView.Config(zoomDuration = 500))
- }
- .build()
- view.context.imageLoader.enqueue(request)
- view.updatePadding(top = statusBarPaddingPx, bottom = bottomPaddingPx)
- },
- modifier = Modifier.fillMaxSize(),
- )
- }
- }
- }
- }
- @Composable
- private fun ActionsPill(content: @Composable () -> Unit) {
- Row(
- modifier = Modifier
- .clip(MaterialTheme.shapes.extraLarge)
- .background(MaterialTheme.colorScheme.background.copy(alpha = 0.95f)),
- ) {
- content()
- }
- }
|