Updated on 2026-08-14

This commit is contained in:
Tangem 2020-09-15 17:18:55 +03:00
parent 957bc23951
commit a0ec01abfe
17 changed files with 400 additions and 177 deletions

View file

@ -2,7 +2,7 @@ package com.tangem.tap.common.redux
import com.tangem.tap.common.redux.global.globalReducer
import com.tangem.tap.common.redux.navigation.NavigationReducer
import com.tangem.tap.features.send.redux.reducers.SendReducer
import com.tangem.tap.features.send.redux.reducers.SendScreenReducer
import com.tangem.tap.features.wallet.redux.WalletReducer
import org.rekotlin.Action
@ -14,7 +14,7 @@ fun appReducer(action: Action, state: AppState?): AppState {
navigationState = NavigationReducer.reduce(action, state),
globalState = globalReducer(action, state),
walletState = WalletReducer.reduce(action, state),
sendState = SendReducer.reduce(action, state.sendState)
sendState = SendScreenReducer.reduce(action, state.sendState)
)
}

View file

@ -1,5 +1,6 @@
package com.tangem.tap.common.redux
import android.widget.Toast
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.snackbar.Snackbar
import com.tangem.tap.domain.TapError
@ -32,6 +33,12 @@ class NotificationsHandler(coordinatorLayout: CoordinatorLayout) {
showNotification(it.context.getString(message))
}
}
fun showToastNotification(message: Int) {
baseLayout.get()?.let {
Toast.makeText(it.context, it.context.getString(message), Toast.LENGTH_LONG).show()
}
}
}
val notificationsMiddleware: Middleware<AppState> = { dispatch, state ->
@ -40,6 +47,9 @@ val notificationsMiddleware: Middleware<AppState> = { dispatch, state ->
if (action is NotificationAction) {
notificationsHandler?.showNotification(action.messageResource)
}
if (action is ToastNotificationAction) {
notificationsHandler?.showToastNotification(action.messageResource)
}
if (action is ErrorAction) {
notificationsHandler?.showNotification(action.error.localizedMessage)
}
@ -48,6 +58,10 @@ val notificationsMiddleware: Middleware<AppState> = { dispatch, state ->
}
}
interface ToastNotificationAction : Action {
val messageResource: Int
}
interface NotificationAction : Action {
val messageResource: Int
}

View file

@ -0,0 +1,85 @@
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,145 @@
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
}
}
}