Updated on 2026-08-14

This commit is contained in:
Tangem 2022-05-21 19:01:17 +03:00
parent fffd53dcf2
commit b5c16ef323
6 changed files with 71 additions and 27 deletions

View file

@ -16,6 +16,7 @@ fun BlockchainSpinner(
isEnabled: Boolean = true,
textFieldConverter: (Blockchain) -> String,
dropdownItemView: @Composable ((Blockchain) -> Unit)? = null,
closePopupTrigger: ClosePopupTrigger = ClosePopupTrigger(),
onItemSelected: (Blockchain) -> Unit,
) {
OutlinedSpinner(
@ -26,6 +27,7 @@ fun BlockchainSpinner(
textFieldConverter = textFieldConverter,
dropdownItemView = dropdownItemView,
isEnabled = isEnabled,
onItemSelected = onItemSelected
onItemSelected = onItemSelected,
closePopupTrigger = closePopupTrigger,
)
}

View file

@ -1,11 +1,14 @@
package com.tangem.tap.common.compose
import android.os.Handler
import android.os.Looper
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.os.postDelayed
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.extensions.VoidCallback
import com.tangem.domain.common.form.Field
@ -25,7 +28,8 @@ fun <T> OutlinedSpinner(
textFieldConverter: (T) -> String = { it.toString() },
dropdownItemView: @Composable ((T) -> Unit)? = null,
isEnabled: Boolean = true,
onClose: VoidCallback = {}
onClose: VoidCallback = {},
closePopupTrigger: ClosePopupTrigger = ClosePopupTrigger(),
) {
val rIsExpanded = remember { mutableStateOf(false) }
val stateSelectedItem = remember { mutableStateOf(selectedItem.value) }
@ -43,6 +47,13 @@ fun <T> OutlinedSpinner(
onClose()
}
closePopupTrigger.close = {
onDismissRequest()
Handler(Looper.getMainLooper()).postDelayed(100) {
closePopupTrigger.onCloseComplete()
}
}
ExposedDropdownMenuBox(
expanded = rIsExpanded.value,
onExpandedChange = { rIsExpanded.value = !rIsExpanded.value },
@ -57,16 +68,17 @@ fun <T> OutlinedSpinner(
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = rIsExpanded.value) },
)
if (!isEnabled) return@ExposedDropdownMenuBox
ExposedDropdownMenu(
expanded = rIsExpanded.value,
onDismissRequest = onDismissRequest,
) {
itemList.forEach { item ->
DropdownMenuItem(onClick = { onDropDownItemSelectedInternal(item) }) {
when (dropdownItemView) {
null -> Text(textFieldConverter(item))
else -> dropdownItemView(item)
if (isEnabled) {
ExposedDropdownMenu(
expanded = rIsExpanded.value,
onDismissRequest = onDismissRequest,
) {
itemList.forEach { item ->
DropdownMenuItem(onClick = { onDropDownItemSelectedInternal(item) }) {
when (dropdownItemView) {
null -> Text(textFieldConverter(item))
else -> dropdownItemView(item)
}
}
}
}
@ -74,6 +86,12 @@ fun <T> OutlinedSpinner(
}
}
class ClosePopupTrigger {
var close: () -> Unit = {}
var onCloseComplete: () -> Unit = {}
var isTriggered = false
}
@Preview
@Composable
fun TestSpinnerPreview() {

View file

@ -13,7 +13,9 @@ import androidx.compose.ui.platform.ComposeView
import com.google.accompanist.appcompattheme.AppCompatTheme
import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenState
import com.tangem.domain.redux.domainStore
import com.tangem.tap.common.compose.ClosePopupTrigger
import com.tangem.tap.features.BaseStoreFragment
import com.tangem.tap.features.FragmentOnBackPressedHandler
import com.tangem.tap.features.addBackPressHandler
import com.tangem.tap.features.tokens.addCustomToken.compose.AddCustomTokenScreen
import com.tangem.wallet.R
@ -48,16 +50,25 @@ class AddCustomTokenFragment : BaseStoreFragment(R.layout.view_compose_fragment)
it.setTitle(R.string.add_custom_token_title)
}
val closePopupTrigger = initClosingPopupTriggerEvent()
view.findViewById<ComposeView>(R.id.view_compose)?.setContent {
AppCompatTheme(requireContext()) {
Box(modifier = Modifier
.fillMaxSize()
) {
AddCustomTokenScreen(state)
AddCustomTokenScreen(state, closePopupTrigger)
}
}
}
addBackPressHandler(this)
}
private fun initClosingPopupTriggerEvent(): ClosePopupTrigger = ClosePopupTrigger().apply {
onCloseComplete = ::handleOnBackPressed
addBackPressHandler(object : FragmentOnBackPressedHandler {
override fun handleOnBackPressed() = close()
})
}
}

View file

@ -21,10 +21,7 @@ import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenState
import com.tangem.domain.features.addCustomToken.redux.ScreenState
import com.tangem.domain.features.addCustomToken.redux.ViewStates
import com.tangem.domain.redux.domainStore
import com.tangem.tap.common.compose.AddCustomTokenWarning
import com.tangem.tap.common.compose.ComposeDialogManager
import com.tangem.tap.common.compose.ToggledRippleTheme
import com.tangem.tap.common.compose.keyboardAsState
import com.tangem.tap.common.compose.*
import com.tangem.tap.common.moduleMessage.ModuleMessageConverter
import com.tangem.tap.features.tokens.addCustomToken.compose.test.TestAddCustomTokenActions
import com.tangem.wallet.R
@ -35,7 +32,10 @@ import com.tangem.wallet.R
private class AddCustomTokenScreen {} // for simple search
@Composable
fun AddCustomTokenScreen(state: MutableState<AddCustomTokenState>) {
fun AddCustomTokenScreen(
state: MutableState<AddCustomTokenState>,
closePopupTrigger: ClosePopupTrigger,
) {
val scaffoldState = rememberScaffoldState()
Scaffold(
@ -64,7 +64,7 @@ fun AddCustomTokenScreen(state: MutableState<AddCustomTokenState>) {
.fillMaxWidth()
.padding(16.dp)
) {
FormFields(state)
FormFields(state, closePopupTrigger)
}
}
}
@ -79,7 +79,10 @@ fun AddCustomTokenScreen(state: MutableState<AddCustomTokenState>) {
}
@Composable
private fun FormFields(state: MutableState<AddCustomTokenState>) {
private fun FormFields(
state: MutableState<AddCustomTokenState>,
closePopupTrigger: ClosePopupTrigger,
) {
val context = LocalContext.current
val errorConverter = remember { ModuleMessageConverter(context) }
@ -88,11 +91,11 @@ private fun FormFields(state: MutableState<AddCustomTokenState>) {
val data = ScreenFieldData.fromState(field, stateValue, errorConverter)
when (field.id) {
ContractAddress -> TokenContractAddressView(data)
Network -> TokenNetworkView(data, stateValue)
Network -> TokenNetworkView(data, stateValue, closePopupTrigger)
Name -> TokenNameView(data)
Symbol -> TokenSymbolView(data)
Decimals -> TokenDecimalsView(data)
DerivationPath -> TokenDerivationPathView(data, stateValue)
DerivationPath -> TokenDerivationPathView(data, stateValue, closePopupTrigger)
}
}
}

View file

@ -86,7 +86,11 @@ fun TokenNameView(screenFieldData: ScreenFieldData) {
}
@Composable
fun TokenNetworkView(screenFieldData: ScreenFieldData, state: AddCustomTokenState) {
fun TokenNetworkView(
screenFieldData: ScreenFieldData,
state: AddCustomTokenState,
closePopupTrigger: ClosePopupTrigger,
) {
if (!screenFieldData.viewState.isVisible) return
val notSelected = stringResource(id = R.string.custom_token_network_input_not_selected)
@ -98,6 +102,7 @@ fun TokenNetworkView(screenFieldData: ScreenFieldData, state: AddCustomTokenStat
selectedItem = networkField.data,
isEnabled = screenFieldData.viewState.isEnabled,
textFieldConverter = { state.blockchainToName(it) ?: notSelected },
closePopupTrigger = closePopupTrigger,
) { domainStore.dispatch(OnTokenNetworkChanged(Field.Data(it, true))) }
SpacerH8()
}
@ -138,7 +143,11 @@ fun TokenDecimalsView(screenFieldData: ScreenFieldData) {
}
@Composable
fun TokenDerivationPathView(screenFieldData: ScreenFieldData, state: AddCustomTokenState) {
fun TokenDerivationPathView(
screenFieldData: ScreenFieldData,
state: AddCustomTokenState,
closePopupTrigger: ClosePopupTrigger,
) {
if (!screenFieldData.viewState.isVisible) return
val notSelected = stringResource(id = R.string.custom_token_derivation_path_default)
@ -154,7 +163,8 @@ fun TokenDerivationPathView(screenFieldData: ScreenFieldData, state: AddCustomTo
val derivationPathName = state.blockchainToName(blockchain, true) ?: notSelected
val blockchainName = state.blockchainToName(blockchain) ?: notSelected
TitleSubtitle(derivationPathName, blockchainName)
}
},
closePopupTrigger = closePopupTrigger,
) { domainStore.dispatch(OnTokenDerivationPathChanged(Field.Data(it, true))) }
SpacerH8()
}

View file

@ -60,7 +60,7 @@ dependencies {
implementation implementation(project(path: ':common'))
// Tangem sdk's
implementation 'com.tangem:blockchain:develop-77'
implementation 'com.tangem:blockchain:develop-78'
implementation 'com.tangem.tangem-sdk-kotlin:core:develop-142'
implementation 'com.tangem.tangem-sdk-kotlin:android:develop-142'