Pdf: improve rendering with zoom and spaces between pages
This commit is contained in:
parent
dfacb42d76
commit
e754d17c13
1 changed files with 33 additions and 17 deletions
|
|
@ -21,6 +21,7 @@ import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
|
@ -48,10 +49,10 @@ import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.LocalInspectionMode
|
import androidx.compose.ui.platform.LocalInspectionMode
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
import androidx.media3.common.MimeTypes
|
|
||||||
import androidx.media3.common.Player
|
import androidx.media3.common.Player
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.ui.AspectRatioFrameLayout
|
import androidx.media3.ui.AspectRatioFrameLayout
|
||||||
|
|
@ -60,14 +61,19 @@ import io.element.android.features.messages.impl.media.local.exoplayer.ExoPlayer
|
||||||
import io.element.android.features.messages.impl.media.local.pdf.ParcelFileDescriptorFactory
|
import io.element.android.features.messages.impl.media.local.pdf.ParcelFileDescriptorFactory
|
||||||
import io.element.android.features.messages.impl.media.local.pdf.PdfPage
|
import io.element.android.features.messages.impl.media.local.pdf.PdfPage
|
||||||
import io.element.android.features.messages.impl.media.local.pdf.PdfRendererManager
|
import io.element.android.features.messages.impl.media.local.pdf.PdfRendererManager
|
||||||
|
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||||
|
import io.element.android.libraries.core.mimetype.MimeTypes.isMimeTypeImage
|
||||||
|
import io.element.android.libraries.core.mimetype.MimeTypes.isMimeTypeVideo
|
||||||
import io.element.android.libraries.designsystem.R
|
import io.element.android.libraries.designsystem.R
|
||||||
import io.element.android.libraries.designsystem.utils.OnLifecycleEvent
|
import io.element.android.libraries.designsystem.utils.OnLifecycleEvent
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import me.saket.telephoto.zoomable.ZoomSpec
|
import me.saket.telephoto.zoomable.ZoomSpec
|
||||||
|
import me.saket.telephoto.zoomable.ZoomableState
|
||||||
import me.saket.telephoto.zoomable.coil.ZoomableAsyncImage
|
import me.saket.telephoto.zoomable.coil.ZoomableAsyncImage
|
||||||
import me.saket.telephoto.zoomable.rememberZoomableImageState
|
import me.saket.telephoto.zoomable.rememberZoomableImageState
|
||||||
import me.saket.telephoto.zoomable.rememberZoomableState
|
import me.saket.telephoto.zoomable.rememberZoomableState
|
||||||
|
import me.saket.telephoto.zoomable.zoomable
|
||||||
|
|
||||||
@SuppressLint("UnsafeOptInUsageError")
|
@SuppressLint("UnsafeOptInUsageError")
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -77,19 +83,28 @@ fun LocalMediaView(
|
||||||
mimeType: String? = localMedia?.mimeType,
|
mimeType: String? = localMedia?.mimeType,
|
||||||
onReady: () -> Unit = {},
|
onReady: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
|
val zoomableState = rememberZoomableState(
|
||||||
|
zoomSpec = ZoomSpec(maxZoomFactor = 3f)
|
||||||
|
)
|
||||||
when {
|
when {
|
||||||
MimeTypes.isImage(mimeType) -> MediaImageView(
|
mimeType.isMimeTypeImage() -> MediaImageView(
|
||||||
|
localMedia = localMedia,
|
||||||
|
zoomableState = zoomableState,
|
||||||
|
onReady = onReady,
|
||||||
|
modifier = modifier
|
||||||
|
)
|
||||||
|
mimeType.isMimeTypeVideo() -> MediaVideoView(
|
||||||
localMedia = localMedia,
|
localMedia = localMedia,
|
||||||
onReady = onReady,
|
onReady = onReady,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
)
|
)
|
||||||
MimeTypes.isVideo(mimeType) -> MediaVideoView(
|
mimeType == MimeTypes.Pdf -> {
|
||||||
localMedia = localMedia,
|
MediaPDFView(
|
||||||
onReady = onReady,
|
localMedia = localMedia,
|
||||||
modifier = modifier
|
zoomableState = zoomableState,
|
||||||
)
|
onReady = onReady,
|
||||||
mimeType == io.element.android.libraries.core.mimetype.MimeTypes.Pdf -> {
|
modifier = modifier
|
||||||
MediaPDFView(localMedia = localMedia, onReady = onReady, modifier = modifier)
|
)
|
||||||
}
|
}
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
@ -98,6 +113,7 @@ fun LocalMediaView(
|
||||||
@Composable
|
@Composable
|
||||||
private fun MediaImageView(
|
private fun MediaImageView(
|
||||||
localMedia: LocalMedia?,
|
localMedia: LocalMedia?,
|
||||||
|
zoomableState: ZoomableState,
|
||||||
onReady: () -> Unit,
|
onReady: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
|
@ -108,9 +124,6 @@ private fun MediaImageView(
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val zoomableState = rememberZoomableState(
|
|
||||||
zoomSpec = ZoomSpec(maxZoomFactor = 3f)
|
|
||||||
)
|
|
||||||
val zoomableImageState = rememberZoomableImageState(zoomableState)
|
val zoomableImageState = rememberZoomableImageState(zoomableState)
|
||||||
LaunchedEffect(zoomableImageState.isImageDisplayed) {
|
LaunchedEffect(zoomableImageState.isImageDisplayed) {
|
||||||
if (zoomableImageState.isImageDisplayed) {
|
if (zoomableImageState.isImageDisplayed) {
|
||||||
|
|
@ -186,15 +199,16 @@ fun MediaVideoView(
|
||||||
@Composable
|
@Composable
|
||||||
fun MediaPDFView(
|
fun MediaPDFView(
|
||||||
localMedia: LocalMedia?,
|
localMedia: LocalMedia?,
|
||||||
|
zoomableState: ZoomableState,
|
||||||
onReady: () -> Unit,
|
onReady: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
BoxWithConstraints(
|
BoxWithConstraints(
|
||||||
modifier = modifier,
|
modifier = modifier.zoomable(zoomableState),
|
||||||
contentAlignment = Alignment.TopCenter
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
val maxWidth = this.maxWidth.dpToPx()
|
val maxWidth = this.maxWidth.dpToPx()
|
||||||
val lazyState = rememberLazyListState()
|
val lazyListState = rememberLazyListState()
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
var pdfRendererManager by remember {
|
var pdfRendererManager by remember {
|
||||||
|
|
@ -214,7 +228,7 @@ fun MediaPDFView(
|
||||||
}
|
}
|
||||||
pdfRendererManager?.run {
|
pdfRendererManager?.run {
|
||||||
val pdfPages = pdfPages.collectAsState().value
|
val pdfPages = pdfPages.collectAsState().value
|
||||||
PdfPagesView(pdfPages.toImmutableList(), lazyState)
|
PdfPagesView(pdfPages.toImmutableList(), lazyListState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -227,7 +241,9 @@ private fun PdfPagesView(
|
||||||
) {
|
) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = modifier.fillMaxSize(),
|
modifier = modifier.fillMaxSize(),
|
||||||
state = lazyListState
|
state = lazyListState,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterVertically)
|
||||||
|
|
||||||
) {
|
) {
|
||||||
items(pdfPages.size) { index ->
|
items(pdfPages.size) { index ->
|
||||||
val pdfPage = pdfPages[index]
|
val pdfPage = pdfPages[index]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue