From ee99da7907aff9c48d94a02863ead7f12ede8498 Mon Sep 17 00:00:00 2001 From: machiav3lli Date: Thu, 23 Jun 2022 02:28:31 +0200 Subject: [PATCH] Add: Snackbar with action on release's long click --- .../app_detail/components/ReleaseItem.kt | 16 +++-- .../looker/droidify/ui/fragments/AppSheetX.kt | 60 ++++++++++++++----- src/main/res/values/strings.xml | 1 + 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/main/kotlin/com/looker/droidify/ui/compose/pages/app_detail/components/ReleaseItem.kt b/src/main/kotlin/com/looker/droidify/ui/compose/pages/app_detail/components/ReleaseItem.kt index 161ca0d1..918ed287 100644 --- a/src/main/kotlin/com/looker/droidify/ui/compose/pages/app_detail/components/ReleaseItem.kt +++ b/src/main/kotlin/com/looker/droidify/ui/compose/pages/app_detail/components/ReleaseItem.kt @@ -5,7 +5,9 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background +import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -55,7 +57,8 @@ fun ReleaseItem( release: Release, repository: Repository, releaseState: Int = RELEASE_STATE_NONE, - onDownloadClick: (Release) -> Unit = {} + onDownloadClick: (Release) -> Unit = {}, + onLongClick: (Release) -> Unit = {}, ) { val currentRelease by remember { mutableStateOf(release) } val isInstalled = releaseState == RELEASE_STATE_INSTALLED @@ -74,11 +77,13 @@ fun ReleaseItem( repository = repository, isSuggested = isSuggested, isInstalled = isInstalled, - onDownloadClick = onDownloadClick + onDownloadClick = onDownloadClick, + onLongClick = onLongClick ) } } +@OptIn(ExperimentalFoundationApi::class) @Composable fun ReleaseItemContent( modifier: Modifier = Modifier, @@ -86,10 +91,13 @@ fun ReleaseItemContent( repository: Repository, isSuggested: Boolean = false, isInstalled: Boolean = false, - onDownloadClick: (Release) -> Unit = {} + onDownloadClick: (Release) -> Unit = {}, + onLongClick: (Release) -> Unit = {} ) { Row( - modifier = Modifier.padding(end = 16.dp), + modifier = Modifier + .combinedClickable(onClick = {}, onLongClick = { onLongClick(release) }) + .padding(end = 16.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start ) { diff --git a/src/main/kotlin/com/looker/droidify/ui/fragments/AppSheetX.kt b/src/main/kotlin/com/looker/droidify/ui/fragments/AppSheetX.kt index 6cb458fa..7ed06132 100644 --- a/src/main/kotlin/com/looker/droidify/ui/fragments/AppSheetX.kt +++ b/src/main/kotlin/com/looker/droidify/ui/fragments/AppSheetX.kt @@ -22,12 +22,16 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.SnackbarResult import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.res.stringResource @@ -35,7 +39,6 @@ import androidx.compose.ui.unit.dp import androidx.core.net.toUri import androidx.fragment.app.viewModels import androidx.lifecycle.lifecycleScope -import com.google.android.material.snackbar.Snackbar import com.looker.droidify.R import com.looker.droidify.RELEASE_STATE_INSTALLED import com.looker.droidify.RELEASE_STATE_NONE @@ -77,6 +80,7 @@ import com.looker.droidify.utility.generateLinks import com.looker.droidify.utility.generatePermissionGroups import com.looker.droidify.utility.isDarkTheme import com.looker.droidify.utility.onLaunchClick +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.flowOn @@ -317,11 +321,24 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks { } } - private fun copyLinkToClipboard(view: View, link: String) { + private fun copyLinkToClipboard( + coroutineScope: CoroutineScope, + scaffoldState: SnackbarHostState, + link: String + ) { val clipboardManager = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager clipboardManager.setPrimaryClip(ClipData.newPlainText(null, link)) - Snackbar.make(view, R.string.link_copied_to_clipboard, Snackbar.LENGTH_SHORT).show() + coroutineScope.launch { + scaffoldState.showSnackbar( + message = getString(R.string.link_copied_to_clipboard), + actionLabel = getString(R.string.open) + ).apply { + if (this == SnackbarResult.ActionPerformed) { + onUriClick(link.toUri(), false) + } + } + } } @OptIn(ExperimentalMaterial3Api::class) @@ -377,6 +394,9 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks { } ) } + val snackbarHostState = remember { SnackbarHostState() } + val coroutineScope = rememberCoroutineScope() + suggestedProductRepo?.let { (product, repo) -> Scaffold( // TODO add the topBar to the activity instead of the fragments @@ -387,7 +407,8 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks { icon = imageData, state = downloadState ) - } + }, + snackbarHost = { SnackbarHost(snackbarHostState) }, ) { paddingValues -> LazyColumn( modifier = Modifier @@ -417,7 +438,8 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks { product.source.let { link -> if (link.isNotEmpty()) { copyLinkToClipboard( - requireActivity().window.decorView.rootView, + coroutineScope, + snackbarHostState, link ) } @@ -482,7 +504,8 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks { }, onLongClick = { link -> copyLinkToClipboard( - requireActivity().window.decorView.rootView, + coroutineScope, + snackbarHostState, link.toString() ) } @@ -505,7 +528,8 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks { }, onLongClick = { link -> copyLinkToClipboard( - requireActivity().window.decorView.rootView, + coroutineScope, + snackbarHostState, link.toString() ) } @@ -576,14 +600,22 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks { } } - items(items = releaseItems) { + items(items = releaseItems) { item -> ReleaseItem( - release = it.first, - repository = it.second, - releaseState = it.third - ) { release -> - onReleaseClick(release) - } + release = item.first, + repository = item.second, + releaseState = item.third, + onDownloadClick = { release -> + onReleaseClick(release) + }, + onLongClick = { + copyLinkToClipboard( + coroutineScope, + snackbarHostState, + it.getDownloadUrl(item.second) + ) + } + ) } } } diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 76b26e44..ed683b12 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -203,4 +203,5 @@ Display screenshots in the app page. Remove from favorites Add to favorites + Open