Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

buy or sell, and swaps #18

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.tonapps.tonkeeper.ui.screen.browser.dapp.DAppViewModel
import com.tonapps.tonkeeper.ui.screen.browser.explore.BrowserExploreViewModel
import com.tonapps.tonkeeper.ui.screen.browser.main.BrowserMainViewModel
import com.tonapps.tonkeeper.ui.screen.browser.search.BrowserSearchViewModel
import com.tonapps.tonkeeper.ui.screen.buyOrSell.utils.BuyOrSellViewModel
import com.tonapps.tonkeeper.ui.screen.collectibles.CollectiblesViewModel
import com.tonapps.tonkeeper.ui.screen.events.EventsViewModel
import com.tonapps.tonkeeper.ui.screen.settings.currency.CurrencyViewModel
Expand All @@ -34,6 +35,7 @@ import com.tonapps.tonkeeper.ui.screen.picker.list.WalletPickerAdapter
import com.tonapps.tonkeeper.ui.screen.settings.main.SettingsViewModel
import com.tonapps.tonkeeper.ui.screen.settings.security.SecurityViewModel
import com.tonapps.tonkeeper.ui.screen.settings.theme.ThemeViewModel
import com.tonapps.tonkeeper.ui.screen.swap.SwapViewModel
import com.tonapps.tonkeeper.ui.screen.wallet.WalletViewModel
import com.tonapps.tonkeeper.ui.screen.wallet.list.WalletAdapter
import kotlinx.coroutines.CoroutineScope
Expand All @@ -57,7 +59,8 @@ val koinModel = module {

uiAdapter { WalletAdapter(get()) }
uiAdapter { WalletPickerAdapter() }

viewModel { SwapViewModel(get()) }
viewModel { BuyOrSellViewModel(get()) }
viewModel { parameters -> NameViewModel(mode = parameters.get(), get(), get()) }
viewModel { parameters -> InitViewModel(parameters.get(), get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { MainViewModel(get(), get()) }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package com.tonapps.tonkeeper.ui.screen.buyOrSell

import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.appcompat.widget.AppCompatEditText
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import com.tonapps.tonkeeper.ui.screen.buyOrSell.screen.operator.OperatorScreen
import com.tonapps.tonkeeper.ui.screen.buyOrSell.utils.BuyOrSellViewModel
import com.tonapps.tonkeeper.ui.screen.buyOrSell.utils.ProgressButtonBuyOrSellState
import com.tonapps.tonkeeper.ui.screen.buyOrSell.utils.model.DealState
import com.tonapps.tonkeeper.ui.screen.buyOrSell.utils.model.RatesModel.RatesModel
import com.tonapps.tonkeeper.ui.screen.buyOrSell.utils.model.formatNumber
import com.tonapps.tonkeeper.ui.screen.buyOrSell.view.ListPayMethodAdapter
import com.tonapps.tonkeeper.ui.screen.swap.view.progressButton.ProgressButton
import com.tonapps.tonkeeper.ui.screen.wallet.list.Item
import com.tonapps.tonkeeperx.R
import com.tonapps.uikit.list.ListCell
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import uikit.base.BaseFragment
import uikit.navigation.Navigation.Companion.navigation
import uikit.widget.SimpleRecyclerView

class BasicBuyOrSellScreen(
private val state: DealState,
private val nextNavHandler: (selectedTon: Double) -> Unit
) : Fragment(R.layout.fragment_basic_buy_or_sell),
BaseFragment.BottomSheet {

private val viewModel: BuyOrSellViewModel by activityViewModels()

private lateinit var inputFieldValue: AppCompatEditText
private lateinit var txCurUsdPrice: TextView
private lateinit var progressButton: ProgressButton
private lateinit var list: SimpleRecyclerView

private val adapter = ListPayMethodAdapter()

private var _stateButtonEnterAmount =
MutableStateFlow<ProgressButtonBuyOrSellState>(ProgressButtonBuyOrSellState.EnterAmount)

private val stateButtonEnterAmount get() = _stateButtonEnterAmount

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// init views
inputFieldValue = view.findViewById(R.id.inputFieldValue)
txCurUsdPrice = view.findViewById(R.id.txCurUsdPrice)
progressButton = view.findViewById(R.id.progressButton)
list = view.findViewById(R.id.list)
list.adapter = adapter
fillTypeMethod()



progressButton.setUpLoading(false)
progressButton.buttonClickListener = {
nextNavHandler(
inputFieldValue.text.toString().toDouble()
)
}

lifecycleScope.launch {
val stateRateBuy = launch {
viewModel.rateBuy.collectLatest { rateModel ->
if (rateModel != null) {
updateCurrencyTx(
rateModel = rateModel,
inputFieldValue.text.toString().toDouble()
)
}
}
}

val stateButtonEnterAmount = launch {
stateButtonEnterAmount.collectLatest {
when (it) {
ProgressButtonBuyOrSellState.EnterAmount -> {
progressButton.updateStateEnabledButton(false)
progressButton.updateTextInButton("Enter Amount")
}

ProgressButtonBuyOrSellState.EnteredAmountIsBelowMinimum -> {
progressButton.updateStateEnabledButton(false)
progressButton.updateTextInButton("Entered amount is below the minimum")
}

ProgressButtonBuyOrSellState.Continue -> {
progressButton.updateStateEnabledButton(true)
progressButton.updateTextInButton("Continue")
}
}
}
}

stateRateBuy.join()
stateButtonEnterAmount.join()
}
inputFieldValue.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s.toString().toDoubleOrNull() != null) {
viewModel.rateBuy.value?.let {
updateCurrencyTx(
rateModel = it,
s.toString().toDouble()
)
}
} else {
viewModel.rateBuy.value?.let {
updateCurrencyTx(
rateModel = it,
0.0
)
}
inputFieldValue.setText("0")
}
}

override fun afterTextChanged(s: Editable?) {

}
})
}

@SuppressLint("SetTextI18n")
private fun updateCurrencyTx(rateModel: RatesModel, itemInputPrice: Double) {
if (itemInputPrice == 0.0) {
txCurUsdPrice.text = "${
itemInputPrice.toString().formatNumber()
} ${rateModel.itemRates?.get(0)?.currency}"
updateStateEnterAmount(ProgressButtonBuyOrSellState.EnterAmount)
} else {
if (rateModel.itemRates?.get(0)?.rate != null) {
val inputItem =
(itemInputPrice * rateModel.itemRates[0].rate).toString().formatNumber()
txCurUsdPrice.text =
"${inputItem.toString().take(5)} ${rateModel.itemRates?.get(0)?.currency}"
if (itemInputPrice < 50) {
updateStateEnterAmount(ProgressButtonBuyOrSellState.EnteredAmountIsBelowMinimum)
} else {
updateStateEnterAmount(ProgressButtonBuyOrSellState.Continue)
}
}
}
}


private fun updateStateEnterAmount(newState: ProgressButtonBuyOrSellState) {
_stateButtonEnterAmount.update { newState }
}


@SuppressLint("UseCompatLoadingForDrawables")
private fun fillTypeMethod() {
val modelList = mutableListOf<Item.ListPayMethod>()
modelList.add(Item.ListPayMethod(name = "Credit Card", image_url = resources.getDrawable(R.drawable.pay_method_1), position = ListCell.Position.FIRST ))
modelList.add(Item.ListPayMethod(name = "Credit Card · RUB", image_url = resources.getDrawable(R.drawable.pay_method_2), position = ListCell.Position.MIDDLE ))
modelList.add(Item.ListPayMethod(name = "Cryptocurrency", image_url = resources.getDrawable(R.drawable.pay_method_3) , position = ListCell.Position.MIDDLE))
modelList.add(Item.ListPayMethod(name = "Apple Pay", image_url = resources.getDrawable(R.drawable.pay_method_4) , position = ListCell.Position.LAST))
adapter.submitList(modelList)
}

override fun onResume() {
super.onResume()
viewModel.updateDealState(state)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.tonapps.tonkeeper.ui.screen.buyOrSell

import android.os.Bundle
import uikit.base.BaseArgs

data class BuyOrSellArgs(val address: String) : BaseArgs() {


private companion object {
private const val ARG_ADDRESS = "address"
}
constructor(bundle: Bundle) : this(
address = bundle.getString(ARG_ADDRESS)!!,
)
override fun toBundle(): Bundle = Bundle().apply {
putString(ARG_ADDRESS, address)
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.tonapps.tonkeeper.ui.screen.buyOrSell

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope

import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayoutMediator
import com.tonapps.tonkeeper.ui.screen.buyOrSell.screen.currencylist.CurrencyListScreen
import com.tonapps.tonkeeper.ui.screen.buyOrSell.screen.operator.OperatorScreen
import com.tonapps.tonkeeper.ui.screen.buyOrSell.utils.BuyOrSellViewModel
import com.tonapps.tonkeeper.ui.screen.buyOrSell.view.HeaderBuyOrSellView
import com.tonapps.tonkeeperx.R
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import uikit.base.BaseFragment
import uikit.navigation.Navigation.Companion.navigation

class BuyOrSellScreen : BaseFragment(R.layout.fragment_buy_or_sell), BaseFragment.BottomSheet {

private lateinit var headerButOrSell: HeaderBuyOrSellView
private lateinit var viewPager: ViewPager2

private val viewModel: BuyOrSellViewModel by activityViewModels()
private val args: BuyOrSellArgs by lazy { BuyOrSellArgs(requireArguments()) }

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Init views

headerButOrSell = view.findViewById(R.id.headerButOrSell)
viewPager = view.findViewById(R.id.viewPager)
val adapter = ViewPagerAdapter(requireContext() as FragmentActivity) {
navigation?.add(OperatorScreen.newInstance(
it,
args.address
))
}
viewPager.adapter = adapter
headerButOrSell.setupWithViewPager(viewPager)
headerButOrSell.doOnCloseClick = {
finish()
}

lifecycleScope.launch {
val stateSelectedFiat = launch {
viewModel.selectedFiat.collectLatest {
if (it != null) {
headerButOrSell.setSelectedTypeCurrency(it.visibleCurrency)
}
}
}

stateSelectedFiat.join()
}

headerButOrSell.doOnSelectLanguageClick = {
viewModel.fiatList.value?.data?.let {
CurrencyListScreen.newInstance(
it.layoutByCountry
)
}?.let {
navigation?.add(
it
)
}
}

}

override fun onResume() {
super.onResume()
viewModel.getItemCurrency()
}

companion object {

fun newInstance(
address: String,
): BuyOrSellScreen {
val fragment = BuyOrSellScreen()
fragment.arguments = BuyOrSellArgs(address = address).toBundle()
return fragment
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.tonapps.tonkeeper.ui.screen.buyOrSell

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.tonapps.tonkeeper.ui.screen.buyOrSell.utils.model.DealState
import uikit.base.BaseFragment

class ViewPagerAdapter(
fragmentActivity: FragmentActivity,
private val nextNavHandler: (selectedTon: Double) -> Unit
) : FragmentStateAdapter(fragmentActivity) {

override fun getItemCount(): Int = 2

override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> BasicBuyOrSellScreen(DealState.BUY, nextNavHandler = nextNavHandler)
1 -> BasicBuyOrSellScreen(DealState.SELL, nextNavHandler = nextNavHandler)
else -> BasicBuyOrSellScreen(DealState.BUY, nextNavHandler = nextNavHandler)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.tonapps.tonkeeper.ui.screen.buyOrSell.screen.currencylist

import android.view.ViewGroup
import com.tonapps.tonkeeper.ui.screen.buyOrSell.utils.model.fiatModel.LayoutByCountry
import com.tonapps.tonkeeper.ui.screen.wallet.list.Item
import com.tonapps.uikit.list.BaseListAdapter
import com.tonapps.uikit.list.BaseListHolder
import com.tonapps.uikit.list.BaseListItem

class CurrencyAdapter(private val selectedToken: LayoutByCountry?) : BaseListAdapter() {

var onClickToItem: ((item: LayoutByCountry) -> Unit)? = null

override fun createHolder(parent: ViewGroup, viewType: Int): BaseListHolder<out BaseListItem> {
return when (viewType) {
Item.TYPE_CURRENCY_LIST -> CurrencyListHolder(
parent = parent,
selectedToken = selectedToken,
onClickToItem = onClickToItem
)

else -> throw IllegalArgumentException("Unknown view type: $viewType")
}
}

}
Loading