Updated on 2026-08-14
This commit is contained in:
parent
bf329401a1
commit
c826afb5c3
3 changed files with 88 additions and 99 deletions
|
|
@ -5,12 +5,10 @@ import android.view.Menu
|
|||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import by.kirich1409.viewbindingdelegate.viewBinding
|
||||
import com.google.accompanist.appcompattheme.AppCompatTheme
|
||||
|
|
@ -22,6 +20,8 @@ import com.tangem.tap.common.extensions.dispatchNotification
|
|||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.common.extensions.getString
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.BaseFragment
|
||||
import com.tangem.tap.features.addBackPressHandler
|
||||
import com.tangem.tap.features.tokens.redux.ContractAddress
|
||||
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
|
||||
import com.tangem.tap.features.tokens.redux.TokensAction
|
||||
|
|
@ -40,8 +40,7 @@ import kotlinx.coroutines.flow.launchIn
|
|||
import kotlinx.coroutines.flow.onEach
|
||||
import org.rekotlin.StoreSubscriber
|
||||
|
||||
class AddTokensFragment : Fragment(R.layout.fragment_add_tokens),
|
||||
StoreSubscriber<TokensState> {
|
||||
class AddTokensFragment : BaseFragment(R.layout.fragment_add_tokens), StoreSubscriber<TokensState> {
|
||||
|
||||
private val binding: FragmentAddTokensBinding by viewBinding(FragmentAddTokensBinding::bind)
|
||||
private var tokensState: MutableState<TokensState> = mutableStateOf(store.state.tokensState)
|
||||
|
|
@ -51,33 +50,7 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens),
|
|||
super.onCreate(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
Analytics.send(ManageTokens.ScreenOpened())
|
||||
|
||||
activity?.onBackPressedDispatcher?.addCallback(
|
||||
this,
|
||||
object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
store.dispatch(TokensAction.ResetState)
|
||||
}
|
||||
},
|
||||
)
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
enterTransition = inflater.inflateTransition(R.transition.slide_right)
|
||||
exitTransition = inflater.inflateTransition(R.transition.fade)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
store.subscribe(this) { state ->
|
||||
state.skipRepeats { oldState, newState ->
|
||||
oldState.tokensState == newState.tokensState
|
||||
}.select { it.tokensState }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
store.unsubscribe(this)
|
||||
addBackPressHandler(this)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) = with(binding) {
|
||||
|
|
@ -96,11 +69,7 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens),
|
|||
}
|
||||
|
||||
val onLoadMore = {
|
||||
store.dispatch(
|
||||
TokensAction.LoadMore(
|
||||
scanResponse = store.state.globalState.scanResponse,
|
||||
),
|
||||
)
|
||||
store.dispatch(TokensAction.LoadMore(scanResponse = store.state.globalState.scanResponse))
|
||||
}
|
||||
|
||||
cvCurrencies.setContent {
|
||||
|
|
@ -115,24 +84,23 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens),
|
|||
}
|
||||
}
|
||||
|
||||
override fun newState(state: TokensState) {
|
||||
if (activity == null || view == null) return
|
||||
val toolbarTitle =
|
||||
if (state.allowToAdd) R.string.main_manage_tokens else R.string.search_tokens_title
|
||||
tokensState.value = state
|
||||
binding.toolbar.title = getString(toolbarTitle)
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
store.subscribe(this) { state ->
|
||||
state
|
||||
.skipRepeats { oldState, newState -> oldState.tokensState == newState.tokensState }
|
||||
.select { it.tokensState }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.menu_search -> true
|
||||
R.id.menu_navigate_add_custom_token -> {
|
||||
Analytics.send(ManageTokens.ButtonCustomToken())
|
||||
store.dispatch(TokensAction.PrepareAndNavigateToAddCustomToken)
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
store.unsubscribe(this)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
store.dispatch(TokensAction.ResetState)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
|
|
@ -156,25 +124,50 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens),
|
|||
return super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.menu_search -> true
|
||||
R.id.menu_navigate_add_custom_token -> {
|
||||
Analytics.send(ManageTokens.ButtonCustomToken())
|
||||
store.dispatch(TokensAction.PrepareAndNavigateToAddCustomToken)
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
override fun configureTransitions() {
|
||||
super.configureTransitions()
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
enterTransition = inflater.inflateTransition(R.transition.slide_right)
|
||||
exitTransition = inflater.inflateTransition(R.transition.fade)
|
||||
}
|
||||
|
||||
override fun handleOnBackPressed() {
|
||||
super.handleOnBackPressed()
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
store.dispatch(TokensAction.ResetState)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun newState(state: TokensState) {
|
||||
if (activity == null || view == null) return
|
||||
val toolbarTitle =
|
||||
if (state.allowToAdd) R.string.main_manage_tokens else R.string.search_tokens_title
|
||||
tokensState.value = state
|
||||
binding.toolbar.title = getString(toolbarTitle)
|
||||
}
|
||||
}
|
||||
|
||||
fun SearchView.inputtedTextAsFlow(): Flow<String> = callbackFlow {
|
||||
val watcher =
|
||||
setOnQueryTextListener(
|
||||
object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
return false
|
||||
}
|
||||
val watcher = setOnQueryTextListener(
|
||||
object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String?): Boolean = false
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
trySend(newText ?: "")
|
||||
return false
|
||||
}
|
||||
},
|
||||
)
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
trySend(newText ?: "")
|
||||
return false
|
||||
}
|
||||
},
|
||||
)
|
||||
awaitClose { (watcher) }
|
||||
}
|
||||
|
|
@ -83,25 +83,21 @@ fun CurrenciesScreen(
|
|||
|
||||
Scaffold(
|
||||
floatingActionButton = {
|
||||
if (tokensState.value.allowToAdd) SaveChangesButton(isKeyboardOpen) {
|
||||
onSaveChanges(addedTokensState.value, addedBlockchainsState.value)
|
||||
if (tokensState.value.allowToAdd) {
|
||||
SaveChangesButton(isKeyboardOpen) {
|
||||
onSaveChanges(addedTokensState.value, addedBlockchainsState.value)
|
||||
}
|
||||
}
|
||||
},
|
||||
floatingActionButtonPosition = FabPosition.Center,
|
||||
) {
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = tokensState.value.loadCoinsState == LoadCoinsState.LOADING,
|
||||
enter = fadeIn(),
|
||||
exit = fadeOut(),
|
||||
) {
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
) {
|
||||
CircularProgressIndicator(
|
||||
color = Color(0xFF1ACE80),
|
||||
)
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator(color = Color(0xFF1ACE80))
|
||||
}
|
||||
}
|
||||
AnimatedVisibility(
|
||||
|
|
@ -148,21 +144,19 @@ private fun toggleBlockchain(
|
|||
currencySymbol = blockchain.currency,
|
||||
),
|
||||
)
|
||||
} else if (isAddedOnMainScreen) {
|
||||
store.dispatchDialogShow(
|
||||
WalletDialog.RemoveWalletDialog(
|
||||
currencyTitle = blockchain.name,
|
||||
onOk = {
|
||||
analyticsCurrencyTypeParam.sendOn()
|
||||
addedBlockchainsState.removeAndNotify(blockchain)
|
||||
},
|
||||
),
|
||||
)
|
||||
} else {
|
||||
if (isAddedOnMainScreen) {
|
||||
store.dispatchDialogShow(
|
||||
WalletDialog.RemoveWalletDialog(
|
||||
currencyTitle = blockchain.name,
|
||||
onOk = {
|
||||
analyticsCurrencyTypeParam.sendOn()
|
||||
addedBlockchainsState.removeAndNotify(blockchain)
|
||||
},
|
||||
),
|
||||
)
|
||||
} else {
|
||||
analyticsCurrencyTypeParam.sendOff()
|
||||
addedBlockchainsState.removeAndNotify(blockchain)
|
||||
}
|
||||
analyticsCurrencyTypeParam.sendOff()
|
||||
addedBlockchainsState.removeAndNotify(blockchain)
|
||||
}
|
||||
} else {
|
||||
analyticsCurrencyTypeParam.sendOn()
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.tap.domain.tokens.Contract
|
||||
import com.tangem.tap.domain.tokens.Currency
|
||||
import com.tangem.tap.features.tokens.redux.ContractAddress
|
||||
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
|
||||
|
|
@ -30,22 +31,20 @@ fun CurrencyExpandedContent(
|
|||
exit = fadeOut() + shrinkVertically(),
|
||||
) {
|
||||
val blockchains = currency.contracts.map { it.blockchain }
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
blockchains.mapIndexed { index, blockchain ->
|
||||
val contract = currency.contracts.firstOrNull { it.blockchain == blockchain }
|
||||
val currencyContract = currency.contracts
|
||||
.firstOrNull { it.blockchain == blockchain }
|
||||
?: return@mapIndexed
|
||||
|
||||
val added = if (contract.address != null) {
|
||||
addedTokens.map { it.token.contractAddress }.contains(contract.address)
|
||||
val added = if (currencyContract.address != null) {
|
||||
addedTokens.any(currencyContract::isInclude)
|
||||
} else {
|
||||
addedBlockchains.contains(blockchain)
|
||||
}
|
||||
NetworkItem(
|
||||
currency = currency,
|
||||
contract = contract,
|
||||
contract = currencyContract,
|
||||
blockchain = blockchain,
|
||||
allowToAdd = allowToAdd,
|
||||
added = added,
|
||||
|
|
@ -57,4 +56,7 @@ fun CurrencyExpandedContent(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Contract.isInclude(addedToken: TokenWithBlockchain): Boolean =
|
||||
address == addedToken.token.contractAddress && blockchain == addedToken.blockchain
|
||||
Loading…
Add table
Add a link
Reference in a new issue