Skip to content

Commit 5c608c0

Browse files
committed
feat(bill-customization): introduce PlaygroundContext for per-caller playground behavior
Replace the FeatureFlag.CurrencyCreator gating on the playground scaffold with a PlaygroundContext passed through Event.Load, so the overlay and available features can diverge between Advanced (Standalone) and Currency Creator (inline, Background-only) entry points. Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent 99ede5b commit 5c608c0

7 files changed

Lines changed: 69 additions & 23 deletions

File tree

apps/flipcash/features/bill-customization/src/main/kotlin/com/flipcash/app/bill/customization/BillCustomizationScaffold.kt

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
4141
import com.flipcash.app.bill.customization.components.BillPlayground
4242
import com.flipcash.app.bills.AnimatedBill
4343
import com.flipcash.app.core.bill.Bill
44-
import com.flipcash.app.featureflags.FeatureFlag
45-
import com.flipcash.app.featureflags.LocalFeatureFlags
4644
import com.flipcash.features.bill.playground.R
4745
import com.getcode.theme.CodeTheme
4846
import com.getcode.ui.components.AppBarDefaults
@@ -54,18 +52,14 @@ import com.getcode.ui.utils.AnimationUtils
5452
@Composable
5553
fun BillPlaygroundScaffold(content: @Composable () -> Unit) {
5654
val controller = LocalBillPlaygroundController.current
57-
val featureFlags = LocalFeatureFlags.current
5855
val playgroundState by controller.state.collectAsStateWithLifecycle()
5956

60-
val currencyCreatorEnabled by featureFlags.observe(FeatureFlag.CurrencyCreator)
61-
.collectAsStateWithLifecycle()
62-
6357
val isUsingPlayground by remember(
6458
playgroundState.isCustomizing,
65-
currencyCreatorEnabled
59+
playgroundState.context,
6660
) {
6761
derivedStateOf {
68-
playgroundState.isCustomizing && !currencyCreatorEnabled
62+
playgroundState.isCustomizing && playgroundState.context.renderAsOverlay
6963
}
7064
}
7165

@@ -79,9 +73,13 @@ fun BillPlaygroundScaffold(content: @Composable () -> Unit) {
7973

8074
val customizationsOptions = playgroundState.customizations
8175

82-
val augmentedBill by remember(playgroundState.bill, customizationsOptions) {
76+
val augmentedBill by remember(
77+
playgroundState.bill,
78+
customizationsOptions,
79+
playgroundState.context,
80+
) {
8381
derivedStateOf {
84-
if (currencyCreatorEnabled) return@derivedStateOf null
82+
if (!playgroundState.context.renderAsOverlay) return@derivedStateOf null
8583
val bill = playgroundState.bill ?: return@derivedStateOf null
8684
if (bill !is Bill.Cash) return@derivedStateOf null
8785
bill.copy(

apps/flipcash/features/currency-creator/src/main/kotlin/com/flipcash/app/currencycreator/internal/CurrencyCreatorViewModel.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ internal class CurrencyCreatorViewModel @Inject constructor(
152152
val success: Boolean = false,
153153
) : Event
154154

155+
data class CustomizationsChanged(val customizations: TokenBillCustomizations): Event
156+
155157
data class LaunchToken(val method: PurchaseMethod) : Event
156158
data object Purchase : Event
157159
data class PurchaseWithReserves(val token: Token, val amount: Fiat) : Event
@@ -352,6 +354,7 @@ internal class CurrencyCreatorViewModel @Inject constructor(
352354
eventFlow
353355
.filterIsInstance<Event.LaunchToken>()
354356
.map { event ->
357+
println("customizations=${stateFlow.value.customizations}")
355358
val request = TokenCreateRequest(
356359
name = ModerationAttestation.Text(
357360
text = stateFlow.value.nameFieldState.text.toString(),
@@ -548,6 +551,10 @@ internal class CurrencyCreatorViewModel @Inject constructor(
548551
)
549552
}
550553

554+
is Event.CustomizationsChanged -> { state ->
555+
state.copy(customizations = event.customizations)
556+
}
557+
551558
is Event.LaunchToken -> { state -> state }
552559
is Event.Purchase -> { state -> state }
553560
is Event.CheckName -> { state -> state }

apps/flipcash/features/currency-creator/src/main/kotlin/com/flipcash/app/currencycreator/internal/screens/BillCustomizationScreen.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import androidx.compose.ui.Modifier
2121
import androidx.lifecycle.compose.collectAsStateWithLifecycle
2222
import com.flipcash.app.bill.customization.Event
2323
import com.flipcash.app.bill.customization.LocalBillPlaygroundController
24+
import com.flipcash.app.bill.customization.PlaygroundContext
2425
import com.flipcash.app.bill.customization.components.BillPlayground
2526
import com.flipcash.app.bills.RenderedBill
2627
import com.flipcash.app.core.bill.Bill
@@ -42,7 +43,8 @@ internal fun BillCustomizationScreen() {
4243
controller.dispatchEvent(
4344
Event.Load(
4445
customizations = state.customizations,
45-
amount = state.purchaseAmount
46+
amount = state.purchaseAmount,
47+
context = PlaygroundContext.CurrencyCreator,
4648
)
4749
)
4850
}
@@ -60,19 +62,23 @@ internal fun BillCustomizationContent(
6062

6163
val augmentedBill by remember(
6264
playgroundState.bill,
63-
playgroundState.customizations
65+
state.customizations
6466
) {
6567
derivedStateOf {
6668
val bill = playgroundState.bill ?: return@derivedStateOf null
6769
if (bill !is Bill.Cash) return@derivedStateOf null
6870
bill.copy(
6971
token = bill.token.copy(
70-
billCustomizations = playgroundState.customizations
72+
billCustomizations = state.customizations
7173
)
7274
)
7375
}
7476
}
7577

78+
LaunchedEffect(playgroundState.customizations) {
79+
dispatch(CurrencyCreatorViewModel.Event.CustomizationsChanged(playgroundState.customizations))
80+
}
81+
7682
Column(
7783
modifier = Modifier.fillMaxSize(),
7884
horizontalAlignment = Alignment.CenterHorizontally

apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ui/components/DecorView.kt

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ import androidx.compose.ui.unit.dp
3939
import androidx.lifecycle.compose.collectAsStateWithLifecycle
4040
import com.flipcash.app.bill.customization.LocalBillPlaygroundController
4141
import com.flipcash.app.core.bill.BillState
42-
import com.flipcash.app.featureflags.FeatureFlag
43-
import com.flipcash.app.featureflags.LocalFeatureFlags
4442
import com.flipcash.app.scanner.internal.ScannerDecorItem
4543
import com.flipcash.app.session.SessionState
4644
import com.flipcash.features.scanner.R
@@ -59,17 +57,14 @@ internal fun DecorView(
5957
onAction: (ScannerDecorItem) -> Unit,
6058
) {
6159
val billPlayground = LocalBillPlaygroundController.current
62-
val featureFlags = LocalFeatureFlags.current
6360
val playgroundState by billPlayground.state.collectAsStateWithLifecycle()
64-
val currencyCreatorEnabled by featureFlags.observe(FeatureFlag.CurrencyCreator)
65-
.collectAsStateWithLifecycle()
6661

6762
val isUsingPlayground by remember(
6863
playgroundState.isCustomizing,
69-
currencyCreatorEnabled
64+
playgroundState.context,
7065
) {
7166
derivedStateOf {
72-
playgroundState.isCustomizing && !currencyCreatorEnabled
67+
playgroundState.isCustomizing && playgroundState.context.renderAsOverlay
7368
}
7469
}
7570

apps/flipcash/shared/bill-customization/src/main/kotlin/com/flipcash/app/bill/customization/BillPlaygroundController.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ interface BillPlaygroundController {
2929

3030
data class PlaygroundState(
3131
val bill: Bill? = null,
32+
val context: PlaygroundContext = PlaygroundContext.Standalone,
3233
val features: List<PlaygroundFeature> = PlaygroundFeature.entries.toList(),
3334
val selectedFeature: PlaygroundFeature = PlaygroundFeature.Background,
3435
val backgroundState: ColorState = ColorState(),
@@ -103,6 +104,7 @@ sealed interface Event {
103104
data class Load(
104105
val customizations: TokenBillCustomizations? = null,
105106
val amount: Fiat = 5.toFiat(),
107+
val context: PlaygroundContext = PlaygroundContext.Standalone,
106108
): Event
107109
data class SelectFeature(val feature: PlaygroundFeature): Event
108110
sealed interface Colors: Event {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.flipcash.app.bill.customization
2+
3+
import com.flipcash.app.bill.customization.models.PlaygroundFeature
4+
5+
sealed interface PlaygroundContext {
6+
val renderAsOverlay: Boolean
7+
val availableFeatures: List<PlaygroundFeature>
8+
9+
/** Playground opened as a standalone overlay (Advanced → Bill Creator). */
10+
data object Standalone : PlaygroundContext {
11+
override val renderAsOverlay: Boolean = true
12+
override val availableFeatures: List<PlaygroundFeature>
13+
get() = PlaygroundFeature.entries
14+
}
15+
16+
/** Playground embedded inside the Currency Creator flow. */
17+
data object CurrencyCreator : PlaygroundContext {
18+
override val renderAsOverlay: Boolean = false
19+
override val availableFeatures: List<PlaygroundFeature>
20+
get() = listOf(PlaygroundFeature.Background)
21+
}
22+
}

apps/flipcash/shared/bill-customization/src/main/kotlin/com/flipcash/app/bill/customization/internal/InternalBillPlaygroundController.kt

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModel
55
import androidx.lifecycle.viewModelScope
66
import com.flipcash.app.bill.customization.BillPlaygroundController
77
import com.flipcash.app.bill.customization.Event
8+
import com.flipcash.app.bill.customization.PlaygroundContext
89
import com.flipcash.app.bill.customization.PlaygroundState
910
import com.flipcash.app.bill.customization.internal.features.BackgroundController
1011
import com.flipcash.app.bill.customization.internal.features.BlendMode
@@ -81,7 +82,12 @@ class InternalBillPlaygroundController(
8182
override val canCopy: Boolean
8283
get() = false
8384

84-
private fun customizeFor(token: Token, amount: Fiat, customizations: TokenBillCustomizations?) {
85+
private fun customizeFor(
86+
token: Token,
87+
amount: Fiat,
88+
customizations: TokenBillCustomizations?,
89+
context: PlaygroundContext,
90+
) {
8591
// create amount for the bill
8692
val demoAmount = LocalFiat(
8793
usdf = amount,
@@ -101,14 +107,24 @@ class InternalBillPlaygroundController(
101107
data = payloadInfo.codeData.toList()
102108
)
103109

104-
_state.update { it.copy(bill = bill) }
110+
_state.update { current ->
111+
val features = context.availableFeatures
112+
val selectedFeature = current.selectedFeature.takeIf { it in features }
113+
?: features.first()
114+
current.copy(
115+
bill = bill,
116+
context = context,
117+
features = features,
118+
selectedFeature = selectedFeature,
119+
)
120+
}
105121
}
106122

107123
override fun dispatchEvent(event: Event) {
108124
when (event) {
109125
// high level actions
110126
is Event.Load -> {
111-
customizeFor(Token.usdf, event.amount, event.customizations)
127+
customizeFor(Token.usdf, event.amount, event.customizations, event.context)
112128
}
113129

114130
// selecting feature from tab row

0 commit comments

Comments
 (0)