Merge pull request #2783 from greenart7c3/claude/add-copy-address-button-LgZSZ

Add copy-to-clipboard functionality for payment targets
This commit is contained in:
Vitor Pamplona
2026-05-08 08:13:26 -04:00
committed by GitHub
2 changed files with 30 additions and 0 deletions
@@ -82,6 +82,7 @@ import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.Role
@@ -128,6 +129,7 @@ import com.vitorpamplona.amethyst.ui.components.M3ActionDialog
import com.vitorpamplona.amethyst.ui.components.M3ActionRow import com.vitorpamplona.amethyst.ui.components.M3ActionRow
import com.vitorpamplona.amethyst.ui.components.M3ActionSection import com.vitorpamplona.amethyst.ui.components.M3ActionSection
import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorMessage import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorMessage
import com.vitorpamplona.amethyst.ui.components.util.setText
import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.routes.Route
import com.vitorpamplona.amethyst.ui.navigation.routes.routeReplyTo import com.vitorpamplona.amethyst.ui.navigation.routes.routeReplyTo
@@ -346,6 +348,8 @@ fun PayReaction(
val authorPubkey = baseNote.author?.pubkeyHex ?: return val authorPubkey = baseNote.author?.pubkeyHex ?: return
val address = remember(authorPubkey) { PaymentTargetsEvent.createAddress(authorPubkey) } val address = remember(authorPubkey) { PaymentTargetsEvent.createAddress(authorPubkey) }
val context = LocalContext.current val context = LocalContext.current
val clipboardManager = LocalClipboard.current
val scope = rememberCoroutineScope()
LoadAddressableNote(address, accountViewModel) { note -> LoadAddressableNote(address, accountViewModel) { note ->
val targets = remember(note) { (note?.event as? PaymentTargetsEvent)?.paymentTargets() ?: emptyList() } val targets = remember(note) { (note?.event as? PaymentTargetsEvent)?.paymentTargets() ?: emptyList() }
@@ -395,6 +399,16 @@ fun PayReaction(
} }
}, },
) )
M3ActionRow(
icon = MaterialSymbols.ContentCopy,
text = stringRes(R.string.copy_to_clipboard),
onClick = {
expanded = false
scope.launch {
clipboardManager.setText(target.authority)
}
},
)
} }
} }
} }
@@ -28,8 +28,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
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.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.net.toUri import androidx.core.net.toUri
@@ -40,6 +42,7 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.ui.components.M3ActionDialog import com.vitorpamplona.amethyst.ui.components.M3ActionDialog
import com.vitorpamplona.amethyst.ui.components.M3ActionRow import com.vitorpamplona.amethyst.ui.components.M3ActionRow
import com.vitorpamplona.amethyst.ui.components.M3ActionSection import com.vitorpamplona.amethyst.ui.components.M3ActionSection
import com.vitorpamplona.amethyst.ui.components.util.setText
import com.vitorpamplona.amethyst.ui.note.ErrorMessageDialog import com.vitorpamplona.amethyst.ui.note.ErrorMessageDialog
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -47,6 +50,7 @@ import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ZeroPadding import com.vitorpamplona.amethyst.ui.theme.ZeroPadding
import com.vitorpamplona.quartz.experimental.nipA3.PaymentTarget import com.vitorpamplona.quartz.experimental.nipA3.PaymentTarget
import com.vitorpamplona.quartz.experimental.nipA3.PaymentTargetsEvent import com.vitorpamplona.quartz.experimental.nipA3.PaymentTargetsEvent
import kotlinx.coroutines.launch
@Composable @Composable
fun PaymentButton( fun PaymentButton(
@@ -72,6 +76,8 @@ fun PaymentButton(
@Composable @Composable
fun PaymentButtonWithTargets(targets: List<PaymentTarget>) { fun PaymentButtonWithTargets(targets: List<PaymentTarget>) {
val context = LocalContext.current val context = LocalContext.current
val clipboardManager = LocalClipboard.current
val scope = rememberCoroutineScope()
var expanded by remember { mutableStateOf(false) } var expanded by remember { mutableStateOf(false) }
var errorMessage by remember { mutableStateOf<String?>(null) } var errorMessage by remember { mutableStateOf<String?>(null) }
@@ -111,6 +117,16 @@ fun PaymentButtonWithTargets(targets: List<PaymentTarget>) {
} }
}, },
) )
M3ActionRow(
icon = MaterialSymbols.ContentCopy,
text = stringRes(R.string.copy_to_clipboard),
onClick = {
expanded = false
scope.launch {
clipboardManager.setText(target.authority)
}
},
)
} }
} }
} }