From 611ad1599743847b4fa005ec36f3679e9d9790b7 Mon Sep 17 00:00:00 2001 From: James Magahern Date: Sat, 23 Mar 2024 18:27:15 -0700 Subject: [PATCH] AttachmentViewer: Make it zoomable using a library --- app/build.gradle | 17 ++++--- .../ui/attachments/AttachmentViewer.kt | 44 ++++++++++++++----- .../buzzert/kordophonedroid/ui/theme/Theme.kt | 41 ++++++++++------- 3 files changed, 71 insertions(+), 31 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 1e1628d..25de093 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -83,7 +83,14 @@ dependencies { // Jetpack Compose Integration implementation "androidx.navigation:navigation-compose:$nav_version" - implementation 'androidx.activity:activity-compose:1.4.3' + // Jetpack Compose + def compose_version = "1.4.3" + implementation "androidx.compose.ui:ui:$compose_version" + implementation "androidx.compose.material:material:$compose_version" + implementation "androidx.compose.foundation:foundation:$compose_version" + + + implementation "androidx.activity:activity-compose:$compose_version" // Lifecycle def lifecycle_version = "2.6.1" @@ -91,9 +98,6 @@ dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version" - implementation "androidx.compose.ui:ui:1.4.3" - implementation 'androidx.compose.material:material:1.4.3' - implementation "androidx.compose.foundation:foundation:1.4.3" // Hilt (dependency injection) implementation "com.google.dagger:hilt-android:${hilt_version}" @@ -107,7 +111,10 @@ dependencies { // Disk LRU Cache implementation "com.jakewharton:disklrucache:2.0.2" - debugImplementation 'androidx.compose.ui:ui-tooling:1.4.3' + // Zooming in images + implementation "net.engawapg.lib:zoomable:$compose_version" + + debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" } // Allow references to generated code diff --git a/app/src/main/java/net/buzzert/kordophonedroid/ui/attachments/AttachmentViewer.kt b/app/src/main/java/net/buzzert/kordophonedroid/ui/attachments/AttachmentViewer.kt index cc76bf3..5d3f5a7 100644 --- a/app/src/main/java/net/buzzert/kordophonedroid/ui/attachments/AttachmentViewer.kt +++ b/app/src/main/java/net/buzzert/kordophonedroid/ui/attachments/AttachmentViewer.kt @@ -1,9 +1,17 @@ package net.buzzert.kordophonedroid.ui.attachments +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.Scaffold import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.hilt.navigation.compose.hiltViewModel @@ -11,28 +19,44 @@ import coil.compose.AsyncImage import coil.request.ImageRequest import net.buzzert.kordophonedroid.ui.LocalNavController import net.buzzert.kordophonedroid.ui.theme.KordophoneTopAppBar +import net.engawapg.lib.zoomable.rememberZoomState +import net.engawapg.lib.zoomable.zoomable @Composable fun AttachmentViewer( attachmentGuid: String, attachmentViewModel: AttachmentViewModel = hiltViewModel() ) { + var topBarVisible = remember { mutableStateOf(true) } val navController = LocalNavController.current Scaffold(topBar = { KordophoneTopAppBar( title = "Attachment", - backAction = { navController.popBackStack() } + backAction = { navController.popBackStack() }, + visible = topBarVisible.value ) }) { padding -> + val zoomState = rememberZoomState() val data = AttachmentFetchData(attachmentGuid, preview = false) - AsyncImage( - model = ImageRequest.Builder(LocalContext.current) - .data(data) - .crossfade(true) - .build(), - contentDescription = "", - modifier = Modifier - .padding(padding) - ) + Column(modifier = Modifier.padding(padding)) { + Spacer(modifier = Modifier.weight(1f)) + + AsyncImage( + model = ImageRequest.Builder(LocalContext.current) + .data(data) + .crossfade(true) + .build(), + contentDescription = "", + modifier = Modifier + .zoomable(zoomState) + .fillMaxWidth() + .align(Alignment.CenterHorizontally) + .clickable { + topBarVisible.value = !topBarVisible.value + } + ) + + Spacer(modifier = Modifier.weight(1f)) + } } } \ No newline at end of file diff --git a/app/src/main/java/net/buzzert/kordophonedroid/ui/theme/Theme.kt b/app/src/main/java/net/buzzert/kordophonedroid/ui/theme/Theme.kt index 0b08827..58c7daf 100644 --- a/app/src/main/java/net/buzzert/kordophonedroid/ui/theme/Theme.kt +++ b/app/src/main/java/net/buzzert/kordophonedroid/ui/theme/Theme.kt @@ -1,5 +1,8 @@ package net.buzzert.kordophonedroid.ui.theme +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutVertically import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material.Icon import androidx.compose.material.IconButton @@ -55,20 +58,26 @@ fun KordophoneTheme( @Composable -fun KordophoneTopAppBar(title: String, backAction: () -> Unit) { - TopAppBar( - title = { - Text( - text = title, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - }, - navigationIcon = { - IconButton(onClick = backAction) { - Icon(Icons.Filled.ArrowBack, null) - } - }, - actions = {} - ) +fun KordophoneTopAppBar(title: String, backAction: () -> Unit, visible: Boolean = true) { + AnimatedVisibility( + visible = visible, + enter = slideInVertically { -it }, + exit = slideOutVertically { -it }, + ) { + TopAppBar( + title = { + Text( + text = title, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + }, + navigationIcon = { + IconButton(onClick = backAction) { + Icon(Icons.Filled.ArrowBack, null) + } + }, + actions = {} + ) + } } \ No newline at end of file