diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/PersonalizeAction.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/PersonalizeAction.kt index 0ccf2ed28f..d82d8c7ddf 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/PersonalizeAction.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/PersonalizeAction.kt @@ -11,7 +11,7 @@ import com.tangem.tangemtest.ucase.variants.personalize.dto.DefaultPersonalizePa */ class PersonalizeAction : BaseAction() { override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val cardConfig = attrs.payload.remove(PayloadKey.CardConfig) as? CardConfig + val cardConfig = attrs.payload.remove(PayloadKey.cardConfig) as? CardConfig ?: throw IllegalArgumentException("CardConfig must be in the payloads of the ParamsManager") val issuer = DefaultPersonalizeParams.issuer() diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/ItemsManager.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/ItemsManager.kt index 0cd35fbc78..6a37f00b34 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/ItemsManager.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/ItemsManager.kt @@ -30,9 +30,10 @@ interface ItemsManager : PayloadHolder { interface PayloadKey { companion object { - val CardConfig: String = "cardConfig" - val IncominJson: String = "incomingJson" - val Card = "card" + val cardConfig: String = "cardConfig" + val incomingJson: String = "incomingJson" + val card = "card" + val actionView = "actionView" } } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/triggers/afterAction/AfterScanModifier.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/triggers/afterAction/AfterScanModifier.kt index 5dc7b53200..9b1e7b6f2f 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/triggers/afterAction/AfterScanModifier.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/triggers/afterAction/AfterScanModifier.kt @@ -1,12 +1,17 @@ package com.tangem.tangemtest.ucase.domain.paramsManager.triggers.afterAction +import com.tangem.commands.Card +import com.tangem.commands.CardStatus import com.tangem.tangemtest._arch.structure.PayloadHolder import com.tangem.tangemtest._arch.structure.abstraction.Item import com.tangem.tangemtest.ucase.domain.paramsManager.PayloadKey import com.tangem.tangemtest.ucase.domain.paramsManager.findDataItem +import com.tangem.tangemtest.ucase.tunnel.ActionView +import com.tangem.tangemtest.ucase.tunnel.CardError import com.tangem.tangemtest.ucase.variants.TlvId import com.tangem.tasks.ScanEvent import com.tangem.tasks.TaskEvent +import ru.dev.gbixahue.eu4d.lib.android.global.threading.postUI /** [REDACTED_AUTHOR] @@ -17,10 +22,19 @@ class AfterScanModifier : AfterActionModification { return if (taskEvent is TaskEvent.Event && taskEvent.data is ScanEvent.OnReadEvent) { val card = (taskEvent.data as ScanEvent.OnReadEvent).card - payload.set(PayloadKey.Card, card) + val actionView = payload.remove(PayloadKey.actionView) as? ActionView ?: return listOf() + + if (isPersonalized(card)) { + actionView.showSnackbar(CardError.NotPersonalized) + return listOf() + } + + payload.set(PayloadKey.card, card) foundItem.setData(card.cardId) + postUI { actionView.showActionFab(true) } listOf(foundItem) } else listOf() } + private fun isPersonalized(card: Card): Boolean = card.status == CardStatus.NotPersonalized } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/triggers/changeConsequence/ParamChangeConsequence.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/triggers/changeConsequence/ParamChangeConsequence.kt index 6d8543cc64..0b2cd58b84 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/triggers/changeConsequence/ParamChangeConsequence.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/triggers/changeConsequence/ParamChangeConsequence.kt @@ -27,7 +27,7 @@ class SignScanConsequence: ItemsChangeConsequence { val hashItem = itemList.findDataItem(TlvId.TransactionOutHash) ?: return null val affectedItems = mutableListOf(hashItem) - val card = payload.remove(PayloadKey.Card) as Card? + val card = payload.remove(PayloadKey.card) as Card? if (card == null) { hashItem.restoreDefaultData() } else { diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/tunnel/Errors.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/tunnel/Errors.kt new file mode 100644 index 0000000000..e10f81c669 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/tunnel/Errors.kt @@ -0,0 +1,10 @@ +package com.tangem.tangemtest.ucase.tunnel + +import com.tangem.tangemtest._arch.structure.Id + +/** +[REDACTED_AUTHOR] + */ +enum class CardError : Id { + NotPersonalized +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/tunnel/ViewScreen.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/tunnel/ViewScreen.kt new file mode 100644 index 0000000000..4103f4f467 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/tunnel/ViewScreen.kt @@ -0,0 +1,14 @@ +package com.tangem.tangemtest.ucase.tunnel + +import com.tangem.tangemtest._arch.structure.Id + +interface ViewScreen + +interface SnackbarHolder { + fun showSnackbar(message: String) + fun showSnackbar(id: Id) +} + +interface ActionView : ViewScreen, SnackbarHolder { + fun showActionFab(enable: Boolean) +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/BaseCardActionFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/BaseCardActionFragment.kt index 16d0d5b945..1f6f679601 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/BaseCardActionFragment.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/BaseCardActionFragment.kt @@ -16,26 +16,31 @@ import com.google.android.material.snackbar.Snackbar import com.tangem.CardManager import com.tangem.tangem_sdk_new.extensions.init import com.tangem.tangemtest.R +import com.tangem.tangemtest._arch.structure.Id import com.tangem.tangemtest._arch.structure.abstraction.BaseItem import com.tangem.tangemtest._main.MainViewModel import com.tangem.tangemtest.ucase.domain.paramsManager.ItemsManager import com.tangem.tangemtest.ucase.domain.paramsManager.ParamsManagerFactory +import com.tangem.tangemtest.ucase.domain.paramsManager.PayloadKey import com.tangem.tangemtest.ucase.resources.ActionType +import com.tangem.tangemtest.ucase.tunnel.ActionView +import com.tangem.tangemtest.ucase.tunnel.CardError import com.tangem.tangemtest.ucase.ui.widgets.ParameterWidget -import ru.dev.gbixahue.eu4d.lib.android._android.views.find import ru.dev.gbixahue.eu4d.lib.android.global.log.Log import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder /** [REDACTED_AUTHOR] */ -abstract class BaseCardActionFragment : Fragment(), LayoutHolder { +abstract class BaseCardActionFragment : Fragment(), LayoutHolder, ActionView { protected val incomingParamsContainer: ViewGroup by lazy { mainView.findViewById(R.id.ll_incoming_params_container) } - protected val viewModel: ParamsViewModel by viewModels { ActionViewModelFactory(itemsManager) } protected lateinit var mainView: View + protected val actionFab: FloatingActionButton by lazy { mainView.findViewById(R.id.fab_action) } + + protected val paramsVM: ParamsViewModel by viewModels { ActionViewModelFactory(itemsManager) } protected val widgetList = mutableListOf() private val itemsManager: ItemsManager by lazy { ParamsManagerFactory.createFactory().get(getAction())!! } @@ -50,23 +55,26 @@ abstract class BaseCardActionFragment : Fragment(), LayoutHolder { super.onViewCreated(view, savedInstanceState) Log.d(this, "onViewCreated") - viewModel.setCardManager(CardManager.init(requireActivity())) + viewLifecycleOwner.lifecycle.addObserver(paramsVM) + paramsVM.setCardManager(CardManager.init(requireActivity())) + paramsVM.attachToPayload(mutableMapOf(PayloadKey.actionView to this as ActionView)) initFab() + showActionFab(false) createWidgets { subscribeToViewModelChanges() } } private fun initFab() { Log.d(this, "initFab") - mainView.find(R.id.fab_action)?.setOnClickListener { viewModel.invokeMainAction() } + actionFab.setOnClickListener { paramsVM.invokeMainAction() } } private fun createWidgets(widgetCreatedCallback: () -> Unit) { Log.d(this, "createWidgets") - viewModel.ldParams.observe(viewLifecycleOwner, Observer { itemList -> + paramsVM.ldParams.observe(viewLifecycleOwner, Observer { itemList -> itemList.forEach { param -> val widget = ParameterWidget(inflateParamView(incomingParamsContainer), param) - widget.onValueChanged = { id, value -> viewModel.userChangedItem(id, value) } - widget.onActionBtnClickListener = viewModel.getItemAction(param.id) + widget.onValueChanged = { id, value -> paramsVM.userChangedItem(id, value) } + widget.onActionBtnClickListener = paramsVM.getItemAction(param.id) widgetList.add(widget) } widgetCreatedCallback() @@ -83,18 +91,18 @@ abstract class BaseCardActionFragment : Fragment(), LayoutHolder { protected open fun listenResponse() { val tvResponse by lazy { mainView.findViewById(R.id.tv_action_response_json) } - viewModel.ldResponse.observe(viewLifecycleOwner, Observer { + paramsVM.ldResponse.observe(viewLifecycleOwner, Observer { Log.d(this, "action response: ${if (it.length > 50) it.substring(0..50) else it}") tvResponse.text = it }) } protected open fun listenError() { - viewModel.seError.observe(viewLifecycleOwner, Observer { showSnackbarMessage(it) }) + paramsVM.seError.observe(viewLifecycleOwner, Observer { showSnackbar(it) }) } protected open fun listenChangedItems() { - viewModel.seChangedItems.observe(viewLifecycleOwner, Observer { itemList -> + paramsVM.seChangedItems.observe(viewLifecycleOwner, Observer { itemList -> itemList.forEach { item -> Log.d(this, "item changed from VM - name: ${item.id}") val dataItem = item as? BaseItem ?: return@Observer @@ -111,10 +119,6 @@ abstract class BaseCardActionFragment : Fragment(), LayoutHolder { }) } - protected fun showSnackbarMessage(message: String) { - Snackbar.make(mainView, message, BaseTransientBottomBar.LENGTH_SHORT).show() - } - private fun inflateParamView(where: ViewGroup): ViewGroup { val inflater = LayoutInflater.from(where.context) val view = inflater.inflate(R.layout.w_card_incoming_param, where, false) @@ -122,5 +126,21 @@ abstract class BaseCardActionFragment : Fragment(), LayoutHolder { return view as ViewGroup } + override fun showActionFab(enable: Boolean) { + if (enable) actionFab.show() else actionFab.hide() + } + + override fun showSnackbar(id: Id) { +// MainResourceHolder.safeGet<>() + when (id) { + CardError.NotPersonalized -> showSnackbar(requireContext().getString(R.string.card_error_not_personalized)) + else -> showSnackbar(requireContext().getString(R.string.unknown)) + } + } + + override fun showSnackbar(message: String) { + Snackbar.make(mainView, message, BaseTransientBottomBar.LENGTH_SHORT).show() + } + abstract fun getAction(): ActionType } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/ParamsViewModel.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/ParamsViewModel.kt index 21923e152d..0ead6ab91a 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/ParamsViewModel.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/ParamsViewModel.kt @@ -1,18 +1,18 @@ package com.tangem.tangemtest.ucase.ui import androidx.annotation.UiThread -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.* import com.google.gson.Gson import com.tangem.CardManager import com.tangem.commands.Card import com.tangem.tangemtest._arch.SingleLiveEvent import com.tangem.tangemtest._arch.structure.Id +import com.tangem.tangemtest._arch.structure.Payload import com.tangem.tangemtest._arch.structure.abstraction.Item import com.tangem.tangemtest.commons.performAction import com.tangem.tangemtest.ucase.domain.paramsManager.ItemsManager import com.tangem.tangemtest.ucase.domain.responses.GsonInitializer +import com.tangem.tangemtest.ucase.tunnel.ViewScreen import com.tangem.tasks.ScanEvent import com.tangem.tasks.TaskError import com.tangem.tasks.TaskEvent @@ -25,11 +25,12 @@ class ActionViewModelFactory(private val manager: ItemsManager) : ViewModelProvi override fun create(modelClass: Class): T = ParamsViewModel(manager) as T } -class ParamsViewModel(val itemsManager: ItemsManager) : ViewModel() { +class ParamsViewModel(private val itemsManager: ItemsManager) : ViewModel(), LifecycleObserver { val ldCard = MutableLiveData() val ldIsVerified = MutableLiveData() val ldResponse = MutableLiveData() + val ldReadResponse = MutableLiveData() val ldParams = MutableLiveData(itemsManager.getItems()) val seError: MutableLiveData = SingleLiveEvent() @@ -51,8 +52,7 @@ class ParamsViewModel(val itemsManager: ItemsManager) : ViewModel() { } //invokes Scan, Sign etc... - fun invokeMainAction(payload: MutableMap = mutableMapOf()) { - itemsManager.attachPayload(payload) + fun invokeMainAction() { performAction(itemsManager, cardManager) { paramsManager, cardManager -> paramsManager.invokeMainAction(cardManager) { response, listOfChangedParams -> notifier.handleActionResult(response, listOfChangedParams) @@ -69,6 +69,17 @@ class ParamsViewModel(val itemsManager: ItemsManager) : ViewModel() { } } } + + fun attachToPayload(payload: Payload) { + itemsManager.attachPayload(payload) + } + + @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) + fun viewOnDestroy() { + val keyList = mutableListOf() + itemsManager.payload.filterValues { it is ViewScreen }.forEach { keyList.add(it.key) } + keyList.forEach { itemsManager.payload.remove(it) } + } } internal class Notifier(private val vm: ParamsViewModel) { @@ -99,7 +110,7 @@ internal class Notifier(private val vm: ParamsViewModel) { when (event) { is ScanEvent.OnReadEvent -> { vm.ldCard.postValue(event.card) - vm.ldResponse.postValue(gson.toJson(event)) + vm.ldReadResponse.postValue(gson.toJson(event)) } is ScanEvent.OnVerifyEvent -> { vm.ldIsVerified.postValue(true) diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/PersonalizeConfigConverter.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/PersonalizeConfigConverter.kt index 2dd1a53b6a..e4bee5910d 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/PersonalizeConfigConverter.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/PersonalizeConfigConverter.kt @@ -175,7 +175,7 @@ class PersonalizeConfigConverter { } private fun addPayload(block: Block, from: PersonalizeConfig) { - block.payload[PayloadKey.IncominJson] = from + block.payload[PayloadKey.incomingJson] = from } private fun createItem(block: ListItemBlock, id: Id) { diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/PersonalizeFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/PersonalizeFragment.kt index 55ce28cc43..f7c8ed9ea9 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/PersonalizeFragment.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/PersonalizeFragment.kt @@ -72,7 +72,8 @@ class PersonalizeFragment : Fragment() { fab_action?.setOnClickListener { val cardConfig = personalizeVM.createCardConfig(personalizeVM.createConfig(blockList)) - paramsVM.invokeMainAction(mutableMapOf(PayloadKey.CardConfig to cardConfig)) + paramsVM.attachToPayload(mutableMapOf(PayloadKey.cardConfig to cardConfig)) + paramsVM.invokeMainAction() } } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/scan/ui/ScanActionFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/scan/ui/ScanActionFragment.kt index 532519981c..ef5e6d8f01 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/scan/ui/ScanActionFragment.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/scan/ui/ScanActionFragment.kt @@ -1,5 +1,7 @@ package com.tangem.tangemtest.ucase.variants.scan.ui +import android.os.Bundle +import android.view.View import android.widget.TextView import androidx.lifecycle.Observer import com.tangem.tangemtest.R @@ -17,10 +19,16 @@ class ScanActionFragment : BaseCardActionFragment() { override fun getAction(): ActionType = ActionType.Scan + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + showActionFab(true) + } + override fun listenResponse() { val tvStub = mainView.findViewById(R.id.tv_screen_stub) val tvResponse by lazy { mainView.findViewById(R.id.tv_action_response_json) } - viewModel.ldResponse.observe(viewLifecycleOwner, Observer { + paramsVM.ldReadResponse.observe(viewLifecycleOwner, Observer { Log.d(this, "action response: ${if (it.length > 50) it.substring(0..50) else it}") tvStub.show(false) tvResponse.text = it diff --git a/tangem-demo/src/main/res/values/strings.xml b/tangem-demo/src/main/res/values/strings.xml index ba36b65e09..ed410bbe60 100644 --- a/tangem-demo/src/main/res/values/strings.xml +++ b/tangem-demo/src/main/res/values/strings.xml @@ -7,4 +7,6 @@ unknown Docs + The card not personalized +