fix: keep zap/reaction card inner content on the card's tint

The embedded note and comment inside the lightning / nutzap / onchain-zap
and reaction activity cards were handed the parent feed / MultiSetCard
background state, so they drew black (the app background) or flashed the
new-note highlight instead of letting the card's orange (or like-tinted)
wash show through.

ActivityCardFrame now exposes a stable transparent background state to its
content for the inner note and comment to draw on; the hand-built onchain
card uses a matching local state. Nothing inside the card's layout changes
background from the feed anymore.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GEUsgVr5e31qYeqNSjgHif
This commit is contained in:
Claude
2026-06-26 19:37:43 +00:00
parent 19debffe15
commit d6fc3232b2
5 changed files with 30 additions and 11 deletions
@@ -36,6 +36,9 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -57,12 +60,20 @@ val LikeTint = Color(0xFFCA395F)
* Gradient card frame shared by the reaction / zap / nutzap / onchain-zap
* renderings, mirroring the onchain card's look: rounded corners and a soft
* top-to-bottom wash of the kind's tint.
*
* The content lambda receives a stable [transparentCardBackground] state to hand
* down to the embedded note and comment: everything inside the card sits on the
* orange (or like-tinted) wash, so inner content must draw transparent and let
* that wash show through. Passing the parent feed / MultiSetCard background here
* instead would paint the inner note black (the app background) or flash it with
* the new-note highlight, breaking the card's solid tint.
*/
@Composable
fun ActivityCardFrame(
tint: Color,
content: @Composable ColumnScope.() -> Unit,
content: @Composable ColumnScope.(transparentCardBackground: MutableState<Color>) -> Unit,
) {
val transparentCardBackground = remember { mutableStateOf<Color>(Color.Transparent) }
Box(
modifier =
Modifier
@@ -78,7 +89,9 @@ fun ActivityCardFrame(
),
).padding(horizontal = 12.dp, vertical = 10.dp),
) {
Column(verticalArrangement = Arrangement.spacedBy(8.dp), content = content)
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
content(transparentCardBackground)
}
}
}
@@ -61,7 +61,7 @@ fun RenderNutzap(
val recipientKey = nutzapEvent.linkedPubKeys().firstOrNull()
val orange = MaterialTheme.colorScheme.bitcoinColor
ActivityCardFrame(orange) {
ActivityCardFrame(orange) { cardBackground ->
ActivityHeaderRow(
tint = orange,
pillLabel = "CASHU",
@@ -89,12 +89,12 @@ fun RenderNutzap(
},
)
RenderZappedPost(note, quotesLeft, backgroundColor, accountViewModel, nav)
RenderZappedPost(note, quotesLeft, cardBackground, accountViewModel, nav)
ActivityAmountRow(showAmount(BigDecimal(nutzapEvent.claimedSatsTotal())), orange)
nutzapEvent.content.ifBlank { null }?.let {
CrossfadeToDisplayComment(it, backgroundColor, nav, accountViewModel)
CrossfadeToDisplayComment(it, cardBackground, nav, accountViewModel)
}
}
}
@@ -105,6 +105,12 @@ fun RenderOnchainZap(
val orange = MaterialTheme.colorScheme.bitcoinColor
// The embedded note sits on the orange wash, so it must draw transparent and
// let that show through. Handing it the parent feed / MultiSetCard background
// instead would paint it black (the app background) or flash it with the
// new-note highlight, breaking the card's solid tint.
val cardBackground = remember { mutableStateOf<Color>(Color.Transparent) }
// Async chain lookup so we can show a real "Confirmed at block N" or
// "In mempool…" pill rather than a sender-claimed status. Null = backend
// not configured, or fetch failed — we just show the sender-claimed sats
@@ -143,7 +149,7 @@ fun RenderOnchainZap(
nav = nav,
)
RenderZappedPost(note, quotesLeft, backgroundColor, accountViewModel, nav)
RenderZappedPost(note, quotesLeft, cardBackground, accountViewModel, nav)
AmountRow(sats = sats, orange = orange)
@@ -50,7 +50,7 @@ fun RenderReaction(
) {
val reactionType = note.event?.content ?: ""
ActivityCardFrame(LikeTint) {
ActivityCardFrame(LikeTint) { cardBackground ->
ActivityHeaderRow(
tint = LikeTint,
pillLabel = "REACTION",
@@ -77,6 +77,6 @@ fun RenderReaction(
},
)
RenderZappedPost(note, quotesLeft, backgroundColor, accountViewModel, nav)
RenderZappedPost(note, quotesLeft, cardBackground, accountViewModel, nav)
}
}
@@ -127,7 +127,7 @@ fun RenderLnZapCard(
) {
val orange = MaterialTheme.colorScheme.bitcoinColor
ActivityCardFrame(orange) {
ActivityCardFrame(orange) { cardBackground ->
ActivityHeaderRow(
tint = orange,
pillLabel = "LIGHTNING",
@@ -150,12 +150,12 @@ fun RenderLnZapCard(
},
)
RenderZappedPost(note, quotesLeft, backgroundColor, accountViewModel, nav)
RenderZappedPost(note, quotesLeft, cardBackground, accountViewModel, nav)
card.amount?.let { ActivityAmountRow(it, orange) }
card.comment?.let {
CrossfadeToDisplayComment(it, backgroundColor, nav, accountViewModel)
CrossfadeToDisplayComment(it, cardBackground, nav, accountViewModel)
}
}
}