diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/AmountSelector.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/AmountSelector.kt index dcf2d558..a90c71ef 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/AmountSelector.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/AmountSelector.kt @@ -15,7 +15,13 @@ import network.bisq.mobile.presentation.ui.components.atoms.BisqSlider import network.bisq.mobile.presentation.ui.components.atoms.BisqText import network.bisq.mobile.presentation.ui.components.atoms.BtcSatsText import network.bisq.mobile.presentation.ui.theme.BisqTheme +import network.bisq.mobile.presentation.ui.theme.BisqUIConstants +// ToDiscuss: +// buddha: Ideally this component should deal only with Fiat values (as Double) and have one valueChange() event +// so `initialSliderPosition` will become `defaultValue`, +// which will be some value between `formattedMinAmount` and `formattedMaxAmount` +// onSliderValueChange() / onTextValueChange() will become onValueChange(value: Double) -> Unit @Composable fun BisqAmountSelector( fiatCurrencyCode: String, @@ -48,7 +54,7 @@ fun BisqAmountSelector( Column( modifier = Modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(BisqUIConstants.ScreenPadding), horizontalAlignment = Alignment.CenterHorizontally ) { diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offer/create_offer/CreateOfferPaymentMethodScreen.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offer/create_offer/CreateOfferPaymentMethodScreen.kt index 96feece2..4f4e4d9a 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offer/create_offer/CreateOfferPaymentMethodScreen.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offer/create_offer/CreateOfferPaymentMethodScreen.kt @@ -37,7 +37,7 @@ fun CreateOfferPaymentMethodSelectorScreen() { color = BisqTheme.colors.light1 ) - BisqGap.V1() + BisqGap.V2() PaymentMethodCard( title = presenter.quoteSideHeadline, diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferAmountScreen.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferAmountScreen.kt index acb7e259..700c5282 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferAmountScreen.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferAmountScreen.kt @@ -1,7 +1,6 @@ package network.bisq.mobile.presentation.ui.uicases.trade.take_offer -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.* import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @@ -25,7 +24,8 @@ fun TakeOfferTradeAmountScreen() { stepIndex = 1, stepsLength = 3, prevOnClick = { presenter.onBack() }, - nextOnClick = { presenter.onNext() } + nextOnClick = { presenter.onNext() }, + useStaticScaffold = true ) { BisqText.h3Regular( text = strings.bisqEasy_takeOffer_amount_headline_buyer, @@ -41,17 +41,20 @@ fun TakeOfferTradeAmountScreen() { color = BisqTheme.colors.grey2 ) - Spacer(modifier = Modifier.height(128.dp)) - - BisqAmountSelector( - presenter.quoteCurrencyCode, - presenter.formattedMinAmountWithCode, - presenter.formattedMaxAmountWithCode, - presenter.sliderPosition, - presenter.formattedQuoteAmount, - presenter.formattedBaseAmount, - { sliderValue -> presenter.onSliderValueChanged(sliderValue) }, - { textInput -> presenter.onTextValueChanged(textInput) } - ) + Column( + modifier = Modifier.fillMaxHeight(), + verticalArrangement = Arrangement.Center, + ) { + BisqAmountSelector( + presenter.quoteCurrencyCode, + presenter.formattedMinAmountWithCode, + presenter.formattedMaxAmountWithCode, + presenter.sliderPosition, + presenter.formattedQuoteAmount, + presenter.formattedBaseAmount, + { sliderValue -> presenter.onSliderValueChanged(sliderValue) }, + { textInput -> presenter.onTextValueChanged(textInput) } + ) + } } } \ No newline at end of file diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferPaymentMethodPresenter.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferPaymentMethodPresenter.kt index d3f69cc8..4ad218e9 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferPaymentMethodPresenter.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferPaymentMethodPresenter.kt @@ -1,5 +1,6 @@ package network.bisq.mobile.presentation.ui.uicases.trade.take_offer +import kotlinx.coroutines.flow.MutableStateFlow import network.bisq.mobile.presentation.BasePresenter import network.bisq.mobile.presentation.MainPresenter import network.bisq.mobile.presentation.ui.navigation.Routes @@ -15,6 +16,7 @@ class TakeOfferPaymentMethodPresenter( lateinit var baseSidePaymentMethods: List var quoteSidePaymentMethod: String? = null var baseSidePaymentMethod: String? = null + var quoteCurrencyCode: String = "USD" private lateinit var takeOfferModel: TakeOfferPresenter.TakeOfferModel @@ -32,6 +34,8 @@ class TakeOfferPaymentMethodPresenter( if (offerListItem.baseSidePaymentMethods.size == 1) { baseSidePaymentMethod = offerListItem.baseSidePaymentMethods[0] } + + quoteCurrencyCode = takeOfferModel.priceQuote.market.quoteCurrencyCode } fun onQuoteSidePaymentMethodSelected(paymentMethod: String) { @@ -72,4 +76,29 @@ class TakeOfferPaymentMethodPresenter( } private fun isValid() = quoteSidePaymentMethod != null && baseSidePaymentMethod != null + + fun getPaymentMethodAsSet(paymentMethod: String?): MutableStateFlow> { + return if (paymentMethod == null) + MutableStateFlow(emptySet()) + else { + MutableStateFlow(setOf(paymentMethod)) + } + } + + fun getQuoteSidePaymentMethodsImagePaths(): List { + return quoteSidePaymentMethods.map { payment -> + getPaymentMethodImagePath(payment, "fiat") + } + } + + fun getBaseSidePaymentMethodsImagePaths(): List { + return baseSidePaymentMethods.map { payment -> + getPaymentMethodImagePath(payment, "bitcoin") + } + } + + private fun getPaymentMethodImagePath(paymentMethod: String, directory: String): String { + val fileName = paymentMethod.lowercase().replace("-", "_") + return "drawable/payment/$directory/$fileName.png" + } } diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferPaymentMethodScreen.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferPaymentMethodScreen.kt index 13026200..35ceccae 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferPaymentMethodScreen.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferPaymentMethodScreen.kt @@ -19,11 +19,15 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import cafe.adriel.lyricist.LocalStrings +import kotlinx.coroutines.flow.MutableStateFlow import network.bisq.mobile.i18n.toDisplayString import network.bisq.mobile.presentation.ui.components.atoms.BisqText import network.bisq.mobile.presentation.ui.components.atoms.DynamicImage +import network.bisq.mobile.presentation.ui.components.atoms.PaymentTypeCard import network.bisq.mobile.presentation.ui.components.atoms.layout.BisqGap import network.bisq.mobile.presentation.ui.components.layout.MultiScreenWizardScaffold +import network.bisq.mobile.presentation.ui.components.molecules.BisqPaymentToggle +import network.bisq.mobile.presentation.ui.components.organisms.PaymentMethodCard import network.bisq.mobile.presentation.ui.helpers.RememberPresenterLifecycle import network.bisq.mobile.presentation.ui.theme.BisqTheme import network.bisq.mobile.presentation.ui.theme.BisqUIConstants @@ -32,19 +36,18 @@ import org.koin.compose.koinInject @Composable fun TakeOfferPaymentMethodScreen() { val strings = LocalStrings.current.bisqEasy - val paymentMethodStrings = LocalStrings.current.paymentMethod val presenter: TakeOfferPaymentMethodPresenter = koinInject() val baseSidePaymentMethod = remember { mutableStateOf(presenter.baseSidePaymentMethod) } val quoteSidePaymentMethod = remember { mutableStateOf(presenter.quoteSidePaymentMethod) } + val quoteCurrencyCode = remember { mutableStateOf(presenter.quoteCurrencyCode) } RememberPresenterLifecycle(presenter, { baseSidePaymentMethod.value = presenter.baseSidePaymentMethod quoteSidePaymentMethod.value = presenter.quoteSidePaymentMethod + quoteCurrencyCode.value = presenter.quoteCurrencyCode }) - var customMethodCounter = 1 - MultiScreenWizardScaffold( strings.bisqEasy_takeOffer_progress_method, stepIndex = 2, @@ -60,112 +63,39 @@ fun TakeOfferPaymentMethodScreen() { ) if (presenter.hasMultipleQuoteSidePaymentMethods) { + BisqGap.V2() - BisqGap.V2() - Column( - modifier = Modifier.padding(horizontal = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - BisqText.largeLight( - text = strings.bisqEasy_takeOffer_paymentMethods_subtitle_fiat_buyer("USD"), - color = BisqTheme.colors.grey2 - ) - BisqGap.V2() - Column( - modifier = Modifier.fillMaxWidth().padding(horizontal = 38.dp), - horizontalAlignment = Alignment.Start, - verticalArrangement = Arrangement.spacedBy(BisqUIConstants.ScreenPadding) - ) { - presenter.quoteSidePaymentMethods.forEach { paymentMethod -> - // TODO: Make this to Toggle buttons. Can get paymentMethod as some Enum? + PaymentMethodCard( + title = strings.bisqEasy_takeOffer_paymentMethods_subtitle_fiat_buyer(quoteCurrencyCode.value), + imagePaths = presenter.getQuoteSidePaymentMethodsImagePaths(), + availablePaymentMethods = presenter.quoteSidePaymentMethods, + i18n = LocalStrings.current.paymentMethod, + selectedPaymentMethods = presenter.getPaymentMethodAsSet(quoteSidePaymentMethod.value), + onToggle = { paymentMethod -> + quoteSidePaymentMethod.value = paymentMethod + presenter.onQuoteSidePaymentMethodSelected(paymentMethod) + }, + ) - val isSelected = paymentMethod == quoteSidePaymentMethod.value - val backgroundColor by animateColorAsState( - targetValue = if (isSelected) BisqTheme.colors.primary else BisqTheme.colors.dark5 - ) - Row( - modifier = Modifier - .fillMaxWidth() - .clip(shape = RoundedCornerShape(6.dp)) - .background(color = backgroundColor) - .clickable { - quoteSidePaymentMethod.value = paymentMethod - presenter.onQuoteSidePaymentMethodSelected(paymentMethod) - } - .padding(start = 18.dp) - .padding(vertical = 10.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(10.dp) - ) - { - DynamicImage( - path = "drawable/payment/fiat/${ - paymentMethod - .lowercase() - .replace("-", "_") - }.png", - fallbackPath = "drawable/payment/fiat/custom_payment_${customMethodCounter++}.png", - modifier = Modifier.size(15.dp), - ) - BisqText.baseRegular(text = paymentMethodStrings.toDisplayString(paymentMethod)) - } - } - } - } } if (presenter.hasMultipleBaseSidePaymentMethods) { + BisqGap.V2() - BisqGap.V2() - Column( - modifier = Modifier.padding(horizontal = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - BisqText.largeLight( - text = strings.bisqEasy_takeOffer_paymentMethods_subtitle_bitcoin_seller, - color = BisqTheme.colors.grey2 - ) - BisqGap.V1() - Column( - modifier = Modifier.fillMaxWidth().padding(horizontal = 38.dp), - horizontalAlignment = Alignment.Start, - verticalArrangement = Arrangement.spacedBy(BisqUIConstants.ScreenPadding) - ) { - presenter.baseSidePaymentMethods.forEach { paymentMethod -> - // TODO: Make this to Toggle buttons. Can get paymentMethod as some Enum? - val isSelected = paymentMethod == baseSidePaymentMethod.value - val backgroundColor by animateColorAsState( - targetValue = if (isSelected) BisqTheme.colors.primary else BisqTheme.colors.dark5 - ) - Row( - modifier = Modifier - .fillMaxWidth() - .clip(shape = RoundedCornerShape(6.dp)) - .background(color = backgroundColor) - .clickable { - baseSidePaymentMethod.value = paymentMethod - presenter.onBaseSidePaymentMethodSelected(paymentMethod) - } - .padding(horizontal = 10.dp) - .padding(vertical = 10.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(10.dp) - ) { - DynamicImage( - "drawable/payment/bitcoin/${ - paymentMethod - .lowercase() - .replace("-", "_") - }.png", - modifier = Modifier.size(15.dp) - ) - BisqText.baseRegular(text = paymentMethodStrings.toDisplayString(paymentMethod)) - } - } - } - } + PaymentMethodCard( + title = strings.bisqEasy_takeOffer_paymentMethods_subtitle_bitcoin_seller, + imagePaths = presenter.getBaseSidePaymentMethodsImagePaths(), + availablePaymentMethods = presenter.baseSidePaymentMethods, + i18n = LocalStrings.current.paymentMethod, + selectedPaymentMethods = presenter.getPaymentMethodAsSet(baseSidePaymentMethod.value), + onToggle = { paymentMethod -> + baseSidePaymentMethod.value = paymentMethod + presenter.onBaseSidePaymentMethodSelected(paymentMethod) + }, + ) + } } } \ No newline at end of file diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferReviewScreen.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferReviewScreen.kt index cfce0e30..34d22b85 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferReviewScreen.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trade/take_offer/TakeOfferReviewScreen.kt @@ -57,7 +57,7 @@ fun TakeOfferReviewTradeScreen() { } BisqHDivider() - Column(verticalArrangement = Arrangement.spacedBy(24.dp)) { + Column(verticalArrangement = Arrangement.spacedBy(BisqUIConstants.ScreenPadding2X)) { InfoBox( label = strings.bisqEasy_tradeWizard_review_priceDescription_taker, valueComposable = {