Skip to content

Commit 8d848c3

Browse files
committed
feat(billcreator): add copy to export selected colors
Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent fc801e6 commit 8d848c3

6 files changed

Lines changed: 56 additions & 26 deletions

File tree

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import androidx.compose.material.DismissState
2424
import androidx.compose.material.DismissValue
2525
import androidx.compose.material.ExperimentalMaterialApi
2626
import androidx.compose.material.Text
27+
import androidx.compose.material.icons.Icons
28+
import androidx.compose.material.icons.filled.CopyAll
2729
import androidx.compose.runtime.Composable
2830
import androidx.compose.runtime.derivedStateOf
2931
import androidx.compose.runtime.getValue
@@ -141,9 +143,11 @@ fun BillPlaygroundScaffold(content: @Composable () -> Unit) {
141143
TopBar(
142144
modifier = Modifier.fillMaxWidth(),
143145
canUndo = controller.canUndo,
146+
canCopy = controller.canCopy,
144147
onUndo = { controller.dispatchEvent(Event.Undo) },
148+
onCopy = { controller.dispatchEvent(Event.Copy) },
145149
onBack = { controller.cancel() },
146-
onDone = { controller.cancel() }
150+
onDone = { controller.cancel() },
147151
)
148152
}
149153

@@ -179,7 +183,9 @@ private fun TopBar(
179183
modifier: Modifier = Modifier,
180184
onBack: () -> Unit,
181185
canUndo: Boolean,
186+
canCopy: Boolean,
182187
onUndo: () -> Unit,
188+
onCopy: () -> Unit,
183189
onDone: () -> Unit,
184190
) {
185191
Row(
@@ -210,6 +216,19 @@ private fun TopBar(
210216
contentDescription = null
211217
)
212218

219+
Text(
220+
modifier = Modifier
221+
.background(Color.Black.copy(0.19f), CircleShape)
222+
.clip(CircleShape)
223+
.rememberedClickable { onCopy() }
224+
.padding(
225+
horizontal = CodeTheme.dimens.grid.x2,
226+
vertical = CodeTheme.dimens.grid.x1
227+
),
228+
text = "Copy",
229+
style = CodeTheme.typography.textMedium,
230+
color = CodeTheme.colors.textMain,
231+
)
213232
Text(
214233
modifier = Modifier
215234
.background(Color.Black.copy(0.19f), CircleShape)

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

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.flipcash.app.bill.customization.components
22

3+
import android.content.ClipboardManager
34
import androidx.compose.animation.AnimatedContent
45
import androidx.compose.animation.ExperimentalSharedTransitionApi
56
import androidx.compose.animation.core.Spring
@@ -182,25 +183,13 @@ internal fun Modifier.presenceBorder(
182183
shape = shape
183184
)
184185

185-
private val usdToCadRate = Rate(fx = 1.37161, currency = CurrencyCode.CAD)
186-
private val cadToUsdRate = Rate(fx = 0.72894, currency = CurrencyCode.USD)
187-
private val rates = mapOf(
188-
CurrencyCode.CAD to usdToCadRate,
189-
CurrencyCode.USD to cadToUsdRate,
190-
)
191-
192186
@Composable
193187
@Preview
194188
private fun PreviewCustomizationControls() {
195189
FlipcashDesignSystem {
196-
val context = LocalContext.current
190+
val clipboardManager = LocalContext.current.getSystemService(ClipboardManager::class.java)
197191
val controller = remember {
198-
InternalBillPlaygroundController(
199-
ExchangeStub(
200-
providedRates = rates,
201-
context = context,
202-
)
203-
)
192+
InternalBillPlaygroundController(clipboardManager)
204193
}
205194
val state by controller.state.collectAsStateWithLifecycle()
206195

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import java.util.UUID
1717
interface BillPlaygroundController {
1818
val state: StateFlow<State>
1919
val canUndo: Boolean
20+
val canCopy: Boolean
2021
fun customizeFor(token: Token)
2122

2223
fun dispatchEvent(event: Event)
@@ -75,6 +76,7 @@ sealed interface Event {
7576
data object OpenHueControls: Event
7677
data object CloseHueControls: Event
7778
data object Undo: Event
79+
data object Copy: Event
7880
}
7981

8082
internal const val MaxGradientColors = 3
@@ -118,6 +120,7 @@ internal fun buildGradient(): List<ColorStore> {
118120
internal object StubPlaygroundController : BillPlaygroundController {
119121
override val state: StateFlow<State> = MutableStateFlow(State())
120122
override val canUndo: Boolean = false
123+
override val canCopy: Boolean = false
121124
override fun customizeFor(token: Token) = Unit
122125
override fun dispatchEvent(event: Event) = Unit
123126
override fun cancel() = Unit

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package com.flipcash.app.bill.customization.inject
22

3+
import android.content.ClipboardManager
34
import com.flipcash.app.bill.customization.BillPlaygroundController
45
import com.flipcash.app.bill.customization.internal.InternalBillPlaygroundController
5-
import com.getcode.opencode.exchange.Exchange
66
import dagger.Module
77
import dagger.Provides
88
import dagger.hilt.InstallIn
@@ -14,6 +14,7 @@ import javax.inject.Singleton
1414
object PlaygroundModule {
1515
@Provides
1616
@Singleton
17-
fun providesPlaygroundController(exchange: Exchange
18-
): BillPlaygroundController = InternalBillPlaygroundController(exchange)
17+
fun providesPlaygroundController(
18+
clipboardManager: ClipboardManager,
19+
): BillPlaygroundController = InternalBillPlaygroundController(clipboardManager)
1920
}

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

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,34 @@
11
package com.flipcash.app.bill.customization.internal
22

3-
import androidx.compose.ui.graphics.Color
4-
import cafe.adriel.voyager.core.stack.Stack
5-
import cafe.adriel.voyager.core.stack.mutableStateStackOf
3+
import android.content.ClipboardManager
64
import com.flipcash.app.bill.customization.BillPlaygroundController
75
import com.flipcash.app.bill.customization.ColorStore
86
import com.flipcash.app.bill.customization.Event
97
import com.flipcash.app.bill.customization.PlaygroundMode
108
import com.flipcash.app.bill.customization.State
119
import com.flipcash.app.core.bill.Bill
12-
import com.getcode.opencode.exchange.Exchange
1310
import com.getcode.opencode.model.core.OpenCodePayload
1411
import com.getcode.opencode.model.core.PayloadKind
1512
import com.getcode.opencode.model.financial.BillBackground
1613
import com.getcode.opencode.model.financial.LocalFiat
1714
import com.getcode.opencode.model.financial.Token
1815
import com.getcode.opencode.model.financial.toFiat
19-
import com.getcode.opencode.model.financial.usdc
2016
import com.getcode.opencode.utils.nonce
2117
import com.getcode.ui.utils.Hsv
2218
import com.getcode.ui.utils.hexToColor
23-
import com.getcode.ui.utils.hsv
19+
import com.getcode.ui.utils.toAGColor
20+
import com.getcode.ui.utils.toHex
2421
import kotlinx.coroutines.flow.MutableSharedFlow
2522
import kotlinx.coroutines.flow.MutableStateFlow
2623
import kotlinx.coroutines.flow.SharedFlow
2724
import kotlinx.coroutines.flow.StateFlow
2825
import kotlinx.coroutines.flow.asSharedFlow
2926
import kotlinx.coroutines.flow.asStateFlow
3027
import kotlinx.coroutines.flow.update
31-
import kotlinx.coroutines.flow.updateAndGet
3228

29+
@OptIn(ExperimentalStdlibApi::class)
3330
class InternalBillPlaygroundController(
34-
private val exchange: Exchange,
31+
private val clipboard: ClipboardManager,
3532
) : BillPlaygroundController {
3633

3734
private val _state: MutableStateFlow<State> = MutableStateFlow(State())
@@ -46,6 +43,9 @@ class InternalBillPlaygroundController(
4643
override val canUndo: Boolean
4744
get() = !undoStack.isEmpty()
4845

46+
override val canCopy: Boolean
47+
get() = true
48+
4949
override fun customizeFor(token: Token) {
5050
// create amount for the bill
5151
val demoAmount = LocalFiat(
@@ -80,6 +80,7 @@ class InternalBillPlaygroundController(
8080
is Event.SelectSlot -> selectSlot(event.slot)
8181
is Event.LoadBackground -> loadBackground(event.background)
8282
Event.Undo -> undoLastChange()
83+
Event.Copy -> copyConfiguration()
8384
}
8485
}
8586

@@ -185,6 +186,18 @@ class InternalBillPlaygroundController(
185186
}
186187
}
187188

189+
private fun copyConfiguration() {
190+
val colors = _state.value.selectedColors.map { it.color }
191+
.map { it.toHex() }
192+
193+
clipboard.setPrimaryClip(
194+
android.content.ClipData.newPlainText(
195+
"",
196+
colors.joinToString()
197+
)
198+
)
199+
}
200+
188201
override fun cancel() {
189202
undoStack.clear()
190203
_state.update { State() }

ui/components/src/main/kotlin/com/getcode/ui/utils/ColorTransformations.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.getcode.ui.utils
22

33
import androidx.compose.ui.graphics.Color
4+
import androidx.compose.ui.graphics.toArgb
45
import androidx.core.graphics.toColorInt
56
import kotlin.math.abs
67
import kotlin.math.roundToInt
@@ -58,6 +59,10 @@ fun Color.value(): Float {
5859
return maxOf(red, green, blue)
5960
}
6061

62+
fun Color.toHex(): String {
63+
return String.format("#%08X", this.toArgb())
64+
}
65+
6166

6267
private fun colorToRgb(color: Color): Rgb {
6368
return Rgb(

0 commit comments

Comments
 (0)