Updated on 2026-08-14

This commit is contained in:
Tangem 2025-05-12 19:25:43 +05:00
parent 88b622053d
commit 8b47cd5aba
3 changed files with 52 additions and 7 deletions

View file

@ -0,0 +1,30 @@
package com.tangem.core.ui.extensions
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.semantics.Role
import com.tangem.core.ui.utils.MultipleClickPreventer
/**
* Clickable modifier with debounce multiple click in a short period of time
*/
fun Modifier.clickableSingle(
enabled: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
onClick: () -> Unit,
) = composed {
val multipleEventsCutter = remember { MultipleClickPreventer.get() }
Modifier.clickable(
enabled = enabled,
onClickLabel = onClickLabel,
onClick = { multipleEventsCutter.processEvent { onClick() } },
role = role,
indication = LocalIndication.current,
interactionSource = remember { MutableInteractionSource() },
)
}

View file

@ -2,6 +2,9 @@ package com.tangem.core.ui.utils
import android.os.SystemClock
/**
* Debounce multiple events (e.i. clicks, etc) in a short period of time
*/
interface MultipleClickPreventer {
fun processEvent(event: () -> Unit)
@ -24,4 +27,9 @@ private class DefaultMultipleClickPreventer : MultipleClickPreventer {
companion object {
private const val TIME_BETWEEN_CLICK_IN_MS = 500L
}
}
}
/**
* Debounce multiple events (e.i. clicks, etc) in a short period of time
*/
fun singleEvent(event: () -> Unit) = MultipleClickPreventer.get().processEvent(event)

View file

@ -2,7 +2,6 @@ package com.tangem.features.send.v2.common.ui
import androidx.compose.animation.*
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
@ -26,10 +25,12 @@ import com.tangem.core.ui.components.SpacerW12
import com.tangem.core.ui.components.buttons.common.TangemButton
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
import com.tangem.features.send.v2.send.ui.state.ButtonsUM
import com.tangem.core.ui.extensions.clickableSingle
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.singleEvent
import com.tangem.features.send.v2.common.ui.state.NavigationUM
import com.tangem.features.send.v2.send.ui.state.ButtonsUM
@Composable
internal fun SendNavigationButtons(navigationUM: NavigationUM, modifier: Modifier = Modifier) {
@ -70,7 +71,7 @@ private fun SendNavigationButton(navigationUM: NavigationUM, modifier: Modifier
modifier = Modifier
.clip(RoundedCornerShape(16.dp))
.background(TangemTheme.colors.button.secondary)
.clickable(onClick = wrappedNavigationUM.onClick)
.clickableSingle(onClick = wrappedNavigationUM.onClick)
.padding(12.dp),
)
SpacerW12()
@ -110,7 +111,11 @@ private fun SendDoneButtons(pairButtonsUM: ButtonsUM.SecondaryPairButtonsUM?, mo
SecondaryButtonIconStart(
text = wrappedPairButtonsUM.leftText.resolveReference(),
iconResId = wrappedPairButtonsUM.leftIconResId!!,
onClick = wrappedPairButtonsUM.onLeftClick,
onClick = {
singleEvent {
wrappedPairButtonsUM.onLeftClick
}
},
modifier = Modifier.weight(1f),
)
SpacerW12()
@ -118,8 +123,10 @@ private fun SendDoneButtons(pairButtonsUM: ButtonsUM.SecondaryPairButtonsUM?, mo
text = wrappedPairButtonsUM.rightText.resolveReference(),
iconResId = wrappedPairButtonsUM.rightIconResId!!,
onClick = {
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
wrappedPairButtonsUM.onRightClick()
singleEvent {
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
wrappedPairButtonsUM.onRightClick()
}
},
modifier = Modifier.weight(1f),
)