Updated on 2026-08-14
This commit is contained in:
parent
73339902b8
commit
0a40ed4957
46 changed files with 1856 additions and 69 deletions
|
|
@ -12,7 +12,7 @@ class CurrencyConverter(
|
|||
private val rateValue: BigDecimal,
|
||||
private val decimals: Int
|
||||
) {
|
||||
private val roundingMode = RoundingMode.DOWN
|
||||
private val roundingMode = RoundingMode.HALF_UP
|
||||
|
||||
fun toFiat(crypto: BigDecimal, fiatDecimals: Int = 2): BigDecimal {
|
||||
return toFiatUnscaled(crypto).setScale(fiatDecimals, roundingMode)
|
||||
|
|
|
|||
55
app/src/main/java/com/tangem/tap/common/DialogManager.kt
Normal file
55
app/src/main/java/com/tangem/tap/common/DialogManager.kt
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package com.tangem.tap.common
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import com.tangem.tap.common.redux.global.GlobalState
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectDialog
|
||||
import com.tangem.tap.features.details.ui.walletconnect.dialogs.ApproveWcSessionDialog
|
||||
import com.tangem.tap.features.details.ui.walletconnect.dialogs.ClipboardOrScanQrDialog
|
||||
import com.tangem.tap.features.details.ui.walletconnect.dialogs.PersonalSignDialog
|
||||
import com.tangem.tap.features.details.ui.walletconnect.dialogs.TransactionDialog
|
||||
import com.tangem.tap.store
|
||||
import org.rekotlin.StoreSubscriber
|
||||
|
||||
class DialogManager : StoreSubscriber<GlobalState> {
|
||||
var context: Context? = null
|
||||
private var dialog: Dialog? = null
|
||||
|
||||
fun onStart(context: Context) {
|
||||
this.context = context
|
||||
store.subscribe(this) { state ->
|
||||
state.skipRepeats { oldState, newState ->
|
||||
oldState.globalState == newState.globalState
|
||||
}.select { it.globalState }
|
||||
}
|
||||
}
|
||||
|
||||
fun onStop() {
|
||||
this.context = null
|
||||
store.unsubscribe(this)
|
||||
}
|
||||
|
||||
|
||||
override fun newState(state: GlobalState) {
|
||||
if (state.dialog == null) {
|
||||
dialog?.dismiss()
|
||||
dialog = null
|
||||
return
|
||||
}
|
||||
val context = context ?: return
|
||||
if (dialog != null) return
|
||||
|
||||
when (state.dialog) {
|
||||
is WalletConnectDialog.ApproveWcSession ->
|
||||
dialog = ApproveWcSessionDialog.create(state.dialog.session, context)
|
||||
|
||||
is WalletConnectDialog.ClipboardOrScanQr ->
|
||||
dialog = ClipboardOrScanQrDialog.create(state.dialog.clipboardUri, context)
|
||||
is WalletConnectDialog.RequestTransaction ->
|
||||
dialog = TransactionDialog.create(state.dialog.dialogData, context)
|
||||
is WalletConnectDialog.PersonalSign ->
|
||||
dialog = PersonalSignDialog.create(state.dialog.data, context)
|
||||
}
|
||||
dialog?.show()
|
||||
}
|
||||
}
|
||||
41
app/src/main/java/com/tangem/tap/common/IntentHandler.kt
Normal file
41
app/src/main/java/com/tangem/tap/common/IntentHandler.kt
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
package com.tangem.tap.common
|
||||
|
||||
import android.content.Intent
|
||||
import android.nfc.NfcAdapter
|
||||
import android.nfc.Tag
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.walletconnect.WalletConnectManager
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
|
||||
import com.tangem.tap.features.home.redux.HomeAction
|
||||
import com.tangem.tap.store
|
||||
|
||||
class IntentHandler {
|
||||
|
||||
fun handleIntent(intent: Intent?) {
|
||||
handleBackgroundScan(intent)
|
||||
handleWalletConnectLink(intent)
|
||||
}
|
||||
|
||||
private fun handleBackgroundScan(intent: Intent?) {
|
||||
if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action ||
|
||||
NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action
|
||||
)
|
||||
) {
|
||||
val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
|
||||
if (tag != null) {
|
||||
intent.action = null
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Home))
|
||||
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
|
||||
store.dispatch(HomeAction.ReadCard)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleWalletConnectLink(intent: Intent?) {
|
||||
if (intent?.scheme == WalletConnectManager.WC_SCHEME) {
|
||||
store.dispatch(WalletConnectAction.HandleDeepLink(intent.data?.toString()))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.tap.common
|
||||
|
||||
import android.view.View
|
||||
|
||||
interface SnackbarHandler {
|
||||
fun showSnackbar(text: Int, buttonTitle: Int? = null, action: View.OnClickListener? = null)
|
||||
fun dismissSnackbar()
|
||||
}
|
||||
|
|
@ -9,6 +9,8 @@ import com.tangem.tap.features.details.ui.DetailsFragment
|
|||
import com.tangem.tap.features.details.ui.DetailsSecurityFragment
|
||||
import com.tangem.tap.features.details.ui.twins.CreateTwinWalletFragment
|
||||
import com.tangem.tap.features.details.ui.twins.TwinWalletWarningFragment
|
||||
import com.tangem.tap.features.details.ui.walletconnect.QrScanFragment
|
||||
import com.tangem.tap.features.details.ui.walletconnect.WalletConnectSessionsFragment
|
||||
import com.tangem.tap.features.disclaimer.ui.DisclaimerFragment
|
||||
import com.tangem.tap.features.home.HomeFragment
|
||||
import com.tangem.tap.features.send.ui.SendFragment
|
||||
|
|
@ -50,5 +52,7 @@ private fun fragmentFactory(screen: AppScreen): Fragment {
|
|||
AppScreen.TwinsOnboarding -> TwinsOnboardingFragment()
|
||||
AppScreen.AddTokens -> AddTokensFragment()
|
||||
AppScreen.WalletDetails -> WalletDetailsFragment()
|
||||
AppScreen.WalletConnectSessions -> WalletConnectSessionsFragment()
|
||||
AppScreen.QrScan -> QrScanFragment()
|
||||
}
|
||||
}
|
||||
|
|
@ -22,13 +22,16 @@ fun BigDecimal.toFormattedString(
|
|||
return df.format(this)
|
||||
}
|
||||
|
||||
fun BigDecimal.toFormattedCurrencyString(decimals: Int, currency: String): String {
|
||||
return "${this.toFormattedString(decimals)} $currency"
|
||||
fun BigDecimal.toFormattedCurrencyString(
|
||||
decimals: Int, currency: String, roundingMode: RoundingMode = RoundingMode.DOWN
|
||||
): String {
|
||||
val formattedAmount = this.toFormattedString(decimals = decimals, roundingMode = roundingMode)
|
||||
return "$formattedAmount $currency"
|
||||
}
|
||||
|
||||
fun BigDecimal.toFiatString(rateValue: BigDecimal, fiatCurrencyName: FiatCurrencyName): String {
|
||||
var fiatValue = rateValue.multiply(this)
|
||||
fiatValue = fiatValue.setScale(2, RoundingMode.DOWN)
|
||||
fiatValue = fiatValue.setScale(2, RoundingMode.HALF_UP)
|
||||
return "≈ ${fiatCurrencyName} $fiatValue"
|
||||
}
|
||||
|
||||
|
|
|
|||
15
app/src/main/java/com/tangem/tap/common/extensions/Store.kt
Normal file
15
app/src/main/java/com/tangem/tap/common/extensions/Store.kt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.tap.common.extensions
|
||||
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.rekotlin.Action
|
||||
import org.rekotlin.Store
|
||||
|
||||
fun Store<AppState>.dispatchOnMain(action: Action) {
|
||||
scope.launch(Dispatchers.Main) {
|
||||
store.dispatch(action)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,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.details.redux.DetailsReducer
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectReducer
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerReducer
|
||||
import com.tangem.tap.features.home.redux.HomeReducer
|
||||
import com.tangem.tap.features.send.redux.reducers.SendScreenReducer
|
||||
|
|
@ -23,6 +24,7 @@ fun appReducer(action: Action, state: AppState?): AppState {
|
|||
detailsState = DetailsReducer.reduce(action, state),
|
||||
disclaimerState = DisclaimerReducer.reduce(action, state),
|
||||
tokensState = TokensReducer.reduce(action, state),
|
||||
walletConnectState = WalletConnectReducer.reduce(action, state.walletConnectState)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import com.tangem.tap.common.redux.navigation.NavigationState
|
|||
import com.tangem.tap.common.redux.navigation.navigationMiddleware
|
||||
import com.tangem.tap.features.details.redux.DetailsMiddleware
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectMiddleware
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectState
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerMiddleware
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerState
|
||||
import com.tangem.tap.features.home.redux.HomeMiddleware
|
||||
|
|
@ -20,14 +22,15 @@ import org.rekotlin.Middleware
|
|||
import org.rekotlin.StateType
|
||||
|
||||
data class AppState(
|
||||
val navigationState: NavigationState = NavigationState(),
|
||||
val globalState: GlobalState = GlobalState(),
|
||||
val homeState: HomeState = HomeState(),
|
||||
val walletState: WalletState = WalletState(),
|
||||
val sendState: SendState = SendState(),
|
||||
val detailsState: DetailsState = DetailsState(),
|
||||
val disclaimerState: DisclaimerState = DisclaimerState(),
|
||||
val tokensState: TokensState = TokensState(),
|
||||
val navigationState: NavigationState = NavigationState(),
|
||||
val globalState: GlobalState = GlobalState(),
|
||||
val homeState: HomeState = HomeState(),
|
||||
val walletState: WalletState = WalletState(),
|
||||
val sendState: SendState = SendState(),
|
||||
val detailsState: DetailsState = DetailsState(),
|
||||
val disclaimerState: DisclaimerState = DisclaimerState(),
|
||||
val tokensState: TokensState = TokensState(),
|
||||
val walletConnectState: WalletConnectState = WalletConnectState(),
|
||||
) : StateType {
|
||||
|
||||
companion object {
|
||||
|
|
@ -40,6 +43,7 @@ data class AppState(
|
|||
DetailsMiddleware().detailsMiddleware,
|
||||
DisclaimerMiddleware().disclaimerMiddleware,
|
||||
TokensMiddleware().tokensMiddleware,
|
||||
WalletConnectMiddleware().walletConnectMiddleware
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,4 +38,7 @@ sealed class GlobalAction : Action {
|
|||
data class SetFeedbackManager(val feedbackManager: FeedbackManager) : GlobalAction()
|
||||
|
||||
data class SendFeedback(val emailData: EmailData) : GlobalAction()
|
||||
|
||||
data class ShowDialog(val stateDialog: StateDialog) : GlobalAction()
|
||||
object HideDialog : GlobalAction()
|
||||
}
|
||||
|
|
@ -67,6 +67,12 @@ fun globalReducer(action: Action, state: AppState): GlobalState {
|
|||
is GlobalAction.SetFeedbackManager -> {
|
||||
globalState.copy(feedbackManager = action.feedbackManager)
|
||||
}
|
||||
is GlobalAction.ShowDialog -> {
|
||||
globalState.copy(dialog = action.stateDialog)
|
||||
}
|
||||
is GlobalAction.HideDialog -> {
|
||||
globalState.copy(dialog = null)
|
||||
}
|
||||
else -> globalState
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@ data class GlobalState(
|
|||
val feedbackManager: FeedbackManager? = null,
|
||||
val appCurrency: FiatCurrencyName = DEFAULT_FIAT_CURRENCY,
|
||||
val scanCardFailsCounter: Int = 0,
|
||||
val dialog: StateDialog? = null
|
||||
) : StateType
|
||||
|
||||
typealias CryptoCurrencyName = String
|
||||
|
|
|
|||
|
|
@ -11,5 +11,6 @@ data class NavigationState(
|
|||
|
||||
enum class AppScreen {
|
||||
Home, Wallet, WalletDetails, Send, Details, DetailsConfirm, DetailsSecurity, Disclaimer,
|
||||
CreateTwinWalletWarning, CreateTwinWallet, TwinsOnboarding, AddTokens
|
||||
CreateTwinWalletWarning, CreateTwinWallet, TwinsOnboarding, AddTokens, WalletConnectSessions,
|
||||
QrScan
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue