Updated on 2026-08-14

This commit is contained in:
Tangem 2021-04-12 11:00:23 +00:00
commit cedea0f61d
6 changed files with 72 additions and 276 deletions

View file

@ -0,0 +1,48 @@
package com.tangem.tap.common.toggleWidget
import android.graphics.drawable.Drawable
import android.view.View
import com.google.android.material.button.MaterialButton
import com.tangem.tap.common.extensions.hide
import com.tangem.tap.common.extensions.show
/**
[REDACTED_AUTHOR]
*/
open class IndeterminateProgressButtonWidget(
private val button: MaterialButton,
private val progress: View,
initialState: ProgressState = ProgressState.None
) : ViewStateWidget {
private var initialButtonText: CharSequence = button.text
private var icon: Drawable? = null
init {
icon = button.icon
changeState(initialState)
}
override fun changeState(state: WidgetState) {
val progressState = state as? ProgressState ?: return
when (progressState) {
is ProgressState.None -> switchToNone()
is ProgressState.Progress -> switchToProgress()
}
}
protected open fun switchToNone() {
button.isClickable = true
button.icon = icon
button.text = initialButtonText
progress.hide()
}
protected open fun switchToProgress() {
button.isClickable = false
button.icon = null
button.text = ""
progress.show()
}
}

View file

@ -1,85 +0,0 @@
package com.tangem.merchant.common.toggleWidget
import android.view.View
import android.view.ViewGroup
/**
[REDACTED_AUTHOR]
*/
interface ToggleState
interface StateModifier {
fun stateChanged(container: ViewGroup, view: View, state: ToggleState)
}
interface ToggleView {
val mainViewModifiers: MutableList<StateModifier>
val toggleViewModifiers: MutableList<StateModifier>
fun setState(state: ToggleState, andApply: Boolean = true)
fun applyState()
fun getView(): View
fun getMainView(): View
fun getToggleView(): View
}
class ToggleWidget : ToggleView {
private val container: ViewGroup
private val mainView: View
private val toggleView: View
private var state: ToggleState
constructor(
container: ViewGroup,
mainView: View,
toggleView: View,
initialState: ToggleState,
mainViewModifier: List<StateModifier> = mutableListOf(),
loadingViewModifier: List<StateModifier> = mutableListOf()
) {
this.container = container
this.mainView = mainView
this.toggleView = toggleView
this.state = initialState
this.mainViewModifiers.addAll(mainViewModifier)
this.toggleViewModifiers.addAll(loadingViewModifier)
}
constructor(
container: ViewGroup,
mainViewId: Int,
toggleViewId: Int,
initialState: ToggleState,
mainViewModifier: List<StateModifier> = mutableListOf(),
loadingViewModifier: List<StateModifier> = mutableListOf()
) {
this.container = container
this.mainView = container.findViewById(mainViewId)
this.toggleView = container.findViewById(toggleViewId)
this.state = initialState
this.mainViewModifiers.addAll(mainViewModifier)
this.toggleViewModifiers.addAll(loadingViewModifier)
}
override val mainViewModifiers: MutableList<StateModifier> = mutableListOf()
override val toggleViewModifiers: MutableList<StateModifier> = mutableListOf()
override fun setState(state: ToggleState, andApply: Boolean) {
this.state = state
if (andApply) applyState()
}
override fun applyState() {
mainViewModifiers.forEach { it.stateChanged(container, mainView, state) }
toggleViewModifiers.forEach { it.stateChanged(container, toggleView, state) }
}
override fun getView(): View = container
override fun getMainView(): View = mainView
override fun getToggleView(): View = toggleView
}

View file

@ -0,0 +1,16 @@
package com.tangem.tap.common.toggleWidget
/**
[REDACTED_AUTHOR]
*/
interface WidgetState
interface ViewStateWidget {
fun changeState(state: WidgetState)
}
sealed class ProgressState : WidgetState {
object None : ProgressState()
data class Progress(val progress: Int = 0) : ProgressState()
}

View file

@ -1,145 +0,0 @@
package com.tangem.tap.common.toggleWidget
import android.graphics.drawable.Drawable
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.core.widget.TextViewCompat
import com.google.android.material.button.MaterialButton
import com.tangem.merchant.common.toggleWidget.StateModifier
import com.tangem.merchant.common.toggleWidget.ToggleState
import com.tangem.tap.common.extensions.beginDelayedTransition
/**
[REDACTED_AUTHOR]
*/
sealed class ProgressState : ToggleState {
class Progress : ProgressState()
class None : ProgressState()
}
class ReplaceTextStateModifier(
private val initialText: String,
private val replaceText: String = ""
) : StateModifier {
override fun stateChanged(container: ViewGroup, view: View, state: ToggleState) {
val tv = view as? TextView ?: return
when (state) {
is ProgressState.Progress -> {
tv.text = replaceText
}
is ProgressState.None -> {
tv.text = initialText
}
}
}
}
class TextViewDrawableStateModifier(
private val initialDrawable: Drawable?,
private val replaceDrawable: Drawable?,
private val position: Int
) : StateModifier {
companion object {
val LEFT = 1
val RIGHT = 2
}
override fun stateChanged(container: ViewGroup, view: View, state: ToggleState) {
val drawable = when (state) {
is ProgressState.Progress -> replaceDrawable
is ProgressState.None -> initialDrawable
else -> null
}
val drawableChanger = getChanger(view)
drawableChanger?.change(drawable, position)
}
private fun getChanger(view: View): DrawableChanger? = when (view) {
is MaterialButton -> MaterialButtonChanger(view)
is Button -> TextViewChanger(view)
is TextView -> TextViewChanger(view)
else -> null
}
internal interface DrawableChanger {
fun change(drawable: Drawable?, position: Int)
}
internal class TextViewChanger(private val view: TextView) : DrawableChanger {
override fun change(drawable: Drawable?, position: Int) {
when (position) {
LEFT -> setLeft(drawable)
RIGHT -> setRight(drawable)
}
}
private fun setLeft(drawable: Drawable?) {
if (drawable == null) {
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(view, 0, 0, 0, 0)
} else {
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(view, drawable, null, null, null)
}
}
private fun setRight(drawable: Drawable?) {
if (drawable == null) {
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(view, 0, 0, 0, 0)
} else {
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(view, null, null, drawable, null)
}
}
}
internal class MaterialButtonChanger(private val view: MaterialButton) : DrawableChanger {
override fun change(drawable: Drawable?, position: Int) {
when (position) {
LEFT -> setLeft(drawable)
RIGHT -> setRight(drawable)
}
}
private fun setLeft(drawable: Drawable?) {
view.iconGravity = MaterialButton.ICON_GRAVITY_START
view.icon = drawable
}
private fun setRight(drawable: Drawable?) {
view.iconGravity = MaterialButton.ICON_GRAVITY_END
view.icon = drawable
}
}
}
class ShowHideStateModifier(
private val isShowOnLoading: Boolean = true,
private val typeOfHiding: Int = View.INVISIBLE
) : StateModifier {
override fun stateChanged(container: ViewGroup, view: View, state: ToggleState) {
container.beginDelayedTransition()
view.visibility = when (state) {
is ProgressState.Progress -> if (isShowOnLoading) View.VISIBLE else typeOfHiding
is ProgressState.None -> if (isShowOnLoading) typeOfHiding else View.VISIBLE
else -> return
}
}
}
class ClickableStateModifier(
private val isClickableOnLoading: Boolean = false
) : StateModifier {
override fun stateChanged(container: ViewGroup, view: View, state: ToggleState) {
view.isClickable = when (state) {
is ProgressState.Progress -> isClickableOnLoading
is ProgressState.None -> !isClickableOnLoading
else -> return
}
}
}

View file

@ -13,12 +13,10 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.textfield.TextInputEditText
import com.tangem.Message
import com.tangem.merchant.common.toggleWidget.ToggleWidget
import com.tangem.tangem_sdk_new.extensions.dpToPx
import com.tangem.tangem_sdk_new.extensions.hideSoftKeyboard
import com.tangem.tap.common.KeyboardObserver
import com.tangem.tap.common.entities.TapCurrency
import com.tangem.tap.common.extensions.getDrawableCompat
import com.tangem.tap.common.extensions.getFromClipboard
import com.tangem.tap.common.extensions.setOnImeActionListener
import com.tangem.tap.common.qrCodeScan.ScanQrCodeActivity
@ -55,17 +53,11 @@ import java.text.DecimalFormatSymbols
*/
class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
lateinit var sendBtn: ToggleWidget
lateinit var sendBtn: ViewStateWidget
private lateinit var etAmountToSend: TextInputEditText
private lateinit var warningsAdapter: WarningMessagesAdapter
private fun initSendButtonStates() {
sendBtn = ToggleWidget(flSendButtonContainer, btnSend, progress, ProgressState.None())
sendBtn.setupSendButtonStateModifiers(requireContext())
sendBtn.setState(ProgressState.None())
}
private val sendSubscriber = SendStateSubscriber(this)
private lateinit var keyboardObserver: KeyboardObserver
@ -80,12 +72,15 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
setupAmountLayout()
setupFeeLayout()
setupWarningMessages()
}
private fun initSendButtonStates() {
btnSend.setOnClickListener {
store.dispatch(SendActionUi.SendAmountToRecipient(
Message(getString(R.string.initial_message_sign_header))
))
}
sendBtn = IndeterminateProgressButtonWidget(btnSend, progress)
}
private fun setupAddressOrPayIdLayout() {
@ -300,37 +295,4 @@ class FeeUiHelper {
}
}
}
}
//class MemoUiHelper {
// companion object {
// fun toId(memo: MemoType): Int {
// return when (memo) {
// MemoType.TEXT -> R.id.chipMemoText
// MemoType.ID -> R.id.chipMemoId
// }
// }
//
// fun toType(id: Int): MemoType {
// return when (id) {
// R.id.chipMemoText -> MemoType.TEXT
// R.id.chipMemoId -> MemoType.ID
// else -> MemoType.TEXT
// }
// }
// }
//}
private fun ToggleWidget.setupSendButtonStateModifiers(context: Context) {
mainViewModifiers.clear()
mainViewModifiers.add(ReplaceTextStateModifier(context.getString(R.string.send_title), ""))
mainViewModifiers.add(
TextViewDrawableStateModifier(
context.getDrawableCompat(R.drawable.ic_arrow_right), null, TextViewDrawableStateModifier.RIGHT
))
mainViewModifiers.add(ClickableStateModifier())
toggleViewModifiers.clear()
toggleViewModifiers.add(ShowHideStateModifier())
}
}

View file

@ -119,15 +119,15 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber
when (state.sendButtonState) {
SendButtonState.ENABLED -> {
fg.btnSend.isEnabled = true
sendFragment.sendBtn.setState(ProgressState.None(), true)
sendFragment.sendBtn.changeState(ProgressState.None)
}
SendButtonState.DISABLED -> {
fg.btnSend.isEnabled = false
sendFragment.sendBtn.setState(ProgressState.None(), true)
sendFragment.sendBtn.changeState(ProgressState.None)
}
SendButtonState.PROGRESS -> {
fg.btnSend.isEnabled = true
sendFragment.sendBtn.setState(ProgressState.Progress(), true)
sendFragment.sendBtn.changeState(ProgressState.Progress())
}
}