Add: Snackbar with action on release's long click

This commit is contained in:
machiav3lli 2022-06-23 02:28:31 +02:00
parent f022a29990
commit ee99da7907
3 changed files with 59 additions and 18 deletions

View File

@ -5,7 +5,9 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@ -55,7 +57,8 @@ fun ReleaseItem(
release: Release, release: Release,
repository: Repository, repository: Repository,
releaseState: Int = RELEASE_STATE_NONE, releaseState: Int = RELEASE_STATE_NONE,
onDownloadClick: (Release) -> Unit = {} onDownloadClick: (Release) -> Unit = {},
onLongClick: (Release) -> Unit = {},
) { ) {
val currentRelease by remember { mutableStateOf(release) } val currentRelease by remember { mutableStateOf(release) }
val isInstalled = releaseState == RELEASE_STATE_INSTALLED val isInstalled = releaseState == RELEASE_STATE_INSTALLED
@ -74,11 +77,13 @@ fun ReleaseItem(
repository = repository, repository = repository,
isSuggested = isSuggested, isSuggested = isSuggested,
isInstalled = isInstalled, isInstalled = isInstalled,
onDownloadClick = onDownloadClick onDownloadClick = onDownloadClick,
onLongClick = onLongClick
) )
} }
} }
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun ReleaseItemContent( fun ReleaseItemContent(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@ -86,10 +91,13 @@ fun ReleaseItemContent(
repository: Repository, repository: Repository,
isSuggested: Boolean = false, isSuggested: Boolean = false,
isInstalled: Boolean = false, isInstalled: Boolean = false,
onDownloadClick: (Release) -> Unit = {} onDownloadClick: (Release) -> Unit = {},
onLongClick: (Release) -> Unit = {}
) { ) {
Row( Row(
modifier = Modifier.padding(end = 16.dp), modifier = Modifier
.combinedClickable(onClick = {}, onLongClick = { onLongClick(release) })
.padding(end = 16.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start horizontalArrangement = Arrangement.Start
) { ) {

View File

@ -22,12 +22,16 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold 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.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -35,7 +39,6 @@ import androidx.compose.ui.unit.dp
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.google.android.material.snackbar.Snackbar
import com.looker.droidify.R import com.looker.droidify.R
import com.looker.droidify.RELEASE_STATE_INSTALLED import com.looker.droidify.RELEASE_STATE_INSTALLED
import com.looker.droidify.RELEASE_STATE_NONE 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.generatePermissionGroups
import com.looker.droidify.utility.isDarkTheme import com.looker.droidify.utility.isDarkTheme
import com.looker.droidify.utility.onLaunchClick import com.looker.droidify.utility.onLaunchClick
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flowOn 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 = val clipboardManager =
requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clipboardManager.setPrimaryClip(ClipData.newPlainText(null, link)) 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) @OptIn(ExperimentalMaterial3Api::class)
@ -377,6 +394,9 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks {
} }
) )
} }
val snackbarHostState = remember { SnackbarHostState() }
val coroutineScope = rememberCoroutineScope()
suggestedProductRepo?.let { (product, repo) -> suggestedProductRepo?.let { (product, repo) ->
Scaffold( Scaffold(
// TODO add the topBar to the activity instead of the fragments // TODO add the topBar to the activity instead of the fragments
@ -387,7 +407,8 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks {
icon = imageData, icon = imageData,
state = downloadState state = downloadState
) )
} },
snackbarHost = { SnackbarHost(snackbarHostState) },
) { paddingValues -> ) { paddingValues ->
LazyColumn( LazyColumn(
modifier = Modifier modifier = Modifier
@ -417,7 +438,8 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks {
product.source.let { link -> product.source.let { link ->
if (link.isNotEmpty()) { if (link.isNotEmpty()) {
copyLinkToClipboard( copyLinkToClipboard(
requireActivity().window.decorView.rootView, coroutineScope,
snackbarHostState,
link link
) )
} }
@ -482,7 +504,8 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks {
}, },
onLongClick = { link -> onLongClick = { link ->
copyLinkToClipboard( copyLinkToClipboard(
requireActivity().window.decorView.rootView, coroutineScope,
snackbarHostState,
link.toString() link.toString()
) )
} }
@ -505,7 +528,8 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks {
}, },
onLongClick = { link -> onLongClick = { link ->
copyLinkToClipboard( copyLinkToClipboard(
requireActivity().window.decorView.rootView, coroutineScope,
snackbarHostState,
link.toString() link.toString()
) )
} }
@ -576,14 +600,22 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), Callbacks {
} }
} }
items(items = releaseItems) { items(items = releaseItems) { item ->
ReleaseItem( ReleaseItem(
release = it.first, release = item.first,
repository = it.second, repository = item.second,
releaseState = it.third releaseState = item.third,
) { release -> onDownloadClick = { release ->
onReleaseClick(release) onReleaseClick(release)
} },
onLongClick = {
copyLinkToClipboard(
coroutineScope,
snackbarHostState,
it.getDownloadUrl(item.second)
)
}
)
} }
} }
} }

View File

@ -203,4 +203,5 @@
<string name="show_screenshots_description">Display screenshots in the app page.</string> <string name="show_screenshots_description">Display screenshots in the app page.</string>
<string name="favorite_remove">Remove from favorites</string> <string name="favorite_remove">Remove from favorites</string>
<string name="favorite_add">Add to favorites</string> <string name="favorite_add">Add to favorites</string>
<string name="open">Open</string>
</resources> </resources>