Updated on 2026-08-14
This commit is contained in:
parent
fffd53dcf2
commit
b5c16ef323
6 changed files with 71 additions and 27 deletions
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue