[#866] Clipboardmanager on Android level 21 in Demo-app

* [#866] Clipboardmanager on Android level 21 in Demo-app

- Notification with Toast on API 32 and less added to let users know they have it copied in the clipboard.

* Replace Toast with Snackbar

- Tested with Android API level 21, 23, 29, 31, 33
This commit is contained in:
Honza Rychnovsky 2023-01-09 14:12:04 +01:00 committed by GitHub
parent 1dd36b582e
commit 327b47cc12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 14 deletions

View File

@ -1,12 +1,14 @@
package cash.z.ecc.android.sdk.demoapp package cash.z.ecc.android.sdk.demoapp
import android.annotation.TargetApi
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.os.Build
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
@ -21,6 +23,9 @@ import cash.z.ecc.android.sdk.demoapp.ui.screen.addresses.view.Addresses
import cash.z.ecc.android.sdk.demoapp.ui.screen.home.view.Home import cash.z.ecc.android.sdk.demoapp.ui.screen.home.view.Home
import cash.z.ecc.android.sdk.demoapp.ui.screen.home.viewmodel.WalletViewModel import cash.z.ecc.android.sdk.demoapp.ui.screen.home.viewmodel.WalletViewModel
import cash.z.ecc.android.sdk.demoapp.ui.screen.send.view.Send import cash.z.ecc.android.sdk.demoapp.ui.screen.send.view.Send
import cash.z.ecc.android.sdk.demoapp.util.AndroidApiVersion
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@OptIn(ExperimentalLifecycleComposeApi::class) @OptIn(ExperimentalLifecycleComposeApi::class)
@Composable @Composable
@ -47,14 +52,23 @@ internal fun ComposeActivity.Navigation() {
if (null == synchronizer) { if (null == synchronizer) {
// Display loading indicator // Display loading indicator
} else { } else {
val scope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() }
// I don't like giving synchronizer directly over to the view, but for now it isolates each of the // I don't like giving synchronizer directly over to the view, but for now it isolates each of the
// demo app views // demo app views
Addresses( Addresses(
synchronizer = synchronizer, synchronizer = synchronizer,
copyToClipboard = { tag, textToCopy -> copyToClipboard = { tag, textToCopy ->
copyToClipboard(applicationContext, tag, textToCopy) copyToClipboard(
applicationContext,
tag,
textToCopy,
scope,
snackbarHostState
)
}, },
onBack = { navController.popBackStackJustOnce(WALLET_ADDRESS_DETAILS) } onBack = { navController.popBackStackJustOnce(WALLET_ADDRESS_DETAILS) },
snackbarHostState = snackbarHostState
) )
} }
} }
@ -107,16 +121,35 @@ private fun NavHostController.popBackStackJustOnce(currentRouteToBePopped: Strin
popBackStack() popBackStack()
} }
// Note: this requires API level 23 (current min is 21 for the Demo-app). We should address this requirement, or set fun copyToClipboard(
// our Demo-app min to 23 context: Context,
@TargetApi(Build.VERSION_CODES.M) tag: String,
fun copyToClipboard(context: Context, tag: String, textToCopy: String) { textToCopy: String,
val clipboardManager = context.getSystemService(ClipboardManager::class.java) scope: CoroutineScope,
snackbarHostState: SnackbarHostState
) {
val clipboardManager = if (AndroidApiVersion.isAtLeastM) {
context.getSystemService(ClipboardManager::class.java)
} else {
context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
}
val data = ClipData.newPlainText( val data = ClipData.newPlainText(
tag, tag,
textToCopy textToCopy
) )
clipboardManager.setPrimaryClip(data) clipboardManager.setPrimaryClip(data)
// Notify users with Snackbar only on Android level 32 and lower, as 33 and higher notifies users by its own system
// way
if (!AndroidApiVersion.isAtLeastT) {
scope.launch {
snackbarHostState.showSnackbar(
message = context.getString(R.string.address_copied, textToCopy),
duration = SnackbarDuration.Short
)
}
}
} }
object NavigationTargets { object NavigationTargets {

View File

@ -13,6 +13,8 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -41,11 +43,13 @@ import kotlinx.coroutines.flow.flow
fun Addresses( fun Addresses(
synchronizer: Synchronizer, synchronizer: Synchronizer,
copyToClipboard: (String, String) -> Unit, copyToClipboard: (String, String) -> Unit,
onBack: () -> Unit onBack: () -> Unit,
snackbarHostState: SnackbarHostState
) { ) {
Scaffold(topBar = { Scaffold(
AddressesTopAppBar(onBack) topBar = { AddressesTopAppBar(onBack) },
}) { paddingValues -> snackbarHost = { SnackbarHost(snackbarHostState) }
) { paddingValues ->
// TODO [#846]: Slow addresses providing // TODO [#846]: Slow addresses providing
// TODO [#846]: https://github.com/zcash/zcash-android-wallet-sdk/issues/846 // TODO [#846]: https://github.com/zcash/zcash-android-wallet-sdk/issues/846
val walletAddresses = flow { val walletAddresses = flow {

View File

@ -1,4 +1,4 @@
<resources> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Demo App</string> <string name="app_name">Demo App</string>
<string name="navigation_drawer_open">Open navigation drawer</string> <string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string> <string name="navigation_drawer_close">Close navigation drawer</string>
@ -37,6 +37,8 @@
<string name="unified_address_tag">Zcash unified address</string> <string name="unified_address_tag">Zcash unified address</string>
<string name="sapling_address_tag">Zcash sapling address</string> <string name="sapling_address_tag">Zcash sapling address</string>
<string name="transparent_address_tag">Zcash transparent address</string> <string name="transparent_address_tag">Zcash transparent address</string>
<string name="address_copied" formatted="true"><xliff:g id="address" example="t1TdMMj5zzMtt...">Copied to
clipboard: %1$s</xliff:g></string>
<string name="configure_seed">Please select your wallet secret phrase</string> <string name="configure_seed">Please select your wallet secret phrase</string>
<string name="person_alyssa">Alyssa P. Hacker</string> <string name="person_alyssa">Alyssa P. Hacker</string>