diff --git a/bisqapps/gradle/libs.versions.toml b/bisqapps/gradle/libs.versions.toml index 0533898c..28e56f6f 100644 --- a/bisqapps/gradle/libs.versions.toml +++ b/bisqapps/gradle/libs.versions.toml @@ -17,6 +17,7 @@ androidx-lifecycle = "2.8.2" androidx-test-compose-ver = "1.6.8" androidx-multidex = "2.0.1" bisq-core = "2.1.2" +coilCompose = "3.0.3" compose-plugin = "1.7.0" junit = "4.13.2" kotlinxDatetime = "0.4.0" @@ -64,6 +65,7 @@ lombok-lib = { strictly = '1.18.34' } typesafe-config-lib = { strictly = '1.4.3' } [libraries] +coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coilCompose" } kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } kotlin-test-junit-v180 = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlinTestJunit" } kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx" } diff --git a/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/model/Currencies.kt b/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/model/Currencies.kt new file mode 100644 index 00000000..b5ff1b74 --- /dev/null +++ b/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/model/Currencies.kt @@ -0,0 +1,18 @@ +package network.bisq.mobile.domain.data.model + +data class FiatCurrency( + val flagImage: String, + val name: String, + val code: String, + val offerCount: Number +) + +class Currencies(val currencies: List = listOf()): BaseModel() + +interface CurrenciesFactory { + fun createCurrencies(): Currencies +} + +class DefaultCurrenciesFactory : CurrenciesFactory { + override fun createCurrencies() = Currencies() +} \ No newline at end of file diff --git a/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/model/MyTrades.kt b/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/model/MyTrades.kt new file mode 100644 index 00000000..492fcda1 --- /dev/null +++ b/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/model/MyTrades.kt @@ -0,0 +1,26 @@ +package network.bisq.mobile.domain.data.model + +// TODO: Update later based on model class from bisq2 lib +data class BisqOffer ( + val id: String = "offer_283UANJD19A", + val isBuy: Boolean = true, + val amIMaker: Boolean = false, + val price: Number = 97000, + val currency: String = "USD", + val fiatAmount: Number = 1000, //Should be a range + val satsAmount: Number= 1030927, //Should be a range + + val partyName: String = "satoshi", + val partyRatings: Double = 4.2, + val partyDP: String = "", // Image URL +) + +class MyTrades(val trades: List = listOf()): BaseModel() + +interface MyTradesFactory { + fun createMyTrades(): MyTrades +} + +class DefaultMyTradesFactory : MyTradesFactory { + override fun createMyTrades() = MyTrades() +} \ No newline at end of file diff --git a/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/repository/CurrenciesRepository.kt b/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/repository/CurrenciesRepository.kt new file mode 100644 index 00000000..fd699350 --- /dev/null +++ b/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/repository/CurrenciesRepository.kt @@ -0,0 +1,52 @@ +package network.bisq.mobile.domain.data.repository + +import kotlinx.coroutines.runBlocking +import network.bisq.mobile.domain.data.model.Currencies +import network.bisq.mobile.domain.data.model.FiatCurrency + +// TODO: +// androidNode will populate List from bisq2 libs +// xClients will populate List via API +open class CurrenciesRepository : SingleObjectRepository() { + init { + runBlocking { + val currencies = Currencies( + currencies = listOf( + FiatCurrency( + flagImage = "currency_aed.png", + name = "United Arab Emirates Dirham", + code = "aed", + offerCount = 9 + ), + FiatCurrency(flagImage = "currency_ars.png", name = "Argentine Peso", code = "ars", offerCount = 0), + FiatCurrency( + flagImage = "currency_aud.png", + name = "Australian Dollar", + code = "aud", + offerCount = 12 + ), + FiatCurrency(flagImage = "currency_eur.png", name = "Euro", code = "eur", offerCount = 66), + FiatCurrency( + flagImage = "currency_gbp.png", + name = "British Pound Sterling", + code = "gbp", + offerCount = 3 + ), + + FiatCurrency(flagImage = "currency_jpy.png", name = "Japanese Yen", code = "jpy", offerCount = 2), + + FiatCurrency(flagImage = "currency_qar.png", name = "Qatari Rial", code = "qar", offerCount = 4), + FiatCurrency(flagImage = "currency_sek.png", name = "Swedish Krona", code = "sek", offerCount = 18), + FiatCurrency( + flagImage = "currency_sgd.png", + name = "Singapore Dollar", + code = "sgd", + offerCount = 16 + ), + FiatCurrency(flagImage = "currency_usd.png", name = "US Dollar", code = "usd", offerCount = 62), + ) + ) + create(currencies) + } + } +} \ No newline at end of file diff --git a/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/repository/Repositories.kt b/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/repository/Repositories.kt index 44b0504b..a2cc2f3d 100644 --- a/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/repository/Repositories.kt +++ b/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/data/repository/Repositories.kt @@ -1,9 +1,7 @@ package network.bisq.mobile.domain.data.repository -import network.bisq.mobile.domain.data.model.BisqStats -import network.bisq.mobile.domain.data.model.BtcPrice -import network.bisq.mobile.domain.data.model.Greeting -import network.bisq.mobile.domain.data.model.Settings +import kotlinx.coroutines.runBlocking +import network.bisq.mobile.domain.data.model.* // this way of definingsupports both platforms // add your repositories here and then in your DI module call this classes for instanciation @@ -11,3 +9,28 @@ open class GreetingRepository: SingleObjectRepository() open class BisqStatsRepository: SingleObjectRepository() open class BtcPriceRepository: SingleObjectRepository() open class SettingsRepository: SingleObjectRepository() + +open class MyTradesRepository : SingleObjectRepository() { + init { + runBlocking { + val myTrades = MyTrades( + trades = listOf( + BisqOffer(id = "offer1", isBuy = true, price = 95000, currency = "USD"), + BisqOffer(id = "offer2", isBuy = false, price = 96000, currency = "USD"), + BisqOffer(id = "offer3", isBuy = true, price = 97000, currency = "USD"), + BisqOffer(id = "offer4", isBuy = false, price = 98000, currency = "USD"), + BisqOffer(id = "offer5", isBuy = true, price = 99000, currency = "USD"), + BisqOffer(id = "offer1", isBuy = true, price = 95000, currency = "USD"), + BisqOffer(id = "offer2", isBuy = false, price = 96000, currency = "USD"), + BisqOffer(id = "offer3", isBuy = true, price = 97000, currency = "USD"), + BisqOffer(id = "offer4", isBuy = false, price = 98000, currency = "USD"), + BisqOffer(id = "offer5", isBuy = true, price = 99000, currency = "USD") + ) + ) + + create(myTrades) + + println("MyTradeRepo :: Created") + } + } +} diff --git a/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/di/DomainModule.kt b/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/di/DomainModule.kt index 042a5836..cd0b9c0d 100644 --- a/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/di/DomainModule.kt +++ b/bisqapps/shared/domain/src/commonMain/kotlin/network/bisq/mobile/domain/di/DomainModule.kt @@ -1,10 +1,7 @@ package network.bisq.mobile.domain.di import network.bisq.mobile.domain.data.model.Greeting -import network.bisq.mobile.domain.data.repository.BisqStatsRepository -import network.bisq.mobile.domain.data.repository.BtcPriceRepository -import network.bisq.mobile.domain.data.repository.GreetingRepository -import network.bisq.mobile.domain.data.repository.SettingsRepository +import network.bisq.mobile.domain.data.repository.* import org.koin.dsl.module val domainModule = module { @@ -12,4 +9,6 @@ val domainModule = module { single { BisqStatsRepository() } single { BtcPriceRepository() } single { SettingsRepository() } + single { MyTradesRepository() } + single { CurrenciesRepository() } } diff --git a/bisqapps/shared/presentation/build.gradle.kts b/bisqapps/shared/presentation/build.gradle.kts index 02b64446..23fde293 100644 --- a/bisqapps/shared/presentation/build.gradle.kts +++ b/bisqapps/shared/presentation/build.gradle.kts @@ -94,6 +94,8 @@ kotlin { implementation(libs.navigation.compose) implementation(libs.lyricist) + implementation(libs.coil.compose) + } val commonTest by getting { dependencies { diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_aed.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_aed.png new file mode 100644 index 00000000..f33edfdc Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_aed.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_ars.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_ars.png new file mode 100644 index 00000000..7fea323e Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_ars.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_aud.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_aud.png new file mode 100644 index 00000000..13397b7e Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_aud.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_eur.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_eur.png new file mode 100644 index 00000000..fc88ad1f Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_eur.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_euro.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_euro.png deleted file mode 100644 index 31d48fe0..00000000 Binary files a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_euro.png and /dev/null differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_gbp.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_gbp.png new file mode 100644 index 00000000..eddcabab Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_gbp.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_gpb.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_gpb.png deleted file mode 100644 index 643fb3b6..00000000 Binary files a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_gpb.png and /dev/null differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_jpy.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_jpy.png new file mode 100644 index 00000000..0e07efbc Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_jpy.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_qar.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_qar.png new file mode 100644 index 00000000..89eed23a Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_qar.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_sek.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_sek.png new file mode 100644 index 00000000..bb872fe5 Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_sek.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_sgd.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_sgd.png new file mode 100644 index 00000000..08c63538 Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_sgd.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_usd.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_usd.png index f272f94e..8bfcbe53 100644 Binary files a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_usd.png and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/currency_usd.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/icon_right_arrow.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/icon_right_arrow.png new file mode 100644 index 00000000..50578a06 Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/icon_right_arrow.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/icon_star.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/icon_star.png new file mode 100644 index 00000000..b5c4f3e0 Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/icon_star.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/img_no_trades.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/img_no_trades.png new file mode 100644 index 00000000..7e932a5f Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/img_no_trades.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_ach.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_ach.png new file mode 100644 index 00000000..b06b74b7 Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_ach.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_bitcoin_round.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_bitcoin_round.png new file mode 100644 index 00000000..613bb8c0 Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_bitcoin_round.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_lightning_round.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_lightning_round.png new file mode 100644 index 00000000..008d98b2 Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_lightning_round.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_strike.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_strike.png new file mode 100644 index 00000000..8421d1f0 Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_strike.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_uspmo.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_uspmo.png new file mode 100644 index 00000000..4b38ee19 Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_uspmo.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_venmo.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_venmo.png new file mode 100644 index 00000000..041a723a Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_venmo.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_wise.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_wise.png new file mode 100644 index 00000000..ea11d1c5 Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_wise.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_zelle.png b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_zelle.png new file mode 100644 index 00000000..f5f5ed03 Binary files /dev/null and b/bisqapps/shared/presentation/src/commonMain/composeResources/drawable/payment_zelle.png differ diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/i18n/EnStrings.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/i18n/EnStrings.kt index 5e432979..a2ef7743 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/i18n/EnStrings.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/i18n/EnStrings.kt @@ -146,4 +146,10 @@ val EnStrings = Strings( buttons_next = "Next", buttons_submit = "Submit", buttons_cancel = "Cancel", + + common_offers = "Offers", + common_search = "Search", + + offers_list_buy_from = "Buy from", + offers_list_sell_to = "Sell to", ) diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/i18n/FrStrings.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/i18n/FrStrings.kt index c4d5d745..56df8ec3 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/i18n/FrStrings.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/i18n/FrStrings.kt @@ -148,4 +148,10 @@ val FRStrings = Strings( buttons_next = "[FR] Next", buttons_submit = "[FR] Submit", buttons_cancel = "[FR] Cancel", + + common_offers = "[FR] offers", + common_search = "[FR] Search", + + offers_list_buy_from = "[FR] Buy from", + offers_list_sell_to = "[FR] Sell to", ) diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/i18n/Strings.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/i18n/Strings.kt index b23042f6..2ab2c063 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/i18n/Strings.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/i18n/Strings.kt @@ -144,4 +144,10 @@ data class Strings( val buttons_next: String, val buttons_submit: String, val buttons_cancel: String, + + val common_offers: String, + val common_search: String, + + val offers_list_buy_from: String, + val offers_list_sell_to: String, ) \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/di/PresentationModule.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/di/PresentationModule.kt index 1482abb4..f6be9d34 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/di/PresentationModule.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/di/PresentationModule.kt @@ -1,16 +1,23 @@ package network.bisq.mobile.presentation.di +import androidx.navigation.NavController import androidx.navigation.NavHostController import network.bisq.mobile.presentation.MainPresenter import network.bisq.mobile.presentation.ui.AppPresenter import network.bisq.mobile.presentation.ui.uicases.GettingStartedPresenter import network.bisq.mobile.presentation.ui.uicases.IGettingStarted +import network.bisq.mobile.presentation.ui.uicases.offers.CurrencyListPresenter +import network.bisq.mobile.presentation.ui.uicases.offers.ICurrencyList +import network.bisq.mobile.presentation.ui.uicases.offers.IOffersList +import network.bisq.mobile.presentation.ui.uicases.offers.OffersListPresenter import network.bisq.mobile.presentation.ui.uicases.startup.CreateProfilePresenter import network.bisq.mobile.presentation.ui.uicases.startup.IOnboardingPresenter import network.bisq.mobile.presentation.ui.uicases.startup.ITrustedNodeSetupPresenter 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.MyTradesPresenter import org.koin.core.qualifier.named import org.koin.dsl.bind import org.koin.dsl.module @@ -55,4 +62,16 @@ val presentationModule = module { settingsRepository = get() ) } bind ITrustedNodeSetupPresenter::class + + single { CurrencyListPresenter(get(), get()) } bind ICurrencyList::class + + single { OffersListPresenter(get()) } bind IOffersList::class + + single { + (navController: NavController, tabController: NavController) -> MyTradesPresenter( + get(), + tabController = tabController, + myTradesRepository = get() + ) + } bind IMyTrades::class } \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/CurrencyProfileCard.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/CurrencyProfileCard.kt index 3bfdcca4..9334e7a2 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/CurrencyProfileCard.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/CurrencyProfileCard.kt @@ -1,54 +1,69 @@ package network.bisq.mobile.presentation.ui.components import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.material3.Text +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.* import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp +import bisqapps.shared.presentation.generated.resources.Res +import cafe.adriel.lyricist.LocalStrings +import coil3.compose.AsyncImage +import network.bisq.mobile.domain.data.model.FiatCurrency import network.bisq.mobile.presentation.ui.components.atoms.BisqText +import network.bisq.mobile.presentation.ui.components.atoms.DynamicImage import network.bisq.mobile.presentation.ui.theme.BisqTheme import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.painterResource + @OptIn(ExperimentalResourceApi::class) @Composable -fun CurrencyProfileCard(currencyName: String, currencyShort: String, image: DrawableResource) { +fun CurrencyProfileCard( + currency: FiatCurrency, + onClick: (FiatCurrency) -> Unit) { + + val strings = LocalStrings.current + val interactionSource = remember { MutableInteractionSource() } + Row( - modifier = Modifier.fillMaxWidth().padding(horizontal = 14.dp, vertical = 16.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 14.dp, vertical = 4.dp) + .clickable( + interactionSource = interactionSource, + indication = null, + onClick = { + onClick(currency) + } + ) + , ) { Row( verticalAlignment = Alignment.CenterVertically, ) { - Image(painterResource(image), null, modifier = Modifier.size(36.dp)) + DynamicImage("drawable/${currency.flagImage}", contentDescription = null) Spacer(modifier = Modifier.width(8.dp)) Column { BisqText.baseRegular( - text = currencyName, + text = currency.name, color = BisqTheme.colors.light1, ) - Spacer(modifier = Modifier.height(8.dp)) + Spacer(modifier = Modifier.height(0.dp)) BisqText.baseRegular( - text = currencyShort, + text = currency.code, color = BisqTheme.colors.grey2, ) } } BisqText.smallRegular( - text = "43 offers", + text = "${currency.offerCount.toString()} ${strings.common_offers}", color = BisqTheme.colors.primary, ) } diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/DynamicImage.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/DynamicImage.kt new file mode 100644 index 00000000..43f004bd --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/DynamicImage.kt @@ -0,0 +1,32 @@ +package network.bisq.mobile.presentation.ui.components.atoms + +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable + +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import bisqapps.shared.presentation.generated.resources.Res +import bisqapps.shared.presentation.generated.resources.bisq_logo +import bisqapps.shared.presentation.generated.resources.currency_aed +import coil3.compose.AsyncImage +import org.jetbrains.compose.resources.ExperimentalResourceApi +import org.jetbrains.compose.resources.painterResource + + +// The idea of this Composable is to load images at run time with a string path. +// TODO: In case the image doesn't exist, it should be handled gracefully +@OptIn(ExperimentalResourceApi::class) +@Composable +fun DynamicImage(path: String, contentDescription: String?, modifier: Modifier? = Modifier) { + AsyncImage( + model = Res.getUri(path), + //model = Res.getUri("drawable/currency_usd.png"), + //fallback = painterResource(Res.drawable.currency_aed), + contentDescription = null, + modifier = Modifier.size(36.dp), + onError = { + println("Error") + } + ) +} \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/PaymentMethods.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/PaymentMethods.kt new file mode 100644 index 00000000..dbe595ef --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/PaymentMethods.kt @@ -0,0 +1,52 @@ +package network.bisq.mobile.presentation.ui.components.atoms + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import bisqapps.shared.presentation.generated.resources.* +import bisqapps.shared.presentation.generated.resources.Res +import org.jetbrains.compose.resources.painterResource + +// TODO: Get params and render apt +@Composable +fun PaymentMethods() { + Row(horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically) { + Row (horizontalArrangement = Arrangement.spacedBy(12.dp)){ + Image( + painterResource(Res.drawable.payment_ach), "", + modifier = Modifier.size(15.dp) + ) + Image( + painterResource(Res.drawable.payment_strike), "", + modifier = Modifier.size(15.dp) + ) + Image( + painterResource(Res.drawable.payment_ach), "", + modifier = Modifier.size(15.dp) + ) + Image( + painterResource(Res.drawable.payment_uspmo), "", + modifier = Modifier.size(15.dp) + ) + } + Image( + painterResource( Res.drawable.icon_right_arrow), "", + modifier = Modifier.size(24.dp) + ) + Row (horizontalArrangement = Arrangement.spacedBy(12.dp)){ + Image( + painterResource(Res.drawable.payment_bitcoin_round), "", + modifier = Modifier.size(15.dp) + ) + Image( + painterResource(Res.drawable.payment_lightning_round), "", + modifier = Modifier.size(15.dp) + ) + } + } +} \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/ProfileRating.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/ProfileRating.kt new file mode 100644 index 00000000..90bd9eb1 --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/atoms/ProfileRating.kt @@ -0,0 +1,40 @@ +package network.bisq.mobile.presentation.ui.components.atoms + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import bisqapps.shared.presentation.generated.resources.Res +import bisqapps.shared.presentation.generated.resources.icon_star +import bisqapps.shared.presentation.generated.resources.img_bot_image +import org.jetbrains.compose.resources.painterResource + +// TODO: Get params and render apt +@Composable +fun ProfileRating() { + Row(horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically) { + Image( + painterResource(Res.drawable.img_bot_image), "", + modifier = Modifier.size(32.dp) + ) + Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { + BisqText.smallMedium( + text = "Satoshi Ninja" + ) + LazyRow(horizontalArrangement = Arrangement.spacedBy(2.dp)) { + items(5) { + Image( + painterResource(Res.drawable.icon_star), "", + modifier = Modifier.size(10.dp) + ) + } + } + } + } +} \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/layout/ScrollScaffold.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/layout/ScrollScaffold.kt index 608f368c..d3b9dd88 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/layout/ScrollScaffold.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/layout/ScrollScaffold.kt @@ -1,13 +1,8 @@ package network.bisq.mobile.presentation.ui.components.layout -import androidx.compose.foundation.background import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Scaffold 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 @@ -23,14 +18,7 @@ fun BisqScrollScaffold( topBar = topBar, bottomBar = bottomBar, content = { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .fillMaxSize() - .background(color = BisqTheme.colors.backgroundColor) - .padding(innerPadding) - .verticalScroll(rememberScrollState()) - ) { + BisqScrollLayout { content() } }, diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/layout/StaticLayout.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/layout/StaticLayout.kt new file mode 100644 index 00000000..f33c8d59 --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/layout/StaticLayout.kt @@ -0,0 +1,28 @@ +package network.bisq.mobile.presentation.ui.components.layout + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.material3.Scaffold +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 + +@Composable +fun BisqStaticLayout( + innerPadding: PaddingValues = PaddingValues(top = 48.dp, bottom = 12.dp, start = 12.dp, end = 12.dp), + verticalArrangement: Arrangement.Vertical = Arrangement.SpaceBetween, + content: @Composable ColumnScope.() -> Unit +) { + Column( + verticalArrangement = verticalArrangement, + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .fillMaxSize() + .background(color = BisqTheme.colors.backgroundColor) + .padding(innerPadding) + ) { + content() + } +} diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/layout/StaticScaffold.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/layout/StaticScaffold.kt index f1036354..d7208b88 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/layout/StaticScaffold.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/layout/StaticScaffold.kt @@ -1,17 +1,14 @@ package network.bisq.mobile.presentation.ui.components.layout -import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.material3.Scaffold 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 @Composable fun BisqStaticScaffold( - innerPadding: PaddingValues = PaddingValues(top = 48.dp, bottom = 30.dp), + innerPadding: PaddingValues = PaddingValues(top = 96.dp, bottom = 12.dp, start = 12.dp, end = 12.dp), topBar: @Composable () -> Unit = {}, bottomBar: @Composable () -> Unit = {}, content: @Composable ColumnScope.() -> Unit @@ -21,16 +18,7 @@ fun BisqStaticScaffold( topBar = topBar, bottomBar = bottomBar, content = { - Column( - verticalArrangement = Arrangement.SpaceBetween, - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .fillMaxSize() - .background(color = BisqTheme.colors.backgroundColor) - .padding(innerPadding) - ) { - content() - } + BisqStaticLayout(innerPadding = innerPadding) { content() } } ) } diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/BisqDialog.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/BisqDialog.kt new file mode 100644 index 00000000..11168f56 --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/BisqDialog.kt @@ -0,0 +1,48 @@ +package network.bisq.mobile.presentation.ui.components.molecules + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Card +import androidx.compose.material3.CardColors +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.compose.ui.window.Dialog +import network.bisq.mobile.presentation.ui.theme.BisqTheme + +@Composable +fun BisqDialog( + onDismissRequest: () -> Unit = {}, + content: @Composable ColumnScope.() -> Unit = {} +) { + Dialog(onDismissRequest = { onDismissRequest() }) { + Box( + modifier = Modifier + .fillMaxSize() + .padding(top = 86.dp) + ) { + Card( + modifier = Modifier + .align(Alignment.TopCenter) + .fillMaxWidth(), + colors = CardColors( + containerColor = BisqTheme.colors.dark3, + contentColor = Color.Unspecified, + disabledContainerColor = Color.Unspecified, + disabledContentColor = Color.Unspecified, + ), + border = BorderStroke(1.dp, color = BisqTheme.colors.grey3), + shape = RoundedCornerShape(8.dp), + ) { + content() + } + } + } +} \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/ConfirmationDialog.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/ConfirmationDialog.kt new file mode 100644 index 00000000..94b6722d --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/ConfirmationDialog.kt @@ -0,0 +1,51 @@ +package network.bisq.mobile.presentation.ui.components.molecules + +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 androidx.navigation.NavController +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.molecules.BisqDialog +import network.bisq.mobile.presentation.ui.theme.BisqTheme + +// TODO: Update default params with translation keys +@Composable +fun ConfirmationDialog( + title: String = "", + message: String = "Are you sure?", + confirmButtonText: String = "Yes", + cancelButtonText: String = "No", + onDismissRequest: () -> Unit, + ) { + BisqDialog { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 24.dp, horizontal = 20.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + BisqText.h6Regular( + text = message, + color = BisqTheme.colors.light1, + modifier = Modifier.padding(vertical = 12.dp) + ) + Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) { + BisqButton( + text = cancelButtonText, + backgroundColor = BisqTheme.colors.dark5, + onClick = { onDismissRequest() }, + padding = PaddingValues(horizontal = 42.dp, vertical = 4.dp) + ) + BisqButton( + text = confirmButtonText, + onClick = { onDismissRequest() }, + padding = PaddingValues(horizontal = 32.dp, vertical = 4.dp) + ) + } + } + } +} \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/OfferCard.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/OfferCard.kt new file mode 100644 index 00000000..036cfb47 --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/OfferCard.kt @@ -0,0 +1,80 @@ +package network.bisq.mobile.presentation.ui.components.molecules + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.VerticalDivider +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +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.icon_chat_outlined +import network.bisq.mobile.presentation.ui.components.atoms.BisqText +import network.bisq.mobile.presentation.ui.components.atoms.PaymentMethods +import network.bisq.mobile.presentation.ui.components.atoms.ProfileRating +import network.bisq.mobile.presentation.ui.theme.BisqTheme +import org.jetbrains.compose.resources.painterResource + +@Composable +fun OfferCard( + onClick: () -> Unit +) { + Row( + modifier = Modifier.clip(shape = RoundedCornerShape(8.dp)).padding(vertical = 5.dp), + + ) { + Row( + modifier = Modifier.background(color = BisqTheme.colors.dark5).padding(12.dp).clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = onClick + ), + verticalAlignment = Alignment.CenterVertically + ) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + ProfileRating() + PaymentMethods() + } + Column( + horizontalAlignment = Alignment.End, + verticalArrangement = Arrangement.SpaceBetween + ) { + BisqText.baseBold( + text = "1.00%", + color = BisqTheme.colors.primary + ) + BisqText.smallMedium( + text = "\$52,000 / BTC", + color = BisqTheme.colors.grey1 + ) + BisqText.baseRegular( + text = "\$50 - \$200", + color = BisqTheme.colors.light1 + ) + } + } + VerticalDivider(thickness = 2.dp, color = BisqTheme.colors.grey3, modifier = Modifier.height(98.dp)) + Column( + verticalArrangement = Arrangement.Center, + modifier = Modifier.background(color = BisqTheme.colors.dark4) + .padding(horizontal = 10.dp, vertical = 41.dp) + ) { + Image( + painterResource( + Res.drawable.icon_chat_outlined), "", + modifier = Modifier.size(16.dp), + ) + } + } +} \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/StateToggle.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/StateToggle.kt new file mode 100644 index 00000000..577d41cc --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/StateToggle.kt @@ -0,0 +1,86 @@ +package network.bisq.mobile.presentation.ui.components.molecules + +import androidx.compose.animation.core.animateDpAsState +import androidx.compose.animation.core.tween +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +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 StateToggle( + states: List, + transitionX: Dp +) { + var selectedOption by remember { + mutableStateOf(states[0]) + } + + val slideOffset by animateDpAsState( + targetValue = if (selectedOption == states[0]) 0.dp else transitionX, + animationSpec = tween(durationMillis = 300) + ) + + Surface( + shape = RoundedCornerShape(6.dp), + modifier = Modifier.wrapContentSize() + ) { + Box( + modifier = Modifier + .background(BisqTheme.colors.dark5) + .padding(6.dp) + ) { + Box( + modifier = Modifier + .offset(x = slideOffset) + .background(BisqTheme.colors.primary, RoundedCornerShape(4.dp)) + ) { + + BisqText.baseMedium( + text = selectedOption, + color = BisqTheme.colors.light1, + modifier = Modifier + .padding(horizontal = 32.dp, vertical = 12.dp) + .alpha(0f), + ) + } + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + states.forEach { text -> + BisqText.baseMedium( + text = text, + color = BisqTheme.colors.light1, + modifier = Modifier + .padding(horizontal = 32.dp, vertical = 12.dp) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = { + selectedOption = text + } + ) + ) + } + } + } + } +} \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/TopBar.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/TopBar.kt index 9f0b2d01..8e40ca96 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/TopBar.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/molecules/TopBar.kt @@ -22,7 +22,7 @@ import org.jetbrains.compose.resources.ExperimentalResourceApi @OptIn(ExperimentalMaterial3Api::class, ExperimentalResourceApi::class) @Composable -fun TopBar(title: String = "",isHome:Boolean = false) { +fun TopBar(title: String = "", isHome:Boolean = false) { TopAppBar( modifier = Modifier.padding(horizontal = 16.dp).padding(end = 16.dp), colors = TopAppBarDefaults.topAppBarColors( diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/startup/BisqPagerView.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/PagerView.kt similarity index 99% rename from bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/startup/BisqPagerView.kt rename to bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/PagerView.kt index 5eb52c46..ba4959e1 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/startup/BisqPagerView.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/components/organisms/PagerView.kt @@ -1,4 +1,4 @@ -package network.bisq.mobile.presentation.ui.components.organisms.startup +package network.bisq.mobile.presentation.ui.components.organisms import androidx.compose.foundation.Image import androidx.compose.foundation.background diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/composeModels/model.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/composeModels/model.kt index 02c75966..d1d4f1b9 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/composeModels/model.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/composeModels/model.kt @@ -3,4 +3,4 @@ package network.bisq.mobile.presentation.ui.composeModels import org.jetbrains.compose.resources.DrawableResource data class BottomNavigationItem(val title: String, val route: String, val icon: DrawableResource) -data class PagerViewItem(val title: String, val image: DrawableResource, val desc: String) +data class PagerViewItem(val title: String, val image: DrawableResource, val desc: String) \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/Routes.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/Routes.kt index 25dc0b40..bd4bea4f 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/Routes.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/Routes.kt @@ -13,7 +13,8 @@ enum class Routes(val title: String) { TrustedNodeSetup(title = "trusted_node_setup"), TabContainer(title = "tab_container"), TabHome(title = "tab_home"), - TabExchange(title = "tab_exchange"), + TabCurrencies(title = "tab_currencies"), TabMyTrades(title = "tab_my_trades"), TabSettings(title = "tab_settings"), + OfferList(title = "offer_list"), } \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/graph/RootNavGraph.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/graph/RootNavGraph.kt index 5aa8d2ec..8d6c3e1b 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/graph/RootNavGraph.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/graph/RootNavGraph.kt @@ -11,6 +11,7 @@ import androidx.navigation.compose.composable import network.bisq.mobile.presentation.ui.navigation.* import network.bisq.mobile.presentation.ui.theme.BisqTheme import network.bisq.mobile.presentation.ui.uicases.* +import network.bisq.mobile.presentation.ui.uicases.offers.OffersListScreen 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 @@ -57,5 +58,14 @@ fun RootNavGraph() { composable(route = Routes.TabContainer.name) { TabContainerScreen() } + + composable(route = Routes.OfferList.name, enterTransition = { + slideIntoContainer( + AnimatedContentTransitionScope.SlideDirection.Left, + animationSpec = tween(300) + ) + }) { + OffersListScreen() + } } } \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/graph/TabNavGraph.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/graph/TabNavGraph.kt index 5b3b392c..a9e07224 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/graph/TabNavGraph.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/navigation/graph/TabNavGraph.kt @@ -11,7 +11,7 @@ import network.bisq.mobile.presentation.ui.navigation.Routes import network.bisq.mobile.presentation.ui.navigation.Graph import network.bisq.mobile.presentation.ui.theme.BisqTheme import network.bisq.mobile.presentation.ui.uicases.GettingStartedScreen -import network.bisq.mobile.presentation.ui.uicases.exchange.ExchangeScreen +import network.bisq.mobile.presentation.ui.uicases.offers.CurrencyListScreen import network.bisq.mobile.presentation.ui.uicases.settings.SettingsScreen import network.bisq.mobile.presentation.ui.uicases.trades.MyTradesScreen import org.koin.compose.koinInject @@ -34,8 +34,8 @@ fun TabNavGraph() { composable(route = Routes.TabHome.name) { GettingStartedScreen() } - composable(route = Routes.TabExchange.name) { - ExchangeScreen() + composable(route = Routes.TabCurrencies.name) { + CurrencyListScreen() } composable(route = Routes.TabMyTrades.name) { MyTradesScreen() diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/TabContainerScreen.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/TabContainerScreen.kt index 6b075ec8..8222e598 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/TabContainerScreen.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/TabContainerScreen.kt @@ -1,6 +1,8 @@ package network.bisq.mobile.presentation.ui.uicases +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.* +import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController import androidx.navigation.compose.currentBackStackEntryAsState import bisqapps.shared.presentation.generated.resources.* @@ -16,7 +18,7 @@ import org.koin.core.qualifier.named val navigationListItem = listOf( BottomNavigationItem("Home", Routes.TabHome.name, Res.drawable.icon_home), - BottomNavigationItem("Buy/Sell", Routes.TabExchange.name, Res.drawable.icon_market), + BottomNavigationItem("Buy/Sell", Routes.TabCurrencies.name, Res.drawable.icon_market), BottomNavigationItem("My Trades", Routes.TabMyTrades.name, Res.drawable.icon_trades), BottomNavigationItem("Settings", Routes.TabSettings.name, Res.drawable.icon_settings), ) @@ -33,6 +35,7 @@ fun TabContainerScreen() { } BisqStaticScaffold( + innerPadding = PaddingValues(top = 48.dp, bottom = 12.dp, start = 12.dp, end = 12.dp), topBar = { // TODO: Since Topbar should go inside Scaffold // the TopBar is written here commonly for all 4 tabs. @@ -43,7 +46,7 @@ fun TabContainerScreen() { isHome = currentRoute == Routes.TabHome.name, title = when (currentRoute) { Routes.TabHome.name -> "Home" - Routes.TabExchange.name -> "Buy/Sell" + Routes.TabCurrencies.name -> "Buy/Sell" Routes.TabMyTrades.name -> "My Trades" Routes.TabSettings.name -> "Settings" else -> "App" diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/exchange/ExchangeScreen.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/exchange/ExchangeScreen.kt deleted file mode 100644 index d35b16d0..00000000 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/exchange/ExchangeScreen.kt +++ /dev/null @@ -1,59 +0,0 @@ -package network.bisq.mobile.presentation.ui.uicases.exchange - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalLayoutDirection -import androidx.compose.ui.unit.dp -import androidx.navigation.NavHostController -import bisqapps.shared.presentation.generated.resources.Res -import bisqapps.shared.presentation.generated.resources.currency_euro -import bisqapps.shared.presentation.generated.resources.currency_gpb -import bisqapps.shared.presentation.generated.resources.currency_usd -import network.bisq.mobile.presentation.ui.components.CurrencyProfileCard -import network.bisq.mobile.components.MaterialTextField -import network.bisq.mobile.presentation.ui.components.molecules.TopBar -import network.bisq.mobile.presentation.ui.components.atoms.icons.SortIcon -import org.jetbrains.compose.resources.ExperimentalResourceApi -import org.koin.compose.koinInject -import org.koin.core.qualifier.named - -@Composable -fun ExchangeScreen() { - val navController: NavHostController = koinInject(named("RootNavController")) - val originDirection = LocalLayoutDirection.current - Column( - modifier = Modifier.fillMaxSize() - ) { -// TopBar("Buy/Sell") - Column(modifier = Modifier.padding(vertical = 12.dp, horizontal = 32.dp)) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Box(modifier = Modifier.width(250.dp)) { - MaterialTextField(text = "Search", onValueChanged = {}) - } - SortIcon(modifier = Modifier.size(24.dp)) - } - Spacer(modifier = Modifier.height(12.dp)) - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - CurrencyProfileCard("US Dollars", "USD", Res.drawable.currency_usd) - CurrencyProfileCard("Euro", "EUR", Res.drawable.currency_euro) - CurrencyProfileCard("British Pounds", "GPB", Res.drawable.currency_gpb) - } - } - } -} \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/CurrencyListPresenter.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/CurrencyListPresenter.kt new file mode 100644 index 00000000..6e2ddc79 --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/CurrencyListPresenter.kt @@ -0,0 +1,49 @@ +package network.bisq.mobile.presentation.ui.uicases.offers + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import network.bisq.mobile.domain.data.BackgroundDispatcher +import network.bisq.mobile.domain.data.model.FiatCurrency +import network.bisq.mobile.domain.data.repository.CurrenciesRepository +import network.bisq.mobile.presentation.BasePresenter +import network.bisq.mobile.presentation.MainPresenter +import network.bisq.mobile.presentation.ui.navigation.Routes + +class CurrencyListPresenter( + mainPresenter: MainPresenter, + private val currenciesRepository: CurrenciesRepository, +) : BasePresenter(mainPresenter), ICurrencyList { + + private val _currencies = MutableStateFlow>(emptyList()) + override val currencies: StateFlow> = _currencies + + override fun onSelectedCurrency(currency: FiatCurrency) { + rootNavigator.navigate(Routes.OfferList.name) + } + + private fun refresh() { + CoroutineScope(BackgroundDispatcher).launch { + try { + delay(1000) // TODO: To simulate loading. Yet to be handled + val currencies = currenciesRepository.fetch() + _currencies.value = currencies?.currencies ?: emptyList() + } catch (e: Exception) { + // Handle errors + println("Error: ${e.message}") + } + } + } + + override fun onViewAttached() { + super.onViewAttached() + refresh() + } + + override fun onResume() { + super.onResume() + refresh() + } +} diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/CurrencyListScreen.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/CurrencyListScreen.kt new file mode 100644 index 00000000..28319410 --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/CurrencyListScreen.kt @@ -0,0 +1,55 @@ +package network.bisq.mobile.presentation.ui.uicases.offers + +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import cafe.adriel.lyricist.LocalStrings +import kotlinx.coroutines.flow.StateFlow +import network.bisq.mobile.presentation.ui.components.CurrencyProfileCard +import network.bisq.mobile.components.MaterialTextField +import network.bisq.mobile.domain.data.model.FiatCurrency +import network.bisq.mobile.presentation.ViewPresenter +import network.bisq.mobile.presentation.ui.components.atoms.icons.SortIcon +import network.bisq.mobile.presentation.ui.components.layout.BisqStaticLayout +import network.bisq.mobile.presentation.ui.helpers.RememberPresenterLifecycle +import org.koin.compose.koinInject + +interface ICurrencyList : ViewPresenter { + val currencies: StateFlow> + fun onSelectedCurrency(currency: FiatCurrency) +} + +@Composable +fun CurrencyListScreen() { + val strings = LocalStrings.current + val presenter: ICurrencyList = koinInject() + val currencies: List = presenter.currencies.collectAsState().value + + RememberPresenterLifecycle(presenter) + + BisqStaticLayout(verticalArrangement = Arrangement.Top) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + MaterialTextField(text = strings.common_search, onValueChanged = {}) + SortIcon(modifier = Modifier.size(24.dp)) + } + Spacer(modifier = Modifier.height(12.dp)) + + LazyColumn() { + items(currencies) { currency -> + CurrencyProfileCard( + currency, + onClick = { presenter.onSelectedCurrency(it) }) + } + } + + } +} \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/OffersListPresenter.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/OffersListPresenter.kt new file mode 100644 index 00000000..53bd1c94 --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/OffersListPresenter.kt @@ -0,0 +1,14 @@ +package network.bisq.mobile.presentation.ui.uicases.offers + +import network.bisq.mobile.presentation.BasePresenter +import network.bisq.mobile.presentation.MainPresenter +import network.bisq.mobile.presentation.ui.navigation.Routes + +open class OffersListPresenter( + mainPresenter: MainPresenter +) : BasePresenter(mainPresenter), IOffersList { + + override fun takeOffer() { + rootNavigator.navigate(Routes.OfferList.name) + } +} diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/OffersListScreen.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/OffersListScreen.kt new file mode 100644 index 00000000..778825c8 --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/offers/OffersListScreen.kt @@ -0,0 +1,69 @@ +package network.bisq.mobile.presentation.ui.uicases.offers + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import cafe.adriel.lyricist.LocalStrings +import network.bisq.mobile.presentation.ViewPresenter +import network.bisq.mobile.presentation.ui.components.layout.BisqStaticScaffold +import network.bisq.mobile.presentation.ui.components.molecules.* +import network.bisq.mobile.presentation.ui.helpers.RememberPresenterLifecycle +import org.koin.compose.koinInject + +interface IOffersList : ViewPresenter { + fun takeOffer() +} + +@Composable +fun OffersListScreen() { + val presenter: ICurrencyList = koinInject() + val strings = LocalStrings.current + + val states = listOf( + strings.offers_list_buy_from, + strings.offers_list_sell_to + ) + + RememberPresenterLifecycle(presenter) + + BisqStaticScaffold( + topBar = { + TopBar(title = strings.common_offers) + }, + ) { + Box(modifier = Modifier.fillMaxSize()) { + Column { + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + StateToggle(states, 130.dp) + + Spacer(modifier = Modifier.height(32.dp)) + LazyColumn( + modifier = Modifier.padding(10.dp), + verticalArrangement = Arrangement.spacedBy(18.dp) + ) { + items(3) { + OfferCard(onClick = { + // TODO: Do navigation here + }) + } + } + + } + } + } + } +} + diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/startup/CreateProfileScreen.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/startup/CreateProfileScreen.kt index 34f5a1b8..5346622e 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/startup/CreateProfileScreen.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/startup/CreateProfileScreen.kt @@ -25,6 +25,7 @@ import network.bisq.mobile.presentation.ui.components.atoms.BisqTextField import network.bisq.mobile.presentation.ui.components.layout.BisqScrollScaffold import network.bisq.mobile.presentation.ui.helpers.RememberPresenterLifecycle import org.koin.core.parameter.parametersOf +import org.koin.core.qualifier.named @Composable fun CreateProfileScreen( @@ -85,4 +86,4 @@ fun CreateProfileScreen( backgroundColor = if (presenter.nickName.value.isEmpty()) BisqTheme.colors.primaryDisabled else BisqTheme.colors.primary ) } -} \ No newline at end of file +} diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/startup/OnBoardingScreen.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/startup/OnBoardingScreen.kt index 787c5cf8..2ae04fa9 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/startup/OnBoardingScreen.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/startup/OnBoardingScreen.kt @@ -16,7 +16,7 @@ import network.bisq.mobile.presentation.ui.components.atoms.icons.BisqLogo 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.layout.BisqScrollScaffold -import network.bisq.mobile.presentation.ui.components.organisms.startup.BisqPagerView +import network.bisq.mobile.presentation.ui.components.organisms.BisqPagerView import network.bisq.mobile.presentation.ui.composeModels.PagerViewItem import network.bisq.mobile.presentation.ui.helpers.RememberPresenterLifecycle import network.bisq.mobile.presentation.ui.theme.* @@ -37,8 +37,7 @@ interface IOnboardingPresenter: ViewPresenter { @Composable fun OnBoardingScreen() { val strings = LocalStrings.current - val navController: NavHostController = koinInject(named("RootNavController")) - val presenter: IOnboardingPresenter = koinInject { parametersOf(navController) } + val presenter: IOnboardingPresenter = koinInject() val coroutineScope = rememberCoroutineScope() val pagerState = rememberPagerState(pageCount = { presenter.indexesToShow.size }) diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/startup/SplashPresenter.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/startup/SplashPresenter.kt index 0edf5b30..b3d9e2da 100644 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/startup/SplashPresenter.kt +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/startup/SplashPresenter.kt @@ -1,6 +1,5 @@ package network.bisq.mobile.presentation.ui.uicases.startup -import androidx.navigation.NavController import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.StateFlow @@ -39,8 +38,8 @@ open class SplashPresenter( // TODO: Conditional nav - Will implement once we got persistant storage from nish to save flags // If firstTimeApp launch, goto Onboarding[clientMode] (androidNode / xClient) // If not, goto TabContainerScreen - rootNavigator.navigate(Routes.Onboarding.name) { - // navController.navigate(Routes.TabContainer.name) { + // rootNavigator.navigate(Routes.Onboarding.name) { + rootNavigator.navigate(Routes.TabContainer.name) { popUpTo(Routes.Splash.name) { inclusive = true } } } diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/MyTrades.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/MyTrades.kt deleted file mode 100644 index f48a8b7e..00000000 --- a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/MyTrades.kt +++ /dev/null @@ -1,32 +0,0 @@ - -package network.bisq.mobile.presentation.ui.uicases.trades - -import androidx.compose.foundation.layout.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.navigation.NavController -import androidx.navigation.NavHostController -import network.bisq.mobile.presentation.ui.components.atoms.BisqText -import network.bisq.mobile.presentation.ui.components.layout.BisqScrollLayout -import network.bisq.mobile.presentation.ui.theme.BisqTheme -import org.jetbrains.compose.resources.ExperimentalResourceApi -import org.koin.compose.koinInject -import org.koin.core.qualifier.named - -@OptIn(ExperimentalResourceApi::class) -@Composable -fun MyTradesScreen() { - BisqScrollLayout(verticalArrangement = Arrangement.Center) { - Box( - modifier = Modifier - .fillMaxSize(), - contentAlignment = Alignment.Center - ) { - BisqText.h2Regular( - text = "My Trades", - color = BisqTheme.colors.light1, - ) - } - } -} \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/MyTradesPresenter.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/MyTradesPresenter.kt new file mode 100644 index 00000000..c00566c9 --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/MyTradesPresenter.kt @@ -0,0 +1,60 @@ +package network.bisq.mobile.presentation.ui.uicases.trades + +import androidx.navigation.NavController +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import network.bisq.mobile.domain.data.BackgroundDispatcher +import network.bisq.mobile.domain.data.model.BisqOffer +import network.bisq.mobile.domain.data.repository.MyTradesRepository +import network.bisq.mobile.presentation.BasePresenter +import network.bisq.mobile.presentation.MainPresenter +import network.bisq.mobile.presentation.ui.navigation.Routes + +class MyTradesPresenter( + mainPresenter: MainPresenter, + private val tabController: NavController, + private val myTradesRepository: MyTradesRepository +) : BasePresenter(mainPresenter), IMyTrades { + + private val _myTrades = MutableStateFlow>(emptyList()) + override val myTrades: StateFlow> = _myTrades + + override fun navigateToCurrencyList() { + + tabController.navigate(Routes.TabCurrencies.name) { + tabController.graph.startDestinationRoute?.let { route -> + popUpTo(route) { + saveState = true + } + } + launchSingleTop = true + restoreState = true + } + } + + private fun refresh() { + CoroutineScope(BackgroundDispatcher).launch { + try { + delay(1000) // TODO: To simulate loading. Yet to be handled + val trades = myTradesRepository.fetch() + _myTrades.value = trades?.trades ?: emptyList() + } catch (e: Exception) { + // Handle errors + println("Error: ${e.message}") + } + } + } + + override fun onViewAttached() { + super.onViewAttached() + refresh() + } + + override fun onResume() { + super.onResume() + refresh() + } +} \ No newline at end of file diff --git a/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/MyTradesScreen.kt b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/MyTradesScreen.kt new file mode 100644 index 00000000..ef2d6647 --- /dev/null +++ b/bisqapps/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/ui/uicases/trades/MyTradesScreen.kt @@ -0,0 +1,90 @@ +package network.bisq.mobile.presentation.ui.uicases.trades + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.navigation.NavHostController +import bisqapps.shared.presentation.generated.resources.Res +import bisqapps.shared.presentation.generated.resources.img_no_trades +import kotlinx.coroutines.flow.StateFlow +import network.bisq.mobile.domain.data.model.BisqOffer +import network.bisq.mobile.presentation.ViewPresenter +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.layout.BisqScrollLayout +import network.bisq.mobile.presentation.ui.components.molecules.OfferCard +import network.bisq.mobile.presentation.ui.helpers.RememberPresenterLifecycle +import network.bisq.mobile.presentation.ui.theme.BisqTheme +import org.jetbrains.compose.resources.painterResource +import org.koin.compose.koinInject +import org.koin.core.parameter.parametersOf +import org.koin.core.qualifier.named + +interface IMyTrades: ViewPresenter { + val myTrades: StateFlow> + + fun navigateToCurrencyList() +} + +@Composable +fun MyTradesScreen() { + val navController: NavHostController = koinInject(named("RootNavController")) + val tabController: NavHostController = koinInject(named("TabNavController")) + + val presenter: IMyTrades = koinInject { parametersOf(navController, tabController) } + + val myTrades: List = presenter.myTrades.collectAsState().value + + RememberPresenterLifecycle(presenter) + + if (myTrades.isEmpty()) { + NoTradesSection(presenter) + } else { + TradeList(presenter, myTrades) + } + +} + + +@Composable +fun TradeList(presenter: IMyTrades, myTrades: List) { + + LazyColumn(modifier = Modifier.padding(top= 48.dp)) { + items(myTrades) { offer -> + OfferCard( onClick = {} ) + } + } + +} + +@Composable +fun NoTradesSection(presenter: IMyTrades) { + BisqScrollLayout(verticalArrangement = Arrangement.Center) { + Column( + modifier = Modifier.padding(vertical = 52.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(64.dp) + ){ + Image( + painterResource(Res.drawable.img_no_trades), "", + modifier = Modifier.height(272.dp).width(350.dp) + ) + BisqText.h3Regular( + text = "A journey of a thousand miles begins with a first step!", + color = BisqTheme.colors.light1, + textAlign = TextAlign.Center + ) + BisqButton( + text = "Start your first trade", + onClick = { presenter.navigateToCurrencyList() } + ) + } + } +} \ No newline at end of file