Updated on 2026-08-14

This commit is contained in:
Tangem 2020-03-24 23:52:05 +03:00
parent 875e220c61
commit 7f7c0b24ce
46 changed files with 1013 additions and 763 deletions

View file

@ -22,7 +22,7 @@ open class ListUnitBlock(
) : BaseBlock(), ItemListHolder<Unit> {
override fun setItems(list: MutableList<Unit>) {
ULog.d(this, "setUnits: $id, ${list.size}")
ULog.d(this, "setItems into: $id, count: ${list.size}")
unitList.clear()
unitList.addAll(list)
unitList.forEach { it.parent = this }
@ -30,25 +30,24 @@ open class ListUnitBlock(
}
override fun getItems(): MutableList<Unit> {
ULog.d(this, "getUnits: $id, ${unitList.size}")
return unitList
}
override fun addItem(item: Unit) {
ULog.d(this, "addUnit: $id, ${unitList.size}")
ULog.d(this, "addIte into: $id, who: ${item.id}")
item.parent = this
unitList.add(item)
blockModified?.invoke()
}
override fun removeItem(item: Unit) {
ULog.d(this, "removeUnit $item")
ULog.d(this, "removeItem from: $id, which: ${item.id}")
unitList.remove(item)
blockModified?.invoke()
}
override fun clear() {
ULog.d(this, "clear")
ULog.d(this, "clear $id")
unitList.clear()
blockModified?.invoke()
}

View file

@ -4,28 +4,50 @@ package com.tangem.tangemtest._arch.structure.base
/**
[REDACTED_AUTHOR]
*/
data class ViewState(
var isEnabled: Boolean = true,
var visibility: Int = 0x00000000,
var descriptionVisibility: Int = 0x00000008
)
typealias ValueChange<V> = (V?) -> kotlin.Unit
typealias SafeValueChange<V> = (V) -> kotlin.Unit
interface UnitViewModel<D> : Payload {
var viewState: ViewState?
val viewState: ViewState
var data: D?
var onDataUpdated: ValueChange<D>?
fun updateData(data: D?)
fun updateDataByView(data: D?)
}
open class BaseUnitViewModel<D>(
override var data: D? = null
) : UnitViewModel<D> {
open class BaseUnitViewModel<D> : UnitViewModel<D> {
override var viewState: ViewState? = ViewState()
override val viewState: ViewState = ViewState()
override val payload: MutableMap<String, Any?> = mutableMapOf()
override fun updateData(data: D?) {
ULog.d(this, "data changed: $data")
this.data = data
override var data: D? = null
set(value) {
if (handleDataUpdates(value)) field = value
}
override var onDataUpdated: ValueChange<D>? = null
protected open fun handleDataUpdates(value: D?): Boolean {
ULog.d(this, "handleDateUpdates: $value")
onDataUpdated?.invoke(value)
return true
}
override fun updateDataByView(data: D?) {
ULog.d(this, "data changed: $data")
val callback = onDataUpdated
onDataUpdated = null
this.data = data
onDataUpdated = callback
}
}
class ViewState {
var descriptionVisibility: Int = 0x00000008
set(value) {
field = value
onDescriptionVisibilityChanged?.invoke(value)
}
var onDescriptionVisibilityChanged: SafeValueChange<Int>? = null
}

View file

@ -10,10 +10,5 @@ class NumberUnit(override val id: Id, value: Number? = null) : DataUnit<Number>(
class BoolUnit(override val id: Id, value: Boolean? = null) : DataUnit<Boolean>(BoolViewModel(value))
class ListUnit(override val id: Id, value: List<KeyValue>, selectedValue: Any)
: DataUnit<ModelHelper>(ListViewModel(ModelHelper(selectedValue, value))
)
fun DataUnit<*>.resName(resId: Int): DataUnit<*> {
payload["resName"] = resId
return this
}
: DataUnit<ListValueWrapper>(ListViewModel(ListValueWrapper(selectedValue, value))
)

View file

@ -5,10 +5,25 @@ import com.tangem.tangemtest._arch.structure.base.BaseUnitViewModel
/**
[REDACTED_AUTHOR]
*/
class StringViewModel(value: String?) : BaseUnitViewModel<String>(value)
class NumberViewModel(value: Number?) : BaseUnitViewModel<Number>(value)
class BoolViewModel(value: Boolean?) : BaseUnitViewModel<Boolean>(value)
class ListViewModel(value: ModelHelper?) : BaseUnitViewModel<ModelHelper>(value)
open class TransitiveViewModel<D>(value: D?) : BaseUnitViewModel<D>() {
init {
data = value
}
}
class StringViewModel(value: String?) : TransitiveViewModel<String>(value)
class NumberViewModel(value: Number?) : TransitiveViewModel<Number>(value)
class BoolViewModel(value: Boolean?) : TransitiveViewModel<Boolean>(value)
class ListViewModel(value: ListValueWrapper?) : TransitiveViewModel<ListValueWrapper>(value) {
override fun handleDataUpdates(value: ListValueWrapper?): Boolean {
val newValue = value ?: return false
if (newValue.selectedItem == data?.selectedItem) return false
onDataUpdated?.invoke(value)
return true
}
}
class KeyValue(val key: String, val value: Any)
class ModelHelper(var selectedItem: Any, val itemList: List<KeyValue>)
class ListValueWrapper(var selectedItem: Any, val itemList: List<KeyValue>)

View file

@ -3,7 +3,10 @@ package com.tangem.tangemtest._main
import android.content.res.Resources
import android.os.Bundle
import android.util.Log
import android.view.Menu
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SwitchCompat
import androidx.appcompat.widget.Toolbar
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
@ -16,6 +19,8 @@ import com.tangem.tangemtest.R
* A simple activity demonstrating use of a NavHostFragment with a navigation drawer.
*/
class MainActivity : AppCompatActivity() {
private val vm: MainViewModel by viewModels<MainViewModel>()
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
@ -45,4 +50,13 @@ class MainActivity : AppCompatActivity() {
override fun onSupportNavigateUp(): Boolean {
return findNavController(R.id.nav_host_fragment).navigateUp(appBarConfiguration)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main_menu, menu)
val switchMenu = menu.findItem(R.id.action_favorite)
(switchMenu.actionView as? SwitchCompat)?.let {
it.setOnCheckedChangeListener { buttonView, isChecked -> vm.switchToggled(isChecked) }
}
return super.onCreateOptionsMenu(menu)
}
}

View file

@ -0,0 +1,15 @@
package com.tangem.tangemtest._main
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
/**
[REDACTED_AUTHOR]
*/
class MainViewModel : ViewModel() {
val ldDescriptionSwitch = MutableLiveData<Boolean>(false)
fun switchToggled(state: Boolean) {
ldDescriptionSwitch.postValue(state)
}
}

View file

@ -5,18 +5,19 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import androidx.navigation.NavController
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.tangem.tangemtest.R
import com.tangem.tangemtest._main.MainViewModel
import com.tangem.tangemtest.commons.ActionType
import com.tangem.tangemtest.commons.NavigateOptions
import com.tangem.tangemtest.commons.getDefaultNavigationOptions
import kotlinx.android.synthetic.main.fg_entry_point.*
import ru.dev.gbixahue.eu4d.lib.android._android.views.find
/**
[REDACTED_AUTHOR]
@ -26,6 +27,8 @@ class EntryPointFragment : Fragment() {
private val navController: NavController by lazy { findNavController() }
private lateinit var rvActions: RecyclerView
private val mainActivityVM: MainViewModel by activityViewModels()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fg_entry_point, container, false)
}
@ -33,13 +36,10 @@ class EntryPointFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initRecyclerView()
initPersonalizeNagivation()
}
private fun initPersonalizeNagivation() {
view?.find<ExtendedFloatingActionButton>(R.id.fab_personalize)?.setOnClickListener {
navigate(R.id.action_nav_entry_point_to_nav_personalize)
}
mainActivityVM.ldDescriptionSwitch.observe(viewLifecycleOwner, Observer {
// do some thing
})
}
private fun initRecyclerView() {
@ -66,6 +66,7 @@ class EntryPointFragment : Fragment() {
return mutableListOf(
NavigateOptions(ActionType.Scan, R.id.action_nav_entry_point_to_nav_scan),
NavigateOptions(ActionType.Sign, R.id.action_nav_entry_point_to_nav_sign),
NavigateOptions(ActionType.Personalize, R.id.action_nav_entry_point_to_nav_personalize),
NavigateOptions(ActionType.CreateWallet, R.id.action_nav_entry_point_to_nav_wallet_create),
NavigateOptions(ActionType.PurgeWallet, R.id.action_nav_entry_point_to_nav_wallet_purge),
NavigateOptions(ActionType.ReadIssuerData, R.id.action_nav_entry_point_to_nav_issuer_read_data),

View file

@ -1,4 +1,4 @@
package com.tangem.tangemtest.card_use_cases.ui.card_action
package com.tangem.tangemtest.card_use_cases.ui.card
import android.os.Bundle
import android.view.LayoutInflater
@ -17,9 +17,9 @@ import com.tangem.tangem_sdk_new.extensions.init
import com.tangem.tangemtest.R
import com.tangem.tangemtest.card_use_cases.domain.params_manager.ParamsManager
import com.tangem.tangemtest.card_use_cases.domain.params_manager.ParamsManagerFactory
import com.tangem.tangemtest.card_use_cases.ui.card_action.widgets.ParameterWidget
import com.tangem.tangemtest.card_use_cases.view_models.ActionViewModelFactory
import com.tangem.tangemtest.card_use_cases.view_models.ParamsViewModel
import com.tangem.tangemtest.card_use_cases.ui.card.actions.ActionViewModelFactory
import com.tangem.tangemtest.card_use_cases.ui.card.actions.ParamsViewModel
import com.tangem.tangemtest.card_use_cases.ui.card.actions.widgets.ParameterWidget
import com.tangem.tangemtest.commons.ActionType
import ru.dev.gbixahue.eu4d.lib.android._android.views.find
import ru.dev.gbixahue.eu4d.lib.android.global.log.Log

View file

@ -1,4 +1,4 @@
package com.tangem.tangemtest.card_use_cases.view_models
package com.tangem.tangemtest.card_use_cases.ui.card.actions
import androidx.annotation.UiThread
import androidx.lifecycle.MutableLiveData

View file

@ -1,6 +1,7 @@
package com.tangem.tangemtest.card_use_cases.ui.card_action
package com.tangem.tangemtest.card_use_cases.ui.card.actions
import com.tangem.tangemtest.R
import com.tangem.tangemtest.card_use_cases.ui.card.BaseCardActionFragment
import com.tangem.tangemtest.commons.ActionType
/**

View file

@ -1,6 +1,7 @@
package com.tangem.tangemtest.card_use_cases.ui.card_action
package com.tangem.tangemtest.card_use_cases.ui.card.actions
import com.tangem.tangemtest.R
import com.tangem.tangemtest.card_use_cases.ui.card.BaseCardActionFragment
import com.tangem.tangemtest.commons.ActionType
/**

View file

@ -1,4 +1,4 @@
package com.tangem.tangemtest.card_use_cases.ui.card_action.widgets
package com.tangem.tangemtest.card_use_cases.ui.card.actions.widgets
import android.text.Editable
import android.text.TextWatcher

View file

@ -7,11 +7,11 @@ import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import com.tangem.tangemtest.R
import com.tangem.tangemtest.card_use_cases.ui.personalize.view_model.PersonalizeViewModel
import com.tangem.tangemtest.card_use_cases.ui.personalize.view_model.PersonalizeViewModelFactory
import com.tangem.tangemtest._main.MainViewModel
import com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.WidgetBuilder
import ru.dev.gbixahue.eu4d.lib.android.global.log.Log
import java.io.IOException
@ -23,11 +23,13 @@ import java.nio.charset.Charset
*/
class PersonalizeFragment : Fragment() {
protected val blockContainer: ViewGroup by lazy {
private val mainActivityVM: MainViewModel by activityViewModels()
private val viewModel: PersonalizeViewModel by viewModels { PersonalizeViewModelFactory(getPersonalizeJson()) }
private val blockContainer: ViewGroup by lazy {
mainView.findViewById<LinearLayout>(R.id.ll_container)
}
protected val viewModel: PersonalizeViewModel by viewModels { PersonalizeViewModelFactory(getPersonalizeJson()) }
protected lateinit var mainView: View
private lateinit var mainView: View
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
Log.d(this, "onCreateView")
@ -40,7 +42,9 @@ class PersonalizeFragment : Fragment() {
viewModel.ldBlockList.observe(viewLifecycleOwner, Observer { blocList ->
blocList.forEach { WidgetBuilder().build(it, blockContainer) }
})
mainActivityVM.ldDescriptionSwitch.observe(viewLifecycleOwner, Observer {
viewModel.toggleDescriptionVisibility(it)
})
}

View file

@ -0,0 +1,339 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.base.*
/**
[REDACTED_AUTHOR]
*/
data class UnitResource(
val resName: Int,
val resDescription: Int? = null
)
object PersonalizeResources {
private val map = mutableMapOf<Id, UnitResource>()
init {
InfoInitializer().init(map)
}
fun get(id: Id): UnitResource = map[id] ?: UnitResource(R.string.unknown, R.string.unknown)
}
internal class InfoInitializer() {
fun init(map: MutableMap<Id, UnitResource>) {
initBlock(map)
initCardNumber(map)
initCommon(map)
initSigningMethod(map)
initSignHashExProp(map)
initDenomination(map)
initToken(map)
initProductMask(map)
initSettingsMask(map)
initSettingsMaskProtocolEnc(map)
initSettingsMaskNde(map)
initPins(map)
}
private fun initBlock(map: MutableMap<Id, UnitResource>) {
map[BlockId.CARD_NUMBER] = UnitResource(
R.string.pers_block_card_number,
R.string.info_pers_block_card_number
)
map[BlockId.COMMON] = UnitResource(
R.string.pers_block_common,
R.string.info_pers_block_common
)
map[BlockId.SIGNING_METHOD] = UnitResource(
R.string.pers_block_signing_method,
R.string.info_pers_block_signing_method
)
map[BlockId.SIGN_HASH_EX_PROP] = UnitResource(
R.string.pers_block_sign_hash_ex_prop,
R.string.info_pers_block_sign_hash_ex_prop
)
map[BlockId.DENOMINATION] = UnitResource(
R.string.pers_block_denomination,
R.string.info_pers_block_denomination
)
map[BlockId.TOKEN] = UnitResource(
R.string.pers_block_token,
R.string.info_pers_block_token
)
map[BlockId.PROD_MASK] = UnitResource(
R.string.pers_block_product_mask,
R.string.info_pers_block_product_mask
)
map[BlockId.SETTINGS_MASK] = UnitResource(
R.string.pers_block_settings_mask,
R.string.info_pers_block_settings_mask
)
map[BlockId.SETTINGS_MASK_PROTOCOL_ENC] = UnitResource(
R.string.pers_block_settings_mask_protocol_enc,
R.string.info_pers_block_settings_mask_protocol_enc
)
map[BlockId.SETTINGS_MASK_NDEF] = UnitResource(
R.string.pers_block_settings_mask_ndef,
R.string.info_pers_block_settings_mask_ndef
)
map[BlockId.PINS] = UnitResource(
R.string.pers_block_pins,
R.string.info_pers_block_pins
)
}
private fun initCardNumber(map: MutableMap<Id, UnitResource>) {
map[CardNumber.SERIES] = UnitResource(
R.string.pers_item_series,
R.string.info_pers_item_series
)
map[CardNumber.NUMBER] = UnitResource(
R.string.pers_item_number,
R.string.info_pers_item_number
)
}
private fun initCommon(map: MutableMap<Id, UnitResource>) {
map[Common.CURVE] = UnitResource(
R.string.pers_item_curve,
R.string.info_pers_item_curve
)
map[Common.BLOCKCHAIN] = UnitResource(
R.string.pers_item_blockchain,
R.string.info_pers_item_blockchain
)
map[Common.BLOCKCHAIN_CUSTOM] = UnitResource(
R.string.pers_item_custom_blockchain,
R.string.info_pers_item_custom_blockchain
)
map[Common.MAX_SIGNATURES] = UnitResource(
R.string.pers_item_max_signatures,
R.string.info_pers_item_max_signatures
)
map[Common.CREATE_WALLET] = UnitResource(
R.string.pers_item_create_wallet,
R.string.info_pers_item_create_wallet
)
}
private fun initSigningMethod(map: MutableMap<Id, UnitResource>) {
map[SigningMethod.SIGN_TX] = UnitResource(
R.string.pers_item_sign_tx_hashes,
R.string.info_pers_item_sign_tx_hashes
)
map[SigningMethod.SIGN_TX_RAW] = UnitResource(
R.string.pers_item_sign_raw_tx,
R.string.info_pers_item_sign_raw_tx
)
map[SigningMethod.SIGN_VALIDATED_TX] = UnitResource(
R.string.pers_item_sign_validated_tx_hashes,
R.string.info_pers_item_sign_validated_tx_hashes
)
map[SigningMethod.SIGN_VALIDATED_TX_RAW] = UnitResource(
R.string.pers_item_sign_validated_raw_tx,
R.string.info_pers_item_sign_validated_raw_tx
)
map[SigningMethod.SIGN_VALIDATED_TX_ISSUER] = UnitResource(
R.string.pers_item_sign_validated_tx_hashes_with_iss_data,
R.string.info_pers_item_sign_validated_tx_hashes_with_iss_data
)
map[SigningMethod.SIGN_VALIDATED_TX_RAW_ISSUER] = UnitResource(
R.string.pers_item_sign_validated_raw_tx_with_iss_data,
R.string.info_pers_item_sign_validated_raw_tx_with_iss_data
)
map[SigningMethod.SIGN_EXTERNAL] = UnitResource(
R.string.pers_item_sign_hash_ex,
R.string.info_pers_item_sign_hash_ex
)
}
private fun initSignHashExProp(map: MutableMap<Id, UnitResource>) {
map[SignHashExProp.PIN_LESS_FLOOR_LIMIT] = UnitResource(
R.string.pers_item_pin_less_floor_limit,
R.string.info_pers_item_pin_less_floor_limit
)
map[SignHashExProp.CRYPTO_EXTRACT_KEY] = UnitResource(
R.string.pers_item_cr_ex_key,
R.string.info_pers_item_cr_ex_key
)
map[SignHashExProp.REQUIRE_TERMINAL_CERT_SIG] = UnitResource(
R.string.pers_item_require_terminal_cert_sig,
R.string.info_pers_item_require_terminal_cert_sig
)
map[SignHashExProp.REQUIRE_TERMINAL_TX_SIG] = UnitResource(
R.string.pers_item_require_terminal_tx_sig,
R.string.info_pers_item_require_terminal_tx_sig
)
map[SignHashExProp.CHECK_PIN3] = UnitResource(
R.string.pers_item_pin3,
R.string.info_pers_item_pin3
)
}
private fun initDenomination(map: MutableMap<Id, UnitResource>) {
map[Denomination.WRITE_ON_PERSONALIZE] = UnitResource(
R.string.pers_item_write_on_personalize,
R.string.info_pers_item_write_on_personalize
)
map[Denomination.DENOMINATION] = UnitResource(
R.string.pers_item_denomination,
R.string.info_pers_item_denomination
)
}
private fun initToken(map: MutableMap<Id, UnitResource>) {
map[Token.ITS_TOKEN] = UnitResource(
R.string.pers_item_its_token,
R.string.info_pers_item_its_token
)
map[Token.SYMBOL] = UnitResource(
R.string.pers_item_symbol,
R.string.info_pers_item_symbol
)
map[Token.CONTRACT_ADDRESS] = UnitResource(
R.string.pers_item_contract_address,
R.string.info_pers_item_contract_address
)
map[Token.DECIMAL] = UnitResource(
R.string.pers_item_decimal,
R.string.info_pers_item_decimal
)
}
private fun initProductMask(map: MutableMap<Id, UnitResource>) {
map[ProductMask.NOTE] = UnitResource(
R.string.pers_item_note,
R.string.info_pers_item_note
)
map[ProductMask.TAG] = UnitResource(
R.string.pers_item_tag,
R.string.info_pers_item_tag
)
map[ProductMask.ID_CARD] = UnitResource(
R.string.pers_item_id_card,
R.string.info_pers_item_id_card
)
}
private fun initSettingsMask(map: MutableMap<Id, UnitResource>) {
map[SettingsMask.IS_REUSABLE] = UnitResource(
R.string.pers_item_is_reusable,
R.string.info_pers_item_is_reusable
)
map[SettingsMask.NEED_ACTIVATION] = UnitResource(
R.string.pers_item_need_activation,
R.string.info_pers_item_need_activation
)
map[SettingsMask.FORBID_PURGE] = UnitResource(
R.string.pers_item_forbid_purge,
R.string.info_pers_item_forbid_purge
)
map[SettingsMask.ALLOW_SELECT_BLOCKCHAIN] = UnitResource(
R.string.pers_item_allow_select_blockchain,
R.string.info_pers_item_allow_select_blockchain
)
map[SettingsMask.USE_BLOCK] = UnitResource(
R.string.pers_item_use_block,
R.string.info_pers_item_use_block
)
map[SettingsMask.ONE_APDU] = UnitResource(
R.string.pers_item_one_apdu_at_once,
R.string.info_pers_item_one_apdu_at_once
)
map[SettingsMask.USE_CVC] = UnitResource(
R.string.pers_item_use_cvc,
R.string.info_pers_item_use_cvc
)
map[SettingsMask.ALLOW_SWAP_PIN] = UnitResource(
R.string.pers_item_allow_swap_pin,
R.string.info_pers_item_allow_swap_pin
)
map[SettingsMask.ALLOW_SWAP_PIN2] = UnitResource(
R.string.pers_item_allow_swap_pin2,
R.string.info_pers_item_allow_swap_pin2
)
map[SettingsMask.FORBID_DEFAULT_PIN] = UnitResource(
R.string.pers_item_forbid_default_pin,
R.string.info_pers_item_forbid_default_pin
)
map[SettingsMask.SMART_SECURITY_DELAY] = UnitResource(
R.string.pers_item_smart_security_delay,
R.string.info_pers_item_smart_security_delay
)
map[SettingsMask.PROTECT_ISSUER_DATA_AGAINST_REPLAY] = UnitResource(
R.string.pers_item_protect_issuer_data_against_replay,
R.string.info_pers_item_protect_issuer_data_against_replay
)
map[SettingsMask.SKIP_SECURITY_DELAY_IF_VALIDATED] = UnitResource(
R.string.pers_item_skip_security_delay_if_validated,
R.string.info_pers_item_skip_security_delay_if_validated
)
map[SettingsMask.SKIP_PIN2_CVC_IF_VALIDATED] = UnitResource(
R.string.pers_item_skip_pin2_and_cvc_if_validated,
R.string.info_pers_item_skip_pin2_and_cvc_if_validated
)
map[SettingsMask.SKIP_SECURITY_DELAY_ON_LINKED_TERMINAL] = UnitResource(
R.string.pers_item_skip_security_delay_on_linked_terminal,
R.string.info_pers_item_skip_security_delay_on_linked_terminal
)
map[SettingsMask.RESTRICT_OVERWRITE_EXTRA_ISSUER_DATA] = UnitResource(
R.string.pers_item_restrict_overwrite_ex_issuer_data,
R.string.info_pers_item_restrict_overwrite_ex_issuer_data
)
}
private fun initSettingsMaskProtocolEnc(map: MutableMap<Id, UnitResource>) {
map[SettingsMaskProtocolEnc.ALLOW_UNENCRYPTED] = UnitResource(
R.string.pers_item_allow_unencrypted,
R.string.info_pers_item_allow_unencrypted
)
map[SettingsMaskProtocolEnc.ALLOW_FAST_ENCRYPTION] = UnitResource(
R.string.pers_item_allow_fast_encryption,
R.string.info_pers_item_allow_fast_encryption
)
}
private fun initSettingsMaskNde(map: MutableMap<Id, UnitResource>) {
map[SettingsMaskNdef.USE_NDEF] = UnitResource(
R.string.pers_item_use_ndef,
R.string.info_pers_item_use_ndef
)
map[SettingsMaskNdef.DYNAMIC_NDEF] = UnitResource(
R.string.pers_item_dynamic_ndef,
R.string.info_pers_item_dynamic_ndef
)
map[SettingsMaskNdef.DISABLE_PRECOMPUTED_NDEF] = UnitResource(
R.string.pers_item_disable_precomputed_ndef,
R.string.info_pers_item_disable_precomputed_ndef
)
map[SettingsMaskNdef.AAR] = UnitResource(
R.string.pers_item_aar,
R.string.info_pers_item_aar
)
}
private fun initPins(map: MutableMap<Id, UnitResource>) {
map[Pins.PIN] = UnitResource(
R.string.pers_item_pin,
R.string.info_pers_item_pin
)
map[Pins.PIN2] = UnitResource(
R.string.pers_item_pin2,
R.string.info_pers_item_pin2
)
map[Pins.PIN3] = UnitResource(
R.string.pers_item_pin3,
R.string.info_pers_item_pin3
)
map[Pins.CVC] = UnitResource(
R.string.pers_item_cvc,
R.string.info_pers_item_cvc
)
map[Pins.PAUSE_BEFORE_PIN2] = UnitResource(
R.string.pers_item_pause_before_pin2,
R.string.info_pers_item_pause_before_pin2
)
}
}

View file

@ -1,14 +1,16 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.view_model
package com.tangem.tangemtest.card_use_cases.ui.personalize
import android.view.View
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.google.gson.Gson
import com.tangem.tangemtest._arch.structure.base.Block
import com.tangem.tangemtest.card_use_cases.ui.personalize.personalize_converter.json_test.BlockToJsonConverter
import com.tangem.tangemtest.card_use_cases.ui.personalize.personalize_converter.json_test.JsonBlockEnDe
import com.tangem.tangemtest.card_use_cases.ui.personalize.personalize_converter.json_test.JsonToBlockConverter
import com.tangem.tangemtest.card_use_cases.ui.personalize.personalize_converter.json_test.TestJsonDto
import com.tangem.tangemtest._arch.structure.base.DataUnit
import com.tangem.tangemtest.card_use_cases.ui.personalize.converter.BlockToJsonConverter
import com.tangem.tangemtest.card_use_cases.ui.personalize.converter.JsonBlockEnDe
import com.tangem.tangemtest.card_use_cases.ui.personalize.converter.JsonToBlockConverter
import com.tangem.tangemtest.card_use_cases.ui.personalize.converter.TestJsonDto
/**
[REDACTED_AUTHOR]
@ -26,4 +28,13 @@ class PersonalizeViewModel(private val jsonPersonalizeString: String) : ViewMode
val jsonDto = Gson().fromJson(jsonPersonalizeString, TestJsonDto::class.java)
return enDe.decode(jsonDto)
}
fun toggleDescriptionVisibility(state: Boolean) {
ldBlockList.value?.forEach { block ->
block.unitList.forEach { unit ->
val vm = unit as? DataUnit<*> ?: return@forEach
vm.viewModel?.viewState?.descriptionVisibility = if (state) View.VISIBLE else View.GONE
}
}
}
}

View file

@ -1,339 +0,0 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.base.*
/**
[REDACTED_AUTHOR]
*/
data class UnitInfo(
val resName: Int,
val resDescription: Int? = null
)
object InfoHolder {
private val map = mutableMapOf<Id, UnitInfo>()
init {
InfoInitializer().init(map)
}
fun getInfo(id: Id): UnitInfo = map[id] ?: UnitInfo(R.string.unknown, R.string.unknown)
}
internal class InfoInitializer() {
fun init(map: MutableMap<Id, UnitInfo>) {
initBlock(map)
initCardNumber(map)
initCommon(map)
initSigningMethod(map)
initSignHashExProp(map)
initDenomination(map)
initToken(map)
initProductMask(map)
initSettingsMask(map)
initSettingsMaskProtocolEnc(map)
initSettingsMaskNde(map)
initPins(map)
}
private fun initBlock(map: MutableMap<Id, UnitInfo>) {
map[BlockId.CARD_NUMBER] = UnitInfo(
R.string.pers_block_card_number,
R.string.info_
)
map[BlockId.COMMON] = UnitInfo(
R.string.pers_block_common,
R.string.info_
)
map[BlockId.SIGNING_METHOD] = UnitInfo(
R.string.pers_block_signing_method,
R.string.info_
)
map[BlockId.SIGN_HASH_EX_PROP] = UnitInfo(
R.string.pers_block_sign_hash_ex_prop,
R.string.info_
)
map[BlockId.DENOMINATION] = UnitInfo(
R.string.pers_block_denomination,
R.string.info_
)
map[BlockId.TOKEN] = UnitInfo(
R.string.pers_block_token,
R.string.info_
)
map[BlockId.PROD_MASK] = UnitInfo(
R.string.pers_block_product_mask,
R.string.info_
)
map[BlockId.SETTINGS_MASK] = UnitInfo(
R.string.pers_block_settings_mask,
R.string.info_
)
map[BlockId.SETTINGS_MASK_PROTOCOL_ENC] = UnitInfo(
R.string.pers_block_settings_mask_protocol_enc,
R.string.info_
)
map[BlockId.SETTINGS_MASK_NDEF] = UnitInfo(
R.string.pers_block_settings_mask_ndef,
R.string.info_
)
map[BlockId.PINS] = UnitInfo(
R.string.pers_block_pins,
R.string.info_
)
}
private fun initCardNumber(map: MutableMap<Id, UnitInfo>) {
map[CardNumber.SERIES] = UnitInfo(
R.string.pers_item_series,
R.string.info_
)
map[CardNumber.NUMBER] = UnitInfo(
R.string.pers_item_number,
R.string.info_
)
}
private fun initCommon(map: MutableMap<Id, UnitInfo>) {
map[Common.CURVE] = UnitInfo(
R.string.pers_item_curve,
R.string.info_
)
map[Common.BLOCKCHAIN] = UnitInfo(
R.string.pers_item_blockchain,
R.string.info_
)
map[Common.BLOCKCHAIN_CUSTOM] = UnitInfo(
R.string.pers_item_custom_blockchain,
R.string.info_
)
map[Common.MAX_SIGNATURES] = UnitInfo(
R.string.pers_item_max_signatures,
R.string.info_
)
map[Common.CREATE_WALLET] = UnitInfo(
R.string.pers_item_create_wallet,
R.string.info_
)
}
private fun initSigningMethod(map: MutableMap<Id, UnitInfo>) {
map[SigningMethod.SIGN_TX] = UnitInfo(
R.string.pers_item_sign_tx_hashes,
R.string.info_
)
map[SigningMethod.SIGN_TX_RAW] = UnitInfo(
R.string.pers_item_sign_raw_tx,
R.string.info_
)
map[SigningMethod.SIGN_VALIDATED_TX] = UnitInfo(
R.string.pers_item_sign_validated_tx_hashes,
R.string.info_
)
map[SigningMethod.SIGN_VALIDATED_TX_RAW] = UnitInfo(
R.string.pers_item_sign_validated_raw_tx,
R.string.info_
)
map[SigningMethod.SIGN_VALIDATED_TX_ISSUER] = UnitInfo(
R.string.pers_item_sign_validated_tx_hashes_with_iss_data,
R.string.info_
)
map[SigningMethod.SIGN_VALIDATED_TX_RAW_ISSUER] = UnitInfo(
R.string.pers_item_sign_validated_raw_tx_with_iss_data,
R.string.info_
)
map[SigningMethod.SIGN_EXTERNAL] = UnitInfo(
R.string.pers_item_sign_hash_ex,
R.string.info_
)
}
private fun initSignHashExProp(map: MutableMap<Id, UnitInfo>) {
map[SignHashExProp.PIN_LESS_FLOOR_LIMIT] = UnitInfo(
R.string.pers_item_pin_less_floor_limit,
R.string.info_
)
map[SignHashExProp.CRYPTO_EXTRACT_KEY] = UnitInfo(
R.string.pers_item_cr_ex_key,
R.string.info_
)
map[SignHashExProp.REQUIRE_TERMINAL_CERT_SIG] = UnitInfo(
R.string.pers_item_require_terminal_cert_sig,
R.string.info_
)
map[SignHashExProp.REQUIRE_TERMINAL_TX_SIG] = UnitInfo(
R.string.pers_item_require_terminal_tx_sig,
R.string.info_
)
map[SignHashExProp.CHECK_PIN3] = UnitInfo(
R.string.pers_item_pin3,
R.string.info_
)
}
private fun initDenomination(map: MutableMap<Id, UnitInfo>) {
map[Denomination.WRITE_ON_PERSONALIZE] = UnitInfo(
R.string.pers_item_write_on_personalize,
R.string.info_
)
map[Denomination.DENOMINATION] = UnitInfo(
R.string.pers_item_denomination,
R.string.info_
)
}
private fun initToken(map: MutableMap<Id, UnitInfo>) {
map[Token.ITS_TOKEN] = UnitInfo(
R.string.pers_item_its_token,
R.string.info_
)
map[Token.SYMBOL] = UnitInfo(
R.string.pers_item_symbol,
R.string.info_
)
map[Token.CONTRACT_ADDRESS] = UnitInfo(
R.string.pers_item_contract_address,
R.string.info_
)
map[Token.DECIMAL] = UnitInfo(
R.string.pers_item_decimal,
R.string.info_
)
}
private fun initProductMask(map: MutableMap<Id, UnitInfo>) {
map[ProductMask.NOTE] = UnitInfo(
R.string.pers_item_note,
R.string.info_
)
map[ProductMask.TAG] = UnitInfo(
R.string.pers_item_tag,
R.string.info_
)
map[ProductMask.ID_CARD] = UnitInfo(
R.string.pers_item_id_card,
R.string.info_
)
}
private fun initSettingsMask(map: MutableMap<Id, UnitInfo>) {
map[SettingsMask.IS_REUSABLE] = UnitInfo(
R.string.pers_item_is_reusable,
R.string.info_
)
map[SettingsMask.NEED_ACTIVATION] = UnitInfo(
R.string.pers_item_need_activation,
R.string.info_
)
map[SettingsMask.FORBID_PURGE] = UnitInfo(
R.string.pers_item_forbid_purge,
R.string.info_
)
map[SettingsMask.ALLOW_SELECT_BLOCKCHAIN] = UnitInfo(
R.string.pers_item_allow_select_blockchain,
R.string.info_
)
map[SettingsMask.USE_BLOCK] = UnitInfo(
R.string.pers_item_use_block,
R.string.info_
)
map[SettingsMask.ONE_APDU] = UnitInfo(
R.string.pers_item_one_apdu_at_once,
R.string.info_
)
map[SettingsMask.USE_CVC] = UnitInfo(
R.string.pers_item_use_cvc,
R.string.info_
)
map[SettingsMask.ALLOW_SWAP_PIN] = UnitInfo(
R.string.pers_item_allow_swap_pin,
R.string.info_
)
map[SettingsMask.ALLOW_SWAP_PIN2] = UnitInfo(
R.string.pers_item_allow_swap_pin2,
R.string.info_
)
map[SettingsMask.FORBID_DEFAULT_PIN] = UnitInfo(
R.string.pers_item_forbid_default_pin,
R.string.info_
)
map[SettingsMask.SMART_SECURITY_DELAY] = UnitInfo(
R.string.pers_item_smart_security_delay,
R.string.info_
)
map[SettingsMask.PROTECT_ISSUER_DATA_AGAINST_REPLAY] = UnitInfo(
R.string.pers_item_protect_issuer_data_against_replay,
R.string.info_
)
map[SettingsMask.SKIP_SECURITY_DELAY_IF_VALIDATED] = UnitInfo(
R.string.pers_item_skip_security_delay_if_validated,
R.string.info_
)
map[SettingsMask.SKIP_PIN2_CVC_IF_VALIDATED] = UnitInfo(
R.string.pers_item_skip_pin2_and_cvc_if_validated,
R.string.info_
)
map[SettingsMask.SKIP_SECURITY_DELAY_ON_LINKED_TERMINAL] = UnitInfo(
R.string.pers_item_skip_security_delay_on_linked_terminal,
R.string.info_
)
map[SettingsMask.RESTRICT_OVERWRITE_EXTRA_ISSUER_DATA] = UnitInfo(
R.string.pers_item_restrict_overwrite_ex_issuer_data,
R.string.info_
)
}
private fun initSettingsMaskProtocolEnc(map: MutableMap<Id, UnitInfo>) {
map[SettingsMaskProtocolEnc.ALLOW_UNENCRYPTED] = UnitInfo(
R.string.pers_item_allow_unencrypted,
R.string.info_
)
map[SettingsMaskProtocolEnc.ALLOW_FAST_ENCRYPTION] = UnitInfo(
R.string.pers_item_allow_fast_encryption,
R.string.info_
)
}
private fun initSettingsMaskNde(map: MutableMap<Id, UnitInfo>) {
map[SettingsMaskNdef.USE_NDEF] = UnitInfo(
R.string.pers_item_use_ndef,
R.string.info_
)
map[SettingsMaskNdef.DYNAMIC_NDEF] = UnitInfo(
R.string.pers_item_dynamic_ndef,
R.string.info_
)
map[SettingsMaskNdef.DISABLE_PRECOMPUTED_NDEF] = UnitInfo(
R.string.pers_item_disable_precomputed_ndef,
R.string.info_
)
map[SettingsMaskNdef.AAR] = UnitInfo(
R.string.pers_item_aar,
R.string.info_
)
}
private fun initPins(map: MutableMap<Id, UnitInfo>) {
map[Pins.PIN] = UnitInfo(
R.string.pers_item_pin,
R.string.info_
)
map[Pins.PIN2] = UnitInfo(
R.string.pers_item_pin2,
R.string.info_
)
map[Pins.PIN3] = UnitInfo(
R.string.pers_item_pin3,
R.string.info_
)
map[Pins.CVC] = UnitInfo(
R.string.pers_item_cvc,
R.string.info_
)
map[Pins.PAUSE_BEFORE_PIN2] = UnitInfo(
R.string.pers_item_pause_before_pin2,
R.string.info_
)
}
}

View file

@ -1,4 +1,4 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.personalize_converter.json_test
package com.tangem.tangemtest.card_use_cases.ui.personalize.converter
import com.tangem.tangemtest._arch.structure.base.Block

View file

@ -1,4 +1,4 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.personalize_converter.json_test
package com.tangem.tangemtest.card_use_cases.ui.personalize.converter
class TestJsonDto {

View file

@ -1,4 +1,4 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.personalize_converter.json_test
package com.tangem.tangemtest.card_use_cases.ui.personalize.converter
import com.tangem.tangemtest._arch.structure.base.*
import com.tangem.tangemtest._arch.structure.impl.*

View file

@ -1,4 +1,4 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.personalize_converter.json_test
package com.tangem.tangemtest.card_use_cases.ui.personalize.converter
import com.tangem.tangemtest._arch.structure.base.Block
import ru.dev.gbixahue.eu4d.lib.kotlin.common.Converter

View file

@ -1,32 +1,15 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.widgets
import android.view.View
import android.view.ViewGroup
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.base.Block
import com.tangem.tangemtest._arch.structure.base.DataUnit
import com.tangem.tangemtest._arch.structure.base.Unit
import com.tangem.tangemtest._arch.structure.impl.*
import ru.dev.gbixahue.eu4d.lib.android._android.views.inflate
/**
[REDACTED_AUTHOR]
*/
interface BlockWidget : ViewWidget
class EmptyWidget(parent: ViewGroup) : BlockWidget {
override val view: View = parent.inflate(getLayoutId(), parent, false)
override fun getLayoutId(): Int = R.layout.w_empty
}
abstract class BaseBlockWidget<D>(parent: ViewGroup) : BaseViewWidget(parent), BlockWidget
class LinearBlockWidget(
private val linearBlock: LinearBlock,
parent: ViewGroup
) : BaseBlockWidget<List<UnitWidget<*>>>(parent) {
override fun getLayoutId(): Int = R.layout.w_personilize_block
}
import com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.base.BlockWidget
import com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.base.EmptyWidget
import com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.base.UnitWidget
import com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.base.ViewWidget
import com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.impl.*
class WidgetBuilder {

View file

@ -0,0 +1,18 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.base
import android.view.View
import android.view.ViewGroup
import com.tangem.tangemtest.R
import ru.dev.gbixahue.eu4d.lib.android._android.views.inflate
/**
[REDACTED_AUTHOR]
*/
interface BlockWidget : ViewWidget
class EmptyWidget(parent: ViewGroup) : BlockWidget {
override val view: View = parent.inflate(getLayoutId(), parent, false)
override fun getLayoutId(): Int = R.layout.w_empty
}
abstract class BaseBlockWidget<D>(parent: ViewGroup) : BaseViewWidget(parent), BlockWidget

View file

@ -0,0 +1,36 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.base
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.base.DataUnit
import com.tangem.tangemtest.card_use_cases.ui.personalize.PersonalizeResources
import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder
/**
[REDACTED_AUTHOR]
*/
interface ViewWidget : LayoutHolder {
val view: View
}
interface UnitWidget<D> : ViewWidget {
val unit: DataUnit<D>
}
abstract class BaseViewWidget(parent: ViewGroup) : ViewWidget {
override val view: View = inflateView(parent)
private fun inflateView(parent: ViewGroup): View {
var id = getLayoutId()
if (id == -1) id = R.layout.w_empty
val inflatedView = LayoutInflater.from(parent.context).inflate(id, parent, false)
parent.addView(inflatedView)
return inflatedView
}
}
fun UnitWidget<*>.getResNameId(): Int = PersonalizeResources.get(unit.id).resName
fun UnitWidget<*>.getResDescription(): Int? = PersonalizeResources.get(unit.id).resDescription

View file

@ -0,0 +1,17 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.impl
import android.view.ViewGroup
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.impl.LinearBlock
import com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.base.BaseBlockWidget
import com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.base.UnitWidget
/**
[REDACTED_AUTHOR]
*/
class LinearBlockWidget(
private val linearBlock: LinearBlock,
parent: ViewGroup
) : BaseBlockWidget<List<UnitWidget<*>>>(parent) {
override fun getLayoutId(): Int = R.layout.w_personilize_block
}

View file

@ -0,0 +1,205 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.impl
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.appcompat.widget.SwitchCompat
import androidx.transition.AutoTransition
import androidx.transition.TransitionManager
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.base.DataUnit
import com.tangem.tangemtest._arch.structure.impl.*
import com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.base.BaseViewWidget
import com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.base.UnitWidget
import com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.base.getResDescription
import com.tangem.tangemtest.card_use_cases.ui.personalize.widgets.base.getResNameId
import ru.dev.gbixahue.eu4d.lib.android._android.views.inflate
import ru.dev.gbixahue.eu4d.lib.android.global.log.Log
import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf
/**
[REDACTED_AUTHOR]
*/
abstract class BaseUnitWidget<D>(
parent: ViewGroup,
override val unit: DataUnit<D>
) : BaseViewWidget(parent), UnitWidget<D> {
private val descriptionContainer: ViewGroup by lazy { view.findViewById<ViewGroup>(R.id.container_description) }
private val tvDescription: TextView? by lazy { descriptionContainer.findViewById<TextView>(R.id.tv_description) }
init {
Log.d(this, "init id: ${unit.id}")
getResDescription()?.let { tvDescription?.setText(it) }
unit.viewModel?.viewState?.onDescriptionVisibilityChanged = { changeDescriptionVisibility(it) }
}
private fun changeDescriptionVisibility(state: Int) {
TransitionManager.beginDelayedTransition(view.parent as ViewGroup, AutoTransition())
descriptionContainer.visibility = state
}
}
class TextWidget(parent: ViewGroup, private val textUnit: TextUnit) : BaseUnitWidget<String>(parent, textUnit) {
private val tvName = view.findViewById<TextView>(R.id.tv_name)
init {
tvName.setText(getResNameId())
}
override fun getLayoutId(): Int = R.layout.w_personalize_item_text
}
class EditTextWidget(parent: ViewGroup, private val editTextUnit: EditTextUnit) : BaseUnitWidget<String>(parent, editTextUnit) {
private val tilItem = view.findViewById<TextInputLayout>(R.id.til_item)
private val etItem = view.findViewById<TextInputEditText>(R.id.et_item)
private val watcher = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
editTextUnit.viewModel?.updateDataByView(stringOf(s))
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
}
init {
tilItem.hint = tilItem.context.getString(getResNameId())
etItem.setText(editTextUnit.viewModel?.data)
etItem.addTextChangedListener(watcher)
editTextUnit.viewModel?.onDataUpdated = {
etItem.removeTextChangedListener(watcher)
etItem.setText(it)
etItem.addTextChangedListener(watcher)
}
}
override fun getLayoutId(): Int = R.layout.w_personalize_item_edit_text
}
class NumberWidget(parent: ViewGroup, private val numberUnit: NumberUnit) : BaseUnitWidget<Number>(parent, numberUnit) {
private val tilItem = view.findViewById<TextInputLayout>(R.id.til_item)
private val etItem = view.findViewById<TextInputEditText>(R.id.et_item)
private val watcher = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
numberUnit.viewModel?.updateDataByView(getIntValue(stringOf(s)))
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
}
init {
tilItem.hint = tilItem.context.getString(getResNameId())
etItem.setText(stringOf(numberUnit.viewModel?.data))
etItem.addTextChangedListener(watcher)
numberUnit.viewModel?.onDataUpdated = {
etItem.removeTextChangedListener(watcher)
etItem.setText(stringOf(it))
etItem.addTextChangedListener(watcher)
}
}
private fun getIntValue(value: String): Number? {
return if (value.isEmpty()) null else value.toInt()
}
override fun getLayoutId(): Int = R.layout.w_personalize_item_number
}
class SwitchWidget(parent: ViewGroup, private val boolUnit: BoolUnit) : BaseUnitWidget<Boolean>(parent, boolUnit) {
private val switchItem = view.findViewById<SwitchCompat>(R.id.sw_item)
private val changeListener = CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
boolUnit.viewModel?.updateDataByView(isChecked)
}
init {
switchItem.setText(getResNameId())
switchItem.isChecked = boolUnit.viewModel?.data ?: false
switchItem.setOnCheckedChangeListener(changeListener)
boolUnit.viewModel?.onDataUpdated = {
switchItem.setOnCheckedChangeListener(null)
switchItem.isChecked = it ?: false
switchItem.setOnCheckedChangeListener(changeListener)
}
}
override fun getLayoutId(): Int = R.layout.w_personalize_item_switch
}
class SpinnerWidget(parent: ViewGroup, private val listUnit: ListUnit) : BaseUnitWidget<ListValueWrapper>(parent, listUnit) {
private val spItem = view.findViewById<Spinner>(R.id.sp_item)
private val spAdapter = SpItemAdapter(listUnit.viewModel?.data?.itemList)
private val onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
val data = listUnit.viewModel?.data ?: return
data.selectedItem = data.itemList[position]
listUnit.viewModel?.updateDataByView(data)
}
}
init {
val name = view.findViewById<TextView>(R.id.tv_name)
name.setText(getResNameId())
spItem.adapter = spAdapter
spItem.onItemSelectedListener = onItemSelectedListener
listUnit.viewModel?.onDataUpdated = {
it?.apply {
spItem.onItemSelectedListener = null
this.itemList.firstOrNull { item -> item.value == selectedItem }?.let {
val position = itemList.indexOf(it)
spItem.setSelection(position)
}
spItem.onItemSelectedListener = onItemSelectedListener
}
}
}
override fun getLayoutId(): Int = R.layout.w_personalize_item_spinner
}
class SpItemAdapter(list: List<KeyValue>?) : BaseAdapter() {
private val itemList: List<KeyValue> = list ?: listOf()
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = convertView ?: parent.inflate(R.layout.vh_sp_item)
val tv = view.findViewById<TextView>(R.id.tv_sp_item)
tv.text = extractData(itemList[position])
return view
}
override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = convertView ?: parent.inflate(R.layout.vh_sp_dropdown_item)
val tv = view.findViewById<TextView>(R.id.tv_sp_item)
tv.text = extractData(itemList[position])
return view
}
private fun extractData(item: KeyValue): String? = item.key
override fun getItem(position: Int): String = stringOf(itemList[position])
override fun getItemId(position: Int): Long = position.toLong()
override fun getCount(): Int = itemList.size
}

View file

@ -1,59 +0,0 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.widgets
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.transition.AutoTransition
import androidx.transition.TransitionManager
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.base.DataUnit
import com.tangem.tangemtest.card_use_cases.ui.personalize.InfoHolder
import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder
/**
[REDACTED_AUTHOR]
*/
interface ViewWidget : LayoutHolder {
val view: View
}
interface UnitWidget<D> : ViewWidget {
val unit: DataUnit<D>
}
abstract class BaseViewWidget(parent: ViewGroup) : ViewWidget {
override val view: View = inflateView(parent)
private fun inflateView(parent: ViewGroup): View {
var id = getLayoutId()
if (id == -1) id = R.layout.w_empty
val inflatedView = LayoutInflater.from(parent.context).inflate(id, parent, false)
parent.addView(inflatedView)
return inflatedView
}
}
interface DescriptionWidget {
fun toggleDescriptionVisibility()
}
interface ParamWidget<D> : UnitWidget<D>, DescriptionWidget
abstract class BaseParamWidget<D>(
parent: ViewGroup,
override val unit: DataUnit<D>
) : BaseViewWidget(parent), ParamWidget<D> {
override fun toggleDescriptionVisibility() {
val tvDescription = view.findViewById<TextView>(R.id.tv_description) ?: return
getResDescription()?.let { tvDescription.setText(it) }
TransitionManager.beginDelayedTransition(tvDescription.parent as ViewGroup, AutoTransition())
tvDescription.visibility = unit.viewModel?.viewState?.descriptionVisibility ?: View.GONE
}
}
fun UnitWidget<*>.getResNameId(): Int = InfoHolder.getInfo(unit.id).resName
fun UnitWidget<*>.getResDescription(): Int? = InfoHolder.getInfo(unit.id).resDescription

View file

@ -1,148 +0,0 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.widgets
import android.view.View
import android.view.ViewGroup
import android.widget.*
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.*
import ru.dev.gbixahue.eu4d.lib.android._android.views.afterTextChanged
import ru.dev.gbixahue.eu4d.lib.android._android.views.inflate
import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf
/**
[REDACTED_AUTHOR]
*/
class TextWidget(parent: ViewGroup, private val textUnit: TextUnit) : BaseParamWidget<String>(parent, textUnit) {
private val tvName = view.findViewById<TextView>(R.id.tv_name)
init {
bindData()
}
private fun bindData() {
tvName.setText(getResNameId())
}
override fun getLayoutId(): Int = R.layout.w_personalize_item_text
}
class EditTextWidget(parent: ViewGroup, private val editTextUnit: EditTextUnit) : BaseParamWidget<String>(parent, editTextUnit) {
private val tilItem = view.findViewById<TextInputLayout>(R.id.til_item)
private val etItem = view.findViewById<TextInputEditText>(R.id.et_item)
init {
bindData()
}
private fun bindData() {
tilItem.hint = tilItem.context.getString(getResNameId())
etItem.setText(editTextUnit.viewModel?.data)
etItem.afterTextChanged { editTextUnit.viewModel?.updateData(it) }
}
override fun getLayoutId(): Int = R.layout.w_personalize_item_edit_text
}
class NumberWidget(parent: ViewGroup, private val numberUnit: NumberUnit) : BaseParamWidget<Number>(parent, numberUnit) {
private val tilItem = view.findViewById<TextInputLayout>(R.id.til_item)
private val etItem = view.findViewById<TextInputEditText>(R.id.et_item)
init {
bindData()
}
private fun bindData() {
tilItem.hint = tilItem.context.getString(getResNameId())
etItem.setText(stringOf(numberUnit.viewModel?.data))
etItem.afterTextChanged { numberUnit.viewModel?.updateData(getIntValue(it)) }
}
private fun getIntValue(value: String): Number? {
return if (value.isEmpty()) null else value.toInt()
}
override fun getLayoutId(): Int = R.layout.w_personalize_item_number
}
class SwitchWidget(parent: ViewGroup, private val boolUnit: BoolUnit) : BaseParamWidget<Boolean>(parent, boolUnit) {
private val switchItem = view.findViewById<Switch>(R.id.sw_item)
init {
bindData()
}
private fun bindData() {
switchItem.setText(getResNameId())
switchItem.isChecked = boolUnit.viewModel?.data ?: false
switchItem.setOnCheckedChangeListener { view, isChecked -> boolUnit.viewModel?.updateData(isChecked) }
}
override fun getLayoutId(): Int = R.layout.w_personalize_item_switch
}
class SpinnerWidget(parent: ViewGroup, private val listUnit: ListUnit) : BaseParamWidget<ModelHelper>(parent, listUnit) {
private val spItem = view.findViewById<Spinner>(R.id.sp_item)
private val spAdapter = SpItemAdapter(listUnit.viewModel?.data?.itemList)
init {
bindData()
}
private fun bindData() {
val name = view.findViewById<TextView>(R.id.tv_name)
name.setText(getResNameId())
spItem.adapter = spAdapter
spItem.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
val data = listUnit.viewModel?.data ?: return
data.selectedItem = data.itemList[position]
listUnit.viewModel?.updateData(data)
}
}
}
override fun getLayoutId(): Int = R.layout.w_personalize_item_spinner
}
class SpItemAdapter(list: List<KeyValue>?) : BaseAdapter() {
private val itemList: List<KeyValue> = list ?: listOf()
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = convertView ?: parent.inflate(R.layout.vh_sp_item)
val tv = view.findViewById<TextView>(R.id.tv_sp_item)
tv.text = extractData(itemList[position])
return view
}
override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = convertView ?: parent.inflate(R.layout.vh_sp_dropdown_item)
val tv = view.findViewById<TextView>(R.id.tv_sp_item)
tv.text = extractData(itemList[position])
return view
}
private fun extractData(item: KeyValue): String? = item.key
override fun getItem(position: Int): String = stringOf(itemList[position])
override fun getItemId(position: Int): Long = position.toLong()
override fun getCount(): Int = itemList.size
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/switchThumbActive" android:state_checked="true" />
<item android:color="@color/switchThumb" />
</selector>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/switchTrackActive" android:state_checked="true" />
<item android:color="@color/switchTrack" />
</selector>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimary" android:state_enabled="true"/>
<item android:alpha="0.12" android:color="?attr/colorOnSurface"/>
<item android:color="?attr/colorPrimary" android:state_enabled="true" />
<item android:alpha="0.12" android:color="?attr/colorOnSurface" />
</selector>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/primary_text_dark" android:state_enabled="true"/>
<item android:alpha="0.38" android:color="?attr/colorOnSurface"/>
<item android:color="@android:color/primary_text_dark" android:state_enabled="true" />
<item android:alpha="0.38" android:color="?attr/colorOnSurface" />
</selector>

View file

@ -13,14 +13,4 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/fab_personalize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="@string/personalize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.switchmaterial.SwitchMaterial xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sw"
style="@style/SwitchCompatTheme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />

View file

@ -1,18 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container_description"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:visibility="gone">
<TextView
android:id="@+id/tv_description"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/def_indent"
android:layout_marginEnd="@dimen/def_indent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:textColor="@color/colorPrimary" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/def_indent"
@ -13,7 +14,6 @@
android:layout_height="wrap_content"
app:boxBackgroundColor="@android:color/transparent"
app:endIconMode="clear_text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
@ -30,5 +30,13 @@
</com.google.android.material.textfield.TextInputLayout>
<include
layout="@layout/w_field_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_item"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/def_indent"
@ -13,7 +14,6 @@
android:layout_height="wrap_content"
app:boxBackgroundColor="@android:color/transparent"
app:endIconMode="clear_text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
@ -23,7 +23,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start|bottom"
android:inputType="number"
android:paddingStart="0dp"
android:paddingEnd="@dimen/def_double_indent"
android:paddingBottom="4dp"
@ -31,5 +30,13 @@
</com.google.android.material.textfield.TextInputLayout>
<include
layout="@layout/w_field_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_item"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -25,4 +25,12 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_name" />
<include
layout="@layout/w_field_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sp_item" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -2,19 +2,26 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/unit_widget_min_height"
android:layout_height="wrap_content"
android:paddingStart="@dimen/def_indent"
android:paddingEnd="@dimen/def_indent">
<Switch
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/sw_item"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="2dp"
android:textSize="@dimen/unit_widget_text_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
layout="@layout/w_field_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sw_item" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -2,7 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:background="@color/delimiter"
android:padding="@dimen/def_indent">
@ -12,9 +12,16 @@
android:layout_height="wrap_content"
android:gravity="start|bottom"
android:textSize="@dimen/unit_widget_text_size_block"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
layout="@layout/w_field_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_name" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_favorite"
android:title=""
app:actionLayout="@layout/menu_item_switch"
app:showAsAction="always" />
</menu>

View file

@ -43,18 +43,18 @@
<action
android:id="@+id/action_nav_entry_point_to_nav_personalize"
app:destination="@id/nav_personalize" />
</fragment>
<fragment
android:id="@+id/nav_scan"
android:name="com.tangem.tangemtest.card_use_cases.ui.card_action.ScanActionFragment"
android:name="com.tangem.tangemtest.card_use_cases.ui.card.actions.ScanActionFragment"
android:label="@string/action_card_scan"
tools:layout="@layout/fg_action_card_scan" />
<fragment
android:id="@+id/nav_sign"
android:name="com.tangem.tangemtest.card_use_cases.ui.card_action.SignActionFragment"
android:name="com.tangem.tangemtest.card_use_cases.ui.card.actions.SignActionFragment"
android:label="@string/action_card_sign"
tools:layout="@layout/fg_action_card_sign" />

View file

@ -5,4 +5,10 @@
<color name="colorAccent">#027AFF</color>
<color name="delimiter">#26000000</color>
<color name="switchTrack">#C6C6C6</color>
<color name="switchTrackActive">#FFE391</color>
<color name="switchThumb">#FFFFFF</color>
<color name="switchThumbActive">#FFA100</color>
</resources>

View file

@ -1,21 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="delimiter_size">1dp</dimen>
<dimen name="delimiter_size">1dp</dimen>
<dimen name="def_half_indent">8dp</dimen>
<dimen name="def_indent">16dp</dimen>
<dimen name="def_double_indent">32dp</dimen>
<dimen name="def_half_indent">8dp</dimen>
<dimen name="def_indent">16dp</dimen>
<dimen name="def_double_indent">32dp</dimen>
<dimen name="unit_widget_min_height">52dp</dimen>
<dimen name="unit_widget_text_size_block">20sp</dimen>
<dimen name="unit_widget_text_size">16sp</dimen>
<dimen name="unit_widget_text_size_hint">12sp</dimen>
<dimen name="unit_widget_text_size_description">14sp</dimen>
<dimen name="unit_widget_min_height">52dp</dimen>
<dimen name="unit_widget_text_size_block">20sp</dimen>
<dimen name="unit_widget_text_size">16sp</dimen>
<dimen name="unit_widget_text_size_hint">12sp</dimen>
<dimen name="unit_widget_text_size_description">14sp</dimen>
<dimen name="indent_card_incoming_param_name_h">@dimen/def_indent</dimen>
<dimen name="indent_card_incoming_param_name_v">@dimen/def_indent</dimen>
<dimen name="indent_card_incoming_param_name_h">@dimen/def_indent</dimen>
<dimen name="indent_card_incoming_param_name_v">@dimen/def_indent</dimen>
<dimen name="indent_card_incoming_param_value_h">@dimen/def_indent</dimen>
<dimen name="indent_card_incoming_param_value_v">0dp</dimen>
<dimen name="indent_card_incoming_param_value_h">@dimen/def_indent</dimen>
<dimen name="indent_card_incoming_param_value_v">0dp</dimen>
</resources>

View file

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="personalize">Personalize</string>
<string name="pers_block_card_number">Card number</string>
<string name="pers_block_common">Common</string>
<string name="pers_block_signing_method">Signing method</string>
<string name="pers_block_sign_hash_ex_prop">Sign hash external properties</string>
<string name="pers_block_denomination">Denomination</string>
<string name="pers_block_token">Token</string>
<string name="pers_block_product_mask">Product mask</string>
<string name="pers_block_settings_mask">Settings mask</string>
<string name="pers_block_settings_mask_protocol_enc">Settings mask protocol encryption</string>
<string name="pers_block_settings_mask_ndef">Settings mask ndef</string>
<string name="pers_block_pins">Pins</string>
<string name="pers_item_series">Series</string>
<string name="pers_item_number">Number</string>
<string name="pers_item_curve">Curve</string>
<string name="pers_item_blockchain">Blockchain</string>
<string name="pers_item_custom_blockchain">Custom blockchain</string>
<string name="pers_item_max_signatures">Max signatures</string>
<string name="pers_item_create_wallet">Create wallet</string>
<string name="pers_item_sign_tx_hashes">Sign TX hashes (0)</string>
<string name="pers_item_sign_raw_tx">Sign raw TX (1)</string>
<string name="pers_item_sign_validated_tx_hashes">Sign validated TX hashes (2)</string>
<string name="pers_item_sign_validated_raw_tx">Sign validated raw TX (3)</string>
<string name="pers_item_sign_validated_tx_hashes_with_iss_data">Sign validated TX hashes with issuer data (4)</string>
<string name="pers_item_sign_validated_raw_tx_with_iss_data">Sign validated raw TX with issuer data (5)</string>
<string name="pers_item_sign_hash_ex">Sign hash external (6)</string>
<string name="pers_item_pin_less_floor_limit">Pin-less floor limit</string>
<string name="pers_item_cr_ex_key">Cr(ypto)Ex(tract) key</string>
<string name="pers_item_require_terminal_cert_sig">Require terminal Cert signature</string>
<string name="pers_item_require_terminal_tx_sig">Require terminal TX signature</string>
<string name="pers_item_check_pin3_on_card">Check PIN3 on card</string>
<string name="pers_item_write_on_personalize">Write on personalize</string>
<string name="pers_item_denomination">Denomination</string>
<string name="pers_item_its_token">It\'s token</string>
<string name="pers_item_symbol">Symbol</string>
<string name="pers_item_contract_address">Contract address</string>
<string name="pers_item_decimal">Decimal</string>
<string name="pers_item_note">Note</string>
<string name="pers_item_tag">Tag</string>
<string name="pers_item_id_card">ID card</string>
<string name="pers_item_is_reusable">Is reusable</string>
<string name="pers_item_need_activation">Need activation</string>
<string name="pers_item_forbid_purge">Forbid purge</string>
<string name="pers_item_allow_select_blockchain">Allow select blockchain</string>
<string name="pers_item_use_block">Use block</string>
<string name="pers_item_one_apdu_at_once">One APDU at once</string>
<string name="pers_item_use_cvc">Use CVC</string>
<string name="pers_item_allow_swap_pin">Allow swap PIN</string>
<string name="pers_item_allow_swap_pin2">Allow swap PIN2</string>
<string name="pers_item_forbid_default_pin">Forbid default PIN</string>
<string name="pers_item_smart_security_delay">Smart Security Delay</string>
<string name="pers_item_protect_issuer_data_against_replay">Protect issuer data against replay</string>
<string name="pers_item_skip_security_delay_if_validated">Security delay if validated</string>
<string name="pers_item_skip_pin2_and_cvc_if_validated">Skip PIN2 and CVC if validated</string>
<string name="pers_item_skip_security_delay_on_linked_terminal">Skip security delay on linked terminal</string>
<string name="pers_item_restrict_overwrite_ex_issuer_data">Restrict overwrite extra issuer data</string>
<string name="pers_item_allow_unencrypted">Allow unencrypted</string>
<string name="pers_item_allow_fast_encryption">Allow \'FAST\' encryption</string>
<string name="pers_item_use_ndef">Use NDEF</string>
<string name="pers_item_dynamic_ndef">Dynamic NDEF</string>
<string name="pers_item_disable_precomputed_ndef">Disable precomputed NDEF</string>
<string name="pers_item_aar">AAR</string>
<string name="pers_item_custom_aar_package_name">Custom AAR package name</string>
<string name="pers_item_pin">PIN</string>
<string name="pers_item_pin2">PIN2</string>
<string name="pers_item_pin3">PIN3</string>
<string name="pers_item_cvc">CVC</string>
<string name="pers_item_pause_before_pin2">Pause before PIN2</string>
<string name="info_pers_block_card_number">Description for the field: Card number</string>
<string name="info_pers_block_common">Description for the field: Common</string>
<string name="info_pers_block_signing_method">Description for the field: Signing method</string>
<string name="info_pers_block_sign_hash_ex_prop">Description for the field: Sign hash external properties</string>
<string name="info_pers_block_denomination">Description for the field: Denomination</string>
<string name="info_pers_block_token">Description for the field: Token</string>
<string name="info_pers_block_product_mask">Description for the field: Product mask</string>
<string name="info_pers_block_settings_mask">Description for the field: Settings mask</string>
<string name="info_pers_block_settings_mask_protocol_enc">Description for the field: Settings mask protocol encryption</string>
<string name="info_pers_block_settings_mask_ndef">Description for the field: Settings mask ndef</string>
<string name="info_pers_block_pins">Description for the field: Pins</string>
<string name="info_pers_item_series">Description for the field: Series</string>
<string name="info_pers_item_number">Description for the field: Number</string>
<string name="info_pers_item_curve">Description for the field: Curve</string>
<string name="info_pers_item_blockchain">Description for the field: Blockchain</string>
<string name="info_pers_item_custom_blockchain">Description for the field: Custom blockchain</string>
<string name="info_pers_item_max_signatures">Description for the field: Max signatures</string>
<string name="info_pers_item_create_wallet">Description for the field: Create wallet</string>
<string name="info_pers_item_sign_tx_hashes">Description for the field: Sign TX hashes (0)</string>
<string name="info_pers_item_sign_raw_tx">Description for the field: Sign raw TX (1)</string>
<string name="info_pers_item_sign_validated_tx_hashes">Description for the field: Sign validated TX hashes (2)</string>
<string name="info_pers_item_sign_validated_raw_tx">Description for the field: Sign validated raw TX (3)</string>
<string name="info_pers_item_sign_validated_tx_hashes_with_iss_data">Description for the field: Sign validated TX hashes with issuer data (4)</string>
<string name="info_pers_item_sign_validated_raw_tx_with_iss_data">Description for the field: Sign validated raw TX with issuer data (5)</string>
<string name="info_pers_item_sign_hash_ex">Description for the field: Sign hash external (6)</string>
<string name="info_pers_item_pin_less_floor_limit">Description for the field: Pin-less floor limit</string>
<string name="info_pers_item_cr_ex_key">Description for the field: Cr(ypto)Ex(tract) key</string>
<string name="info_pers_item_require_terminal_cert_sig">Description for the field: Require terminal Cert signature</string>
<string name="info_pers_item_require_terminal_tx_sig">Description for the field: Require terminal TX signature</string>
<string name="info_pers_item_check_pin3_on_card">Description for the field: Check PIN3 on card</string>
<string name="info_pers_item_write_on_personalize">Description for the field: Write on personalize</string>
<string name="info_pers_item_denomination">Description for the field: Denomination</string>
<string name="info_pers_item_its_token">Description for the field: It\'s token</string>
<string name="info_pers_item_symbol">Description for the field: Symbol</string>
<string name="info_pers_item_contract_address">Description for the field: Contract address</string>
<string name="info_pers_item_decimal">Description for the field: Decimal</string>
<string name="info_pers_item_note">Description for the field: Note</string>
<string name="info_pers_item_tag">Description for the field: Tag</string>
<string name="info_pers_item_id_card">Description for the field: ID card</string>
<string name="info_pers_item_is_reusable">Description for the field: Is reusable</string>
<string name="info_pers_item_need_activation">Description for the field: Need activation</string>
<string name="info_pers_item_forbid_purge">Description for the field: Forbid purge</string>
<string name="info_pers_item_allow_select_blockchain">Description for the field: Allow select blockchain</string>
<string name="info_pers_item_use_block">Description for the field: Use block</string>
<string name="info_pers_item_one_apdu_at_once">Description for the field: One APDU at once</string>
<string name="info_pers_item_use_cvc">Description for the field: Use CVC</string>
<string name="info_pers_item_allow_swap_pin">Description for the field: Allow swap PIN</string>
<string name="info_pers_item_allow_swap_pin2">Description for the field: Allow swap PIN2</string>
<string name="info_pers_item_forbid_default_pin">Description for the field: Forbid default PIN</string>
<string name="info_pers_item_smart_security_delay">Description for the field: Smart Security Delay</string>
<string name="info_pers_item_protect_issuer_data_against_replay">Description for the field: Protect issuer data against replay</string>
<string name="info_pers_item_skip_security_delay_if_validated">Description for the field: Security delay if validated</string>
<string name="info_pers_item_skip_pin2_and_cvc_if_validated">Description for the field: Skip PIN2 and CVC if validated</string>
<string name="info_pers_item_skip_security_delay_on_linked_terminal">Description for the field: Skip security delay on linked terminal</string>
<string name="info_pers_item_restrict_overwrite_ex_issuer_data">Description for the field: Restrict overwrite extra issuer data</string>
<string name="info_pers_item_allow_unencrypted">Description for the field: Allow unencrypted</string>
<string name="info_pers_item_allow_fast_encryption">Description for the field: Allow \'FAST\' encryption</string>
<string name="info_pers_item_use_ndef">Description for the field: Use NDEF</string>
<string name="info_pers_item_dynamic_ndef">Description for the field: Dynamic NDEF</string>
<string name="info_pers_item_disable_precomputed_ndef">Description for the field: Disable precomputed NDEF</string>
<string name="info_pers_item_aar">Description for the field: AAR</string>
<string name="info_pers_item_custom_aar_package_name">Description for the field: Custom AAR package name</string>
<string name="info_pers_item_pin">Description for the field: PIN</string>
<string name="info_pers_item_pin2">Description for the field: PIN2</string>
<string name="info_pers_item_pin3">Description for the field: PIN3</string>
<string name="info_pers_item_cvc">Description for the field: CVC</string>
<string name="info_pers_item_pause_before_pin2">Description for the field: Pause before PIN2</string>
</resources>

View file

@ -4,6 +4,7 @@
<string name="fg_name_entry_point">@string/app_name</string>
<string name="action_card_scan">Scan</string>
<string name="action_card_sign">Sign</string>
<string name="action_personalize">Personalize</string>
<string name="action_wallet_create">Create wallet</string>
<string name="action_wallet_purge">Purge wallet</string>
<string name="action_issuer_read_data">Read issuer data</string>
@ -15,75 +16,4 @@
<string name="current_card_id">"Current card ID: "</string>
<string name="unknown">unknown</string>
<string name="personalize">Personalize</string>
<string name="pers_block_card_number">Card number</string>
<string name="pers_block_common">Common</string>
<string name="pers_block_signing_method">Signing method</string>
<string name="pers_block_sign_hash_ex_prop">Sign hash external properties</string>
<string name="pers_block_denomination">Denomination</string>
<string name="pers_block_token">Token</string>
<string name="pers_block_product_mask">Product mask</string>
<string name="pers_block_settings_mask">Settings mask</string>
<string name="pers_block_settings_mask_protocol_enc">Settings mask protocol encryption</string>
<string name="pers_block_settings_mask_ndef">Settings mask ndef</string>
<string name="pers_block_pins">Pins</string>
<string name="pers_item_series">Series</string>
<string name="pers_item_number">Number</string>
<string name="pers_item_curve">Curve</string>
<string name="pers_item_blockchain">Blockchain</string>
<string name="pers_item_custom_blockchain">Custom blockchain</string>
<string name="pers_item_max_signatures">Max signatures</string>
<string name="pers_item_create_wallet">Create wallet</string>
<string name="pers_item_sign_tx_hashes">Sign TX hashes (0)</string>
<string name="pers_item_sign_raw_tx">Sign raw TX (1)</string>
<string name="pers_item_sign_validated_tx_hashes">Sign validated TX hashes (2)</string>
<string name="pers_item_sign_validated_raw_tx">Sign validated raw TX (3)</string>
<string name="pers_item_sign_validated_tx_hashes_with_iss_data">Sign validated TX hashes with issuer data (4)</string>
<string name="pers_item_sign_validated_raw_tx_with_iss_data">Sign validated raw TX with issuer data (5)</string>
<string name="pers_item_sign_hash_ex">Sign hash external (6)</string>
<string name="pers_item_pin_less_floor_limit">Pin-less floor limit</string>
<string name="pers_item_cr_ex_key">Cr(ypto)Ex(tract) key</string>
<string name="pers_item_require_terminal_cert_sig">Require terminal Cert signature</string>
<string name="pers_item_require_terminal_tx_sig">Require terminal TX signature</string>
<string name="pers_item_check_pin3_on_card">Check PIN3 on card</string>
<string name="pers_item_write_on_personalize">Write on personalize</string>
<string name="pers_item_denomination">Denomination</string>
<string name="pers_item_its_token">It\'s token</string>
<string name="pers_item_symbol">Symbol</string>
<string name="pers_item_contract_address">Contract address</string>
<string name="pers_item_decimal">Decimal</string>
<string name="pers_item_note">Note</string>
<string name="pers_item_tag">Tag</string>
<string name="pers_item_id_card">ID card</string>
<string name="pers_item_is_reusable">Is reusable</string>
<string name="pers_item_need_activation">Need activation</string>
<string name="pers_item_forbid_purge">Forbid purge</string>
<string name="pers_item_allow_select_blockchain">Allow select blockchain</string>
<string name="pers_item_use_block">Use block</string>
<string name="pers_item_one_apdu_at_once">One APDU at once</string>
<string name="pers_item_use_cvc">Use CVC</string>
<string name="pers_item_allow_swap_pin">Allow swap PIN</string>
<string name="pers_item_allow_swap_pin2">Allow swap PIN2</string>
<string name="pers_item_forbid_default_pin">Forbid default PIN</string>
<string name="pers_item_smart_security_delay">Smart Security Delay</string>
<string name="pers_item_protect_issuer_data_against_replay">Protect issuer data against replay</string>
<string name="pers_item_skip_security_delay_if_validated">Security delay if validated</string>
<string name="pers_item_skip_pin2_and_cvc_if_validated">Skip PIN2 and CVC if validated</string>
<string name="pers_item_skip_security_delay_on_linked_terminal">Skip security delay on linked terminal</string>
<string name="pers_item_restrict_overwrite_ex_issuer_data">Restrict overwrite extra issuer data</string>
<string name="pers_item_allow_unencrypted">Allow unencrypted</string>
<string name="pers_item_allow_fast_encryption">Allow \'FAST\' encryption</string>
<string name="pers_item_use_ndef">Use NDEF</string>
<string name="pers_item_dynamic_ndef">Dynamic NDEF</string>
<string name="pers_item_disable_precomputed_ndef">Disable precomputed NDEF</string>
<string name="pers_item_aar">AAR</string>
<string name="pers_item_custom_aar_package_name">Custom AAR package name</string>
<string name="pers_item_pin">PIN</string>
<string name="pers_item_pin2">PIN2</string>
<string name="pers_item_pin3">PIN3</string>
<string name="pers_item_cvc">CVC</string>
<string name="pers_item_pause_before_pin2">Pause before PIN2</string>
<string name="info_">Some very useful description</string>
</resources>

View file

@ -8,19 +8,9 @@
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="TvParamNameStyle" parent="@style/Widget.AppCompat.TextView">
<item name="android:layout_marginStart">@dimen/indent_card_incoming_param_name_h</item>
<item name="android:layout_marginEnd">@dimen/indent_card_incoming_param_name_h</item>
<item name="android:layout_marginTop">@dimen/indent_card_incoming_param_name_v</item>
<item name="android:layout_marginBottom">@dimen/indent_card_incoming_param_name_v</item>
</style>
<style name="EtParamValueStyle" parent="@style/Widget.AppCompat.EditText">
<item name="android:layout_marginStart">@dimen/indent_card_incoming_param_value_h</item>
<item name="android:layout_marginEnd">@dimen/indent_card_incoming_param_value_h</item>
<item name="android:layout_marginTop">@dimen/indent_card_incoming_param_value_v</item>
<item name="android:layout_marginBottom">@dimen/indent_card_incoming_param_value_v</item>
<style name="SwitchCompatTheme" parent="Widget.MaterialComponents.CompoundButton.Switch">
<item name="thumbTint">@color/menu_switch_color_thumb</item>
<item name="trackTint">@color/menu_switch_color_track</item>
</style>
</resources>