From ec5fac4e42760513096a87961471217e0e1563c1 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 10 Mar 2020 11:12:34 +0300 Subject: [PATCH 01/68] Updated on 2026-08-14 --- tangem-demo/src/main/AndroidManifest.xml | 2 +- .../com/tangem/tangemtest/Old_MainActivity.kt | 161 ++++++++++++++++++ ...ctivity_main.xml => old_activity_main.xml} | 2 +- 3 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/Old_MainActivity.kt rename tangem-demo/src/main/res/layout/{activity_main.xml => old_activity_main.xml} (99%) diff --git a/tangem-demo/src/main/AndroidManifest.xml b/tangem-demo/src/main/AndroidManifest.xml index f90fa6c597..600bca8f4e 100644 --- a/tangem-demo/src/main/AndroidManifest.xml +++ b/tangem-demo/src/main/AndroidManifest.xml @@ -17,7 +17,7 @@ android:supportsRtl="true" android:theme="@style/AppTheme"> - + diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/Old_MainActivity.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/Old_MainActivity.kt new file mode 100644 index 0000000000..f2c89bc9b4 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/Old_MainActivity.kt @@ -0,0 +1,161 @@ +package com.tangem.tangemtest + +import android.content.Intent +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import com.tangem.CardManager +import com.tangem.tangem_sdk_new.extensions.init +import com.tangem.tasks.ScanEvent +import com.tangem.tasks.TaskError +import com.tangem.tasks.TaskEvent +import kotlinx.android.synthetic.main.old_activity_main.* + +class Old_MainActivity : AppCompatActivity() { + + private lateinit var cardManager: CardManager + private lateinit var cardId: String + private lateinit var issuerData: ByteArray + private lateinit var issuerDataSignature: ByteArray + private var issuerDataCounter: Int = 1 + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.old_activity_main) + + cardManager = CardManager.init(this) + + btn_scan?.setOnClickListener { _ -> + cardManager.scanCard { taskEvent -> + when (taskEvent) { + is TaskEvent.Event -> { + when (taskEvent.data) { + is ScanEvent.OnReadEvent -> { + // Handle returned card data + cardId = (taskEvent.data as ScanEvent.OnReadEvent).card.cardId + runOnUiThread { + tv_card_cid?.text = cardId + btn_create_wallet.isEnabled = true + } + } + is ScanEvent.OnVerifyEvent -> { + //Handle card verification + runOnUiThread { + tv_card_cid?.text = cardId + btn_sign.isEnabled = true + btn_read_issuer_data.isEnabled = true + btn_read_issuer_extra_data.isEnabled = true + btn_write_issuer_data.isEnabled = true + btn_purge_wallet.isEnabled = true + btn_create_wallet.isEnabled = true + } + } + } + } + is TaskEvent.Completion -> { + if (taskEvent.error != null) { + if (taskEvent.error is TaskError.UserCancelled) { + // Handle case when user cancelled manually + } + // Handle other errors + } + // Handle completion + } + } + } + } + btn_sign?.setOnClickListener { _ -> + cardManager.sign( + createSampleHashes(), + cardId) { + when (it) { + is TaskEvent.Completion -> { + if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } + } + is TaskEvent.Event -> runOnUiThread { tv_card_cid?.text = cardId + "was used to sign sample hashes." } + } + } + } + btn_read_issuer_data?.setOnClickListener { _ -> + cardManager.readIssuerData(cardId) { + when (it) { + is TaskEvent.Completion -> { + if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } + } + is TaskEvent.Event -> runOnUiThread { + btn_write_issuer_data.isEnabled = true + tv_card_cid?.text = it.data.issuerData.contentToString() + issuerData = it.data.issuerData + issuerDataSignature = it.data.issuerDataSignature + } + } + } + } + btn_write_issuer_data?.setOnClickListener { _ -> + cardManager.writeIssuerData( + cardId, + issuerData, + issuerDataSignature) { + when (it) { + is TaskEvent.Completion -> { + if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } + } + is TaskEvent.Event -> runOnUiThread { + tv_card_cid?.text = it.data.cardId + } + } + } + } + btn_read_issuer_extra_data?.setOnClickListener { _ -> + cardManager.readIssuerExtraData(cardId) { + when (it) { + is TaskEvent.Completion -> { + if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } + } + is TaskEvent.Event -> runOnUiThread { + issuerDataCounter = (it.data.issuerDataCounter ?: 0) + 1 + btn_write_issuer_data.isEnabled = true + tv_card_cid?.text = "Read ${it.data.issuerData.size} bytes of data." + } + } + } + } + btn_purge_wallet?.setOnClickListener { _ -> + cardManager.purgeWallet( + cardId) { + when (it) { + is TaskEvent.Completion -> { + if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } + } + is TaskEvent.Event -> runOnUiThread { + tv_card_cid?.text = it.data.status.name + } + } + } + } + btn_create_wallet?.setOnClickListener { _ -> + cardManager.createWallet( + cardId) { + when (it) { + is TaskEvent.Completion -> { + if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } + } + is TaskEvent.Event -> runOnUiThread { + tv_card_cid?.text = it.data.status.name + btn_sign.isEnabled = true + btn_read_issuer_data.isEnabled = true + btn_purge_wallet.isEnabled = true + btn_create_wallet.isEnabled = false + + } + } + } + } + btn_read_write_user_data?.setOnClickListener { startActivity(Intent(this, TestUserDataActivity::class.java)) } + } + + private fun createSampleHashes(): Array { + val hash1 = ByteArray(32) { 1 } + val hash2 = ByteArray(32) { 2 } + return arrayOf(hash1, hash2) + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/res/layout/activity_main.xml b/tangem-demo/src/main/res/layout/old_activity_main.xml similarity index 99% rename from tangem-demo/src/main/res/layout/activity_main.xml rename to tangem-demo/src/main/res/layout/old_activity_main.xml index 2af3ad92de..13c1d81f26 100644 --- a/tangem-demo/src/main/res/layout/activity_main.xml +++ b/tangem-demo/src/main/res/layout/old_activity_main.xml @@ -9,7 +9,7 @@ android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".MainActivity"> + tools:context=".Old_MainActivity"> Date: Tue, 10 Mar 2020 11:14:19 +0300 Subject: [PATCH 02/68] Updated on 2026-08-14 --- .idea/navEditor.xml | 541 -------------------------------------------- 1 file changed, 541 deletions(-) delete mode 100644 .idea/navEditor.xml diff --git a/.idea/navEditor.xml b/.idea/navEditor.xml deleted file mode 100644 index 09d3bc259e..0000000000 --- a/.idea/navEditor.xml +++ /dev/null @@ -1,541 +0,0 @@ - - - - - - \ No newline at end of file From 5a452ba1e213faa7c32620761b3fff105b7d6c46 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 10 Mar 2020 14:25:09 +0300 Subject: [PATCH 03/68] Updated on 2026-08-14 --- .idea/gradle.xml | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 .idea/gradle.xml diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 280cc6ed9d..0000000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - \ No newline at end of file From 586dc1a563ac298c29f4a5b56c65463448532d27 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 10 Mar 2020 16:39:20 +0300 Subject: [PATCH 04/68] Updated on 2026-08-14 --- tangem-demo/build.gradle | 22 ++- tangem-demo/src/main/AndroidManifest.xml | 6 +- .../com/tangem/tangemtest/AppTangemDemo.kt | 14 ++ .../com/tangem/tangemtest/MainActivity.kt | 161 ------------------ .../tangem/tangemtest/_main/MainActivity.kt | 48 ++++++ .../_main/entry_point/EntryPointFragment.kt | 62 +++++++ .../tangem/tangemtest/_main/entry_point/rv.kt | 69 ++++++++ .../tangemtest/card_use_cases/CardContext.kt | 31 ++++ .../actions/ScanActionFragment.kt | 41 +++++ .../actions/SignActionFragment.kt | 40 +++++ .../card_use_cases/actions/actions.kt | 12 ++ .../base/BaseCardActionFragment.kt | 53 ++++++ .../tangem/tangemtest/commons/abstracts.kt | 12 ++ .../java/com/tangem/tangemtest/commons/di.kt | 17 ++ .../tangem/tangemtest/commons/navigation.kt | 23 +++ .../tangem/tangemtest/commons/threading.kt | 30 ++++ tangem-demo/src/main/res/anim/fade_in.xml | 22 +++ tangem-demo/src/main/res/anim/fade_out.xml | 22 +++ .../src/main/res/anim/slide_in_left.xml | 10 ++ .../src/main/res/anim/slide_in_right.xml | 10 ++ .../src/main/res/anim/slide_out_left.xml | 10 ++ .../src/main/res/anim/slide_out_right.xml | 10 ++ tangem-demo/src/main/res/layout/a_main.xml | 22 +++ .../src/main/res/layout/fg_card_scan.xml | 17 ++ .../src/main/res/layout/fg_card_sign.xml | 17 ++ .../src/main/res/layout/fg_entry_point.xml | 16 ++ .../src/main/res/layout/vh_actions.xml | 31 ++++ .../src/main/res/navigation/navigation.xml | 58 +++++++ tangem-demo/src/main/res/values/strings.xml | 6 +- tangem-demo/src/main/res/values/styles.xml | 2 +- 30 files changed, 721 insertions(+), 173 deletions(-) create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/AppTangemDemo.kt delete mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/MainActivity.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_main/MainActivity.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_main/entry_point/EntryPointFragment.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_main/entry_point/rv.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/CardContext.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/actions/ScanActionFragment.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/actions/SignActionFragment.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/actions/actions.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/base/BaseCardActionFragment.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/commons/abstracts.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/commons/di.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/commons/navigation.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/commons/threading.kt create mode 100644 tangem-demo/src/main/res/anim/fade_in.xml create mode 100644 tangem-demo/src/main/res/anim/fade_out.xml create mode 100644 tangem-demo/src/main/res/anim/slide_in_left.xml create mode 100644 tangem-demo/src/main/res/anim/slide_in_right.xml create mode 100644 tangem-demo/src/main/res/anim/slide_out_left.xml create mode 100644 tangem-demo/src/main/res/anim/slide_out_right.xml create mode 100644 tangem-demo/src/main/res/layout/a_main.xml create mode 100644 tangem-demo/src/main/res/layout/fg_card_scan.xml create mode 100644 tangem-demo/src/main/res/layout/fg_card_sign.xml create mode 100644 tangem-demo/src/main/res/layout/fg_entry_point.xml create mode 100644 tangem-demo/src/main/res/layout/vh_actions.xml create mode 100644 tangem-demo/src/main/res/navigation/navigation.xml diff --git a/tangem-demo/build.gradle b/tangem-demo/build.gradle index b1de1a90fd..116ffff7cd 100644 --- a/tangem-demo/build.gradle +++ b/tangem-demo/build.gradle @@ -3,8 +3,7 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 29 - buildToolsVersion "29.0.2" - + buildToolsVersion "29.0.3" defaultConfig { applicationId "com.tangem.tangemtest" @@ -34,13 +33,22 @@ android { dependencies { implementation project(':tangem-core') implementation project(':tangem-sdk') - implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$versions.kotlin" - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'androidx.core:core-ktx:1.1.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$versions.kotlin" + + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.core:core-ktx:1.2.0' + implementation "androidx.constraintlayout:constraintlayout:2.0.0-beta4" + implementation "androidx.navigation:navigation-fragment-ktx:2.2.1" + implementation "androidx.navigation:navigation-ui-ktx:2.2.1" + implementation "androidx.recyclerview:recyclerview:1.2.0-alpha01" + + implementation "com.google.android.material:material:1.2.0-alpha05" + + implementation 'com.google.code.gson:gson:2.8.6' } diff --git a/tangem-demo/src/main/AndroidManifest.xml b/tangem-demo/src/main/AndroidManifest.xml index 600bca8f4e..cf184dcfe2 100644 --- a/tangem-demo/src/main/AndroidManifest.xml +++ b/tangem-demo/src/main/AndroidManifest.xml @@ -8,8 +8,8 @@ - - + - + diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/AppTangemDemo.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/AppTangemDemo.kt new file mode 100644 index 0000000000..cd3f9ace12 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/AppTangemDemo.kt @@ -0,0 +1,14 @@ +package com.tangem.tangemtest + +import android.app.Application +import com.tangem.tangemtest.card_use_cases.CardContext +import com.tangem.tangemtest.commons.DiManager + +/** +[REDACTED_AUTHOR] + */ +class AppTangemDemo : Application(), DiManager { + private val cardContext: CardContext = CardContext() + + override fun getCardContext(): CardContext = cardContext +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/MainActivity.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/MainActivity.kt deleted file mode 100644 index 01207d703d..0000000000 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/MainActivity.kt +++ /dev/null @@ -1,161 +0,0 @@ -package com.tangem.tangemtest - -import android.content.Intent -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.tangem.CardManager -import com.tangem.tangem_sdk_new.extensions.init -import com.tangem.tasks.ScanEvent -import com.tangem.tasks.TaskError -import com.tangem.tasks.TaskEvent -import kotlinx.android.synthetic.main.activity_main.* - -class MainActivity : AppCompatActivity() { - - private lateinit var cardManager: CardManager - private lateinit var cardId: String - private lateinit var issuerData: ByteArray - private lateinit var issuerDataSignature: ByteArray - private var issuerDataCounter: Int = 1 - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - - cardManager = CardManager.init(this) - - btn_scan?.setOnClickListener { _ -> - cardManager.scanCard { taskEvent -> - when (taskEvent) { - is TaskEvent.Event -> { - when (taskEvent.data) { - is ScanEvent.OnReadEvent -> { - // Handle returned card data - cardId = (taskEvent.data as ScanEvent.OnReadEvent).card.cardId - runOnUiThread { - tv_card_cid?.text = cardId - btn_create_wallet.isEnabled = true - } - } - is ScanEvent.OnVerifyEvent -> { - //Handle card verification - runOnUiThread { - tv_card_cid?.text = cardId - btn_sign.isEnabled = true - btn_read_issuer_data.isEnabled = true - btn_read_issuer_extra_data.isEnabled = true - btn_write_issuer_data.isEnabled = true - btn_purge_wallet.isEnabled = true - btn_create_wallet.isEnabled = true - } - } - } - } - is TaskEvent.Completion -> { - if (taskEvent.error != null) { - if (taskEvent.error is TaskError.UserCancelled) { - // Handle case when user cancelled manually - } - // Handle other errors - } - // Handle completion - } - } - } - } - btn_sign?.setOnClickListener { _ -> - cardManager.sign( - createSampleHashes(), - cardId) { - when (it) { - is TaskEvent.Completion -> { - if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } - } - is TaskEvent.Event -> runOnUiThread { tv_card_cid?.text = cardId + "was used to sign sample hashes." } - } - } - } - btn_read_issuer_data?.setOnClickListener { _ -> - cardManager.readIssuerData(cardId) { - when (it) { - is TaskEvent.Completion -> { - if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } - } - is TaskEvent.Event -> runOnUiThread { - btn_write_issuer_data.isEnabled = true - tv_card_cid?.text = it.data.issuerData.contentToString() - issuerData = it.data.issuerData - issuerDataSignature = it.data.issuerDataSignature - } - } - } - } - btn_write_issuer_data?.setOnClickListener { _ -> - cardManager.writeIssuerData( - cardId, - issuerData, - issuerDataSignature) { - when (it) { - is TaskEvent.Completion -> { - if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } - } - is TaskEvent.Event -> runOnUiThread { - tv_card_cid?.text = it.data.cardId - } - } - } - } - btn_read_issuer_extra_data?.setOnClickListener { _ -> - cardManager.readIssuerExtraData(cardId) { - when (it) { - is TaskEvent.Completion -> { - if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } - } - is TaskEvent.Event -> runOnUiThread { - issuerDataCounter = (it.data.issuerDataCounter ?: 0) + 1 - btn_write_issuer_data.isEnabled = true - tv_card_cid?.text = "Read ${it.data.issuerData.size} bytes of data." - } - } - } - } - btn_purge_wallet?.setOnClickListener { _ -> - cardManager.purgeWallet( - cardId) { - when (it) { - is TaskEvent.Completion -> { - if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } - } - is TaskEvent.Event -> runOnUiThread { - tv_card_cid?.text = it.data.status.name - } - } - } - } - btn_create_wallet?.setOnClickListener { _ -> - cardManager.createWallet( - cardId) { - when (it) { - is TaskEvent.Completion -> { - if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName } - } - is TaskEvent.Event -> runOnUiThread { - tv_card_cid?.text = it.data.status.name - btn_sign.isEnabled = true - btn_read_issuer_data.isEnabled = true - btn_purge_wallet.isEnabled = true - btn_create_wallet.isEnabled = false - - } - } - } - } - btn_read_write_user_data?.setOnClickListener { startActivity(Intent(this, TestUserDataActivity::class.java)) } - } - - private fun createSampleHashes(): Array { - val hash1 = ByteArray(32) { 1 } - val hash2 = ByteArray(32) { 2 } - return arrayOf(hash1, hash2) - } -} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_main/MainActivity.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_main/MainActivity.kt new file mode 100644 index 0000000000..7be9b29f37 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_main/MainActivity.kt @@ -0,0 +1,48 @@ +package com.tangem.tangemtest._main + +import android.content.res.Resources +import android.os.Bundle +import android.util.Log +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.Toolbar +import androidx.navigation.findNavController +import androidx.navigation.fragment.NavHostFragment +import androidx.navigation.ui.AppBarConfiguration +import androidx.navigation.ui.navigateUp +import androidx.navigation.ui.setupActionBarWithNavController +import com.tangem.tangemtest.R + +/** + * A simple activity demonstrating use of a NavHostFragment with a navigation drawer. + */ +class MainActivity : AppCompatActivity() { + private lateinit var appBarConfiguration: AppBarConfiguration + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.a_main) + + val toolbar = findViewById(R.id.toolbar) + setSupportActionBar(toolbar) + + val host: NavHostFragment = supportFragmentManager + .findFragmentById(R.id.nav_host_fragment) as NavHostFragment? ?: return + + val navController = host.navController + appBarConfiguration = AppBarConfiguration(setOf(R.id.nav_entry_point)) + setupActionBarWithNavController(navController, appBarConfiguration) + + navController.addOnDestinationChangedListener { _, destination, _ -> + val dest: String = try { + resources.getResourceName(destination.id) + } catch (e: Resources.NotFoundException) { + destination.id.toString() + } + Log.d("NavigationActivity", "Navigated to $dest") + } + } + + override fun onSupportNavigateUp(): Boolean { + return findNavController(R.id.nav_host_fragment).navigateUp(appBarConfiguration) + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_main/entry_point/EntryPointFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_main/entry_point/EntryPointFragment.kt new file mode 100644 index 0000000000..1537c2bd2c --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_main/entry_point/EntryPointFragment.kt @@ -0,0 +1,62 @@ +package com.tangem.tangemtest._main.entry_point + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.navigation.NavController +import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.tangem.tangemtest.R +import com.tangem.tangemtest.card_use_cases.CardContext +import com.tangem.tangemtest.card_use_cases.actions.Action +import com.tangem.tangemtest.commons.NavigateAction +import com.tangem.tangemtest.commons.getDefaultNavigationOptions +import com.tangem.tangemtest.commons.getDiManager +import kotlinx.android.synthetic.main.fg_entry_point.* + +/** +[REDACTED_AUTHOR] + */ +class EntryPointFragment : Fragment() { + + private val navController: NavController by lazy { findNavController() } + private lateinit var rvActions: RecyclerView + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.fg_entry_point, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val activity = activity ?: throw Exception("Fragment isn't associated with activity ") + + val cardContext = getDiManager().getCardContext().init(activity) + initRecyclerView(cardContext) + } + + private fun initRecyclerView(cardContext: CardContext) { + rvActions = rv_actions + rvActions.layoutManager = LinearLayoutManager(activity) + + val adapter = RvActionsAdapter(cardContext) { position, destinationId -> navigate(destinationId as Int) } + adapter.setItems(mutableListOf( + NavigateAction(Action.Scan(), R.id.nav_scan), + NavigateAction(Action.Sign(), R.id.nav_sign) + )) + rvActions.adapter = adapter + } + + override fun onResume() { + super.onResume() + + rvActions.adapter?.notifyDataSetChanged() + } + + private fun navigate(destinationId: Int) { + navController.navigate(destinationId, null, getDefaultNavigationOptions()) + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_main/entry_point/rv.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_main/entry_point/rv.kt new file mode 100644 index 0000000000..6035bebb85 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_main/entry_point/rv.kt @@ -0,0 +1,69 @@ +package com.tangem.tangemtest._main.entry_point + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.tangem.tangemtest.R +import com.tangem.tangemtest.card_use_cases.CardContext +import com.tangem.tangemtest.card_use_cases.actions.Action +import com.tangem.tangemtest.commons.Bindable +import com.tangem.tangemtest.commons.NavigateAction + +/** +[REDACTED_AUTHOR] + */ +typealias RvCallback = (Int, Any?) -> Unit + +class RvActionsAdapter( + private val cardContext: CardContext, + private val callback: RvCallback +) : RecyclerView.Adapter() { + + private val actionList = mutableListOf() + + fun setItems(list: MutableList) { + actionList.clear() + actionList.addAll(list) + } + + fun addToItems(list: MutableList) { + actionList.addAll(list) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RvActionsVH { + val view = LayoutInflater.from(parent.context).inflate(R.layout.vh_actions, parent, false) + return RvActionsVH(view, cardContext.isVerified, callback) + } + + override fun getItemCount(): Int = actionList.size + + override fun onBindViewHolder(holder: RvActionsVH, position: Int) { + holder.bind(actionList[position]) + } +} + +class RvActionsVH( + view: View, + private val cardIsVerified: Boolean, + private val callback: RvCallback +) : RecyclerView.ViewHolder(view), Bindable { + + private val tvAction = itemView.findViewById(R.id.tv_title) + private val navigateRight = itemView.findViewById(R.id.tv_navigate_right) + + override fun bind(data: NavigateAction) { + tvAction.text = tvAction.context.getString(data.action.resId) + itemView.setOnClickListener { callback(adapterPosition, data.destinationId) } + switchItemBackground(data.action) + } + + private fun switchItemBackground(action: Action) { + when (action) { + is Action.Scan -> { + } + else -> itemView.visibility = if (cardIsVerified) View.VISIBLE else View.GONE + } + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/CardContext.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/CardContext.kt new file mode 100644 index 0000000000..2f37449a27 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/CardContext.kt @@ -0,0 +1,31 @@ +package com.tangem.tangemtest.card_use_cases + +import androidx.fragment.app.FragmentActivity +import com.tangem.CardManager +import com.tangem.commands.Card +import com.tangem.tangem_sdk_new.extensions.init + +/** +[REDACTED_AUTHOR] + */ +class CardContext { + lateinit var cardManager: CardManager + private set + + var card: Card? = null + var isVerified: Boolean = false + + fun reset() { + isVerified = false + card = null + } + + fun requireCard(): Card = card!! + + fun init(activity: FragmentActivity): CardContext { + if (::cardManager.isInitialized) return this + + cardManager = CardManager.init(activity) + return this + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/actions/ScanActionFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/actions/ScanActionFragment.kt new file mode 100644 index 0000000000..f6a24b91ed --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/actions/ScanActionFragment.kt @@ -0,0 +1,41 @@ +package com.tangem.tangemtest.card_use_cases.actions + +import android.os.Bundle +import android.view.View +import com.google.gson.Gson +import com.tangem.tangemtest.R +import com.tangem.tangemtest.card_use_cases.base.BaseCardActionFragment +import com.tangem.tangemtest.commons.postUI +import com.tangem.tasks.ScanEvent +import com.tangem.tasks.TaskEvent +import kotlinx.android.synthetic.main.fg_card_scan.* + +/** +[REDACTED_AUTHOR] + */ +class ScanActionFragment : BaseCardActionFragment() { + + override fun getLayoutId(): Int = R.layout.fg_card_scan + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + cardContext.reset() + cardContext.cardManager.scanCard { taskEvent -> + when (taskEvent) { + is TaskEvent.Event -> handleDataEvent(taskEvent.data) + is TaskEvent.Completion -> handleCompletionEvent(taskEvent) + } + } + } + + private fun handleDataEvent(event: ScanEvent) { + when (event) { + is ScanEvent.OnReadEvent -> { + cardContext.card = event.card + postUI { tv_card_cid.text = Gson().toJson(cardContext.card) } + } + is ScanEvent.OnVerifyEvent -> cardContext.isVerified = true + } + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/actions/SignActionFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/actions/SignActionFragment.kt new file mode 100644 index 0000000000..51513df71f --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/actions/SignActionFragment.kt @@ -0,0 +1,40 @@ +package com.tangem.tangemtest.card_use_cases.actions + +import android.os.Bundle +import android.view.View +import com.tangem.commands.SignResponse +import com.tangem.tangemtest.R +import com.tangem.tangemtest.card_use_cases.base.BaseCardActionFragment +import com.tangem.tangemtest.commons.postUI +import com.tangem.tasks.TaskEvent +import kotlinx.android.synthetic.main.fg_card_sign.* + +/** +[REDACTED_AUTHOR] + */ +class SignActionFragment : BaseCardActionFragment() { + + override fun getLayoutId(): Int = R.layout.fg_card_sign + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val cardId = cardContext.requireCard().cardId + cardContext.cardManager.sign(createSampleHashes(), cardId) { taskEvent -> + when (taskEvent) { + is TaskEvent.Event -> handleDataEvent(taskEvent.data) + is TaskEvent.Completion -> handleCompletionEvent(taskEvent) + } + } + } + + private fun handleDataEvent(event: SignResponse) { + postUI { tv_sign_result.text = toJson(event) } + } + + private fun createSampleHashes(): Array { + val hash1 = ByteArray(32) { 1 } + val hash2 = ByteArray(32) { 2 } + return arrayOf(hash1, hash2) + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/actions/actions.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/actions/actions.kt new file mode 100644 index 0000000000..69fecafb54 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/actions/actions.kt @@ -0,0 +1,12 @@ +package com.tangem.tangemtest.card_use_cases.actions + +import androidx.annotation.StringRes +import com.tangem.tangemtest.R + +/** +[REDACTED_AUTHOR] + */ +sealed class Action(@StringRes val resId: Int) { + class Scan: Action(R.string.action_card_scan) + class Sign: Action(R.string.action_card_sign) +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/base/BaseCardActionFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/base/BaseCardActionFragment.kt new file mode 100644 index 0000000000..aacbf2d2d7 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/base/BaseCardActionFragment.kt @@ -0,0 +1,53 @@ +package com.tangem.tangemtest.card_use_cases.base + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.annotation.UiThread +import androidx.fragment.app.Fragment +import com.google.android.material.snackbar.BaseTransientBottomBar +import com.google.android.material.snackbar.Snackbar +import com.google.gson.Gson +import com.tangem.tangemtest.card_use_cases.CardContext +import com.tangem.tangemtest.commons.LayoutHolder +import com.tangem.tangemtest.commons.getDiManager +import com.tangem.tasks.TaskError +import com.tangem.tasks.TaskEvent + +/** +[REDACTED_AUTHOR] + */ +abstract class BaseCardActionFragment : Fragment(), LayoutHolder { + + protected lateinit var cardContext: CardContext + protected lateinit var mainView: View + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + mainView = inflater.inflate(getLayoutId(), container, false) + return mainView + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + cardContext = getDiManager().getCardContext() + } + + @UiThread + protected fun handleCompletionEvent(taskEvent: TaskEvent.Completion<*>) { + val error: TaskError = taskEvent.error ?: return + + when (error) { + is TaskError.UserCancelled -> showSnackbarMessage("Error: User was canceled") + else -> showSnackbarMessage("Description not implemented. code: ${error.code}") + } + + } + + protected fun showSnackbarMessage(message: String) { + Snackbar.make(mainView, message, BaseTransientBottomBar.LENGTH_SHORT).show() + } + + protected fun toJson(obj: Any): String = Gson().toJson(obj) + +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/commons/abstracts.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/abstracts.kt new file mode 100644 index 0000000000..3ca51329f8 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/abstracts.kt @@ -0,0 +1,12 @@ +package com.tangem.tangemtest.commons + +/** +[REDACTED_AUTHOR] + */ +interface LayoutHolder { + fun getLayoutId(): Int +} + +interface Bindable { + fun bind(data: T) +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/commons/di.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/di.kt new file mode 100644 index 0000000000..fdea2ad5af --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/di.kt @@ -0,0 +1,17 @@ +package com.tangem.tangemtest.commons + +import android.content.Context +import androidx.fragment.app.Fragment +import com.tangem.tangemtest.card_use_cases.CardContext + +/** +[REDACTED_AUTHOR] + */ + +interface DiManager { + fun getCardContext(): CardContext +} + +fun Context.getDiManager(): DiManager = applicationContext as DiManager + +fun Fragment.getDiManager(): DiManager = activity?.applicationContext as DiManager \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/commons/navigation.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/navigation.kt new file mode 100644 index 0000000000..0ad3b205ff --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/navigation.kt @@ -0,0 +1,23 @@ +package com.tangem.tangemtest.commons + +import androidx.navigation.NavOptions +import androidx.navigation.navOptions +import com.tangem.tangemtest.R +import com.tangem.tangemtest.card_use_cases.actions.Action + +/** +[REDACTED_AUTHOR] + */ + +fun getDefaultNavigationOptions(): NavOptions { + return navOptions { + anim { + enter = R.anim.slide_in_right + exit = R.anim.slide_out_left + popEnter = R.anim.slide_in_left + popExit = R.anim.slide_out_right + } + } +} + +data class NavigateAction(val action: Action, val destinationId: Int) \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/commons/threading.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/threading.kt new file mode 100644 index 0000000000..0e7a797614 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/threading.kt @@ -0,0 +1,30 @@ +package com.tangem.tangemtest.commons + +import android.os.Handler +import android.os.HandlerThread +import android.os.Looper + +/** +[REDACTED_AUTHOR] + */ +object Threading { + val uiHandler: Handler = Handler(Looper.getMainLooper()) + val workHandler: Handler = Handler(HandlerThread("Application worker thread").apply { start() }.looper) + + fun postInCurrentThread(msTime: Long, func: () -> Unit) { + Handler().postDelayed({ func() }, msTime) + } +} + + +fun post(msTime: Long, func: () -> Unit) { + Threading.postInCurrentThread(msTime, func) +} + +fun postUI(msTime: Long = 0, func: () -> Unit) { + if (msTime > 0) Threading.uiHandler.postDelayed({ func() }, msTime) else Threading.uiHandler.post(func) +} + +fun postWork(msTime: Long = 0, func: () -> Unit) { + if (msTime > 0) Threading.workHandler.postDelayed({ func() }, msTime) else Threading.workHandler.post(func) +} \ No newline at end of file diff --git a/tangem-demo/src/main/res/anim/fade_in.xml b/tangem-demo/src/main/res/anim/fade_in.xml new file mode 100644 index 0000000000..1052d2aa22 --- /dev/null +++ b/tangem-demo/src/main/res/anim/fade_in.xml @@ -0,0 +1,22 @@ + + + + + \ No newline at end of file diff --git a/tangem-demo/src/main/res/anim/fade_out.xml b/tangem-demo/src/main/res/anim/fade_out.xml new file mode 100644 index 0000000000..cfe4193dc3 --- /dev/null +++ b/tangem-demo/src/main/res/anim/fade_out.xml @@ -0,0 +1,22 @@ + + + + + \ No newline at end of file diff --git a/tangem-demo/src/main/res/anim/slide_in_left.xml b/tangem-demo/src/main/res/anim/slide_in_left.xml new file mode 100644 index 0000000000..3ab232f97f --- /dev/null +++ b/tangem-demo/src/main/res/anim/slide_in_left.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/tangem-demo/src/main/res/anim/slide_in_right.xml b/tangem-demo/src/main/res/anim/slide_in_right.xml new file mode 100644 index 0000000000..5c18975a6f --- /dev/null +++ b/tangem-demo/src/main/res/anim/slide_in_right.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/tangem-demo/src/main/res/anim/slide_out_left.xml b/tangem-demo/src/main/res/anim/slide_out_left.xml new file mode 100644 index 0000000000..3e5db825b6 --- /dev/null +++ b/tangem-demo/src/main/res/anim/slide_out_left.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/tangem-demo/src/main/res/anim/slide_out_right.xml b/tangem-demo/src/main/res/anim/slide_out_right.xml new file mode 100644 index 0000000000..486d3ae08c --- /dev/null +++ b/tangem-demo/src/main/res/anim/slide_out_right.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/tangem-demo/src/main/res/layout/a_main.xml b/tangem-demo/src/main/res/layout/a_main.xml new file mode 100644 index 0000000000..a3736051f4 --- /dev/null +++ b/tangem-demo/src/main/res/layout/a_main.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/tangem-demo/src/main/res/layout/fg_card_scan.xml b/tangem-demo/src/main/res/layout/fg_card_scan.xml new file mode 100644 index 0000000000..e8efc318bc --- /dev/null +++ b/tangem-demo/src/main/res/layout/fg_card_scan.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/tangem-demo/src/main/res/layout/fg_card_sign.xml b/tangem-demo/src/main/res/layout/fg_card_sign.xml new file mode 100644 index 0000000000..ea78e82cdb --- /dev/null +++ b/tangem-demo/src/main/res/layout/fg_card_sign.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/tangem-demo/src/main/res/layout/fg_entry_point.xml b/tangem-demo/src/main/res/layout/fg_entry_point.xml new file mode 100644 index 0000000000..8a589c5489 --- /dev/null +++ b/tangem-demo/src/main/res/layout/fg_entry_point.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/tangem-demo/src/main/res/layout/vh_actions.xml b/tangem-demo/src/main/res/layout/vh_actions.xml new file mode 100644 index 0000000000..e1ebc1d1a6 --- /dev/null +++ b/tangem-demo/src/main/res/layout/vh_actions.xml @@ -0,0 +1,31 @@ + + + + + + + + \ No newline at end of file diff --git a/tangem-demo/src/main/res/navigation/navigation.xml b/tangem-demo/src/main/res/navigation/navigation.xml new file mode 100644 index 0000000000..7ca8a58e7b --- /dev/null +++ b/tangem-demo/src/main/res/navigation/navigation.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tangem-demo/src/main/res/values/strings.xml b/tangem-demo/src/main/res/values/strings.xml index 821087e07e..c480d46cdf 100644 --- a/tangem-demo/src/main/res/values/strings.xml +++ b/tangem-demo/src/main/res/values/strings.xml @@ -1,3 +1,7 @@ - TangemTest + Tangem Demo + + @string/app_name + Read card + Sign card diff --git a/tangem-demo/src/main/res/values/styles.xml b/tangem-demo/src/main/res/values/styles.xml index 5885930df6..0eb88fe335 100644 --- a/tangem-demo/src/main/res/values/styles.xml +++ b/tangem-demo/src/main/res/values/styles.xml @@ -1,7 +1,7 @@ - + + + + + From 26993f16bba120161ba30a17e471c0afaf26f76d Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 13 Mar 2020 12:25:34 +0300 Subject: [PATCH 06/68] Updated on 2026-08-14 --- .../card_use_cases/models/params/manager/card_actions.kt | 7 ++++++- .../params/manager/modifiers/after_action_modifiers.kt | 8 +++++++- .../params/manager/modifiers/param_change_consequence.kt | 3 +++ .../models/params/manager/params_managers.kt | 6 ++++-- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/card_actions.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/card_actions.kt index 48cd4193a8..c6474873ac 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/card_actions.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/card_actions.kt @@ -8,7 +8,12 @@ import com.tangem.tangemtest.card_use_cases.models.params.manager.modifiers.Para import com.tangem.tasks.TaskEvent import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf - +/** +[REDACTED_AUTHOR] + * + * The Card Action class family is designed for calling Card Manager functions + * and then processing the response. It also allows you to extract the main action as a lambda expression + */ data class AttrForAction( val cardManager: CardManager, val paramsList: List, diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/after_action_modifiers.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/after_action_modifiers.kt index e94abfa672..8a72f0b514 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/after_action_modifiers.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/after_action_modifiers.kt @@ -6,7 +6,13 @@ import com.tangem.tangemtest.card_use_cases.models.params.manager.ParamsManager import com.tangem.tasks.ScanEvent import com.tangem.tasks.TaskEvent - +/** +[REDACTED_AUTHOR] + * + * The After Action Modification class family is intended for modifying parameters (if necessary) + * after calling CardManager.anyAction. + * Returns a list of parameters that have been modified + */ interface AfterActionModification { fun modify(taskEvent: TaskEvent<*>, paramsList: List): List } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/param_change_consequence.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/param_change_consequence.kt index 8d60022226..60707484b7 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/param_change_consequence.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/param_change_consequence.kt @@ -5,6 +5,9 @@ import com.tangem.tangemtest.card_use_cases.models.params.manager.IncomingParame /** [REDACTED_AUTHOR] + * + * The ParamsChangeConsequence class family modifies parameters depending on the state + * of the incoming parameter */ interface ParamsChangeConsequence { fun affectChanges(changedParameter: IncomingParameter, paramsList: List): List diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/params_managers.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/params_managers.kt index 2ed9feb265..a5f4e070d9 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/params_managers.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/params_managers.kt @@ -8,15 +8,17 @@ import com.tangem.tasks.TaskEvent /** [REDACTED_AUTHOR] + * + * ParamsManager monitors parameter changes and runs the CardManager command */ -class IncomingParameter(val tlvTag: TlvTag, var data: Any? = null) - typealias ActionResponse = TaskEvent<*> typealias AffectedList = List typealias AffectedParamsCallback = (AffectedList) -> Unit typealias ActionCallback = (ActionResponse, AffectedList) -> Unit +class IncomingParameter(val tlvTag: TlvTag, var data: Any? = null) + interface ParamsManager { fun parameterChanged(tag: TlvTag, value: Any?, callback: AffectedParamsCallback? = null) From adb12edd24df7429ba2b8c8e5ca986e09a29191b Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Mar 2020 17:37:33 +0300 Subject: [PATCH 07/68] Updated on 2026-08-14 --- tangem-demo/build.gradle | 4 + .../mvp/dialog/BaseMvpBottomSheetDialog.kt | 71 ++++++++++++++++ .../mvp/dialog/BaseMvpBottomSheetPresenter.kt | 64 ++++++++++++++ .../_arch/mvp/dialog/MvpDlgPresenter.kt | 18 ++++ .../tangemtest/_arch/mvp/dialog/MvpDlgView.kt | 8 ++ .../_arch/mvp/presenter/BaseMvpPresenter.kt | 76 +++++++++++++++++ .../_arch/mvp/presenter/DisposableHolder.kt | 5 ++ .../_arch/mvp/presenter/MvpPresenter.kt | 19 +++++ .../_arch/mvp/view/BaseMvpActivity.kt | 55 ++++++++++++ .../_arch/mvp/view/BaseMvpFragment.kt | 85 +++++++++++++++++++ .../tangemtest/_arch/mvp/view/MvpView.kt | 7 ++ .../mvp/view/custom/BaseMvpCustomView.kt | 51 +++++++++++ .../_arch/mvp/view/custom/MvpCustomView.kt | 18 ++++ .../ui/BaseCardActionFragment.kt | 2 +- .../view_models/ParamsViewModel.kt | 2 +- .../tangem/tangemtest/commons/abstracts.kt | 4 +- .../tangem/tangemtest/commons/threading.kt | 30 ------- 17 files changed, 485 insertions(+), 34 deletions(-) create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/BaseMvpBottomSheetDialog.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/BaseMvpBottomSheetPresenter.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/MvpDlgPresenter.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/MvpDlgView.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/presenter/BaseMvpPresenter.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/presenter/DisposableHolder.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/presenter/MvpPresenter.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/BaseMvpActivity.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/BaseMvpFragment.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/MvpView.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/custom/BaseMvpCustomView.kt create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/custom/MvpCustomView.kt delete mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/commons/threading.kt diff --git a/tangem-demo/build.gradle b/tangem-demo/build.gradle index 18050d7ecf..baed8de1b6 100644 --- a/tangem-demo/build.gradle +++ b/tangem-demo/build.gradle @@ -51,4 +51,8 @@ dependencies { implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.github.gbIxaHue:eu4d:0.2.3' + + implementation 'io.reactivex.rxjava2:rxjava:2.2.6' + implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' + implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0' } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/BaseMvpBottomSheetDialog.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/BaseMvpBottomSheetDialog.kt new file mode 100644 index 0000000000..a25109f2fc --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/BaseMvpBottomSheetDialog.kt @@ -0,0 +1,71 @@ +package com.tangem.tangemtest._arch.mvp.dialog + +import android.content.Context +import android.os.Bundle +import android.view.View +import com.google.android.material.bottomsheet.BottomSheetDialog +import com.tangem.tangemtest.commons.OnBackPressHandler +import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder + +/** +[REDACTED_AUTHOR] + */ +abstract class BaseMvpBottomSheetDialog( + context: Context +) : BottomSheetDialog(context), MvpDlgView, LayoutHolder { + + protected val presenter: MvpDlgPresenter + protected val mainView: View + + init { + initComponent() + presenter = getMvpPresenter() + presenter.attached(this) + mainView = layoutInflater.inflate(getLayoutId(), null, false) + setContentView(mainView) + presenter.contentViewSet() + } + + abstract fun initComponent() + abstract fun getMvpPresenter(): MvpDlgPresenter + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + presenter.created() + } + + override fun onStart() { + super.onStart() + presenter.started() + } + + override fun show() { + super.show() + presenter.showed() + } + + override fun onStop() { + super.onStop() + presenter.stopped() + } + + override fun dismiss() { + super.dismiss() + presenter.dismissed() + } + + override fun cancel() { + super.cancel() + presenter.cancelled() + presenter.detached() + } + + override fun onBackPressed() { + super.onBackPressed() + (presenter as? OnBackPressHandler)?.onBackPressed() + } + + protected fun bindView(id: Int): T { + return mainView.findViewById(id) as T + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/BaseMvpBottomSheetPresenter.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/BaseMvpBottomSheetPresenter.kt new file mode 100644 index 0000000000..7fbd884534 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/BaseMvpBottomSheetPresenter.kt @@ -0,0 +1,64 @@ +package com.tangem.tangemtest._arch.mvp.dialog + +import com.tangem.tangemtest.commons.OnBackPressHandler +import io.reactivex.disposables.CompositeDisposable +import ru.dev.gbixahue.eu4d.lib.android.global.log.Log + + +/** +[REDACTED_AUTHOR] + */ +open class BaseMvpBottomSheetPresenter : MvpDlgPresenter, OnBackPressHandler { + + protected var view: View? = null + + protected val stopDisposable = CompositeDisposable() + protected val dismissDisposable = CompositeDisposable() + protected val cancelDisposable = CompositeDisposable() + + override fun attached(view: View) { + Log.d(this, "mvpView attached") + this.view = view + } + + override fun contentViewSet() { + Log.d(this, "contentViewSet") + } + + override fun created() { + Log.d(this, "created") + } + + override fun started() { + Log.d(this, "started") + } + + override fun showed() { + Log.d(this, "showed") + } + + override fun stopped() { + Log.d(this, "stoped") + stopDisposable.clear() + } + + override fun dismissed() { + Log.d(this, "dismissed") + dismissDisposable.clear() + } + + override fun cancelled() { + Log.d(this, "cancelled") + cancelDisposable.clear() + } + + override fun detached() { + Log.d(this, "detached") + view = null + } + + override fun onBackPressed(): Boolean { + Log.d(this, "onBackPressed") + return true + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/MvpDlgPresenter.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/MvpDlgPresenter.kt new file mode 100644 index 0000000000..921f8bc74e --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/MvpDlgPresenter.kt @@ -0,0 +1,18 @@ +package com.tangem.tangemtest._arch.mvp.dialog + +/** +[REDACTED_AUTHOR] + */ +interface MvpDlgPresenter { + + fun attached(view: T) + fun contentViewSet() + + fun created() + fun started() + fun showed() + fun stopped() + fun dismissed() + fun cancelled() + fun detached() +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/MvpDlgView.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/MvpDlgView.kt new file mode 100644 index 0000000000..7f9467f6bd --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/dialog/MvpDlgView.kt @@ -0,0 +1,8 @@ +package com.tangem.tangemtest._arch.mvp.dialog + +import com.tangem.tangemtest._arch.mvp.view.MvpView + +/** +[REDACTED_AUTHOR] + */ +interface MvpDlgView : MvpView \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/presenter/BaseMvpPresenter.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/presenter/BaseMvpPresenter.kt new file mode 100644 index 0000000000..99a5980e8a --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/presenter/BaseMvpPresenter.kt @@ -0,0 +1,76 @@ +package com.tangem.tangemtest._arch.mvp.presenter + +import com.tangem.tangemtest._arch.mvp.view.MvpView +import com.tangem.tangemtest.commons.OnBackPressHandler +import io.reactivex.disposables.CompositeDisposable +import ru.dev.gbixahue.eu4d.lib.android.global.log.Log + +/** +[REDACTED_AUTHOR] + */ + +abstract class BaseMvpPresenter : MvpPresenter, OnBackPressHandler, DisposableHolder { + + protected var view: View? = null + + protected val pauseDisposable = CompositeDisposable() + protected val stopDisposable = CompositeDisposable() + protected val destroyDisposable = CompositeDisposable() + + override fun attached(view: View) { + Log.d(this, "attached") + this.view = view + } + + override fun created() { + Log.d(this, "created") + } + + override fun createView() { + Log.d(this, "createView") + } + + override fun viewCreated() { + Log.d(this, "viewCreated") + } + + override fun started() { + Log.d(this, "started") + } + + override fun resumed() { + Log.d(this, "resumed") + } + + override fun paused() { + Log.d(this, "paused") + pauseDisposable.clear() + } + + override fun stopped() { + Log.d(this, "stopped") + stopDisposable.clear() + } + + override fun destroyView() { + Log.d(this, "destroyView") + destroyDisposable.clear() + } + + override fun viewDestroyed() { + Log.d(this, "viewDestroyed") + } + + override fun detached() { + Log.d(this, "detached") + this.view = null + } + + override fun disposeAll() { + pauseDisposable.clear() + stopDisposable.clear() + destroyDisposable.clear() + } + + override fun onBackPressed(): Boolean = true +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/presenter/DisposableHolder.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/presenter/DisposableHolder.kt new file mode 100644 index 0000000000..037fbefd08 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/presenter/DisposableHolder.kt @@ -0,0 +1,5 @@ +package com.tangem.tangemtest._arch.mvp.presenter + +interface DisposableHolder { + fun disposeAll() +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/presenter/MvpPresenter.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/presenter/MvpPresenter.kt new file mode 100644 index 0000000000..79c8b4da7f --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/presenter/MvpPresenter.kt @@ -0,0 +1,19 @@ +package com.tangem.tangemtest._arch.mvp.presenter + +import com.tangem.tangemtest._arch.mvp.view.MvpView + + +interface MvpPresenter { + + fun attached(view: T) + fun created() + fun createView() + fun viewCreated() + fun started() + fun resumed() + fun paused() + fun stopped() + fun destroyView() + fun viewDestroyed() + fun detached() +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/BaseMvpActivity.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/BaseMvpActivity.kt new file mode 100644 index 0000000000..946ff246ef --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/BaseMvpActivity.kt @@ -0,0 +1,55 @@ +package com.tangem.tangemtest._arch.mvp.view + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import com.tangem.tangemtest._arch.mvp.presenter.MvpPresenter +import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder + +/** +[REDACTED_AUTHOR] + */ +abstract class BaseMvpActivity : AppCompatActivity(), MvpView, LayoutHolder { + + protected var presenter: MvpPresenter? = null + + protected abstract fun initComponent() + protected abstract fun getMvpPresenter(): MvpPresenter? + + override fun onCreate(savedInstanceState: Bundle?) { + initComponent() + presenter = getMvpPresenter() + presenter?.attached(this) + super.onCreate(savedInstanceState) + presenter?.created() + setContentView(getLayoutId()) + presenter?.createView() + presenter?.viewCreated() + } + + override fun onStart() { + super.onStart() + presenter?.started() + } + + override fun onResume() { + super.onResume() + presenter?.resumed() + } + + override fun onPause() { + super.onPause() + presenter?.paused() + } + + override fun onStop() { + super.onStop() + presenter?.stopped() + } + + override fun onDestroy() { + presenter?.destroyView() + super.onDestroy() + presenter?.viewDestroyed() + presenter?.detached() + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/BaseMvpFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/BaseMvpFragment.kt new file mode 100644 index 0000000000..10ecdc6d32 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/BaseMvpFragment.kt @@ -0,0 +1,85 @@ +package com.tangem.tangemtest._arch.mvp.view + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.tangem.tangemtest._arch.mvp.presenter.MvpPresenter +import com.tangem.tangemtest.commons.OnBackPressHandler + +/** +[REDACTED_AUTHOR] + */ +abstract class BaseMvpFragment : Fragment(), MvpView, OnBackPressHandler { + + protected lateinit var mainView: View + protected var presenter: MvpPresenter? = null + + protected abstract fun getMvpPresenter(): MvpPresenter? + + override fun onAttach(context: Context) { + super.onAttach(context) + presenter = getMvpPresenter() + presenter?.attached(this) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + presenter?.created() + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + mainView = super.onCreateView(inflater, container, savedInstanceState)!! + presenter?.createView() + return mainView + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + presenter?.viewCreated() + } + + override fun onStart() { + super.onStart() + presenter?.started() + } + + override fun onResume() { + super.onResume() + presenter?.resumed() + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + android.R.id.home -> onBackPressed() + } + return super.onOptionsItemSelected(item) + } + + override fun onBackPressed() + : Boolean = (presenter as? OnBackPressHandler)?.onBackPressed() ?: false + + override fun onPause() { + super.onPause() + presenter?.paused() + } + + override fun onStop() { + super.onStop() + presenter?.stopped() + } + + override fun onDestroyView() { + presenter?.destroyView() + super.onDestroyView() + presenter?.viewDestroyed() + } + + override fun onDetach() { + super.onDetach() + presenter?.detached() + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/MvpView.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/MvpView.kt new file mode 100644 index 0000000000..14bbbdffcf --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/MvpView.kt @@ -0,0 +1,7 @@ +package com.tangem.tangemtest._arch.mvp.view + +/** +[REDACTED_AUTHOR] + */ + +interface MvpView \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/custom/BaseMvpCustomView.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/custom/BaseMvpCustomView.kt new file mode 100644 index 0000000000..58f7ed38ff --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/custom/BaseMvpCustomView.kt @@ -0,0 +1,51 @@ +package com.tangem.tangemtest._arch.mvp.view.custom + +import android.view.View +import com.tangem.tangemtest._arch.mvp.presenter.MvpPresenter +import com.tangem.tangemtest._arch.mvp.view.MvpView + +/** +[REDACTED_AUTHOR] + */ +open class BaseMvpCustomView( + protected val mainView: View, + protected val presenter: MvpPresenter +) : MvpCustomView { + + override fun onViewCreated() { + presenter.created() + presenter.viewCreated() + } + + override fun onStart() { + presenter.started() + } + + override fun onResume() { + presenter.resumed() + } + + override fun onPause() { + presenter.paused() + } + + override fun onStop() { + presenter.stopped() + } + + override fun onDestroyView() { + presenter.destroyView() + } + + override fun onViewDestroyed() { + presenter.viewDestroyed() + } + + override fun onDetach() { + presenter.detached() + } + + protected fun bindView(id: Int): T { + return mainView.findViewById(id) as T + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/custom/MvpCustomView.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/custom/MvpCustomView.kt new file mode 100644 index 0000000000..d9862bcb84 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/custom/MvpCustomView.kt @@ -0,0 +1,18 @@ +package com.tangem.tangemtest._arch.mvp.view.custom + +import com.tangem.tangemtest._arch.mvp.view.MvpView + +/** +[REDACTED_AUTHOR] + */ +interface MvpCustomView : MvpView { + + fun onViewCreated() + fun onStart() + fun onResume() + fun onPause() + fun onStop() + fun onDestroyView() + fun onViewDestroyed() + fun onDetach() +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/BaseCardActionFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/BaseCardActionFragment.kt index 34cff55ae5..b90ff4438a 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/BaseCardActionFragment.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/BaseCardActionFragment.kt @@ -16,8 +16,8 @@ import com.tangem.tangemtest.R import com.tangem.tangemtest.card_use_cases.ui.widgets.ParameterWidget import com.tangem.tangemtest.card_use_cases.view_models.ParamsViewModel import com.tangem.tangemtest.commons.Action -import com.tangem.tangemtest.commons.LayoutHolder import ru.dev.gbixahue.eu4d.lib.android.global.log.Log +import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder /** [REDACTED_AUTHOR] diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/view_models/ParamsViewModel.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/view_models/ParamsViewModel.kt index 407c9e2056..2c2043c885 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/view_models/ParamsViewModel.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/view_models/ParamsViewModel.kt @@ -13,10 +13,10 @@ import com.tangem.tangemtest.card_use_cases.models.params.manager.ParamsManager import com.tangem.tangemtest.card_use_cases.models.params.manager.ParamsManagerFactory import com.tangem.tangemtest.commons.Action import com.tangem.tangemtest.commons.performAction -import com.tangem.tangemtest.commons.postUI import com.tangem.tasks.ScanEvent import com.tangem.tasks.TaskError import com.tangem.tasks.TaskEvent +import ru.dev.gbixahue.eu4d.lib.android.global.threading.postUI /** [REDACTED_AUTHOR] diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/commons/abstracts.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/abstracts.kt index b58468b10e..14d7dca27f 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/commons/abstracts.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/abstracts.kt @@ -3,6 +3,6 @@ package com.tangem.tangemtest.commons /** [REDACTED_AUTHOR] */ -interface LayoutHolder { - fun getLayoutId(): Int +interface OnBackPressHandler { + fun onBackPressed(): Boolean } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/commons/threading.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/threading.kt deleted file mode 100644 index 0e7a797614..0000000000 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/commons/threading.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.tangem.tangemtest.commons - -import android.os.Handler -import android.os.HandlerThread -import android.os.Looper - -/** -[REDACTED_AUTHOR] - */ -object Threading { - val uiHandler: Handler = Handler(Looper.getMainLooper()) - val workHandler: Handler = Handler(HandlerThread("Application worker thread").apply { start() }.looper) - - fun postInCurrentThread(msTime: Long, func: () -> Unit) { - Handler().postDelayed({ func() }, msTime) - } -} - - -fun post(msTime: Long, func: () -> Unit) { - Threading.postInCurrentThread(msTime, func) -} - -fun postUI(msTime: Long = 0, func: () -> Unit) { - if (msTime > 0) Threading.uiHandler.postDelayed({ func() }, msTime) else Threading.uiHandler.post(func) -} - -fun postWork(msTime: Long = 0, func: () -> Unit) { - if (msTime > 0) Threading.workHandler.postDelayed({ func() }, msTime) else Threading.workHandler.post(func) -} \ No newline at end of file From 58462ba3607958f581dbf51bc45162276fc4cffa Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 18 Mar 2020 16:35:59 +0300 Subject: [PATCH 08/68] Updated on 2026-08-14 --- .../com/tangem/tangemtest/_arch/live_data.kt | 44 +++++++++ .../_arch/mvp/view/BaseMvpFragment.kt | 2 +- .../_main/entry_point/EntryPointFragment.kt | 22 ++--- .../models/params/manager/card_actions.kt | 8 +- .../models/params/manager/factory.kt | 8 +- .../ui/BaseCardActionFragment.kt | 63 ++++++------- .../card_use_cases/ui/ScanActionFragment.kt | 4 +- .../card_use_cases/ui/SignActionFragment.kt | 4 +- .../ui/widgets/ParameterWidget.kt | 93 +++++++++++-------- .../view_models/ParamsViewModel.kt | 89 +++++++----------- .../tangem/tangemtest/commons/navigation.kt | 4 +- 11 files changed, 186 insertions(+), 155 deletions(-) create mode 100644 tangem-demo/src/main/java/com/tangem/tangemtest/_arch/live_data.kt diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/live_data.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/live_data.kt new file mode 100644 index 0000000000..943023a1c1 --- /dev/null +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/live_data.kt @@ -0,0 +1,44 @@ +package com.tangem.tangemtest._arch + +import android.util.Log +import androidx.annotation.MainThread +import androidx.annotation.Nullable +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.Observer +import java.util.concurrent.atomic.AtomicBoolean + +/** +[REDACTED_AUTHOR] + */ +class SingleLiveEvent : MutableLiveData() { + private val mPending: AtomicBoolean = AtomicBoolean(false) + + override fun observe(owner: LifecycleOwner, observer: Observer) { + if (hasActiveObservers()) { + Log.w(TAG, "Multiple observers registered but only one will be notified of changes.") + } + + // Observe the internal MutableLiveData + super.observe(owner, Observer { + if (mPending.compareAndSet(true, false)) { + observer.onChanged(it) + } + }) + } + + @MainThread + override fun setValue(@Nullable t: T?) { + mPending.set(true) + super.setValue(t) + } + + @MainThread + fun call() { + setValue(null) + } + + companion object { + private const val TAG = "SingleLiveEvent" + } +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/BaseMvpFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/BaseMvpFragment.kt index 10ecdc6d32..9d100ae08e 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/BaseMvpFragment.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_arch/mvp/view/BaseMvpFragment.kt @@ -18,7 +18,7 @@ abstract class BaseMvpFragment : Fragment(), MvpView, OnBackPressHandler { protected lateinit var mainView: View protected var presenter: MvpPresenter? = null - protected abstract fun getMvpPresenter(): MvpPresenter? + protected abstract fun getMvpPresenter(): MvpPresenter override fun onAttach(context: Context) { super.onAttach(context) diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/_main/entry_point/EntryPointFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/_main/entry_point/EntryPointFragment.kt index ed27931b8a..8859a79897 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/_main/entry_point/EntryPointFragment.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/_main/entry_point/EntryPointFragment.kt @@ -11,7 +11,7 @@ import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.tangem.tangemtest.R -import com.tangem.tangemtest.commons.Action +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.* @@ -55,16 +55,16 @@ class EntryPointFragment : Fragment() { private fun getNavigateOptions(): MutableList { return mutableListOf( - NavigateOptions(Action.Scan, R.id.action_nav_entry_point_to_nav_scan), - NavigateOptions(Action.Sign, R.id.action_nav_entry_point_to_nav_sign), - NavigateOptions(Action.CreateWallet, R.id.action_nav_entry_point_to_nav_wallet_create), - NavigateOptions(Action.PurgeWallet, R.id.action_nav_entry_point_to_nav_wallet_purge), - NavigateOptions(Action.ReadIssuerData, R.id.action_nav_entry_point_to_nav_issuer_read_data), - NavigateOptions(Action.WriteIssuerData, R.id.action_nav_entry_point_to_nav_issuer_write_data), - NavigateOptions(Action.ReadIssuerExData, R.id.action_nav_entry_point_to_nav_issuer_read_ex_data), - NavigateOptions(Action.WriteIssuerExData, R.id.action_nav_entry_point_to_nav_issuer_write_ex_data), - NavigateOptions(Action.ReadUserData, R.id.action_nav_entry_point_to_nav_user_read_data), - NavigateOptions(Action.WriteUserData, R.id.action_nav_entry_point_to_nav_user_write_data) + 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.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), + NavigateOptions(ActionType.WriteIssuerData, R.id.action_nav_entry_point_to_nav_issuer_write_data), + NavigateOptions(ActionType.ReadIssuerExData, R.id.action_nav_entry_point_to_nav_issuer_read_ex_data), + NavigateOptions(ActionType.WriteIssuerExData, R.id.action_nav_entry_point_to_nav_issuer_write_ex_data), + NavigateOptions(ActionType.ReadUserData, R.id.action_nav_entry_point_to_nav_user_read_data), + NavigateOptions(ActionType.WriteUserData, R.id.action_nav_entry_point_to_nav_user_write_data) ) } } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/card_actions.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/card_actions.kt index c6474873ac..79df4fa6bd 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/card_actions.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/card_actions.kt @@ -55,10 +55,10 @@ class SignAction : BaseCardAction() { } override fun getActionByTag(tag: TlvTag, attrs: AttrForAction): ((ActionCallback) -> Unit)? { - if (tag != TlvTag.CardId) return null - val pCardId = ParamsManager.findParameter(tag, attrs.paramsList) ?: return null - - return if (pCardId.data == null) { callback -> ScanAction().executeMainAction(attrs, callback) } else null + return when (tag) { + TlvTag.CardId -> { callback -> ScanAction().executeMainAction(attrs, callback) } + else -> null + } } private fun findHashes(): Array { diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/factory.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/factory.kt index 3458fcdfa1..5e9bc9624f 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/factory.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/factory.kt @@ -1,18 +1,18 @@ package com.tangem.tangemtest.card_use_cases.models.params.manager -import com.tangem.tangemtest.commons.Action +import com.tangem.tangemtest.commons.ActionType import ru.dev.gbixahue.eu4d.lib.kotlin.common.BaseTypedHolder /** [REDACTED_AUTHOR] */ -class ParamsManagerFactory : BaseTypedHolder() { +class ParamsManagerFactory : BaseTypedHolder() { companion object { fun createFactory(): ParamsManagerFactory { return ParamsManagerFactory().apply { - register(Action.Scan, ScanParamsManager()) - register(Action.Sign, SignParamsManager()) + register(ActionType.Scan, ScanParamsManager()) + register(ActionType.Sign, SignParamsManager()) } } } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/BaseCardActionFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/BaseCardActionFragment.kt index b90ff4438a..6ae2504a1b 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/BaseCardActionFragment.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/BaseCardActionFragment.kt @@ -12,10 +12,15 @@ import androidx.lifecycle.Observer import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton import com.google.android.material.snackbar.BaseTransientBottomBar import com.google.android.material.snackbar.Snackbar +import com.tangem.CardManager +import com.tangem.tangem_sdk_new.extensions.init import com.tangem.tangemtest.R +import com.tangem.tangemtest.card_use_cases.models.params.manager.ParamsManager +import com.tangem.tangemtest.card_use_cases.models.params.manager.ParamsManagerFactory import com.tangem.tangemtest.card_use_cases.ui.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.commons.Action +import com.tangem.tangemtest.commons.ActionType import ru.dev.gbixahue.eu4d.lib.android.global.log.Log import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder @@ -24,33 +29,21 @@ import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder */ abstract class BaseCardActionFragment : Fragment(), LayoutHolder { - protected lateinit var mainView: View + protected val mainView: View by lazy { view!! } protected val incomingParamsContainer: ViewGroup by lazy { mainView.findViewById(R.id.ll_incoming_params_container) } + protected val viewModel: ParamsViewModel by viewModels { ActionViewModelFactory(paramsManager) } - protected val viewModel: ParamsViewModel by viewModels() - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - Log.d(this, "onCreateView") - mainView = inflater.inflate(getLayoutId(), container, false) - return mainView - } + private val paramsManager: ParamsManager by lazy { ParamsManagerFactory.createFactory().get(getAction())!! } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) Log.d(this, "onViewCreated") - val activity = activity ?: return - try { - viewModel.init(activity, getAction()) - initFab() - val widgetList = createWidgets() - subscribeToViewModelChanges(widgetList) - } catch (e: Exception) { - Log.e(this, e) - showSnackbarMessage(e.toString()) - } + viewModel.setCardManager(CardManager.init(requireActivity())) + initFab() + createWidgets { subscribeToViewModelChanges(it) } } private fun initFab() { @@ -61,28 +54,30 @@ abstract class BaseCardActionFragment : Fragment(), LayoutHolder { fab.setOnClickListener { viewModel.invokeMainAction() } } - private fun createWidgets(): MutableList { + private fun createWidgets(callback: (List) -> Unit) { Log.d(this, "createWidgets") - - val widgetList = mutableListOf() - viewModel.getInitialParams()?.forEach { param -> - val widget = ParameterWidget(inflateParamView(incomingParamsContainer), param) - widget.onParameterValueChanged = { viewModel.userChangedParameter(it) } - widget.onParameterAction = viewModel.getParameterAction(param.tlvTag) - widgetList.add(widget) - } - return widgetList + viewModel.ldParams.observe(viewLifecycleOwner, Observer { paramsList -> + val widgetList = mutableListOf() + paramsList.forEach { param -> + val widget = ParameterWidget(inflateParamView(incomingParamsContainer), param) + widget.onValueChanged = { tag, value -> viewModel.userChangedParameter(tag, value) } + widget.onActionBtnClickListener = viewModel.getParameterAction(param.tlvTag) + widgetList.add(widget) + } + callback(widgetList) + }) } - private fun subscribeToViewModelChanges(widgetList: MutableList) { + private fun subscribeToViewModelChanges(widgetList: List) { Log.d(this, "subscribeToViewModelChanges") + val tvResponse by lazy { mainView.findViewById(R.id.tv_action_response_json) } viewModel.ldResponse.observe(viewLifecycleOwner, Observer { Log.d(this, "action response: ${if (it.length > 50) it.substring(0..50) else it}") - mainView.findViewById(R.id.tv_action_response_json).text = it + tvResponse.text = it }) - viewModel.ldError.observe(viewLifecycleOwner, Observer { showSnackbarMessage(it) }) - viewModel.ldIncomingParameter.observe(viewLifecycleOwner, Observer { param -> + viewModel.seError.observe(viewLifecycleOwner, Observer { showSnackbarMessage(it) }) + viewModel.seIncomingParameter.observe(viewLifecycleOwner, Observer { param -> Log.d(this, "parameter changed from VM - name: ${param.tlvTag.name}, value:${param.data}") widgetList.firstOrNull { it.tlvTag == param.tlvTag }?.changeParamValue(param.data) }) @@ -100,5 +95,5 @@ abstract class BaseCardActionFragment : Fragment(), LayoutHolder { return view } - abstract fun getAction(): Action + abstract fun getAction(): ActionType } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/ScanActionFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/ScanActionFragment.kt index 5b11212866..fe7874b438 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/ScanActionFragment.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/ScanActionFragment.kt @@ -1,7 +1,7 @@ package com.tangem.tangemtest.card_use_cases.ui import com.tangem.tangemtest.R -import com.tangem.tangemtest.commons.Action +import com.tangem.tangemtest.commons.ActionType /** [REDACTED_AUTHOR] @@ -10,5 +10,5 @@ class ScanActionFragment : BaseCardActionFragment() { override fun getLayoutId(): Int = R.layout.fg_action_card_scan - override fun getAction(): Action = Action.Scan + override fun getAction(): ActionType = ActionType.Scan } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/SignActionFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/SignActionFragment.kt index 82dee2a968..ab0d643941 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/SignActionFragment.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/SignActionFragment.kt @@ -1,7 +1,7 @@ package com.tangem.tangemtest.card_use_cases.ui import com.tangem.tangemtest.R -import com.tangem.tangemtest.commons.Action +import com.tangem.tangemtest.commons.ActionType /** [REDACTED_AUTHOR] @@ -10,5 +10,5 @@ class SignActionFragment : BaseCardActionFragment() { override fun getLayoutId(): Int = R.layout.fg_action_card_sign - override fun getAction(): Action = Action.Sign + override fun getAction(): ActionType = ActionType.Sign } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/widgets/ParameterWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/widgets/ParameterWidget.kt index 925fe91335..9e8333d0a2 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/widgets/ParameterWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/widgets/ParameterWidget.kt @@ -12,60 +12,61 @@ import androidx.transition.TransitionManager import com.tangem.common.tlv.TlvTag import com.tangem.tangemtest.R import com.tangem.tangemtest.card_use_cases.models.params.manager.IncomingParameter -import com.tangem.tangemtest.commons.Action +import com.tangem.tangemtest.commons.ActionType import ru.dev.gbixahue.eu4d.lib.android.global.log.Log import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf /** [REDACTED_AUTHOR] */ -class ParameterWidget(parent: View, private val model: IncomingParameter) { +class ParameterWidget(parent: View, model: IncomingParameter) { + + val tlvTag: TlvTag = model.tlvTag + + var onValueChanged: ((TlvTag, Any?) -> Unit)? = null + var onActionBtnClickListener: (() -> Unit)? = null + set(value) { + field = value + toggleActionBtnVisibility() + } private val tvName: TextView = parent.findViewById(R.id.tv_param_name) private val etValue: EditText = parent.findViewById(R.id.tv_param_value) private val btnAction: Button = parent.findViewById(R.id.btn_action) private val valueWatcher: TextWatcher by lazy { getWatcher() } - val tlvTag: TlvTag = model.tlvTag - - private var parameterActionStorage: (() -> Unit)? = null - var onParameterAction: (() -> Unit)? = null - set(value) { - TransitionManager.beginDelayedTransition(etValue.parent as ViewGroup, AutoTransition()) - if (value != null) { - parameterActionStorage = value - setActionButtonTitle() - btnAction.visibility = View.VISIBLE - } else { - btnAction.visibility = View.GONE - } - field = value - } - - var onParameterValueChanged: ((IncomingParameter) -> Unit)? = null + private var actionBtnVisibilityState: Int = btnAction.visibility + private var value: Any? = model.data init { tvName.text = model.tlvTag.name + etValue.setText(stringOf(model.data)) etValue.addTextChangedListener(valueWatcher) - btnAction.setOnClickListener { onParameterAction?.invoke() } + btnAction.setOnClickListener { onActionBtnClickListener?.invoke() } + btnAction.text = btnAction.context.getString(getActionResName()) + toggleActionBtnVisibility() } - private fun setActionButtonTitle() { - val action = when (model.tlvTag) { - TlvTag.CardId -> Action.Scan - else -> Action.Unknown + fun changeParamValue(data: Any?, silent: Boolean = true) { + Log.d(this, "changeParamValue: tag: $tlvTag, value: $data") + value = data + toggleActionBtnVisibility() + if (silent) { + etValue.removeTextChangedListener(valueWatcher) + etValue.setText(stringOf(value)) + etValue.addTextChangedListener(valueWatcher) + } else { + etValue.setText(stringOf(value)) } - btnAction.setText(action.resName) } private fun getWatcher(): TextWatcher { return object : TextWatcher { - override fun afterTextChanged(s: Editable?) { - val newValue = stringOf(s) - onParameterAction = if (newValue.isEmpty() && onParameterAction == null) parameterActionStorage - else null - model.data = newValue - onParameterValueChanged?.invoke(model) + override fun afterTextChanged(editable: Editable?) { + Log.d(this, "afterTextChanged $editable") + value = if (editable.isNullOrEmpty()) null else editable.toString() + toggleActionBtnVisibility() + onValueChanged?.invoke(tlvTag, value) } override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} @@ -74,15 +75,27 @@ class ParameterWidget(parent: View, private val model: IncomingParameter) { } } - fun changeParamValue(data: Any?, silent: Boolean = true) { - Log.d(this, "changeParamValue: tag: $tlvTag, value: $data") - if (silent) { - etValue.removeTextChangedListener(valueWatcher) - etValue.setText(stringOf(data)) - etValue.addTextChangedListener(valueWatcher) - } else { - etValue.setText(stringOf(data)) + private fun getActionResName(): Int { + val action = when (tlvTag) { + TlvTag.CardId -> ActionType.Scan + else -> ActionType.Unknown + } + return action.resName + } + + private fun toggleActionBtnVisibility() { + fun switchVisibilityState(newState: Int) { + actionBtnVisibilityState = newState + TransitionManager.beginDelayedTransition(etValue.parent as ViewGroup, AutoTransition()) + btnAction.visibility = actionBtnVisibilityState + } + when { + onActionBtnClickListener == null -> { + if (actionBtnVisibilityState == View.GONE) return + switchVisibilityState(View.GONE) + } + value == null && actionBtnVisibilityState != View.VISIBLE -> switchVisibilityState(View.VISIBLE) + value != null && actionBtnVisibilityState != View.GONE -> switchVisibilityState(View.GONE) } - onParameterAction = null } } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/view_models/ParamsViewModel.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/view_models/ParamsViewModel.kt index 2c2043c885..deebec0cf5 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/view_models/ParamsViewModel.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/view_models/ParamsViewModel.kt @@ -1,65 +1,57 @@ package com.tangem.tangemtest.card_use_cases.view_models import androidx.annotation.UiThread -import androidx.fragment.app.FragmentActivity -import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider import com.google.gson.GsonBuilder +import com.tangem.CardManager +import com.tangem.commands.Card import com.tangem.common.tlv.TlvTag -import com.tangem.tangemtest.card_use_cases.models.CardContext +import com.tangem.tangemtest._arch.SingleLiveEvent import com.tangem.tangemtest.card_use_cases.models.params.manager.IncomingParameter import com.tangem.tangemtest.card_use_cases.models.params.manager.ParamsManager -import com.tangem.tangemtest.card_use_cases.models.params.manager.ParamsManagerFactory -import com.tangem.tangemtest.commons.Action import com.tangem.tangemtest.commons.performAction import com.tangem.tasks.ScanEvent import com.tangem.tasks.TaskError import com.tangem.tasks.TaskEvent -import ru.dev.gbixahue.eu4d.lib.android.global.threading.postUI /** [REDACTED_AUTHOR] */ -class ParamsViewModel : ViewModel() { - val ldResponse: MutableLiveData = MutableLiveData() - val ldError: MutableLiveData = MutableLiveData() - val ldIncomingParameter: MutableLiveData = MutableLiveData() - lateinit var ldCardContext: MutableLiveData - private set +class ActionViewModelFactory(private val manager: ParamsManager) : ViewModelProvider.NewInstanceFactory() { + override fun create(modelClass: Class): T = ParamsViewModel(manager) as T +} - private lateinit var ldParamsManager: LiveData - private lateinit var notifier: Notifier +class ParamsViewModel(val paramsManager: ParamsManager) : ViewModel() { - // call before any subscriptions - fun init(context: FragmentActivity, action: Action) { - if (::ldCardContext.isInitialized && ::ldParamsManager.isInitialized) return + val ldCard = MutableLiveData() + val ldIsVerified = MutableLiveData() + val ldResponse = MutableLiveData() + val ldParams = MutableLiveData(paramsManager.getParams()) - val factory = ParamsManagerFactory.createFactory() - val manager = factory.get(action) ?: throw NotImplementedError( - "ParamsManager for the ${context.getString(action.resName)} not implemented yet") + val seError: MutableLiveData = SingleLiveEvent() + val seIncomingParameter: MutableLiveData = SingleLiveEvent() - ldParamsManager = MutableLiveData(manager) - ldCardContext = MutableLiveData(CardContext().init(context)) - notifier = Notifier(this) + private val notifier: Notifier = Notifier(this) + private lateinit var cardManager: CardManager + + fun setCardManager(cardManager: CardManager) { + this.cardManager = cardManager } - fun getInitialParams(): List? { - return ldParamsManager.value?.getParams() - } - - fun userChangedParameter(param: IncomingParameter) { - parameterChanged(param.tlvTag, param.data) + fun userChangedParameter(tlvTag: TlvTag, value: Any?) { + parameterChanged(tlvTag, value) } private fun parameterChanged(tlvTag: TlvTag, value: Any?) { - ldParamsManager.value?.parameterChanged(tlvTag, value) { notifier.notifyParameterChanges(it) } + paramsManager.parameterChanged(tlvTag, value) { notifier.notifyParameterChanges(it) } } //invokes Scan, Sign etc... fun invokeMainAction() { - performAction(ldParamsManager.value, ldCardContext.value?.cardManager) { paramsManager, cardManager -> + performAction(paramsManager, cardManager) { paramsManager, cardManager -> paramsManager.invokeMainAction(cardManager) { response, listOfChangedParams -> notifier.handleActionResult(response, listOfChangedParams) } @@ -67,8 +59,6 @@ class ParamsViewModel : ViewModel() { } fun getParameterAction(tag: TlvTag): (() -> Unit)? { - val paramsManager = ldParamsManager.value ?: return null - val cardManager = ldCardContext.value?.cardManager ?: return null val parameterFunction = paramsManager.getActionByTag(tag, cardManager) ?: return null return { @@ -85,57 +75,46 @@ internal class Notifier(private val vm: ParamsViewModel) { private var notShowedError: TaskError? = null fun handleActionResult(response: TaskEvent<*>, list: List) { - postUI { notifyParameterChanges(list) } + notifyParameterChanges(list) handleResponse(response) } @UiThread fun notifyParameterChanges(list: List) { - list.forEach { vm.ldIncomingParameter.value = it } + list.forEach { vm.seIncomingParameter.postValue(it) } } fun handleResponse(response: TaskEvent<*>) { val taskEvent = response as? TaskEvent<*> ?: return - postUI { - when (taskEvent) { - is TaskEvent.Completion -> handleCompletionEvent(taskEvent) - is TaskEvent.Event -> handleDataEvent(taskEvent.data) - } + when (taskEvent) { + is TaskEvent.Completion -> handleCompletionEvent(taskEvent) + is TaskEvent.Event -> handleDataEvent(taskEvent.data) } } - @UiThread private fun handleDataEvent(event: Any?) { when (event) { is ScanEvent.OnReadEvent -> { - val cardContext = vm.ldCardContext.value ?: return - - cardContext.card = event.card - vm.ldCardContext.value = cardContext - vm.ldResponse.value = gsonConverter.toJson(event) + vm.ldCard.postValue(event.card) + vm.ldResponse.postValue(gsonConverter.toJson(event)) } is ScanEvent.OnVerifyEvent -> { - val cardContext = vm.ldCardContext.value ?: return - - cardContext.isVerified = true - vm.ldCardContext.value = cardContext - + vm.ldIsVerified.postValue(true) } - else -> vm.ldResponse.value = gsonConverter.toJson(event) + else -> vm.ldResponse.postValue(gsonConverter.toJson(event)) } } - @UiThread private fun handleCompletionEvent(taskEvent: TaskEvent.Completion<*>) { val error: TaskError = taskEvent.error ?: return when (error) { is TaskError.UserCancelled -> { if (notShowedError == null) { - vm.ldError.value = "User was cancelled" + vm.seError.postValue("User was cancelled") } else { - vm.ldError.value = "Error description not implemented. Code: ${notShowedError!!.code}" + vm.seError.postValue("Error description not implemented. Code: ${notShowedError!!.code}") notShowedError = null } } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/commons/navigation.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/navigation.kt index c4acf6935e..05cf3df94d 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/commons/navigation.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/commons/navigation.kt @@ -20,9 +20,9 @@ fun getDefaultNavigationOptions(): NavOptions { } } -data class NavigateOptions(val name: Action, val destinationId: Int) +data class NavigateOptions(val name: ActionType, val destinationId: Int) -enum class Action(@StringRes val resName: Int) { +enum class ActionType(@StringRes val resName: Int) { Scan(R.string.action_card_scan), Sign(R.string.action_card_sign), CreateWallet(R.string.action_wallet_create), From ad014e143e925d3f4cf1537b51f0ea205e7434ab Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 19 Mar 2020 10:56:33 +0300 Subject: [PATCH 09/68] Updated on 2026-08-14 --- tangem-demo/build.gradle | 3 +- .../{models => domain}/CardContext.kt | 2 +- .../card_action}/card_actions.kt | 26 ++++++---- .../params_manager}/factory.kt | 2 +- .../modifiers/after_action_modifiers.kt | 8 +-- .../modifiers/param_change_consequence.kt | 4 +- .../params_manager}/params_managers.kt | 21 ++++---- .../ui/BaseCardActionFragment.kt | 16 ++++-- .../ui/widgets/ParameterWidget.kt | 16 +++--- .../view_models/ParamsViewModel.kt | 4 +- .../main/res/layout/fg_action_card_scan.xml | 6 ++- .../main/res/layout/fg_action_card_sign.xml | 6 ++- .../main/res/layout/w_card_incoming_param.xml | 52 ++++++------------- 13 files changed, 84 insertions(+), 82 deletions(-) rename tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/{models => domain}/CardContext.kt (92%) rename tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/{models/params/manager => domain/card_action}/card_actions.kt (68%) rename tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/{models/params/manager => domain/params_manager}/factory.kt (88%) rename tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/{models/params/manager => domain/params_manager}/modifiers/after_action_modifiers.kt (74%) rename tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/{models/params/manager => domain/params_manager}/modifiers/param_change_consequence.kt (86%) rename tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/{models/params/manager => domain/params_manager}/params_managers.kt (81%) diff --git a/tangem-demo/build.gradle b/tangem-demo/build.gradle index baed8de1b6..e489a1ec36 100644 --- a/tangem-demo/build.gradle +++ b/tangem-demo/build.gradle @@ -48,9 +48,10 @@ dependencies { implementation "androidx.navigation:navigation-ui-ktx:2.2.1" implementation "androidx.recyclerview:recyclerview:1.2.0-alpha01" implementation "com.google.android.material:material:1.2.0-alpha05" + implementation "androidx.viewpager2:viewpager2:1.0.0" implementation 'com.google.code.gson:gson:2.8.6' - implementation 'com.github.gbIxaHue:eu4d:0.2.3' + implementation 'com.github.gbIxaHue:eu4d:0.3.1' implementation 'io.reactivex.rxjava2:rxjava:2.2.6' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/CardContext.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/CardContext.kt similarity index 92% rename from tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/CardContext.kt rename to tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/CardContext.kt index 22af4ca879..f0137ce272 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/CardContext.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/CardContext.kt @@ -1,4 +1,4 @@ -package com.tangem.tangemtest.card_use_cases.models +package com.tangem.tangemtest.card_use_cases.domain import androidx.fragment.app.FragmentActivity import com.tangem.CardManager diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/card_actions.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/card_action/card_actions.kt similarity index 68% rename from tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/card_actions.kt rename to tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/card_action/card_actions.kt index 79df4fa6bd..51ed8731de 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/card_actions.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/card_action/card_actions.kt @@ -1,10 +1,13 @@ -package com.tangem.tangemtest.card_use_cases.models.params.manager +package com.tangem.tangemtest.card_use_cases.domain.card_action import com.tangem.CardManager import com.tangem.common.tlv.TlvTag -import com.tangem.tangemtest.card_use_cases.models.params.manager.modifiers.AfterActionModification -import com.tangem.tangemtest.card_use_cases.models.params.manager.modifiers.AfterScanModifier -import com.tangem.tangemtest.card_use_cases.models.params.manager.modifiers.ParamsChangeConsequence +import com.tangem.tangemtest.card_use_cases.domain.params_manager.ActionCallback +import com.tangem.tangemtest.card_use_cases.domain.params_manager.IncomingParameter +import com.tangem.tangemtest.card_use_cases.domain.params_manager.findParameter +import com.tangem.tangemtest.card_use_cases.domain.params_manager.modifiers.AfterActionModification +import com.tangem.tangemtest.card_use_cases.domain.params_manager.modifiers.AfterScanModifier +import com.tangem.tangemtest.card_use_cases.domain.params_manager.modifiers.ParamsChangeConsequence import com.tangem.tasks.TaskEvent import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf @@ -49,9 +52,12 @@ class ScanAction : BaseCardAction() { class SignAction : BaseCardAction() { override fun executeMainAction(attrs: AttrForAction, callback: ActionCallback) { - val hashes = findHashes() - val cardId = ParamsManager.findParameter(TlvTag.CardId, attrs.paramsList)?.data - attrs.cardManager.sign(hashes, stringOf(cardId)) { handleResponse(it, null, attrs, callback) } + val dataForHashing = attrs.paramsList.findParameter(TlvTag.TransactionOutHash) ?: return + + val arHashes = createHashes(stringOf(dataForHashing.data)) + val cardId = attrs.paramsList.findParameter(TlvTag.CardId)?.data ?: return + + attrs.cardManager.sign(arHashes, stringOf(cardId)) { handleResponse(it, null, attrs, callback) } } override fun getActionByTag(tag: TlvTag, attrs: AttrForAction): ((ActionCallback) -> Unit)? { @@ -61,9 +67,7 @@ class SignAction : BaseCardAction() { } } - private fun findHashes(): Array { - val hash1 = ByteArray(32) { 1 } - val hash2 = ByteArray(32) { 2 } - return arrayOf(hash1, hash2) + private fun createHashes(value: String): Array { + return arrayOf(value.toByteArray()) } } \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/factory.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/params_manager/factory.kt similarity index 88% rename from tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/factory.kt rename to tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/params_manager/factory.kt index 5e9bc9624f..54a3784a7c 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/factory.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/params_manager/factory.kt @@ -1,4 +1,4 @@ -package com.tangem.tangemtest.card_use_cases.models.params.manager +package com.tangem.tangemtest.card_use_cases.domain.params_manager import com.tangem.tangemtest.commons.ActionType import ru.dev.gbixahue.eu4d.lib.kotlin.common.BaseTypedHolder diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/after_action_modifiers.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/params_manager/modifiers/after_action_modifiers.kt similarity index 74% rename from tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/after_action_modifiers.kt rename to tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/params_manager/modifiers/after_action_modifiers.kt index 8a72f0b514..c504238c0f 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/after_action_modifiers.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/params_manager/modifiers/after_action_modifiers.kt @@ -1,8 +1,8 @@ -package com.tangem.tangemtest.card_use_cases.models.params.manager.modifiers +package com.tangem.tangemtest.card_use_cases.domain.params_manager.modifiers import com.tangem.common.tlv.TlvTag -import com.tangem.tangemtest.card_use_cases.models.params.manager.IncomingParameter -import com.tangem.tangemtest.card_use_cases.models.params.manager.ParamsManager +import com.tangem.tangemtest.card_use_cases.domain.params_manager.IncomingParameter +import com.tangem.tangemtest.card_use_cases.domain.params_manager.findParameter import com.tangem.tasks.ScanEvent import com.tangem.tasks.TaskEvent @@ -19,7 +19,7 @@ interface AfterActionModification { class AfterScanModifier : AfterActionModification { override fun modify(taskEvent: TaskEvent<*>, paramsList: List): List { - val parameter = ParamsManager.findParameter(TlvTag.CardId, paramsList) ?: return listOf() + val parameter = paramsList.findParameter(TlvTag.CardId) ?: return listOf() return if (taskEvent is TaskEvent.Event && taskEvent.data is ScanEvent.OnReadEvent) { parameter.data = (taskEvent.data as ScanEvent.OnReadEvent).card.cardId diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/param_change_consequence.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/params_manager/modifiers/param_change_consequence.kt similarity index 86% rename from tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/param_change_consequence.kt rename to tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/params_manager/modifiers/param_change_consequence.kt index 60707484b7..e2c2148bd9 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/modifiers/param_change_consequence.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/params_manager/modifiers/param_change_consequence.kt @@ -1,7 +1,7 @@ -package com.tangem.tangemtest.card_use_cases.models.params.manager.modifiers +package com.tangem.tangemtest.card_use_cases.domain.params_manager.modifiers import com.tangem.common.tlv.TlvTag -import com.tangem.tangemtest.card_use_cases.models.params.manager.IncomingParameter +import com.tangem.tangemtest.card_use_cases.domain.params_manager.IncomingParameter /** [REDACTED_AUTHOR] diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/params_managers.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/params_manager/params_managers.kt similarity index 81% rename from tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/params_managers.kt rename to tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/params_manager/params_managers.kt index a5f4e070d9..c22861de59 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/models/params/manager/params_managers.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/domain/params_manager/params_managers.kt @@ -1,9 +1,12 @@ -package com.tangem.tangemtest.card_use_cases.models.params.manager +package com.tangem.tangemtest.card_use_cases.domain.params_manager import com.tangem.CardManager import com.tangem.common.tlv.TlvTag -import com.tangem.tangemtest.card_use_cases.models.params.manager.ParamsManager.Companion.findParameter -import com.tangem.tangemtest.card_use_cases.models.params.manager.modifiers.ParamsChangeConsequence +import com.tangem.tangemtest.card_use_cases.domain.card_action.AttrForAction +import com.tangem.tangemtest.card_use_cases.domain.card_action.CardAction +import com.tangem.tangemtest.card_use_cases.domain.card_action.ScanAction +import com.tangem.tangemtest.card_use_cases.domain.card_action.SignAction +import com.tangem.tangemtest.card_use_cases.domain.params_manager.modifiers.ParamsChangeConsequence import com.tangem.tasks.TaskEvent /** @@ -26,10 +29,10 @@ interface ParamsManager { fun invokeMainAction(cardManager: CardManager, callback: ActionCallback) fun getActionByTag(tag: TlvTag, cardManager: CardManager): ((ActionCallback) -> Unit)? - companion object { - fun findParameter(tlvTag: TlvTag, paramsList: List) - : IncomingParameter? = paramsList.firstOrNull { it.tlvTag == tlvTag } - } +} + +fun List.findParameter(tag: TlvTag): IncomingParameter? { + return firstOrNull { it.tlvTag == tag } } abstract class BaseParamsManager(protected val action: CardAction) : ParamsManager { @@ -40,7 +43,7 @@ abstract class BaseParamsManager(protected val action: CardAction) : ParamsManag override fun parameterChanged(tag: TlvTag, value: Any?, callback: AffectedParamsCallback?) { if (paramsList.isEmpty()) return - val foundParam = findParameter(tag, paramsList) ?: return + val foundParam = paramsList.findParameter(tag) ?: return foundParam.data = value applyChangesByAffectedParams(foundParam, callback) @@ -75,7 +78,7 @@ class SignParamsManager : BaseParamsManager(SignAction()) { override fun createParamsList(): List { return listOf( IncomingParameter(TlvTag.CardId, null), - IncomingParameter(TlvTag.TransactionOutHash, "") + IncomingParameter(TlvTag.TransactionOutHash, "Data used for hashing") ) } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/BaseCardActionFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/BaseCardActionFragment.kt index 6ae2504a1b..f59884a96c 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/BaseCardActionFragment.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/BaseCardActionFragment.kt @@ -15,8 +15,8 @@ import com.google.android.material.snackbar.Snackbar import com.tangem.CardManager import com.tangem.tangem_sdk_new.extensions.init import com.tangem.tangemtest.R -import com.tangem.tangemtest.card_use_cases.models.params.manager.ParamsManager -import com.tangem.tangemtest.card_use_cases.models.params.manager.ParamsManagerFactory +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.widgets.ParameterWidget import com.tangem.tangemtest.card_use_cases.view_models.ActionViewModelFactory import com.tangem.tangemtest.card_use_cases.view_models.ParamsViewModel @@ -29,14 +29,20 @@ import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder */ abstract class BaseCardActionFragment : Fragment(), LayoutHolder { - protected val mainView: View by lazy { view!! } protected val incomingParamsContainer: ViewGroup by lazy { mainView.findViewById(R.id.ll_incoming_params_container) } protected val viewModel: ParamsViewModel by viewModels { ActionViewModelFactory(paramsManager) } + protected lateinit var mainView: View private val paramsManager: ParamsManager by lazy { ParamsManagerFactory.createFactory().get(getAction())!! } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + Log.d(this, "onCreateView") + mainView = inflater.inflate(getLayoutId(), container, false) + return mainView + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) Log.d(this, "onViewCreated") @@ -87,12 +93,12 @@ abstract class BaseCardActionFragment : Fragment(), LayoutHolder { Snackbar.make(mainView, message, BaseTransientBottomBar.LENGTH_SHORT).show() } - private fun inflateParamView(where: ViewGroup): View { + private fun inflateParamView(where: ViewGroup): ViewGroup { val inflater = LayoutInflater.from(where.context) val view = inflater.inflate(R.layout.w_card_incoming_param, where, false) where.addView(view) inflater.inflate(R.layout.m_divider_h, where, true) - return view + return view as ViewGroup } abstract fun getAction(): ActionType diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/widgets/ParameterWidget.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/widgets/ParameterWidget.kt index 9e8333d0a2..67915dfc31 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/widgets/ParameterWidget.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/ui/widgets/ParameterWidget.kt @@ -5,13 +5,13 @@ import android.text.TextWatcher import android.view.View import android.view.ViewGroup import android.widget.Button -import android.widget.EditText -import android.widget.TextView 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.common.tlv.TlvTag import com.tangem.tangemtest.R -import com.tangem.tangemtest.card_use_cases.models.params.manager.IncomingParameter +import com.tangem.tangemtest.card_use_cases.domain.params_manager.IncomingParameter import com.tangem.tangemtest.commons.ActionType import ru.dev.gbixahue.eu4d.lib.android.global.log.Log import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf @@ -19,7 +19,7 @@ import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf /** [REDACTED_AUTHOR] */ -class ParameterWidget(parent: View, model: IncomingParameter) { +class ParameterWidget(private val parent: ViewGroup, model: IncomingParameter) { val tlvTag: TlvTag = model.tlvTag @@ -30,8 +30,8 @@ class ParameterWidget(parent: View, model: IncomingParameter) { toggleActionBtnVisibility() } - private val tvName: TextView = parent.findViewById(R.id.tv_param_name) - private val etValue: EditText = parent.findViewById(R.id.tv_param_value) + private val tilValue: TextInputLayout = parent.findViewById(R.id.til_param) + private val etValue: TextInputEditText = parent.findViewById(R.id.et_param) private val btnAction: Button = parent.findViewById(R.id.btn_action) private val valueWatcher: TextWatcher by lazy { getWatcher() } @@ -39,7 +39,7 @@ class ParameterWidget(parent: View, model: IncomingParameter) { private var value: Any? = model.data init { - tvName.text = model.tlvTag.name + tilValue.hint = model.tlvTag.name etValue.setText(stringOf(model.data)) etValue.addTextChangedListener(valueWatcher) btnAction.setOnClickListener { onActionBtnClickListener?.invoke() } @@ -86,7 +86,7 @@ class ParameterWidget(parent: View, model: IncomingParameter) { private fun toggleActionBtnVisibility() { fun switchVisibilityState(newState: Int) { actionBtnVisibilityState = newState - TransitionManager.beginDelayedTransition(etValue.parent as ViewGroup, AutoTransition()) + TransitionManager.beginDelayedTransition(parent, AutoTransition()) btnAction.visibility = actionBtnVisibilityState } when { diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/view_models/ParamsViewModel.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/view_models/ParamsViewModel.kt index deebec0cf5..974c2e0453 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/view_models/ParamsViewModel.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/card_use_cases/view_models/ParamsViewModel.kt @@ -9,8 +9,8 @@ import com.tangem.CardManager import com.tangem.commands.Card import com.tangem.common.tlv.TlvTag import com.tangem.tangemtest._arch.SingleLiveEvent -import com.tangem.tangemtest.card_use_cases.models.params.manager.IncomingParameter -import com.tangem.tangemtest.card_use_cases.models.params.manager.ParamsManager +import com.tangem.tangemtest.card_use_cases.domain.params_manager.IncomingParameter +import com.tangem.tangemtest.card_use_cases.domain.params_manager.ParamsManager import com.tangem.tangemtest.commons.performAction import com.tangem.tasks.ScanEvent import com.tangem.tasks.TaskError diff --git a/tangem-demo/src/main/res/layout/fg_action_card_scan.xml b/tangem-demo/src/main/res/layout/fg_action_card_scan.xml index 2a3ad5529a..bb8668ecf6 100644 --- a/tangem-demo/src/main/res/layout/fg_action_card_scan.xml +++ b/tangem-demo/src/main/res/layout/fg_action_card_scan.xml @@ -22,7 +22,11 @@ - + diff --git a/tangem-demo/src/main/res/layout/fg_action_card_sign.xml b/tangem-demo/src/main/res/layout/fg_action_card_sign.xml index 2a3ad5529a..bb8668ecf6 100644 --- a/tangem-demo/src/main/res/layout/fg_action_card_sign.xml +++ b/tangem-demo/src/main/res/layout/fg_action_card_sign.xml @@ -22,7 +22,11 @@ - + diff --git a/tangem-demo/src/main/res/layout/w_card_incoming_param.xml b/tangem-demo/src/main/res/layout/w_card_incoming_param.xml index 8e60a09379..554f39f7bf 100644 --- a/tangem-demo/src/main/res/layout/w_card_incoming_param.xml +++ b/tangem-demo/src/main/res/layout/w_card_incoming_param.xml @@ -3,47 +3,27 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="48dp"> + android:layout_height="wrap_content"> - - - - - - - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + +