From 9056c31bb6ae30622c2d67d9b38a247cd4d66b6b Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 9 Apr 2020 18:03:08 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../_arch/structure/HelpAbstracts.kt | 12 - .../tangem/tangemtest/_arch/structure/Ids.kt | 4 +- .../_arch/structure/abstraction/Extension.kt | 10 +- .../_arch/structure/abstraction/Item.kt | 32 +- .../abstraction/{Block.kt => ItemGroup.kt} | 32 +- .../{ViewModel.kt => ItemViewModel.kt} | 105 +++--- .../tangemtest/_arch/structure/impl/Items.kt | 24 +- .../_arch/structure/impl/ViewModels.kt | 29 -- .../_arch/widget/ItemWidgetBuilder.kt | 2 +- .../tangemtest/_arch/widget/WidgetBuilder.kt | 23 +- .../_arch/widget/abstraction/ViewWidget.kt | 44 +-- .../_arch/widget/impl/LinearBlockWidget.kt | 27 -- .../_arch/widget/impl/LinearGroupWidget.kt | 18 ++ .../_arch/widget/impl/StubWidget.kt | 9 +- .../tangemtest/commons/GlobalFunctions.kt | 3 +- .../domain/actions/DepersonalizeAction.kt | 4 +- .../ucase/domain/actions/PersonalizeAction.kt | 18 +- .../ucase/domain/actions/SignAction.kt | 6 +- .../managers/BaseItemsManager.kt | 4 +- .../triggers/afterAction/AfterScanModifier.kt | 4 +- .../ParamChangeConsequence.kt | 4 +- .../tangemtest/ucase/ui/ActionViewModel.kt | 8 +- .../ucase/ui/BaseCardActionFragment.kt | 5 +- .../ucase/ui/widgets/ParameterWidget.kt | 8 +- .../personalize/converter/DefaultValues.kt | 2 +- .../converter/{fromTo => }/ItemTypes.kt | 2 +- .../PersonalizationConfigConverter.kt | 289 ++++++++++++++++- .../PersonalizationConfigToCardConfig.kt | 113 +++++++ .../fromTo/ItemsToPersonalizationConfig.kt | 114 ------- .../converter/fromTo/PersonalizeConfigTo.kt | 305 ------------------ .../personalize/ui/widgets/BaseAppWidget.kt | 28 ++ .../ui/widgets/DescriptionWidget.kt | 14 +- .../personalize/ui/widgets/EditTextWidget.kt | 13 +- ...BlockHeadWidget.kt => GroupTitleWidget.kt} | 3 +- .../personalize/ui/widgets/NumberWidget.kt | 16 +- .../ui/widgets/PersonalizationItemBuilder.kt | 6 +- .../personalize/ui/widgets/SpinnerWidget.kt | 32 +- .../personalize/ui/widgets/SwitchWidget.kt | 15 +- .../variants/responses/ResponseViewModel.kt | 4 +- .../responses/converter/CardConverter.kt | 79 +++-- .../responses/ui/widget/CheckBoxWidget.kt | 9 +- .../ui/widget/ResponseItemBuilder.kt | 2 +- .../responses/ui/widget/ResponseTextWidget.kt | 11 +- 43 files changed, 730 insertions(+), 762 deletions(-) rename tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/{Block.kt => ItemGroup.kt} (61%) rename tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/{ViewModel.kt => ItemViewModel.kt} (70%) delete mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/impl/ViewModels.kt delete mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/impl/LinearBlockWidget.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/impl/LinearGroupWidget.kt rename tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/{fromTo => }/ItemTypes.kt (99%) create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/PersonalizationConfigToCardConfig.kt delete mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/fromTo/ItemsToPersonalizationConfig.kt delete mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/fromTo/PersonalizeConfigTo.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/BaseAppWidget.kt rename tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/{BlockHeadWidget.kt => GroupTitleWidget.kt} (72%) diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/HelpAbstracts.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/HelpAbstracts.kt index 98704005f5..309309c947 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/HelpAbstracts.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/HelpAbstracts.kt @@ -3,10 +3,6 @@ package com.tangem.tangemtest._arch.structure /** [REDACTED_AUTHOR] */ -interface DataHolder { - var viewModel: D -} - typealias Payload = MutableMap interface PayloadHolder { @@ -17,12 +13,4 @@ interface PayloadHolder { fun set(key: String, value: Any?) { payload[key] = value } -} - -interface ItemListHolder { - fun setItems(list: MutableList) - fun getItems(): MutableList - fun addItem(item: I) - fun removeItem(item: I) - fun clear() } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/Ids.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/Ids.kt index ce27853356..5e517808f2 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/Ids.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/Ids.kt @@ -5,7 +5,9 @@ package com.tangem.tangemtest._arch.structure */ interface Id -class StringId(val name: String) : Id +class StringId(val value: String) : Id + +class StringResId(val value: Int) : Id enum class Additional : Id { UNDEFINED, diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/Extension.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/Extension.kt index 71924302a3..76b43ce50a 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/Extension.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/Extension.kt @@ -5,11 +5,11 @@ import com.tangem.tangemtest._arch.structure.Id /** [REDACTED_AUTHOR] */ -fun List.findDataItem(id: Id): BaseItem? { - var foundItem: BaseItem? = null +fun List.findItem(id: Id): Item? { + var foundItem: Item? = null iterate { if (it.id == id) { - foundItem = it as? BaseItem + foundItem = it return@iterate } } @@ -19,8 +19,8 @@ fun List.findDataItem(id: Id): BaseItem? { fun List.iterate(func: (Item) -> Unit) { forEach { when (it) { - is BaseItem<*> -> func(it) - is Block -> it.itemList.iterate(func) + is BaseItem -> func(it) + is ItemGroup -> it.itemList.iterate(func) } } } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/Item.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/Item.kt index 40a546b78b..eaf3d7afa4 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/Item.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/Item.kt @@ -1,31 +1,39 @@ package com.tangem.tangemtest._arch.structure.abstraction -import com.tangem.tangemtest._arch.structure.DataHolder import com.tangem.tangemtest._arch.structure.Id -import com.tangem.tangemtest._arch.structure.Payload -import com.tangem.tangemtest._arch.structure.PayloadHolder /** [REDACTED_AUTHOR] */ -interface Item : PayloadHolder { +interface Item { val id: Id var parent: Item? -} + var viewModel: ItemViewModel -abstract class BaseItem( - override var viewModel: ItemViewModel -) : Item, DataHolder> { - override var parent: Item? = null - override val payload: Payload = mutableMapOf() + fun added(parent: Item) { + this.parent = parent + } - fun getData(): D? = viewModel.data + fun removed(parent: Item) { + this.parent = null + } - fun setData(value: D?) { + fun getData(): D? = viewModel.data as? D + + fun setData(value: Any?) { viewModel.data = value } fun restoreDefaultData() { setData(viewModel.defaultData) } +} + +open class BaseItem( + override val id: Id, + override var viewModel: ItemViewModel +) : Item { + + override var parent: Item? = null + } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/Block.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/ItemGroup.kt similarity index 61% rename from tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/Block.kt rename to tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/ItemGroup.kt index 11086e6f93..61a43a0d1c 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/Block.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/ItemGroup.kt @@ -2,45 +2,47 @@ package com.tangem.tangemtest._arch.structure.abstraction import com.tangem.tangemtest._arch.structure.ILog import com.tangem.tangemtest._arch.structure.Id -import com.tangem.tangemtest._arch.structure.ItemListHolder /** [REDACTED_AUTHOR] */ -interface Block : Item { +interface ItemGroup : Item { val itemList: MutableList + + fun setItems(list: MutableList) + fun getItems(): MutableList + fun addItem(item: Item) + fun removeItem(item: Item) + fun clear() } -abstract class BaseBlock : Block { +open class SimpleItemGroup( + override val id: Id, + override var viewModel: ItemViewModel = BaseItemViewModel() +) : ItemGroup { + override var parent: Item? = null override val itemList: MutableList = mutableListOf() - override val payload: MutableMap = mutableMapOf() -} - -open class ListItemBlock( - override val id: Id -) : BaseBlock(), ItemListHolder { override fun setItems(list: MutableList) { ILog.d(this, "setItems into: $id, count: ${list.size}") + itemList.forEach { it.removed(this) } itemList.clear() - itemList.addAll(list) - itemList.forEach { it.parent = this } + list.forEach { addItem(it) } } - override fun getItems(): MutableList { - return itemList - } + override fun getItems(): MutableList = itemList override fun addItem(item: Item) { ILog.d(this, "addItem into: $id, who: ${item.id}") - item.parent = this itemList.add(item) + item.added(this) } override fun removeItem(item: Item) { ILog.d(this, "removeItem from: $id, which: ${item.id}") itemList.remove(item) + item.removed(this) } override fun clear() { diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/ViewModel.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/ItemViewModel.kt similarity index 70% rename from tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/ViewModel.kt rename to tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/ItemViewModel.kt index 86d1d1b345..d298f84f93 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/ViewModel.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/abstraction/ItemViewModel.kt @@ -11,54 +11,7 @@ import com.tangem.tangemtest._arch.structure.PayloadHolder typealias ValueChange = (V?) -> Unit typealias SafeValueChange = (V) -> Unit -interface ItemViewModel : PayloadHolder { - val viewState: ViewState - var data: D? - var defaultData: D? - var onDataUpdated: ValueChange? - - fun updateDataByView(data: D?) -} - -open class BaseItemViewModel : ItemViewModel { - - override val viewState: ViewState = ViewState() - override val payload: Payload = mutableMapOf() - - // Don't update it directly from a View. Use for it updateDataByView() - override var data: D? = null - set(value) { - if (handleDataUpdates(value)) field = value - } - - // Data for restoring initial value - override var defaultData: D? = null - set(value) { - field = value - data = value - } - - // Use it for handling data updates in View - override var onDataUpdated: ValueChange? = null - - // When data updates directly it invokes onDataUpdated - // return true = data will update - // return false = data won't update - protected open fun handleDataUpdates(value: D?): Boolean { - ILog.d(this, "handleDateUpdates: $value") - onDataUpdated?.invoke(value) - return true - } - - // Use it to update the data from a View. It disables onDataUpdated to prevent a callback loop - override fun updateDataByView(data: D?) { - ILog.d(this, "data changed: $data") - val callback = onDataUpdated - onDataUpdated = null - this.data = data - onDataUpdated = callback - } -} +class KeyValue(val key: String, val value: Any) class ViewState { var isHiddenField = false @@ -70,4 +23,58 @@ class ViewState { } var onDescriptionVisibilityChanged: SafeValueChange? = null -} \ No newline at end of file +} + +interface ItemViewModel : PayloadHolder { + val viewState: ViewState + var data: Any? + var defaultData: Any? + var onDataUpdated: ValueChange? + + fun updateDataByView(data: Any?) +} + +open class BaseItemViewModel(value: Any? = null) : ItemViewModel { + + override val viewState: ViewState = ViewState() + override val payload: Payload = mutableMapOf() + + // Don't update it directly from a View. Use for it updateDataByView() + override var data: Any? = value + set(value) { + if (handleDataUpdates(value)) field = value + } + + // Data for restoring initial value + override var defaultData: Any? = value + set(value) { + field = value + data = value + } + + // Use it for handling data updates in View + override var onDataUpdated: ValueChange? = null + + // When data updates directly it invokes onDataUpdated + // return true = data will update + // return false = data won't update + protected open fun handleDataUpdates(value: Any?): Boolean { + ILog.d(this, "handleDateUpdates: $value") + onDataUpdated?.invoke(value) + return true + } + + // Use it to update the data from a View. It disables onDataUpdated to prevent a callback loop + override fun updateDataByView(data: Any?) { + ILog.d(this, "data changed: $data") + val callback = onDataUpdated + onDataUpdated = null + this.data = data + onDataUpdated = callback + } +} + +class ListViewModel( + var selectedItem: Any?, + val itemList: List +) : BaseItemViewModel(selectedItem) \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/impl/Items.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/impl/Items.kt index 5e6d10bd37..923f58f94a 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/impl/Items.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/impl/Items.kt @@ -2,18 +2,24 @@ package com.tangem.tangemtest._arch.structure.impl import com.tangem.tangemtest._arch.structure.Id import com.tangem.tangemtest._arch.structure.abstraction.BaseItem +import com.tangem.tangemtest._arch.structure.abstraction.BaseItemViewModel +import com.tangem.tangemtest._arch.structure.abstraction.KeyValue +import com.tangem.tangemtest._arch.structure.abstraction.ListViewModel /** [REDACTED_AUTHOR] */ -class AnyItem(override val id: Id, value: Any? = null) : BaseItem(AnyViewModel(value)) -class TextItem(override val id: Id, value: String? = null) : BaseItem(StringViewModel(value)) -class EditTextItem(override val id: Id, value: String? = null) : BaseItem(StringViewModel(value)) -class NumberItem(override val id: Id, value: Number? = null) : BaseItem(NumberViewModel(value)) -class BoolItem(override val id: Id, value: Boolean? = null) : BaseItem(BoolViewModel(value)) -class ListItem(override val id: Id, value: List, selectedValue: Any?) - : BaseItem(ListViewModel(ListValueWrapper(selectedValue, value)) -) +open class TypedItem(id: Id, value: D? = null) : BaseItem(id, BaseItemViewModel(value)) { + open fun getTypedData(): D? = viewModel.data as? D +} -inline fun BaseItem.getData(): T? = viewModel.data \ No newline at end of file +class TextItem(id: Id, value: String? = null) : TypedItem(id, value) +class NumberItem(id: Id, value: Number? = null) : TypedItem(id, value) +class BoolItem(id: Id, value: Boolean? = null) : TypedItem(id, value) + +class EditTextItem(id: Id, value: String? = null) : TypedItem(id, value) + +class SpinnerItem(id: Id, value: List, selectedValue: Any?) + : TypedItem(id, ListViewModel(selectedValue, value) +) \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/impl/ViewModels.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/impl/ViewModels.kt deleted file mode 100644 index f082577e70..0000000000 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/structure/impl/ViewModels.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.tangem.tangemtest._arch.structure.impl - -import com.tangem.tangemtest._arch.structure.abstraction.BaseItemViewModel - -/** -[REDACTED_AUTHOR] - */ -open class TransitiveViewModel(value: D?) : BaseItemViewModel() { - init { - defaultData = value - } -} - -class AnyViewModel(value: Any? = null) : TransitiveViewModel(value) -class StringViewModel(value: String? = null) : TransitiveViewModel(value) -class NumberViewModel(value: Number? = null) : TransitiveViewModel(value) -class BoolViewModel(value: Boolean? = null) : TransitiveViewModel(value) -class ListViewModel(value: ListValueWrapper? = null) : TransitiveViewModel(value) { - - override fun handleDataUpdates(value: ListValueWrapper?): Boolean { - val newValue = value ?: return false - if (newValue.selectedItem == data?.selectedItem) return false - - return super.handleDataUpdates(value) - } -} - -class KeyValue(val key: String, val value: Any) -class ListValueWrapper(var selectedItem: Any?, val itemList: List) \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/ItemWidgetBuilder.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/ItemWidgetBuilder.kt index b507573e99..2ed1e1ab8f 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/ItemWidgetBuilder.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/ItemWidgetBuilder.kt @@ -8,5 +8,5 @@ import com.tangem.tangemtest._arch.widget.abstraction.ViewWidget [REDACTED_AUTHOR] */ interface ItemWidgetBuilder { - fun build(item: BaseItem<*>, parent: ViewGroup): ViewWidget? + fun build(item: BaseItem, parent: ViewGroup): ViewWidget? } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/WidgetBuilder.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/WidgetBuilder.kt index a524006f74..3d9a3493a5 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/WidgetBuilder.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/WidgetBuilder.kt @@ -2,11 +2,10 @@ package com.tangem.tangemtest._arch.widget import android.view.ViewGroup import com.tangem.tangemtest._arch.structure.abstraction.BaseItem -import com.tangem.tangemtest._arch.structure.abstraction.Block import com.tangem.tangemtest._arch.structure.abstraction.Item -import com.tangem.tangemtest._arch.structure.abstraction.ListItemBlock +import com.tangem.tangemtest._arch.structure.abstraction.ItemGroup import com.tangem.tangemtest._arch.widget.abstraction.ViewWidget -import com.tangem.tangemtest._arch.widget.impl.LinearBlockWidget +import com.tangem.tangemtest._arch.widget.impl.LinearGroupWidget import com.tangem.tangemtest._arch.widget.impl.StubWidget /** @@ -18,20 +17,20 @@ class WidgetBuilder( fun build(item: Item, parent: ViewGroup): ViewWidget? { return when (item) { - is Block -> buildBlock(item, parent) - is BaseItem<*> -> itemBuilder.build(item, parent) - else -> StubWidget(parent) + is ItemGroup -> buildBlock(item, parent) + is BaseItem -> itemBuilder.build(item, parent) + else -> StubWidget(item.id, parent) } } - private fun buildBlock(block: Block, parent: ViewGroup): ViewWidget { - return when (block) { - is ListItemBlock -> { - val linearBlock = LinearBlockWidget(parent, block) - block.getItems().forEach { build(it, linearBlock.view as ViewGroup) } + private fun buildBlock(itemGroup: ItemGroup, parent: ViewGroup): ViewWidget { + return when (itemGroup) { + is ItemGroup -> { + val linearBlock = LinearGroupWidget(parent, itemGroup) + itemGroup.getItems().forEach { build(it, linearBlock.view as ViewGroup) } linearBlock } - else -> StubWidget(parent) + else -> StubWidget(itemGroup.id, parent) } } } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/abstraction/ViewWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/abstraction/ViewWidget.kt index 7fa8fd5bbb..8a220c0f1a 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/abstraction/ViewWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/abstraction/ViewWidget.kt @@ -4,13 +4,9 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.tangem.tangemtest.R -import com.tangem.tangemtest._arch.structure.DataHolder import com.tangem.tangemtest._arch.structure.StringId -import com.tangem.tangemtest._arch.structure.abstraction.BaseItem -import com.tangem.tangemtest._arch.structure.abstraction.ItemViewModel -import com.tangem.tangemtest.ucase.resources.MainResourceHolder -import com.tangem.tangemtest.ucase.resources.Resources -import ru.dev.gbixahue.eu4d.lib.android._android.views.stringFrom +import com.tangem.tangemtest._arch.structure.StringResId +import com.tangem.tangemtest._arch.structure.abstraction.Item import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder /** @@ -18,39 +14,31 @@ import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder */ interface ViewWidget : LayoutHolder { val view: View + var item: Item + + fun getName(): String } -interface DataWidget : ViewWidget { - var dataItem: BaseItem -} - -interface BlockViewWidget : ViewWidget, DataHolder>> - -abstract class BaseWidget( +abstract class BaseViewWidget( parent: ViewGroup, - override var dataItem: BaseItem -) : ViewWidget, DataWidget { + override var item: Item +) : ViewWidget { override val view: View = inflate(getLayoutId(), parent) init { - if (dataItem.viewModel.viewState.isHiddenField) { + if (item.viewModel.viewState.isHiddenField) { view.visibility = View.GONE } } -} -abstract class BaseBlockWidget(parent: ViewGroup) : BlockViewWidget { - override val view: View = inflate(getLayoutId(), parent) -} - -fun DataWidget<*>.getResNameId(): Int = MainResourceHolder.safeGet(dataItem.id).resName - -fun DataWidget<*>.getResDescription(): Int? = MainResourceHolder.safeGet(dataItem.id).resDescription - -fun DataWidget<*>.getName(): String { - val id = dataItem.id - return if (id is StringId) id.name else view.stringFrom(getResNameId()) + override fun getName(): String { + return when (val id = item.id) { + is StringId -> id.value + is StringResId -> view.resources.getString(id.value) + else -> view.resources.getString(R.string.unknown) + } + } } internal fun inflate(id: Int, parent: ViewGroup): View { diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/impl/LinearBlockWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/impl/LinearBlockWidget.kt deleted file mode 100644 index 5f1d268c6f..0000000000 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/impl/LinearBlockWidget.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.tangem.tangemtest._arch.widget.impl - -import android.view.ViewGroup -import com.tangem.tangemtest.R -import com.tangem.tangemtest._arch.structure.abstraction.ItemViewModel -import com.tangem.tangemtest._arch.structure.abstraction.ListItemBlock -import com.tangem.tangemtest._arch.structure.abstraction.iterate -import com.tangem.tangemtest._arch.widget.abstraction.BaseBlockWidget - -/** -[REDACTED_AUTHOR] - */ -class LinearBlockWidget( - parent: ViewGroup, - private val children: ListItemBlock -) : BaseBlockWidget(parent) { - override fun getLayoutId(): Int = R.layout.w_personilize_block - - override var viewModel: List> = listOf() - get() { - val vmList = mutableListOf>() - children.itemList.iterate { item -> - (item as? ItemViewModel<*>)?.let { vmList.add(it) } - } - return vmList.toList() - } -} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/impl/LinearGroupWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/impl/LinearGroupWidget.kt new file mode 100644 index 0000000000..97c8d36a35 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/impl/LinearGroupWidget.kt @@ -0,0 +1,18 @@ +package com.tangem.tangemtest._arch.widget.impl + +import android.view.ViewGroup +import com.tangem.tangemtest.R +import com.tangem.tangemtest._arch.structure.abstraction.ItemGroup +import com.tangem.tangemtest._arch.widget.abstraction.BaseViewWidget + +/** +[REDACTED_AUTHOR] + */ +class LinearGroupWidget( + parent: ViewGroup, + itemGroup: ItemGroup +) : BaseViewWidget(parent, itemGroup) { + + override fun getLayoutId(): Int = R.layout.w_personilize_block + +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/impl/StubWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/impl/StubWidget.kt index 98e2bcd57a..1b832e362a 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/impl/StubWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/widget/impl/StubWidget.kt @@ -2,13 +2,14 @@ package com.tangem.tangemtest._arch.widget.impl import android.view.ViewGroup import com.tangem.tangemtest.R -import com.tangem.tangemtest._arch.structure.abstraction.ItemViewModel -import com.tangem.tangemtest._arch.widget.abstraction.BaseBlockWidget +import com.tangem.tangemtest._arch.structure.Id +import com.tangem.tangemtest._arch.structure.abstraction.BaseItem +import com.tangem.tangemtest._arch.structure.abstraction.BaseItemViewModel +import com.tangem.tangemtest._arch.widget.abstraction.BaseViewWidget /** [REDACTED_AUTHOR] */ -class StubWidget(parent: ViewGroup) : BaseBlockWidget(parent) { +class StubWidget(id: Id, parent: ViewGroup) : BaseViewWidget(parent, BaseItem(id, BaseItemViewModel())) { override fun getLayoutId(): Int = R.layout.w_empty - override var viewModel: List> = listOf() } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/commons/GlobalFunctions.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/GlobalFunctions.kt index 7a19cf981f..59ae0da2b9 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/commons/GlobalFunctions.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/GlobalFunctions.kt @@ -3,6 +3,7 @@ package com.tangem.tangemtest.commons /** [REDACTED_AUTHOR] */ -fun performAction(a: A?, b: B?, action: (A, B) -> Unit) { +fun performAction(a: A?, b: B?, action: (A, B) -> Unit, onFail: (() -> Unit)? = null) { if (a != null && b != null) action(a, b) + else onFail?.invoke() } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/DepersonalizeAction.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/DepersonalizeAction.kt index 2433302a4b..5f49aa15aa 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/DepersonalizeAction.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/DepersonalizeAction.kt @@ -2,7 +2,7 @@ package com.tangem.tangemtest.ucase.domain.actions import com.tangem.tangemtest._arch.structure.Id import com.tangem.tangemtest._arch.structure.PayloadHolder -import com.tangem.tangemtest._arch.structure.abstraction.findDataItem +import com.tangem.tangemtest._arch.structure.abstraction.findItem import com.tangem.tangemtest.ucase.domain.paramsManager.ActionCallback import com.tangem.tangemtest.ucase.variants.TlvId @@ -11,7 +11,7 @@ import com.tangem.tangemtest.ucase.variants.TlvId */ class DepersonalizeAction : BaseAction() { override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val item = attrs.itemList.findDataItem(TlvId.CardId) ?: return + val item = attrs.itemList.findItem(TlvId.CardId) ?: return val cardId = item.viewModel.data as? String ?: return attrs.cardManager.depersonalize(cardId) { handleResult(payload, it, null, attrs, callback) } 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 a50bc09456..21143ddec8 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 @@ -2,7 +2,7 @@ package com.tangem.tangemtest.ucase.domain.actions import com.tangem.tangemtest._arch.structure.PayloadHolder import com.tangem.tangemtest._arch.structure.abstraction.Item -import com.tangem.tangemtest._arch.structure.abstraction.findDataItem +import com.tangem.tangemtest._arch.structure.abstraction.findItem import com.tangem.tangemtest._arch.structure.impl.EditTextItem import com.tangem.tangemtest._arch.structure.impl.NumberItem import com.tangem.tangemtest.ucase.domain.paramsManager.ActionCallback @@ -11,7 +11,7 @@ import com.tangem.tangemtest.ucase.tunnel.ActionView import com.tangem.tangemtest.ucase.tunnel.ItemError import com.tangem.tangemtest.ucase.variants.personalize.CardNumber import com.tangem.tangemtest.ucase.variants.personalize.converter.PersonalizationConfigConverter -import com.tangem.tangemtest.ucase.variants.personalize.converter.fromTo.PersonalizeConfigToCardConfig +import com.tangem.tangemtest.ucase.variants.personalize.converter.PersonalizationConfigToCardConfig import com.tangem.tangemtest.ucase.variants.personalize.dto.DefaultPersonalizationParams import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizationConfig import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf @@ -38,7 +38,7 @@ class PersonalizeAction : BaseAction() { val manufacturer = DefaultPersonalizationParams.manufacturer() val personalizeConfig = PersonalizationConfigConverter().convert(itemList, PersonalizationConfig()) - val cardConfig = PersonalizeConfigToCardConfig().convert(personalizeConfig) + val cardConfig = PersonalizationConfigToCardConfig().convert(personalizeConfig) attrs.cardManager.personalize(cardConfig, issuer, manufacturer, acquirer) { handleResult(payload, it, null, attrs, callback) @@ -46,18 +46,18 @@ class PersonalizeAction : BaseAction() { } private fun checkSeries(itemList: List): Boolean { - val seriesItem = itemList.findDataItem(CardNumber.Series) as? EditTextItem ?: return false - val data = seriesItem.getData() ?: return false + val seriesItem = itemList.findItem(CardNumber.Series) as? EditTextItem ?: return false + val data = seriesItem.getData() as? String ?: return false seriesItem.setData(data.toUpperCase()) return data.length == 2 || data.length == 4 } private fun checkNumber(itemList: List): Boolean { - val seriesItem = itemList.findDataItem(CardNumber.Series) as? EditTextItem ?: return false - val numberItem = itemList.findDataItem(CardNumber.Number) as? NumberItem ?: return false - val seriesData = seriesItem.getData() ?: return false - val numberData = stringOf(numberItem.getData()) + val seriesItem = itemList.findItem(CardNumber.Series) as? EditTextItem ?: return false + val numberItem = itemList.findItem(CardNumber.Number) as? NumberItem ?: return false + val seriesData = seriesItem.getData() as? String ?: return false + val numberData = stringOf(numberItem.getData() as? Number) return if (seriesData.length == 2 && numberData.length > 13) false else !(seriesData.length == 4 && numberData.length > 11) diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/SignAction.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/SignAction.kt index 18fef1d8c5..d71eaeb900 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/SignAction.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/SignAction.kt @@ -2,7 +2,7 @@ package com.tangem.tangemtest.ucase.domain.actions import com.tangem.tangemtest._arch.structure.Id import com.tangem.tangemtest._arch.structure.PayloadHolder -import com.tangem.tangemtest._arch.structure.abstraction.findDataItem +import com.tangem.tangemtest._arch.structure.abstraction.findItem import com.tangem.tangemtest.ucase.domain.paramsManager.ActionCallback import com.tangem.tangemtest.ucase.variants.TlvId import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf @@ -12,9 +12,9 @@ import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf */ class SignAction : BaseAction() { override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val dataForHashing = attrs.itemList.findDataItem(TlvId.TransactionOutHash) ?: return + val dataForHashing = attrs.itemList.findItem(TlvId.TransactionOutHash) ?: return val hash = dataForHashing.getData() as? ByteArray ?: return - val cardId = attrs.itemList.findDataItem(TlvId.CardId)?.viewModel?.data ?: return + val cardId = attrs.itemList.findItem(TlvId.CardId)?.viewModel?.data ?: return attrs.cardManager.sign(arrayOf(hash), stringOf(cardId)) { handleResult(payload, it, null, attrs, callback) } } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/managers/BaseItemsManager.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/managers/BaseItemsManager.kt index bfb987742d..72729d11eb 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/managers/BaseItemsManager.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/managers/BaseItemsManager.kt @@ -5,7 +5,7 @@ import com.tangem.CardManager 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.findDataItem +import com.tangem.tangemtest._arch.structure.abstraction.findItem import com.tangem.tangemtest.ucase.domain.actions.Action import com.tangem.tangemtest.ucase.domain.actions.AttrForAction import com.tangem.tangemtest.ucase.domain.paramsManager.ActionCallback @@ -30,7 +30,7 @@ open class BaseItemsManager(protected val action: Action) : ItemsManager, Lifecy override fun itemChanged(id: Id, value: Any?, callback: AffectedItemsCallback?) { if (itemList.isEmpty()) return - val foundItem = itemList.findDataItem(id) ?: return + val foundItem = itemList.findItem(id) ?: return foundItem.setData(value) applyChangesByAffectedItems(foundItem, callback) 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 990f2a78f4..5cf644eb32 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 @@ -4,7 +4,7 @@ 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._arch.structure.abstraction.findDataItem +import com.tangem.tangemtest._arch.structure.abstraction.findItem import com.tangem.tangemtest.ucase.domain.paramsManager.PayloadKey import com.tangem.tangemtest.ucase.tunnel.ActionView import com.tangem.tangemtest.ucase.tunnel.CardError @@ -18,7 +18,7 @@ import ru.dev.gbixahue.eu4d.lib.android.global.threading.postUI */ class AfterScanModifier : AfterActionModification { override fun modify(payload: PayloadHolder, taskEvent: TaskEvent<*>, itemList: List): List { - val foundItem = itemList.findDataItem(TlvId.CardId) ?: return listOf() + val foundItem = itemList.findItem(TlvId.CardId) ?: return listOf() val card = smartCast(taskEvent)?.card ?: return listOf() val actionView = payload.get(PayloadKey.actionView) as? ActionView ?: return listOf() 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 41bd4cd0a3..730c570be6 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 @@ -6,7 +6,7 @@ import com.tangem.common.extensions.calculateSha256 import com.tangem.common.extensions.calculateSha512 import com.tangem.tangemtest._arch.structure.PayloadHolder import com.tangem.tangemtest._arch.structure.abstraction.Item -import com.tangem.tangemtest._arch.structure.abstraction.findDataItem +import com.tangem.tangemtest._arch.structure.abstraction.findItem import com.tangem.tangemtest.ucase.domain.paramsManager.PayloadKey import com.tangem.tangemtest.ucase.tunnel.ActionView import com.tangem.tangemtest.ucase.variants.TlvId @@ -27,7 +27,7 @@ class SignScanConsequence : ItemsChangeConsequence { override fun affectChanges(payload: PayloadHolder, changedItem: Item, itemList: List): List? { if (changedItem.id != TlvId.CardId) return null - val hashItem = itemList.findDataItem(TlvId.TransactionOutHash) ?: return null + val hashItem = itemList.findItem(TlvId.TransactionOutHash) ?: return null val affectedItems = mutableListOf(hashItem) val card = payload.remove(PayloadKey.card) as Card? if (card == null) { diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/ActionViewModel.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/ActionViewModel.kt index 8ffcb80328..e1b63c7df7 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/ActionViewModel.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/ActionViewModel.kt @@ -8,7 +8,6 @@ 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 @@ -55,11 +54,11 @@ class ActionViewModel(private val itemsManager: ItemsManager) : ViewModel(), Lif //invokes Scan, Sign etc... fun invokeMainAction() { - performAction(itemsManager, cardManager) { paramsManager, cardManager -> + performAction(itemsManager, cardManager, { paramsManager, cardManager -> paramsManager.invokeMainAction(cardManager) { response, listOfChangedParams -> notifier.handleActionResult(response, listOfChangedParams) } - } + }) } fun getItemAction(id: Id): (() -> Unit)? { @@ -74,8 +73,7 @@ class ActionViewModel(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 + it.viewModel.viewState.descriptionVisibility = if (state) View.VISIBLE else View.GONE } } 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 44acd319b8..b9186f495a 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 @@ -13,7 +13,6 @@ 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.PayloadKey @@ -106,9 +105,7 @@ abstract class BaseCardActionFragment : BaseFragment(), ActionView { protected open fun listenChangedItems() { actionVM.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 - Log.d(this, "item changed from VM - name: ${dataItem.id}, value:${dataItem.viewModel.data}") + Log.d(this, "item changed from VM - name: ${item.id}, value:${item.viewModel.data}") paramsWidgetList.firstOrNull { it.id == item.id }?.changeParamValue(item.viewModel.data) } }) diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/widgets/ParameterWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/widgets/ParameterWidget.kt index 15ba1cdcba..96037984ea 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/widgets/ParameterWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/ui/widgets/ParameterWidget.kt @@ -12,8 +12,8 @@ import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import com.tangem.tangemtest.R import com.tangem.tangemtest._arch.structure.Id -import com.tangem.tangemtest._arch.structure.abstraction.BaseItem import com.tangem.tangemtest._arch.structure.abstraction.Item +import com.tangem.tangemtest._arch.structure.impl.EditTextItem import com.tangem.tangemtest.ucase.resources.ActionType import com.tangem.tangemtest.ucase.resources.MainResourceHolder import com.tangem.tangemtest.ucase.resources.Resources @@ -29,7 +29,7 @@ class ParameterWidget( ) { val id: Id = item.id - val dataItem: BaseItem = item as BaseItem + val typedItem = item as EditTextItem var onValueChanged: ((Id, Any?) -> Unit)? = null var onActionBtnClickListener: (() -> Unit)? = null @@ -47,11 +47,11 @@ class ParameterWidget( private val tvDescription: TextView? by lazy { descriptionContainer.findViewById(R.id.tv_description) } private var actionBtnVisibilityState: Int = btnAction.visibility - private var value: Any? = dataItem.viewModel.data + private var value: Any? = typedItem.viewModel.data init { tilValue.hint = tilValue.context.getString(getResNameId()) - etValue.setText(stringOf(dataItem.viewModel.data)) + etValue.setText(stringOf(typedItem.viewModel.data)) etValue.addTextChangedListener(valueWatcher) btnAction.setOnClickListener { onActionBtnClickListener?.invoke() } btnAction.setText(getResNameId(ActionType.Scan)) diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/DefaultValues.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/DefaultValues.kt index 49dd2faa8d..37364a0f8a 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/DefaultValues.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/DefaultValues.kt @@ -2,7 +2,7 @@ package com.tangem.tangemtest.ucase.variants.personalize.converter import com.tangem.commands.EllipticCurve import com.tangem.tangemtest._arch.structure.Id -import com.tangem.tangemtest._arch.structure.impl.KeyValue +import com.tangem.tangemtest._arch.structure.abstraction.KeyValue import com.tangem.tangemtest.ucase.variants.personalize.* import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizationConfig import ru.dev.gbixahue.eu4d.lib.kotlin.common.BaseTypedHolder diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/fromTo/ItemTypes.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/ItemTypes.kt similarity index 99% rename from tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/fromTo/ItemTypes.kt rename to tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/ItemTypes.kt index 9902d38da4..238a0aeaa0 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/fromTo/ItemTypes.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/ItemTypes.kt @@ -1,4 +1,4 @@ -package com.tangem.tangemtest.ucase.variants.personalize.converter.fromTo +package com.tangem.tangemtest.ucase.variants.personalize.converter import com.tangem.tangemtest.ucase.variants.personalize.* diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/PersonalizationConfigConverter.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/PersonalizationConfigConverter.kt index 7fbf672259..c350690412 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/PersonalizationConfigConverter.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/PersonalizationConfigConverter.kt @@ -1,12 +1,12 @@ package com.tangem.tangemtest.ucase.variants.personalize.converter -import com.tangem.tangemtest._arch.structure.abstraction.Item -import com.tangem.tangemtest._arch.structure.abstraction.ItemsToModel -import com.tangem.tangemtest._arch.structure.abstraction.ModelConverter -import com.tangem.tangemtest._arch.structure.abstraction.ModelToItems -import com.tangem.tangemtest.ucase.variants.personalize.converter.fromTo.ItemsToPersonalizationConfig -import com.tangem.tangemtest.ucase.variants.personalize.converter.fromTo.PersonalizationConfigToItems +import com.tangem.tangemtest._arch.structure.Additional +import com.tangem.tangemtest._arch.structure.Id +import com.tangem.tangemtest._arch.structure.abstraction.* +import com.tangem.tangemtest._arch.structure.impl.* +import com.tangem.tangemtest.ucase.variants.personalize.* import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizationConfig +import ru.dev.gbixahue.eu4d.lib.android.global.log.Log /** [REDACTED_AUTHOR] @@ -23,4 +23,281 @@ class PersonalizationConfigConverter : ModelConverter { override fun convert(from: PersonalizationConfig): List { return toItems.convert(from) } +} + +class ItemsToPersonalizationConfig : ItemsToModel { + protected val valuesHolder = ConfigValuesHolder() + + override fun convert(from: List, default: PersonalizationConfig): PersonalizationConfig { + valuesHolder.init(default) + mapListItems(from) + return createModel() + } + + private fun mapListItems(itemList: List) { + itemList.iterate { item -> mapItemToHolder(item) } + } + + private fun mapItemToHolder(item: Item) { + when (item) { + is ItemGroup -> mapListItems(item.itemList) + is BaseItem -> { + val defValue = valuesHolder.get(item.id) ?: return + defValue.set(item.viewModel.data) + } + } + } + + private fun createModel(): PersonalizationConfig { + val export = PersonalizationConfig() + export.series = getTyped(CardNumber.Series) + export.startNumber = getTyped(CardNumber.Number) + export.curveID = getTyped(Common.Curve) + export.blockchain = getTyped(Common.Blockchain) + export.blockchainCustom = getTyped(Common.BlockchainCustom) + export.MaxSignatures = getTyped(Common.MaxSignatures) + export.createWallet = getTyped(Common.CreateWallet) + export.SigningMethod0 = getTyped(SigningMethod.SignTx) + export.SigningMethod1 = getTyped(SigningMethod.SignTxRaw) + export.SigningMethod2 = getTyped(SigningMethod.SignValidatedTx) + export.SigningMethod3 = getTyped(SigningMethod.SignValidatedTxRaw) + export.SigningMethod4 = getTyped(SigningMethod.SignValidatedTxIssuer) + export.SigningMethod5 = getTyped(SigningMethod.SignValidatedTxRawIssuer) + export.SigningMethod6 = getTyped(SigningMethod.SignExternal) + export.pinLessFloorLimit = getTyped(SignHashExProp.PinLessFloorLimit) + export.hexCrExKey = getTyped(SignHashExProp.CryptoExKey) + export.requireTerminalCertSignature = getTyped(SignHashExProp.RequireTerminalCertSig) + export.requireTerminalTxSignature = getTyped(SignHashExProp.RequireTerminalTxSig) + export.checkPIN3onCard = getTyped(SignHashExProp.CheckPin3) + export.writeOnPersonalization = getTyped(Denomination.WriteOnPersonalize) + export.denomination = getTyped(Denomination.Denomination) + export.itsToken = getTyped(Token.ItsToken) + export.symbol = getTyped(Token.Symbol) + export.contractAddress = getTyped(Token.ContractAddress) + export.decimal = getTyped(Token.Decimal) + export.cardData = export.cardData.apply { this.product_note = getTyped(ProductMask.Note) } + export.cardData = export.cardData.apply { this.product_tag = getTyped(ProductMask.Tag) } + export.cardData = export.cardData.apply { this.product_id_card = getTyped(ProductMask.IdCard) } + export.cardData = export.cardData.apply { this.product_id_issuer = getTyped(ProductMask.IdIssuerCard) } + export.isReusable = getTyped(SettingsMask.IsReusable) + export.useActivation = getTyped(SettingsMask.NeedActivation) + export.forbidPurgeWallet = getTyped(SettingsMask.ForbidPurge) + export.allowSelectBlockchain = getTyped(SettingsMask.AllowSelectBlockchain) + export.useBlock = getTyped(SettingsMask.UseBlock) + export.oneApdu = getTyped(SettingsMask.OneApdu) + export.useCVC = getTyped(SettingsMask.UseCvc) + export.allowSwapPIN = getTyped(SettingsMask.AllowSwapPin) + export.allowSwapPIN2 = getTyped(SettingsMask.AllowSwapPin2) + export.forbidDefaultPIN = getTyped(SettingsMask.ForbidDefaultPin) + export.smartSecurityDelay = getTyped(SettingsMask.SmartSecurityDelay) + export.protectIssuerDataAgainstReplay = getTyped(SettingsMask.ProtectIssuerDataAgainstReplay) + export.skipSecurityDelayIfValidatedByIssuer = getTyped(SettingsMask.SkipSecurityDelayIfValidated) + export.skipCheckPIN2andCVCIfValidatedByIssuer = getTyped(SettingsMask.SkipPin2CvcIfValidated) + export.skipSecurityDelayIfValidatedByLinkedTerminal = getTyped(SettingsMask.SkipSecurityDelayOnLinkedTerminal) + export.restrictOverwriteIssuerDataEx = getTyped(SettingsMask.RestrictOverwriteExtraIssuerData) + export.protocolAllowUnencrypted = getTyped(SettingsMaskProtocolEnc.AllowUnencrypted) + export.protocolAllowStaticEncryption = getTyped(SettingsMaskProtocolEnc.AllowStaticEncryption) + export.useNDEF = getTyped(SettingsMaskNdef.UseNdef) + export.useDynamicNDEF = getTyped(SettingsMaskNdef.DynamicNdef) + export.disablePrecomputedNDEF = getTyped(SettingsMaskNdef.DisablePrecomputedNdef) + export.aar = getTyped(SettingsMaskNdef.Aar) + export.aarCustom = getTyped(SettingsMaskNdef.AarCustom) + export.uri = getTyped(SettingsMaskNdef.Uri) + export.PIN = getTyped(Pins.Pin) + export.PIN2 = getTyped(Pins.Pin2) + export.PIN3 = getTyped(Pins.Pin3) + export.CVC = getTyped(Pins.Cvc) + export.pauseBeforePIN2 = getTyped(Pins.PauseBeforePin2) + return export + } + + private inline fun getTyped(id: Id): Type { + return getTypedBy(valuesHolder, id)!! + } + + private inline fun getTypedBy(holder: ConfigValuesHolder, id: Id): Type? { + Log.d(this, "getTyped for id: $id") + var typedValue = holder.get(id)?.get() + + typedValue = when (typedValue) { + is ListViewModel -> typedValue.selectedItem as Type + else -> typedValue as? Type ?: null + } + return typedValue + } +} + +class PersonalizationConfigToItems : ModelToItems { + private val valuesHolder = ConfigValuesHolder() + private val itemTypes = ItemTypes() + + override fun convert(from: PersonalizationConfig): List { + valuesHolder.init(from) + val blocList = mutableListOf() + blocList.add(cardNumber()) + blocList.add(common()) + blocList.add(signingMethod()) + blocList.add(signHashExProperties()) + blocList.add(denomination()) + blocList.add(token()) + blocList.add(productMask()) + blocList.add(settingsMask()) + blocList.add(settingsMaskProtocolEnc()) + blocList.add(settingsMaskNdef()) + blocList.add(pins()) + blocList.iterate { + if (itemTypes.hiddenList.contains(it.id)) { + it.viewModel.viewState.isHiddenField = true + } + } + return blocList + } + + private fun cardNumber(): ItemGroup { + val block = createGroup(BlockId.CardNumber) + mutableListOf( + CardNumber.Series, + CardNumber.Number, + CardNumber.BatchId + ).forEach { createItem(block, it as Id) } + return block + } + + private fun common(): ItemGroup { + val block = createGroup(BlockId.Common) + mutableListOf( + Common.Curve, + Common.Blockchain, + Common.BlockchainCustom, + Common.MaxSignatures, + Common.CreateWallet + ).forEach { createItem(block, it) } + return block + } + + private fun signingMethod(): ItemGroup { + val block = createGroup(BlockId.SigningMethod) + mutableListOf( + SigningMethod.SignTx, + SigningMethod.SignTxRaw, + SigningMethod.SignValidatedTx, + SigningMethod.SignValidatedTxRaw, + SigningMethod.SignValidatedTxIssuer, + SigningMethod.SignValidatedTxRawIssuer, + SigningMethod.SignExternal + ).forEach { createItem(block, it) } + return block + } + + private fun signHashExProperties(): ItemGroup { + val block = createGroup(BlockId.SignHashExProp) + mutableListOf( + SignHashExProp.PinLessFloorLimit, + SignHashExProp.CryptoExKey, + SignHashExProp.RequireTerminalCertSig, + SignHashExProp.RequireTerminalTxSig, + SignHashExProp.CheckPin3 + ).forEach { createItem(block, it) } + return block + } + + private fun denomination(): ItemGroup { + val block = createGroup(BlockId.Denomination) + mutableListOf( + Denomination.WriteOnPersonalize, + Denomination.Denomination + ).forEach { createItem(block, it) } + return block + } + + private fun token(): ItemGroup { + val block = createGroup(BlockId.Token) + mutableListOf( + Token.ItsToken, + Token.Symbol, + Token.ContractAddress, + Token.Decimal + ).forEach { createItem(block, it) } + return block + } + + private fun productMask(): ItemGroup { + val block = createGroup(BlockId.ProdMask) + mutableListOf( + ProductMask.Note, + ProductMask.Tag, + ProductMask.IdCard, + ProductMask.IdIssuerCard + ).forEach { createItem(block, it) } + return block + } + + private fun settingsMask(): ItemGroup { + val block = createGroup(BlockId.SettingsMask) + mutableListOf( + SettingsMask.IsReusable, + SettingsMask.NeedActivation, + SettingsMask.ForbidPurge, + SettingsMask.AllowSelectBlockchain, + SettingsMask.UseBlock, + SettingsMask.OneApdu, + SettingsMask.UseCvc, + SettingsMask.AllowSwapPin, + SettingsMask.AllowSwapPin2, + SettingsMask.ForbidDefaultPin, + SettingsMask.SmartSecurityDelay, + SettingsMask.ProtectIssuerDataAgainstReplay, + SettingsMask.SkipSecurityDelayIfValidated, + SettingsMask.SkipPin2CvcIfValidated, + SettingsMask.SkipSecurityDelayOnLinkedTerminal, + SettingsMask.RestrictOverwriteExtraIssuerData + ).forEach { createItem(block, it) } + return block + } + + private fun settingsMaskProtocolEnc(): ItemGroup { + val block = createGroup(BlockId.SettingsMaskProtocolEnc) + mutableListOf( + SettingsMaskProtocolEnc.AllowUnencrypted, + SettingsMaskProtocolEnc.AllowStaticEncryption + ).forEach { createItem(block, it) } + return block + } + + private fun settingsMaskNdef(): ItemGroup { + val block = createGroup(BlockId.SettingsMaskNdef) + mutableListOf( + SettingsMaskNdef.UseNdef, + SettingsMaskNdef.DynamicNdef, + SettingsMaskNdef.DisablePrecomputedNdef, + SettingsMaskNdef.Aar, + SettingsMaskNdef.AarCustom, + SettingsMaskNdef.Uri + ).forEach { createItem(block, it) } + return block + } + + private fun pins(): ItemGroup { + val block = createGroup(BlockId.Pins) + mutableListOf(Pins.Pin, Pins.Pin2, Pins.Pin3, Pins.Cvc, Pins.PauseBeforePin2) + .forEach { createItem(block, it) } + return block + } + + private fun createGroup(id: Id): ItemGroup { + return SimpleItemGroup(id).apply { addItem(TextItem(id)) } + } + + private fun createItem(itemGroup: ItemGroup, id: Id) { + val holder = valuesHolder.get(id) ?: return + val item = when { + itemTypes.blockIdList.contains(id) -> TextItem(id, holder.get() as? String) + itemTypes.listItemList.contains(id) -> SpinnerItem(id, holder.list as List, holder.get()) + itemTypes.boolList.contains(id) -> BoolItem(id, holder.get() as? Boolean) + itemTypes.editTextList.contains(id) -> EditTextItem(id, holder.get() as? String) + itemTypes.numberList.contains(id) -> NumberItem(id, holder.get() as? Number) + else -> SimpleItemGroup(Additional.UNDEFINED) + } + itemGroup.addItem(item) + } } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/PersonalizationConfigToCardConfig.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/PersonalizationConfigToCardConfig.kt new file mode 100644 index 0000000000..fa79df96e0 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/PersonalizationConfigToCardConfig.kt @@ -0,0 +1,113 @@ +package com.tangem.tangemtest.ucase.variants.personalize.converter + +import com.tangem.commands.CardData +import com.tangem.commands.EllipticCurve +import com.tangem.commands.ProductMaskBuilder +import com.tangem.commands.personalization.entities.CardConfig +import com.tangem.commands.personalization.entities.NdefRecord +import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizationConfig +import ru.dev.gbixahue.eu4d.lib.kotlin.common.Converter +import java.util.* + +class PersonalizationConfigToCardConfig : Converter { + + override fun convert(from: PersonalizationConfig): CardConfig { + val signingMethod = com.tangem.commands.SigningMethod.build( + signHash = from.SigningMethod0, + signRaw = from.SigningMethod1, + signHashValidatedByIssuer = from.SigningMethod2, + signRawValidatedByIssuer = from.SigningMethod3, + signHashValidatedByIssuerAndWriteIssuerData = from.SigningMethod4, + signRawValidatedByIssuerAndWriteIssuerData = from.SigningMethod5, + signPos = from.SigningMethod6 + ) + + val isNote = from.cardData.product_note + val isTag = from.cardData.product_tag + val isIdCard = from.cardData.product_id_card + val isIdIssuer = from.cardData.product_id_issuer + + val productMaskBuilder = ProductMaskBuilder() + if (isNote) productMaskBuilder.add(com.tangem.commands.ProductMask.note) + if (isTag) productMaskBuilder.add(com.tangem.commands.ProductMask.tag) + if (isIdCard) productMaskBuilder.add(com.tangem.commands.ProductMask.idCard) + if (isIdIssuer) productMaskBuilder.add(com.tangem.commands.ProductMask.idIssuer) + val productMask = productMaskBuilder.build() + + var tokenSymbol: String? = null + var tokenContractAddress: String? = null + var tokenDecimal: Int? = null + if (from.itsToken) { + tokenSymbol = from.symbol + tokenContractAddress = from.contractAddress + tokenDecimal = from.decimal.toInt() + } + + val blockchain = if (from.blockchain.isNotEmpty()) from.blockchain else from.blockchainCustom + val cardData = CardData( + blockchainName = blockchain, + batchId = from.batchId, + productMask = productMask, + tokenSymbol = tokenSymbol, + tokenContractAddress = tokenContractAddress, + tokenDecimal = tokenDecimal, + issuerName = null, + manufactureDateTime = Calendar.getInstance().time, + manufacturerSignature = null) + + + val ndefs = mutableListOf() + if (from.uri.isNotEmpty()) { + ndefs.add(NdefRecord(NdefRecord.Type.URI, from.uri)) + } + when (from.aar) { + "None" -> null + "--- CUSTOM ---" -> NdefRecord(NdefRecord.Type.AAR, from.aarCustom) + else -> NdefRecord(NdefRecord.Type.AAR, from.aar) + }?.let { ndefs.add(it) } + + return CardConfig( + "Tangem", + "Tangem Test", + from.series, + from.startNumber, + 1000, + from.PIN, + from.PIN2, + from.PIN3, + from.hexCrExKey, + from.CVC, + from.pauseBeforePIN2.toInt(), + from.smartSecurityDelay, + EllipticCurve.byName(from.curveID) ?: EllipticCurve.Secp256k1, + signingMethod, + from.MaxSignatures.toInt(), + from.isReusable, + from.allowSwapPIN, + from.allowSwapPIN2, + from.useActivation, + from.useCVC, + from.useNDEF, + from.useDynamicNDEF, + from.oneApdu, + from.useBlock, + from.allowSelectBlockchain, + from.forbidPurgeWallet, + from.protocolAllowUnencrypted, + from.protocolAllowStaticEncryption, + from.protectIssuerDataAgainstReplay, + from.forbidDefaultPIN, + from.disablePrecomputedNDEF, + from.skipSecurityDelayIfValidatedByIssuer, + from.skipCheckPIN2andCVCIfValidatedByIssuer, + from.skipSecurityDelayIfValidatedByLinkedTerminal, + from.restrictOverwriteIssuerDataEx, + from.requireTerminalTxSignature, + from.requireTerminalCertSignature, + from.checkPIN3onCard, + from.createWallet, + cardData, + ndefs + ) + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/fromTo/ItemsToPersonalizationConfig.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/fromTo/ItemsToPersonalizationConfig.kt deleted file mode 100644 index 95fd18908d..0000000000 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/fromTo/ItemsToPersonalizationConfig.kt +++ /dev/null @@ -1,114 +0,0 @@ -package com.tangem.tangemtest.ucase.variants.personalize.converter.fromTo - -import com.tangem.tangemtest._arch.structure.Id -import com.tangem.tangemtest._arch.structure.abstraction.* -import com.tangem.tangemtest._arch.structure.impl.ListValueWrapper -import com.tangem.tangemtest.ucase.variants.personalize.* -import com.tangem.tangemtest.ucase.variants.personalize.converter.ConfigValuesHolder -import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizationConfig -import ru.dev.gbixahue.eu4d.lib.android.global.log.Log - -/** -[REDACTED_AUTHOR] - */ -class ItemsToPersonalizationConfig : ItemsToModel { - protected val valuesHolder = ConfigValuesHolder() - - override fun convert(from: List, default: PersonalizationConfig): PersonalizationConfig { - valuesHolder.init(default) - mapListItems(from) - return createModel() - } - - private fun mapListItems(itemList: List) { - itemList.iterate { item -> mapItemToHolder(item) } - } - - private fun mapItemToHolder(item: Item) { - when (item) { - is Block -> mapListItems(item.itemList) - is BaseItem<*> -> { - val defValue = valuesHolder.get(item.id) ?: return - defValue.set(item.viewModel.data) - } - } - } - - private fun createModel(): PersonalizationConfig { - val export = PersonalizationConfig() - export.series = getTyped(CardNumber.Series) - export.startNumber = getTyped(CardNumber.Number) - export.curveID = getTyped(Common.Curve) - export.blockchain = getTyped(Common.Blockchain) - export.blockchainCustom = getTyped(Common.BlockchainCustom) - export.MaxSignatures = getTyped(Common.MaxSignatures) - export.createWallet = getTyped(Common.CreateWallet) - export.SigningMethod0 = getTyped(SigningMethod.SignTx) - export.SigningMethod1 = getTyped(SigningMethod.SignTxRaw) - export.SigningMethod2 = getTyped(SigningMethod.SignValidatedTx) - export.SigningMethod3 = getTyped(SigningMethod.SignValidatedTxRaw) - export.SigningMethod4 = getTyped(SigningMethod.SignValidatedTxIssuer) - export.SigningMethod5 = getTyped(SigningMethod.SignValidatedTxRawIssuer) - export.SigningMethod6 = getTyped(SigningMethod.SignExternal) - export.pinLessFloorLimit = getTyped(SignHashExProp.PinLessFloorLimit) - export.hexCrExKey = getTyped(SignHashExProp.CryptoExKey) - export.requireTerminalCertSignature = getTyped(SignHashExProp.RequireTerminalCertSig) - export.requireTerminalTxSignature = getTyped(SignHashExProp.RequireTerminalTxSig) - export.checkPIN3onCard = getTyped(SignHashExProp.CheckPin3) - export.writeOnPersonalization = getTyped(Denomination.WriteOnPersonalize) - export.denomination = getTyped(Denomination.Denomination) - export.itsToken = getTyped(Token.ItsToken) - export.symbol = getTyped(Token.Symbol) - export.contractAddress = getTyped(Token.ContractAddress) - export.decimal = getTyped(Token.Decimal) - export.cardData = export.cardData.apply { this.product_note = getTyped(ProductMask.Note) } - export.cardData = export.cardData.apply { this.product_tag = getTyped(ProductMask.Tag) } - export.cardData = export.cardData.apply { this.product_id_card = getTyped(ProductMask.IdCard) } - export.cardData = export.cardData.apply { this.product_id_issuer = getTyped(ProductMask.IdIssuerCard) } - export.isReusable = getTyped(SettingsMask.IsReusable) - export.useActivation = getTyped(SettingsMask.NeedActivation) - export.forbidPurgeWallet = getTyped(SettingsMask.ForbidPurge) - export.allowSelectBlockchain = getTyped(SettingsMask.AllowSelectBlockchain) - export.useBlock = getTyped(SettingsMask.UseBlock) - export.oneApdu = getTyped(SettingsMask.OneApdu) - export.useCVC = getTyped(SettingsMask.UseCvc) - export.allowSwapPIN = getTyped(SettingsMask.AllowSwapPin) - export.allowSwapPIN2 = getTyped(SettingsMask.AllowSwapPin2) - export.forbidDefaultPIN = getTyped(SettingsMask.ForbidDefaultPin) - export.smartSecurityDelay = getTyped(SettingsMask.SmartSecurityDelay) - export.protectIssuerDataAgainstReplay = getTyped(SettingsMask.ProtectIssuerDataAgainstReplay) - export.skipSecurityDelayIfValidatedByIssuer = getTyped(SettingsMask.SkipSecurityDelayIfValidated) - export.skipCheckPIN2andCVCIfValidatedByIssuer = getTyped(SettingsMask.SkipPin2CvcIfValidated) - export.skipSecurityDelayIfValidatedByLinkedTerminal = getTyped(SettingsMask.SkipSecurityDelayOnLinkedTerminal) - export.restrictOverwriteIssuerDataEx = getTyped(SettingsMask.RestrictOverwriteExtraIssuerData) - export.protocolAllowUnencrypted = getTyped(SettingsMaskProtocolEnc.AllowUnencrypted) - export.protocolAllowStaticEncryption = getTyped(SettingsMaskProtocolEnc.AllowStaticEncryption) - export.useNDEF = getTyped(SettingsMaskNdef.UseNdef) - export.useDynamicNDEF = getTyped(SettingsMaskNdef.DynamicNdef) - export.disablePrecomputedNDEF = getTyped(SettingsMaskNdef.DisablePrecomputedNdef) - export.aar = getTyped(SettingsMaskNdef.Aar) - export.aarCustom = getTyped(SettingsMaskNdef.AarCustom) - export.uri = getTyped(SettingsMaskNdef.Uri) - export.PIN = getTyped(Pins.Pin) - export.PIN2 = getTyped(Pins.Pin2) - export.PIN3 = getTyped(Pins.Pin3) - export.CVC = getTyped(Pins.Cvc) - export.pauseBeforePIN2 = getTyped(Pins.PauseBeforePin2) - return export - } - - private inline fun getTyped(id: Id): Type { - return getTypedBy(valuesHolder, id)!! - } - - private inline fun getTypedBy(holder: ConfigValuesHolder, id: Id): Type? { - Log.d(this, "getTyped for id: $id") - var typedValue = holder.get(id)?.get() - - typedValue = when (typedValue) { - is ListValueWrapper -> typedValue.selectedItem as Type - else -> typedValue as? Type ?: null - } - return typedValue - } -} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/fromTo/PersonalizeConfigTo.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/fromTo/PersonalizeConfigTo.kt deleted file mode 100644 index 30a581378f..0000000000 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/fromTo/PersonalizeConfigTo.kt +++ /dev/null @@ -1,305 +0,0 @@ -package com.tangem.tangemtest.ucase.variants.personalize.converter.fromTo - -import com.tangem.commands.CardData -import com.tangem.commands.EllipticCurve -import com.tangem.commands.ProductMaskBuilder -import com.tangem.commands.personalization.entities.CardConfig -import com.tangem.commands.personalization.entities.NdefRecord -import com.tangem.tangemtest._arch.structure.Additional -import com.tangem.tangemtest._arch.structure.Id -import com.tangem.tangemtest._arch.structure.abstraction.* -import com.tangem.tangemtest._arch.structure.impl.* -import com.tangem.tangemtest.ucase.domain.paramsManager.PayloadKey -import com.tangem.tangemtest.ucase.variants.personalize.* -import com.tangem.tangemtest.ucase.variants.personalize.converter.ConfigValuesHolder -import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizationConfig -import ru.dev.gbixahue.eu4d.lib.kotlin.common.Converter -import java.util.* - -/** -[REDACTED_AUTHOR] - */ -class PersonalizationConfigToItems : ModelToItems { - private val valuesHolder = ConfigValuesHolder() - private val itemTypes = ItemTypes() - - override fun convert(from: PersonalizationConfig): List { - valuesHolder.init(from) - val blocList = mutableListOf() - blocList.add(cardNumber()) - blocList.add(common()) - blocList.add(signingMethod()) - blocList.add(signHashExProperties()) - blocList.add(denomination()) - blocList.add(token()) - blocList.add(productMask()) - blocList.add(settingsMask()) - blocList.add(settingsMaskProtocolEnc()) - blocList.add(settingsMaskNdef()) - blocList.add(pins()) - val payloadBlock = ListItemBlock(Additional.JSON_TAILS) - addPayload(payloadBlock, from) - blocList.add(payloadBlock) - blocList.iterate { - if (itemTypes.hiddenList.contains(it.id)) { - (it as BaseItem<*>)?.viewModel.viewState.isHiddenField = true - } - } - return blocList - } - - private fun cardNumber(): Block { - val block = createBlock(BlockId.CardNumber) - mutableListOf( - CardNumber.Series, - CardNumber.Number, - CardNumber.BatchId - ).forEach { createItem(block, it as Id) } - return block - } - - private fun common(): Block { - val block = createBlock(BlockId.Common) - mutableListOf( - Common.Curve, - Common.Blockchain, - Common.BlockchainCustom, - Common.MaxSignatures, - Common.CreateWallet - ).forEach { createItem(block, it) } - return block - } - - private fun signingMethod(): Block { - val block = createBlock(BlockId.SigningMethod) - mutableListOf( - SigningMethod.SignTx, - SigningMethod.SignTxRaw, - SigningMethod.SignValidatedTx, - SigningMethod.SignValidatedTxRaw, - SigningMethod.SignValidatedTxIssuer, - SigningMethod.SignValidatedTxRawIssuer, - SigningMethod.SignExternal - ).forEach { createItem(block, it) } - return block - } - - private fun signHashExProperties(): Block { - val block = createBlock(BlockId.SignHashExProp) - mutableListOf( - SignHashExProp.PinLessFloorLimit, - SignHashExProp.CryptoExKey, - SignHashExProp.RequireTerminalCertSig, - SignHashExProp.RequireTerminalTxSig, - SignHashExProp.CheckPin3 - ).forEach { createItem(block, it) } - return block - } - - private fun denomination(): Block { - val block = createBlock(BlockId.Denomination) - mutableListOf( - Denomination.WriteOnPersonalize, - Denomination.Denomination - ).forEach { createItem(block, it) } - return block - } - - private fun token(): Block { - val block = createBlock(BlockId.Token) - mutableListOf( - Token.ItsToken, - Token.Symbol, - Token.ContractAddress, - Token.Decimal - ).forEach { createItem(block, it) } - return block - } - - private fun productMask(): Block { - val block = createBlock(BlockId.ProdMask) - mutableListOf( - ProductMask.Note, - ProductMask.Tag, - ProductMask.IdCard, - ProductMask.IdIssuerCard - ).forEach { createItem(block, it) } - return block - } - - private fun settingsMask(): Block { - val block = createBlock(BlockId.SettingsMask) - mutableListOf( - SettingsMask.IsReusable, - SettingsMask.NeedActivation, - SettingsMask.ForbidPurge, - SettingsMask.AllowSelectBlockchain, - SettingsMask.UseBlock, - SettingsMask.OneApdu, - SettingsMask.UseCvc, - SettingsMask.AllowSwapPin, - SettingsMask.AllowSwapPin2, - SettingsMask.ForbidDefaultPin, - SettingsMask.SmartSecurityDelay, - SettingsMask.ProtectIssuerDataAgainstReplay, - SettingsMask.SkipSecurityDelayIfValidated, - SettingsMask.SkipPin2CvcIfValidated, - SettingsMask.SkipSecurityDelayOnLinkedTerminal, - SettingsMask.RestrictOverwriteExtraIssuerData - ).forEach { createItem(block, it) } - return block - } - - private fun settingsMaskProtocolEnc(): Block { - val block = createBlock(BlockId.SettingsMaskProtocolEnc) - mutableListOf( - SettingsMaskProtocolEnc.AllowUnencrypted, - SettingsMaskProtocolEnc.AllowStaticEncryption - ).forEach { createItem(block, it) } - return block - } - - private fun settingsMaskNdef(): Block { - val block = createBlock(BlockId.SettingsMaskNdef) - mutableListOf( - SettingsMaskNdef.UseNdef, - SettingsMaskNdef.DynamicNdef, - SettingsMaskNdef.DisablePrecomputedNdef, - SettingsMaskNdef.Aar, - SettingsMaskNdef.AarCustom, - SettingsMaskNdef.Uri - ).forEach { createItem(block, it) } - return block - } - - private fun pins(): Block { - val block = createBlock(BlockId.Pins) - mutableListOf(Pins.Pin, Pins.Pin2, Pins.Pin3, Pins.Cvc, Pins.PauseBeforePin2) - .forEach { createItem(block, it) } - return block - } - - private fun createBlock(id: Id): ListItemBlock { - return ListItemBlock(id).apply { addItem(TextItem(id)) } - } - - private fun addPayload(block: Block, from: PersonalizationConfig) { - block.payload[PayloadKey.incomingJson] = from - } - - private fun createItem(block: ListItemBlock, id: Id) { - val holder = valuesHolder.get(id) ?: return - val item = when { - itemTypes.blockIdList.contains(id) -> TextItem(id, holder.get() as? String) - itemTypes.listItemList.contains(id) -> ListItem(id, holder.list as List, holder.get()) - itemTypes.boolList.contains(id) -> BoolItem(id, holder.get() as? Boolean) - itemTypes.editTextList.contains(id) -> EditTextItem(id, holder.get() as? String) - itemTypes.numberList.contains(id) -> NumberItem(id, holder.get() as? Number) - else -> ListItemBlock(Additional.UNDEFINED) - } - block.addItem(item) - } -} - -class PersonalizeConfigToCardConfig : Converter { - - override fun convert(from: PersonalizationConfig): CardConfig { - val signingMethod = com.tangem.commands.SigningMethod.build( - signHash = from.SigningMethod0, - signRaw = from.SigningMethod1, - signHashValidatedByIssuer = from.SigningMethod2, - signRawValidatedByIssuer = from.SigningMethod3, - signHashValidatedByIssuerAndWriteIssuerData = from.SigningMethod4, - signRawValidatedByIssuerAndWriteIssuerData = from.SigningMethod5, - signPos = from.SigningMethod6 - ) - - val isNote = from.cardData.product_note - val isTag = from.cardData.product_tag - val isIdCard = from.cardData.product_id_card - val isIdIssuer = from.cardData.product_id_issuer - - val productMaskBuilder = ProductMaskBuilder() - if (isNote) productMaskBuilder.add(com.tangem.commands.ProductMask.note) - if (isTag) productMaskBuilder.add(com.tangem.commands.ProductMask.tag) - if (isIdCard) productMaskBuilder.add(com.tangem.commands.ProductMask.idCard) - if (isIdIssuer) productMaskBuilder.add(com.tangem.commands.ProductMask.idIssuer) - val productMask = productMaskBuilder.build() - - var tokenSymbol: String? = null - var tokenContractAddress: String? = null - var tokenDecimal: Int? = null - if (from.itsToken) { - tokenSymbol = from.symbol - tokenContractAddress = from.contractAddress - tokenDecimal = from.decimal.toInt() - } - - val blockchain = if (from.blockchain.isNotEmpty()) from.blockchain else from.blockchainCustom - val cardData = CardData( - blockchainName = blockchain, - batchId = from.batchId, - productMask = productMask, - tokenSymbol = tokenSymbol, - tokenContractAddress = tokenContractAddress, - tokenDecimal = tokenDecimal, - issuerName = null, - manufactureDateTime = Calendar.getInstance().time, - manufacturerSignature = null) - - - val ndefs = mutableListOf() - if (from.uri.isNotEmpty()) { - ndefs.add(NdefRecord(NdefRecord.Type.URI, from.uri)) - } - when (from.aar) { - "None" -> null - "--- CUSTOM ---" -> NdefRecord(NdefRecord.Type.AAR, from.aarCustom) - else -> NdefRecord(NdefRecord.Type.AAR, from.aar) - }?.let { ndefs.add(it) } - - return CardConfig( - "Tangem", - "Tangem Test", - from.series, - from.startNumber, - 1000, - from.PIN, - from.PIN2, - from.PIN3, - from.hexCrExKey, - from.CVC, - from.pauseBeforePIN2.toInt(), - from.smartSecurityDelay, - EllipticCurve.byName(from.curveID) ?: EllipticCurve.Secp256k1, - signingMethod, - from.MaxSignatures.toInt(), - from.isReusable, - from.allowSwapPIN, - from.allowSwapPIN2, - from.useActivation, - from.useCVC, - from.useNDEF, - from.useDynamicNDEF, - from.oneApdu, - from.useBlock, - from.allowSelectBlockchain, - from.forbidPurgeWallet, - from.protocolAllowUnencrypted, - from.protocolAllowStaticEncryption, - from.protectIssuerDataAgainstReplay, - from.forbidDefaultPIN, - from.disablePrecomputedNDEF, - from.skipSecurityDelayIfValidatedByIssuer, - from.skipCheckPIN2andCVCIfValidatedByIssuer, - from.skipSecurityDelayIfValidatedByLinkedTerminal, - from.restrictOverwriteIssuerDataEx, - from.requireTerminalTxSignature, - from.requireTerminalCertSignature, - from.checkPIN3onCard, - from.createWallet, - cardData, - ndefs - ) - } -} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/BaseAppWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/BaseAppWidget.kt new file mode 100644 index 0000000000..60ab69c243 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/BaseAppWidget.kt @@ -0,0 +1,28 @@ +package com.tangem.tangemtest.ucase.variants.personalize.ui.widgets + +import android.view.ViewGroup +import com.tangem.tangemtest._arch.structure.StringId +import com.tangem.tangemtest._arch.structure.StringResId +import com.tangem.tangemtest._arch.structure.abstraction.Item +import com.tangem.tangemtest._arch.widget.abstraction.BaseViewWidget +import com.tangem.tangemtest._arch.widget.abstraction.ViewWidget +import com.tangem.tangemtest.ucase.resources.MainResourceHolder +import com.tangem.tangemtest.ucase.resources.Resources +import ru.dev.gbixahue.eu4d.lib.android._android.views.stringFrom + +/** +[REDACTED_AUTHOR] + */ +abstract class BaseAppWidget(parent: ViewGroup, item: Item): BaseViewWidget(parent, item) { + override fun getName(): String { + return when (val id = item.id) { + is StringId -> id.value + is StringResId -> view.stringFrom(id.value) + else -> view.stringFrom(getResNameId()) + } + } +} + +fun ViewWidget.getResNameId(): Int = MainResourceHolder.safeGet(item.id).resName + +fun ViewWidget.getResDescription(): Int? = MainResourceHolder.safeGet(item.id).resDescription \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/DescriptionWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/DescriptionWidget.kt index 9dfff32c48..0e49f54ec5 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/DescriptionWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/DescriptionWidget.kt @@ -5,29 +5,27 @@ import android.widget.TextView import androidx.transition.AutoTransition import androidx.transition.TransitionManager import com.tangem.tangemtest.R -import com.tangem.tangemtest._arch.structure.abstraction.BaseItem -import com.tangem.tangemtest._arch.widget.abstraction.BaseWidget -import com.tangem.tangemtest._arch.widget.abstraction.getResDescription +import com.tangem.tangemtest._arch.structure.abstraction.Item import ru.dev.gbixahue.eu4d.lib.android.global.log.Log /** [REDACTED_AUTHOR] */ -abstract class DescriptionWidget( +abstract class DescriptionWidget( parent: ViewGroup, - data: BaseItem -) : BaseWidget(parent, data) { + item: Item +) : BaseAppWidget(parent, item) { private val descriptionContainer: ViewGroup by lazy { view.findViewById(R.id.container_description) } private val tvDescription: TextView? by lazy { descriptionContainer.findViewById(R.id.tv_description) } init { - Log.d(this, "init id: ${dataItem.id}") + Log.d(this, "init id: ${item.id}") initDescriptionWidget() } private fun initDescriptionWidget() { - dataItem.viewModel.viewState.onDescriptionVisibilityChanged = { changeDescriptionVisibility(it) } + item.viewModel.viewState.onDescriptionVisibilityChanged = { changeDescriptionVisibility(it) } } protected open fun changeDescriptionVisibility(state: Int) { diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/EditTextWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/EditTextWidget.kt index 9cb1061414..df0951947d 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/EditTextWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/EditTextWidget.kt @@ -7,14 +7,17 @@ import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import com.tangem.tangemtest.R import com.tangem.tangemtest._arch.structure.impl.EditTextItem -import com.tangem.tangemtest._arch.widget.abstraction.getName import ru.dev.gbixahue.eu4d.lib.android._android.views.moveCursorToEnd import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf /** [REDACTED_AUTHOR] */ -class EditTextWidget(parent: ViewGroup, data: EditTextItem) : DescriptionWidget(parent, data) { +class EditTextWidget( + parent: ViewGroup, + private val typedItem: EditTextItem +) : DescriptionWidget(parent, typedItem) { + override fun getLayoutId(): Int = R.layout.w_personalize_item_edit_text private val tilItem = view.findViewById(R.id.til_item) @@ -22,7 +25,7 @@ class EditTextWidget(parent: ViewGroup, data: EditTextItem) : DescriptionWidget< private val watcher = object : TextWatcher { override fun afterTextChanged(s: Editable?) { - dataItem.viewModel.updateDataByView(stringOf(s)) + typedItem.viewModel.updateDataByView(stringOf(s)) } override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} @@ -31,9 +34,9 @@ class EditTextWidget(parent: ViewGroup, data: EditTextItem) : DescriptionWidget< init { tilItem.hint = getName() - etItem.setText(dataItem.getData()) + etItem.setText(typedItem.getTypedData()) etItem.addTextChangedListener(watcher) - dataItem.viewModel.onDataUpdated = { silentUpdate(it) } + item.viewModel.onDataUpdated = { silentUpdate(it as? String) } } private fun silentUpdate(value: String?) { diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/BlockHeadWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/GroupTitleWidget.kt similarity index 72% rename from tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/BlockHeadWidget.kt rename to tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/GroupTitleWidget.kt index 4b0837723b..27167508ad 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/BlockHeadWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/GroupTitleWidget.kt @@ -4,12 +4,11 @@ import android.view.ViewGroup import android.widget.TextView import com.tangem.tangemtest.R import com.tangem.tangemtest._arch.structure.impl.TextItem -import com.tangem.tangemtest._arch.widget.abstraction.getName /** [REDACTED_AUTHOR] */ -class BlockHeadWidget(parent: ViewGroup, data: TextItem) : DescriptionWidget(parent, data) { +class GroupTitleWidget(parent: ViewGroup, data: TextItem) : DescriptionWidget(parent, data) { override fun getLayoutId(): Int = R.layout.w_personalize_item_text private val tvName = view.findViewById(R.id.tv_name) diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/NumberWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/NumberWidget.kt index e2702465a4..61cab1f430 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/NumberWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/NumberWidget.kt @@ -8,7 +8,6 @@ import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import com.tangem.tangemtest.R import com.tangem.tangemtest._arch.structure.impl.NumberItem -import com.tangem.tangemtest._arch.widget.abstraction.getName import com.tangem.tangemtest.ucase.variants.personalize.CardNumber import ru.dev.gbixahue.eu4d.lib.android._android.views.addInputFilter import ru.dev.gbixahue.eu4d.lib.android._android.views.moveCursorToEnd @@ -17,7 +16,11 @@ import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf /** [REDACTED_AUTHOR] */ -class NumberWidget(parent: ViewGroup, data: NumberItem) : DescriptionWidget(parent, data) { +class NumberWidget( + parent: ViewGroup, + private val typedItem: NumberItem +) : DescriptionWidget(parent, typedItem) { + override fun getLayoutId(): Int = R.layout.w_personalize_item_number private val tilItem = view.findViewById(R.id.til_item) @@ -25,7 +28,7 @@ class NumberWidget(parent: ViewGroup, data: NumberItem) : DescriptionWidget, parent: ViewGroup): ViewWidget? { + override fun build(item: BaseItem, parent: ViewGroup): ViewWidget? { return when (item) { - is TextItem -> BlockHeadWidget(parent, item) + is TextItem -> GroupTitleWidget(parent, item) is EditTextItem -> EditTextWidget(parent, item) is NumberItem -> NumberWidget(parent, item) is BoolItem -> SwitchWidget(parent, item) - is ListItem -> SpinnerWidget(parent, item) + is SpinnerItem -> SpinnerWidget(parent, item) else -> null } } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/SpinnerWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/SpinnerWidget.kt index d4e2b2fb40..757634df6d 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/SpinnerWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/SpinnerWidget.kt @@ -7,20 +7,23 @@ import android.widget.BaseAdapter import android.widget.Spinner import android.widget.TextView import com.tangem.tangemtest.R -import com.tangem.tangemtest._arch.structure.impl.KeyValue -import com.tangem.tangemtest._arch.structure.impl.ListItem -import com.tangem.tangemtest._arch.structure.impl.ListValueWrapper -import com.tangem.tangemtest._arch.widget.abstraction.getName +import com.tangem.tangemtest._arch.structure.abstraction.KeyValue +import com.tangem.tangemtest._arch.structure.abstraction.ListViewModel +import com.tangem.tangemtest._arch.structure.impl.SpinnerItem import ru.dev.gbixahue.eu4d.lib.android._android.views.inflate import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf /** [REDACTED_AUTHOR] */ -class SpinnerWidget(parent: ViewGroup, listItem: ListItem) : DescriptionWidget(parent, listItem) { +class SpinnerWidget( + parent: ViewGroup, + private val typedItem: SpinnerItem +) : DescriptionWidget(parent, typedItem) { + override fun getLayoutId(): Int = R.layout.w_personalize_item_spinner - private val data: ListValueWrapper = listItem.getData()!! + private val data: ListViewModel = typedItem.getTypedData()!! private val spItem = view.findViewById(R.id.sp_item) private val spAdapter = SpItemAdapter(data.itemList) @@ -30,7 +33,7 @@ class SpinnerWidget(parent: ViewGroup, listItem: ListItem) : DescriptionWidget?, view: View?, position: Int, id: Long) { data.selectedItem = data.itemList[position].value - dataItem.viewModel.updateDataByView(data) + typedItem.viewModel.updateDataByView(data) } } @@ -42,15 +45,14 @@ class SpinnerWidget(parent: ViewGroup, listItem: ListItem) : DescriptionWidget item.value == selectedItem }?.let { - val position = itemList.indexOf(it) - spItem.setSelection(position) - } - spItem.onItemSelectedListener = onItemSelectedListener + typedItem.viewModel.onDataUpdated = { + val selectedItem = it as? String + spItem.onItemSelectedListener = null + data.itemList.firstOrNull { item -> item.value == selectedItem }?.let { keyValue -> + val position = data.itemList.indexOf(keyValue) + spItem.setSelection(position) } + spItem.onItemSelectedListener = onItemSelectedListener } } } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/SwitchWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/SwitchWidget.kt index 015ea477b2..ffa0b6879b 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/SwitchWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/ui/widgets/SwitchWidget.kt @@ -5,27 +5,30 @@ import android.widget.CompoundButton import androidx.appcompat.widget.SwitchCompat import com.tangem.tangemtest.R import com.tangem.tangemtest._arch.structure.impl.BoolItem -import com.tangem.tangemtest._arch.widget.abstraction.getName /** [REDACTED_AUTHOR] */ -class SwitchWidget(parent: ViewGroup, data: BoolItem) : DescriptionWidget(parent, data) { +class SwitchWidget( + parent: ViewGroup, + private val typedItem: BoolItem +) : DescriptionWidget(parent, typedItem) { + override fun getLayoutId(): Int = R.layout.w_personalize_item_switch private val switchItem = view.findViewById(R.id.sw_item) private val changeListener = CompoundButton.OnCheckedChangeListener { buttonView, isChecked -> - dataItem.viewModel.updateDataByView(isChecked) + typedItem.viewModel.updateDataByView(isChecked) } init { switchItem.text = getName() - switchItem.isChecked = dataItem.getData() ?: false + switchItem.isChecked = typedItem.getTypedData() ?: false switchItem.setOnCheckedChangeListener(changeListener) - dataItem.viewModel.onDataUpdated = { + typedItem.viewModel.onDataUpdated = { switchItem.setOnCheckedChangeListener(null) - switchItem.isChecked = it ?: false + switchItem.isChecked = it as? Boolean ?: false switchItem.setOnCheckedChangeListener(changeListener) } } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ResponseViewModel.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ResponseViewModel.kt index ced5ffa144..50e8df7aa2 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ResponseViewModel.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ResponseViewModel.kt @@ -2,7 +2,6 @@ package com.tangem.tangemtest.ucase.variants.responses import android.view.View import androidx.lifecycle.ViewModel -import com.tangem.tangemtest._arch.structure.abstraction.BaseItem import com.tangem.tangemtest._arch.structure.abstraction.Item import com.tangem.tangemtest._arch.structure.abstraction.ModelToItems import com.tangem.tangemtest._arch.structure.abstraction.iterate @@ -30,8 +29,7 @@ class ResponseViewModel : ViewModel() { fun toggleDescriptionVisibility(state: Boolean) { itemList?.iterate { - val baseItem = it as? BaseItem<*> ?: return@iterate - baseItem.viewModel.viewState.descriptionVisibility = if (state) View.VISIBLE else View.GONE + it.viewModel.viewState.descriptionVisibility = if (state) View.VISIBLE else View.GONE } } } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/converter/CardConverter.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/converter/CardConverter.kt index 492989ebe1..007cf07543 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/converter/CardConverter.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/converter/CardConverter.kt @@ -6,8 +6,9 @@ import com.tangem.commands.SettingsMask import com.tangem.tangemtest._arch.structure.Id import com.tangem.tangemtest._arch.structure.StringId import com.tangem.tangemtest._arch.structure.abstraction.Item -import com.tangem.tangemtest._arch.structure.abstraction.ListItemBlock +import com.tangem.tangemtest._arch.structure.abstraction.ItemGroup import com.tangem.tangemtest._arch.structure.abstraction.ModelToItems +import com.tangem.tangemtest._arch.structure.abstraction.SimpleItemGroup import com.tangem.tangemtest._arch.structure.impl.BoolItem import com.tangem.tangemtest._arch.structure.impl.TextItem import com.tangem.tangemtest.ucase.variants.personalize.BlockId @@ -31,55 +32,53 @@ class CardConverter : ModelToItems { } private fun simpleFields(from: Card): Item { - val block = createBlock(BlockId.Common) - block.addItem(TextItem(CardId.cardId, from.cardId)) - block.addItem(TextItem(CardId.manufacturerName, from.manufacturerName)) - block.addItem(TextItem(CardId.status, stringOf(from.status))) - block.addItem(TextItem(CardId.firmwareVersion, from.firmwareVersion)) - block.addItem(TextItem(CardId.cardPublicKey, stringOf(from.cardPublicKey))) - block.addItem(TextItem(CardId.issuerPublicKey, stringOf(from.issuerPublicKey))) - block.addItem(TextItem(CardId.curve, stringOf(from.curve))) - block.addItem(TextItem(CardId.maxSignatures, stringOf(from.maxSignatures))) - block.addItem(TextItem(CardId.signingMethod, stringOf(from.signingMethod))) - block.addItem(TextItem(CardId.pauseBeforePin2, stringOf(from.pauseBeforePin2))) - block.addItem(TextItem(CardId.walletPublicKey, stringOf(from.walletPublicKey))) - block.addItem(TextItem(CardId.walletRemainingSignatures, stringOf(from.walletRemainingSignatures))) - block.addItem(TextItem(CardId.walletSignedHashes, stringOf(from.walletSignedHashes))) - block.addItem(TextItem(CardId.health, stringOf(from.health))) - block.addItem(TextItem(CardId.isActivated, stringOf(from.isActivated))) - block.addItem(TextItem(CardId.activationSeed, stringOf(from.activationSeed))) - block.addItem(TextItem(CardId.paymentFlowVersion, stringOf(from.paymentFlowVersion))) - block.addItem(TextItem(CardId.userCounter, stringOf(from.userCounter))) + val group = createGroup(BlockId.Common) + group.addItem(TextItem(CardId.cardId, from.cardId)) + group.addItem(TextItem(CardId.manufacturerName, from.manufacturerName)) + group.addItem(TextItem(CardId.status, stringOf(from.status))) + group.addItem(TextItem(CardId.firmwareVersion, from.firmwareVersion)) + group.addItem(TextItem(CardId.cardPublicKey, stringOf(from.cardPublicKey))) + group.addItem(TextItem(CardId.issuerPublicKey, stringOf(from.issuerPublicKey))) + group.addItem(TextItem(CardId.curve, stringOf(from.curve))) + group.addItem(TextItem(CardId.maxSignatures, stringOf(from.maxSignatures))) + group.addItem(TextItem(CardId.signingMethod, stringOf(from.signingMethod))) + group.addItem(TextItem(CardId.pauseBeforePin2, stringOf(from.pauseBeforePin2))) + group.addItem(TextItem(CardId.walletPublicKey, stringOf(from.walletPublicKey))) + group.addItem(TextItem(CardId.walletRemainingSignatures, stringOf(from.walletRemainingSignatures))) + group.addItem(TextItem(CardId.walletSignedHashes, stringOf(from.walletSignedHashes))) + group.addItem(TextItem(CardId.health, stringOf(from.health))) + group.addItem(TextItem(CardId.isActivated, stringOf(from.isActivated))) + group.addItem(TextItem(CardId.activationSeed, stringOf(from.activationSeed))) + group.addItem(TextItem(CardId.paymentFlowVersion, stringOf(from.paymentFlowVersion))) + group.addItem(TextItem(CardId.userCounter, stringOf(from.userCounter))) // block.addItem(TextItem(CardId.UserProtectedCounter, stringOf(from.userProtectedCounter))) - return block + return group } private fun cardData(from: Card): Item { - val block = createBlock(BlockId.Common) - val data = from.cardData ?: return block - - val itemList = block.itemList - itemList.add(TextItem(CardDataId.batchId, data.batchId)) + val group = createGroup(BlockId.Common) + val data = from.cardData ?: return group + group.addItem(TextItem(CardDataId.batchId, data.batchId)) // Format: Year (2 bytes) | Month (1 byte) | Day (1 byte) - itemList.add(TextItem(CardDataId.manufactureDateTime, stringOf(data.manufactureDateTime))) - itemList.add(TextItem(CardDataId.issuerName, data.issuerName)) - itemList.add(TextItem(CardDataId.blockchainName, data.blockchainName)) - itemList.add(TextItem(CardDataId.manufacturerSignature, stringOf(data.manufacturerSignature))) - itemList.add(TextItem(CardDataId.productMask, stringOf(data.productMask))) - itemList.add(TextItem(CardDataId.tokenSymbol, data.tokenSymbol)) - itemList.add(TextItem(CardDataId.tokenContractAddress, data.tokenContractAddress)) - itemList.add(TextItem(CardDataId.tokenDecimal, data.tokenSymbol)) + group.addItem(TextItem(CardDataId.manufactureDateTime, stringOf(data.manufactureDateTime))) + group.addItem(TextItem(CardDataId.issuerName, data.issuerName)) + group.addItem(TextItem(CardDataId.blockchainName, data.blockchainName)) + group.addItem(TextItem(CardDataId.manufacturerSignature, stringOf(data.manufacturerSignature))) + group.addItem(TextItem(CardDataId.productMask, stringOf(data.productMask))) + group.addItem(TextItem(CardDataId.tokenSymbol, data.tokenSymbol)) + group.addItem(TextItem(CardDataId.tokenContractAddress, data.tokenContractAddress)) + group.addItem(TextItem(CardDataId.tokenDecimal, data.tokenSymbol)) - return block + return group } private fun settingsMask(from: SettingsMask?): Item { - val block = createBlock(CardId.settingsMask) - val data = from ?: return block + val group = createGroup(CardId.settingsMask) + val data = from ?: return group - Settings.values().forEach { block.addItem(BoolItem(StringId(it.name), data.contains(it))) } - return block + Settings.values().forEach { group.addItem(BoolItem(StringId(it.name), data.contains(it))) } + return group } - private fun createBlock(id: Id): ListItemBlock = ListItemBlock(id).apply { addItem(TextItem(id)) } + private fun createGroup(id: Id): ItemGroup = SimpleItemGroup(id).apply { addItem(TextItem(id)) } } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ui/widget/CheckBoxWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ui/widget/CheckBoxWidget.kt index 5350ab0135..a988a93948 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ui/widget/CheckBoxWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ui/widget/CheckBoxWidget.kt @@ -4,21 +4,24 @@ import android.view.ViewGroup import com.google.android.material.checkbox.MaterialCheckBox import com.tangem.tangemtest.R import com.tangem.tangemtest._arch.structure.impl.BoolItem -import com.tangem.tangemtest._arch.widget.abstraction.getName import com.tangem.tangemtest.ucase.variants.personalize.ui.widgets.DescriptionWidget import ru.dev.gbixahue.eu4d.lib.android._android.views.colorFrom /** [REDACTED_AUTHOR] */ -class CheckBoxWidget(parent: ViewGroup, private val boolItem: BoolItem) : DescriptionWidget(parent, boolItem) { +class CheckBoxWidget( + parent: ViewGroup, + private val typedItem: BoolItem +) : DescriptionWidget(parent, typedItem) { + override fun getLayoutId(): Int = R.layout.w_response_item_checkbox private val switchItem = view.findViewById(R.id.sw_item) init { switchItem.text = getName() - switchItem.isChecked = dataItem.getData() ?: false + switchItem.isChecked = typedItem.getData() ?: false switchItem.isEnabled = false switchItem.setTextColor(switchItem.colorFrom(R.color.action_name)) } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ui/widget/ResponseItemBuilder.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ui/widget/ResponseItemBuilder.kt index cde044dc2c..051974e674 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ui/widget/ResponseItemBuilder.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ui/widget/ResponseItemBuilder.kt @@ -11,7 +11,7 @@ import com.tangem.tangemtest._arch.widget.abstraction.ViewWidget [REDACTED_AUTHOR] */ class ResponseItemBuilder : ItemWidgetBuilder { - override fun build(item: BaseItem<*>, parent: ViewGroup): ViewWidget? { + override fun build(item: BaseItem, parent: ViewGroup): ViewWidget? { return when (item) { is TextItem -> ResponseTextWidget(parent, item) is BoolItem -> CheckBoxWidget(parent, item) diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ui/widget/ResponseTextWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ui/widget/ResponseTextWidget.kt index 468b9963e7..a0d546f973 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ui/widget/ResponseTextWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/responses/ui/widget/ResponseTextWidget.kt @@ -8,13 +8,16 @@ import android.view.ViewGroup import android.widget.TextView import com.tangem.tangemtest.R import com.tangem.tangemtest._arch.structure.impl.TextItem -import com.tangem.tangemtest._arch.widget.abstraction.getName import com.tangem.tangemtest.ucase.variants.personalize.ui.widgets.DescriptionWidget /** [REDACTED_AUTHOR] */ -class ResponseTextWidget(parent: ViewGroup, private val textItem: TextItem) : DescriptionWidget(parent, textItem) { +class ResponseTextWidget( + parent: ViewGroup, + private val typedItem: TextItem +) : DescriptionWidget(parent, typedItem) { + override fun getLayoutId(): Int = R.layout.w_response_item private val tvName: TextView = view.findViewById(R.id.tv_name) @@ -25,7 +28,7 @@ class ResponseTextWidget(parent: ViewGroup, private val textItem: TextItem) : De } private fun initWidgets() { - val data = textItem.getData() + val data = typedItem.getData() as? String if (data == null || data.isEmpty()) { view.visibility = View.GONE return @@ -38,7 +41,7 @@ class ResponseTextWidget(parent: ViewGroup, private val textItem: TextItem) : De val clipboard = view.context.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager ?: return@setOnClickListener - val clip: ClipData = ClipData.newPlainText("FieldValue", "${dataItem.getData()}") + val clip: ClipData = ClipData.newPlainText("FieldValue", "$data") clipboard.setPrimaryClip(clip) } }