Skip to content

Commit

Permalink
Merge pull request #26 from Adyen/feature/copy-paste
Browse files Browse the repository at this point in the history
Copy payment method data to clipboard
  • Loading branch information
OscarSpruit authored Nov 7, 2024
2 parents c1ee792 + 77ee373 commit 81a0ba3
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 15 deletions.
46 changes: 46 additions & 0 deletions app/src/main/java/com/adyen/testcards/ui/CopyMenu.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.adyen.testcards.ui

import androidx.compose.foundation.layout.padding
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ClipboardManager
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.unit.dp

@Composable
fun CopyMenu(
expanded: Boolean,
items: Map<String, String>,
onDismissRequest: () -> Unit,
) {
DropdownMenu(
expanded = expanded,
onDismissRequest = onDismissRequest,
) {
Text(
text = "Copy...",
style = MaterialTheme.typography.labelLarge,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f),
modifier = Modifier.padding(start = 12.dp, top = 8.dp, end = 12.dp, bottom = 16.dp),
)

HorizontalDivider()

val clipboardManager: ClipboardManager = LocalClipboardManager.current
items.forEach { (title, value) ->
DropdownMenuItem(
text = { Text(title) },
onClick = {
clipboardManager.setText(AnnotatedString(value))
onDismissRequest()
},
)
}
}
}
20 changes: 18 additions & 2 deletions app/src/main/java/com/adyen/testcards/ui/CreditCard.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.adyen.testcards.ui

import androidx.compose.foundation.clickable
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand Down Expand Up @@ -68,6 +69,7 @@ internal fun LazyListScope.creditCardSection(
}
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun CreditCard(
card: CreditCard,
Expand All @@ -76,6 +78,7 @@ internal fun CreditCard(
onClick: ((CreditCard) -> Unit)? = null,
) {
var isFavorite by remember(card) { mutableStateOf(card.isFavorite) }
var showCopyMenu by remember(card) { mutableStateOf(false) }
FavoritableRow(
isFavorite = isFavorite,
onFavoriteClicked = {
Expand All @@ -84,7 +87,10 @@ internal fun CreditCard(
},
icon = card.icon,
modifier = modifier
.clickable(enabled = onClick != null) { onClick?.invoke(card) }
.combinedClickable(
onClick = { onClick?.invoke(card) },
onLongClick = { showCopyMenu = true },
)
.fillMaxWidth()
.padding(start = 16.dp, top = 8.dp, end = 8.dp, bottom = 8.dp),
) {
Expand All @@ -109,6 +115,16 @@ internal fun CreditCard(
}
}
}

CopyMenu(
expanded = showCopyMenu,
onDismissRequest = { showCopyMenu = false },
items = buildMap {
set("Number", card.number)
set("Expiry date", card.expiryDate)
card.securityCode?.let { set("Security code", it) }
},
)
}
}

Expand Down
19 changes: 17 additions & 2 deletions app/src/main/java/com/adyen/testcards/ui/GiftCard.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.adyen.testcards.ui

import androidx.compose.foundation.clickable
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand Down Expand Up @@ -48,6 +49,7 @@ internal fun LazyListScope.giftCardSection(
}
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun GiftCard(
giftCard: GiftCard,
Expand All @@ -56,6 +58,7 @@ internal fun GiftCard(
onClick: ((GiftCard) -> Unit)? = null,
) {
var isFavorite by remember(giftCard) { mutableStateOf(giftCard.isFavorite) }
var showCopyMenu by remember(giftCard) { mutableStateOf(false) }
FavoritableRow(
isFavorite = isFavorite,
onFavoriteClicked = {
Expand All @@ -64,7 +67,10 @@ internal fun GiftCard(
},
icon = R.drawable.ic_pm_gift_card.takeIf { giftCard.showIcon },
modifier = modifier
.clickable(enabled = onClick != null) { onClick?.invoke(giftCard) }
.combinedClickable(
onClick = { onClick?.invoke(giftCard) },
onLongClick = { showCopyMenu = true },
)
.fillMaxWidth()
.padding(start = 16.dp, top = 8.dp, end = 8.dp, bottom = 8.dp),
) {
Expand All @@ -76,6 +82,15 @@ internal fun GiftCard(
Text(text = giftCard.securityCode, style = MaterialTheme.typography.labelSmall)
}
}

CopyMenu(
expanded = showCopyMenu,
onDismissRequest = { showCopyMenu = false },
items = buildMap {
set("Number", giftCard.number)
set("Security code", giftCard.securityCode)
},
)
}
}

Expand Down
18 changes: 16 additions & 2 deletions app/src/main/java/com/adyen/testcards/ui/IBAN.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.adyen.testcards.ui

import androidx.compose.foundation.clickable
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand Down Expand Up @@ -48,6 +49,7 @@ internal fun LazyListScope.ibanSection(
}
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun IBAN(
iban: IBAN,
Expand All @@ -56,6 +58,7 @@ internal fun IBAN(
onClick: ((IBAN) -> Unit)? = null,
) {
var isFavorite by remember(iban) { mutableStateOf(iban.isFavorite) }
var showCopyMenu by remember(iban) { mutableStateOf(false) }
FavoritableRow(
isFavorite = isFavorite,
onFavoriteClicked = {
Expand All @@ -64,7 +67,10 @@ internal fun IBAN(
},
icon = R.drawable.ic_pm_bank.takeIf { iban.showIcon },
modifier = modifier
.clickable(enabled = onClick != null) { onClick?.invoke(iban) }
.combinedClickable(
onClick = { onClick?.invoke(iban) },
onLongClick = { showCopyMenu = true },
)
.fillMaxWidth()
.padding(start = 16.dp, top = 8.dp, end = 8.dp, bottom = 8.dp),
) {
Expand All @@ -76,6 +82,14 @@ internal fun IBAN(
Text(text = iban.issuingCountry, style = MaterialTheme.typography.labelSmall)
}
}

CopyMenu(
expanded = showCopyMenu,
onDismissRequest = { showCopyMenu = false },
items = buildMap {
set("IBAN", iban.iban)
},
)
}
}

Expand Down
18 changes: 16 additions & 2 deletions app/src/main/java/com/adyen/testcards/ui/UPI.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.adyen.testcards.ui

import androidx.compose.foundation.clickable
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyListScope
Expand Down Expand Up @@ -42,6 +43,7 @@ internal fun LazyListScope.upiSection(
}
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun UPI(
upi: UPI,
Expand All @@ -50,6 +52,7 @@ internal fun UPI(
onClick: ((UPI) -> Unit)? = null,
) {
var isFavorite by remember(upi) { mutableStateOf(upi.isFavorite) }
var showCopyMenu by remember(upi) { mutableStateOf(false) }
FavoritableRow(
isFavorite = isFavorite,
onFavoriteClicked = {
Expand All @@ -58,11 +61,22 @@ internal fun UPI(
},
icon = R.drawable.ic_pm_upi.takeIf { upi.showIcon },
modifier = modifier
.clickable(enabled = onClick != null) { onClick?.invoke(upi) }
.combinedClickable(
onClick = { onClick?.invoke(upi) },
onLongClick = { showCopyMenu = true },
)
.fillMaxWidth()
.padding(start = 16.dp, top = 8.dp, end = 8.dp, bottom = 8.dp),
) {
Text(text = upi.virtualPaymentAddress)

CopyMenu(
expanded = showCopyMenu,
onDismissRequest = { showCopyMenu = false },
items = buildMap {
set("Virtual Payment Address", upi.virtualPaymentAddress)
},
)
}
}

Expand Down
19 changes: 17 additions & 2 deletions app/src/main/java/com/adyen/testcards/ui/UsernamePassword.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.adyen.testcards.ui

import androidx.compose.foundation.clickable
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand Down Expand Up @@ -48,6 +49,7 @@ internal fun LazyListScope.usernamePasswordSection(
}
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun UsernamePassword(
data: UsernamePassword,
Expand All @@ -56,6 +58,7 @@ internal fun UsernamePassword(
onClick: ((UsernamePassword) -> Unit)? = null,
) {
var isFavorite by remember(data) { mutableStateOf(data.isFavorite) }
var showCopyMenu by remember(data) { mutableStateOf(false) }
FavoritableRow(
isFavorite = isFavorite,
onFavoriteClicked = {
Expand All @@ -64,7 +67,10 @@ internal fun UsernamePassword(
},
icon = R.drawable.ic_pm_wallet.takeIf { data.showIcon },
modifier = modifier
.clickable(enabled = onClick != null) { onClick?.invoke(data) }
.combinedClickable(
onClick = { onClick?.invoke(data) },
onLongClick = { showCopyMenu = true },
)
.fillMaxWidth()
.padding(start = 16.dp, top = 8.dp, end = 8.dp, bottom = 8.dp),
) {
Expand All @@ -76,6 +82,15 @@ internal fun UsernamePassword(
Text(text = data.password, style = MaterialTheme.typography.labelSmall)
}
}

CopyMenu(
expanded = showCopyMenu,
onDismissRequest = { showCopyMenu = false },
items = buildMap {
set("Username", data.username)
set("Password", data.password)
},
)
}
}

Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/ic_copy.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#000000" android:viewportHeight="960" android:viewportWidth="960" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M360,720Q327,720 303.5,696.5Q280,673 280,640L280,160Q280,127 303.5,103.5Q327,80 360,80L720,80Q753,80 776.5,103.5Q800,127 800,160L800,640Q800,673 776.5,696.5Q753,720 720,720L360,720ZM360,640L720,640Q720,640 720,640Q720,640 720,640L720,160Q720,160 720,160Q720,160 720,160L360,160Q360,160 360,160Q360,160 360,160L360,640Q360,640 360,640Q360,640 360,640ZM200,880Q167,880 143.5,856.5Q120,833 120,800L120,240L200,240L200,800Q200,800 200,800Q200,800 200,800L640,800L640,880L200,880ZM360,640Q360,640 360,640Q360,640 360,640L360,160Q360,160 360,160Q360,160 360,160L360,160Q360,160 360,160Q360,160 360,160L360,640Q360,640 360,640Q360,640 360,640Z"/>

</vector>
10 changes: 5 additions & 5 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
[versions]
activityCompose = "1.9.2"
activityCompose = "1.9.3"
agp = "8.6.1"
appcompat = "1.7.0"
autofill = "1.3.0-beta01"
composeBom = "2024.09.02"
coreKtx = "1.13.1"
composeBom = "2024.10.01"
coreKtx = "1.15.0"
datastore = "1.1.1"
espressoCore = "3.6.1"
hilt = "2.52"
junit = "4.13.2"
junitVersion = "1.2.1"
kotlin = "2.0.20"
ksp = "2.0.20-1.0.25"
kotlin = "2.0.21"
ksp = "2.0.21-1.0.25"
material = "1.12.0"
moshi = "1.15.1"
protobuf = "4.28.1"
Expand Down

0 comments on commit 81a0ba3

Please sign in to comment.