[#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:
parent
1dd36b582e
commit
327b47cc12
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue