Updated on 2026-08-14
This commit is contained in:
parent
99f1b91bae
commit
a7fc5e1036
38 changed files with 1486 additions and 195 deletions
|
|
@ -16,9 +16,12 @@ 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.onboarding.products.note.OnboardingNoteFragment
|
||||
import com.tangem.tap.features.onboarding.products.old.OnboardingOtherCardsFragment
|
||||
import com.tangem.tap.features.onboarding.products.wallet.OnboardingWalletFragment
|
||||
import com.tangem.tap.features.send.ui.SendFragment
|
||||
import com.tangem.tap.features.tokens.ui.AddTokensFragment
|
||||
import com.tangem.tap.features.wallet.ui.TwinsOnboardingFragment
|
||||
import com.tangem.tap.features.wallet.ui.OnboardingTwinsFragment
|
||||
import com.tangem.tap.features.wallet.ui.WalletDetailsFragment
|
||||
import com.tangem.tap.features.wallet.ui.WalletFragment
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -67,6 +70,10 @@ fun FragmentActivity.addOnBackPressedDispatcher(
|
|||
private fun fragmentFactory(screen: AppScreen): Fragment {
|
||||
return when (screen) {
|
||||
AppScreen.Home -> HomeFragment()
|
||||
AppScreen.OnboardingNote -> OnboardingNoteFragment()
|
||||
AppScreen.OnboardingWallet -> OnboardingWalletFragment()
|
||||
AppScreen.OnboardingTwins -> OnboardingTwinsFragment()
|
||||
AppScreen.OnboardingOther -> OnboardingOtherCardsFragment()
|
||||
AppScreen.Wallet -> WalletFragment()
|
||||
AppScreen.Send -> SendFragment()
|
||||
AppScreen.Details -> DetailsFragment()
|
||||
|
|
@ -75,7 +82,6 @@ private fun fragmentFactory(screen: AppScreen): Fragment {
|
|||
AppScreen.Disclaimer -> DisclaimerFragment()
|
||||
AppScreen.CreateTwinWalletWarning -> TwinWalletWarningFragment()
|
||||
AppScreen.CreateTwinWallet -> CreateTwinWalletFragment()
|
||||
AppScreen.TwinsOnboarding -> TwinsOnboardingFragment()
|
||||
AppScreen.AddTokens -> AddTokensFragment()
|
||||
AppScreen.WalletDetails -> WalletDetailsFragment()
|
||||
AppScreen.WalletConnectSessions -> WalletConnectSessionsFragment()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ 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.onboarding.products.note.redux.OnboardingNoteReducer
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletReducer
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingReducer
|
||||
import com.tangem.tap.features.send.redux.reducers.SendScreenReducer
|
||||
import com.tangem.tap.features.tokens.redux.TokensReducer
|
||||
import com.tangem.tap.features.wallet.redux.reducers.WalletReducer
|
||||
|
|
@ -19,6 +22,9 @@ fun appReducer(action: Action, state: AppState?): AppState {
|
|||
navigationState = NavigationReducer.reduce(action, state),
|
||||
globalState = globalReducer(action, state),
|
||||
homeState = HomeReducer.reduce(action, state),
|
||||
onboardingState = OnboardingReducer.reduce(action, state),
|
||||
onboardingNoteState = OnboardingNoteReducer.reduce(action, state),
|
||||
onboardingWalletState = OnboardingWalletReducer.reduce(action, state),
|
||||
walletState = WalletReducer.reduce(action, state),
|
||||
sendState = SendScreenReducer.reduce(action, state.sendState),
|
||||
detailsState = DetailsReducer.reduce(action, state),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.common.redux
|
||||
|
||||
import com.tangem.tap.common.redux.global.GlobalMiddleware
|
||||
import com.tangem.tap.common.redux.global.GlobalState
|
||||
import com.tangem.tap.common.redux.global.globalMiddleware
|
||||
import com.tangem.tap.common.redux.navigation.NavigationState
|
||||
import com.tangem.tap.common.redux.navigation.navigationMiddleware
|
||||
import com.tangem.tap.features.details.redux.DetailsMiddleware
|
||||
|
|
@ -12,6 +12,12 @@ import com.tangem.tap.features.disclaimer.redux.DisclaimerMiddleware
|
|||
import com.tangem.tap.features.disclaimer.redux.DisclaimerState
|
||||
import com.tangem.tap.features.home.redux.HomeMiddleware
|
||||
import com.tangem.tap.features.home.redux.HomeState
|
||||
import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteMiddleware
|
||||
import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteState
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletMiddleware
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletState
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingMiddleware
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingState
|
||||
import com.tangem.tap.features.send.redux.middlewares.SendMiddleware
|
||||
import com.tangem.tap.features.send.redux.states.SendState
|
||||
import com.tangem.tap.features.tokens.redux.TokensMiddleware
|
||||
|
|
@ -25,6 +31,9 @@ data class AppState(
|
|||
val navigationState: NavigationState = NavigationState(),
|
||||
val globalState: GlobalState = GlobalState(),
|
||||
val homeState: HomeState = HomeState(),
|
||||
val onboardingState: OnboardingState = OnboardingState(),
|
||||
val onboardingNoteState: OnboardingNoteState = OnboardingNoteState(),
|
||||
val onboardingWalletState: OnboardingWalletState = OnboardingWalletState(),
|
||||
val walletState: WalletState = WalletState(),
|
||||
val sendState: SendState = SendState(),
|
||||
val detailsState: DetailsState = DetailsState(),
|
||||
|
|
@ -36,8 +45,12 @@ data class AppState(
|
|||
companion object {
|
||||
fun getMiddleware(): List<Middleware<AppState>> {
|
||||
return listOf(
|
||||
logMiddleware, navigationMiddleware, notificationsMiddleware, globalMiddleware,
|
||||
HomeMiddleware().homeMiddleware,
|
||||
logMiddleware, navigationMiddleware, notificationsMiddleware,
|
||||
GlobalMiddleware.handler,
|
||||
HomeMiddleware.handler,
|
||||
OnboardingMiddleware.handler,
|
||||
OnboardingNoteMiddleware.handler,
|
||||
OnboardingWalletMiddleware.handler,
|
||||
WalletMiddleware().walletMiddleware,
|
||||
SendMiddleware().sendMiddleware,
|
||||
DetailsMiddleware().detailsMiddleware,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ package com.tangem.tap.common.redux.global
|
|||
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemError
|
||||
import com.tangem.tap.common.redux.DebugErrorAction
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.domain.configurable.config.ConfigManager
|
||||
import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
|
||||
import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager
|
||||
|
|
@ -14,6 +17,14 @@ import org.rekotlin.Action
|
|||
|
||||
sealed class GlobalAction : Action {
|
||||
|
||||
data class DebugShowError(override val error: TapError) : GlobalAction(), DebugErrorAction
|
||||
|
||||
data class ReadCard(
|
||||
val onSuccess: (suspend (ScanNoteResponse) -> Unit)? = null,
|
||||
val onFailure: (suspend (TangemError) -> Unit)? = null,
|
||||
val messageResId: Int? = null,
|
||||
) : GlobalAction()
|
||||
|
||||
object ScanFailsCounter {
|
||||
data class ChooseBehavior(val result: CompletionResult<ScanNoteResponse>) : GlobalAction()
|
||||
object Reset : GlobalAction()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.tap.common.redux.global
|
|||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager
|
||||
|
|
@ -13,10 +14,19 @@ import com.tangem.tap.network.moonpay.MoonpayService
|
|||
import com.tangem.tap.preferencesStorage
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
val globalMiddleware: Middleware<AppState> = { dispatch, appState ->
|
||||
class GlobalMiddleware {
|
||||
companion object {
|
||||
val handler = globalMiddlewareHandler
|
||||
}
|
||||
}
|
||||
|
||||
private val globalMiddlewareHandler: Middleware<AppState> = { dispatch, appState ->
|
||||
{ nextDispatch ->
|
||||
{ action ->
|
||||
when (action) {
|
||||
|
|
@ -78,6 +88,21 @@ val globalMiddleware: Middleware<AppState> = { dispatch, appState ->
|
|||
}
|
||||
}
|
||||
}
|
||||
is GlobalAction.ReadCard -> {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.scanNote(FirebaseAnalyticsHandler, action.messageResId)
|
||||
withContext(Dispatchers.Main) {
|
||||
store.dispatch(GlobalAction.ScanFailsCounter.ChooseBehavior(result))
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
tangemSdkManager.changeDisplayedCardIdNumbersCount(result.data.card)
|
||||
action.onSuccess?.invoke(result.data)
|
||||
}
|
||||
is CompletionResult.Failure -> action.onFailure?.invoke(result.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nextDispatch(action)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ package com.tangem.tap.common.redux.navigation
|
|||
|
||||
import android.view.View
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.transition.ChangeBounds
|
||||
import androidx.transition.ChangeImageTransform
|
||||
import androidx.transition.ChangeTransform
|
||||
import androidx.transition.TransitionSet
|
||||
import org.rekotlin.Action
|
||||
import java.lang.ref.WeakReference
|
||||
|
|
@ -27,4 +30,14 @@ data class FragmentShareTransition(
|
|||
val exitTransitionSet: TransitionSet
|
||||
)
|
||||
|
||||
data class ShareElement(val wView: WeakReference<View>, val name: String)
|
||||
data class ShareElement(val wView: WeakReference<View>, val name: String)
|
||||
|
||||
//TODO: remove transition example
|
||||
class DetailsTransition : TransitionSet() {
|
||||
init {
|
||||
ordering = ORDERING_TOGETHER;
|
||||
addTransition(ChangeBounds())
|
||||
.addTransition(ChangeTransform())
|
||||
.addTransition(ChangeImageTransform())
|
||||
}
|
||||
}
|
||||
|
|
@ -5,12 +5,19 @@ import org.rekotlin.StateType
|
|||
import java.lang.ref.WeakReference
|
||||
|
||||
data class NavigationState(
|
||||
val backStack: List<AppScreen> = listOf(AppScreen.Home),
|
||||
val activity: WeakReference<FragmentActivity>? = null
|
||||
val backStack: List<AppScreen> = listOf(AppScreen.Home),
|
||||
val activity: WeakReference<FragmentActivity>? = null
|
||||
) : StateType
|
||||
|
||||
enum class AppScreen {
|
||||
Home, Wallet, WalletDetails, Send, Details, DetailsConfirm, DetailsSecurity, Disclaimer,
|
||||
CreateTwinWalletWarning, CreateTwinWallet, TwinsOnboarding, AddTokens, WalletConnectSessions,
|
||||
Home,
|
||||
Disclaimer,
|
||||
OnboardingNote, OnboardingWallet, OnboardingTwins, OnboardingOther,
|
||||
Wallet, WalletDetails,
|
||||
Send,
|
||||
Details, DetailsConfirm, DetailsSecurity,
|
||||
CreateTwinWalletWarning, CreateTwinWallet,
|
||||
AddTokens,
|
||||
WalletConnectSessions,
|
||||
QrScan
|
||||
}
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
package com.tangem.tap.features.disclaimer.redux
|
||||
|
||||
import com.tangem.tap.common.post
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.home.redux.HomeAction
|
||||
import com.tangem.tap.preferencesStorage
|
||||
import com.tangem.tap.store
|
||||
import org.rekotlin.Middleware
|
||||
|
|
@ -14,16 +15,10 @@ class DisclaimerMiddleware {
|
|||
when (action) {
|
||||
is DisclaimerAction.AcceptDisclaimer -> {
|
||||
preferencesStorage.saveDisclaimerAccepted()
|
||||
if (store.state.walletState.twinCardsState != null) {
|
||||
val showOnboarding = !preferencesStorage.wasTwinsOnboardingShown()
|
||||
if (showOnboarding) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.TwinsOnboarding))
|
||||
} else {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
} else {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
|
||||
//delayed sending used for better animation
|
||||
post(550) { store.dispatch(HomeAction.ReadCard) }
|
||||
}
|
||||
}
|
||||
next(action)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,20 @@
|
|||
package com.tangem.tap.features.home
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.common.extensions.safeStartActivity
|
||||
import com.tangem.tap.common.extensions.toast
|
||||
import com.tangem.tap.common.redux.global.StateDialog
|
||||
import com.tangem.tap.common.redux.navigation.DetailsTransition
|
||||
import com.tangem.tap.common.redux.navigation.FragmentShareTransition
|
||||
import com.tangem.tap.common.redux.navigation.ShareElement
|
||||
import com.tangem.tap.common.toggleWidget.IndeterminateProgressButtonWidget
|
||||
import com.tangem.tap.common.toggleWidget.ViewStateWidget
|
||||
import com.tangem.tap.features.home.redux.HomeAction
|
||||
import com.tangem.tap.features.home.redux.HomeDialog
|
||||
import com.tangem.tap.features.home.redux.HomeState
|
||||
|
|
@ -15,11 +23,36 @@ import com.tangem.tap.store
|
|||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fragment_home.*
|
||||
import org.rekotlin.StoreSubscriber
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class HomeFragment : Fragment(R.layout.fragment_home), StoreSubscriber<HomeState> {
|
||||
|
||||
lateinit var btnScanCard: ViewStateWidget
|
||||
|
||||
private var dialog: Dialog? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
exitTransition = inflater.inflateTransition(R.transition.fade)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val transitionViews = mutableListOf<ShareElement>()
|
||||
transitionViews.add(ShareElement(WeakReference(imv_front_card), "imv_front_card"))
|
||||
val shareTransition = FragmentShareTransition(transitionViews, DetailsTransition(), DetailsTransition())
|
||||
|
||||
store.dispatch(HomeAction.SetFragmentShareTransition(shareTransition))
|
||||
store.dispatch(HomeAction.Init)
|
||||
|
||||
btn_scan_card?.setOnClickListener { store.dispatch(HomeAction.ReadCard) }
|
||||
btn_get_new_card?.setOnClickListener { store.dispatch(HomeAction.GoToShop) }
|
||||
|
||||
btnScanCard = IndeterminateProgressButtonWidget(btn_scan_card, progress)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
store.subscribe(this) { state ->
|
||||
|
|
@ -37,16 +70,23 @@ class HomeFragment : Fragment(R.layout.fragment_home), StoreSubscriber<HomeState
|
|||
|
||||
override fun newState(state: HomeState) {
|
||||
if (activity == null) return
|
||||
if (state.firstLaunch) {
|
||||
tv_home_description.text = getText(R.string.home_welcome)
|
||||
btn_shop.text = getText(R.string.common_no)
|
||||
btn_yes.text = getText(R.string.home_button_yes)
|
||||
} else {
|
||||
tv_home_description.text = getText(R.string.home_welcome_back)
|
||||
btn_shop.text = getText(R.string.home_button_shop)
|
||||
btn_yes.text = getText(R.string.home_button_scan)
|
||||
}
|
||||
|
||||
handleOpenUrl(state)
|
||||
handleDialog(state.dialog)
|
||||
|
||||
btnScanCard.changeState(state.btnScanState.progressState)
|
||||
btnScanCard.mainView.isEnabled = state.btnScanState.enabled
|
||||
}
|
||||
|
||||
private fun handleOpenUrl(state: HomeState) {
|
||||
if (state.openUrl == null) return
|
||||
val context = context ?: return
|
||||
|
||||
val uri = Uri.parse(state.openUrl)
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
context.safeStartActivity(intent, null, { toast(it.toString()) }, {
|
||||
store.dispatch(HomeAction.SetOpenUrl(null))
|
||||
})
|
||||
}
|
||||
|
||||
private fun handleDialog(stateDialog: StateDialog?) {
|
||||
|
|
@ -61,19 +101,8 @@ class HomeFragment : Fragment(R.layout.fragment_home), StoreSubscriber<HomeState
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
btn_yes?.setOnClickListener { store.dispatch(HomeAction.ReadCard) }
|
||||
btn_shop?.setOnClickListener { store.dispatch(HomeAction.GoToShop(requireContext())) }
|
||||
|
||||
store.dispatch(GlobalAction.GetMoonPayUserStatus)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
exitTransition = inflater.inflateTransition(R.transition.fade)
|
||||
override fun onDestroyView() {
|
||||
store.dispatch(HomeAction.SetFragmentShareTransition(null))
|
||||
super.onDestroyView()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,22 @@
|
|||
package com.tangem.tap.features.home.redux
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.tap.common.entities.IndeterminateProgressButton
|
||||
import com.tangem.tap.common.redux.navigation.FragmentShareTransition
|
||||
import org.rekotlin.Action
|
||||
|
||||
sealed class HomeAction : Action {
|
||||
object Init : HomeAction()
|
||||
data class SetFragmentShareTransition(val shareTransition: FragmentShareTransition?) : HomeAction()
|
||||
|
||||
object ReadCard : HomeAction()
|
||||
data class GoToShop(val context: Context) : HomeAction()
|
||||
object CheckIfFirstLaunch : HomeAction() {
|
||||
data class Result(val firstLaunch: Boolean) : HomeAction()
|
||||
}
|
||||
object GoToShop : HomeAction()
|
||||
class SetOpenUrl(val url: String?) : HomeAction()
|
||||
class SetTermsOfUseState(val isDisclaimerAccepted: Boolean) : HomeAction()
|
||||
|
||||
data class ChangeScanCardButtonState(val state: IndeterminateProgressButton) : HomeAction()
|
||||
|
||||
object ShowDialog : HomeAction() {
|
||||
object ScanFails : HomeAction()
|
||||
}
|
||||
|
||||
object HideDialog : HomeAction()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,80 +1,82 @@
|
|||
package com.tangem.tap.features.home.redux
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.core.content.ContextCompat.startActivity
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
|
||||
import com.tangem.tap.common.entities.IndeterminateProgressButton
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.features.onboarding.OnboardingService
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingAction
|
||||
import com.tangem.tap.features.send.redux.states.ButtonState
|
||||
import com.tangem.tap.preferencesStorage
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
class HomeMiddleware {
|
||||
val homeMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
when (action) {
|
||||
is HomeAction.CheckIfFirstLaunch -> {
|
||||
store.dispatch(
|
||||
HomeAction.CheckIfFirstLaunch.Result(preferencesStorage.getCountOfLaunches() == 1)
|
||||
)
|
||||
}
|
||||
is HomeAction.ReadCard -> {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.scanNote(FirebaseAnalyticsHandler)
|
||||
withContext(Dispatchers.Main) {
|
||||
store.dispatch(GlobalAction.ScanFailsCounter.ChooseBehavior(result))
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
tangemSdkManager.changeDisplayedCardIdNumbersCount(result.data.card)
|
||||
store.dispatch(GlobalAction.RestoreAppCurrency)
|
||||
store.state.globalState.tapWalletManager.onCardScanned(result.data)
|
||||
showDisclaimerOrNavigateToWallet()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is HomeAction.GoToShop -> {
|
||||
val uri = Uri.parse(CARD_SHOP_URI)
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
startActivity(action.context, intent, null)
|
||||
}
|
||||
}
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showDisclaimerOrNavigateToWallet() {
|
||||
if (!preferencesStorage.wasDisclaimerAccepted()) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Disclaimer))
|
||||
return
|
||||
}
|
||||
if (store.state.walletState.twinCardsState != null) {
|
||||
val showOnboarding = !preferencesStorage.wasTwinsOnboardingShown()
|
||||
if (showOnboarding) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.TwinsOnboarding))
|
||||
return
|
||||
}
|
||||
}
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val CARD_SHOP_URI =
|
||||
val handler = homeMiddleware
|
||||
|
||||
const val CARD_SHOP_URI =
|
||||
"https://shop.tangem.com/?afmc=1i&utm_campaign=1i&utm_source=leaddyno&utm_medium=affiliate"
|
||||
}
|
||||
}
|
||||
|
||||
private val homeMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
when (action) {
|
||||
is HomeAction.Init -> {
|
||||
store.dispatch(GlobalAction.RestoreAppCurrency)
|
||||
store.dispatch(GlobalAction.GetMoonPayUserStatus)
|
||||
store.dispatch(HomeAction.SetTermsOfUseState(preferencesStorage.wasDisclaimerAccepted()))
|
||||
}
|
||||
is HomeAction.ReadCard -> {
|
||||
if (!preferencesStorage.wasDisclaimerAccepted()) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Disclaimer))
|
||||
} else {
|
||||
launchOnboardingService()
|
||||
}
|
||||
}
|
||||
is HomeAction.GoToShop -> store.dispatch(HomeAction.SetOpenUrl(HomeMiddleware.CARD_SHOP_URI))
|
||||
}
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun launchOnboardingService() {
|
||||
fun changeButtonState(state: ButtonState) {
|
||||
val btnState = IndeterminateProgressButton(state)
|
||||
store.dispatch(HomeAction.ChangeScanCardButtonState(btnState))
|
||||
}
|
||||
changeButtonState(ButtonState.PROGRESS)
|
||||
|
||||
val walletManager = store.state.globalState.tapWalletManager
|
||||
val service = OnboardingService(
|
||||
walletManager,
|
||||
preferencesStorage.usedCardsPrefStorage
|
||||
)
|
||||
|
||||
service.onReadyToProceed = {
|
||||
store.dispatch(OnboardingAction.SetData(it))
|
||||
changeButtonState(ButtonState.ENABLED)
|
||||
store.dispatch(NavigationAction.NavigateTo(it.onboardingScreen))
|
||||
}
|
||||
|
||||
service.onFailedToProceedToOnboardingCase = {
|
||||
changeButtonState(ButtonState.ENABLED)
|
||||
walletManager.onCardScanned(it)
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
|
||||
service.onError = {
|
||||
changeButtonState(ButtonState.ENABLED)
|
||||
store.dispatch(GlobalAction.DebugShowError(TapError.CustomError(it)))
|
||||
}
|
||||
|
||||
store.dispatch(GlobalAction.ReadCard(service::onSuccess, {
|
||||
changeButtonState(ButtonState.ENABLED)
|
||||
store.dispatch(GlobalAction.DebugShowError(TapError.ScanCardError))
|
||||
}))
|
||||
}
|
||||
|
|
@ -13,18 +13,27 @@ private fun internalReduce(action: Action, state: AppState): HomeState {
|
|||
|
||||
if (action !is HomeAction) return state.homeState
|
||||
|
||||
var homeState = state.homeState
|
||||
var state = state.homeState
|
||||
when (action) {
|
||||
is HomeAction.CheckIfFirstLaunch.Result -> {
|
||||
homeState = homeState.copy(firstLaunch = action.firstLaunch)
|
||||
is HomeAction.SetFragmentShareTransition -> {
|
||||
state = state.copy(shareTransition = action.shareTransition)
|
||||
}
|
||||
is HomeAction.SetTermsOfUseState -> {
|
||||
state = state.copy(isDisclaimerAccepted = action.isDisclaimerAccepted)
|
||||
}
|
||||
is HomeAction.SetOpenUrl -> {
|
||||
state = state.copy(openUrl = action.url)
|
||||
}
|
||||
is HomeAction.ChangeScanCardButtonState -> {
|
||||
state = state.copy(btnScanState = action.state)
|
||||
}
|
||||
is HomeAction.ShowDialog.ScanFails -> {
|
||||
homeState = homeState.copy(dialog = HomeDialog.ScanFailsDialog)
|
||||
state = state.copy(dialog = HomeDialog.ScanFailsDialog)
|
||||
}
|
||||
is HomeAction.HideDialog -> {
|
||||
homeState = homeState.copy(dialog = null)
|
||||
state = state.copy(dialog = null)
|
||||
}
|
||||
}
|
||||
|
||||
return homeState
|
||||
return state
|
||||
}
|
||||
|
|
@ -1,13 +1,19 @@
|
|||
package com.tangem.tap.features.home.redux
|
||||
|
||||
import com.tangem.tap.common.entities.IndeterminateProgressButton
|
||||
import com.tangem.tap.common.redux.global.StateDialog
|
||||
import com.tangem.tap.common.redux.navigation.FragmentShareTransition
|
||||
import com.tangem.tap.features.send.redux.states.ButtonState
|
||||
import org.rekotlin.StateType
|
||||
|
||||
data class HomeState(
|
||||
val firstLaunch: Boolean = true,
|
||||
val dialog: StateDialog? = null
|
||||
val openUrl: String? = null,
|
||||
val isDisclaimerAccepted: Boolean = false,
|
||||
val shareTransition: FragmentShareTransition? = null,
|
||||
val btnScanState: IndeterminateProgressButton = IndeterminateProgressButton(ButtonState.ENABLED),
|
||||
val dialog: StateDialog? = null,
|
||||
) : StateType
|
||||
|
||||
sealed class HomeDialog: StateDialog {
|
||||
object ScanFailsDialog: HomeDialog()
|
||||
sealed class HomeDialog : StateDialog {
|
||||
object ScanFailsDialog : HomeDialog()
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
package com.tangem.tap.features.onboarding
|
||||
|
||||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.domain.TapWalletManager
|
||||
import com.tangem.tap.domain.TapWorkarounds.isTangemNote
|
||||
import com.tangem.tap.domain.TapWorkarounds.isTangemWallet
|
||||
import com.tangem.tap.domain.UrlBitmapLoader
|
||||
import com.tangem.tap.domain.extensions.getArtworkUrl
|
||||
import com.tangem.tap.domain.extensions.hasWallets
|
||||
import com.tangem.tap.domain.extensions.makePrimaryWalletManager
|
||||
import com.tangem.tap.domain.tasks.ScanNoteResponse
|
||||
import com.tangem.tap.domain.twins.isTangemTwin
|
||||
import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteAction
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingData
|
||||
import com.tangem.tap.features.wallet.redux.Artwork
|
||||
import com.tangem.tap.persistence.UsedCardsPrefStorage
|
||||
import com.tangem.tap.store
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class OnboardingService(
|
||||
private val tapWalletManager: TapWalletManager,
|
||||
private val cardInfoStorage: UsedCardsPrefStorage
|
||||
) {
|
||||
|
||||
var onReadyToProceed: ((OnboardingData) -> Unit)? = null
|
||||
set(value) {
|
||||
field = value
|
||||
onboardingDataLinker.onReady = { value?.invoke(it) }
|
||||
}
|
||||
var onFailedToProceedToOnboardingCase: (suspend (ScanNoteResponse) -> Unit)? = null
|
||||
var onError: ((String) -> Unit)? = null
|
||||
|
||||
private val onboardingDataLinker = OnboardingDataLinker()
|
||||
|
||||
suspend fun onSuccess(response: ScanNoteResponse) {
|
||||
onboardingDataLinker.scanNoteResponse = response
|
||||
val card = response.card
|
||||
val hasWallets = card.hasWallets()
|
||||
|
||||
if (!card.isTangemNote() && !card.isTangemWallet() && !card.isTangemTwin()) {
|
||||
if (hasWallets) {
|
||||
cardInfoStorage.activated(card.cardId)
|
||||
onFailedToProceedToOnboardingCase?.invoke(response)
|
||||
return
|
||||
} else {
|
||||
cardInfoStorage.activated(card.cardId) // вызвать только после того, как был создан кошелек
|
||||
onboardingDataLinker.navigateTo = AppScreen.OnboardingOther
|
||||
}
|
||||
}
|
||||
if (cardInfoStorage.wasActivated(card.cardId)) {
|
||||
onFailedToProceedToOnboardingCase?.invoke(response)
|
||||
return
|
||||
}
|
||||
|
||||
loadCardImage(card) { onboardingDataLinker.cardArtwork = it }
|
||||
|
||||
if (hasWallets) {
|
||||
val walletManagerFactory = tapWalletManager.walletManagerFactory
|
||||
when {
|
||||
card.isTangemNote() -> loadBalanceNote(walletManagerFactory, response)
|
||||
card.isTangemWallet() -> loadBalanceWallet(walletManagerFactory, response)
|
||||
card.isTangemTwin() -> loadBalanceTwins(walletManagerFactory, response)
|
||||
}
|
||||
} else {
|
||||
onboardingDataLinker.valueOfWalletAmount = BigDecimal.ZERO
|
||||
}
|
||||
|
||||
onboardingDataLinker.navigateTo = when {
|
||||
card.isTangemNote() -> AppScreen.OnboardingNote
|
||||
card.isTangemWallet() -> AppScreen.OnboardingWallet
|
||||
card.isTangemTwin() -> AppScreen.OnboardingTwins
|
||||
else -> AppScreen.OnboardingOther
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loadBalanceNote(walletManagerFactory: WalletManagerFactory, response: ScanNoteResponse) {
|
||||
val walletManager: WalletManager = walletManagerFactory.makePrimaryWalletManager(response).guard {
|
||||
onError?.invoke("Can't proceed: primary wallet manager didn't create")
|
||||
return
|
||||
}
|
||||
walletManager.update()
|
||||
store.dispatch(OnboardingNoteAction.SetWalletManager(walletManager))
|
||||
|
||||
val wallet = walletManager.wallet
|
||||
val valueOfAmount = wallet.amounts[AmountType.Coin]?.value
|
||||
if (valueOfAmount == null) {
|
||||
onError?.invoke("Amount can't be NULL")
|
||||
return
|
||||
}
|
||||
|
||||
onboardingDataLinker.valueOfWalletAmount = valueOfAmount
|
||||
}
|
||||
|
||||
private suspend fun loadBalanceWallet(walletManagerFactory: WalletManagerFactory, response: ScanNoteResponse) {
|
||||
|
||||
}
|
||||
|
||||
private suspend fun loadBalanceTwins(walletManagerFactory: WalletManagerFactory, response: ScanNoteResponse) {
|
||||
|
||||
}
|
||||
|
||||
private suspend fun loadCardImage(card: Card, callback: (Artwork?) -> Unit) {
|
||||
fun loadBitmap(url: String, callback: (Artwork?) -> Unit) {
|
||||
UrlBitmapLoader().loadBitmap(url) {
|
||||
when (it) {
|
||||
is Result.Success -> callback(Artwork(url, it.data))
|
||||
is Result.Failure -> callback(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
when (val cardInfoResult = OnlineCardVerifier().getCardInfo(card.cardId, card.cardPublicKey)) {
|
||||
is Result.Success -> {
|
||||
val artworkUrl = card.getArtworkUrl(cardInfoResult.data.artwork?.id) ?: Artwork.DEFAULT_IMG_URL
|
||||
loadBitmap(artworkUrl, callback)
|
||||
}
|
||||
is Result.Failure -> loadBitmap(Artwork.DEFAULT_IMG_URL, callback)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class OnboardingDataLinker {
|
||||
var onReady: ((OnboardingData) -> Unit)? = null
|
||||
|
||||
internal var scanNoteResponse: ScanNoteResponse? = null
|
||||
set(value) {
|
||||
field = value
|
||||
tryToProceed()
|
||||
}
|
||||
internal var cardArtwork: Artwork? = null
|
||||
set(value) {
|
||||
field = value
|
||||
tryToProceed()
|
||||
}
|
||||
internal var valueOfWalletAmount: BigDecimal? = null
|
||||
set(value) {
|
||||
field = value
|
||||
tryToProceed()
|
||||
}
|
||||
internal var navigateTo: AppScreen? = null
|
||||
set(value) {
|
||||
field = value
|
||||
tryToProceed()
|
||||
}
|
||||
|
||||
private fun tryToProceed() {
|
||||
if (!isReady()) return
|
||||
|
||||
val data = OnboardingData(scanNoteResponse!!, cardArtwork!!, valueOfWalletAmount, navigateTo!!)
|
||||
onReady?.invoke(data)
|
||||
}
|
||||
|
||||
private fun isReady(): Boolean {
|
||||
val objList = mutableListOf(scanNoteResponse, cardArtwork, valueOfWalletAmount, navigateTo)
|
||||
return !objList.any { it == null }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
package com.tangem.tap.features.onboarding.products.note
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.tangem.tap.common.extensions.addOnBackPressedDispatcher
|
||||
import com.tangem.tap.common.extensions.beginDelayedTransition
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteAction
|
||||
import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteState
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingAction
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingNoteStep
|
||||
import com.tangem.tap.features.send.BaseStoreFragment
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fragment_onboarding.*
|
||||
import org.rekotlin.StoreSubscriber
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class OnboardingNoteFragment : BaseStoreFragment(R.layout.fragment_onboarding), StoreSubscriber<OnboardingNoteState> {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
activity?.addOnBackPressedDispatcher {
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
store.dispatch(OnboardingAction.SetInitialStepOfScreen(OnboardingNoteStep.None))
|
||||
}
|
||||
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
enterTransition = inflater.inflateTransition(R.transition.fade)
|
||||
exitTransition = inflater.inflateTransition(R.transition.fade)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
store.dispatch(OnboardingNoteAction.Init)
|
||||
|
||||
imv_front_card.setImageBitmap(store.state.onboardingState.onboardingData?.cardArtwork?.artwork)
|
||||
}
|
||||
|
||||
override fun subscribeToStore() {
|
||||
store.subscribe(this) { state ->
|
||||
state.skipRepeats { oldState, newState ->
|
||||
oldState.onboardingNoteState == newState.onboardingNoteState
|
||||
}.select { it.onboardingNoteState }
|
||||
}
|
||||
}
|
||||
|
||||
override fun newState(state: OnboardingNoteState) {
|
||||
if (activity == null) return
|
||||
|
||||
pb_state.max = state.steps.size - 1
|
||||
|
||||
onboarding_main_container.beginDelayedTransition()
|
||||
when (state.currentStep) {
|
||||
OnboardingNoteStep.None -> setupNoneState(state)
|
||||
OnboardingNoteStep.CreateWallet -> setupCreateWalletState(state)
|
||||
OnboardingNoteStep.TopUpWallet -> setupTopUpWalletState(state)
|
||||
OnboardingNoteStep.Done -> setupSuccessState(state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupNoneState(state: OnboardingNoteState) {
|
||||
pb_state.progress = state.progress
|
||||
|
||||
btn_main_action.isVisible = true
|
||||
btn_alternative_action.isVisible = true
|
||||
btn_check_balance.isVisible = true
|
||||
tv_header.isVisible = true
|
||||
tv_body.isVisible = true
|
||||
|
||||
btn_main_action.text = "NULL"
|
||||
btn_alternative_action.text = "NULL"
|
||||
btn_check_balance.text = "NULL balance"
|
||||
tv_header.text = "NULL"
|
||||
tv_body.text = "NULL"
|
||||
}
|
||||
|
||||
private fun setupCreateWalletState(state: OnboardingNoteState) {
|
||||
pb_state.progress = state.progress
|
||||
|
||||
btn_main_action.setText(R.string.onboarding_create_wallet_button_create_wallet)
|
||||
btn_main_action.setOnClickListener { store.dispatch(OnboardingNoteAction.CreateWallet) }
|
||||
|
||||
btn_alternative_action.setText(R.string.onboarding_button_what_does_it_mean)
|
||||
btn_alternative_action.setOnClickListener { }
|
||||
|
||||
btn_check_balance.isVisible = false
|
||||
btn_check_balance.setOnClickListener { }
|
||||
|
||||
tv_header.setText(R.string.onboarding_create_wallet_header)
|
||||
tv_body.setText(R.string.onboarding_create_wallet_body)
|
||||
}
|
||||
|
||||
private fun setupTopUpWalletState(state: OnboardingNoteState) {
|
||||
pb_state.progress = state.progress
|
||||
|
||||
btn_main_action.setText(R.string.onboarding_top_up_button_but_crypto)
|
||||
btn_main_action.setOnClickListener { store.dispatch(OnboardingNoteAction.TopUp) }
|
||||
|
||||
btn_alternative_action.setText(R.string.onboarding_top_up_button_show_wallet_address)
|
||||
btn_alternative_action.setOnClickListener { }
|
||||
|
||||
btn_check_balance.isVisible = false
|
||||
btn_check_balance.setOnClickListener { }
|
||||
|
||||
tv_header.setText(R.string.onboarding_top_up_header)
|
||||
tv_body.setText(R.string.onboarding_top_up_body)
|
||||
}
|
||||
|
||||
private fun setupSuccessState(state: OnboardingNoteState) {
|
||||
pb_state.progress = state.progress
|
||||
|
||||
btn_main_action.setText(R.string.onboarding_done_button_continue)
|
||||
btn_main_action.setOnClickListener { store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet)) }
|
||||
|
||||
btn_alternative_action.isVisible = false
|
||||
btn_alternative_action.setText("")
|
||||
btn_alternative_action.setOnClickListener { }
|
||||
|
||||
btn_check_balance.isVisible = false
|
||||
btn_check_balance.setOnClickListener { }
|
||||
|
||||
tv_header.setText(R.string.onboarding_done_header)
|
||||
tv_body.setText(R.string.onboarding_done_body)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.tap.features.onboarding.products.note.redux
|
||||
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import org.rekotlin.Action
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
sealed class OnboardingNoteAction : Action {
|
||||
object Init : OnboardingNoteAction()
|
||||
object CreateWallet : OnboardingNoteAction()
|
||||
object TopUp : OnboardingNoteAction()
|
||||
object Done : OnboardingNoteAction()
|
||||
|
||||
data class SetWalletManager(val walletManager: WalletManager) : OnboardingNoteAction()
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package com.tangem.tap.features.onboarding.products.note.redux
|
||||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingAction
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingNoteStep
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
import kotlinx.coroutines.launch
|
||||
import org.rekotlin.Action
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
class OnboardingNoteMiddleware {
|
||||
companion object {
|
||||
private const val CARD_SHOP_URI =
|
||||
"https://shop.tangem.com/?afmc=1i&utm_campaign=1i&utm_source=leaddyno&utm_medium=affiliate"
|
||||
val handler = onboardingNoteMiddleware
|
||||
}
|
||||
}
|
||||
|
||||
private val onboardingNoteMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
handleMainOnboardingAction(action, ::handleNoteAction)
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleMainOnboardingAction(action: Action, isNotMainAction: (Action) -> Unit) {
|
||||
val action = action as? OnboardingAction ?: isNotMainAction(action)
|
||||
|
||||
when (action) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleNoteAction(action: Action) {
|
||||
val onboardingState = store.state.onboardingState
|
||||
val noteState = store.state.onboardingNoteState
|
||||
|
||||
when (action) {
|
||||
is OnboardingNoteAction.SetWalletManager -> {
|
||||
}
|
||||
is OnboardingNoteAction.Init -> {
|
||||
val step = if (noteState.walletManager == null) {
|
||||
OnboardingNoteStep.CreateWallet
|
||||
} else {
|
||||
OnboardingNoteStep.TopUpWallet
|
||||
}
|
||||
store.dispatch(OnboardingAction.SetInitialStepOfScreen(step))
|
||||
}
|
||||
is OnboardingNoteAction.CreateWallet -> {
|
||||
scope.launch {
|
||||
val scanNoteResponse = onboardingState.onboardingData?.scanNoteResponse
|
||||
val result = tangemSdkManager.createWallet(scanNoteResponse?.card?.cardId)
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
// val scanNoteResponse = scanNoteResponse!!.copy(card = result.data)
|
||||
// store.dispatch(OnboardingAction.SetScanNoteResponse(scanNoteResponse))
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
store.dispatch(OnboardingAction.Error("Failed to create wallet"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is OnboardingNoteAction.TopUp -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.tap.features.onboarding.products.note.redux
|
||||
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingAction
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingNoteStep
|
||||
import org.rekotlin.Action
|
||||
|
||||
class OnboardingNoteReducer {
|
||||
companion object {
|
||||
fun reduce(action: Action, state: AppState): OnboardingNoteState = internalReduce(action, state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun internalReduce(action: Action, appState: AppState): OnboardingNoteState {
|
||||
var state = appState.onboardingNoteState
|
||||
|
||||
when (action) {
|
||||
is OnboardingAction.SetInitialStepOfScreen -> {
|
||||
(action.step as? OnboardingNoteStep)?.let {
|
||||
if (it != state.currentStep && state.steps.contains(it)) {
|
||||
state = state.copy(currentStep = it)
|
||||
}
|
||||
}
|
||||
}
|
||||
OnboardingAction.SwitchToNextStep -> {
|
||||
val progress = state.progress
|
||||
if (progress >= 0 && progress != state.steps.size - 1) {
|
||||
state = state.copy(currentStep = state.steps[progress + 1])
|
||||
}
|
||||
}
|
||||
is OnboardingNoteAction.SetWalletManager -> {
|
||||
state = state.copy(walletManager = action.walletManager)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.tap.features.onboarding.products.note.redux
|
||||
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingNoteStep
|
||||
import org.rekotlin.StateType
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
data class OnboardingNoteState(
|
||||
val walletManager: WalletManager? = null,
|
||||
val currentStep: OnboardingNoteStep = OnboardingNoteStep.None,
|
||||
val steps: List<OnboardingNoteStep> = OnboardingNoteStep.values().toList(),
|
||||
) : StateType {
|
||||
|
||||
val progress: Int
|
||||
get() = steps.indexOf(currentStep)
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.tangem.tap.features.onboarding.products.old
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.tangem.tap.common.extensions.addOnBackPressedDispatcher
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingAction
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingOtherCardsState
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingOtherStep
|
||||
import com.tangem.tap.features.send.BaseStoreFragment
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import org.rekotlin.StoreSubscriber
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class OnboardingOtherCardsFragment : BaseStoreFragment(R.layout.fragment_onboarding), StoreSubscriber<OnboardingOtherCardsState> {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
activity?.addOnBackPressedDispatcher {
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
store.dispatch(OnboardingAction.SetInitialStepOfScreen(OnboardingOtherStep.Done))
|
||||
}
|
||||
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
enterTransition = inflater.inflateTransition(R.transition.fade)
|
||||
exitTransition = inflater.inflateTransition(R.transition.fade)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun subscribeToStore() {
|
||||
// store.subscribe(this) { state ->
|
||||
// state.skipRepeats { oldState, newState ->
|
||||
// oldState.onboardingOtherState == newState.onboardingOtherState
|
||||
// }.select { it.onboardingOtherState }
|
||||
// }
|
||||
}
|
||||
|
||||
override fun newState(state: OnboardingOtherCardsState) {
|
||||
if (activity == null) return
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.tangem.tap.common.extensions.addOnBackPressedDispatcher
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletState
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingAction
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingOtherStep
|
||||
import com.tangem.tap.features.send.BaseStoreFragment
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import org.rekotlin.StoreSubscriber
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class OnboardingWalletFragment : BaseStoreFragment(R.layout.fragment_onboarding_wallet), StoreSubscriber<OnboardingWalletState> {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
activity?.addOnBackPressedDispatcher {
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
store.dispatch(OnboardingAction.SetInitialStepOfScreen(OnboardingOtherStep.Done))
|
||||
}
|
||||
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
enterTransition = inflater.inflateTransition(R.transition.fade)
|
||||
exitTransition = inflater.inflateTransition(R.transition.fade)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
store.dispatch(OnboardingAction.OnboardingOtherAction.Init)
|
||||
}
|
||||
|
||||
override fun subscribeToStore() {
|
||||
store.subscribe(this) { state ->
|
||||
state.skipRepeats { oldState, newState ->
|
||||
oldState.onboardingWalletState == newState.onboardingWalletState
|
||||
}.select { it.onboardingWalletState }
|
||||
}
|
||||
}
|
||||
|
||||
override fun newState(state: OnboardingWalletState) {
|
||||
if (activity == null) return
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.redux
|
||||
|
||||
import org.rekotlin.Action
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
sealed class OnboardingWalletAction : Action {
|
||||
object Init : OnboardingWalletAction()
|
||||
object CreateWallet : OnboardingWalletAction()
|
||||
object TopUp : OnboardingWalletAction()
|
||||
object Done : OnboardingWalletAction()
|
||||
|
||||
object ProceedBackup : OnboardingWalletAction()
|
||||
|
||||
sealed class Backup : Action {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.redux
|
||||
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
class OnboardingWalletMiddleware {
|
||||
companion object {
|
||||
val handler = onboardingWalletMiddleware
|
||||
}
|
||||
}
|
||||
|
||||
private val onboardingWalletMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.redux
|
||||
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import org.rekotlin.Action
|
||||
|
||||
class OnboardingWalletReducer {
|
||||
companion object {
|
||||
fun reduce(action: Action, state: AppState): OnboardingWalletState = internalReduce(action, state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun internalReduce(action: Action, appState: AppState): OnboardingWalletState {
|
||||
var state = appState.onboardingWalletState
|
||||
|
||||
when (action) {
|
||||
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.redux
|
||||
|
||||
import com.tangem.tap.features.onboarding.redux.OnboardingStep
|
||||
import org.rekotlin.StateType
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
data class OnboardingWalletState(
|
||||
val any: String? = null
|
||||
) : StateType
|
||||
|
||||
enum class OnboardingWalletStep : OnboardingStep {
|
||||
None, CreateWallet, TopUpWallet, Backup, Done
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.tangem.tap.features.onboarding.redux
|
||||
|
||||
import org.rekotlin.Action
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
sealed class OnboardingAction : Action {
|
||||
|
||||
data class SetInitialStepOfScreen(val step: OnboardingStep) : OnboardingAction()
|
||||
object SwitchToNextStep : OnboardingAction()
|
||||
|
||||
data class SetData(val data: OnboardingData) : OnboardingAction()
|
||||
|
||||
sealed class OnboardingOtherAction : Action {
|
||||
object Init : OnboardingOtherAction()
|
||||
object CreateWallet : OnboardingOtherAction()
|
||||
object Done : OnboardingOtherAction()
|
||||
}
|
||||
|
||||
class Error(val message: String) : OnboardingAction()
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.tangem.tap.features.onboarding.redux
|
||||
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.store
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
class OnboardingMiddleware {
|
||||
companion object {
|
||||
val handler = onboardingMiddleware
|
||||
}
|
||||
}
|
||||
|
||||
private val onboardingMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
val onboardingState = store.state.onboardingState
|
||||
when (action) {
|
||||
}
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.tap.features.onboarding.redux
|
||||
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import org.rekotlin.Action
|
||||
|
||||
class OnboardingReducer {
|
||||
companion object {
|
||||
fun reduce(action: Action, state: AppState): OnboardingState = internalReduce(action, state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun internalReduce(action: Action, appState: AppState): OnboardingState {
|
||||
|
||||
if (action !is OnboardingAction) return appState.onboardingState
|
||||
|
||||
var state = appState.onboardingState
|
||||
when (action) {
|
||||
is OnboardingAction.SetData -> {
|
||||
state = state.copy(onboardingData = action.data)
|
||||
}
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.tap.features.onboarding.redux
|
||||
|
||||
import org.rekotlin.StateType
|
||||
|
||||
data class OnboardingState(
|
||||
val onboardingData: OnboardingData? = null,
|
||||
) : StateType
|
||||
|
||||
data class OnboardingOtherCardsState(
|
||||
val any: String? = null
|
||||
) : StateType
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.tangem.tap.features.onboarding.redux
|
||||
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.domain.tasks.ScanNoteResponse
|
||||
import com.tangem.tap.features.wallet.redux.Artwork
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
data class OnboardingData(
|
||||
val scanNoteResponse: ScanNoteResponse,
|
||||
val cardArtwork: Artwork,
|
||||
val balance: BigDecimal?,
|
||||
val onboardingScreen: AppScreen
|
||||
)
|
||||
|
||||
interface OnboardingStep
|
||||
|
||||
enum class OnboardingNoteStep : OnboardingStep {
|
||||
None, CreateWallet, TopUpWallet, Done
|
||||
}
|
||||
|
||||
enum class OnboardingOtherStep : OnboardingStep {
|
||||
CreateWallet, Done
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@ import com.tangem.wallet.R
|
|||
import kotlinx.android.synthetic.main.fragment_twin_cards.*
|
||||
import kotlinx.android.synthetic.main.layout_twin_cards.*
|
||||
|
||||
class TwinsOnboardingFragment : Fragment(R.layout.fragment_twin_cards) {
|
||||
class OnboardingTwinsFragment : Fragment(R.layout.fragment_twin_cards) {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
@ -107,7 +107,7 @@ class SingleWalletView : WalletView {
|
|||
tv_twin_card_number.hide()
|
||||
}
|
||||
if (twinCardsState?.showTwinOnboarding == true) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.TwinsOnboarding))
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.OnboardingTwins))
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
9
app/src/main/res/drawable/bg_circle_gray.xml
Normal file
9
app/src/main/res/drawable/bg_circle_gray.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
|
||||
<size
|
||||
android:width="236dp"
|
||||
android:height="236dp" />
|
||||
</shape>
|
||||
108
app/src/main/res/drawable/ic_home_card_back.xml
Normal file
108
app/src/main/res/drawable/ic_home_card_back.xml
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="246dp"
|
||||
android:height="196dp"
|
||||
android:viewportWidth="246"
|
||||
android:viewportHeight="196">
|
||||
<path
|
||||
android:fillColor="#E4E4E4"
|
||||
android:pathData="M2.764,83.513C1.312,79.771 3.196,75.57 6.971,74.131L191.999,3.6C195.775,2.16 200.012,4.028 201.464,7.77L242.473,113.481C243.925,117.223 242.041,121.424 238.266,122.863L53.238,193.394C49.463,194.833 45.225,192.966 43.773,189.224L2.764,83.513Z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M2.764,83.513C1.312,79.771 3.196,75.57 6.971,74.131L191.999,3.6C195.775,2.16 200.012,4.028 201.464,7.77L242.473,113.481C243.925,117.223 242.041,121.424 238.266,122.863L53.238,193.394C49.463,194.833 45.225,192.966 43.773,189.224L2.764,83.513Z"
|
||||
android:strokeWidth="0.5">
|
||||
<aapt:attr name="android:strokeColor">
|
||||
<gradient
|
||||
android:endX="244.936"
|
||||
android:endY="113.728"
|
||||
android:startX="-3.49681"
|
||||
android:startY="75.6005"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#FFDCDCDC"
|
||||
android:offset="0" />
|
||||
<item
|
||||
android:color="#FFDEDEDE"
|
||||
android:offset="0.9999" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M58.419,167.205L56.516,166.832L57.275,168.602L56.449,168.917L55.823,167.097L54.645,168.65L53.964,168.049L55.242,166.644L53.347,166.441L53.457,165.567L55.367,165.922L54.613,164.165L55.433,163.852L56.063,165.664L57.233,164.128L57.918,164.699L56.631,166.121L58.543,166.311L58.419,167.205Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M66.585,164.093L64.682,163.72L65.441,165.49L64.615,165.805L63.988,163.985L62.811,165.538L62.129,164.937L63.408,163.532L61.513,163.329L61.622,162.455L63.533,162.81L62.779,161.053L63.598,160.74L64.229,162.552L65.399,161.016L66.083,161.587L64.797,163.01L66.709,163.199L66.585,164.093Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M74.75,160.981L72.848,160.608L73.606,162.378L72.78,162.693L72.154,160.873L70.976,162.426L70.295,161.825L71.573,160.42L69.678,160.217L69.788,159.343L71.698,159.698L70.945,157.941L71.764,157.628L72.394,159.44L73.564,157.904L74.249,158.475L72.963,159.898L74.874,160.087L74.75,160.981Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M82.916,157.869L81.013,157.497L81.772,159.266L80.946,159.581L80.32,157.761L79.142,159.314L78.46,158.713L79.739,157.308L77.844,157.105L77.953,156.231L79.864,156.586L79.11,154.829L79.93,154.517L80.56,156.328L81.73,154.792L82.414,155.363L81.128,156.786L83.04,156.975L82.916,157.869Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M95.666,153.01L93.763,152.637L94.522,154.407L93.696,154.722L93.07,152.902L91.892,154.455L91.211,153.854L92.489,152.449L90.594,152.246L90.704,151.372L92.614,151.727L91.86,149.97L92.68,149.657L93.31,151.469L94.48,149.932L95.165,150.504L93.878,151.926L95.79,152.116L95.666,153.01Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M103.832,149.898L101.929,149.525L102.688,151.295L101.862,151.61L101.235,149.79L100.058,151.343L99.376,150.742L100.655,149.337L98.759,149.134L98.869,148.26L100.78,148.615L100.026,146.858L100.846,146.545L101.476,148.357L102.646,146.821L103.33,147.392L102.044,148.814L103.956,149.004L103.832,149.898Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M111.997,146.786L110.095,146.413L110.853,148.183L110.027,148.498L109.401,146.678L108.223,148.231L107.542,147.63L108.82,146.225L106.925,146.022L107.035,145.148L108.945,145.503L108.192,143.746L109.011,143.433L109.641,145.245L110.811,143.709L111.496,144.28L110.21,145.702L112.121,145.892L111.997,146.786Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M120.163,143.674L118.26,143.301L119.019,145.071L118.193,145.386L117.567,143.566L116.389,145.119L115.707,144.518L116.986,143.113L115.091,142.91L115.2,142.036L117.111,142.391L116.357,140.634L117.177,140.321L117.807,142.133L118.977,140.597L119.661,141.168L118.375,142.59L120.287,142.78L120.163,143.674Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M132.913,138.815L131.01,138.442L131.769,140.212L130.943,140.527L130.317,138.706L129.139,140.26L128.457,139.659L129.736,138.254L127.841,138.05L127.951,137.177L129.861,137.532L129.107,135.775L129.927,135.462L130.557,137.274L131.727,135.737L132.412,136.309L131.125,137.731L133.037,137.921L132.913,138.815Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M141.079,135.703L139.176,135.33L139.935,137.1L139.109,137.415L138.482,135.595L137.305,137.148L136.623,136.547L137.902,135.142L136.006,134.939L136.116,134.065L138.027,134.42L137.273,132.663L138.092,132.35L138.723,134.162L139.893,132.625L140.577,133.197L139.291,134.619L141.203,134.809L141.079,135.703Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M149.244,132.591L147.342,132.218L148.1,133.988L147.274,134.303L146.648,132.483L145.47,134.036L144.789,133.435L146.067,132.03L144.172,131.827L144.282,130.953L146.192,131.308L145.438,129.551L146.258,129.238L146.888,131.05L148.058,129.513L148.743,130.085L147.457,131.507L149.368,131.697L149.244,132.591Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M157.41,129.479L155.507,129.106L156.266,130.876L155.44,131.191L154.814,129.371L153.636,130.924L152.954,130.323L154.233,128.918L152.338,128.715L152.447,127.841L154.358,128.196L153.604,126.439L154.424,126.126L155.054,127.938L156.224,126.401L156.908,126.973L155.622,128.395L157.534,128.585L157.41,129.479Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M170.16,124.619L168.257,124.247L169.016,126.017L168.19,126.331L167.564,124.511L166.386,126.065L165.704,125.464L166.983,124.058L165.088,123.855L165.198,122.981L167.108,123.336L166.354,121.579L167.174,121.267L167.804,123.078L168.974,121.542L169.659,122.113L168.372,123.536L170.284,123.726L170.16,124.619Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M178.326,121.507L176.423,121.135L177.182,122.905L176.356,123.219L175.729,121.399L174.552,122.953L173.87,122.352L175.149,120.946L173.253,120.743L173.363,119.869L175.274,120.224L174.52,118.467L175.339,118.155L175.97,119.966L177.14,118.43L177.824,119.001L176.538,120.424L178.45,120.614L178.326,121.507Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M186.491,118.395L184.588,118.023L185.347,119.793L184.521,120.107L183.895,118.287L182.717,119.841L182.036,119.24L183.314,117.835L181.419,117.631L181.529,116.758L183.439,117.113L182.685,115.355L183.505,115.043L184.135,116.854L185.305,115.318L185.99,115.889L184.704,117.312L186.615,117.502L186.491,118.395Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M194.657,115.283L192.754,114.911L193.513,116.681L192.687,116.995L192.061,115.175L190.883,116.729L190.201,116.128L191.48,114.723L189.585,114.519L189.694,113.646L191.605,114.001L190.851,112.243L191.671,111.931L192.301,113.743L193.471,112.206L194.155,112.777L192.869,114.2L194.781,114.39L194.657,115.283Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M30.825,92.486L33.107,98.201L35.685,97.19C35.785,97.15 35.865,97.074 35.909,96.978C35.952,96.881 35.955,96.773 35.917,96.676L33.781,91.326L30.825,92.486Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M27.195,100.098C27.235,100.194 27.312,100.271 27.41,100.312C27.508,100.352 27.619,100.354 27.719,100.315L30.298,99.303L28.016,93.588L25.059,94.748L27.195,100.098Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M32.611,88.395L31.59,85.839C31.551,85.74 31.474,85.659 31.376,85.616C31.278,85.574 31.167,85.571 31.069,85.61L23.091,88.741C22.992,88.779 22.913,88.856 22.872,88.953C22.83,89.051 22.829,89.162 22.869,89.261L23.889,91.817L32.611,88.395Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M46.76,83.865C46.137,83.852 45.519,83.98 44.951,84.238C44.185,84.537 43.454,84.919 42.772,85.377L43.291,86.676C43.858,86.372 44.441,86.097 45.037,85.852C45.353,85.711 45.688,85.615 46.03,85.567C46.142,85.557 46.254,85.575 46.357,85.618C46.46,85.662 46.55,85.73 46.619,85.816C46.853,86.128 47.037,86.474 47.165,86.84L47.318,87.223C46.596,87.462 46.025,87.663 45.64,87.814C45.221,87.955 44.842,88.194 44.537,88.51C44.308,88.789 44.196,89.142 44.221,89.498C44.266,90.015 44.395,90.519 44.604,90.994C44.799,91.634 45.195,92.197 45.735,92.601C45.986,92.728 46.265,92.795 46.548,92.794C46.831,92.794 47.111,92.728 47.365,92.6C47.673,92.478 48.624,92.077 48.828,91.363C48.864,91.248 48.886,91.13 48.894,91.01L49.232,91.723L50.79,91.112L48.861,86.281C48.634,85.647 48.315,85.049 47.913,84.507C47.776,84.328 47.603,84.179 47.405,84.069C47.207,83.959 46.987,83.889 46.76,83.865ZM47.929,88.802C48.148,89.224 48.249,89.696 48.221,90.171C48.175,90.323 48.084,90.457 47.959,90.557C47.816,90.665 47.657,90.751 47.488,90.813C47.24,90.949 46.948,90.984 46.675,90.911C46.439,90.729 46.269,90.476 46.192,90.189C46.094,89.973 46.029,89.743 45.998,89.507C45.989,89.438 45.996,89.369 46.016,89.303C46.037,89.237 46.072,89.175 46.118,89.123C46.253,88.998 46.414,88.904 46.591,88.847L47.763,88.387L47.929,88.802Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M60.415,79.018C60.36,78.976 60.303,78.936 60.244,78.901C59.462,78.429 58.278,79.01 58.278,79.01C57.869,79.156 57.52,79.432 57.283,79.799C57.075,80.251 57.031,80.766 57.156,81.255C57.565,82.978 58.227,84.634 59.118,86.169C59.36,86.605 59.74,86.949 60.195,87.142C60.657,87.266 61.144,87.221 61.57,87.017C61.57,87.017 61.594,87.007 61.611,87.001C61.611,87.001 62.751,86.656 63.064,85.881C63.258,86.337 63.412,86.809 63.523,87.291C63.553,87.42 63.552,87.553 63.52,87.68C63.487,87.806 63.424,87.921 63.337,88.016C63.043,88.27 62.702,88.461 62.332,88.581L60.624,89.217L61.15,90.534C61.486,90.471 61.819,90.391 62.147,90.293C62.552,90.178 62.929,90.05 63.281,89.911C63.959,89.703 64.558,89.299 65.007,88.748C65.152,88.526 65.251,88.275 65.298,88.011C65.345,87.747 65.339,87.474 65.281,87.21C65.09,86.35 64.819,85.508 64.472,84.696L61.719,77.801L60.208,78.394L60.415,79.018ZM62.265,84.2C62.324,84.421 62.298,84.655 62.194,84.855C62.054,85.044 61.859,85.183 61.636,85.254C61.401,85.369 61.137,85.414 60.875,85.382C60.639,85.278 60.449,85.085 60.346,84.844C59.799,83.742 59.342,82.596 58.979,81.421C58.891,81.184 58.897,80.924 58.994,80.695C59.169,80.496 59.395,80.352 59.649,80.277C59.873,80.168 60.129,80.141 60.374,80.202C60.617,80.318 60.813,80.517 60.93,80.762C61.208,81.278 61.45,81.813 61.654,82.362C61.914,82.954 62.118,83.57 62.265,84.2Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M68.077,75.46C67.418,75.362 66.748,75.465 66.153,75.756C65.497,75.962 64.918,76.359 64.49,76.897C64.202,77.351 64.107,77.902 64.226,78.431C64.418,79.295 64.69,80.139 65.04,80.953C65.347,81.786 65.735,82.587 66.198,83.345C66.339,83.574 66.524,83.772 66.743,83.928C66.961,84.084 67.208,84.195 67.47,84.252C68.178,84.327 68.891,84.206 69.531,83.902C69.95,83.736 70.359,83.548 70.757,83.338C71.091,83.17 71.41,82.976 71.712,82.759L71.185,81.437C70.447,81.82 69.832,82.11 69.338,82.303C68.982,82.468 68.599,82.567 68.206,82.596C68.08,82.592 67.957,82.557 67.848,82.493C67.738,82.43 67.645,82.34 67.577,82.232C67.317,81.796 67.097,81.336 66.923,80.858L70.575,79.426L70.346,78.852C70.028,77.998 69.647,77.168 69.205,76.37C68.961,75.932 68.556,75.605 68.077,75.46ZM68.491,78.799L66.424,79.61C66.249,79.172 66.104,78.723 65.989,78.266C65.956,78.16 65.946,78.049 65.959,77.938C65.971,77.828 66.007,77.722 66.063,77.627C66.423,77.285 66.903,77.096 67.402,77.102C67.508,77.136 67.605,77.191 67.689,77.264C67.773,77.337 67.841,77.426 67.89,77.526C68.127,77.932 68.329,78.358 68.491,78.799Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M79.571,72.006C79.363,71.69 79.051,71.454 78.687,71.337C78.273,71.253 77.841,71.304 77.458,71.484C77.458,71.484 77.42,71.499 77.394,71.509C77.394,71.509 76.096,71.936 75.826,72.781C75.797,72.875 75.777,72.971 75.765,73.068C75.594,72.886 75.373,72.758 75.128,72.7C74.722,72.641 74.307,72.701 73.933,72.871C73.933,72.871 72.633,73.295 72.365,74.143C72.334,74.237 72.314,74.333 72.303,74.431L71.993,73.776L70.448,74.382L73.555,82.164L75.248,81.5L73.628,77.443C73.425,76.959 73.249,76.466 73.101,75.963C73.017,75.72 73.016,75.456 73.1,75.211C73.227,74.987 73.439,74.821 73.689,74.749C73.897,74.649 74.128,74.605 74.357,74.622C74.456,74.661 74.545,74.718 74.62,74.792C74.695,74.866 74.753,74.953 74.793,75.05C75.029,75.512 75.239,75.986 75.424,76.47L77.136,80.759L78.83,80.095L77.21,76.038C76.94,75.363 76.747,74.878 76.678,74.56C76.594,74.315 76.596,74.049 76.686,73.804C76.817,73.58 77.032,73.414 77.283,73.34C77.492,73.239 77.724,73.194 77.956,73.21C78.054,73.25 78.142,73.308 78.216,73.382C78.29,73.456 78.348,73.544 78.387,73.64C78.625,74.101 78.836,74.575 79.018,75.06L80.73,79.349L82.424,78.685L80.377,73.559C80.17,73.012 79.899,72.491 79.571,72.006Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M54.288,80.92C53.846,80.836 53.386,80.895 52.977,81.089C52.977,81.089 52.943,81.103 52.925,81.109C52.925,81.109 51.612,81.548 51.338,82.389C51.318,82.448 51.303,82.508 51.292,82.57L51.02,82.001L49.454,82.615L52.563,90.4L54.278,89.727L52.658,85.668C52.455,85.188 52.28,84.696 52.134,84.196C52.051,83.95 52.056,83.682 52.149,83.437C52.293,83.2 52.524,83.023 52.795,82.944C53.017,82.839 53.261,82.789 53.506,82.799C53.609,82.835 53.704,82.891 53.784,82.965C53.864,83.038 53.926,83.128 53.969,83.226C54.208,83.684 54.419,84.155 54.602,84.637L56.314,88.928L58.03,88.255L56.012,83.201C55.804,82.64 55.535,82.103 55.209,81.599C54.997,81.271 54.671,81.031 54.288,80.92Z" />
|
||||
<path
|
||||
android:fillColor="#707070"
|
||||
android:pathData="M39.368,83.88L37.631,84.561L38.522,86.793L37.441,87.217L38.011,88.643L39.091,88.219L41.668,94.672L43.405,93.991L40.828,87.538L42.15,87.019L41.58,85.593L40.259,86.112L39.368,83.88Z" />
|
||||
</vector>
|
||||
126
app/src/main/res/drawable/ic_home_card_front.xml
Normal file
126
app/src/main/res/drawable/ic_home_card_front.xml
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="256dp"
|
||||
android:height="160dp"
|
||||
android:viewportWidth="256"
|
||||
android:viewportHeight="160">
|
||||
<path
|
||||
android:fillAlpha="0.03"
|
||||
android:pathData="M10.892,8.102L239.889,0.339A9.999,10.001 133.108,0 1,250.223 9.994L254.666,140.586A9.999,10.001 133.108,0 1,245.012 150.919L16.016,158.682A9.999,10.001 133.108,0 1,5.681 149.027L1.238,18.435A9.999,10.001 133.108,0 1,10.892 8.102z" />
|
||||
<path
|
||||
android:fillAlpha="0.5"
|
||||
android:pathData="M10.892,8.102L239.889,0.339A9.999,10.001 133.108,0 1,250.223 9.994L254.666,140.586A9.999,10.001 133.108,0 1,245.012 150.919L16.016,158.682A9.999,10.001 133.108,0 1,5.681 149.027L1.238,18.435A9.999,10.001 133.108,0 1,10.892 8.102z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:centerX="8.62593"
|
||||
android:centerY="16.876131"
|
||||
android:gradientRadius="268.5784"
|
||||
android:type="radial">
|
||||
<item
|
||||
android:color="#FFFFFFFF"
|
||||
android:offset="0" />
|
||||
<item
|
||||
android:color="#19FFFFFF"
|
||||
android:offset="1" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#1B1D1C"
|
||||
android:pathData="M10.892,8.102L239.889,0.339A9.999,10.001 133.108,0 1,250.223 9.994L254.666,140.586A9.999,10.001 133.108,0 1,245.012 150.919L16.016,158.682A9.999,10.001 133.108,0 1,5.681 149.027L1.238,18.435A9.999,10.001 133.108,0 1,10.892 8.102z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M10.909,8.602L239.906,0.839A9.499,9.501 133.108,0 1,249.723 10.011L254.167,140.603A9.499,9.501 133.108,0 1,244.995 150.419L15.999,158.182A9.499,9.501 133.108,0 1,6.181 149.01L1.738,18.418A9.499,9.501 133.108,0 1,10.909 8.602z"
|
||||
android:strokeWidth="1">
|
||||
<aapt:attr name="android:strokeColor">
|
||||
<gradient
|
||||
android:endX="253.74025"
|
||||
android:endY="145.41006"
|
||||
android:startX="3.852738"
|
||||
android:startY="11.758317"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#FF1A1A1A"
|
||||
android:offset="0" />
|
||||
<item
|
||||
android:color="#FF565656"
|
||||
android:offset="1" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M32.283,129.077L30.278,127.906L30.428,130.208L29.366,130.24L29.386,127.932L27.43,129.227L26.899,128.278L28.91,127.19L26.846,126.214L27.32,125.267L29.341,126.422L29.192,124.135L30.245,124.104L30.233,126.404L32.173,125.125L32.719,126.041L30.693,127.146L32.781,128.113L32.283,129.077Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M42.776,128.768L40.771,127.597L40.921,129.9L39.86,129.931L39.88,127.623L37.924,128.919L37.393,127.97L39.403,126.881L37.339,125.905L37.813,124.959L39.834,126.113L39.685,123.826L40.738,123.796L40.726,126.095L42.666,124.816L43.213,125.732L41.186,126.837L43.275,127.805L42.776,128.768Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M53.27,128.459L51.264,127.288L51.414,129.591L50.353,129.622L50.373,127.314L48.417,128.61L47.886,127.661L49.897,126.573L47.832,125.597L48.307,124.65L50.328,125.804L50.178,123.518L51.231,123.487L51.219,125.786L53.16,124.507L53.706,125.424L51.679,126.528L53.768,127.496L53.27,128.459Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M63.763,128.15L61.758,126.979L61.908,129.282L60.846,129.313L60.866,127.006L58.91,128.301L58.379,127.352L60.39,126.264L58.326,125.288L58.8,124.341L60.821,125.496L60.672,123.209L61.725,123.178L61.713,125.478L63.653,124.199L64.199,125.115L62.173,126.22L64.261,127.187L63.763,128.15Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M80.148,127.668L78.142,126.497L78.293,128.8L77.231,128.831L77.251,126.524L75.295,127.819L74.764,126.87L76.775,125.782L74.71,124.806L75.185,123.859L77.206,125.014L77.057,122.727L78.11,122.696L78.098,124.995L80.038,123.717L80.584,124.633L78.558,125.738L80.646,126.705L80.148,127.668Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M90.641,127.36L88.636,126.189L88.786,128.491L87.725,128.523L87.745,126.215L85.789,127.51L85.257,126.561L87.268,125.473L85.204,124.497L85.678,123.551L87.699,124.705L87.55,122.418L88.603,122.387L88.591,124.687L90.531,123.408L91.077,124.324L89.051,125.429L91.14,126.396L90.641,127.36Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M101.135,127.051L99.129,125.88L99.279,128.183L98.218,128.214L98.238,125.906L96.282,127.202L95.751,126.253L97.762,125.165L95.697,124.188L96.172,123.242L98.193,124.396L98.043,122.11L99.096,122.079L99.084,124.378L101.024,123.099L101.571,124.016L99.544,125.12L101.633,126.088L101.135,127.051Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M111.628,126.742L109.622,125.571L109.772,127.874L108.711,127.905L108.731,125.598L106.775,126.893L106.244,125.944L108.255,124.856L106.19,123.88L106.665,122.933L108.686,124.088L108.536,121.801L109.59,121.77L109.577,124.069L111.518,122.79L112.064,123.707L110.038,124.811L112.126,125.779L111.628,126.742Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M128.013,126.26L126.007,125.089L126.157,127.392L125.096,127.423L125.116,125.115L123.16,126.411L122.629,125.462L124.64,124.374L122.575,123.398L123.05,122.451L125.071,123.605L124.921,121.319L125.975,121.288L125.962,123.587L127.903,122.308L128.449,123.225L126.422,124.329L128.511,125.297L128.013,126.26Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M138.506,125.951L136.501,124.781L136.651,127.083L135.589,127.114L135.609,124.807L133.653,126.102L133.122,125.153L135.133,124.065L133.069,123.089L133.543,122.142L135.564,123.297L135.415,121.01L136.468,120.979L136.456,123.279L138.396,122L138.942,122.916L136.916,124.021L139.004,124.988L138.506,125.951Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M148.999,125.643L146.994,124.472L147.144,126.775L146.083,126.806L146.103,124.498L144.147,125.794L143.616,124.845L145.626,123.756L143.562,122.78L144.036,121.834L146.058,122.988L145.908,120.701L146.961,120.67L146.949,122.97L148.889,121.691L149.436,122.607L147.409,123.712L149.498,124.68L148.999,125.643Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M159.493,125.334L157.487,124.163L157.637,126.466L156.576,126.497L156.596,124.189L154.64,125.485L154.109,124.536L156.12,123.448L154.055,122.471L154.53,121.525L156.551,122.679L156.401,120.393L157.455,120.362L157.442,122.661L159.383,121.382L159.929,122.299L157.902,123.403L159.991,124.371L159.493,125.334Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M175.878,124.852L173.872,123.681L174.022,125.984L172.961,126.015L172.981,123.707L171.025,125.003L170.494,124.054L172.505,122.966L170.44,121.989L170.915,121.043L172.936,122.197L172.786,119.911L173.839,119.88L173.827,122.179L175.767,120.9L176.314,121.817L174.287,122.921L176.376,123.889L175.878,124.852Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M186.371,124.543L184.365,123.372L184.515,125.675L183.454,125.706L183.474,123.399L181.518,124.694L180.987,123.745L182.998,122.657L180.933,121.681L181.408,120.734L183.429,121.889L183.28,119.602L184.333,119.571L184.32,121.87L186.261,120.591L186.807,121.508L184.781,122.613L186.869,123.58L186.371,124.543Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M196.864,124.235L194.859,123.064L195.009,125.366L193.947,125.398L193.968,123.09L192.012,124.385L191.48,123.436L193.491,122.348L191.427,121.372L191.901,120.425L193.922,121.58L193.773,119.293L194.826,119.262L194.814,121.562L196.754,120.283L197.3,121.199L195.274,122.304L197.363,123.271L196.864,124.235Z" />
|
||||
<path
|
||||
android:fillColor="#A5A5A5"
|
||||
android:pathData="M207.358,123.926L205.352,122.755L205.502,125.058L204.441,125.089L204.461,122.781L202.505,124.077L201.974,123.128L203.985,122.039L201.92,121.063L202.394,120.117L204.416,121.271L204.266,118.984L205.319,118.954L205.307,121.253L207.247,119.974L207.794,120.89L205.767,121.995L207.856,122.963L207.358,123.926Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M29.972,38.778L30.243,44.919L33.014,44.799C33.121,44.794 33.221,44.748 33.295,44.671C33.367,44.594 33.406,44.493 33.402,44.389L33.148,38.641L29.972,38.778Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M24.03,44.796C24.036,44.9 24.084,44.997 24.163,45.067C24.242,45.137 24.347,45.175 24.454,45.171L27.225,45.05L26.954,38.909L23.777,39.047L24.03,44.796Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M33.009,35.491L32.888,32.745C32.883,32.638 32.837,32.537 32.758,32.465C32.681,32.393 32.576,32.355 32.471,32.359L23.899,32.732C23.792,32.737 23.693,32.784 23.621,32.862C23.549,32.941 23.512,33.046 23.517,33.152L23.638,35.899L33.009,35.491Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M47.875,35.796C47.29,35.582 46.664,35.502 46.042,35.563C45.219,35.597 44.403,35.72 43.607,35.932L43.669,37.328C44.305,37.225 44.947,37.154 45.591,37.115C45.936,37.084 46.284,37.103 46.623,37.168C46.732,37.195 46.833,37.248 46.916,37.322C46.999,37.397 47.061,37.491 47.098,37.595C47.216,37.965 47.276,38.351 47.276,38.739L47.294,39.15C46.533,39.142 45.927,39.147 45.513,39.165C45.071,39.163 44.634,39.265 44.241,39.465C43.933,39.655 43.711,39.952 43.617,40.297C43.489,40.799 43.445,41.318 43.485,41.835C43.459,42.503 43.647,43.163 44.024,43.719C44.219,43.921 44.461,44.075 44.729,44.166C44.997,44.258 45.283,44.285 45.565,44.246C45.896,44.232 46.928,44.161 47.356,43.552C47.427,43.455 47.487,43.351 47.534,43.241L47.618,44.024L49.292,43.951L49.063,38.76C49.057,38.087 48.953,37.419 48.752,36.777C48.681,36.563 48.567,36.366 48.416,36.198C48.265,36.029 48.081,35.892 47.875,35.796ZM47.35,40.841C47.418,41.311 47.358,41.789 47.175,42.229C47.082,42.357 46.951,42.455 46.8,42.509C46.629,42.564 46.451,42.594 46.271,42.598C45.992,42.646 45.704,42.585 45.47,42.428C45.307,42.179 45.23,41.884 45.251,41.589C45.23,41.352 45.245,41.114 45.293,40.881C45.308,40.813 45.337,40.75 45.378,40.694C45.419,40.638 45.473,40.592 45.534,40.557C45.702,40.483 45.886,40.446 46.071,40.449L47.331,40.395L47.35,40.841Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M62.377,35.641C62.339,35.583 62.299,35.528 62.254,35.475C61.671,34.775 60.361,34.941 60.361,34.941C59.926,34.946 59.505,35.094 59.16,35.364C58.814,35.724 58.603,36.196 58.56,36.699C58.378,38.46 58.457,40.24 58.793,41.978C58.878,42.47 59.124,42.918 59.49,43.248C59.886,43.514 60.361,43.63 60.831,43.574C60.831,43.574 60.857,43.573 60.875,43.572C60.875,43.572 62.066,43.616 62.617,42.985C62.65,43.479 62.64,43.975 62.585,44.467C62.572,44.598 62.527,44.724 62.454,44.833C62.382,44.942 62.285,45.031 62.171,45.092C61.809,45.236 61.424,45.306 61.035,45.3L59.211,45.347L59.274,46.762C59.612,46.812 59.953,46.844 60.295,46.858C60.716,46.881 61.114,46.882 61.493,46.865C62.202,46.887 62.902,46.699 63.508,46.324C63.718,46.162 63.895,45.957 64.026,45.722C64.158,45.488 64.242,45.229 64.274,44.96C64.377,44.085 64.399,43.201 64.338,42.322L64.011,34.914L62.388,34.984L62.377,35.641ZM62.416,41.138C62.399,41.366 62.298,41.579 62.133,41.734C61.939,41.867 61.709,41.935 61.474,41.93C61.214,41.963 60.95,41.919 60.713,41.804C60.524,41.629 60.409,41.386 60.391,41.125C60.237,39.905 60.183,38.675 60.228,37.447C60.223,37.194 60.314,36.95 60.481,36.765C60.712,36.634 60.974,36.571 61.238,36.583C61.486,36.552 61.737,36.61 61.948,36.747C62.139,36.935 62.259,37.187 62.289,37.457C62.382,38.034 62.434,38.618 62.446,39.203C62.496,39.847 62.486,40.495 62.416,41.138Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M70.792,34.762C70.201,34.456 69.534,34.336 68.876,34.418C68.188,34.4 67.509,34.588 66.928,34.957C66.506,35.293 66.235,35.783 66.173,36.321C66.069,37.2 66.048,38.086 66.11,38.969C66.125,39.855 66.228,40.738 66.415,41.604C66.472,41.867 66.583,42.114 66.737,42.332C66.893,42.55 67.09,42.735 67.318,42.874C67.962,43.175 68.676,43.291 69.382,43.211C69.832,43.191 70.281,43.146 70.726,43.076C71.097,43.025 71.462,42.946 71.82,42.838L71.757,41.418C70.934,41.54 70.257,41.615 69.726,41.638C69.335,41.678 68.941,41.648 68.56,41.548C68.442,41.503 68.338,41.43 68.255,41.334C68.172,41.239 68.115,41.124 68.086,41C67.983,40.504 67.927,39.998 67.92,39.49L71.844,39.319L71.817,38.703C71.798,37.793 71.712,36.885 71.557,35.988C71.471,35.494 71.196,35.054 70.792,34.762ZM70.081,38.051L67.861,38.148C67.84,37.677 67.851,37.207 67.893,36.738C67.897,36.626 67.924,36.518 67.972,36.418C68.02,36.318 68.089,36.229 68.174,36.157C68.627,35.951 69.143,35.928 69.612,36.095C69.701,36.161 69.774,36.245 69.83,36.341C69.885,36.437 69.92,36.543 69.934,36.654C70.024,37.114 70.074,37.582 70.081,38.051Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M82.794,35.223C82.701,34.857 82.484,34.533 82.179,34.304C81.815,34.091 81.39,34 80.969,34.045C80.969,34.045 80.928,34.047 80.9,34.048C80.9,34.048 79.533,34.031 78.998,34.741C78.941,34.821 78.89,34.905 78.846,34.993C78.745,34.766 78.578,34.574 78.366,34.439C78.002,34.252 77.59,34.174 77.18,34.213C77.18,34.213 75.812,34.193 75.278,34.907C75.219,34.986 75.167,35.07 75.125,35.159L75.048,34.44L73.388,34.512L73.757,42.873L75.577,42.794L75.384,38.436C75.352,37.913 75.348,37.389 75.374,36.866C75.374,36.609 75.461,36.359 75.62,36.155C75.814,35.984 76.07,35.896 76.33,35.91C76.56,35.882 76.792,35.915 77.004,36.005C77.084,36.074 77.149,36.158 77.195,36.252C77.242,36.346 77.268,36.447 77.274,36.551C77.345,37.064 77.387,37.581 77.401,38.098L77.605,42.706L79.425,42.627L79.232,38.269C79.2,37.543 79.177,37.022 79.217,36.699C79.218,36.44 79.308,36.19 79.473,35.988C79.672,35.819 79.929,35.731 80.191,35.742C80.422,35.714 80.657,35.747 80.87,35.838C80.949,35.907 81.013,35.991 81.059,36.085C81.105,36.178 81.131,36.28 81.136,36.384C81.209,36.896 81.251,37.413 81.263,37.931L81.467,42.539L83.286,42.46L83.043,36.952C83.027,36.368 82.944,35.788 82.794,35.223Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M55.96,35.452C55.57,35.23 55.116,35.137 54.665,35.188C54.665,35.188 54.628,35.189 54.61,35.19C54.61,35.19 53.224,35.179 52.688,35.885C52.649,35.934 52.615,35.986 52.584,36.041L52.515,35.415L50.833,35.488L51.203,43.852L53.046,43.772L52.853,39.412C52.82,38.892 52.817,38.371 52.844,37.85C52.846,37.591 52.939,37.34 53.108,37.138C53.323,36.961 53.599,36.869 53.881,36.882C54.126,36.854 54.373,36.886 54.601,36.975C54.687,37.043 54.758,37.127 54.809,37.222C54.86,37.317 54.89,37.422 54.898,37.529C54.973,38.039 55.017,38.552 55.03,39.068L55.234,43.677L57.077,43.597L56.837,38.168C56.825,37.57 56.748,36.975 56.606,36.393C56.514,36.014 56.285,35.681 55.96,35.452Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M40.884,33.414L39.018,33.495L39.124,35.893L37.963,35.943L38.03,37.476L39.191,37.425L39.498,44.359L41.364,44.278L41.057,37.344L42.477,37.283L42.41,35.75L40.99,35.812L40.884,33.414Z" />
|
||||
</vector>
|
||||
|
|
@ -2,95 +2,126 @@
|
|||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
app:layoutDescription="@xml/fragment_welcome_scene">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_home_card"
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/imv_back_card"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="73dp"
|
||||
android:layout_marginEnd="77dp"
|
||||
android:elevation="3dp"
|
||||
android:src="@drawable/ic_card_home"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_home_circle"
|
||||
android:layout_width="374dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:elevation="0dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_ellipse_4"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
android:src="@drawable/ic_home_card_back"
|
||||
android:translationY="-55dp"
|
||||
app:layout_constraintEnd_toEndOf="@+id/imv_front_card"
|
||||
app:layout_constraintStart_toStartOf="@+id/imv_front_card"
|
||||
app:layout_constraintTop_toBottomOf="@+id/imv_front_card" />
|
||||
|
||||
|
||||
<ImageView
|
||||
android:layout_width="88dp"
|
||||
android:layout_height="26dp"
|
||||
android:layout_marginTop="120dp"
|
||||
android:layout_marginEnd="50dp"
|
||||
android:elevation="3dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_tangem_logo"
|
||||
app:layout_constraintEnd_toEndOf="@id/iv_home_card"
|
||||
app:layout_constraintTop_toTopOf="@+id/iv_home_card" />
|
||||
|
||||
<ImageView
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/imv_front_card"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="153dp"
|
||||
android:layout_marginEnd="50dp"
|
||||
android:elevation="3dp"
|
||||
android:layout_marginTop="48dp"
|
||||
android:elevation="1dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_dots"
|
||||
app:layout_constraintEnd_toEndOf="@id/iv_home_card"
|
||||
app:layout_constraintTop_toTopOf="@+id/iv_home_card" />
|
||||
android:src="@drawable/ic_home_card_front"
|
||||
android:transitionName="imv_front_card"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.496"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/view" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_home_description"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/tv_home_header"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="100dp"
|
||||
android:paddingStart="30dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/home_welcome"
|
||||
android:textColor="@color/darkGray6"
|
||||
android:textSize="29sp"
|
||||
app:layout_constraintTop_toBottomOf="@id/iv_home_card" />
|
||||
android:layout_marginBottom="14dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="@string/home_welcome_header"
|
||||
android:textColor="#060606"
|
||||
android:textSize="24sp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tv_home_body"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.508"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_home_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="50dp"
|
||||
android:text="@string/home_welcome_body"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#686868"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/fl_scan_card_container"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fl_scan_card_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btn_get_new_card"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_scan_card"
|
||||
style="@style/TapButton"
|
||||
android:layout_width="295dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@string/home_button_scan" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_gravity="center"
|
||||
android:elevation="18dp"
|
||||
android:indeterminate="true"
|
||||
android:indeterminateTint="@color/backgroundLightGray"
|
||||
android:translationY="-4dp" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_shop"
|
||||
style="@style/TapBlackButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="33dp"
|
||||
android:text="@string/common_no"
|
||||
app:icon="@drawable/ic_shop"
|
||||
android:id="@+id/btn_get_new_card"
|
||||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="295dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="@string/home_button_get_new_card"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/tapButtonColorBlack"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:id="@+id/guideline2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintGuide_percent="0.37" />
|
||||
app:layout_constraintGuide_percent="0.5"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_yes"
|
||||
style="@style/TapButtonWithIcon"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="33dp"
|
||||
android:text="@string/home_button_yes"
|
||||
app:icon="@drawable/ic_send"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
<View
|
||||
android:id="@+id/view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="20dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/guideline" />
|
||||
app:layout_constraintHorizontal_bias="0.498"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
|||
161
app/src/main/res/layout/fragment_onboarding.xml
Normal file
161
app/src/main/res/layout/fragment_onboarding.xml
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/coordinator_details_confirm"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/backgroundLightGray"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
style="@style/Widget.MaterialComponents.Toolbar.Surface"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/backgroundLightGray"
|
||||
android:fitsSystemWindows="true"
|
||||
app:liftOnScroll="true">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:navigationIcon="@drawable/ic_baseline_arrow_back_24"
|
||||
app:title="@string/onboarding_title" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/onboarding_main_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layoutDescription="@xml/fragment_welcome_scene"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/pb_state"
|
||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/imv_back_card"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="0dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/bg_circle_gray"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/imv_front_card"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintEnd_toEndOf="@+id/imv_front_card"
|
||||
app:layout_constraintStart_toStartOf="@+id/imv_front_card"
|
||||
app:layout_constraintTop_toTopOf="@+id/imv_front_card"
|
||||
app:tint="#F3F3F3" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/imv_front_card"
|
||||
android:layout_width="296dp"
|
||||
android:layout_height="180dp"
|
||||
android:layout_marginTop="72dp"
|
||||
android:background="@drawable/card_default"
|
||||
android:elevation="1dp"
|
||||
android:scaleType="fitXY"
|
||||
android:transitionName="imv_front_card"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/pb_state" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/ll_header_body_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginTop="72dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/guideline2">
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_header"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="72dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="Header"
|
||||
android:textColor="#060606"
|
||||
android:textSize="24sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.504"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/guideline2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_body"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="64dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginEnd="64dp"
|
||||
android:text="Body"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#686868"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_header" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_main_action"
|
||||
style="@style/TapButton"
|
||||
android:layout_width="295dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="92dp"
|
||||
android:text="Main Action"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_alternative_action"
|
||||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="295dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:text="Atlernative action"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/tapButtonColorBlack"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintGuide_percent="0.5"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_check_balance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="Check balance"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/guideline2" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
6
app/src/main/res/layout/fragment_onboarding_wallet.xml
Normal file
6
app/src/main/res/layout/fragment_onboarding_wallet.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
Loading…
Add table
Add a link
Reference in a new issue