From 5992c4bc8966a8a3b52d687806e71fcf5543d265 Mon Sep 17 00:00:00 2001 From: nostrbuddha Date: Wed, 4 Dec 2024 17:13:06 +0530 Subject: [PATCH] Trade flow screen UI 1/2 --- .../offers/TakeOfferReviewTradeScreen.kt | 173 ++++++++++++++++++ .../drawable/exchange_h_arrow.png | Bin 0 -> 219 bytes .../drawable/exchange_v_arrow.png | Bin 0 -> 197 bytes .../img_bitcoin_payment_confirmation.png | Bin 0 -> 3699 bytes .../drawable/img_bitcoin_payment_waiting.png | Bin 0 -> 9381 bytes .../drawable/img_fiat_payment_waiting.png | Bin 0 -> 7019 bytes .../drawable/svg_exchange_h_arrow.svg | 3 + .../drawable/svg_exchange_v_arrow.svg | 3 + .../composeResources/drawable/svg_star.svg | 3 + .../drawable/svg_up_arrow.svg | 3 + .../composeResources/drawable/up_arrow.png | Bin 0 -> 196 bytes .../presentation/di/PresentationModule.kt | 4 + .../ui/components/atoms/Button.kt | 3 + .../components/atoms/CircularLoadingImage.kt | 39 ++++ .../ui/components/atoms/SvgImages.kt | 5 + .../ui/components/atoms/TextField.kt | 2 +- .../ui/components/atoms/icons/Icons.kt | 15 ++ .../ui/components/molecules/info/InfoBox.kt | 31 +++- .../ui/components/molecules/info/InfoRow.kt | 13 +- .../organisms/trades/StepperSection.kt | 85 +++++++++ .../trades/TradeFlow01AccountDetails.kt | 56 ++++++ .../trades/TradeFlow02FiatPayment.kt | 120 ++++++++++++ .../organisms/trades/TradeFlow03BtcPayment.kt | 79 ++++++++ .../organisms/trades/TradeFlow04Completed.kt | 67 +++++++ .../organisms/trades/TradeHeader.kt | 158 ++++++++++++++++ .../presentation/ui/navigation/Routes.kt | 2 + .../ui/navigation/graph/RootNavGraph.kt | 5 + .../ui/uicases/offers/MarketListPresenter.kt | 3 +- .../offers/takeOffer/ReviewTradeScreen.kt | 3 +- .../ui/uicases/trades/TradeFlowPresenter.kt | 30 +++ .../ui/uicases/trades/TradeFlowScreen.kt | 106 +++++++++++ 31 files changed, 998 insertions(+), 13 deletions(-) create mode 100644 bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/TakeOfferReviewTradeScreen.kt create mode 100644 shared/presentation/src/commonMain/composeResources/drawable/exchange_h_arrow.png create mode 100644 shared/presentation/src/commonMain/composeResources/drawable/exchange_v_arrow.png create mode 100644 shared/presentation/src/commonMain/composeResources/drawable/img_bitcoin_payment_confirmation.png create mode 100644 shared/presentation/src/commonMain/composeResources/drawable/img_bitcoin_payment_waiting.png create mode 100644 shared/presentation/src/commonMain/composeResources/drawable/img_fiat_payment_waiting.png create mode 100644 shared/presentation/src/commonMain/composeResources/drawable/svg_exchange_h_arrow.svg create mode 100644 shared/presentation/src/commonMain/composeResources/drawable/svg_exchange_v_arrow.svg create mode 100644 shared/presentation/src/commonMain/composeResources/drawable/svg_star.svg create mode 100644 shared/presentation/src/commonMain/composeResources/drawable/svg_up_arrow.svg create mode 100644 shared/presentation/src/commonMain/composeResources/drawable/up_arrow.png create mode 100644 shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/CircularLoadingImage.kt create mode 100644 shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/StepperSection.kt create mode 100644 shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow01AccountDetails.kt create mode 100644 shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow02FiatPayment.kt create mode 100644 shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow03BtcPayment.kt create mode 100644 shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow04Completed.kt create mode 100644 shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeHeader.kt create mode 100644 shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/TradeFlowPresenter.kt create mode 100644 shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/TradeFlowScreen.kt diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/TakeOfferReviewTradeScreen.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/TakeOfferReviewTradeScreen.kt new file mode 100644 index 00000000..0c851386 --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/TakeOfferReviewTradeScreen.kt @@ -0,0 +1,173 @@ +package network.bisq.mobile.presentation.ui.uicases.offers + +import androidx.compose.foundation.layout.* +import androidx.compose.material3.HorizontalDivider +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.navigation.NavHostController +import network.bisq.mobile.presentation.ui.components.atoms.BisqButton +import network.bisq.mobile.presentation.ui.components.atoms.BisqText +import network.bisq.mobile.presentation.ui.navigation.Routes +import network.bisq.mobile.presentation.ui.theme.BisqTheme +import org.koin.compose.koinInject +import org.koin.core.qualifier.named + +@Composable +fun TakeOfferReviewTradeScreen() { + val navController: NavHostController = koinInject(named("RootNavController")) + TakeOfferScaffold { + Column(modifier = Modifier.padding(horizontal = 32.dp, vertical = 24.dp)) { + BisqText.h3Regular( + text = "Review trade", + color = BisqTheme.colors.light1 + ) + Spacer(modifier = Modifier.height(32.dp)) + Column( + verticalArrangement = Arrangement.spacedBy(32.dp) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + BisqText.largeRegular( + text = "I WANT TO", + color = BisqTheme.colors.grey2 + ) + BisqText.h5Regular( + text = "BUY Bitcoin" + ) + } + Column( + verticalArrangement = Arrangement.spacedBy(12.dp), + horizontalAlignment = Alignment.End + ) { + BisqText.largeRegular( + text = "FIAT PAYMENT METHOD", + color = BisqTheme.colors.grey2 + ) + BisqText.h5Regular( + text = "Strike" + ) + } + } + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + BisqText.largeRegular( + text = "AMOUNT TO PAY", + color = BisqTheme.colors.grey2 + ) + BisqText.h5Regular( + text = "900.00" + ) + } + Column( + verticalArrangement = Arrangement.spacedBy(12.dp), + horizontalAlignment = Alignment.End + ) { + BisqText.largeRegular( + text = "AMOUNT TO RECEIVE", + color = BisqTheme.colors.grey2 + ) + BisqText.h5Regular( + text = "0.00918367 btc" + ) + } + } + } + HorizontalDivider( + thickness = 1.dp, + modifier = Modifier.padding(vertical = 28.dp), + color = Color(0XFF2B2B2B) + ) + Column( + verticalArrangement = Arrangement.spacedBy(32.dp) + ) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + BisqText.largeRegular( + text = "Trade price", + color = BisqTheme.colors.grey2 + ) + Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { + Row( + verticalAlignment = Alignment.Bottom, + horizontalArrangement = Arrangement.spacedBy(4.dp) + ) { + BisqText.h5Regular( + text = "98,000.68" + ) + BisqText.baseRegular( + text = "BTC/USD", + color = BisqTheme.colors.grey2 + ) + } + BisqText.smallRegular( + text = "Float price 1.00% above market price of 60,000 BTC/USD", + color = BisqTheme.colors.grey4 + ) + } + } + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + BisqText.largeRegular( + text = "Bitcoin settlement method", + color = BisqTheme.colors.grey2 + ) + BisqText.h5Regular( + text = "Lightning" + ) + } + Column( + verticalArrangement = Arrangement.spacedBy(12.dp), + horizontalAlignment = Alignment.End + ) { + BisqText.largeRegular( + text = "Fiat payment", + color = BisqTheme.colors.grey2 + ) + BisqText.h5Regular( + text = "Strike" + ) + } + } + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + BisqText.largeRegular( + text = "Fees", + color = BisqTheme.colors.grey2 + ) + BisqText.h5Regular( + text = "No trade fees in Bisq Easy :-)" + ) + } + } + } + Row( + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier.fillMaxWidth().padding(horizontal = 32.dp) + ) { + BisqButton( + text = "Back", + backgroundColor = BisqTheme.colors.dark5, + onClick = { }, + padding = PaddingValues(horizontal = 64.dp, vertical = 4.dp) + ) + BisqButton( + text = "Next", + onClick = { + navController.navigate(Routes.TradeFlow.name) + }, + padding = PaddingValues(horizontal = 64.dp, vertical = 4.dp) + ) + } + } +} \ No newline at end of file diff --git a/shared/presentation/src/commonMain/composeResources/drawable/exchange_h_arrow.png b/shared/presentation/src/commonMain/composeResources/drawable/exchange_h_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..ec73a7eaca00e4b2b66d5398faac3c4064edfe41 GIT binary patch literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1O%mREuT!HkeRjX#rnl*Fg%o#Ig zKo}4nmxA8-BW(TXl}^_W@?wI^$RjxMRHaX90C k;6+xcw}j*=)p^V1vlcTZe7m3i4`>2|r>mdKI;Vst0AL_jQ~&?~ literal 0 HcmV?d00001 diff --git a/shared/presentation/src/commonMain/composeResources/drawable/exchange_v_arrow.png b/shared/presentation/src/commonMain/composeResources/drawable/exchange_v_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..8f4d5df67abed0895cc7c168a5386f300bd00e8e GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^JRmj;Gmy+@pHv8>bOU@sT!Hk=nKNh1m@$3&bRc8) z?AbszkOTrC7a9Ej|6lPcYc)^nty9C!SD(Lzm`Lsb$}lE*ySwn^ z?=|oTa&$ah978y+Cnq#8svDfF6Y@!2FTxV2WSri#(_%$}fT~5d^bG6mj6N$5@Uk#` XG~~Aa*m0s8sE@(Z)z4*}Q$iB}%#1>- literal 0 HcmV?d00001 diff --git a/shared/presentation/src/commonMain/composeResources/drawable/img_bitcoin_payment_confirmation.png b/shared/presentation/src/commonMain/composeResources/drawable/img_bitcoin_payment_confirmation.png new file mode 100644 index 0000000000000000000000000000000000000000..daeacaa38ca03ceaa68eed9df40ba324d6347d25 GIT binary patch literal 3699 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 literal 0 HcmV?d00001 diff --git a/shared/presentation/src/commonMain/composeResources/drawable/img_fiat_payment_waiting.png b/shared/presentation/src/commonMain/composeResources/drawable/img_fiat_payment_waiting.png new file mode 100644 index 0000000000000000000000000000000000000000..80d7c624727684ab955df8f58fc6fafe524f67f0 GIT binary patch literal 7019 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�sTu@ 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 JPDHLkV1mx^d$Rxl literal 0 HcmV?d00001 diff --git a/shared/presentation/src/commonMain/composeResources/drawable/svg_exchange_h_arrow.svg b/shared/presentation/src/commonMain/composeResources/drawable/svg_exchange_h_arrow.svg new file mode 100644 index 00000000..9e61003e --- /dev/null +++ b/shared/presentation/src/commonMain/composeResources/drawable/svg_exchange_h_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/shared/presentation/src/commonMain/composeResources/drawable/svg_exchange_v_arrow.svg b/shared/presentation/src/commonMain/composeResources/drawable/svg_exchange_v_arrow.svg new file mode 100644 index 00000000..50eafa00 --- /dev/null +++ b/shared/presentation/src/commonMain/composeResources/drawable/svg_exchange_v_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/shared/presentation/src/commonMain/composeResources/drawable/svg_star.svg b/shared/presentation/src/commonMain/composeResources/drawable/svg_star.svg new file mode 100644 index 00000000..0fe9d3a5 --- /dev/null +++ b/shared/presentation/src/commonMain/composeResources/drawable/svg_star.svg @@ -0,0 +1,3 @@ + + + diff --git a/shared/presentation/src/commonMain/composeResources/drawable/svg_up_arrow.svg b/shared/presentation/src/commonMain/composeResources/drawable/svg_up_arrow.svg new file mode 100644 index 00000000..c51a18f5 --- /dev/null +++ b/shared/presentation/src/commonMain/composeResources/drawable/svg_up_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/shared/presentation/src/commonMain/composeResources/drawable/up_arrow.png b/shared/presentation/src/commonMain/composeResources/drawable/up_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..222eda69eb98b6e711515415b5ff173df4a4c0c9 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^53NZ z5RcBc=MA|I1qirayup!ojF+QK?4sK56G|)x4>=`0jO)F+QSyVhQpUanL-A!*himsN z^PKc#zeE4O@K1}?pU-+E*(PxR@q-ZWI?X4t+a%QWIe(hED3`fj^Nni?<;cs3f0BCg s)9fZzzKH!lZzlBrJkIJl>B?h9t%8Ntn_T}Z0v*BN>FVdQ&MBb@0MV^XSpWb4 literal 0 HcmV?d00001 diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/di/PresentationModule.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/di/PresentationModule.kt index e264d994..66662bd6 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/di/PresentationModule.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/di/PresentationModule.kt @@ -20,7 +20,9 @@ import network.bisq.mobile.presentation.ui.uicases.startup.OnBoardingPresenter import network.bisq.mobile.presentation.ui.uicases.startup.SplashPresenter import network.bisq.mobile.presentation.ui.uicases.startup.TrustedNodeSetupPresenter import network.bisq.mobile.presentation.ui.uicases.trades.IMyTrades +import network.bisq.mobile.presentation.ui.uicases.trades.ITradeFlowPresenter import network.bisq.mobile.presentation.ui.uicases.trades.MyTradesPresenter +import network.bisq.mobile.presentation.ui.uicases.trades.TradeFlowPresenter import org.koin.core.qualifier.named import org.koin.dsl.bind import org.koin.dsl.module @@ -83,4 +85,6 @@ val presentationModule = module { myTradesRepository = get() ) } bind IMyTrades::class + + single{ TradeFlowPresenter(get(), get()) } bind ITradeFlowPresenter::class } \ No newline at end of file diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/Button.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/Button.kt index 82d44753..f31adab6 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/Button.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/Button.kt @@ -1,5 +1,6 @@ package network.bisq.mobile.presentation.ui.components.atoms +import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Button @@ -30,6 +31,7 @@ fun BisqButton( modifier: Modifier = Modifier, cornerRadius: Dp = 8.dp, disabled: Boolean = false, + border: BorderStroke? = null ) { Button( @@ -42,6 +44,7 @@ fun BisqButton( disabledContentColor = color), shape = RoundedCornerShape(cornerRadius), enabled = !disabled, + border = border ) { if (iconOnly == null && text == null) { BisqText.baseMedium("Error: Pass either text or icon") diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/CircularLoadingImage.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/CircularLoadingImage.kt new file mode 100644 index 00000000..9fc5f911 --- /dev/null +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/CircularLoadingImage.kt @@ -0,0 +1,39 @@ +package network.bisq.mobile.presentation.ui.components.atoms + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import network.bisq.mobile.presentation.ui.theme.BisqTheme +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.painterResource + +@Composable +fun CircularLoadingImage( + image: DrawableResource, + isLoading: Boolean +) { + Box( + contentAlignment = Alignment.Center + ) { + Image( + painterResource(image), "", + modifier = Modifier.height(36.dp).width(30.dp) + ) + if (isLoading) { + CircularProgressIndicator( + modifier = Modifier + .align(Alignment.Center) + .size(60.dp), + color = BisqTheme.colors.primaryDisabled, + strokeWidth = 2.dp + ) + } + } +} \ No newline at end of file diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/SvgImages.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/SvgImages.kt index b5f65be4..ffb53b0d 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/SvgImages.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/SvgImages.kt @@ -24,5 +24,10 @@ fun SvgImage( } object SvgImageNames { + const val BACK_BUTTON = "svg_back_button.svg" + const val STAR = "svg_star.svg" const val INFO = "svg_info.svg" + const val EXCHANGE_VERTICAL_ARROW = "svg_exchange_v_arrow.svg" + const val EXCHANGE_HORIZONTAL_ARROW = "svg_exchange_h_arrow.svg" + const val UP_ARROW = "svg_up_arrow.svg" } \ No newline at end of file diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/TextField.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/TextField.kt index fa7c62bb..4653d500 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/TextField.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/TextField.kt @@ -26,7 +26,7 @@ fun BisqTextField( label: String, value: String, onValueChanged: (String) -> Unit, - placeholder: String?, + placeholder: String? = null, labelRightSuffix: (@Composable () -> Unit)? = null, modifier: Modifier = Modifier, ) { diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/icons/Icons.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/icons/Icons.kt index 53654031..5dfe2abc 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/icons/Icons.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/icons/Icons.kt @@ -28,6 +28,16 @@ fun CopyIcon(modifier: Modifier = Modifier) { Image(painterResource(Res.drawable.icon_copy), "Copy icon", modifier = modifier) } +@Composable +fun SwapHArrowIcon(modifier: Modifier = Modifier.size(16.dp)) { + Image(painterResource(Res.drawable.exchange_h_arrow), "Swap horizontal icon", modifier = modifier) +} + +@Composable +fun SwapVArrowIcon(modifier: Modifier = Modifier.size(16.dp)) { + Image(painterResource(Res.drawable.exchange_v_arrow), "Swap vertical icon", modifier = modifier) +} + @Composable fun QuestionIcon(modifier: Modifier = Modifier) { Image(painterResource(Res.drawable.icon_question_mark), "Question icon", modifier = modifier) @@ -54,6 +64,11 @@ fun StarFillIcon(modifier: Modifier = Modifier.size(16.dp)) { Image(painterResource(Res.drawable.icon_star), "Filled star icon", modifier = modifier) } +@Composable +fun UpIcon(modifier: Modifier = Modifier.size(30.dp)) { + Image(painterResource(Res.drawable.up_arrow), "Up icon", modifier = modifier) +} + @Composable fun UserIcon(platformImage: PlatformImage?, modifier: Modifier = Modifier) { if (platformImage == null) { diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/info/InfoBox.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/info/InfoBox.kt index f28a19f9..a0963605 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/info/InfoBox.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/info/InfoBox.kt @@ -1,4 +1,4 @@ -package network.bisq.mobile.presentation.ui.components.atoms.text +package network.bisq.mobile.presentation.ui.components.molecules.info import androidx.compose.foundation.layout.* import androidx.compose.runtime.Composable @@ -13,6 +13,11 @@ enum class InfoBoxValueType { TitleSmall, } +enum class InfoBoxStyle { + Style1, // Label on top, value below + Style2 // Value on top, label below +} + @Composable fun InfoBox( label: String, @@ -20,6 +25,7 @@ fun InfoBox( valueComposable: (@Composable () -> Unit)? = null, rightAlign: Boolean = false, valueType: InfoBoxValueType = InfoBoxValueType.BoldValue, + style: InfoBoxStyle = InfoBoxStyle.Style1, ) { val valueWidget: @Composable () -> Unit = if (value != null) { @@ -40,6 +46,28 @@ fun InfoBox( } } + when (style) { + InfoBoxStyle.Style1 -> { + Column( + horizontalAlignment = if (rightAlign) Alignment.End else Alignment.Start, + verticalArrangement = Arrangement.spacedBy(2.dp) + ) { + BisqText.baseRegular(text = label, color = BisqTheme.colors.grey2) + valueWidget() + } + } + InfoBoxStyle.Style2 -> { + Column( + horizontalAlignment = if (rightAlign) Alignment.End else Alignment.Start, + verticalArrangement = Arrangement.spacedBy(2.dp) + ) { + valueWidget() + BisqText.baseRegular(text = label, color = BisqTheme.colors.grey2) + } + } + } + + /* Column( horizontalAlignment = if (rightAlign) Alignment.End else Alignment.Start, verticalArrangement = Arrangement.spacedBy(2.dp) @@ -47,4 +75,5 @@ fun InfoBox( BisqText.baseRegular(text = label, color = BisqTheme.colors.grey2) valueWidget() } + */ } diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/info/InfoRow.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/info/InfoRow.kt index e35a29ac..0152e0dc 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/info/InfoRow.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/info/InfoRow.kt @@ -2,13 +2,7 @@ package network.bisq.mobile.presentation.ui.components.molecules.info import androidx.compose.foundation.layout.* import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import network.bisq.mobile.presentation.ui.components.atoms.BisqText -import network.bisq.mobile.presentation.ui.components.atoms.text.InfoBox -import network.bisq.mobile.presentation.ui.components.atoms.text.InfoBoxValueType -import network.bisq.mobile.presentation.ui.theme.BisqTheme @Composable fun InfoRow( @@ -17,6 +11,7 @@ fun InfoRow( label2: String, value2: String, valueType: InfoBoxValueType = InfoBoxValueType.BoldValue, + style: InfoBoxStyle = InfoBoxStyle.Style1, ) { Row( modifier = Modifier.fillMaxWidth(), @@ -25,13 +20,15 @@ fun InfoRow( InfoBox( label = label1, value = value1, - valueType = valueType + valueType = valueType, + style = style, ) InfoBox( label = label2, value = value2, valueType = valueType, - rightAlign = true + rightAlign = true, + style = style, ) } } \ No newline at end of file diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/StepperSection.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/StepperSection.kt new file mode 100644 index 00000000..8a31013a --- /dev/null +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/StepperSection.kt @@ -0,0 +1,85 @@ +package network.bisq.mobile.presentation.ui.components.organisms.trades + +import androidx.compose.animation.* +import androidx.compose.foundation.layout.* +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import network.bisq.mobile.presentation.ui.components.atoms.BisqText +import network.bisq.mobile.presentation.ui.theme.BisqTheme + +@Composable +fun StepperSection( + stepNumber: Int = 0, + isActive: Boolean = false, + isLastIndex: Boolean = false, + contentStartOffset: Dp = 32.dp, + spacerBetweenNodes: Dp = 32.dp, + content: @Composable BoxScope.(modifier: Modifier) -> Unit +) { + val lineColor = BisqTheme.colors.dark5 + Box( + modifier = Modifier.wrapContentSize().drawBehind { + drawLine( + color = lineColor, + start = Offset(x = 12.dp.toPx(), y = 12.dp.toPx() * 2), + end = Offset(x = 12.dp.toPx(), y = this.size.height), + strokeWidth = 1.dp.toPx() + ) + + } + ) { + val primary = BisqTheme.colors.primary + Box( + modifier = Modifier.wrapContentSize().drawBehind { + if (isActive) { + drawCircle( + color = lineColor, + radius = 12.dp.toPx(), + center = Offset(12.dp.toPx(), 12.dp.toPx()), + ) + drawCircle( + color = primary, + radius = 8.dp.toPx(), + center = Offset(12.dp.toPx(), 12.dp.toPx()), + ) + drawCircle( + color = primary, + radius = 12.dp.toPx(), + center = Offset(12.dp.toPx(), 12.dp.toPx()), + style = Stroke(width = 1.dp.toPx()) + ) + } else { + drawCircle( + color = lineColor, + radius = 12.dp.toPx(), + center = Offset(12.dp.toPx(), 12.dp.toPx()), + ) + } + + }) { + + BisqText.xsmallRegular( + textAlign = TextAlign.Center, + text = stepNumber.toString(), + modifier = Modifier.padding(start = 8.dp) + ) + } + content( + Modifier + .padding( + start = contentStartOffset, + bottom = if (isLastIndex) { + 0.dp + } else { + spacerBetweenNodes + } + ) + ) + } +} diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow01AccountDetails.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow01AccountDetails.kt new file mode 100644 index 00000000..ea09538c --- /dev/null +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow01AccountDetails.kt @@ -0,0 +1,56 @@ +package network.bisq.mobile.presentation.ui.components.organisms.trades + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import network.bisq.mobile.presentation.ui.components.atoms.BisqButton +import network.bisq.mobile.presentation.ui.components.atoms.BisqText +import network.bisq.mobile.presentation.ui.components.atoms.BisqTextField +import network.bisq.mobile.presentation.ui.theme.BisqTheme + +@Composable +fun TradeFlow01AccountDetails( + onNext: () -> Unit +) { + Column { + BisqText.smallRegular( + text = "Waiting for the seller to provide their account information. Meanwhile you can provide your settlement details." + ) + BisqText.h6Regular( + text = "Fill in your Lightning invoice" + ) + BisqTextField( + placeholder = "", + value = "lncb21h345t34io", + onValueChanged = {}, + label = "Lightning Invoice" + ) + BisqButton( + text = "Send to seller", + onClick = onNext, + padding = PaddingValues( + horizontal = 18.dp, + vertical = 6.dp + ) + ) + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + BisqText.xsmallMedium( + text = "If you don’t have a wallet yet, refer to our" + ) + BisqText.xsmallMedium( + text = "Wallet guide", + modifier = Modifier.clip(shape = RoundedCornerShape(4.dp)) + .background(color = BisqTheme.colors.primary) + .padding(vertical = 2.dp, horizontal = 8.dp) + ) + } + } +} \ No newline at end of file diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow02FiatPayment.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow02FiatPayment.kt new file mode 100644 index 00000000..972baa4a --- /dev/null +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow02FiatPayment.kt @@ -0,0 +1,120 @@ +package network.bisq.mobile.presentation.ui.components.organisms.trades + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import bisqapps.shared.presentation.generated.resources.Res +import bisqapps.shared.presentation.generated.resources.img_fiat_payment_waiting +import kotlinx.coroutines.delay +import network.bisq.mobile.presentation.ui.components.atoms.BisqButton +import network.bisq.mobile.presentation.ui.components.atoms.BisqText +import network.bisq.mobile.presentation.ui.components.atoms.BisqTextField +import network.bisq.mobile.presentation.ui.components.atoms.CircularLoadingImage +import network.bisq.mobile.presentation.ui.theme.BisqTheme + +@Composable +fun TradeFlow02FiatPayment( + onNext: () -> Unit +) { + var isLoading by remember { mutableStateOf(false) } + + if (!isLoading) { + Column { + BisqText.h6Regular( + text = "Send 10000.02 USD to the seller’s payment account" + ) + BisqTextField( + value = "10000.02 USD", + onValueChanged = {}, + label = "Amount to transfer", + placeholder = "" + ) + BisqTextField( + value = "someone@zelle.com", + onValueChanged = {}, + label = "Payment account of seller", + placeholder = "" + ) + BisqText.smallRegular( + text = "Please leave the ‘Reason for payment’ field empty, in case you make a bank transfer", + color = BisqTheme.colors.grey1 + ) + BisqButton( + text = "Confirm payment of 10000.02 USD", + onClick = { + isLoading = true + }, + padding = PaddingValues( + horizontal = 18.dp, + vertical = 6.dp + ) + ) + } + } else { + LaunchedEffect(Unit) { + delay(3000) + isLoading = false + onNext() + } + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + CircularLoadingImage( + image = Res.drawable.img_fiat_payment_waiting, + isLoading = isLoading + ) + + Column( + verticalArrangement = Arrangement.spacedBy( + 12.dp + ) + ) { + BisqText.h6Regular( + text = "Waiting for the seller to confirm receipt of payment" + ) + BisqText.smallRegular( + text = "Once the seller has received the payment of 10000.02 USD, they will start the Bitcoin transfer to your provided Lightning invoice.", + color = BisqTheme.colors.grey1 + ) + } + } + } + + /* + Column { + BisqText.h6Regular( + text = "Send 10000.02 USD to the seller’s payment account" + ) + BisqTextField( + value = "10000.02 USD", + onValueChanged = {}, + label = "Amount to transfer", + placeholder = "" + ) + BisqTextField( + value = "someone@zelle.com", + onValueChanged = {}, + label = "Payment account of seller", + placeholder = "" + ) + BisqText.smallRegular( + text = "Please leave the ‘Reason for payment’ field empty, in case you make a bank transfer", + color = BisqTheme.colors.grey1 + ) + BisqButton( + text = "Confirm payment of 10000.02 USD", + onClick = onNext, + padding = PaddingValues( + horizontal = 18.dp, + vertical = 6.dp + ) + ) + } + */ +} \ No newline at end of file diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow03BtcPayment.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow03BtcPayment.kt new file mode 100644 index 00000000..72c703fe --- /dev/null +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow03BtcPayment.kt @@ -0,0 +1,79 @@ +package network.bisq.mobile.presentation.ui.components.organisms.trades +import androidx.compose.foundation.layout.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.unit.dp +import bisqapps.shared.presentation.generated.resources.Res +import bisqapps.shared.presentation.generated.resources.img_bitcoin_payment_confirmation +import bisqapps.shared.presentation.generated.resources.img_bitcoin_payment_waiting +import kotlinx.coroutines.delay +import network.bisq.mobile.presentation.ui.components.atoms.BisqButton +import network.bisq.mobile.presentation.ui.components.atoms.BisqText +import network.bisq.mobile.presentation.ui.components.atoms.CircularLoadingImage +import network.bisq.mobile.presentation.ui.theme.BisqTheme + +@Composable +fun TradeFlow03BtcPayment( + onNext: () -> Unit +) { + var isLoading by remember { mutableStateOf(true) } + LaunchedEffect(Unit) { + delay(3000) + isLoading = false + } + if (isLoading) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + CircularLoadingImage( + image = Res.drawable.img_bitcoin_payment_waiting, + isLoading = isLoading + ) + + Column( + verticalArrangement = Arrangement.spacedBy( + 12.dp + ) + ) { + BisqText.h6Regular( + text = "Waiting for the seller’s Bitcoin settlement" + ) + BisqText.smallRegular( + text = "The seller need to start the Bitcoin transfer to your provided Lightning invoice.", + color = BisqTheme.colors.grey1 + ) + } + } + } else { + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + CircularLoadingImage( + image = Res.drawable.img_bitcoin_payment_confirmation, + isLoading = !isLoading + ) + + Column( + verticalArrangement = Arrangement.spacedBy( + 12.dp + ) + ) { + BisqText.h6Regular( + text = "The seller has sent the Bitcoin via Lightning network" + ) + BisqText.smallRegular( + text = "Transfers via the Lightning Network are typically near-instant. If you haven't received the payment within one minute, please contact the seller in the trade. Occasionally, payments may fail and need to be retried.", + color = BisqTheme.colors.grey1 + ) + BisqButton( + text = "Confirm receipt", + onClick = onNext, + padding = PaddingValues(horizontal = 18.dp, 6.dp) + ) + } + } + } +} diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow04Completed.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow04Completed.kt new file mode 100644 index 00000000..0c137b7f --- /dev/null +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeFlow04Completed.kt @@ -0,0 +1,67 @@ +package network.bisq.mobile.presentation.ui.components.organisms.trades + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import network.bisq.mobile.presentation.ui.components.atoms.BisqButton +import network.bisq.mobile.presentation.ui.components.atoms.BisqText +import network.bisq.mobile.presentation.ui.components.atoms.BisqTextField +import network.bisq.mobile.presentation.ui.theme.BisqTheme + +@Composable +fun TradeFlow04Completed( + onNext: () -> Unit +){ + Column { + BisqText.h6Regular( + text = "Trade was successfully completed" + ) + BisqTextField( + value = "10000.02 USD", + onValueChanged = {}, + label = "You have received" + ) + BisqTextField( + value = "0.00173399 BTC", + onValueChanged = {}, + label = "You have sold" + ) + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + BisqButton( + text = "Close trade", + color = BisqTheme.colors.primary, + onClick = onNext, + backgroundColor = BisqTheme.colors.dark5, + border = BorderStroke( + width = 2.dp, + color = BisqTheme.colors.primary + ), + padding = PaddingValues( + horizontal = 18.dp, + vertical = 6.dp + ) + ) + BisqButton( + text = "Explore trade data", + color = BisqTheme.colors.light1, + onClick = {}, + backgroundColor = BisqTheme.colors.dark5, + padding = PaddingValues( + horizontal = 18.dp, + vertical = 6.dp + ) + ) + } + } +} \ No newline at end of file diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeHeader.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeHeader.kt new file mode 100644 index 00000000..6cbb4ae1 --- /dev/null +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/trades/TradeHeader.kt @@ -0,0 +1,158 @@ +package network.bisq.mobile.presentation.ui.components.organisms.trades + +import androidx.compose.animation.* +import androidx.compose.animation.core.MutableTransitionState +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.rememberTransition +import androidx.compose.animation.core.tween +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.IconButton +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.rotate +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import bisqapps.shared.presentation.generated.resources.Res +import bisqapps.shared.presentation.generated.resources.img_bitcoin_payment_confirmation +import bisqapps.shared.presentation.generated.resources.img_bitcoin_payment_waiting +import kotlinx.coroutines.delay +import network.bisq.mobile.domain.data.model.OfferListItem +import network.bisq.mobile.presentation.ui.components.atoms.BisqButton +import network.bisq.mobile.presentation.ui.components.atoms.BisqText +import network.bisq.mobile.presentation.ui.components.atoms.CircularLoadingImage +import network.bisq.mobile.presentation.ui.components.atoms.ProfileRating +import network.bisq.mobile.presentation.ui.components.atoms.icons.SwapHArrowIcon +import network.bisq.mobile.presentation.ui.components.atoms.icons.UpIcon +import network.bisq.mobile.presentation.ui.components.molecules.info.InfoBoxStyle +import network.bisq.mobile.presentation.ui.components.molecules.info.InfoRow +import network.bisq.mobile.presentation.ui.theme.BisqTheme +import network.bisq.mobile.presentation.ui.theme.BisqUIConstants + +@Composable +fun TradeHeader( + offer: OfferListItem, +) { + + val enterTransition = remember { + expandVertically( + expandFrom = Alignment.Top, + animationSpec = tween(300) + ) + fadeIn( + initialAlpha = 0.3f, + animationSpec = tween(300) + ) + } + val exitTransition = remember { + shrinkVertically( + shrinkTowards = Alignment.Top, + animationSpec = tween(300) + ) + fadeOut( + animationSpec = tween(300) + ) + } + var visible by remember { mutableStateOf(false) } + + val transitionState = remember { + MutableTransitionState(visible).apply { + targetState = !visible + } + } + val transition = rememberTransition(transitionState) + val arrowRotationDegree by transition.animateFloat({ + tween(durationMillis = 300) + }) { + if (visible) 0f else 180f + } + + Row(modifier = Modifier.clip(shape = RoundedCornerShape(12.dp))) { + Column( + modifier = Modifier.fillMaxWidth() + .background(color = BisqTheme.colors.dark5) + .padding(12.dp), + verticalArrangement = Arrangement.spacedBy(12.dp) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + ProfileRating(offer) + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + BisqText.xsmallRegular(text = "10000.02 USD") + SwapHArrowIcon() + BisqText.xsmallRegular(text = "0.00173399 BTC") + } + } + AnimatedVisibility( + visible = visible, + enter = enterTransition, + exit = exitTransition + ) { + Column { + + InfoRow( + style = InfoBoxStyle.Style2, + label1 = "Trade ID", + value1 = "07b9bab1", + label2 = "Date", + value2 = "29 Sep 2024", + ) + + Spacer(modifier = Modifier.height(BisqUIConstants.ScreenPadding)) + + InfoRow( + style = InfoBoxStyle.Style2, + label1 = "Floating percentage", + value1 = "1.71%", + label2 = "Price", + value2 = "9567056.04 USD/BTC", + ) + + Spacer(modifier = Modifier.height(BisqUIConstants.ScreenPadding)) + + InfoRow( + style = InfoBoxStyle.Style2, + label1 = "Payment method", + value1 = "CashApp", + label2 = "Settlement method", + value2 = "Lightning", + ) + + } + } + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + BisqButton( + text = "Cancel Trade", + color = BisqTheme.colors.primary, + onClick = {}, + backgroundColor = Color.Transparent, + padding = PaddingValues(horizontal = 70.dp, vertical = 6.dp) + ) + IconButton( + onClick = { + visible = !visible + } + ) { + UpIcon( + modifier = Modifier + .size(24.dp) + .clip(shape = RoundedCornerShape(12.dp)) + .rotate(arrowRotationDegree) + .background(color = BisqTheme.colors.primary) + ) + } + } + } + } +} diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/Routes.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/Routes.kt index bfebd9de..643ce069 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/Routes.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/Routes.kt @@ -20,4 +20,6 @@ enum class Routes(val title: String) { TakeOfferTradeAmount(title = "take_offer_trade_amount"), TakeOfferPaymentMethod(title = "take_offer_payment_method"), TakeOfferReviewTrade(title = "take_offer_review_trade"), + + TradeFlow(title = "trade_flow"), } \ No newline at end of file diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/graph/RootNavGraph.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/graph/RootNavGraph.kt index 49cedd61..63bbb003 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/graph/RootNavGraph.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/graph/RootNavGraph.kt @@ -20,6 +20,7 @@ import network.bisq.mobile.presentation.ui.uicases.startup.CreateProfileScreen import network.bisq.mobile.presentation.ui.uicases.startup.OnBoardingScreen import network.bisq.mobile.presentation.ui.uicases.startup.SplashScreen import network.bisq.mobile.presentation.ui.uicases.startup.TrustedNodeSetupScreen +import network.bisq.mobile.presentation.ui.uicases.trades.TradeFlowScreen import org.koin.compose.koinInject import org.koin.core.qualifier.named @@ -68,6 +69,10 @@ fun RootNavGraph() { TakeOfferReviewTradeScreen() } + addScreen(Routes.TradeFlow.name) { + TradeFlowScreen() + } + } } diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/MarketListPresenter.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/MarketListPresenter.kt index 4a47bbef..8c536d84 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/MarketListPresenter.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/MarketListPresenter.kt @@ -27,7 +27,8 @@ class MarketListPresenter( fun onSelectMarket(marketListItem: MarketListItem) { offerbookServiceFacade.selectMarket(marketListItem) - rootNavigator.navigate(Routes.OfferList.name) + // rootNavigator.navigate(Routes.OfferList.name) + rootNavigator.navigate(Routes.TradeFlow.name) } override fun onViewAttached() { diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/takeOffer/ReviewTradeScreen.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/takeOffer/ReviewTradeScreen.kt index f6950f31..0c10e37d 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/takeOffer/ReviewTradeScreen.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/takeOffer/ReviewTradeScreen.kt @@ -12,10 +12,9 @@ import network.bisq.mobile.domain.data.model.OfferListItem import network.bisq.mobile.presentation.ViewPresenter import network.bisq.mobile.presentation.ui.components.atoms.BisqHDivider import network.bisq.mobile.presentation.ui.components.atoms.BisqText -import network.bisq.mobile.presentation.ui.components.atoms.text.InfoBox -import network.bisq.mobile.presentation.ui.components.layout.BisqScrollLayout import network.bisq.mobile.presentation.ui.theme.BisqTheme import network.bisq.mobile.presentation.ui.components.layout.MultiScreenWizardScaffold +import network.bisq.mobile.presentation.ui.components.molecules.info.InfoBox import network.bisq.mobile.presentation.ui.components.molecules.info.InfoRow import network.bisq.mobile.presentation.ui.theme.BisqUIConstants import org.koin.compose.koinInject diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/TradeFlowPresenter.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/TradeFlowPresenter.kt new file mode 100644 index 00000000..f1c6c4c4 --- /dev/null +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/TradeFlowPresenter.kt @@ -0,0 +1,30 @@ +package network.bisq.mobile.presentation.ui.uicases.trades + +import kotlinx.coroutines.flow.StateFlow +import network.bisq.mobile.domain.data.model.OfferListItem +import network.bisq.mobile.domain.service.offerbook.OfferbookServiceFacade +import network.bisq.mobile.presentation.BasePresenter +import network.bisq.mobile.presentation.MainPresenter +import network.bisq.mobile.presentation.ui.navigation.Routes + +// TODO: Should do Interface for this? +open class TradeFlowPresenter( + mainPresenter: MainPresenter, + private val offerbookServiceFacade: OfferbookServiceFacade, +) : BasePresenter(mainPresenter), ITradeFlowPresenter { + + override val offerListItems: StateFlow> = offerbookServiceFacade.offerListItems + + override val steps = listOf( + TradeFlowScreenSteps.ACCOUNT_DETAILS.title, + TradeFlowScreenSteps.FIAT_PAYMENT.title, + TradeFlowScreenSteps.BITCOIN_TRANSFER.title, + TradeFlowScreenSteps.TRADE_COMPLETED.title + ) + + override fun onViewAttached() { + } + + override fun onViewUnattaching() { + } +} diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/TradeFlowScreen.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/TradeFlowScreen.kt new file mode 100644 index 00000000..5f5653f6 --- /dev/null +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/TradeFlowScreen.kt @@ -0,0 +1,106 @@ +package network.bisq.mobile.presentation.ui.uicases.trades + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.* +import androidx.compose.foundation.layout.* +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import cafe.adriel.lyricist.LocalStrings +import kotlinx.coroutines.flow.StateFlow +import network.bisq.mobile.domain.data.model.OfferListItem +import network.bisq.mobile.presentation.ViewPresenter +import network.bisq.mobile.presentation.ui.components.atoms.* +import network.bisq.mobile.presentation.ui.components.layout.BisqStaticScaffold +import network.bisq.mobile.presentation.ui.components.molecules.TopBar +import network.bisq.mobile.presentation.ui.components.organisms.trades.* +import network.bisq.mobile.presentation.ui.theme.BisqTheme +import network.bisq.mobile.presentation.ui.theme.BisqUIConstants +import org.koin.compose.koinInject + +enum class TradeFlowScreenSteps(val title: String) { + ACCOUNT_DETAILS(title = "ACCOUNT DETAILS"), + FIAT_PAYMENT(title = "FIAT PAYMENT"), + BITCOIN_TRANSFER(title = "BITCOIN TRANSFER"), + TRADE_COMPLETED(title = "TRADE COMPLETED") +} + +interface ITradeFlowPresenter : ViewPresenter { + // TODO: Update later to refer to a single state specific object + val offerListItems: StateFlow> + + val steps: List +} + +@Composable +fun TradeFlowScreen() { + val strings = LocalStrings.current.bisqEasy + val presenter: ITradeFlowPresenter = koinInject() + + val offer = presenter.offerListItems.collectAsState().value.first() + + BisqStaticScaffold( + topBar = { TopBar("Trade - 07b9bab1") } + ) { + + Column( + modifier = Modifier + .verticalScroll(rememberScrollState()) + .fillMaxSize() + ) { + + TradeHeader(offer) + + Spacer(modifier = Modifier.height(BisqUIConstants.ScreenPadding)) + + TradeFlowStepper() + + } + } +} + +@Composable +fun TradeFlowStepper() { + val presenter: ITradeFlowPresenter = koinInject() + var expandedStep by remember { mutableStateOf(0) } + + Column( + modifier = Modifier.fillMaxWidth() + ) { + presenter.steps.forEachIndexed { index, step -> + StepperSection( + stepNumber = index + 1, + isActive = expandedStep == index, + isLastIndex = index == step.lastIndex, + ) { modifier -> + Column(modifier = modifier) { + BisqText.baseRegular( + text = step, + color = if (expandedStep == index) BisqTheme.colors.light1 else BisqTheme.colors.grey2, + ) + + AnimatedVisibility( + visible = expandedStep == index, + ) { + when (step) { + TradeFlowScreenSteps.ACCOUNT_DETAILS.title -> { + TradeFlow01AccountDetails(onNext = { expandedStep += 1 }) + } + + TradeFlowScreenSteps.FIAT_PAYMENT.title -> { + TradeFlow02FiatPayment(onNext = { expandedStep += 1 }) + } + + TradeFlowScreenSteps.BITCOIN_TRANSFER.title -> { + TradeFlow03BtcPayment(onNext = { expandedStep += 1 }) + } + + TradeFlowScreenSteps.TRADE_COMPLETED.title -> { + TradeFlow04Completed(onNext = { expandedStep += 1 }) + } + } + } + } + } + } + } +}