Updated on 2026-08-14

This commit is contained in:
Tangem 2020-04-10 15:16:11 +03:00
parent b4bcd8200c
commit 82c48330e2
11 changed files with 131 additions and 151 deletions

View file

@ -2,7 +2,7 @@ package com.tangem.tangemtest._main
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.tangem.tasks.TaskEvent
import com.tangem.commands.CommandResponse
import ru.dev.gbixahue.eu4d.lib.android.global.log.Log
/**
@ -11,16 +11,16 @@ import ru.dev.gbixahue.eu4d.lib.android.global.log.Log
class MainViewModel : ViewModel() {
val ldDescriptionSwitch = MutableLiveData<Boolean>(false)
var responseEvent: TaskEvent<*>? = null
var commandResponse: CommandResponse? = null
fun switchToggled(state: Boolean) {
ldDescriptionSwitch.postValue(state)
}
fun changeResponseEvent(event: TaskEvent<*>?) {
fun changeResponseEvent(commandResponse: CommandResponse?) {
Log.d(this, "changeResponseEvent")
val reqEvent = event ?: return
val response = commandResponse ?: return
responseEvent = reqEvent
this.commandResponse = response
}
}

View file

@ -2,7 +2,7 @@ package com.tangem.tangemtest.ucase.domain.paramsManager.managers
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.OnLifecycleEvent
import com.tangem.CardManager
import com.tangem.TangemSdk
import com.tangem.tangemtest.commons.Store
import com.tangem.tangemtest.ucase.domain.actions.PersonalizeAction
import com.tangem.tangemtest.ucase.domain.paramsManager.ActionCallback
@ -23,8 +23,8 @@ class PersonalizationItemsManager(
setItems(converter.convert(config))
}
override fun invokeMainAction(cardManager: CardManager, callback: ActionCallback) {
action.executeMainAction(this, getAttrsForAction(cardManager), callback)
override fun invokeMainAction(tangemSdk: TangemSdk, callback: ActionCallback) {
action.executeMainAction(this, getAttrsForAction(tangemSdk), callback)
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)

View file

@ -1,12 +1,8 @@
package com.tangem.tangemtest.ucase.domain.responses
import com.google.gson.*
import com.tangem.commands.ProductMask
import com.tangem.commands.Settings
import com.tangem.commands.SettingsMask
import com.tangem.commands.SigningMethod
import com.tangem.commands.*
import com.tangem.common.extensions.toHexString
import com.tangem.tasks.TaskEvent
import java.lang.reflect.Type
import java.text.DateFormat
import java.util.*
@ -29,12 +25,7 @@ class ResponseJsonConverter {
return builder.create()
}
fun convertTaskEvent(task: TaskEvent<*>?): String = gson.toJson(task)
fun convertEvent(task: TaskEvent<*>?): String {
val event = task as? TaskEvent.Event ?: ""
return gson.toJson(event)
}
fun convertResponse(response: CommandResponse?): String = gson.toJson(response)
}
class ByteTypeAdapter : JsonSerializer<ByteArray> {

View file

@ -14,13 +14,9 @@ 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._arch.structure.abstraction.iterate
import com.tangem.tangemtest.commons.performAction
import com.tangem.tangemtest.ucase.domain.paramsManager.ItemsManager
import com.tangem.tangemtest.ucase.domain.responses.ResponseJsonConverter
import com.tangem.tangemtest.ucase.tunnel.ViewScreen
import com.tangem.tasks.ScanEvent
import com.tangem.tasks.TaskError
import com.tangem.tasks.TaskEvent
import ru.dev.gbixahue.eu4d.lib.android.global.log.Log
/**
@ -32,9 +28,9 @@ class ActionViewModelFactory(private val manager: ItemsManager) : ViewModelProvi
class ActionViewModel(private val itemsManager: ItemsManager) : ViewModel(), LifecycleObserver {
val seResponseEvent = SingleLiveEvent<TaskEvent<*>>()
val seReadResponse = SingleLiveEvent<String>()
val seResponse = SingleLiveEvent<String>()
val seResponse = SingleLiveEvent<CommandResponse>()
val seResponseData = SingleLiveEvent<CommandResponse>()
val seResponseCardData = SingleLiveEvent<Card>()
val ldItemList = MutableLiveData(itemsManager.getItems())
val seError: MutableLiveData<String> = SingleLiveEvent()
@ -58,88 +54,87 @@ class ActionViewModel(private val itemsManager: ItemsManager) : ViewModel(), Lif
//invokes Scan, Sign etc...
fun invokeMainAction() {
performAction(itemsManager, tangemSdk) { paramsManager, cardManager ->
performAction(itemsManager, tangemSdk, { paramsManager, cardManager ->
paramsManager.invokeMainAction(tangemSdk) { response, listOfChangedParams ->
notifier.handleActionResult(response, listOfChangedParams)
}
})
if (!::tangemSdk.isInitialized) {
Log.e(this, "TangemSdk isn't initialized")
return
}
fun getItemAction(id: Id): (() -> Unit)? {
val itemFunction = itemsManager.getActionByTag(id, tangemSdk) ?: return null
return {
itemFunction { response, listOfChangedParams ->
notifier.handleActionResult(response, listOfChangedParams)
}
}
}
fun toggleDescriptionVisibility(state: Boolean) {
ldItemList.value?.iterate {
it.viewModel.viewState.descriptionVisibility = if (state) View.VISIBLE else View.GONE
}
}
fun attachToPayload(payload: Payload) {
itemsManager.attachPayload(payload)
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun viewOnDestroy() {
val keyList = mutableListOf<String>()
itemsManager.payload.filterValues { it is ViewScreen }.forEach { keyList.add(it.key) }
keyList.forEach { itemsManager.payload.remove(it) }
itemsManager.invokeMainAction(tangemSdk) { response, listOfChangedParams ->
notifier.handleActionResult(response, listOfChangedParams)
}
}
internal class Notifier(private val vm: ActionViewModel) {
fun getItemAction(id: Id): (() -> Unit)? {
val itemFunction = itemsManager.getActionByTag(id, tangemSdk) ?: return null
private var notShowedError: SessionError? = null
private val gson: Gson = ResponseJsonConverter().gson
fun handleActionResult(response: CompletionResult<*>, list: List<Item>) {
if (list.isNotEmpty()) notifyItemsChanged(list)
handleResponse(response)
}
@UiThread
fun notifyItemsChanged(list: List<Item>) {
vm.seChangedItems.postValue(list)
}
fun handleResponse(response: CompletionResult<*>) {
val taskEvent = response as? CompletionResult<CommandResponse> ?: return
when (commandResponse) {
is CompletionResult.Success -> handleDataEvent(commandResponse.data)
is CompletionResult.Failure -> handleError(commandResponse.error)
return {
itemFunction { response, listOfChangedParams ->
notifier.handleActionResult(response, listOfChangedParams)
}
}
}
private fun handleDataEvent(event: CommandResponse?) {
when (event) {
is ScanEvent.OnReadEvent -> vm.seReadResponse.postValue(gson.toJson(event))
is ScanEvent.OnVerifyEvent -> {
fun toggleDescriptionVisibility(state: Boolean) {
ldItemList.value?.iterate {
it.viewModel.viewState.descriptionVisibility = if (state) View.VISIBLE else View.GONE
}
}
fun attachToPayload(payload: Payload) {
itemsManager.attachPayload(payload)
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun viewOnDestroy() {
val keyList = mutableListOf<String>()
itemsManager.payload.filterValues { it is ViewScreen }.forEach { keyList.add(it.key) }
keyList.forEach { itemsManager.payload.remove(it) }
}
}
internal class Notifier(private val vm: ActionViewModel) {
private var notShowedError: SessionError? = null
private val gson: Gson = ResponseJsonConverter().gson
fun handleActionResult(result: CompletionResult<*>, list: List<Item>) {
if (list.isNotEmpty()) notifyItemsChanged(list)
handleCompletionResult(result)
}
@UiThread
fun notifyItemsChanged(list: List<Item>) {
vm.seChangedItems.postValue(list)
}
fun handleCompletionResult(result: CompletionResult<*>) {
val commandResponse = result as? CompletionResult<CommandResponse> ?: return
when (commandResponse) {
is CompletionResult.Success -> handleData(commandResponse.data)
is CompletionResult.Failure -> handleError(commandResponse.error)
}
}
private fun handleData(event: CommandResponse?) {
vm.seResponse.postValue(event)
when (event) {
is Card -> vm.seResponseCardData.postValue(event)
else -> vm.seResponseData.postValue(event)
}
}
private fun handleError(error: SessionError) {
Log.d(this, "error = $error")
when (error) {
is SessionError.UserCancelled -> {
if (notShowedError == null) {
vm.seError.postValue("User canceled the action")
} else {
vm.seError.postValue("${notShowedError!!::class.simpleName}")
notShowedError = null
}
else -> vm.seResponse.postValue(gson.toJson(event))
}
}
private fun handleCompletionEvent(error: SessionError) {
Log.d(this, "error = ${taskEvent.error}")
when (taskEvent.error) {
is TaskError.UserCancelled -> {
if (notShowedError == null) {
vm.seError.postValue("User canceled the action")
} else {
vm.seError.postValue("${notShowedError!!::class.simpleName}")
notShowedError = null
}
}
else -> notShowedError = taskEvent.error
}
else -> notShowedError = error
}
}
}

View file

@ -9,9 +9,8 @@ import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import com.tangem.TangemSdk
import com.tangem.commands.Card
import com.tangem.tangem_sdk_new.extensions.init
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.Id
@ -77,28 +76,37 @@ abstract class BaseCardActionFragment : BaseFragment(), ActionView {
protected open fun subscribeToViewModelChanges() {
Log.d(this, "subscribeToViewModelChanges")
listenEvent()
listenReadResponse()
listenResponse()
listenResponseData()
listenResponseCardData()
listenError()
listenChangedItems()
listenDescriptionSwitchChanges()
}
protected open fun listenEvent() {
actionVM.seResponseEvent.observe(viewLifecycleOwner, Observer {
private fun listenResponse() {
actionVM.seResponse.observe(viewLifecycleOwner, Observer {
Log.d(this, "listen response: $it")
mainActivityVM.changeResponseEvent(it)
})
}
protected open fun listenReadResponse() {}
protected open fun listenResponse() {
actionVM.seResponse.observe(viewLifecycleOwner, Observer {
protected open fun listenResponseData() {
actionVM.seResponseData.observe(viewLifecycleOwner, Observer {
Log.d(this, "listen responseData: $it")
navigateTo(R.id.action_nav_card_action_to_response_screen)
})
}
protected open fun listenResponseCardData() {
actionVM.seResponseCardData.observe(viewLifecycleOwner, Observer {
Log.d(this, "listen responseCardData: $it")
responseCardDataHandled(it)
})
}
protected open fun responseCardDataHandled(card: Card?) {}
protected open fun listenError() {
actionVM.seError.observe(viewLifecycleOwner, Observer { showSnackbar(it) })
}

View file

@ -3,6 +3,7 @@ package com.tangem.tangemtest.ucase.variants.personalize.ui
import android.os.Bundle
import android.view.View
import androidx.lifecycle.Observer
import com.tangem.commands.Card
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.Id
import com.tangem.tangemtest._arch.structure.abstraction.Item
@ -52,20 +53,6 @@ class PersonalizationFragment : BaseCardActionFragment() {
})
}
override fun subscribeToViewModelChanges() {
Log.d(this, "subscribeToViewModelChanges")
listenEvent()
listenError()
listenDescriptionSwitchChanges()
}
override fun listenEvent() {
actionVM.seResponseEvent.observe(viewLifecycleOwner, Observer {
mainActivityVM.changeResponseEvent(it)
navigateTo(R.id.action_nav_card_action_to_response_screen)
})
}
override fun showSnackbar(id: Id, additionalHandler: ((Id) -> Int)?) {
super.showSnackbar(id) {
when (id) {
@ -75,4 +62,9 @@ class PersonalizationFragment : BaseCardActionFragment() {
}
}
}
override fun responseCardDataHandled(card: Card?) {
super.responseCardDataHandled(card)
navigateTo(R.id.action_nav_card_action_to_response_screen)
}
}

View file

@ -3,6 +3,7 @@ package com.tangem.tangemtest.ucase.variants.responses
import android.view.View
import androidx.lifecycle.ViewModel
import com.tangem.commands.Card
import com.tangem.commands.CommandResponse
import com.tangem.commands.SignResponse
import com.tangem.commands.personalization.DepersonalizeResponse
import com.tangem.tangemtest.R
@ -10,8 +11,6 @@ import com.tangem.tangemtest._arch.structure.abstraction.Item
import com.tangem.tangemtest._arch.structure.abstraction.ModelToItems
import com.tangem.tangemtest._arch.structure.abstraction.iterate
import com.tangem.tangemtest.ucase.variants.responses.converter.ConvertersStore
import com.tangem.tasks.ScanEvent
import com.tangem.tasks.TaskEvent
import ru.dev.gbixahue.eu4d.lib.android.global.log.Log
/**
@ -22,13 +21,13 @@ class ResponseViewModel : ViewModel() {
private val convertersHolder = ConvertersStore()
private var itemList: List<Item>? = null
fun createItemList(taskEvent: TaskEvent<*>?): List<Item> {
fun createItemList(response: CommandResponse?): List<Item> {
Log.d(this, "createItemList: itemList size: ${itemList?.size ?: 0}")
val event = taskEvent as? TaskEvent.Event<Any> ?: return emptyList()
val type = event.data::class.java
val responseEvent = response ?: return emptyList()
val type = responseEvent::class.java
val converter = convertersHolder.get(type) as? ModelToItems<Any> ?: return emptyList()
itemList = converter.convert(event.data)
itemList = converter.convert(responseEvent)
return itemList!!
}
@ -38,13 +37,12 @@ class ResponseViewModel : ViewModel() {
}
}
fun determineTitleId(taskEvent: TaskEvent<*>?): Int {
val event = taskEvent as? TaskEvent.Event<Any> ?: return R.string.unknown
fun determineTitleId(response: CommandResponse?): Int {
val responseEvent = response ?: return R.string.unknown
return when (event.data) {
is ScanEvent.OnReadEvent -> R.string.fg_name_response_scan
is SignResponse -> R.string.fg_name_response_sign
return when (responseEvent) {
is Card -> R.string.fg_name_response_personalization
is SignResponse -> R.string.fg_name_response_sign
is DepersonalizeResponse -> R.string.fg_name_response_depersonalization
else -> R.string.unknown
}

View file

@ -3,13 +3,12 @@ package com.tangem.tangemtest.ucase.variants.responses.converter
import com.tangem.commands.Card
import com.tangem.commands.SignResponse
import com.tangem.commands.personalization.DepersonalizeResponse
import com.tangem.tasks.ScanEvent
import ru.dev.gbixahue.eu4d.lib.kotlin.common.BaseTypedHolder
import java.lang.reflect.Type
class ConvertersStore : BaseTypedHolder<Type, Any>() {
init {
register(ScanEvent.OnReadEvent::class.java, ReadEventConverter())
// register(CompletionResult.Success<Card>::class.java, ReadEventConverter())
register(SignResponse::class.java, SignResponseConverter())
register(Card::class.java, CardConverter())
register(DepersonalizeResponse::class.java, DepersonalizeResponseConverter())

View file

@ -1,19 +1,20 @@
package com.tangem.tangemtest.ucase.variants.responses.converter
import com.tangem.commands.Card
import com.tangem.commands.SignResponse
import com.tangem.commands.personalization.DepersonalizeResponse
import com.tangem.common.CompletionResult
import com.tangem.tangemtest._arch.structure.StringId
import com.tangem.tangemtest._arch.structure.abstraction.Item
import com.tangem.tangemtest._arch.structure.abstraction.ModelToItems
import com.tangem.tangemtest._arch.structure.impl.TextItem
import com.tangem.tasks.ScanEvent
import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf
/**
[REDACTED_AUTHOR]
*/
class ReadEventConverter : ModelToItems<ScanEvent.OnReadEvent> {
override fun convert(from: ScanEvent.OnReadEvent): List<Item> = CardConverter().convert(from.card)
class ReadEventConverter : ModelToItems<CompletionResult.Success<Card>> {
override fun convert(from: CompletionResult.Success<Card>): List<Item> = CardConverter().convert(from.data)
}
class SignResponseConverter : ModelToItems<SignResponse> {

View file

@ -33,7 +33,7 @@ open class ResponseFragment : BaseFragment() {
}
private fun setTittle() {
val titleId = selfVM.determineTitleId(mainActivityVM.responseEvent)
val titleId = selfVM.determineTitleId(mainActivityVM.commandResponse)
activity?.setTitle(titleId)
}
@ -47,7 +47,7 @@ open class ResponseFragment : BaseFragment() {
private fun buildWidgets() {
val builder = WidgetBuilder(ResponseItemBuilder())
val itemList = selfVM.createItemList(mainActivityVM.responseEvent)
val itemList = selfVM.createItemList(mainActivityVM.commandResponse)
itemList.forEach { builder.build(it, itemContainer) }
}
@ -67,7 +67,7 @@ open class ResponseFragment : BaseFragment() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_share -> {
shareText(ResponseJsonConverter().convertEvent(mainActivityVM.responseEvent))
shareText(ResponseJsonConverter().convertResponse(mainActivityVM.commandResponse))
}
}
return super.onOptionsItemSelected(item)

View file

@ -1,8 +1,6 @@
package com.tangem.tangemtest.ucase.variants.scan.ui
import android.os.Bundle
import android.view.View
import androidx.lifecycle.Observer
import com.tangem.commands.Card
import com.tangem.tangemtest.R
import com.tangem.tangemtest.ucase.domain.paramsManager.ItemsManager
import com.tangem.tangemtest.ucase.domain.paramsManager.managers.ScanItemsManager
@ -17,14 +15,12 @@ class ScanActionFragment : BaseCardActionFragment() {
override fun getLayoutId(): Int = R.layout.fg_action_card_scan
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
enableActionFab(true)
override fun initFab() {
actionFab.setOnClickListener { actionVM.invokeMainAction() }
}
override fun listenReadResponse() {
actionVM.seReadResponse.observe(viewLifecycleOwner, Observer {
navigateTo(R.id.action_nav_card_action_to_response_screen)
})
override fun responseCardDataHandled(card: Card?) {
super.responseCardDataHandled(card)
navigateTo(R.id.action_nav_card_action_to_response_screen)
}
}