Updated on 2026-08-14

This commit is contained in:
Tangem 2020-04-08 00:07:11 +03:00
parent e7d4125588
commit 6a69b80ae8
11 changed files with 68 additions and 184 deletions

View file

@ -4,12 +4,14 @@ import com.tangem.CardManager
import com.tangem.tangemtest._arch.structure.abstraction.Item
import com.tangem.tangemtest.ucase.domain.actions.PersonalizeAction
import com.tangem.tangemtest.ucase.domain.paramsManager.ActionCallback
import com.tangem.tangemtest.ucase.variants.personalize.converter.PersonalizeConfigConverter
import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizeConfig
/**
[REDACTED_AUTHOR]
*/
class PersonalizeItemsManager : BaseItemsManager(PersonalizeAction()) {
override fun createItemsList(): List<Item> = listOf()
override fun createItemsList(): List<Item> = PersonalizeConfigConverter().convert(PersonalizeConfig())
override fun invokeMainAction(cardManager: CardManager, callback: ActionCallback) {
action.executeMainAction(this, getAttrsForAction(cardManager), callback)

View file

@ -5,13 +5,13 @@ import com.tangem.tangemtest._arch.structure.Id
/**
[REDACTED_AUTHOR]
*/
interface Errors: Id
interface Errors : Id
enum class CardError : Errors {
NotPersonalized,
}
enum class ItemError: Errors {
enum class ItemError : Errors {
BadSeries,
BadCardNumber,
}

View file

@ -4,8 +4,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.core.os.bundleOf
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
@ -32,15 +30,18 @@ import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder
*/
abstract class BaseCardActionFragment : BaseFragment(), LayoutHolder, ActionView {
protected val incomingParamsContainer: ViewGroup by lazy {
mainView.findViewById<LinearLayout>(R.id.ll_incoming_params_container)
}
protected val actionFab: FloatingActionButton by lazy { mainView.findViewById<FloatingActionButton>(R.id.fab_action) }
protected val itemContainer: ViewGroup
get() = mainView.findViewById(R.id.ll_container)
protected val actionFab: FloatingActionButton
get() = mainView.findViewById(R.id.fab_action)
protected val mainActivityVM by activityViewModels<MainViewModel>()
protected val paramsVM: ParamsViewModel by viewModels { ActionViewModelFactory(itemsManager) }
protected val widgetList = mutableListOf<ParameterWidget>()
private val itemsManager: ItemsManager by lazy { ParamsManagerFactory.createFactory().get(getAction())!! }
protected val itemsManager: ItemsManager by lazy { ParamsManagerFactory.createFactory().get(getAction())!! }
private val paramsWidgetList = mutableListOf<ParameterWidget>()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -49,30 +50,32 @@ abstract class BaseCardActionFragment : BaseFragment(), LayoutHolder, ActionView
viewLifecycleOwner.lifecycle.addObserver(paramsVM)
paramsVM.setCardManager(CardManager.init(requireActivity()))
paramsVM.attachToPayload(mutableMapOf(PayloadKey.actionView to this as ActionView))
initFab()
createWidgets { subscribeToViewModelChanges() }
}
private fun initFab() {
protected open fun initFab() {
enableActionFab(false)
actionFab.setOnClickListener { paramsVM.invokeMainAction() }
}
private fun createWidgets(widgetCreatedCallback: () -> Unit) {
protected open fun createWidgets(widgetCreatedCallback: () -> Unit) {
Log.d(this, "createWidgets")
paramsVM.ldItemList.observe(viewLifecycleOwner, Observer { itemList ->
itemList.forEach { param ->
val widget = ParameterWidget(inflateParamView(incomingParamsContainer), param)
val widget = ParameterWidget(inflateParamView(itemContainer), param)
widget.onValueChanged = { id, value -> paramsVM.userChangedItem(id, value) }
widget.onActionBtnClickListener = paramsVM.getItemAction(param.id)
widgetList.add(widget)
paramsWidgetList.add(widget)
}
widgetCreatedCallback()
})
}
private fun subscribeToViewModelChanges() {
protected open fun subscribeToViewModelChanges() {
Log.d(this, "subscribeToViewModelChanges")
listenEvent()
listenReadResponse()
listenResponse()
listenError()
@ -80,12 +83,17 @@ abstract class BaseCardActionFragment : BaseFragment(), LayoutHolder, ActionView
listenDescriptionSwitchChanges()
}
protected open fun listenEvent() {
paramsVM.seResponseEvent.observe(viewLifecycleOwner, Observer {
mainActivityVM.changeResponseEvent(it)
})
}
protected open fun listenReadResponse() {}
protected open fun listenResponse() {
paramsVM.seResponse.observe(viewLifecycleOwner, Observer {
navigateTo(R.id.action_nav_card_action_to_response_screen,
bundleOf(Pair(BaseCardResponseFragment.response, it)))
navigateTo(R.id.action_nav_card_action_to_response_screen)
})
}
@ -93,21 +101,21 @@ abstract class BaseCardActionFragment : BaseFragment(), LayoutHolder, ActionView
paramsVM.seError.observe(viewLifecycleOwner, Observer { showSnackbar(it) })
}
@Deprecated("Start to use itemViewModel")
protected open fun listenChangedItems() {
paramsVM.seChangedItems.observe(viewLifecycleOwner, Observer { itemList ->
itemList.forEach { item ->
Log.d(this, "item changed from VM - name: ${item.id}")
val dataItem = item as? BaseItem<Any?> ?: return@Observer
Log.d(this, "item changed from VM - name: ${dataItem.id}, value:${dataItem.viewModel.data}")
widgetList.firstOrNull { it.id == item.id }?.changeParamValue(item.viewModel.data)
paramsWidgetList.firstOrNull { it.id == item.id }?.changeParamValue(item.viewModel.data)
}
})
}
protected open fun listenDescriptionSwitchChanges() {
val mainActViewModel by activityViewModels<MainViewModel>()
mainActViewModel.ldDescriptionSwitch.observe(viewLifecycleOwner, Observer { isEnabled ->
widgetList.forEach { it.toggleDescriptionVisibility(isEnabled) }
mainActivityVM.ldDescriptionSwitch.observe(viewLifecycleOwner, Observer {
paramsVM.toggleDescriptionVisibility(it)
})
}

View file

@ -1,58 +0,0 @@
package com.tangem.tangemtest.ucase.ui
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.abstraction.BaseItem
import com.tangem.tangemtest._arch.structure.abstraction.Item
import com.tangem.tangemtest._arch.structure.abstraction.ListItemBlock
import com.tangem.tangemtest._arch.structure.abstraction.iterate
import com.tangem.tangemtest._arch.structure.impl.TextItem
import com.tangem.tangemtest._arch.widget.WidgetBuilder
import com.tangem.tangemtest._main.MainViewModel
import com.tangem.tangemtest.ucase.resources.StringId
/**
[REDACTED_AUTHOR]
*/
class BaseCardResponseFragment : BaseFragment() {
companion object Arg {
val response = "response"
}
private val mainActivityVM: MainViewModel by activityViewModels()
private val blockContainer: ViewGroup by lazy { mainView.findViewById<LinearLayout>(R.id.ll_container) }
override fun getLayoutId(): Int = R.layout.fg_card_response
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val response = requireArguments().getString(Arg.response) ?: return
if (response.isEmpty()) return
val itemList = createItemList(response)
itemList.forEach { WidgetBuilder(ResponseItemBuilder()).build(it, blockContainer) }
mainActivityVM.ldDescriptionSwitch.observe(viewLifecycleOwner, Observer {
itemList.iterate { item ->
val baseItem = item as? BaseItem<*> ?: return@iterate
baseItem.viewModel.viewState.descriptionVisibility = if (it) View.VISIBLE else View.GONE
}
})
}
protected open fun createItemList(response: String): List<Item> {
return listOf(
ListItemBlock(StringId("")).apply {
addItem(TextItem(StringId("resp.fieldName"), response))
}
)
}
}

View file

@ -10,6 +10,7 @@ import androidx.navigation.fragment.NavHostFragment.findNavController
import com.google.android.material.snackbar.Snackbar
import com.tangem.tangemtest.ucase.getDefaultNavigationOptions
import com.tangem.tangemtest.ucase.tunnel.SnackbarHolder
import ru.dev.gbixahue.eu4d.lib.android.global.log.Log
import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder
/**
@ -25,6 +26,7 @@ abstract class BaseFragment : Fragment(), LayoutHolder, SnackbarHolder {
}
protected fun navigateTo(navigationId: Int, bundle: Bundle? = null, options: NavOptions? = getDefaultNavigationOptions()) {
Log.d(this, "navigateTo id: $navigationId")
findNavController(this).navigate(navigationId, bundle, options)
}

View file

@ -1,5 +1,6 @@
package com.tangem.tangemtest.ucase.ui
import android.view.View
import androidx.annotation.UiThread
import androidx.lifecycle.*
import com.google.gson.Gson
@ -7,7 +8,9 @@ import com.tangem.CardManager
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.BaseItem
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.GsonInitializer
@ -26,6 +29,7 @@ class ActionViewModelFactory(private val manager: ItemsManager) : ViewModelProvi
class ParamsViewModel(private val itemsManager: ItemsManager) : ViewModel(), LifecycleObserver {
val seResponseEvent = SingleLiveEvent<TaskEvent<*>>()
val seReadResponse = SingleLiveEvent<String>()
val seResponse = SingleLiveEvent<String>()
@ -67,6 +71,13 @@ class ParamsViewModel(private val itemsManager: ItemsManager) : ViewModel(), Lif
}
}
fun toggleDescriptionVisibility(state: Boolean) {
ldItemList.value?.iterate {
val baseItem = it as? BaseItem<*> ?: return@iterate
baseItem.viewModel.viewState.descriptionVisibility = if (state) View.VISIBLE else View.GONE
}
}
fun attachToPayload(payload: Payload) {
itemsManager.attachPayload(payload)
}
@ -99,18 +110,17 @@ internal class Notifier(private val vm: ParamsViewModel) {
when (taskEvent) {
is TaskEvent.Completion -> handleCompletionEvent(taskEvent)
is TaskEvent.Event -> handleDataEvent(taskEvent.data)
is TaskEvent.Event -> {
handleDataEvent(taskEvent.data)
vm.seResponseEvent.postValue(taskEvent)
}
}
}
private fun handleDataEvent(event: Any?) {
when (event) {
is ScanEvent.OnReadEvent -> {
// vm.ldCard.postValue(event.card)
vm.seReadResponse.postValue(gson.toJson(event))
}
is ScanEvent.OnReadEvent -> vm.seReadResponse.postValue(gson.toJson(event))
is ScanEvent.OnVerifyEvent -> {
// vm.ldIsVerified.postValue(true)
}
else -> vm.seResponse.postValue(gson.toJson(event))
}

View file

@ -1,112 +1,62 @@
package com.tangem.tangemtest.ucase.variants.personalize.ui
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import com.google.android.material.floatingactionbutton.FloatingActionButton
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.Item
import com.tangem.tangemtest._arch.widget.WidgetBuilder
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.tunnel.ItemError
import com.tangem.tangemtest.ucase.ui.ActionViewModelFactory
import com.tangem.tangemtest.ucase.ui.BaseFragment
import com.tangem.tangemtest.ucase.ui.ParamsViewModel
import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizeConfig
import com.tangem.tangemtest.ucase.ui.BaseCardActionFragment
import com.tangem.tangemtest.ucase.variants.personalize.ui.widgets.PersonalizeItemBuilder
import ru.dev.gbixahue.eu4d.lib.android.global.log.Log
/**
[REDACTED_AUTHOR]
*/
class PersonalizeFragment : BaseFragment(), ActionView {
private lateinit var itemContainer: ViewGroup
private lateinit var actionFab: FloatingActionButton
private val mainActivityVM: MainViewModel by activityViewModels()
private val personalizeVM: PersonalizeViewModel by viewModels { PersonalizeViewModelFactory(PersonalizeConfig()) }
private val paramsVM: ParamsViewModel by viewModels() { ActionViewModelFactory(itemsManager) }
private val itemsManager: ItemsManager by lazy { ParamsManagerFactory.createFactory().get(ActionType.Personalize)!! }
class PersonalizeFragment : BaseCardActionFragment(), ActionView {
override fun getLayoutId(): Int = R.layout.fg_personalize
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
itemContainer = mainView.findViewById(R.id.ll_container)
actionFab = mainView.findViewById(R.id.fab_action)
paramsVM.setCardManager(CardManager.init(requireActivity()))
paramsVM.attachToPayload(mutableMapOf(PayloadKey.actionView to this as ActionView))
initFab()
createWidgets { subscribeToViewModelChanges() }
}
private fun initFab() {
override fun initFab() {
actionFab.setOnClickListener { paramsVM.invokeMainAction() }
}
private fun createWidgets(widgetCreatedCallback: () -> Unit) {
override fun createWidgets(widgetCreatedCallback: () -> Unit) {
Log.d(this, "createWidgets")
val blockList = mutableListOf<Item>()
personalizeVM.ldBlockList.observe(viewLifecycleOwner, Observer { list ->
val itemList = mutableListOf<Item>()
paramsVM.ldItemList.observe(viewLifecycleOwner, Observer { list ->
Log.d(this, "ldBlockList size: ${list.size}")
blockList.clear()
blockList.addAll(list)
blockList.forEach { WidgetBuilder(PersonalizeItemBuilder()).build(it, itemContainer) }
itemList.clear()
itemList.addAll(list)
itemList.forEach { WidgetBuilder(PersonalizeItemBuilder()).build(it, itemContainer) }
paramsVM.attachToPayload(mutableMapOf(
PayloadKey.actionView to this as ActionView,
PayloadKey.itemList to blockList
PayloadKey.itemList to itemList
))
widgetCreatedCallback()
})
}
private fun subscribeToViewModelChanges() {
override fun subscribeToViewModelChanges() {
Log.d(this, "subscribeToViewModelChanges")
listenEvent()
listenError()
listenDescriptionSwitchChanges()
}
private fun listenEvent() {
override fun listenEvent() {
paramsVM.seResponseEvent.observe(viewLifecycleOwner, Observer {
mainActivityVM.changeResponseEvent(it)
navigateTo(R.id.action_nav_card_action_to_response_screen)
})
}
private fun listenError() {
paramsVM.seError.observe(viewLifecycleOwner, Observer { showSnackbar(it) })
}
private fun listenDescriptionSwitchChanges() {
mainActivityVM.ldDescriptionSwitch.observe(viewLifecycleOwner, Observer {
personalizeVM.toggleDescriptionVisibility(it)
})
}
override fun enableActionFab(enable: Boolean) {
if (enable) actionFab.show() else actionFab.hide()
}
override fun showSnackbar(id: Id) {
// MainResourceHolder.safeGet<>()
when (id) {
CardError.NotPersonalized -> showSnackbar(R.string.card_error_not_personalized)
ItemError.BadSeries -> showSnackbar(R.string.card_error_bad_series)
@ -114,6 +64,8 @@ class PersonalizeFragment : BaseFragment(), ActionView {
else -> showSnackbar(requireContext().getString(R.string.unknown))
}
}
override fun getAction(): ActionType = ActionType.Personalize
}

View file

@ -1,32 +0,0 @@
package com.tangem.tangemtest.ucase.variants.personalize.ui
import android.view.View
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.tangem.tangemtest._arch.structure.abstraction.BaseItem
import com.tangem.tangemtest._arch.structure.abstraction.Item
import com.tangem.tangemtest._arch.structure.abstraction.iterate
import com.tangem.tangemtest.ucase.variants.personalize.converter.PersonalizeConfigConverter
import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizeConfig
/**
[REDACTED_AUTHOR]
*/
class PersonalizeViewModelFactory(private val config: PersonalizeConfig) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel?> create(modelClass: Class<T>): T = PersonalizeViewModel(config) as T
}
class PersonalizeViewModel(private val config: PersonalizeConfig) : ViewModel() {
val ldBlockList: MutableLiveData<List<Item>> by lazy { MutableLiveData(initBlockList()) }
private fun initBlockList(): List<Item> = PersonalizeConfigConverter().convert(config)
fun toggleDescriptionVisibility(state: Boolean) {
ldBlockList.value?.iterate {
val baseItem = it as? BaseItem<*> ?: return@iterate
baseItem.viewModel.viewState.descriptionVisibility = if (state) View.VISIBLE else View.GONE
}
}
}

View file

@ -15,7 +15,7 @@
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_incoming_params_container"
android:id="@+id/ll_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

View file

@ -15,7 +15,7 @@
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_incoming_params_container"
android:id="@+id/ll_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

View file

@ -15,7 +15,7 @@
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_incoming_params_container"
android:id="@+id/ll_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">