From 56a123f485e20a8cef222c23bc484e92f350ccf1 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 24 Feb 2022 13:43:33 +0300 Subject: [PATCH] Updated on 2026-08-14 --- app/build.gradle | 7 +- .../main/java/com/tangem/tap/MainActivity.kt | 8 +- .../com/tangem/tap/common/extensions/UI.kt | 9 + .../leapfrogWidget/TestLeapfrogFragment.kt | 22 +- .../details/ui/DetailsConfirmFragment.kt | 34 +- .../features/details/ui/DetailsFragment.kt | 59 +-- .../details/ui/DetailsSecurityFragment.kt | 79 ++-- .../ui/walletconnect/SessionsAdapter.kt | 10 +- .../WalletConnectSessionsFragment.kt | 37 +- .../disclaimer/ui/DisclaimerFragment.kt | 15 +- .../tangem/tap/features/home/HomeFragment.kt | 2 +- .../AddressInfoBottomSheetDialog.kt | 36 +- .../products/BaseOnboardingFragment.kt | 26 +- .../products/note/OnboardingNoteFragment.kt | 151 +++---- .../OnboardingOtherCardsFragment.kt | 87 ++-- .../products/twins/ui/TwinsCardsFragment.kt | 415 ++++++++++-------- .../products/wallet/ui/BackupInfoAdapter.kt | 19 +- .../wallet/ui/OnboardingWalletFragment.kt | 215 ++++----- .../wallet/ui/dialogs/AccessCodeDialog.kt | 78 ++-- .../tap/features/send/ui/SendFragment.kt | 32 +- .../stateSubscribers/SendStateSubscriber.kt | 326 +++++++------- .../tap/features/shop/ui/ShopFragment.kt | 66 +-- .../features/tokens/ui/AddTokensFragment.kt | 18 +- .../tokens/ui/adapters/CurrenciesAdapter.kt | 105 ++--- .../tap/features/wallet/ui/BalanceWidget.kt | 157 +++---- .../wallet/ui/WalletDetailsFragment.kt | 238 +++++----- .../tap/features/wallet/ui/WalletFragment.kt | 45 +- .../ui/adapters/PendingTransactionsAdapter.kt | 30 +- .../wallet/ui/adapters/WalletAdapter.kt | 45 +- .../ui/adapters/WarningMessagesAdapter.kt | 52 ++- .../wallet/ui/dialogs/AmountToSendDialog.kt | 48 +- .../ui/dialogs/ChooseTradeActionDialog.kt | 18 +- .../wallet/ui/wallet/MultiWalletView.kt | 111 ++--- .../wallet/ui/wallet/SingleWalletView.kt | 163 ++++--- .../features/wallet/ui/wallet/WalletView.kt | 5 +- .../res/layout/fragment_onboarding_main.xml | 4 +- .../res/layout/fragment_onboarding_wallet.xml | 1 + app/src/main/res/layout/fragment_send.xml | 2 + .../layout/lp_onboarding_done_activation.xml | 1 + 39 files changed, 1485 insertions(+), 1291 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4c9e37ce22..8af93fbaa2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,5 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.firebase.crashlytics' @@ -15,11 +14,9 @@ android { targetSdkVersion 31 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } - androidExtensions { - experimental = true - } buildFeatures { compose true + viewBinding true } buildTypes { release { @@ -150,6 +147,8 @@ dependencies { implementation 'androidx.compose.ui:ui-tooling:1.1.0' implementation "com.google.accompanist:accompanist-appcompat-theme:0.23.0" + implementation 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.6' + testImplementation 'junit:junit:4.13.2' testImplementation "com.google.truth:truth:1.1.3" androidTestImplementation 'androidx.test.ext:junit:1.1.3' diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 29d7ef5595..ed0df5d1f8 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -6,6 +6,7 @@ import android.os.Bundle import android.util.Log import android.view.View import androidx.appcompat.app.AppCompatActivity +import by.kirich1409.viewbindingdelegate.viewBinding import com.google.android.material.snackbar.Snackbar import com.tangem.TangemSdk import com.tangem.operations.backup.BackupService @@ -25,7 +26,7 @@ import com.tangem.tap.domain.TangemSdkManager import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction import com.tangem.tap.features.shop.redux.ShopAction import com.tangem.wallet.R -import kotlinx.android.synthetic.main.activity_main.* +import com.tangem.wallet.databinding.ActivityMainBinding import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -63,6 +64,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler { private var snackbar: Snackbar? = null private val dialogManager = DialogManager() private val intentHandler = IntentHandler() + private val binding: ActivityMainBinding by viewBinding(ActivityMainBinding::bind) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -102,7 +104,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler { override fun onResume() { super.onResume() - notificationsHandler = NotificationsHandler(fragment_container) + notificationsHandler = NotificationsHandler(binding.fragmentContainer) val backStackIsEmpty = supportFragmentManager.backStackEntryCount == 0 val isScannedBefore = store.state.globalState.scanResponse != null @@ -139,7 +141,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler { if (snackbar != null) return snackbar = Snackbar.make( - fragment_container, getString(text), Snackbar.LENGTH_INDEFINITE + binding.fragmentContainer, getString(text), Snackbar.LENGTH_INDEFINITE ) if (buttonTitle != null && action != null) { snackbar?.setAction(getString(buttonTitle), action) diff --git a/app/src/main/java/com/tangem/tap/common/extensions/UI.kt b/app/src/main/java/com/tangem/tap/common/extensions/UI.kt index 182461aa4c..2f1bca0d7f 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/UI.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/UI.kt @@ -37,6 +37,11 @@ fun Context.getColorCompat(@ColorRes colorRes: Int): Int { return ContextCompat.getColor(this, colorRes) } +@ColorInt +fun View.getColor(@ColorRes colorRes: Int): Int { + return ContextCompat.getColor(context, colorRes) +} + fun View.getString(@StringRes id: Int): String { return context.getString(id) } @@ -165,4 +170,8 @@ fun Context.safeStartActivity( } finally { finally?.invoke() } +} + +fun View.getString(resId: Int, vararg formatArgs: Any?): String { + return context.getString(resId, formatArgs) } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/leapfrogWidget/TestLeapfrogFragment.kt b/app/src/main/java/com/tangem/tap/common/leapfrogWidget/TestLeapfrogFragment.kt index 36e92a0ebe..1999c35855 100644 --- a/app/src/main/java/com/tangem/tap/common/leapfrogWidget/TestLeapfrogFragment.kt +++ b/app/src/main/java/com/tangem/tap/common/leapfrogWidget/TestLeapfrogFragment.kt @@ -5,15 +5,18 @@ import android.view.View import android.widget.FrameLayout import androidx.fragment.app.Fragment import androidx.transition.TransitionInflater +import by.kirich1409.viewbindingdelegate.viewBinding import com.tangem.tangem_sdk_new.ui.widget.leapfrogWidget.LeapfrogWidget import com.tangem.tangem_sdk_new.ui.widget.leapfrogWidget.LeapfrogWidgetState import com.tangem.tap.domain.twins.TwinsCardWidget import com.tangem.wallet.R -import kotlinx.android.synthetic.main.test_leapfrog_fragment.* +import com.tangem.wallet.databinding.TestLeapfrogFragmentBinding class TestLeapfrogFragment : Fragment(R.layout.test_leapfrog_fragment) { private lateinit var twinsCardWidget: TwinsCardWidget + private val binding: TestLeapfrogFragmentBinding by viewBinding(TestLeapfrogFragmentBinding::bind) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -28,30 +31,29 @@ class TestLeapfrogFragment : Fragment(R.layout.test_leapfrog_fragment) { val leapfrog = LeapfrogWidget(leapfrogContainer) twinsCardWidget = TwinsCardWidget(leapfrog) { 200f } - btn_twin_welcome.setOnClickListener { + binding.btnTwinWelcome.setOnClickListener { twinsCardWidget.toWelcome() } - btn_twin_to_leapfrog.setOnClickListener { + binding.btnTwinToLeapfrog.setOnClickListener { twinsCardWidget.toLeapfrog() } - btn_twin_activate.setOnClickListener { + binding.btnTwinActivate.setOnClickListener { twinsCardWidget.toActivate() } - - btn_lp_init.setOnClickListener { + binding.btnLpInit.setOnClickListener { leapfrog.initViews() } - btn_lp_unfold.setOnClickListener { + binding.btnLpUnfold.setOnClickListener { leapfrog.unfold() } - btn_lp_fold.setOnClickListener { + binding.btnLpFold.setOnClickListener { leapfrog.fold() } - btn_lp_leap.setOnClickListener { + binding.btnLpLeap.setOnClickListener { leapfrog.leap() } - btn_lp_leap_back.setOnClickListener { + binding.btnLpLeapBack.setOnClickListener { leapfrog.leapBack() } } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsConfirmFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsConfirmFragment.kt index 07d0ea9b41..acbe36e4ae 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsConfirmFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsConfirmFragment.kt @@ -5,6 +5,7 @@ import android.view.View import androidx.activity.OnBackPressedCallback import androidx.fragment.app.Fragment import androidx.transition.TransitionInflater +import by.kirich1409.viewbindingdelegate.viewBinding import com.tangem.tap.common.extensions.getDrawable import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.features.details.redux.ConfirmScreenState @@ -12,12 +13,14 @@ import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.redux.DetailsState import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_details_confirm.* +import com.tangem.wallet.databinding.FragmentDetailsConfirmBinding import org.rekotlin.StoreSubscriber class DetailsConfirmFragment : Fragment(R.layout.fragment_details_confirm), StoreSubscriber { + private val binding: FragmentDetailsConfirmBinding by viewBinding(FragmentDetailsConfirmBinding::bind) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) { @@ -47,38 +50,39 @@ class DetailsConfirmFragment : Fragment(R.layout.fragment_details_confirm), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - toolbar.setNavigationOnClickListener { + binding.toolbar.setNavigationOnClickListener { store.dispatch(NavigationAction.PopBackTo()) } } override fun newState(state: DetailsState) { - if (activity == null) return + if (activity == null || view == null) return + setState(state) + } + private fun setState(state: DetailsState) = with(binding) { when (state.confirmScreenState) { ConfirmScreenState.EraseWallet -> { toolbar.title = getString(R.string.details_row_title_reset_factory_settings) - tv_warning_description.text = getString(R.string.details_row_title_reset_factory_settings_warning) - btn_confirm.text = getString(R.string.details_row_title_reset_factory_settings) - btn_confirm.setCompoundDrawablesRelativeWithIntrinsicBounds( - null, null, getDrawable(R.drawable.ic_send), null + tvWarningDescription.text = getString(R.string.details_row_title_reset_factory_settings_warning) + btnConfirm.text = getString(R.string.details_row_title_reset_factory_settings) + btnConfirm.setCompoundDrawablesRelativeWithIntrinsicBounds( + null, null, getDrawable(R.drawable.ic_send), null ) - btn_confirm.setOnClickListener { store.dispatch(DetailsAction.ResetToFactory.Confirm) } + btnConfirm.setOnClickListener { store.dispatch(DetailsAction.ResetToFactory.Confirm) } } ConfirmScreenState.LongTap, ConfirmScreenState.AccessCode, ConfirmScreenState.PassCode -> { toolbar.title = getString(R.string.details_manage_security_title) - tv_warning_description.text = getString(R.string.details_security_management_warning) - btn_confirm.text = getString(R.string.common_save_changes) - btn_confirm.setCompoundDrawablesRelativeWithIntrinsicBounds( - null, null, getDrawable(R.drawable.ic_save), null + tvWarningDescription.text = getString(R.string.details_security_management_warning) + btnConfirm.text = getString(R.string.common_save_changes) + btnConfirm.setCompoundDrawablesRelativeWithIntrinsicBounds( + null, null, getDrawable(R.drawable.ic_save), null ) - btn_confirm.setOnClickListener { store.dispatch(DetailsAction.ManageSecurity.SaveChanges) } + btnConfirm.setOnClickListener { store.dispatch(DetailsAction.ManageSecurity.SaveChanges) } } } - - } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt index 8651dbd9d3..5df5d5969b 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt @@ -6,6 +6,7 @@ import android.view.View import androidx.activity.OnBackPressedCallback import androidx.fragment.app.Fragment import androidx.transition.TransitionInflater +import by.kirich1409.viewbindingdelegate.viewBinding import com.tangem.tap.common.extensions.show import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.AppScreen @@ -18,13 +19,13 @@ import com.tangem.tap.features.details.redux.SecurityOption import com.tangem.tap.features.feedback.FeedbackEmail import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_details.* -import kotlinx.android.synthetic.main.fragment_wallet.toolbar +import com.tangem.wallet.databinding.FragmentDetailsBinding import org.rekotlin.StoreSubscriber class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber { private var currencySelectionDialog = CurrencySelectionDialog() + private val binding: FragmentDetailsBinding by viewBinding(FragmentDetailsBinding::bind) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -55,15 +56,18 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber R.string.details_manage_security_access_code null -> null } - currentSecurity?.let { tv_security.text = getString(it) } + currentSecurity?.let { tvSecurity.text = getString(it) } if (state.appCurrencyState.showAppCurrencyDialog && !state.appCurrencyState.fiatCurrencies.isNullOrEmpty()) { @@ -147,7 +151,6 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber { + private val binding: FragmentDetailsSecurityBinding by viewBinding( + FragmentDetailsSecurityBinding::bind + ) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) { @@ -49,14 +53,14 @@ class DetailsSecurityFragment : Fragment(R.layout.fragment_details_security), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - toolbar.setNavigationOnClickListener { + binding.toolbar.setNavigationOnClickListener { store.dispatch(NavigationAction.PopBackTo()) } setOnClickListeners() } private fun setOnClickListeners() { - btn_save_changes.setOnClickListener { + binding.btnSaveChanges.setOnClickListener { store.state.detailsState.securityScreenState?.selectedOption?.let { store.dispatch(DetailsAction.ManageSecurity.ConfirmSelection(it)) } @@ -64,7 +68,8 @@ class DetailsSecurityFragment : Fragment(R.layout.fragment_details_security), } override fun newState(state: DetailsState) { - if (activity == null) return + if (activity == null || view == null) return + selectSecurityOption(state.securityScreenState?.selectedOption) for (option in SecurityOption.values()) { setupOption( @@ -73,18 +78,18 @@ class DetailsSecurityFragment : Fragment(R.layout.fragment_details_security), ?: EnumSet.noneOf(SecurityOption::class.java) ) } - tv_access_code_unavailable_disclaimer.show( + binding.tvAccessCodeUnavailableDisclaimer.show( state.scanResponse?.card?.backupStatus == Card.BackupStatus.NoBackup ) } - private fun selectSecurityOption(securityOption: SecurityOption?) { - radiobutton_long_tap.isChecked = - securityOption == SecurityOption.LongTap && radiobutton_long_tap.isEnabled - radiobutton_passcode.isChecked = - securityOption == SecurityOption.PassCode && radiobutton_passcode.isEnabled - radiobutton_access_code.isChecked = - securityOption == SecurityOption.AccessCode && radiobutton_access_code.isEnabled + private fun selectSecurityOption(securityOption: SecurityOption?) = with(binding) { + radiobuttonLongTap.isChecked = + securityOption == SecurityOption.LongTap && radiobuttonLongTap.isEnabled + radiobuttonPasscode.isChecked = + securityOption == SecurityOption.PassCode && radiobuttonPasscode.isEnabled + radiobuttonAccessCode.isChecked = + securityOption == SecurityOption.AccessCode && radiobuttonAccessCode.isEnabled } private fun setupOption(option: SecurityOption, allowedOptions: EnumSet) { @@ -95,46 +100,46 @@ class DetailsSecurityFragment : Fragment(R.layout.fragment_details_security), } } - private fun enableLongTap(enable: Boolean) { - group_long_tap.show(enable) + private fun enableLongTap(enable: Boolean) = with(binding) { + groupLongTap.show(enable) val alpha = if (enable) 1f else 0.5f - tv_long_tap_description.alpha = alpha - tv_long_tap_title.alpha = alpha - radiobutton_long_tap.alpha = alpha - radiobutton_long_tap.isEnabled = enable - v_long_tap.isClickable = enable + tvLongTapDescription.alpha = alpha + tvLongTapTitle.alpha = alpha + radiobuttonLongTap.alpha = alpha + radiobuttonLongTap.isEnabled = enable + vLongTap.isClickable = enable if (enable) { - v_long_tap.setOnClickListener { + vLongTap.setOnClickListener { store.dispatch(DetailsAction.ManageSecurity.SelectOption(SecurityOption.LongTap)) } } } - private fun enablePasscode(enable: Boolean) { - group_passcode.show(enable) + private fun enablePasscode(enable: Boolean) = with(binding) { + groupPasscode.show(enable) val alpha = if (enable) 1f else 0.5f - tv_passcode_description.alpha = alpha - tv_passcode_title.alpha = alpha - radiobutton_passcode.alpha = alpha - radiobutton_passcode.isEnabled = enable - v_passcode.isClickable = enable + tvPasscodeDescription.alpha = alpha + tvPasscodeTitle.alpha = alpha + radiobuttonPasscode.alpha = alpha + radiobuttonPasscode.isEnabled = enable + vPasscode.isClickable = enable if (enable) { - v_passcode.setOnClickListener { + vPasscode.setOnClickListener { store.dispatch(DetailsAction.ManageSecurity.SelectOption(SecurityOption.PassCode)) } } } - private fun enableAccessCode(enable: Boolean) { - group_access_code.show(enable) + private fun enableAccessCode(enable: Boolean) = with(binding) { + groupAccessCode.show(enable) val alpha = if (enable) 1f else 0.5f - tv_access_code_description.alpha = alpha - tv_access_code_title.alpha = alpha - radiobutton_access_code.alpha = alpha - radiobutton_access_code.isEnabled = enable - v_access_code.isClickable = enable + tvAccessCodeDescription.alpha = alpha + tvAccessCodeTitle.alpha = alpha + radiobuttonAccessCode.alpha = alpha + radiobuttonAccessCode.isEnabled = enable + vAccessCode.isClickable = enable if (enable) { - v_access_code.setOnClickListener { + vAccessCode.setOnClickListener { store.dispatch(DetailsAction.ManageSecurity.SelectOption(SecurityOption.AccessCode)) } } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/SessionsAdapter.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/SessionsAdapter.kt index c1028c874d..95c28cf26a 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/SessionsAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/SessionsAdapter.kt @@ -3,14 +3,15 @@ package com.tangem.tap.features.details.ui.walletconnect import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.chip.Chip import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction import com.tangem.tap.features.details.redux.walletconnect.WalletConnectSession import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.item_wallet_connect_session.view.* class WalletConnectSessionsAdapter : ListAdapter( @@ -41,15 +42,14 @@ class WalletConnectSessionsAdapter RecyclerView.ViewHolder(view) { fun bind(session: WalletConnectSession) { - view.tv_card_id.text = view.context.getString( + view.findViewById(R.id.tv_card_id).text = view.context.getString( R.string.wallet_connect_card_number, session.wallet.cardId ) - view.tv_d_app_name.text = session.peerMeta.name + view.findViewById(R.id.tv_d_app_name).text = session.peerMeta.name - view.btn_disconnect.setOnClickListener { + view.findViewById(R.id.btn_disconnect).setOnClickListener { store.dispatch(WalletConnectAction.DisconnectSession(session.session)) } - } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectSessionsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectSessionsFragment.kt index 1a55a976c7..b019dc95e7 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectSessionsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectSessionsFragment.kt @@ -1,19 +1,20 @@ package com.tangem.tap.features.details.ui.walletconnect -import android.app.Dialog import android.os.Bundle import android.view.View import androidx.activity.OnBackPressedCallback import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.transition.TransitionInflater +import by.kirich1409.viewbindingdelegate.viewBinding import com.tangem.tap.common.extensions.show import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction +import com.tangem.tap.features.details.redux.walletconnect.WalletConnectSession import com.tangem.tap.features.details.redux.walletconnect.WalletConnectState import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_wallet_connect_sessions.* +import com.tangem.wallet.databinding.FragmentWalletConnectSessionsBinding import org.rekotlin.StoreSubscriber @@ -21,7 +22,9 @@ class WalletConnectSessionsFragment : Fragment(R.layout.fragment_wallet_connect_ StoreSubscriber { private lateinit var walletConnectSessionsAdapter: WalletConnectSessionsAdapter - private var dialog: Dialog? = null + private val binding: FragmentWalletConnectSessionsBinding by viewBinding( + FragmentWalletConnectSessionsBinding::bind + ) override fun onCreate(savedInstanceState: Bundle?) { @@ -53,7 +56,7 @@ class WalletConnectSessionsFragment : Fragment(R.layout.fragment_wallet_connect_ override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - toolbar.setNavigationOnClickListener { + binding.toolbar.setNavigationOnClickListener { store.dispatch(NavigationAction.PopBackTo()) } setOnClickListeners() @@ -61,27 +64,31 @@ class WalletConnectSessionsFragment : Fragment(R.layout.fragment_wallet_connect_ } private fun setOnClickListeners() { - fab_open_session.setOnClickListener { + binding.fabOpenSession.setOnClickListener { store.dispatch(WalletConnectAction.StartWalletConnect(activity = requireActivity())) } } - private fun setupTransactionsRecyclerView() { + private fun setupTransactionsRecyclerView() = with(binding) { walletConnectSessionsAdapter = WalletConnectSessionsAdapter() - rv_wallet_connect_sessions.layoutManager = LinearLayoutManager(requireContext()) - rv_wallet_connect_sessions.adapter = walletConnectSessionsAdapter + rvWalletConnectSessions.layoutManager = LinearLayoutManager(requireContext()) + rvWalletConnectSessions.adapter = walletConnectSessionsAdapter walletConnectSessionsAdapter.submitList(store.state.walletConnectState.sessions) } override fun newState(state: WalletConnectState) { - if (activity == null) return + if (activity == null || view == null) return - fab_open_session.show(!state.loading) - pb_wallet_connect.show(state.loading) + binding.fabOpenSession.show(!state.loading) + binding.pbWalletConnect.show(state.loading) - walletConnectSessionsAdapter.submitList(state.sessions) - rv_wallet_connect_sessions.show(state.sessions.isNotEmpty()) - tv_no_sessions.show(state.sessions.isEmpty()) - tv_no_sessions_title.show(state.sessions.isEmpty()) + showUpdatedList(state.sessions) + } + + private fun showUpdatedList(sessions: List) = with(binding) { + walletConnectSessionsAdapter.submitList(sessions) + rvWalletConnectSessions.show(sessions.isNotEmpty()) + tvNoSessions.show(sessions.isEmpty()) + tvNoSessionsTitle.show(sessions.isEmpty()) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt index 82f131a3a2..4538be7224 100644 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt @@ -5,18 +5,21 @@ import android.view.View import androidx.activity.OnBackPressedCallback import androidx.fragment.app.Fragment import androidx.transition.TransitionInflater +import by.kirich1409.viewbindingdelegate.viewBinding import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.features.disclaimer.redux.DisclaimerAction import com.tangem.tap.features.disclaimer.redux.DisclaimerState import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_disclaimer.* +import com.tangem.wallet.databinding.FragmentDisclaimerBinding import org.rekotlin.StoreSubscriber class DisclaimerFragment : Fragment(R.layout.fragment_disclaimer), StoreSubscriber { + private val binding: FragmentDisclaimerBinding by viewBinding(FragmentDisclaimerBinding::bind) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) { @@ -45,22 +48,22 @@ class DisclaimerFragment : Fragment(R.layout.fragment_disclaimer), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - toolbar.setNavigationOnClickListener { + binding.toolbar.setNavigationOnClickListener { store.dispatch(NavigationAction.PopBackTo()) } setOnClickListeners() } private fun setOnClickListeners() { - btn_accept.setOnClickListener { store.dispatch(DisclaimerAction.AcceptDisclaimer) } + binding.btnAccept.setOnClickListener { store.dispatch(DisclaimerAction.AcceptDisclaimer) } } override fun newState(state: DisclaimerState) { - if (activity == null) return + if (activity == null || view == null) return if (state.accepted) { - half_transparent_overlay.hide() - btn_accept.hide() + binding.halfTransparentOverlay.hide() + binding.btnAccept.hide() } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt index 652eea56a5..b577781a18 100644 --- a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt @@ -56,7 +56,7 @@ class HomeFragment : Fragment(R.layout.fragment_home), StoreSubscriber : BaseStoreFragment(R.layout.fragment_onboarding_main), StoreSubscriber { + protected val binding: FragmentOnboardingMainBinding by viewBinding(FragmentOnboardingMainBinding::bind) + protected val pbBinding: ViewOnboardingProgressBinding by viewBinding(ViewOnboardingProgressBinding::bind) + override fun configureTransitions() { enterTransition = HomeToOnboardingTransition() exitTransition = HomeToOnboardingTransition() } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - onboarding_top_container.inflate(getOnboardingTopContainerId(), true) - } - - abstract fun getOnboardingTopContainerId(): Int - - protected fun showConfetti(show: Boolean) { - lav_confetti.show(show) + protected fun showConfetti(show: Boolean) = with(binding.vConfetti) { + lavConfetti.show(show) if (show) { - lav_confetti.playAnimation() + lavConfetti.playAnimation() } else { - lav_confetti.cancelAnimation() + lavConfetti.cancelAnimation() } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt index d9d832d5a6..3125784ba9 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt @@ -26,11 +26,6 @@ import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteStat import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteStep import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_onboarding_main.* -import kotlinx.android.synthetic.main.layout_onboarding_container_bottom.* -import kotlinx.android.synthetic.main.layout_onboarding_container_top.* -import kotlinx.android.synthetic.main.view_onboarding_progress.* -import kotlinx.android.synthetic.main.view_onboarding_tv_balance.* /** [REDACTED_AUTHOR] @@ -41,8 +36,6 @@ class OnboardingNoteFragment : BaseOnboardingFragment() { private lateinit var btnRefreshBalanceWidget: RefreshBalanceWidget - override fun getOnboardingTopContainerId(): Int = R.layout.layout_onboarding_container_top - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) postponeEnterTransition() @@ -52,11 +45,11 @@ class OnboardingNoteFragment : BaseOnboardingFragment() { super.onViewCreated(view, savedInstanceState) addBackPressHandler(this) - imv_front_card.transitionName = ShareElement.imvFrontCard + binding.onboardingTopContainer.imvFrontCard.transitionName = ShareElement.imvFrontCard startPostponedEnterTransition() - toolbar.setTitle(R.string.onboarding_title) - btnRefreshBalanceWidget = RefreshBalanceWidget(onboarding_main_container) + binding.toolbar.setTitle(R.string.onboarding_title) + btnRefreshBalanceWidget = RefreshBalanceWidget(binding.onboardingTopContainer.onboardingMainContainer) store.dispatch(OnboardingNoteAction.LoadCardArtwork) store.dispatch(OnboardingNoteAction.DetermineStepOfScreen) @@ -72,19 +65,19 @@ class OnboardingNoteFragment : BaseOnboardingFragment() { } override fun newState(state: OnboardingNoteState) { - if (activity == null) return + if (activity == null || view == null) return Picasso.get() - .load(state.cardArtworkUrl) - .error(R.drawable.card_placeholder_black) - .placeholder(R.drawable.card_placeholder_black) - ?.into(imv_front_card) + .load(state.cardArtworkUrl) + .error(R.drawable.card_placeholder_black) + .placeholder(R.drawable.card_placeholder_black) + ?.into(binding.onboardingTopContainer.imvFrontCard) - pb_state.max = state.steps.size - 1 - pb_state.progress = state.progress + pbBinding.pbState.max = state.steps.size - 1 + pbBinding.pbState.progress = state.progress when (state.currentStep) { - OnboardingNoteStep.None -> setupNoneState(state) + OnboardingNoteStep.None -> setupNoneState() OnboardingNoteStep.CreateWallet -> setupCreateWalletState(state) OnboardingNoteStep.TopUpWallet -> setupTopUpWalletState(state) OnboardingNoteStep.Done -> setupDoneState(state) @@ -97,77 +90,82 @@ class OnboardingNoteFragment : BaseOnboardingFragment() { private fun setBalance(state: OnboardingNoteState) { if (state.walletBalance.currency.blockchain == Blockchain.Unknown) return - if (state.balanceCriticalError == null) { - val balanceValue = state.walletBalance.value.stripZeroPlainString() - tv_balance_value.text = balanceValue - tv_balance_currency.text = state.walletBalance.currency.currencySymbol - } else { - tv_balance_value.text = "–" - tv_balance_currency.text = "" + with (binding.onboardingTopContainer.onboardingTvBalance) { + if (state.balanceCriticalError == null) { + val balanceValue = state.walletBalance.value.stripZeroPlainString() + tvBalanceValue.text = balanceValue + tvBalanceCurrency.text = state.walletBalance.currency.currencySymbol + } else { + tvBalanceValue.text = "–" + tvBalanceCurrency.text = "" + } } } - private fun setupNoneState(state: OnboardingNoteState) { - btn_main_action.isVisible = false - btn_alternative_action.isVisible = false + private fun setupNoneState() = with(binding.onboardingActionContainer) { + btnMainAction.isVisible = false + btnAlternativeAction.isVisible = false btnRefreshBalanceWidget.show(false) - tv_header.isVisible = false - tv_body.isVisible = false + tvHeader.isVisible = false + tvBody.isVisible = false - btn_main_action.text = "" - btn_alternative_action.text = "" - tv_header.text = "" - tv_body.text = "" + btnMainAction.text = "" + btnAlternativeAction.text = "" + tvHeader.text = "" + tvBody.text = "" } - private fun setupCreateWalletState(state: OnboardingNoteState) { - btn_main_action.setText(R.string.onboarding_create_wallet_button_create_wallet) - btn_main_action.setOnClickListener { store.dispatch(OnboardingNoteAction.CreateWallet) } - btn_alternative_action.setText(R.string.onboarding_button_what_does_it_mean) - btn_alternative_action.setOnClickListener { } + private fun setupCreateWalletState(state: OnboardingNoteState) = + with(binding.onboardingActionContainer) { + btnMainAction.setText(R.string.onboarding_create_wallet_button_create_wallet) + btnMainAction.setOnClickListener { store.dispatch(OnboardingNoteAction.CreateWallet) } + btnAlternativeAction.setText(R.string.onboarding_button_what_does_it_mean) + btnAlternativeAction.setOnClickListener { } - btnRefreshBalanceWidget.mainView.setOnClickListener(null) + btnRefreshBalanceWidget.mainView.setOnClickListener(null) - tv_header.setText(R.string.onboarding_create_wallet_header) - tv_body.setText(R.string.onboarding_create_wallet_body) + tvHeader.setText(R.string.onboarding_create_wallet_header) + tvBody.setText(R.string.onboarding_create_wallet_body) - imv_card_background.setBackgroundDrawable(requireContext().getDrawableCompat(R.drawable.shape_circle)) - updateConstraints(state.currentStep, R.layout.lp_onboarding_create_wallet) + binding.onboardingTopContainer.imvCardBackground.setBackgroundDrawable( + requireContext().getDrawableCompat(R.drawable.shape_circle) + ) + updateConstraints(state.currentStep, R.layout.lp_onboarding_create_wallet) - btn_alternative_action.isVisible = false // temporary - } + btnAlternativeAction.isVisible = false // temporary + } - private fun setupTopUpWalletState(state: OnboardingNoteState) { + private fun setupTopUpWalletState(state: OnboardingNoteState) = with(binding.onboardingActionContainer) { if (state.isBuyAllowed) { - btn_main_action.setText(R.string.onboarding_top_up_button_but_crypto) - btn_main_action.setOnClickListener { + btnMainAction.setText(R.string.onboarding_top_up_button_but_crypto) + btnMainAction.setOnClickListener { store.dispatch(OnboardingNoteAction.TopUp) } - btn_alternative_action.isVisible = true - btn_alternative_action.setText(R.string.onboarding_top_up_button_show_wallet_address) - btn_alternative_action.setOnClickListener { + btnAlternativeAction.isVisible = true + btnAlternativeAction.setText(R.string.onboarding_top_up_button_show_wallet_address) + btnAlternativeAction.setOnClickListener { store.dispatch(OnboardingNoteAction.ShowAddressInfoDialog) } } else { - btn_main_action.setText(R.string.onboarding_button_receive_crypto) - btn_main_action.setOnClickListener { + btnMainAction.setText(R.string.onboarding_button_receive_crypto) + btnMainAction.setOnClickListener { store.dispatch(OnboardingNoteAction.ShowAddressInfoDialog) } - btn_alternative_action.isVisible = false + btnAlternativeAction.isVisible = false } - tv_header.setText(R.string.onboarding_top_up_header) + tvHeader.setText(R.string.onboarding_top_up_header) if (state.balanceNonCriticalError == null) { - tv_body.setText(R.string.onboarding_top_up_body) + tvBody.setText(R.string.onboarding_top_up_body) } else { state.walletBalance.amountToCreateAccount?.let { amount -> val tvBodyMessage = getString( R.string.onboarding_top_up_body_no_account_error, amount, state.walletBalance.currency.currencySymbol ) - tv_body.text = tvBodyMessage + tvBody.text = tvBodyMessage } } @@ -177,38 +175,43 @@ class OnboardingNoteFragment : BaseOnboardingFragment() { store.dispatch(OnboardingNoteAction.Balance.Update) } } - imv_card_background.setBackgroundDrawable(requireContext().getDrawableCompat(R.drawable.shape_rectangle_rounded_8)) + binding.onboardingTopContainer.imvCardBackground + .setBackgroundDrawable(requireContext().getDrawableCompat(R.drawable.shape_rectangle_rounded_8)) updateConstraints(state.currentStep, R.layout.lp_onboarding_topup_wallet) } - private fun setupDoneState(state: OnboardingNoteState) { - btn_main_action.setText(R.string.onboarding_done_button_continue) - btn_main_action.setOnClickListener { + private fun setupDoneState(state: OnboardingNoteState) = with(binding.onboardingActionContainer) { + btnMainAction.setText(R.string.onboarding_done_button_continue) + btnMainAction.setOnClickListener { showConfetti(false) store.dispatch(OnboardingNoteAction.Done) } - btn_alternative_action.isVisible = false - btn_alternative_action.setText("") - btn_alternative_action.setOnClickListener { } + btnAlternativeAction.isVisible = false + btnAlternativeAction.setText("") + btnAlternativeAction.setOnClickListener { } btnRefreshBalanceWidget.mainView.setOnClickListener(null) - tv_header.setText(R.string.onboarding_done_header) - tv_body.setText(R.string.onboarding_done_body) + tvHeader.setText(R.string.onboarding_done_header) + tvBody.setText(R.string.onboarding_done_body) - imv_card_background.setBackgroundDrawable(requireContext().getDrawableCompat(R.drawable.shape_rectangle_rounded_8)) + binding.onboardingTopContainer.imvCardBackground.setBackgroundDrawable( + requireContext().getDrawableCompat(R.drawable.shape_rectangle_rounded_8) + ) updateConstraints(state.currentStep, R.layout.lp_onboarding_done_activation) } private fun updateConstraints(currentStep: OnboardingNoteStep, @LayoutRes layoutId: Int) { if (this.previousStep == currentStep) return - val constraintSet = ConstraintSet() - constraintSet.clone(requireContext(), layoutId) - constraintSet.applyTo(onboarding_main_container) - val transition = InternalNoteLayoutTransition() - transition.interpolator = OvershootInterpolator() - TransitionManager.beginDelayedTransition(onboarding_main_container, transition) + with(binding.onboardingTopContainer) { + val constraintSet = ConstraintSet() + constraintSet.clone(requireContext(), layoutId) + constraintSet.applyTo(onboardingMainContainer) + val transition = InternalNoteLayoutTransition() + transition.interpolator = OvershootInterpolator() + TransitionManager.beginDelayedTransition(onboardingMainContainer, transition) + } } } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt index 22e479721b..996fdd67fe 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt @@ -18,18 +18,12 @@ import com.tangem.tap.features.onboarding.products.otherCards.redux.OnboardingOt import com.tangem.tap.features.onboarding.products.otherCards.redux.OnboardingOtherCardsStep import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_onboarding_main.* -import kotlinx.android.synthetic.main.layout_onboarding_container_bottom.* -import kotlinx.android.synthetic.main.layout_onboarding_container_top.* -import kotlinx.android.synthetic.main.view_onboarding_progress.* /** [REDACTED_AUTHOR] */ class OnboardingOtherCardsFragment : BaseOnboardingFragment() { - override fun getOnboardingTopContainerId(): Int = R.layout.layout_onboarding_container_top - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) postponeEnterTransition() @@ -39,10 +33,10 @@ class OnboardingOtherCardsFragment : BaseOnboardingFragment setupCreateWalletState(state) - OnboardingOtherCardsStep.Done -> setupDoneState(state) + OnboardingOtherCardsStep.CreateWallet -> setupCreateWalletState() + OnboardingOtherCardsStep.Done -> setupDoneState() } showConfetti(state.showConfetti) } - private fun setupCreateWalletState(state: OnboardingOtherCardsState) { - btn_main_action.setText(R.string.onboarding_create_wallet_button_create_wallet) - btn_main_action.setOnClickListener { store.dispatch(OnboardingOtherCardsAction.CreateWallet) } - btn_alternative_action.setText(R.string.onboarding_button_what_does_it_mean) - btn_alternative_action.setOnClickListener { } + private fun setupCreateWalletState() = with(binding) { - tv_header.setText(R.string.onboarding_create_wallet_header) - tv_body.setText(R.string.onboarding_create_wallet_body) + with(onboardingActionContainer) { + btnMainAction.setText(R.string.onboarding_create_wallet_button_create_wallet) + btnMainAction.setOnClickListener { store.dispatch(OnboardingOtherCardsAction.CreateWallet) } + btnAlternativeAction.setText(R.string.onboarding_button_what_does_it_mean) + btnAlternativeAction.setOnClickListener { } - imv_card_background.setBackgroundDrawable(requireContext().getDrawableCompat(R.drawable.shape_circle)) + tvHeader.setText(R.string.onboarding_create_wallet_header) + tvBody.setText(R.string.onboarding_create_wallet_body) + + btnAlternativeAction.isVisible = false // temporary + } + + + binding.onboardingTopContainer.imvCardBackground.setBackgroundDrawable( + requireContext().getDrawableCompat(R.drawable.shape_circle) + ) updateConstraints(R.layout.lp_onboarding_create_wallet) - btn_alternative_action.isVisible = false // temporary } - private fun setupDoneState(state: OnboardingOtherCardsState) { - btn_main_action.setText(R.string.onboarding_done_button_continue) - btn_main_action.setOnClickListener { + private fun setupDoneState() = with(binding.onboardingActionContainer) { + btnMainAction.setText(R.string.onboarding_done_button_continue) + btnMainAction.setOnClickListener { showConfetti(false) store.dispatch(OnboardingOtherCardsAction.Done) } - btn_alternative_action.isVisible = false - btn_alternative_action.setText("") - btn_alternative_action.setOnClickListener { } + btnAlternativeAction.isVisible = false + btnAlternativeAction.setText("") + btnAlternativeAction.setOnClickListener { } - tv_header.setText(R.string.onboarding_done_header) - tv_body.setText(R.string.onboarding_done_body) + tvHeader.setText(R.string.onboarding_done_header) + tvBody.setText(R.string.onboarding_done_body) - imv_card_background.setBackgroundDrawable(requireContext().getDrawableCompat(R.drawable.shape_rectangle_rounded_8)) + binding.onboardingTopContainer.imvCardBackground?.setBackgroundDrawable( + requireContext().getDrawableCompat(R.drawable.shape_rectangle_rounded_8) + ) updateConstraints(R.layout.lp_onboarding_done) } private fun updateConstraints(@LayoutRes layoutId: Int) { - val constraintSet = ConstraintSet() - constraintSet.clone(requireContext(), layoutId) - constraintSet.applyTo(onboarding_main_container) - val transition = InternalNoteLayoutTransition() - transition.interpolator = OvershootInterpolator() - TransitionManager.beginDelayedTransition(onboarding_main_container, transition) + with(binding.onboardingTopContainer) { + val constraintSet = ConstraintSet() + constraintSet.clone(requireContext(), layoutId) + constraintSet.applyTo(onboardingMainContainer) + val transition = InternalNoteLayoutTransition() + transition.interpolator = OvershootInterpolator() + TransitionManager.beginDelayedTransition(onboardingMainContainer, transition) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt index 12e87f2a70..f8051e67fd 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt @@ -31,12 +31,7 @@ import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsStep import com.tangem.tap.features.wallet.redux.Artwork import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_onboarding_main.* -import kotlinx.android.synthetic.main.layout_onboarding_container_bottom.* -import kotlinx.android.synthetic.main.layout_onboarding_container_top.* -import kotlinx.android.synthetic.main.view_bg_twins_welcome.* -import kotlinx.android.synthetic.main.view_onboarding_progress.* -import kotlinx.android.synthetic.main.view_onboarding_tv_balance.* +import com.tangem.wallet.databinding.LayoutOnboardingContainerTopBinding class TwinsCardsFragment : BaseOnboardingFragment() { @@ -47,12 +42,11 @@ class TwinsCardsFragment : BaseOnboardingFragment() { private val assetReader: AssetReader by lazy { object : AssetReader { - override fun readAssetAsString(name: String): String = requireContext().readAssetAsString(name) + override fun readAssetAsString(name: String): String = + requireContext().readAssetAsString(name) } } - override fun getOnboardingTopContainerId(): Int = R.layout.layout_onboarding_container_top - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) postponeEnterTransition() @@ -74,36 +68,39 @@ class TwinsCardsFragment : BaseOnboardingFragment() { super.onViewCreated(view, savedInstanceState) addBackPressHandler(this) - reconfigureLayoutForTwins() - twinsWidget = TwinsCardWidget(LeapfrogWidget(cards_container)) { 285f } - btnRefreshBalanceWidget = RefreshBalanceWidget(onboarding_main_container) + reconfigureLayoutForTwins(binding.onboardingTopContainer) + twinsWidget = + TwinsCardWidget(LeapfrogWidget(binding.onboardingTopContainer.cardsContainer)) { 285f } + btnRefreshBalanceWidget = + RefreshBalanceWidget(binding.onboardingTopContainer.onboardingMainContainer) - toolbar.title = getText(R.string.twins_recreate_toolbar) + binding.toolbar.title = getText(R.string.twins_recreate_toolbar) Picasso.get() - .load(Artwork.TWIN_CARD_1) - .error(R.drawable.card_placeholder_black) - .placeholder(R.drawable.card_placeholder_black) - ?.into(imv_twin_front_card) + .load(Artwork.TWIN_CARD_1) + .error(R.drawable.card_placeholder_black) + .placeholder(R.drawable.card_placeholder_black) + ?.into(binding.onboardingTopContainer.imvTwinFrontCard) Picasso.get() - .load(Artwork.TWIN_CARD_2) - .error(R.drawable.card_placeholder_white) - .placeholder(R.drawable.card_placeholder_white) - ?.into(imv_twin_back_card) + .load(Artwork.TWIN_CARD_2) + .error(R.drawable.card_placeholder_white) + .placeholder(R.drawable.card_placeholder_white) + ?.into(binding.onboardingTopContainer.imvTwinBackCard) } - private fun reconfigureLayoutForTwins() { - imv_front_card.hide() - imv_card_background.hide() - cards_container.show() + private fun reconfigureLayoutForTwins(containerBinding: LayoutOnboardingContainerTopBinding) = + with(containerBinding) { + imvFrontCard.hide() + imvCardBackground.hide() + cardsContainer.show() - imv_twin_front_card.transitionName = ShareElement.imvFrontCard - imv_twin_back_card.transitionName = ShareElement.imvBackCard + imvTwinFrontCard.transitionName = ShareElement.imvFrontCard + imvTwinBackCard.transitionName = ShareElement.imvBackCard - // if don't this, the bg_circle_... is overflow the app_bar - app_bar.bringToFront() - } + // if don't this, the bg_circle_... is overflow the app_bar + binding.appBar.bringToFront() + } override fun subscribeToStore() { store.subscribe(this) { state -> @@ -115,10 +112,10 @@ class TwinsCardsFragment : BaseOnboardingFragment() { } override fun newState(state: TwinCardsState) { - if (activity == null) return + if (activity == null || view == null) return - pb_state.max = state.steps.size - 1 - pb_state.progress = state.progress + pbBinding.pbState.max = state.steps.size - 1 + pbBinding.pbState.progress = state.progress when (state.currentStep) { TwinCardsStep.WelcomeOnly -> setupWelcomeOnlyState(state) @@ -139,13 +136,15 @@ class TwinsCardsFragment : BaseOnboardingFragment() { private fun setBalance(state: TwinCardsState) { if (state.walletBalance.currency.blockchain == Blockchain.Unknown) return - if (state.balanceCriticalError == null) { - val balanceValue = state.walletBalance.value.stripZeroPlainString() - tv_balance_value.text = balanceValue - tv_balance_currency.text = state.walletBalance.currency.currencySymbol - } else { - tv_balance_value.text = "–" - tv_balance_currency.text = "" + with(binding.onboardingTopContainer.onboardingTvBalance) { + if (state.balanceCriticalError == null) { + val balanceValue = state.walletBalance.value.stripZeroPlainString() + tvBalanceValue.text = balanceValue + tvBalanceCurrency.text = state.walletBalance.currency.currencySymbol + } else { + tvBalanceValue.text = "–" + tvBalanceCurrency.text = "" + } } } @@ -160,203 +159,235 @@ class TwinsCardsFragment : BaseOnboardingFragment() { setupWelcomeState(state) { store.dispatch(TwinCardsAction.SetStepOfScreen(TwinCardsStep.CreateFirstWallet)) } } - private fun setupWelcomeState(state: TwinCardsState, mainAction: VoidCallback) { + private fun setupWelcomeState(state: TwinCardsState, mainAction: VoidCallback) = + with(binding.onboardingActionContainer) { + twinsWidget.toWelcome(false) { startPostponedEnterTransition() } + + binding.onboardingTopContainer.onboardingTwinsWelcomeBg.root.show() + pbBinding.pbState.hide() + + tvHeader.setText(R.string.twins_onboarding_subtitle) + tvBody.text = getString( + R.string.twins_onboarding_description_format, + state.cardNumber?.pairIndexNumber() + ) + + btnMainAction.setText(R.string.common_continue) + btnMainAction.setOnClickListener { mainAction() } + } + + private fun setupWarningState(state: TwinCardsState) = with(binding.onboardingActionContainer) { twinsWidget.toWelcome(false) { startPostponedEnterTransition() } - onboarding_twins_welcome_bg.show() - pb_state.hide() + binding.onboardingTopContainer.onboardingTwinsWelcomeBg.root.hide() + pbBinding.pbState.hide() + chbUnderstand.show() - tv_header.setText(R.string.twins_onboarding_subtitle) - tv_body.text = getString(R.string.twins_onboarding_description_format, state.cardNumber?.pairIndexNumber()) + tvHeader.setText(R.string.common_warning) + tvBody.setText(R.string.twins_recreate_warning) - btn_main_action.setText(R.string.common_continue) - btn_main_action.setOnClickListener { mainAction() } - } - - private fun setupWarningState(state: TwinCardsState) { - twinsWidget.toWelcome(false) { startPostponedEnterTransition() } - - onboarding_twins_welcome_bg.hide() - pb_state.hide() - chb_understand.show() - - tv_header.setText(R.string.common_warning) - tv_body.setText(R.string.twins_recreate_warning) - - chb_understand.setOnCheckedChangeListener { buttonView, isChecked -> + chbUnderstand.setOnCheckedChangeListener { buttonView, isChecked -> store.dispatch(TwinCardsAction.SetUserUnderstand(isChecked)) } - btn_main_action.isEnabled = state.userWasUnderstandIfWalletRecreate - btn_main_action.setText(R.string.common_continue) - btn_main_action.setOnClickListener { + btnMainAction.isEnabled = state.userWasUnderstandIfWalletRecreate + btnMainAction.setText(R.string.common_continue) + btnMainAction.setOnClickListener { store.dispatch(TwinCardsAction.SetStepOfScreen(TwinCardsStep.CreateFirstWallet)) } } - private fun setupCreateFirstWalletState(state: TwinCardsState) { - onboarding_twins_welcome_bg.hide() - bg_circle_large.hide() - bg_circle_medium.hide() - bg_circle_min.hide() - chb_understand.hide() - pb_state.show() + private fun setupCreateFirstWalletState(state: TwinCardsState) = + with(binding.onboardingActionContainer) { + binding.onboardingTopContainer.onboardingTwinsWelcomeBg.root.hide() + binding.onboardingTopContainer.onboardingTwinsWelcomeBg.bgCircleLarge.hide() + binding.onboardingTopContainer.onboardingTwinsWelcomeBg.bgCircleMedium.hide() + binding.onboardingTopContainer.onboardingTwinsWelcomeBg.bgCircleMin.hide() + chbUnderstand.hide() + pbBinding.pbState.show() - onboarding_main_container.beginDelayedTransition() + binding.onboardingTopContainer.onboardingMainContainer.beginDelayedTransition() - when (previousStep) { - TwinCardsStep.None -> { - twinsWidget.toLeapfrog(false) { - when (state.cardNumber) { - TwinCardNumber.First -> startPostponedEnterTransition() - TwinCardNumber.Second -> { - switchToCard(state.cardNumber, false) { startPostponedEnterTransition() } + when (previousStep) { + TwinCardsStep.None -> { + twinsWidget.toLeapfrog(false) { + when (state.cardNumber) { + TwinCardNumber.First -> startPostponedEnterTransition() + TwinCardNumber.Second -> { + switchToCard( + state.cardNumber, + false + ) { startPostponedEnterTransition() } + } } } } + TwinCardsStep.Welcome, TwinCardsStep.Warning -> { + twinsWidget.toLeapfrog(onEnd = { switchToCard(state.cardNumber) }) + } } - TwinCardsStep.Welcome, TwinCardsStep.Warning -> { - twinsWidget.toLeapfrog(onEnd = { switchToCard(state.cardNumber) }) + + val twinIndexNumber = state.cardNumber?.indexNumber() + tvHeader.text = getString(R.string.twins_recreate_title_format, twinIndexNumber) + tvBody.setText(R.string.onboarding_twins_interrupt_warning) + + btnMainAction.text = getString(R.string.twins_recreate_button_format, twinIndexNumber) + btnMainAction.setOnClickListener { + store.dispatch( + TwinCardsAction.Wallet.LaunchFirstStep( + Message(getString(R.string.twins_recreate_title_format, twinIndexNumber)), + assetReader + ) + ) + } + + btnAlternativeAction.isVisible = false + btnAlternativeAction.isClickable = false + } + + private fun setupCreateSecondWalletState(state: TwinCardsState) = + with(binding.onboardingActionContainer) { + switchToCard(state.cardNumber?.pairNumber()) + + val twinPairIndexNumber = state.cardNumber?.pairIndexNumber() + tvHeader.text = getString(R.string.twins_recreate_title_format, twinPairIndexNumber) + tvBody.setText(R.string.onboarding_twins_interrupt_warning) + + btnMainAction.text = + getString(R.string.twins_recreate_button_format, twinPairIndexNumber) + btnMainAction.setOnClickListener { + store.dispatch( + TwinCardsAction.Wallet.LaunchSecondStep( + Message( + getString( + R.string.twins_recreate_title_format, + twinPairIndexNumber + ) + ), + Message(getString(R.string.twins_recreate_title_preparing)), + Message(getString(R.string.twins_recreate_title_creating_wallet)), + ) + ) } } - val twinIndexNumber = state.cardNumber?.indexNumber() - tv_header.text = getString(R.string.twins_recreate_title_format, twinIndexNumber) - tv_body.setText(R.string.onboarding_twins_interrupt_warning) + private fun setupCreateThirdWalletState(state: TwinCardsState) = + with(binding.onboardingActionContainer) { + switchToCard(state.cardNumber) - btn_main_action.text = getString(R.string.twins_recreate_button_format, twinIndexNumber) - btn_main_action.setOnClickListener { - store.dispatch(TwinCardsAction.Wallet.LaunchFirstStep( - Message(getString(R.string.twins_recreate_title_format, twinIndexNumber)), - assetReader - )) + val twinIndexNumber = state.cardNumber?.indexNumber() + tvHeader.text = getString(R.string.twins_recreate_title_format, twinIndexNumber) + tvBody.setText(R.string.onboarding_twins_interrupt_warning) + + btnMainAction.text = getString(R.string.twins_recreate_button_format, twinIndexNumber) + btnMainAction.setOnClickListener { + store.dispatch( + TwinCardsAction.Wallet.LaunchThirdStep( + Message(getString(R.string.twins_recreate_title_format, twinIndexNumber)) + ) + ) + } } - btn_alternative_action.isVisible = false - btn_alternative_action.isClickable = false - } - private fun setupCreateSecondWalletState(state: TwinCardsState) { - switchToCard(state.cardNumber?.pairNumber()) - - val twinPairIndexNumber = state.cardNumber?.pairIndexNumber() - tv_header.text = getString(R.string.twins_recreate_title_format, twinPairIndexNumber) - tv_body.setText(R.string.onboarding_twins_interrupt_warning) - - btn_main_action.text = getString(R.string.twins_recreate_button_format, twinPairIndexNumber) - btn_main_action.setOnClickListener { - store.dispatch(TwinCardsAction.Wallet.LaunchSecondStep( - Message(getString(R.string.twins_recreate_title_format, twinPairIndexNumber)), - Message(getString(R.string.twins_recreate_title_preparing)), - Message(getString(R.string.twins_recreate_title_creating_wallet)), - )) - } - } - - private fun setupCreateThirdWalletState(state: TwinCardsState) { - switchToCard(state.cardNumber) - - val twinIndexNumber = state.cardNumber?.indexNumber() - tv_header.text = getString(R.string.twins_recreate_title_format, twinIndexNumber) - tv_body.setText(R.string.onboarding_twins_interrupt_warning) - - btn_main_action.text = getString(R.string.twins_recreate_button_format, twinIndexNumber) - btn_main_action.setOnClickListener { - store.dispatch(TwinCardsAction.Wallet.LaunchThirdStep( - Message(getString(R.string.twins_recreate_title_format, twinIndexNumber)) - )) - } - } - - - private fun setupTopUpWalletState(state: TwinCardsState) { - when (previousStep) { - TwinCardsStep.None -> { - when (state.cardNumber) { - TwinCardNumber.First -> { - twinsWidget.leapfrogWidget.unfold(false) { - twinsWidget.toActivate(false) { + private fun setupTopUpWalletState(state: TwinCardsState) = + with(binding.onboardingActionContainer) { + when (previousStep) { + TwinCardsStep.None -> { + when (state.cardNumber) { + TwinCardNumber.First -> { + twinsWidget.leapfrogWidget.unfold(false) { + twinsWidget.toActivate(false) { + startPostponedEnterTransition() + } + } + } + TwinCardNumber.Second -> { + switchToCard(state.cardNumber, false) { + twinsWidget.toActivate(false) startPostponedEnterTransition() } } } - TwinCardNumber.Second -> { - switchToCard(state.cardNumber, false) { - twinsWidget.toActivate(false) - startPostponedEnterTransition() - } - } + } + TwinCardsStep.CreateThirdWallet -> { + twinsWidget.toActivate() } } - TwinCardsStep.CreateThirdWallet -> { - twinsWidget.toActivate() - } - } - if (state.isBuyAllowed) { - btn_main_action.setText(R.string.onboarding_top_up_button_but_crypto) - btn_main_action.setOnClickListener { - store.dispatch(TwinCardsAction.TopUp) + if (state.isBuyAllowed) { + btnMainAction.setText(R.string.onboarding_top_up_button_but_crypto) + btnMainAction.setOnClickListener { + store.dispatch(TwinCardsAction.TopUp) + } + + btnAlternativeAction.isVisible = true + btnAlternativeAction.setText(R.string.onboarding_top_up_button_show_wallet_address) + btnAlternativeAction.setOnClickListener { + store.dispatch(TwinCardsAction.ShowAddressInfoDialog) + } + } else { + btnAlternativeAction.setText(R.string.onboarding_button_receive_crypto) + btnAlternativeAction.setOnClickListener { + store.dispatch(TwinCardsAction.ShowAddressInfoDialog) + } + + btnAlternativeAction.isVisible = false } - btn_alternative_action.isVisible = true - btn_alternative_action.setText(R.string.onboarding_top_up_button_show_wallet_address) - btn_alternative_action.setOnClickListener { - store.dispatch(TwinCardsAction.ShowAddressInfoDialog) + tvHeader.setText(R.string.onboarding_top_up_header) + tvBody.setText(R.string.onboarding_top_up_body) + + btnRefreshBalanceWidget.changeState(state.walletBalance.state) + if (btnRefreshBalanceWidget.isShowing != true) { + btnRefreshBalanceWidget.mainView.setOnClickListener { + store.dispatch(TwinCardsAction.Balance.Update) + } } - } else { - btn_main_action.setText(R.string.onboarding_button_receive_crypto) - btn_main_action.setOnClickListener { - store.dispatch(TwinCardsAction.ShowAddressInfoDialog) + binding.onboardingTopContainer.imvCardBackground.setBackgroundDrawable( + requireContext().getDrawableCompat(R.drawable.shape_rectangle_rounded_8) + ) + updateConstraints(state.currentStep, R.layout.lp_onboarding_topup_wallet_twins) + } + + private fun setupDoneState(state: TwinCardsState) = + with(binding.onboardingActionContainer) { + btnMainAction.setText(R.string.onboarding_done_button_continue) + btnMainAction.setOnClickListener { + store.dispatch(TwinCardsAction.Confetti.Hide) + store.dispatch(TwinCardsAction.Done) } - btn_alternative_action.isVisible = false - } + btnAlternativeAction.isVisible = false + btnAlternativeAction.isClickable = false - tv_header.setText(R.string.onboarding_top_up_header) - tv_body.setText(R.string.onboarding_top_up_body) + tvHeader.setText(R.string.onboarding_done_header) + tvBody.setText(R.string.onboarding_done_body) - btnRefreshBalanceWidget.changeState(state.walletBalance.state) - if (btnRefreshBalanceWidget.isShowing != true) { - btnRefreshBalanceWidget.mainView.setOnClickListener { - store.dispatch(TwinCardsAction.Balance.Update) + val layout = when (state.mode) { + CreateTwinWalletMode.CreateWallet -> R.layout.lp_onboarding_done_activation_twins + CreateTwinWalletMode.RecreateWallet -> R.layout.lp_onboarding_done } + updateConstraints(state.currentStep, layout) } - imv_card_background.setBackgroundDrawable(requireContext().getDrawableCompat(R.drawable.shape_rectangle_rounded_8)) - updateConstraints(state.currentStep, R.layout.lp_onboarding_topup_wallet_twins) - } - - private fun setupDoneState(state: TwinCardsState) { - btn_main_action.setText(R.string.onboarding_done_button_continue) - btn_main_action.setOnClickListener { - store.dispatch(TwinCardsAction.Confetti.Hide) - store.dispatch(TwinCardsAction.Done) - } - - btn_alternative_action.isVisible = false - btn_alternative_action.isClickable = false - - tv_header.setText(R.string.onboarding_done_header) - tv_body.setText(R.string.onboarding_done_body) - - val layout = when (state.mode) { - CreateTwinWalletMode.CreateWallet -> R.layout.lp_onboarding_done_activation_twins - CreateTwinWalletMode.RecreateWallet -> R.layout.lp_onboarding_done - } - updateConstraints(state.currentStep, layout) - } private fun updateConstraints(currentStep: TwinCardsStep, @LayoutRes layoutId: Int) { if (this.previousStep == currentStep) return - val constraintSet = ConstraintSet() - constraintSet.clone(requireContext(), layoutId) - constraintSet.applyTo(onboarding_main_container) - val transition = InternalNoteLayoutTransition() - transition.interpolator = OvershootInterpolator() - TransitionManager.beginDelayedTransition(onboarding_main_container, transition) + with(binding.onboardingTopContainer) { + val constraintSet = ConstraintSet() + constraintSet.clone(requireContext(), layoutId) + constraintSet.applyTo(onboardingMainContainer) + val transition = InternalNoteLayoutTransition() + transition.interpolator = OvershootInterpolator() + TransitionManager.beginDelayedTransition(onboardingMainContainer, transition) + } } - private fun switchToCard(cardNumber: TwinCardNumber?, animate: Boolean = true, onEnd: VoidCallback = {}) { + private fun switchToCard( + cardNumber: TwinCardNumber?, + animate: Boolean = true, + onEnd: VoidCallback = {} + ) { val position = cardNumber?.number ?: return if (twinsWidget.leapfrogWidget.getViewPositionByIndex(1) != position - 1) { diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/BackupInfoAdapter.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/BackupInfoAdapter.kt index f7044f9986..3388e72a96 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/BackupInfoAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/BackupInfoAdapter.kt @@ -1,28 +1,30 @@ package com.tangem.tap.features.onboarding.products.wallet.ui import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup import androidx.annotation.StringRes import androidx.recyclerview.widget.RecyclerView import com.tangem.tap.common.extensions.getString import com.tangem.wallet.R -import kotlinx.android.synthetic.main.item_backup_info_adapter.view.* +import com.tangem.wallet.databinding.ItemBackupInfoAdapterBinding class BackupInfoAdapter : RecyclerView.Adapter() { private val data = backupInfoSnippets override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BackupInfoViewHolder = - BackupInfoViewHolder(LayoutInflater.from(parent.context) - .inflate(R.layout.item_backup_info_adapter, parent, false)) + BackupInfoViewHolder( + ItemBackupInfoAdapterBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + ) override fun getItemCount(): Int = data.size override fun onBindViewHolder(holder: BackupInfoViewHolder, position: Int) = - holder.itemView.run { - tv_header.text = getString(data[position].header) - tv_body.text = getString(data[position].body) + holder.binding.run { + tvHeader.text = root.getString(data[position].header) + tvBody.text = root.getString(data[position].body) } } @@ -51,4 +53,5 @@ private val backupInfoSnippets = listOf( ) -class BackupInfoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) \ No newline at end of file +class BackupInfoViewHolder(val binding: ItemBackupInfoAdapterBinding) : + RecyclerView.ViewHolder(binding.root) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt index d63d66047c..1d81fc9a80 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt @@ -7,6 +7,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.transition.TransitionInflater import androidx.transition.TransitionManager +import by.kirich1409.viewbindingdelegate.viewBinding import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.tabs.TabLayoutMediator import com.squareup.picasso.Picasso @@ -21,11 +22,8 @@ import com.tangem.tap.features.onboarding.products.wallet.redux.* import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.AccessCodeDialog import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_onboarding_wallet.* -import kotlinx.android.synthetic.main.layout_onboarding_buttons_add_cards.* -import kotlinx.android.synthetic.main.layout_onboarding_buttons_common.* -import kotlinx.android.synthetic.main.view_confetti.* -import kotlinx.android.synthetic.main.view_onboarding_progress.* +import com.tangem.wallet.databinding.FragmentOnboardingWalletBinding +import com.tangem.wallet.databinding.ViewOnboardingProgressBinding import org.rekotlin.StoreSubscriber class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet), @@ -33,6 +31,12 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet), private var accessCodeDialog: AccessCodeDialog? = null private lateinit var cardsWidget: WalletCardsWidget + private val binding: FragmentOnboardingWalletBinding by viewBinding( + FragmentOnboardingWalletBinding::bind + ) + private val pbBinding: ViewOnboardingProgressBinding by viewBinding( + ViewOnboardingProgressBinding::bind) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -47,19 +51,22 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val leapfrog = LeapfrogWidget(fl_cards_container) + val leapfrog = LeapfrogWidget(binding.flCardsContainer) cardsWidget = WalletCardsWidget(leapfrog) { 200f } startPostponedEnterTransition() - view_pager_backup_info.adapter = BackupInfoAdapter() - TabLayoutMediator(tab_layout_backup_info, view_pager_backup_info) { tab, position -> + binding.viewPagerBackupInfo.adapter = BackupInfoAdapter() + TabLayoutMediator( + binding.tabLayoutBackupInfo, + binding.viewPagerBackupInfo + ) { tab, position -> //Some implementation }.attach() - (activity as? AppCompatActivity)?.setSupportActionBar(toolbar) + (activity as? AppCompatActivity)?.setSupportActionBar(binding.toolbar) store.dispatch(OnboardingWalletAction.Init) - toolbar.setNavigationOnClickListener { activity?.onBackPressed() } + binding.toolbar.setNavigationOnClickListener { activity?.onBackPressed() } store.dispatch(OnboardingWalletAction.LoadArtwork) @@ -81,16 +88,18 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet), } override fun newState(state: OnboardingWalletState) { - if (activity == null) return + if (activity == null || view == null) return requireActivity().invalidateOptionsMenu() - loadImageIntoImageView(state.cardArtworkUrl, imv_front_card) - loadImageIntoImageView(state.cardArtworkUrl, imv_first_backup_card) - loadImageIntoImageView(state.cardArtworkUrl, imv_second_backup_card) + with(binding) { + loadImageIntoImageView(state.cardArtworkUrl, imvFrontCard) + loadImageIntoImageView(state.cardArtworkUrl, imvFirstBackupCard) + loadImageIntoImageView(state.cardArtworkUrl, imvSecondBackupCard) + } - pb_state.max = 6 - pb_state.progress = state.getProgressStep() + pbBinding.pbState.max = 6 + pbBinding.pbState.progress = state.getProgressStep() when (state.step) { OnboardingWalletStep.None -> { @@ -111,15 +120,15 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet), ?.into(view) } - private fun setupCreateWalletState() { - btn_main_action.setText(R.string.onboarding_create_wallet_button_create_wallet) - btn_main_action.setOnClickListener { store.dispatch(OnboardingWalletAction.CreateWallet) } - btn_alternative_action.hide() + private fun setupCreateWalletState() = with(binding) { + layoutButtonsCommon.btnMainAction.setText(R.string.onboarding_create_wallet_button_create_wallet) + layoutButtonsCommon.btnMainAction.setOnClickListener { store.dispatch(OnboardingWalletAction.CreateWallet) } + layoutButtonsCommon.btnAlternativeAction.hide() toolbar.title = getText(R.string.onboarding_getting_started) - tv_header.setText(R.string.onboarding_create_wallet_header) - tv_body.setText(R.string.onboarding_create_wallet_body) + tvHeader.setText(R.string.onboarding_create_wallet_header) + tvBody.setText(R.string.onboarding_create_wallet_body) cardsWidget.toFolded() startPostponedEnterTransition() @@ -129,7 +138,7 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet), private fun setBackupState(state: BackupState) { when (state.backupStep) { BackupStep.InitBackup -> showBackupIntro(state) - BackupStep.ScanOriginCard -> showScanOriginCard(state) + BackupStep.ScanOriginCard -> showScanOriginCard() BackupStep.AddBackupCards -> showAddBackupCards(state) BackupStep.SetAccessCode -> showSetAccessCode() BackupStep.EnterAccessCode -> showEnterAccessCode(state) @@ -140,65 +149,70 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet), } } - private fun showBackupIntro(state: BackupState) { - imv_first_backup_card.show() - imv_second_backup_card.show() + private fun showBackupIntro(state: BackupState) = with(binding) { + imvFirstBackupCard.show() + imvSecondBackupCard.show() cardsWidget.toWelcome() - tv_header.hide() - tv_body.hide() - view_pager_backup_info.show() - tab_layout_backup_info.show() + tvHeader.hide() + tvBody.hide() + viewPagerBackupInfo.show() + tabLayoutBackupInfo.show() + + with(layoutButtonsCommon) { + btnMainAction.text = getText(R.string.onboarding_button_backup_now) + btnAlternativeAction.text = getText(R.string.onboarding_button_skip_backup) + btnAlternativeAction.show(state.canSkipBackup) + btnMainAction.setOnClickListener { store.dispatch(BackupAction.StartBackup) } + btnAlternativeAction.setOnClickListener { store.dispatch(BackupAction.DismissBackup) } + } - btn_main_action.text = getText(R.string.onboarding_button_backup_now) - btn_alternative_action.text = getText(R.string.onboarding_button_skip_backup) - btn_alternative_action.show(state.canSkipBackup) - btn_main_action.setOnClickListener { store.dispatch(BackupAction.StartBackup) } - btn_alternative_action.setOnClickListener { store.dispatch(BackupAction.DismissBackup) } startPostponedEnterTransition() } - private fun showScanOriginCard(state: BackupState) { + private fun showScanOriginCard() = with(binding) { prepareBackupView() cardsWidget.toFolded() - tv_header.text = getText(R.string.onboarding_title_scan_origin_card) - tv_body.text = getString( + tvHeader.text = getText(R.string.onboarding_title_scan_origin_card) + tvBody.text = getString( R.string.onboarding_subtitle_scan_origin_card, ) - btn_main_action.text = getString(R.string.onboarding_button_scan_origin_card) - btn_alternative_action.hide() - btn_main_action.setOnClickListener { store.dispatch(BackupAction.ScanPrimaryCard) } + with(layoutButtonsCommon) { + btnMainAction.text = getString(R.string.onboarding_button_scan_origin_card) + btnAlternativeAction.hide() + btnMainAction.setOnClickListener { store.dispatch(BackupAction.ScanPrimaryCard) } + } } - private fun prepareBackupView() { + private fun prepareBackupView() = with(binding) { toolbar.title = getText(R.string.onboarding_navbar_title_creating_backup) - tv_header.show() - tv_body.show() - view_pager_backup_info.hide() - tab_layout_backup_info.hide() + tvHeader.show() + tvBody.show() + viewPagerBackupInfo.hide() + tabLayoutBackupInfo.hide() - imv_first_backup_card.show() - imv_second_backup_card.show() + imvSecondBackupCard.show() + imvSecondBackupCard.show() } - private fun showAddBackupCards(state: BackupState) { + private fun showAddBackupCards(state: BackupState) = with(binding) { prepareBackupView() accessCodeDialog?.dismiss() accessCodeDialog = null - layout_buttons_add_cards.show() - layout_buttons_common.hide() - btn_add_card.text = getText(R.string.onboarding_button_add_backup_card) + layoutButtonsAddCards.root.show() + layoutButtonsCommon.root.hide() + layoutButtonsAddCards.btnAddCard.text = getText(R.string.onboarding_button_add_backup_card) if (state.backupCardsNumber < state.maxBackupCards) { - btn_add_card.setOnClickListener { store.dispatch(BackupAction.AddBackupCard) } + layoutButtonsAddCards.btnAddCard.setOnClickListener { store.dispatch(BackupAction.AddBackupCard) } } else { - btn_add_card.isEnabled = false + layoutButtonsAddCards.btnAddCard.isEnabled = false } when (state.backupCardsNumber) { @@ -207,27 +221,27 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet), cardsWidget.getFirstBackupCardView().animate().alpha(0.6f).setDuration(200) cardsWidget.getSecondBackupCardView().animate().alpha(0.2f).setDuration(200) } - tv_header.text = getText(R.string.onboarding_title_no_backup_cards) - tv_body.text = getText(R.string.onboarding_subtitle_no_backup_cards) + tvHeader.text = getText(R.string.onboarding_title_no_backup_cards) + tvBody.text = getText(R.string.onboarding_subtitle_no_backup_cards) } 1 -> { - tv_header.text = getText(R.string.onboarding_title_one_backup_card) - tv_body.text = getText(R.string.onboarding_subtitle_one_backup_card) + tvHeader.text = getText(R.string.onboarding_title_one_backup_card) + tvBody.text = getText(R.string.onboarding_subtitle_one_backup_card) cardsWidget.getFirstBackupCardView().animate().alpha(1f).setDuration(400) cardsWidget.getSecondBackupCardView().alpha = 0.2f } 2 -> { - tv_header.text = getText(R.string.onboarding_title_two_backup_cards) - tv_body.text = getText(R.string.onboarding_subtitle_two_backup_cards) + tvHeader.text = getText(R.string.onboarding_title_two_backup_cards) + tvBody.text = getText(R.string.onboarding_subtitle_two_backup_cards) cardsWidget.getFirstBackupCardView().alpha = 1f cardsWidget.getSecondBackupCardView().animate().alpha(1f).setDuration(400) } } - btn_continue.text = getText(R.string.onboarding_button_finalize_backup) - btn_continue.setOnClickListener { store.dispatch(BackupAction.FinishAddingBackupCards) } - btn_continue.isEnabled = state.backupCardsNumber != 0 + layoutButtonsAddCards.btnContinue.text = getText(R.string.onboarding_button_finalize_backup) + layoutButtonsAddCards.btnContinue.setOnClickListener { store.dispatch(BackupAction.FinishAddingBackupCards) } + layoutButtonsAddCards.btnContinue.isEnabled = state.backupCardsNumber != 0 } private fun showSetAccessCode() { @@ -258,7 +272,7 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet), accessCodeDialog?.showError(state.accessCodeError) } - private fun showWritePrimaryCard(state: BackupState) { + private fun showWritePrimaryCard(state: BackupState) = with(binding) { accessCodeDialog?.dismiss() prepareViewForFinalizeStep() @@ -270,33 +284,33 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet), } val cardIdFormatter = CardIdFormatter(CardIdDisplayFormat.LastMasked(4)) - tv_header.text = getText(R.string.onboarding_title_prepare_origin) - tv_body.text = getString( + tvHeader.text = getText(R.string.onboarding_title_prepare_origin) + tvBody.text = getString( R.string.onboarding_subtitle_scan_primary_card_format, state.primaryCardId?.let { cardIdFormatter.getFormattedCardId(it) } ) - btn_main_action.text = getText(R.string.onboarding_button_backup_origin) - btn_main_action.setOnClickListener { store.dispatch(BackupAction.WritePrimaryCard) } + layoutButtonsCommon.btnMainAction.text = getText(R.string.onboarding_button_backup_origin) + layoutButtonsCommon.btnMainAction.setOnClickListener { store.dispatch(BackupAction.WritePrimaryCard) } } - private fun prepareViewForFinalizeStep() { - layout_buttons_add_cards.hide() - layout_buttons_common.show() + private fun prepareViewForFinalizeStep() = with(binding) { + layoutButtonsAddCards.root.hide() + layoutButtonsCommon.root.show() - imv_first_backup_card.show() - imv_second_backup_card.show() + imvFirstBackupCard.show() + imvSecondBackupCard.show() toolbar.title = getText(R.string.onboarding_button_finalize_backup) - imv_card_background.hide() + imvCardBackground.hide() cardsWidget.toLeapfrog() - btn_alternative_action.hide() + layoutButtonsCommon.btnAlternativeAction.hide() } - private fun showWriteBackupCard(state: BackupState) { + private fun showWriteBackupCard(state: BackupState) = with(binding) { prepareViewForFinalizeStep() cardsWidget.getSecondBackupCardView().show(state.backupCardsNumber == 2) @@ -316,46 +330,47 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet), } val cardIdFormatter = CardIdFormatter(CardIdDisplayFormat.LastMasked(4)) - tv_header.text = + tvHeader.text = getString(R.string.onboarding_title_backup_card_format, cardNumber) - tv_body.text = getString( + tvBody.text = getString( R.string.onboarding_subtitle_scan_backup_card_format, cardIdFormatter.getFormattedCardId(state.backupCardIds[cardNumber - 1]) ) - btn_main_action.text = getString( + layoutButtonsCommon.btnMainAction.text = getString( R.string.onboarding_button_backup_card_format, cardNumber ) - - btn_main_action.setOnClickListener { store.dispatch(BackupAction.WriteBackupCard(cardNumber)) } + layoutButtonsCommon.btnMainAction.setOnClickListener { + store.dispatch(BackupAction.WriteBackupCard(cardNumber)) + } } - private fun showSuccess() { - tv_header.text = getText(R.string.onboarding_done_header) + private fun showSuccess() = with(binding) { + tvHeader.text = getText(R.string.onboarding_done_header) - tv_header.show() - tv_body.show() - view_pager_backup_info.hide() - tab_layout_backup_info.hide() + tvHeader.show() + tvBody.show() + viewPagerBackupInfo.hide() + tabLayoutBackupInfo.hide() - tv_body.text = getText(R.string.onboarding_subtitle_success_tangem_wallet_onboarding) - btn_main_action.text = getText(R.string.onboarding_button_continue_wallet) - btn_alternative_action.hide() - btn_main_action.setOnClickListener { - lav_confetti.cancelAnimation() - lav_confetti.hide() + tvBody.text = getText(R.string.onboarding_subtitle_success_tangem_wallet_onboarding) + layoutButtonsCommon.btnMainAction.text = getText(R.string.onboarding_button_continue_wallet) + layoutButtonsCommon.btnAlternativeAction.hide() + layoutButtonsCommon.btnMainAction.setOnClickListener { + vConfetti.lavConfetti.cancelAnimation() + vConfetti.lavConfetti.hide() store.dispatch(OnboardingWalletAction.FinishOnboarding) } cardsWidget.leapfrogWidget.fold { - fl_cards_container?.hide() - imv_card_background?.hide() - lav_confetti?.show() - lav_confetti?.playAnimation() - imv_success?.alpha = 0f - imv_success?.show() + flCardsContainer.hide() + imvCardBackground.hide() + vConfetti.lavConfetti.show() + vConfetti.lavConfetti.playAnimation() + imvSuccess.alpha = 0f + imvSuccess.show() - imv_success?.animate() + imvSuccess.animate() ?.alpha(1f) ?.setDuration(400) } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/AccessCodeDialog.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/AccessCodeDialog.kt index 9433d4e274..c8b5e3ccb0 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/AccessCodeDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/AccessCodeDialog.kt @@ -1,8 +1,9 @@ package com.tangem.tap.features.onboarding.products.wallet.ui.dialogs import android.content.Context +import android.content.DialogInterface +import android.os.Bundle import android.view.LayoutInflater -import android.view.View import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.tangem.tap.common.extensions.hide @@ -11,64 +12,69 @@ import com.tangem.tap.features.onboarding.products.wallet.redux.AccessCodeError import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.layout_backup_access_code.* -import kotlinx.android.synthetic.main.layout_backup_access_code_info.* -import kotlinx.android.synthetic.main.layout_backup_access_code_submit.* +import com.tangem.wallet.databinding.LayoutBackupAccessCodeBinding class AccessCodeDialog(context: Context) : BottomSheetDialog(context) { + var binding: LayoutBackupAccessCodeBinding? = null - init { - behavior.state = BottomSheetBehavior.STATE_EXPANDED - val dialogView = LayoutInflater.from(context).inflate(R.layout.layout_backup_access_code, null) - setContentView(dialogView) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = LayoutBackupAccessCodeBinding + .inflate(LayoutInflater.from(context)) + setContentView(binding!!.root) behavior.state = BottomSheetBehavior.STATE_EXPANDED } - override fun setContentView(view: View) { - super.setContentView(view) - behavior.state = BottomSheetBehavior.STATE_EXPANDED + override fun setOnDismissListener(listener: DialogInterface.OnDismissListener?) { + super.setOnDismissListener(listener) + binding = null } - - fun showInfoScreen() { + fun showInfoScreen() = with(binding!!) { behavior.state = BottomSheetBehavior.STATE_EXPANDED - access_code_title.text = context.getText(R.string.onboarding_access_code_intro_title) - layout_backup_access_code_info.show() - layout_backup_access_code_submit.hide() - btn_access_code_create.setOnClickListener { + accessCodeTitle.text = context.getText(R.string.onboarding_access_code_intro_title) + layoutBackupAccessCodeInfo.root.show() + layoutBackupAccessCodeSubmit.root.hide() + layoutBackupAccessCodeInfo.btnAccessCodeCreate.setOnClickListener { store.dispatch(BackupAction.ShowEnterAccessCodeScreen) } } - fun showEnterAccessCode() { - layout_backup_access_code_info.hide() - layout_backup_access_code_submit.show() - access_code_title.text = context.getText(R.string.onboarding_access_code_intro_title) - btn_access_code_submit.text = context.getText(R.string.common_continue) - btn_access_code_submit.setOnClickListener { - store.dispatch(BackupAction.CheckAccessCode(et_access_code.text.toString())) + fun showEnterAccessCode() = with(binding!!) { + layoutBackupAccessCodeInfo.root.hide() + layoutBackupAccessCodeSubmit.root.show() + accessCodeTitle.text = context.getText(R.string.onboarding_access_code_intro_title) + + with(layoutBackupAccessCodeSubmit) { + btnAccessCodeSubmit.text = context.getText(R.string.common_continue) + btnAccessCodeSubmit.setOnClickListener { + store.dispatch(BackupAction.CheckAccessCode(etAccessCode.text.toString())) + } } } - fun showReenterAccessCode() { - layout_backup_access_code_info.hide() - layout_backup_access_code_submit.show() - access_code_title.text = context.getText(R.string.onboarding_access_code_repeat_code_title) - et_access_code.setText("") - btn_access_code_submit.text = context.getText(R.string.common_submit) - btn_access_code_submit.setOnClickListener { - store.dispatch(BackupAction.SaveAccessCodeConfirmation(et_access_code.text.toString())) + fun showReenterAccessCode() = with(binding!!) { + layoutBackupAccessCodeInfo.root.hide() + layoutBackupAccessCodeSubmit.root.show() + accessCodeTitle.text = context.getText(R.string.onboarding_access_code_repeat_code_title) + with(layoutBackupAccessCodeSubmit) { + etAccessCode.setText("") + btnAccessCodeSubmit.text = context.getText(R.string.common_submit) + btnAccessCodeSubmit.setOnClickListener { + store.dispatch(BackupAction.SaveAccessCodeConfirmation(etAccessCode.text.toString())) + } } + } - fun showError(error: AccessCodeError?) { + fun showError(error: AccessCodeError?) = with(binding!!.layoutBackupAccessCodeSubmit) { when (error) { AccessCodeError.CodeTooShort -> - til_access_code.error = context.getString(R.string.onboarding_access_code_too_short) + tilAccessCode.error = context.getString(R.string.onboarding_access_code_too_short) AccessCodeError.CodesDoNotMatch -> - til_access_code.error = context.getString(R.string.onboarding_access_codes_doesnt_match) - null -> til_access_code.error = null + tilAccessCode.error = context.getString(R.string.onboarding_access_codes_doesnt_match) + null -> tilAccessCode.error = null } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt index eab62a8479..d999d79bcb 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt @@ -11,6 +11,7 @@ import androidx.core.view.postDelayed import androidx.core.widget.addTextChangedListener import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import by.kirich1409.viewbindingdelegate.viewBinding import com.google.android.material.textfield.TextInputEditText import com.tangem.Message import com.tangem.tangem_sdk_new.extensions.dpToPx @@ -40,10 +41,7 @@ import com.tangem.tap.features.wallet.ui.adapters.WarningMessagesAdapter import com.tangem.tap.mainScope import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_send.* -import kotlinx.android.synthetic.main.layout_send_address_payid.* -import kotlinx.android.synthetic.main.layout_send_amount.* -import kotlinx.android.synthetic.main.layout_send_fee.* +import com.tangem.wallet.databinding.FragmentSendBinding import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.* @@ -62,6 +60,8 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { private val sendSubscriber = SendStateSubscriber(this) private lateinit var keyboardObserver: KeyboardObserver + val binding: FragmentSendBinding by viewBinding(FragmentSendBinding::bind) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) addBackPressHandler(this) @@ -77,7 +77,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { store.dispatch(SendActionUi.CheckIfTransactionDataWasProvided) } - private fun initSendButtonStates() { + private fun initSendButtonStates() = with(binding) { btnSend.setOnClickListener { store.dispatch(SendActionUi.SendAmountToRecipient( Message(getString(R.string.initial_message_sign_header)) @@ -86,7 +86,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { sendBtn = IndeterminateProgressButtonWidget(btnSend, progress) } - private fun setupAddressOrPayIdLayout() { + private fun setupAddressOrPayIdLayout() = with(binding.lSendAddressPayid) { store.dispatch(SetTruncateHandler { etAddressOrPayId.truncateMiddleWith(it, "...") }) store.dispatch(CheckClipboard(requireContext().getFromClipboard()?.toString())) @@ -113,7 +113,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { } } - private fun setupTransactionExtrasLayout() { + private fun setupTransactionExtrasLayout() = with(binding.lSendAddressPayid) { etXlmMemo.inputtedTextAsFlow() .debounce(400) .filter { @@ -151,9 +151,9 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { // Delayed launch is needed in order for the UI to be drawn and to process the sent events. // If do not use the delay, then etAmount error field is not displayed when // inserting an incorrect amount by shareUri - imvQrCode.postDelayed({ + binding.lSendAddressPayid.imvQrCode.postDelayed({ store.dispatch(PasteAddressPayId(scannedCode)) - store.dispatch(TruncateOrRestore(!etAddressOrPayId.isFocused)) + store.dispatch(TruncateOrRestore(!binding.lSendAddressPayid.etAddressOrPayId.isFocused)) }, 200) } @@ -165,7 +165,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { val decimalSeparator = DecimalFormatSymbols.getInstance().decimalSeparator.toString() store.dispatch(AmountAction.SetDecimalSeparator(decimalSeparator)) - tvAmountCurrency.setOnClickListener { + binding.lSendAmount.tvAmountCurrency.setOnClickListener { store.dispatch(ToggleMainCurrency) store.dispatch(ReceiptAction.RefreshReceipt) store.dispatch(SendAction.ChangeSendButtonState(store.state.sendState.getButtonState())) @@ -223,8 +223,8 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { } } - private fun setupFeeLayout() { - flExpandCollapse.setOnClickListener { + private fun setupFeeLayout() = with(binding.clNetworkFee) { + flExpandCollapse.flExpandCollapse.setOnClickListener { store.dispatch(ToggleControlsVisibility) } chipGroup.check(FeeUiHelper.toId(FeeType.NORMAL)) @@ -240,12 +240,12 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { } } - private fun setupWarningMessages() { + private fun setupWarningMessages() = with(binding) { warningsAdapter = WarningMessagesAdapter() val layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false) - rv_warning_messages.layoutManager = layoutManager - rv_warning_messages.addItemDecoration(SpacesItemDecoration(rv_warning_messages.dpToPx(16f).toInt())) - rv_warning_messages.adapter = warningsAdapter + rvWarningMessages.layoutManager = layoutManager + rvWarningMessages.addItemDecoration(SpacesItemDecoration(rvWarningMessages.dpToPx(16f).toInt())) + rvWarningMessages.adapter = warningsAdapter store.dispatch(SendAction.Warnings.Update) } diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt index 894d9809ba..ac785194fd 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt @@ -26,32 +26,30 @@ import com.tangem.tap.features.send.ui.dialogs.TezosWarningDialog import com.tangem.tap.features.wallet.ui.adapters.WarningMessagesAdapter import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.btn_expand_collapse.* -import kotlinx.android.synthetic.main.fragment_send.* -import kotlinx.android.synthetic.main.fragment_send.clReceiptContainer -import kotlinx.android.synthetic.main.layout_receipt_total.* -import kotlinx.android.synthetic.main.layout_receipt_total.view.* -import kotlinx.android.synthetic.main.layout_send_address_payid.* -import kotlinx.android.synthetic.main.layout_send_amount.* -import kotlinx.android.synthetic.main.layout_send_fee.* -import kotlinx.android.synthetic.main.layout_send_receipt.* /** [REDACTED_AUTHOR] */ -class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber(fragment) { +class SendStateSubscriber(fragment: BaseStoreFragment) : + FragmentStateSubscriber(fragment) { private var dialog: Dialog? = null override fun updateWithNewState(fg: BaseStoreFragment, state: SendState) { + fg.view ?: return + if (fg !is SendFragment) return + val lastChangedStates = state.lastChangedStates.toList() state.lastChangedStates.clear() - fg.main_send_container.beginDelayedTransition() + (fg as? SendFragment)?.binding?.mainSendContainer?.beginDelayedTransition() lastChangedStates.forEach { when (it) { StateId.SEND_SCREEN -> handleSendScreen(fg, state) StateId.ADDRESS_PAY_ID -> handleAddressPayIdState(fg, state.addressPayIdState) - StateId.TRANSACTION_EXTRAS -> handleTransactionExtrasState(fg, state.transactionExtrasState) + StateId.TRANSACTION_EXTRAS -> handleTransactionExtrasState( + fg, + state.transactionExtrasState + ) StateId.AMOUNT -> handleAmountState(fg, state.amountState) StateId.FEE -> handleFeeState(fg, state.feeState) StateId.RECEIPT -> handleReceiptState(fg, state.receiptState) @@ -59,57 +57,58 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber } } - private fun handleTransactionExtrasState(fg: BaseStoreFragment, infoState: TransactionExtrasState) { - fun showView(view: View, info: Any?) { - view.show(info != null) - } - showView(fg.xlmMemoContainer, infoState.xlmMemo) - showView(fg.xrpDestinationTagContainer, infoState.xrpDestinationTag) - showView(fg.binanceMemoContainer, infoState.binanceMemo) + private fun handleTransactionExtrasState(fg: SendFragment, infoState: TransactionExtrasState) = + with(fg.binding.lSendAddressPayid) { - infoState.xlmMemo?.let { - fg.etXlmMemo.inputType = when (it.selectedMemoType) { - XlmMemoType.TEXT -> InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS - XlmMemoType.ID -> InputType.TYPE_CLASS_NUMBER + fun showView(view: View, info: Any?) { + view.show(info != null) } - if (!it.viewFieldValue.isFromUserInput) fg.etXlmMemo.setText(it.viewFieldValue.value) - if (it.error != null) { - if (it.error == TransactionExtraError.INVALID_XLM_MEMO) { - fg.tilXlmMemo.error = fg.getText(R.string.send_error_invalid_memo_id) - } - } else { - fg.tilXlmMemo.error = null - } - } - infoState.xrpDestinationTag?.let { - if (infoState.xrpDestinationTag.error != null) { - if (infoState.xrpDestinationTag.error == TransactionExtraError.INVALID_DESTINATION_TAG) { - fg.tilDestinationTag.error = fg.getText(R.string.send_error_invalid_destination_tag) - } - } else { - fg.tilDestinationTag.error = null - } - if (!it.viewFieldValue.isFromUserInput) { - fg.etDestinationTag.setText(it.viewFieldValue.value) - } - } - infoState.binanceMemo?.let { - if (infoState.binanceMemo.error != null) { - if (infoState.binanceMemo.error == TransactionExtraError.INVALID_BINANCE_MEMO) { - fg.tilBinanceMemo.error = fg.getText(R.string.send_error_invalid_memo_id) - } - } else { - fg.tilBinanceMemo.error = null - } - if (!it.viewFieldValue.isFromUserInput) { - fg.etBinanceMemo.setText(it.viewFieldValue.value) - } - } - } + showView(xlmMemoContainer, infoState.xlmMemo) + showView(xrpDestinationTagContainer, infoState.xrpDestinationTag) + showView(binanceMemoContainer, infoState.binanceMemo) - private fun handleSendScreen(fg: BaseStoreFragment, state: SendState) { - val sendFragment = (fg as? SendFragment) ?: return + infoState.xlmMemo?.let { + etXlmMemo.inputType = when (it.selectedMemoType) { + XlmMemoType.TEXT -> InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS + XlmMemoType.ID -> InputType.TYPE_CLASS_NUMBER + } + if (!it.viewFieldValue.isFromUserInput) etXlmMemo.setText(it.viewFieldValue.value) + if (it.error != null) { + if (it.error == TransactionExtraError.INVALID_XLM_MEMO) { + tilXlmMemo.error = fg.getText(R.string.send_error_invalid_memo_id) + } + } else { + tilXlmMemo.error = null + } + } + infoState.xrpDestinationTag?.let { + if (infoState.xrpDestinationTag.error != null) { + if (infoState.xrpDestinationTag.error == TransactionExtraError.INVALID_DESTINATION_TAG) { + tilDestinationTag.error = + fg.getText(R.string.send_error_invalid_destination_tag) + } + } else { + tilDestinationTag.error = null + } + if (!it.viewFieldValue.isFromUserInput) { + etDestinationTag.setText(it.viewFieldValue.value) + } + } + infoState.binanceMemo?.let { + if (infoState.binanceMemo.error != null) { + if (infoState.binanceMemo.error == TransactionExtraError.INVALID_BINANCE_MEMO) { + tilBinanceMemo.error = fg.getText(R.string.send_error_invalid_memo_id) + } + } else { + tilBinanceMemo.error = null + } + if (!it.viewFieldValue.isFromUserInput) { + etBinanceMemo.setText(it.viewFieldValue.value) + } + } + } + private fun handleSendScreen(fg: SendFragment, state: SendState) = with(fg.binding) { when (state.dialog) { is SendAction.Dialog.TezosWarningDialog -> { if (dialog == null) { @@ -129,147 +128,158 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber } } - sendFragment.sendBtn.changeState(state.sendButtonState.progressState) - sendFragment.sendBtn.mainView.isEnabled = state.sendButtonState.enabled + fg.sendBtn.changeState(state.sendButtonState.progressState) + fg.sendBtn.mainView.isEnabled = state.sendButtonState.enabled - val rv = fg.rv_warning_messages + val rv = rvWarningMessages val adapter = rv.adapter as? WarningMessagesAdapter ?: return adapter.submitList(state.sendWarningsList) rv.show(state.sendWarningsList.isNotEmpty()) - fg.toolbar.title = fg.getString( + toolbar.title = fg.getString( R.string.send_title_currency_format, state.amountState.mainCurrency.currencySymbol ) } - private fun handleAddressPayIdState(fg: BaseStoreFragment, state: AddressPayIdState) { - fun parseError(context: Context, error: Error?): String? { - val resId = when (error) { - Error.PAY_ID_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.send_error_payid_unsupported_by_blockchain - Error.PAY_ID_NOT_REGISTERED -> R.string.send_error_payid_not_registered - Error.PAY_ID_REQUEST_FAILED -> R.string.send_error_payid_request_failed - Error.ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.send_validation_invalid_address - Error.ADDRESS_SAME_AS_WALLET -> R.string.send_error_address_same_as_wallet - else -> null + private fun handleAddressPayIdState(fg: SendFragment, state: AddressPayIdState) = + with(fg.binding.lSendAddressPayid) { + fun parseError(context: Context, error: Error?): String? { + val resId = when (error) { + Error.PAY_ID_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.send_error_payid_unsupported_by_blockchain + Error.PAY_ID_NOT_REGISTERED -> R.string.send_error_payid_not_registered + Error.PAY_ID_REQUEST_FAILED -> R.string.send_error_payid_request_failed + Error.ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.send_validation_invalid_address + Error.ADDRESS_SAME_AS_WALLET -> R.string.send_error_address_same_as_wallet + else -> null + } + return if (resId == null) null else context.getString(resId, "", "") } - return if (resId == null) null else context.getString(resId, "", "") + + imvPaste.isEnabled = state.pasteIsEnabled + + val et = etAddressOrPayId + val til = tilAddressOrPayId + val parsedError = parseError(til.context, state.error) + + til.isEnabled = state.inputIsEnabled + imvPaste.show(state.inputIsEnabled) + imvQrCode.show(state.inputIsEnabled) + flPaste.show(state.inputIsEnabled) + flQrCode.show(state.inputIsEnabled) + + val hintResId = if (state.sendingToPayIdEnabled) { + R.string.send_destination_hint_address_payid + } else { + R.string.send_destination_hint_address + } + til.hint = til.getString(hintResId) + til.error = parsedError + til.isErrorEnabled = parsedError != null + til.helperText = state.destinationWalletAddress + til.isHelperTextEnabled = state.isPayIdState() && parsedError == null + + if (!state.viewFieldValue.isFromUserInput) et.update(state.viewFieldValue.value) } - fg.imvPaste.isEnabled = state.pasteIsEnabled - val et = fg.etAddressOrPayId - val til = fg.tilAddressOrPayId - val parsedError = parseError(til.context, state.error) - - til.isEnabled = state.inputIsEnabled - fg.imvPaste.show(state.inputIsEnabled) - fg.imvQrCode.show(state.inputIsEnabled) - fg.flPaste.show(state.inputIsEnabled) - fg.flQrCode.show(state.inputIsEnabled) - - val hintResId = if (state.sendingToPayIdEnabled) { - R.string.send_destination_hint_address_payid - } else { - R.string.send_destination_hint_address - } - til.hint = til.getString(hintResId) - til.error = parsedError - til.isErrorEnabled = parsedError != null - til.helperText = state.destinationWalletAddress - til.isHelperTextEnabled = state.isPayIdState() && parsedError == null - - if (!state.viewFieldValue.isFromUserInput) et.update(state.viewFieldValue.value) - } - - private fun handleAmountState(fg: BaseStoreFragment, state: AmountState) { + private fun handleAmountState(fg: SendFragment, state: AmountState) = with(fg.binding.lSendAmount) { if (state.error != null) { val context = fg.requireContext() val message = when (state.error) { is MultiMessageError -> { val multiError = state.error as MultiMessageError - val messageList = multiError.assembleErrors().map { getMessageString(context, it.first, it.second) } + val messageList = multiError.assembleErrors() + .map { getMessageString(context, it.first, it.second) } multiError.builder(messageList) } else -> context.getString(state.error.messageResource) } - fg.tilAmountToSend.enableError(true, message) + tilAmountToSend.enableError(true, message) } else { - fg.tilAmountToSend.enableError(false) + tilAmountToSend.enableError(false) } val filter = DecimalDigitsInputFilter(12, state.maxLengthOfAmount, state.decimalSeparator) - fg.etAmountToSend.filters = arrayOf(filter) + etAmountToSend.filters = arrayOf(filter) val amountToSend = state.viewAmountValue - if (!amountToSend.isFromUserInput) fg.etAmountToSend.update(amountToSend.value) + if (!amountToSend.isFromUserInput) etAmountToSend.update(amountToSend.value) - fg.tvAmountCurrency.update(state.mainCurrency.currencySymbol) + tvAmountCurrency.update(state.mainCurrency.currencySymbol) (fg as? SendFragment)?.saveMainCurrency(state.mainCurrency.type) val balanceText = when (state.mainCurrency.type) { - MainCurrencyType.FIAT -> fg.getString(R.string.send_balance_subtitle_format, - state.viewBalanceValue, state.mainCurrency.currencySymbol).remove(":") - MainCurrencyType.CRYPTO -> fg.getString(R.string.send_balance_subtitle_format, - state.mainCurrency.currencySymbol, state.viewBalanceValue) + MainCurrencyType.FIAT -> fg.getString( + R.string.send_balance_subtitle_format, + state.viewBalanceValue, state.mainCurrency.currencySymbol + ).remove(":") + MainCurrencyType.CRYPTO -> fg.getString( + R.string.send_balance_subtitle_format, + state.mainCurrency.currencySymbol, state.viewBalanceValue + ) } - fg.tvBalance.update(balanceText) + tvBalance.update(balanceText) - fg.tilAmountToSend.isEnabled = state.inputIsEnabled + tilAmountToSend.isEnabled = state.inputIsEnabled val imageRes = if (state.inputIsEnabled) R.drawable.ic_arrows_up_down else 0 - fg.tvAmountCurrency.setCompoundDrawablesWithIntrinsicBounds(0, 0, imageRes, 0) + tvAmountCurrency.setCompoundDrawablesWithIntrinsicBounds(0, 0, imageRes, 0) val textColor = if (state.inputIsEnabled) R.color.blue else R.color.textGray - fg.tvAmountCurrency.setTextColor(fg.getColor(textColor)) - + tvAmountCurrency.setTextColor(fg.getColor(textColor)) } - private fun handleFeeState(fg: BaseStoreFragment, state: FeeState) { - fg.chipGroup.fitChipsByGroupWidth() + private fun handleFeeState(fg: SendFragment, state: FeeState) = with(fg.binding.clNetworkFee) { + chipGroup.fitChipsByGroupWidth() fg.view?.findViewById(R.id.clNetworkFee)?.show(state.mainLayoutIsVisible) + flExpandCollapse.imvExpandCollapse.rotation = if (state.controlsLayoutIsVisible) 0f else 180f + llFeeControlsContainer.show(state.controlsLayoutIsVisible) + chipGroup.show(state.feeChipGroupIsVisible) - fg.imvExpandCollapse.rotation = if (state.controlsLayoutIsVisible) 0f else 180f - fg.llFeeControlsContainer.show(state.controlsLayoutIsVisible) - fg.chipGroup.show(state.feeChipGroupIsVisible) - - fg.swIncludeFee.isEnabled = state.includeFeeSwitcherIsEnabled - if (fg.swIncludeFee.isChecked != state.feeIsIncluded) { - fg.swIncludeFee.isChecked = state.feeIsIncluded + swIncludeFee.isEnabled = state.includeFeeSwitcherIsEnabled + if (swIncludeFee.isChecked != state.feeIsIncluded) { + swIncludeFee.isChecked = state.feeIsIncluded } if (state.error == FeeAction.Error.REQUEST_FAILED) { - fg.showRetrySnackbar(fg.requireContext().getString(R.string.send_error_fee_request_failed)) { + fg.showRetrySnackbar( + fg.requireContext().getString(R.string.send_error_fee_request_failed) + ) { store.dispatch(FeeAction.RequestFee) } } val chipId = FeeUiHelper.toId(state.selectedFeeType) - if (fg.chipGroup.checkedChipId != chipId && chipId != View.NO_ID) fg.chipGroup.check(chipId) + if (chipGroup.checkedChipId != chipId && chipId != View.NO_ID) chipGroup.check(chipId) } - private fun handleReceiptState(fg: BaseStoreFragment, state: ReceiptState) { - val mainLayout = fg.clReceiptContainer as ViewGroup - val totalLayout = fg.llTotal as ViewGroup - val totalTokenLayout = fg.flTotalTokenCrypto as ViewGroup + private fun handleReceiptState(fg: SendFragment, state: ReceiptState) = with(fg.binding.clReceiptContainer) { + val mainLayout = clReceiptContainer as ViewGroup + val totalLayout = llTotalContainer.llTotal as ViewGroup + val totalTokenLayout = llTotalContainer.flTotalTokenCrypto as ViewGroup fun getString(id: Int, vararg formatStrings: String): String = - mainLayout.context.getString(id, *formatStrings) + mainLayout.context.getString(id, *formatStrings) val rough = getString(R.string.sign_rough) - fun roughOrEmpty(value: String): String = if (value == ReceiptReducer.EMPTY) value else "$rough $value" + fun roughOrEmpty(value: String): String = + if (value == ReceiptReducer.EMPTY) value else "$rough $value" when (state.visibleTypeOfReceipt) { ReceiptLayoutType.FIAT -> { val receipt = state.fiat ?: return + llTotalContainer.tvTotalValue totalLayout.show(true) totalTokenLayout.show(false) - fg.tvReceiptAmountValue.update("${receipt.amountFiat} ${receipt.symbols.fiat}") - fg.tvReceiptFeeValue.update("${receipt.feeFiat} ${receipt.symbols.fiat}") - totalLayout.tvTotalValue.update("${roughOrEmpty(receipt.totalFiat)} ${receipt.symbols.fiat}") + tvReceiptAmountValue.update("${receipt.amountFiat} ${receipt.symbols.fiat}") + tvReceiptFeeValue.update("${receipt.feeFiat} ${receipt.symbols.fiat}") + llTotalContainer.tvTotalValue.update("${roughOrEmpty(receipt.totalFiat)} ${receipt.symbols.fiat}") - val willSent = getString(R.string.send_total_subtitle_format, - receipt.willSentCrypto, receipt.symbols.crypto) - totalLayout.tvWillBeSentValue.update(willSent) + val willSent = getString( + R.string.send_total_subtitle_format, + receipt.willSentCrypto, receipt.symbols.crypto + ) + llTotalContainer.tvWillBeSentValue.update(willSent) } ReceiptLayoutType.CRYPTO -> { @@ -277,34 +287,34 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber totalLayout.show(true) totalTokenLayout.show(false) - fg.tvReceiptAmountValue.update("${receipt.amountCrypto} ${receipt.symbols.crypto}") - fg.tvReceiptFeeValue.update("${receipt.feeCrypto} ${receipt.symbols.crypto}") - totalLayout.tvTotalValue.update("${receipt.totalCrypto} ${receipt.symbols.crypto}") + tvReceiptAmountValue.update("${receipt.amountCrypto} ${receipt.symbols.crypto}") + tvReceiptFeeValue.update("${receipt.feeCrypto} ${receipt.symbols.crypto}") + llTotalContainer.tvTotalValue.update("${receipt.totalCrypto} ${receipt.symbols.crypto}") val willSent = SpannableStringBuilder() - .bold { - append(roughOrEmpty(receipt.willSentFiat)).append(" ") - append(receipt.symbols.fiat) - append(" (fee: ${receipt.feeFiat} ") - append(receipt.symbols.fiat).append(")") - } - totalLayout.tvWillBeSentValue.update(willSent.toString()) + .bold { + append(roughOrEmpty(receipt.willSentFiat)).append(" ") + append(receipt.symbols.fiat) + append(" (fee: ${receipt.feeFiat} ") + append(receipt.symbols.fiat).append(")") + } + llTotalContainer.tvWillBeSentValue.update(willSent.toString()) } ReceiptLayoutType.TOKEN_FIAT -> { val receipt = state.tokenFiat ?: return totalLayout.show(true) totalTokenLayout.show(false) - fg.tvReceiptAmountValue.update("${receipt.amountFiat} ${receipt.symbols.fiat}") - fg.tvReceiptFeeValue.update("${receipt.feeFiat} ${receipt.symbols.fiat}") - totalLayout.tvTotalValue.update("${roughOrEmpty(receipt.totalFiat)} ${receipt.symbols.fiat}") + tvReceiptAmountValue.update("${receipt.amountFiat} ${receipt.symbols.fiat}") + tvReceiptFeeValue.update("${receipt.feeFiat} ${receipt.symbols.fiat}") + llTotalContainer.tvTotalValue.update("${roughOrEmpty(receipt.totalFiat)} ${receipt.symbols.fiat}") val willSent = getString( R.string.send_total_subtitle_asset_format, receipt.symbols.token ?: "", receipt.willSentToken, receipt.symbols.crypto, receipt.willSentFeeCoin ) - totalLayout.tvWillBeSentValue.update(willSent) + llTotalContainer.tvWillBeSentValue.update(willSent) } ReceiptLayoutType.TOKEN_CRYPTO -> { val receipt = state.tokenCrypto ?: return @@ -312,15 +322,15 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber totalLayout.show(false) totalTokenLayout.show(true) - fg.tvReceiptAmountValue.update("${receipt.amountToken} ${receipt.symbols.token}") - fg.tvReceiptFeeValue.update("${receipt.feeCoin} ${receipt.symbols.crypto}") + tvReceiptAmountValue.update("${receipt.amountToken} ${receipt.symbols.token}") + tvReceiptFeeValue.update("${receipt.feeCoin} ${receipt.symbols.crypto}") val willSent = SpannableStringBuilder() - .bold { - append(roughOrEmpty(receipt.totalFiat)).append(" ") - append(receipt.symbols.fiat) - } - totalTokenLayout.tvTotalTokenCryptoValue.update(willSent.toString()) + .bold { + append(roughOrEmpty(receipt.totalFiat)).append(" ") + append(receipt.symbols.fiat) + } + llTotalContainer.tvTotalTokenCryptoValue.update(willSent.toString()) } } } diff --git a/app/src/main/java/com/tangem/tap/features/shop/ui/ShopFragment.kt b/app/src/main/java/com/tangem/tap/features/shop/ui/ShopFragment.kt index 27a20c0842..a360c1700c 100644 --- a/app/src/main/java/com/tangem/tap/features/shop/ui/ShopFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/shop/ui/ShopFragment.kt @@ -9,6 +9,7 @@ import android.view.View.OnFocusChangeListener import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputMethodManager import androidx.activity.OnBackPressedCallback +import by.kirich1409.viewbindingdelegate.viewBinding import com.tangem.tap.common.KeyboardObserver import com.tangem.tap.common.extensions.show import com.tangem.tap.common.redux.navigation.NavigationAction @@ -18,12 +19,13 @@ import com.tangem.tap.features.shop.redux.ShopAction import com.tangem.tap.features.shop.redux.ShopState import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_shop.* +import com.tangem.wallet.databinding.FragmentShopBinding import org.rekotlin.StoreSubscriber class ShopFragment : BaseStoreFragment(R.layout.fragment_shop), StoreSubscriber { + private val binding: FragmentShopBinding by viewBinding(FragmentShopBinding::bind) override fun subscribeToStore() { store.subscribe(this) { state -> @@ -51,41 +53,41 @@ class ShopFragment : BaseStoreFragment(R.layout.fragment_shop), StoreSubscriber< setupProductSelection() setupPromoCodeEditText() - toolbar.setNavigationOnClickListener { + binding.toolbar.setNavigationOnClickListener { requireActivity().onBackPressed() } val keyboardObserver = KeyboardObserver(requireActivity()) keyboardObserver.registerListener { isVisible -> - fl_cards.show(!isVisible) + binding.flCards.show(!isVisible) } } private fun setupCardsImages() { - imv_second.animate() + binding.imvSecond.animate() .translationY(70f) .scaleX(0.9f) .scaleY(0.9f) .start() - imv_third.animate() + binding.imvThird.animate() .translationY(140f) .scaleX(0.8f) .scaleY(0.8f) .start() } - private fun setupProductSelection() { - chip_product_1.setOnCheckedChangeListener { _, isChecked -> + private fun setupProductSelection() = with(binding) { + chipProduct1.setOnCheckedChangeListener { _, isChecked -> if (isChecked) store.dispatch(ShopAction.SelectProduct(ProductType.WALLET_3_CARDS)) } - chip_product_2.setOnCheckedChangeListener { _, isChecked -> + chipProduct2.setOnCheckedChangeListener { _, isChecked -> if (isChecked) store.dispatch(ShopAction.SelectProduct(ProductType.WALLET_2_CARDS)) } } - private fun setupPromoCodeEditText() { - et_promo_code.setOnEditorActionListener { view, actionId, event -> + private fun setupPromoCodeEditText() = with(binding) { + etPromoCode.setOnEditorActionListener { view, actionId, event -> if (actionId == EditorInfo.IME_ACTION_DONE) { val imm: InputMethodManager = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager @@ -96,15 +98,15 @@ class ShopFragment : BaseStoreFragment(R.layout.fragment_shop), StoreSubscriber< return@setOnEditorActionListener false } - et_promo_code.onFocusChangeListener = OnFocusChangeListener { _, hasFocus -> + etPromoCode.onFocusChangeListener = OnFocusChangeListener { _, hasFocus -> if (!hasFocus) { - store.dispatch(ShopAction.ApplyPromoCode(et_promo_code.text.toString())) + store.dispatch(ShopAction.ApplyPromoCode(etPromoCode.text.toString())) } } } override fun newState(state: ShopState) { - if (activity == null) return + if (activity == null || view == null) return animateProductSelection(state.selectedProduct) handlePriceState(state) @@ -120,43 +122,43 @@ class ShopFragment : BaseStoreFragment(R.layout.fragment_shop), StoreSubscriber< showOrHideThirdCardWithAnimation(show) } - private fun showOrHideThirdCardWithAnimation(show: Boolean) { + private fun showOrHideThirdCardWithAnimation(show: Boolean) = with(binding) { val translationY = if (show) 140f else 0f - if (show) imv_third.show() - imv_third.animate() + if (show) imvThird.show() + imvThird.animate() .translationY(translationY) .setListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { super.onAnimationEnd(animation) - imv_third?.show(show) + imvThird?.show(show) } }) } - private fun handlePriceState(state: ShopState) { - tv_total.text = state.total - tv_total_before_discount.text = state.priceBeforeDiscount + private fun handlePriceState(state: ShopState) = with(binding) { + tvTotal.text = state.total + tvTotalBeforeDiscount.text = state.priceBeforeDiscount - pb_price.show(state.total == null) + pbPrice.show(state.total == null) } - private fun handlePromoCodeState(state: ShopState) { - if (state.promoCode == null && !et_promo_code.hasFocus()) { - et_promo_code.setText("") + private fun handlePromoCodeState(state: ShopState) = with(binding) { + if (state.promoCode == null && !etPromoCode.hasFocus()) { + etPromoCode.setText("") } - pb_promo_code.show(state.promoCodeLoading) + pbPromoCode.show(state.promoCodeLoading) } - private fun handleButtonsState(state: ShopState) { - btn_pay_google_pay.show(state.isGooglePayAvailable) - btn_alternative_payment.show(state.isGooglePayAvailable) - btn_main_action.show(!state.isGooglePayAvailable) + private fun handleButtonsState(state: ShopState) = with(binding) { + btnPayGooglePay.root.show(state.isGooglePayAvailable) + btnAlternativePayment.show(state.isGooglePayAvailable) + btnMainAction.show(!state.isGooglePayAvailable) if (state.total != null) { - btn_alternative_payment.setOnClickListener { store.dispatch(ShopAction.StartWebCheckout) } - btn_main_action.setOnClickListener { store.dispatch(ShopAction.StartWebCheckout) } - btn_pay_google_pay.setOnClickListener { store.dispatch(ShopAction.BuyWithGooglePay) } + btnAlternativePayment.setOnClickListener { store.dispatch(ShopAction.StartWebCheckout) } + btnMainAction.setOnClickListener { store.dispatch(ShopAction.StartWebCheckout) } + btnPayGooglePay.root.setOnClickListener { store.dispatch(ShopAction.BuyWithGooglePay) } } } diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/AddTokensFragment.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/AddTokensFragment.kt index 6a2559848e..fd7caf6b08 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/ui/AddTokensFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/AddTokensFragment.kt @@ -11,6 +11,7 @@ import androidx.appcompat.widget.SearchView import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.transition.TransitionInflater +import by.kirich1409.viewbindingdelegate.viewBinding import com.tangem.tap.common.extensions.getString import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.features.tokens.redux.TokensAction @@ -19,7 +20,7 @@ import com.tangem.tap.features.tokens.ui.adapters.CurrenciesAdapter import com.tangem.tap.mainScope import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_add_tokens.* +import com.tangem.wallet.databinding.FragmentAddTokensBinding import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.* import org.rekotlin.StoreSubscriber @@ -29,6 +30,7 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens), StoreSubscriber { private lateinit var viewAdapter: CurrenciesAdapter + private val binding: FragmentAddTokensBinding by viewBinding(FragmentAddTokensBinding::bind) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -57,29 +59,29 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens), store.unsubscribe(this) } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + override fun onViewCreated(view: View, savedInstanceState: Bundle?) = with(binding) { super.onViewCreated(view, savedInstanceState) (activity as? AppCompatActivity)?.setSupportActionBar(toolbar) toolbar.setNavigationOnClickListener { activity?.onBackPressed() } setupPopularTokensRecyclerView() - btn_tokens_save_changes.setOnClickListener { + btnTokensSaveChanges.setOnClickListener { store.dispatch(TokensAction.SaveChanges(viewAdapter.getAddedItems())) } } - private fun setupPopularTokensRecyclerView() { + private fun setupPopularTokensRecyclerView() = with(binding) { viewAdapter = CurrenciesAdapter() viewAdapter.setOnItemAddListener { - btn_tokens_save_changes.isEnabled = viewAdapter.getAddedItems().isNotEmpty() + btnTokensSaveChanges.isEnabled = viewAdapter.getAddedItems().isNotEmpty() } - rv_popular_tokens.layoutManager = LinearLayoutManager(context) - rv_popular_tokens.adapter = viewAdapter + rvPopularTokens.layoutManager = LinearLayoutManager(context) + rvPopularTokens.adapter = viewAdapter } override fun newState(state: TokensState) { - if (activity == null) return + if (activity == null || view == null) return viewAdapter.addedCurrencies = state.addedCurrencies viewAdapter.submitUnfilteredList(state.shownCurrencies) diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/adapters/CurrenciesAdapter.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/adapters/CurrenciesAdapter.kt index bc2b3177ae..f62908d09d 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/ui/adapters/CurrenciesAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/adapters/CurrenciesAdapter.kt @@ -1,7 +1,6 @@ package com.tangem.tap.features.tokens.ui.adapters import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter @@ -19,8 +18,8 @@ import com.tangem.tap.features.tokens.redux.CurrencyListItem import com.tangem.tap.features.tokens.redux.TokensAction import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.item_currency_subtitle.view.* -import kotlinx.android.synthetic.main.item_popular_token.view.* +import com.tangem.wallet.databinding.ItemCurrencySubtitleBinding +import com.tangem.wallet.databinding.ItemPopularTokenBinding import java.util.* class CurrenciesAdapter : ListAdapter(DiffUtilCallback) { @@ -61,18 +60,18 @@ class CurrenciesAdapter : ListAdapter override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { 0 -> TitleViewHolder( - LayoutInflater.from(parent.context) - .inflate(R.layout.item_currency_subtitle, parent, false) + binding = ItemCurrencySubtitleBinding + .inflate(LayoutInflater.from(parent.context), parent, false) ) 1 -> CurrenciesViewHolder( - LayoutInflater.from(parent.context) - .inflate(R.layout.item_popular_token, parent, false), - vhOnItemAddListener + binding = ItemPopularTokenBinding + .inflate(LayoutInflater.from(parent.context), parent, false), + onItemAddListener = vhOnItemAddListener ) else -> CurrenciesViewHolder( - LayoutInflater.from(parent.context) - .inflate(R.layout.item_popular_token, parent, false), - vhOnItemAddListener + binding = ItemPopularTokenBinding + .inflate(LayoutInflater.from(parent.context), parent, false), + onItemAddListener = vhOnItemAddListener ) } } @@ -108,15 +107,15 @@ class CurrenciesAdapter : ListAdapter is CurrencyListItem.BlockchainListItem -> { element.blockchain.currency.toLowerCase(Locale.US) .contains(queryNormalized) || - element.blockchain.fullName.toLowerCase(Locale.US) - .contains(queryNormalized) + element.blockchain.fullName.toLowerCase(Locale.US) + .contains(queryNormalized) } is CurrencyListItem.TokenListItem -> { element.token.name.toLowerCase(Locale.US) .contains(queryNormalized) || - element.token.symbol.toLowerCase(Locale.US) - .contains(queryNormalized) + element.token.symbol.toLowerCase(Locale.US) + .contains(queryNormalized) } is CurrencyListItem.TitleListItem -> true } @@ -128,9 +127,9 @@ class CurrenciesAdapter : ListAdapter } class CurrenciesViewHolder( - private val view: View, + private val binding: ItemPopularTokenBinding, private val onItemAddListener: ((CurrencyListItem) -> Unit), - ) : RecyclerView.ViewHolder(view) { + ) : RecyclerView.ViewHolder(binding.root) { fun bind( currency: CurrencyListItem, @@ -140,12 +139,14 @@ class CurrenciesAdapter : ListAdapter when (currency) { is CurrencyListItem.BlockchainListItem -> { val addedBlockchains = addedCurrencies?.blockchains ?: listOf() - val currentlyAdded = currentlyAddedItems.filterIsInstance() + val currentlyAdded = + currentlyAddedItems.filterIsInstance() bindBlockchain(currency, addedBlockchains, currentlyAdded) } is CurrencyListItem.TokenListItem -> { val addedTokens = addedCurrencies?.tokens ?: listOf() - val currentlyAdded = currentlyAddedItems.filterIsInstance() + val currentlyAdded = + currentlyAddedItems.filterIsInstance() bindToken(currency, addedTokens, currentlyAdded) } } @@ -155,13 +156,13 @@ class CurrenciesAdapter : ListAdapter currency: CurrencyListItem.BlockchainListItem, addedBlockchains: List, currentlyAdded: List - ) { + ) = with(binding) { val blockchain = currency.blockchain - Picasso.get().loadCurrenciesIcon(view.iv_currency, view.tv_token_letter, null, blockchain) + Picasso.get().loadCurrenciesIcon(ivCurrency, tvTokenLetter, null, blockchain) - view.tv_currency_name.text = blockchain.fullName - view.tv_currency_symbol.text = blockchain.currency - view.btn_add_token.setOnClickListener { + tvCurrencyName.text = blockchain.fullName + tvCurrencySymbol.text = blockchain.currency + btnAddToken.setOnClickListener { onItemAddListener.invoke(currency) currency.isAdded = true modifyAddTokenButton(currency) @@ -177,16 +178,17 @@ class CurrenciesAdapter : ListAdapter currency: CurrencyListItem.TokenListItem, addedTokens: List, currentlyAdded: List - ) { + ) = with(binding) { val token = currency.token - Picasso.get().loadCurrenciesIcon(view.iv_currency, view.tv_token_letter, token, token.blockchain) + Picasso.get() + .loadCurrenciesIcon(ivCurrency, tvTokenLetter, token, token.blockchain) - view.tv_currency_name.text = token.name - view.tv_currency_symbol.text = view.context.getString( + tvCurrencyName.text = token.name + tvCurrencySymbol.text = tvCurrencySymbol.getString( R.string.token_symbol_address_format, token.symbol, token.contractAddress ) - view.btn_add_token.setOnClickListener { + btnAddToken.setOnClickListener { onItemAddListener.invoke(currency) currency.isAdded = true modifyAddTokenButton(currency) @@ -199,48 +201,51 @@ class CurrenciesAdapter : ListAdapter modifyAddTokenButton(currency) } - private fun modifyAddTokenButton(currency: CurrencyListItem) { + private fun modifyAddTokenButton(currency: CurrencyListItem) = with(binding) { if (currency.isLocked) { - view.btn_add_token.setText(R.string.common_add) - view.btn_add_token.isEnabled = false + btnAddToken.setText(R.string.common_add) + btnAddToken.isEnabled = false } else { val text = if (currency.isAdded) R.string.add_token_added else R.string.common_add - view.btn_add_token.setText(text) - view.btn_add_token.isEnabled = !currency.isAdded + btnAddToken.setText(text) + btnAddToken.isEnabled = !currency.isAdded } } } - class TitleViewHolder(val view: View) : - RecyclerView.ViewHolder(view) { - fun bind(title: CurrencyListItem.TitleListItem) { - view.tv_subtitle.text = view.getString(title.titleResId).uppercase() + class TitleViewHolder(val binding: ItemCurrencySubtitleBinding) : + RecyclerView.ViewHolder(binding.root) { + + fun bind(title: CurrencyListItem.TitleListItem) = with(binding) { + tvSubtitle.text = tvSubtitle.getString(title.titleResId).uppercase() if (title.blockchain != null) { - view.cl_subtitle_container.setOnClickListener { + clSubtitleContainer.setOnClickListener { val rotation = if (title.isContentShown) -90f else 90f - store.dispatch(TokensAction.ToggleShowTokensForBlockchain( - title.isContentShown, title.blockchain - )) - view.iv_toggle_sublist_visibility.animate().rotation(rotation).withEndAction { - showArrow(view, title.isContentShown) + store.dispatch( + TokensAction.ToggleShowTokensForBlockchain( + title.isContentShown, title.blockchain + ) + ) + ivToggleSublistVisibility.animate().rotation(rotation).withEndAction { + showArrow(title.isContentShown) } } - showArrow(view, title.isContentShown) + showArrow(title.isContentShown) } else { - view.iv_toggle_sublist_visibility.hide() + ivToggleSublistVisibility.hide() } } - private fun showArrow(view: View, isContentShown: Boolean) { - view.iv_toggle_sublist_visibility.show() + private fun showArrow(isContentShown: Boolean) = with(binding) { + ivToggleSublistVisibility.show() val drawable = if (isContentShown) { R.drawable.ic_arrow_angle_down } else { R.drawable.ic_arrow_angle_right } - view.iv_toggle_sublist_visibility.setImageResource(drawable) - view.iv_toggle_sublist_visibility.rotation = 0f + ivToggleSublistVisibility.setImageResource(drawable) + ivToggleSublistVisibility.rotation = 0f } } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt index 2992b2d543..42527e8528 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt @@ -1,13 +1,10 @@ package com.tangem.tap.features.wallet.ui import androidx.annotation.IdRes -import androidx.fragment.app.Fragment import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show import com.tangem.wallet.R -import kotlinx.android.synthetic.main.card_balance.* -import kotlinx.android.synthetic.main.layout_balance.* -import kotlinx.android.synthetic.main.layout_balance_error.* +import com.tangem.wallet.databinding.CardBalanceBinding import java.math.BigDecimal enum class BalanceStatus { @@ -34,30 +31,34 @@ data class BalanceWidgetData( ) data class TokenData( - val amount: String, - val tokenSymbol: String, - val fiatAmount: String? = null, - val fiatRateString: String? = null, - val fiatRate: BigDecimal? = null, + val amount: String, + val tokenSymbol: String, + val fiatAmount: String? = null, + val fiatRateString: String? = null, + val fiatRate: BigDecimal? = null, ) class BalanceWidget( - val fragment: Fragment, - val data: BalanceWidgetData, - private val isTwinCard: Boolean, + private val binding: CardBalanceBinding, + private val fragment: WalletFragment, + private val data: BalanceWidgetData, + private val isTwinCard: Boolean, ) { fun setup() { when (data.status) { BalanceStatus.Loading -> { - fragment.l_balance.show() - fragment.l_balance_error.hide() - fragment.tv_fiat_amount.hide() + with(binding) { + lBalance.root.show() + lBalanceError.root.hide() + lBalance.tvFiatAmount.hide() + + lBalance.tvCurrency.text = data.currency + lBalance.tvAmount.text = "" + } - fragment.tv_currency.text = data.currency - fragment.tv_amount.text = "" showStatus(R.id.tv_status_loading) @@ -67,18 +68,18 @@ class BalanceWidget( showBalanceWithoutToken(data, false) } } - BalanceStatus.VerifiedOnline, BalanceStatus.TransactionInProgress -> { - fragment.l_balance.show() - fragment.l_balance_error.hide() + BalanceStatus.VerifiedOnline, BalanceStatus.TransactionInProgress -> with(binding.lBalance) { + root.show() + binding.lBalanceError.root.hide() val statusView = if (data.status == BalanceStatus.VerifiedOnline) { R.id.tv_status_verified } else { - fragment.tv_status_error.text = - fragment.getText(R.string.wallet_balance_tx_in_progress) + tvStatusError.text = + fragment.getText(R.string.wallet_balance_tx_in_progress) R.id.group_error } showStatus(statusView) - fragment.tv_status_error_message.hide() + tvStatusErrorMessage.hide() if (data.token != null) { showBalanceWithToken(data, true) @@ -86,79 +87,83 @@ class BalanceWidget( showBalanceWithoutToken(data, true) } } - BalanceStatus.Unreachable -> { - fragment.l_balance.show() - fragment.l_balance_error.hide() - fragment.tv_fiat_amount.hide() - fragment.group_base_currency.hide() + BalanceStatus.Unreachable -> with(binding.lBalance) { + root.show() + binding.lBalanceError.root.hide() + tvFiatAmount.hide() + groupBaseCurrency.hide() val currency = if (data.token != null) data.token.tokenSymbol else data.currency - fragment.tv_currency.text = currency - fragment.tv_amount.text = "" + tvCurrency.text = currency + tvAmount.text = "" - fragment.tv_status_error_message.text = data.errorMessage - fragment.tv_status_error.text = - fragment.getString(R.string.wallet_balance_blockchain_unreachable) + tvStatusErrorMessage.text = data.errorMessage + tvStatusError.text = + fragment.getString(R.string.wallet_balance_blockchain_unreachable) showStatus(R.id.group_error) - fragment.tv_status_error_message.show(!data.errorMessage.isNullOrBlank()) + tvStatusErrorMessage.show(!data.errorMessage.isNullOrBlank()) } - BalanceStatus.EmptyCard -> { - fragment.l_balance.hide() - fragment.l_balance_error.show() + BalanceStatus.EmptyCard -> with(binding.lBalanceError) { + binding.lBalance.root.hide() + binding.lBalanceError.root.show() if (isTwinCard) { - fragment.tv_error_title.text = fragment.getText(R.string.wallet_error_empty_twin_card) - fragment.tv_error_descriptions.text = fragment.getText(R.string.wallet_error_empty_twin_card_subtitle) + tvErrorTitle.text = fragment.getText(R.string.wallet_error_empty_twin_card) + tvErrorDescriptions.text = + fragment.getText(R.string.wallet_error_empty_twin_card_subtitle) } else { - fragment.tv_error_title.text = fragment.getText(R.string.wallet_error_empty_card) - fragment.tv_error_descriptions.text = fragment.getText(R.string.wallet_error_empty_card_subtitle) + tvErrorTitle.text = fragment.getText(R.string.wallet_error_empty_card) + tvErrorDescriptions.text = + fragment.getText(R.string.wallet_error_empty_card_subtitle) } } - BalanceStatus.NoAccount -> { - fragment.l_balance.hide() - fragment.l_balance_error.show() - fragment.tv_error_title.text = fragment.getText(R.string.wallet_error_no_account) - fragment.tv_error_descriptions.text = - fragment.getString( - R.string.wallet_error_no_account_subtitle_format, - data.amountToCreateAccount, data.currencySymbol - ) + BalanceStatus.NoAccount -> with(binding.lBalanceError) { + binding.lBalance.root.hide() + binding.lBalanceError.root.show() + tvErrorTitle.text = fragment.getText(R.string.wallet_error_no_account) + tvErrorDescriptions.text = + fragment.getString( + R.string.wallet_error_no_account_subtitle_format, + data.amountToCreateAccount, data.currencySymbol + ) } - BalanceStatus.UnknownBlockchain -> { - fragment.l_balance.hide() - fragment.l_balance_error.show() - fragment.tv_error_title.text = fragment.getText(R.string.wallet_error_unsupported_blockchain) - fragment.tv_error_descriptions.text = - fragment.getString(R.string.wallet_error_unsupported_blockchain_subtitle) + BalanceStatus.UnknownBlockchain -> with(binding.lBalanceError) { + binding.lBalance.root.hide() + binding.lBalanceError.root.show() + tvErrorTitle.text = + fragment.getText(R.string.wallet_error_unsupported_blockchain) + tvErrorDescriptions.text = + fragment.getString(R.string.wallet_error_unsupported_blockchain_subtitle) } } } - private fun showStatus(@IdRes viewRes: Int) { - fragment.group_error.show(viewRes == R.id.group_error) - fragment.tv_status_loading.show(viewRes == R.id.tv_status_loading) - fragment.tv_status_verified.show(viewRes == R.id.tv_status_verified) + private fun showStatus(@IdRes viewRes: Int) = with(binding.lBalance) { + groupError.show(viewRes == R.id.group_error) + tvStatusLoading.show(viewRes == R.id.tv_status_loading) + tvStatusVerified.show(viewRes == R.id.tv_status_verified) } - private fun showBalanceWithToken(data: BalanceWidgetData, showAmount: Boolean) { - fragment.group_base_currency.show() - fragment.tv_currency.text = data.token?.tokenSymbol - fragment.tv_base_currency.text = data.currency - fragment.tv_amount.text = if (showAmount) data.token?.amount else "" - fragment.tv_base_amount.text = if (showAmount) data.amount else "" + private fun showBalanceWithToken(data: BalanceWidgetData, showAmount: Boolean) = with(binding.lBalance) { + groupBaseCurrency.show() + tvCurrency.text = data.token?.tokenSymbol + tvBaseCurrency.text = data.currency + tvAmount.text = if (showAmount) data.token?.amount else "" + tvBaseAmount.text = if (showAmount) data.amount else "" if (showAmount) { - fragment.tv_fiat_amount.show() - fragment.tv_fiat_amount.text = data.token?.fiatAmount + tvFiatAmount.show() + tvFiatAmount.text = data.token?.fiatAmount } } - private fun showBalanceWithoutToken(data: BalanceWidgetData, showAmount: Boolean) { - fragment.group_base_currency.hide() - fragment.tv_currency.text = data.currency - fragment.tv_amount.text = if (showAmount) data.amount else "" - if (showAmount) { - fragment.tv_fiat_amount.show() - fragment.tv_fiat_amount.text = data.fiatAmountFormatted + private fun showBalanceWithoutToken(data: BalanceWidgetData, showAmount: Boolean) = + with(binding.lBalance) { + groupBaseCurrency.hide() + tvCurrency.text = data.currency + tvAmount.text = if (showAmount) data.amount else "" + if (showAmount) { + tvFiatAmount.show() + tvFiatAmount.text = data.fiatAmountFormatted + } } - } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index f1d99a3053..936a4d0321 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -9,6 +9,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.transition.TransitionInflater +import by.kirich1409.viewbindingdelegate.viewBinding import com.squareup.picasso.Picasso import com.tangem.common.extensions.guard import com.tangem.tap.common.SnackbarHandler @@ -22,19 +23,17 @@ import com.tangem.tap.features.wallet.ui.adapters.PendingTransactionsAdapter import com.tangem.tap.features.wallet.ui.dialogs.AmountToSendDialog import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_wallet_details.* -import kotlinx.android.synthetic.main.layout_balance_error.* -import kotlinx.android.synthetic.main.layout_balance_wallet_details.* -import kotlinx.android.synthetic.main.layout_wallet_details.* -import kotlinx.android.synthetic.main.layout_wallet_details.card_balance -import kotlinx.android.synthetic.main.layout_wallet_details_rent.* +import com.tangem.wallet.databinding.FragmentWalletDetailsBinding import org.rekotlin.StoreSubscriber -class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreSubscriber { +class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), + StoreSubscriber { private lateinit var pendingTransactionAdapter: PendingTransactionsAdapter private var dialog: Dialog? = null + private val binding: FragmentWalletDetailsBinding by viewBinding(FragmentWalletDetailsBinding::bind) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) @@ -65,8 +64,8 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - (activity as? AppCompatActivity)?.setSupportActionBar(toolbar) - toolbar.setNavigationOnClickListener { activity?.onBackPressed() } + (activity as? AppCompatActivity)?.setSupportActionBar(binding.toolbar) + binding.toolbar.setNavigationOnClickListener { activity?.onBackPressed() } setupTransactionsRecyclerView() @@ -74,91 +73,98 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS } - private fun setupTransactionsRecyclerView() { + private fun setupTransactionsRecyclerView() = with(binding) { pendingTransactionAdapter = PendingTransactionsAdapter() - rv_pending_transaction.layoutManager = LinearLayoutManager(requireContext()) - rv_pending_transaction.adapter = pendingTransactionAdapter + rvPendingTransaction.layoutManager = LinearLayoutManager(requireContext()) + rvPendingTransaction.adapter = pendingTransactionAdapter } - private fun setupButtons() { - btn_confirm.text = getString(R.string.wallet_button_send) - btn_confirm.setOnClickListener { store.dispatch(WalletAction.Send()) } + private fun setupButtons() = with(binding) { + btnConfirm.text = getString(R.string.wallet_button_send) + btnConfirm.setOnClickListener { store.dispatch(WalletAction.Send()) } - btn_share.setOnClickListener { store.dispatch(WalletAction.ShowDialog.QrCode) } + binding.lWalletDetails.btnShare.setOnClickListener { store.dispatch(WalletAction.ShowDialog.QrCode) } - btn_trade.setOnClickListener { store.dispatch(WalletAction.TradeCryptoAction.Buy) } + btnTrade.setOnClickListener { store.dispatch(WalletAction.TradeCryptoAction.Buy) } - btn_sell.setOnClickListener { store.dispatch(WalletAction.TradeCryptoAction.Sell) } + btnSell.setOnClickListener { store.dispatch(WalletAction.TradeCryptoAction.Sell) } } override fun newState(state: WalletState) { - if (activity == null) return + if (activity == null || view == null) return if (state.selectedWallet == null) return val selectedWallet = state.getSelectedWalletData() ?: return - tv_currency_title.text = selectedWallet.currencyData.currency - val currency = selectedWallet.currency - if (currency is Currency.Token) { - tv_currency_subtitle.text = currency.blockchain.tokenDisplayName() - tv_currency_subtitle.show() - } else { - tv_currency_subtitle.hide() - } - showPendingTransactionsIfPresent(selectedWallet.pendingTransactions) + setupCurrency(selectedWallet.currencyData, selectedWallet.currency) setupAddressCard(selectedWallet) setupNoInternetHandling(state) setupBalanceData(selectedWallet.currencyData) - - btn_confirm.isEnabled = selectedWallet.mainButton.enabled - btn_copy.setOnClickListener { - selectedWallet.walletAddresses?.selectedAddress?.address?.let { addressString -> - store.dispatch(WalletAction.CopyAddress(addressString, requireContext())) - } - } - btn_share.setOnClickListener { - selectedWallet.walletAddresses?.selectedAddress?.address?.let { addressString -> - store.dispatch(WalletAction.ShareAddress(addressString, requireContext())) - } - } + setupButtons(selectedWallet) handleDialogs(state.walletDialog) handleCurrencyIcon(selectedWallet) handleWalletRent(selectedWallet.walletRent) - srl_wallet_details.setOnRefreshListener { + + binding.srlWalletDetails.setOnRefreshListener { if (selectedWallet.currencyData.status != BalanceStatus.Loading) { - store.dispatch(WalletAction.LoadWallet( - blockchain = selectedWallet.currency.blockchain - )) + store.dispatch( + WalletAction.LoadWallet( + blockchain = selectedWallet.currency.blockchain + ) + ) } } if (selectedWallet.currencyData.status != BalanceStatus.Loading) { - srl_wallet_details.isRefreshing = false + binding.srlWalletDetails.isRefreshing = false } - - btn_trade.isEnabled = selectedWallet.tradeCryptoState.buyingAllowed - btn_sell.show(selectedWallet.tradeCryptoState.sellingAllowed) } - private fun handleWalletRent(rent: WalletRent?) { + private fun setupCurrency(currencyData: BalanceWidgetData, currency: Currency) = with(binding) { + tvCurrencyTitle.text = currencyData.currency + if (currency is Currency.Token) { + binding.tvCurrencySubtitle.text = currency.blockchain.tokenDisplayName() + binding.tvCurrencySubtitle.show() + } else { + binding.tvCurrencySubtitle.hide() + } + } + + private fun setupButtons(selectedWallet: WalletData) = with(binding) { + btnConfirm.isEnabled = selectedWallet.mainButton.enabled + lWalletDetails.btnCopy.setOnClickListener { + selectedWallet.walletAddresses?.selectedAddress?.address?.let { addressString -> + store.dispatch(WalletAction.CopyAddress(addressString, requireContext())) + } + } + lWalletDetails.btnShare.setOnClickListener { + selectedWallet.walletAddresses?.selectedAddress?.address?.let { addressString -> + store.dispatch(WalletAction.ShareAddress(addressString, requireContext())) + } + } + btnTrade.isEnabled = selectedWallet.tradeCryptoState.buyingAllowed + btnSell.show(selectedWallet.tradeCryptoState.sellingAllowed) + } + + private fun handleWalletRent(rent: WalletRent?) = with(binding) { val rent = rent.guard { - l_rent_warning.hide() + lRentWarning.root.hide() return } - val warningMessage = requireContext().getString( - R.string.solana_rent_warning, rent.minRentValue, rent.rentExemptValue) - tv_rent_warning_message.text = warningMessage - l_rent_warning.show() + R.string.solana_rent_warning, rent.minRentValue, rent.rentExemptValue + ) + lRentWarning.tvRentWarningMessage.text = warningMessage + lRentWarning.root.show() } - private fun handleCurrencyIcon(wallet: WalletData) { + private fun handleCurrencyIcon(wallet: WalletData) = with(binding.lWalletDetails.lBalance) { Picasso.get().loadCurrenciesIcon( - imageView = iv_currency, - textView = tv_token_letter, + imageView = ivCurrency, + textView = tvTokenLetter, blockchain = wallet.currency.blockchain, token = (wallet.currency as? Currency.Token)?.token ) @@ -167,42 +173,48 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS private fun showPendingTransactionsIfPresent(pendingTransactions: List) { pendingTransactionAdapter.submitList(pendingTransactions) - rv_pending_transaction?.show(pendingTransactions.isNotEmpty()) + binding.rvPendingTransaction?.show(pendingTransactions.isNotEmpty()) } - private fun setupAddressCard(state: WalletData) { + private fun setupAddressCard(state: WalletData) = with(binding.lWalletDetails) { if (state.walletAddresses != null) { if (state.shouldShowMultipleAddress() && state.currency is Currency.Blockchain) { - (card_balance as? ViewGroup)?.beginDelayedTransition() - chip_group_address_type.show() - chip_group_address_type.fitChipsByGroupWidth() + (cardBalance as? ViewGroup)?.beginDelayedTransition() + chipGroupAddressType.show() + chipGroupAddressType.fitChipsByGroupWidth() - val checkedId = MultipleAddressUiHelper.typeToId(state.walletAddresses.selectedAddress.type) - if (checkedId != View.NO_ID) chip_group_address_type.check(checkedId) + val checkedId = + MultipleAddressUiHelper.typeToId(state.walletAddresses.selectedAddress.type) + if (checkedId != View.NO_ID) chipGroupAddressType.check(checkedId) - chip_group_address_type.setOnCheckedChangeListener { group, checkedId -> + chipGroupAddressType.setOnCheckedChangeListener { group, checkedId -> if (checkedId == -1) return@setOnCheckedChangeListener - val type = MultipleAddressUiHelper.idToType(checkedId, state.currency.blockchain) + val type = + MultipleAddressUiHelper.idToType(checkedId, state.currency.blockchain) type?.let { store.dispatch(WalletAction.ChangeSelectedAddress(type)) } } } else { - chip_group_address_type.hide() + chipGroupAddressType.hide() } - tv_address.text = state.walletAddresses.selectedAddress.address - tv_explore?.setOnClickListener { - store.dispatch(WalletAction.ExploreAddress( - state.walletAddresses.selectedAddress.exploreUrl, - requireContext())) + tvAddress.text = state.walletAddresses.selectedAddress.address + tvExplore?.setOnClickListener { + store.dispatch( + WalletAction.ExploreAddress( + state.walletAddresses.selectedAddress.exploreUrl, + requireContext() + ) + ) } - iv_qr_code.setImageBitmap(state.walletAddresses.selectedAddress.shareUrl.toQrCode()) - tv_receive_message.text = getQRReceiveMessage(tv_receive_message.context, state.currency) + ivQrCode.setImageBitmap(state.walletAddresses.selectedAddress.shareUrl.toQrCode()) + tvReceiveMessage.text = + getQRReceiveMessage(tvReceiveMessage.context, state.currency) } } private fun setupNoInternetHandling(state: WalletState) { if (state.state == ProgressState.Error) { if (state.error == ErrorType.NoInternetConnection) { - srl_wallet_details?.isRefreshing = false + binding.srlWalletDetails.isRefreshing = false (activity as? SnackbarHandler)?.showSnackbar( text = R.string.wallet_notification_no_internet, buttonTitle = R.string.common_retry @@ -213,73 +225,77 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS } } - private fun setupBalanceData(data: BalanceWidgetData) { + private fun setupBalanceData(data: BalanceWidgetData) = with(binding.lWalletDetails) { when (data.status) { BalanceStatus.Loading -> { - l_balance.show() - l_balance_error.hide() - tv_fiat_amount.hide() - tv_amount.text = "" - + lBalance.root.show() + lBalanceError.root.hide() + lBalance.tvFiatAmount.hide() + lBalance.tvAmount.text = "" showStatus(R.id.tv_status_loading) showBalanceWithoutToken(data, false) } BalanceStatus.VerifiedOnline, BalanceStatus.SameCurrencyTransactionInProgress, BalanceStatus.TransactionInProgress -> { - l_balance.show() - l_balance_error.hide() + lBalance.root.show() + lBalanceError.root.hide() val statusView = if (data.status == BalanceStatus.VerifiedOnline || - data.status == BalanceStatus.SameCurrencyTransactionInProgress) { + data.status == BalanceStatus.SameCurrencyTransactionInProgress + ) { R.id.tv_status_verified } else { - tv_status_error.text = - getText(R.string.wallet_balance_tx_in_progress) + lBalance.tvStatusError.text = + getText(R.string.wallet_balance_tx_in_progress) R.id.group_error } showStatus(statusView) - tv_status_error_message.hide() + lBalance.tvStatusErrorMessage.hide() showBalanceWithoutToken(data, true) } BalanceStatus.Unreachable -> { - l_balance.show() - l_balance_error.hide() - tv_fiat_amount.hide() + lBalance.root.show() + lBalanceError.root.hide() + lBalance.tvFiatAmount.hide() - tv_amount.text = "" + lBalance.tvAmount.text = "" - tv_status_error_message.text = data.errorMessage - tv_status_error.text = - getString(R.string.wallet_balance_blockchain_unreachable) + lBalance.tvStatusErrorMessage.text = data.errorMessage + lBalance.tvStatusError.text = + getString(R.string.wallet_balance_blockchain_unreachable) showStatus(R.id.group_error) - tv_status_error_message.show(!data.errorMessage.isNullOrBlank()) + lBalance.tvStatusErrorMessage.show(!data.errorMessage.isNullOrBlank()) } BalanceStatus.NoAccount -> { - l_balance.hide() - l_balance_error.show() - tv_error_title.text = getText(R.string.wallet_error_no_account) - tv_error_descriptions.text = - getString( - R.string.wallet_error_no_account_subtitle_format, - data.amountToCreateAccount, data.currencySymbol - ) + lBalance.root.hide() + lBalanceError.root.show() + lBalanceError.tvErrorTitle.text = getText(R.string.wallet_error_no_account) + lBalanceError.tvErrorDescriptions.text = + getString( + R.string.wallet_error_no_account_subtitle_format, + data.amountToCreateAccount, data.currencySymbol + ) } } - card_pending_transaction_warning.show(data.status == BalanceStatus.SameCurrencyTransactionInProgress) + binding.cardPendingTransactionWarning.show(data.status == BalanceStatus.SameCurrencyTransactionInProgress) } private fun showStatus(@IdRes viewRes: Int) { - group_error.show(viewRes == R.id.group_error) - tv_status_loading.show(viewRes == R.id.tv_status_loading) - tv_status_verified.show(viewRes == R.id.tv_status_verified) + with(binding.lWalletDetails.lBalance) { + groupError.show(viewRes == R.id.group_error) + tvStatusLoading.show(viewRes == R.id.tv_status_loading) + tvStatusVerified.show(viewRes == R.id.tv_status_verified) + } } private fun showBalanceWithoutToken(data: BalanceWidgetData, showAmount: Boolean) { - tv_amount.text = if (showAmount) data.amount else "" - if (showAmount) { - tv_fiat_amount.show() - tv_fiat_amount.text = data.fiatAmountFormatted + with(binding.lWalletDetails.lBalance) { + tvAmount.text = if (showAmount) data.amount else "" + if (showAmount) { + tvFiatAmount.show() + tvFiatAmount.text = data.fiatAmountFormatted + } } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index f7978e35d8..9f6a876537 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -11,6 +11,7 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.transition.TransitionInflater +import by.kirich1409.viewbindingdelegate.viewBinding import com.squareup.picasso.Picasso import com.tangem.tangem_sdk_new.extensions.dpToPx import com.tangem.tap.MainActivity @@ -29,9 +30,7 @@ import com.tangem.tap.features.wallet.ui.wallet.SingleWalletView import com.tangem.tap.features.wallet.ui.wallet.WalletView import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.fragment_wallet.* -import kotlinx.android.synthetic.main.fragment_wallet.toolbar -import kotlinx.android.synthetic.main.fragment_wallet_details.* +import com.tangem.wallet.databinding.FragmentWalletBinding import org.rekotlin.StoreSubscriber @@ -39,6 +38,8 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber) { warningsAdapter.submitList(warnings) - rv_warning_messages.show(warnings.isNotEmpty()) + binding.rvWarningMessages.show(warnings.isNotEmpty()) } private fun setupNoInternetHandling(state: WalletState) { if (state.state == ProgressState.Error) { if (state.error == ErrorType.NoInternetConnection) { - srl_wallet_details?.isRefreshing = false + binding.srlWallet.isRefreshing = false (activity as? MainActivity)?.showSnackbar( text = R.string.wallet_notification_no_internet, buttonTitle = R.string.common_retry @@ -152,7 +155,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber(DiffUtilCallback) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionsViewHolder { - val layout = LayoutInflater.from(parent.context) - .inflate(R.layout.item_pending_transaction, parent, false) - return TransactionsViewHolder(layout) + val binding = ItemPendingTransactionBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + return TransactionsViewHolder(binding) } override fun onBindViewHolder(holder: TransactionsViewHolder, position: Int) { @@ -36,13 +37,13 @@ class PendingTransactionsAdapter ) = oldItem == newItem } - class TransactionsViewHolder(val view: View) : - RecyclerView.ViewHolder(view) { + class TransactionsViewHolder(val binding: ItemPendingTransactionBinding) : + RecyclerView.ViewHolder(binding.root) { fun bind(transaction: PendingTransaction) { if (transaction.type == PendingTransactionType.Unknown) { - view.hide() + binding.root.hide() } val transactionDescriptionRes = when (transaction.type) { @@ -60,17 +61,16 @@ class PendingTransactionsAdapter PendingTransactionType.Outgoing -> R.drawable.ic_arrow_right_20 PendingTransactionType.Unknown -> return } - view.tv_pending_transaction.text = view.context.getString(transactionDescriptionRes) + binding.tvPendingTransaction.text = binding.root.getString(transactionDescriptionRes) - transaction.amount?.let { view.tv_pending_transaction_amount.text = "$it " } - view.tv_pending_transaction_currency.text = "${transaction.currency}" + transaction.amount?.let { binding.tvPendingTransactionAmount.text = "$it " } + binding.tvPendingTransactionCurrency.text = "${transaction.currency}" if (transaction.address != null) { - view.tv_pending_transaction_address.text = - view.context.getString(transactionAddressRes, transaction.address) + binding.tvPendingTransactionAddress.text = + binding.root.getString(transactionAddressRes, transaction.address) } - - view.iv_pending_transaction.setImageDrawable(view.context.getDrawableCompat(image)) + binding.ivPendingTransaction.setImageDrawable(binding.root.context.getDrawableCompat(image)) } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt index 4d96d05004..074d4a882b 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt @@ -1,7 +1,6 @@ package com.tangem.tap.features.wallet.ui.adapters import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter @@ -9,6 +8,7 @@ import androidx.recyclerview.widget.RecyclerView import com.squareup.picasso.Picasso import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token +import com.tangem.tap.common.extensions.getString import com.tangem.tap.common.extensions.loadCurrenciesIcon import com.tangem.tap.common.extensions.show import com.tangem.tap.features.wallet.redux.Currency @@ -17,7 +17,7 @@ import com.tangem.tap.features.wallet.redux.WalletData import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.item_currency_wallet.view.* +import com.tangem.wallet.databinding.ItemCurrencyWalletBinding class WalletAdapter : ListAdapter(DiffUtilCallback) { @@ -32,8 +32,9 @@ class WalletAdapter } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WalletsViewHolder { - val layout = LayoutInflater.from(parent.context) - .inflate(R.layout.item_currency_wallet, parent, false) + val layout = ItemCurrencyWalletBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) return WalletsViewHolder(layout) } @@ -51,24 +52,24 @@ class WalletAdapter ) = oldItem == newItem } - class WalletsViewHolder(val view: View) : - RecyclerView.ViewHolder(view) { + class WalletsViewHolder(val binding: ItemCurrencyWalletBinding) : + RecyclerView.ViewHolder(binding.root) { - fun bind(wallet: WalletData) { - view.tv_currency.text = wallet.currencyData.currency - view.tv_amount.text = wallet.currencyData.amount?.takeWhile { !it.isWhitespace() } - view.tv_currency_symbol.text = wallet.currencyData.amount?.takeLastWhile { !it.isWhitespace() } - view.tv_amount_fiat.text = wallet.currencyData.fiatAmountFormatted - view.tv_exchange_rate.text = wallet.fiatRateString - view.card_wallet.setOnClickListener { + fun bind(wallet: WalletData) = with(binding) { + tvCurrency.text = wallet.currencyData.currency + tvAmount.text = wallet.currencyData.amount?.takeWhile { !it.isWhitespace() } + tvCurrencySymbol.text = wallet.currencyData.amount?.takeLastWhile { !it.isWhitespace() } + tvAmountFiat.text = wallet.currencyData.fiatAmountFormatted + tvExchangeRate.text = wallet.fiatRateString + cardWallet.setOnClickListener { store.dispatch(WalletAction.MultiWallet.SelectWallet(wallet)) } val blockchain = wallet.currency.blockchain val token = (wallet.currency as? Currency.Token)?.token Picasso.get().loadCurrenciesIcon( - imageView = view.iv_currency, - textView = view.tv_token_letter, + imageView = ivCurrency, + textView = tvTokenLetter, token = token, blockchain = blockchain, ) @@ -77,16 +78,16 @@ class WalletAdapter BalanceStatus.Loading -> { hideWarning() if (wallet.currencyData.amount == null) { - view.tv_exchange_rate.text = view.context.getText(R.string.wallet_balance_loading) + tvExchangeRate.text = root.getString(R.string.wallet_balance_loading) } } BalanceStatus.TransactionInProgress -> - showWarning(view.context.getString(R.string.wallet_balance_tx_in_progress)) + showWarning(root.getString(R.string.wallet_balance_tx_in_progress)) BalanceStatus.Unreachable -> - showWarning(view.context.getString(R.string.wallet_balance_blockchain_unreachable)) + showWarning(root.getString(R.string.wallet_balance_blockchain_unreachable)) BalanceStatus.NoAccount -> - showWarning(view.context.getString(R.string.wallet_error_no_account)) + showWarning(root.getString(R.string.wallet_error_no_account)) else -> { } } @@ -94,7 +95,7 @@ class WalletAdapter private fun showWarning(message: String) { toggleWarning(true) - view.tv_status_error_message.text = message + binding.tvStatusErrorMessage.text = message } private fun hideWarning() { @@ -102,8 +103,8 @@ class WalletAdapter } private fun toggleWarning(show: Boolean) { - view.tv_exchange_rate.show(!show) - view.tv_status_error_message.show(show) + binding.tvExchangeRate.show(!show) + binding.tvStatusErrorMessage.show(show) } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WarningMessagesAdapter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WarningMessagesAdapter.kt index 22c2d56cf3..afcba036da 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WarningMessagesAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WarningMessagesAdapter.kt @@ -10,25 +10,23 @@ import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.ItemDecoration import com.google.android.play.core.review.ReviewManagerFactory import com.tangem.tap.common.analytics.AnalyticsEvent -import com.tangem.tap.common.extensions.getActivity -import com.tangem.tap.common.extensions.getString -import com.tangem.tap.common.extensions.hide -import com.tangem.tap.common.extensions.show +import com.tangem.tap.common.extensions.* import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.features.feedback.RateCanBeBetterEmail import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.layout_warning.view.* +import com.tangem.wallet.databinding.LayoutWarningBinding import timber.log.Timber class WarningMessagesAdapter : ListAdapter(DiffUtilCallback) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WarningMessageVH { - val inflater = LayoutInflater.from(parent.context) - val layout = inflater.inflate(R.layout.layout_warning, parent, false) - return WarningMessageVH(layout) + val binding = LayoutWarningBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + return WarningMessageVH(binding) } override fun onBindViewHolder(holder: WarningMessageVH, position: Int) { @@ -44,7 +42,7 @@ class WarningMessagesAdapter : ListAdapter(Dif } } -class WarningMessageVH(val view: View) : RecyclerView.ViewHolder(view) { +class WarningMessageVH(val binding: LayoutWarningBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(warning: WarningMessage) { setBgColor(warning.priority) @@ -52,12 +50,12 @@ class WarningMessageVH(val view: View) : RecyclerView.ViewHolder(view) { setupControlButtons(warning) } - private fun setText(warning: WarningMessage) { + private fun setText(warning: WarningMessage) = with(binding) { fun getString(resId: Int?, default: String, formatArgs: String? = null) = - if (resId == null) default else view.context.getString(resId, formatArgs) + if (resId == null) default else root.getString(resId, formatArgs) - view.tv_title.text = getString(warning.titleResId, warning.title) - view.tv_message.text = getString( + tvTitle.text = getString(warning.titleResId, warning.title) + tvMessage.text = getString( resId = warning.messageResId, default = warning.message, formatArgs = warning.messageFormatArg ) } @@ -68,17 +66,17 @@ class WarningMessageVH(val view: View) : RecyclerView.ViewHolder(view) { WarningMessage.Priority.Warning -> R.color.warning_warning WarningMessage.Priority.Critical -> R.color.warning_critical } - view.card_view.setCardBackgroundColor(view.context.resources.getColor(color)) + binding.cardView.setCardBackgroundColor(binding.root.getColor(color)) } private fun setupControlButtons(warning: WarningMessage) = when (warning.type) { WarningMessage.Type.Permanent, WarningMessage.Type.TestCard -> { - view.group_controls_temporary.hide() - view.group_controls_rating.hide() + binding.groupControlsTemporary.hide() + binding.groupControlsRating.hide() } WarningMessage.Type.Temporary -> { - view.group_controls_rating.hide() - view.group_controls_temporary.show() + binding.groupControlsRating.hide() + binding.groupControlsTemporary.show() val buttonAction = when (warning.titleResId) { R.string.warning_important_security_info -> { @@ -92,29 +90,29 @@ class WarningMessageVH(val view: View) : RecyclerView.ViewHolder(view) { } } } - val buttonTitle = view.getString( + val buttonTitle = binding.root.getString( warning.buttonTextId ?: R.string.how_to_got_it_button ) - view.btn_got_it.setOnClickListener (buttonAction) - view.btn_got_it.text = buttonTitle + binding.btnGotIt.setOnClickListener (buttonAction) + binding.btnGotIt.text = buttonTitle } WarningMessage.Type.AppRating -> { - view.group_controls_temporary.hide() - view.group_controls_rating.show() + binding.groupControlsTemporary.hide() + binding.groupControlsRating.show() val analyticsHandler = store.state.globalState.analyticsHandlers - view.btn_close.setOnClickListener { + binding.btnClose.setOnClickListener { analyticsHandler?.triggerEvent(AnalyticsEvent.APP_RATING_DISMISS) store.dispatch(GlobalAction.HideWarningMessage(warning)) store.dispatch(WalletAction.Warnings.AppRating.RemindLater) } - view.btn_can_be_better.setOnClickListener { + binding.btnCanBeBetter.setOnClickListener { analyticsHandler?.triggerEvent(AnalyticsEvent.APP_RATING_NEGATIVE) store.dispatch(WalletAction.Warnings.AppRating.SetNeverToShow) store.dispatch(GlobalAction.HideWarningMessage(warning)) store.dispatch(GlobalAction.SendFeedback(RateCanBeBetterEmail())) } - view.btn_really_cool.setOnClickListener { - val activity = view.context.getActivity() ?: return@setOnClickListener + binding.btnReallyCool.setOnClickListener { + val activity = binding.root.context.getActivity() ?: return@setOnClickListener analyticsHandler?.triggerEvent(AnalyticsEvent.APP_RATING_POSITIVE) store.dispatch(WalletAction.Warnings.AppRating.SetNeverToShow) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/AmountToSendDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/AmountToSendDialog.kt index 0175d55b59..5eea55091b 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/AmountToSendDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/AmountToSendDialog.kt @@ -1,8 +1,9 @@ package com.tangem.tap.features.wallet.ui.dialogs import android.content.Context +import android.content.DialogInterface +import android.os.Bundle import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup import androidx.appcompat.view.ContextThemeWrapper import androidx.recyclerview.widget.* @@ -12,14 +13,22 @@ import com.tangem.tap.common.extensions.toFormattedString import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.dialog_wallet_send.* -import kotlinx.android.synthetic.main.item_wallet_amount_to_send.view.* - +import com.tangem.wallet.databinding.DialogWalletSendBinding +import com.tangem.wallet.databinding.ItemWalletAmountToSendBinding class AmountToSendDialog(context: Context) : BottomSheetDialog(context) { - init { - this.setContentView(R.layout.dialog_wallet_send) + var binding: DialogWalletSendBinding? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = DialogWalletSendBinding.inflate(LayoutInflater.from(context)) + setContentView(binding!!.root) + } + + override fun setOnCancelListener(listener: DialogInterface.OnCancelListener?) { + super.setOnCancelListener(listener) + binding = null } fun show(amounts: List?) { @@ -27,15 +36,15 @@ class AmountToSendDialog(context: Context) : BottomSheetDialog(context) { store.dispatch(WalletAction.Send.Cancel) } - rv_amounts_to_send.layoutManager = LinearLayoutManager(context) + binding!!.rvAmountsToSend.layoutManager = LinearLayoutManager(context) val dividerItemDecoration = DividerItemDecoration( - ContextThemeWrapper(rv_amounts_to_send.context, R.style.AppTheme), + ContextThemeWrapper(binding!!.root.context, R.style.AppTheme), DividerItemDecoration.VERTICAL ) - rv_amounts_to_send.addItemDecoration(dividerItemDecoration) + binding!!.rvAmountsToSend.addItemDecoration(dividerItemDecoration) val viewAdapter = ChooseAmountAdapter() - rv_amounts_to_send.adapter = viewAdapter + binding!!.rvAmountsToSend.adapter = viewAdapter viewAdapter.submitList(amounts) @@ -48,9 +57,10 @@ class ChooseAmountAdapter : ListAdapter(DiffUtilCallback) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AmountViewHolder { - val layout = LayoutInflater.from(parent.context) - .inflate(R.layout.item_wallet_amount_to_send, parent, false) - return AmountViewHolder(layout) + val binding = ItemWalletAmountToSendBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + return AmountViewHolder(binding) } override fun onBindViewHolder(holder: AmountViewHolder, position: Int) { @@ -67,13 +77,13 @@ class ChooseAmountAdapter ) = oldItem == newItem } - class AmountViewHolder(val view: View) : - RecyclerView.ViewHolder(view) { + class AmountViewHolder(val binding: ItemWalletAmountToSendBinding) : + RecyclerView.ViewHolder(binding.root) { - fun bind(amount: Amount) { - view.tv_currency_symbol.text = amount.currencySymbol - view.tv_amount.text = amount.value?.toFormattedString(amount.decimals) - view.setOnClickListener { + fun bind(amount: Amount) = with(binding) { + tvCurrencySymbol.text = amount.currencySymbol + tvAmount.text = amount.value?.toFormattedString(amount.decimals) + root.setOnClickListener { store.dispatch(WalletAction.Send.Cancel) store.dispatch(WalletAction.Send(amount)) } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ChooseTradeActionDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ChooseTradeActionDialog.kt index 95ff1f65ea..93baaf29a3 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ChooseTradeActionDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ChooseTradeActionDialog.kt @@ -1,30 +1,36 @@ package com.tangem.tap.features.wallet.ui.dialogs import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater import com.google.android.material.bottomsheet.BottomSheetDialog import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.store -import com.tangem.wallet.R -import kotlinx.android.synthetic.main.dialog_wallet_trade.* +import com.tangem.wallet.databinding.DialogWalletTradeBinding class ChooseTradeActionDialog(context: Context) : BottomSheetDialog(context) { - init { - this.setContentView(R.layout.dialog_wallet_trade) + var binding: DialogWalletTradeBinding? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = DialogWalletTradeBinding.inflate(LayoutInflater.from(context)) + setContentView(binding!!.root) } override fun show() { super.show() this.setOnDismissListener { + binding = null store.dispatch(WalletAction.HideDialog) } - dialog_btn_buy.setOnClickListener { + binding!!.dialogBtnBuy.setOnClickListener { store.dispatch(WalletAction.TradeCryptoAction.Buy) dismiss() } - dialog_btn_sell.setOnClickListener { + binding!!.dialogBtnSell.setOnClickListener { store.dispatch(WalletAction.TradeCryptoAction.Sell) dismiss() } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt index 8eeef0afdc..7b2e9ba9ec 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt @@ -18,64 +18,64 @@ import com.tangem.tap.features.wallet.ui.adapters.WalletAdapter import com.tangem.tap.features.wallet.ui.dialogs.SignedHashesWarningDialog import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.card_balance.* -import kotlinx.android.synthetic.main.fragment_wallet.* -import kotlinx.android.synthetic.main.layout_balance_error.* -import kotlinx.android.synthetic.main.layout_wallet_long_buttons.* +import com.tangem.wallet.databinding.FragmentWalletBinding class MultiWalletView : WalletView { private var fragment: WalletFragment? = null + private var binding: FragmentWalletBinding? = null private var dialog: Dialog? = null private lateinit var walletsAdapter: WalletAdapter - override fun changeWalletView(fragment: WalletFragment) { - setFragment(fragment) + override fun changeWalletView(fragment: WalletFragment, binding: FragmentWalletBinding) { + setFragment(fragment, binding) onViewCreated() - showMultiWalletView(fragment) - setupButtons(fragment) + showMultiWalletView(binding) + setupButtons(binding) } - private fun showMultiWalletView(fragment: WalletFragment) = with(fragment) { - tv_twin_card_number.hide() - rv_pending_transaction.hide() - l_card_balance.hide() - l_address.hide() - l_buttons_short.hide() - l_buttons_long.hide() - btn_scan_multiwallet?.show() - rv_multiwallet.show() - btn_add_token.show() - setupWalletCardNumber(fragment) + private fun showMultiWalletView(binding: FragmentWalletBinding) = with(binding) { + tvTwinCardNumber.hide() + rvPendingTransaction.hide() + lCardBalance.root.hide() + lAddress.root.hide() + lButtonsShort.root.hide() + lButtonsLong.root.hide() + btnScanMultiwallet.show() + rvMultiwallet.show() + btnAddToken.show() + setupWalletCardNumber(binding) } - private fun setupWalletCardNumber(fragment: WalletFragment) = with(fragment) { + private fun setupWalletCardNumber(binding: FragmentWalletBinding) = with(binding) { val card = store.state.globalState.scanResponse?.card if (card?.backupStatus is Card.BackupStatus.Active) { val cardCount = (card.backupStatus as Card.BackupStatus.Active).cardCount + 1 - tv_twin_card_number.show() - tv_twin_card_number.text = - getString(R.string.wallet_twins_chip_format, 1, cardCount) + tvTwinCardNumber.show() + tvTwinCardNumber.text = + fragment?.getString(R.string.wallet_twins_chip_format, 1, cardCount) } else { - tv_twin_card_number.hide() + tvTwinCardNumber.hide() } } - private fun setupButtons(fragment: WalletFragment) = with(fragment) { - btn_scan_multiwallet?.setOnClickListener { store.dispatch(WalletAction.Scan) } + private fun setupButtons(binding: FragmentWalletBinding) = with(binding) { + btnScanMultiwallet.setOnClickListener { store.dispatch(WalletAction.Scan) } } - override fun setFragment(fragment: WalletFragment) { + override fun setFragment(fragment: WalletFragment, binding: FragmentWalletBinding) { this.fragment = fragment + this.binding = binding } override fun removeFragment() { this.fragment = null + this.binding = null } override fun onViewCreated() { @@ -86,37 +86,42 @@ class MultiWalletView : WalletView { val fragment = fragment ?: return walletsAdapter = WalletAdapter() walletsAdapter.setHasStableIds(true) - fragment.rv_multiwallet.layoutManager = LinearLayoutManager(fragment.requireContext()) - fragment.rv_multiwallet.adapter = walletsAdapter + binding?.rvMultiwallet?.layoutManager = LinearLayoutManager(fragment.requireContext()) + binding?.rvMultiwallet?.adapter = walletsAdapter } override fun onNewState(state: WalletState) { val fragment = fragment ?: return + val binding = binding ?: return walletsAdapter.submitList(state.wallets, state.primaryBlockchain, state.primaryToken) - fragment.btn_add_token?.setOnClickListener { + binding.btnAddToken.setOnClickListener { store.dispatch(TokensAction.LoadCurrencies) store.dispatch(TokensAction.SetAddedCurrencies(state.wallets)) store.dispatch(NavigationAction.NavigateTo(AppScreen.AddTokens)) } - handleErrorStates(state, fragment) + handleErrorStates(state = state, binding = binding, fragment = fragment) handleDialogs(state.walletDialog) } - private fun handleErrorStates(state: WalletState, fragment: WalletFragment) { + private fun handleErrorStates( + state: WalletState, + binding: FragmentWalletBinding, + fragment: WalletFragment + ) { when (state.primaryWallet?.currencyData?.status) { BalanceStatus.EmptyCard -> { showErrorState( - fragment, + binding, fragment.getText(R.string.wallet_error_empty_card), fragment.getString(R.string.wallet_error_empty_card_subtitle) ) - configureButtonsForEmptyWalletState(fragment) + configureButtonsForEmptyWalletState(binding) } BalanceStatus.UnknownBlockchain -> { showErrorState( - fragment, + binding, fragment.getText(R.string.wallet_error_unsupported_blockchain), fragment.getString(R.string.wallet_error_unsupported_blockchain_subtitle) ) @@ -125,24 +130,28 @@ class MultiWalletView : WalletView { } private fun showErrorState( - fragment: WalletFragment, errorTitle: CharSequence, errorDescription: CharSequence, - ) = with(fragment) { - l_card_balance.show() - l_balance.hide() - l_balance_error.show() - rv_multiwallet.hide() - btn_add_token.hide() - tv_error_title.text = errorTitle - tv_error_descriptions.text = errorDescription + binding: FragmentWalletBinding, errorTitle: CharSequence, errorDescription: CharSequence, + ) = with(binding) { + lCardBalance.root.show() + with(lCardBalance) { + lBalance.root.hide() + lBalanceError.root.show() + rvMultiwallet.show() + btnAddToken.hide() + lBalanceError.tvErrorTitle.text = errorTitle + lBalanceError.tvErrorDescriptions.text = errorDescription + } } - private fun configureButtonsForEmptyWalletState(fragment: WalletFragment) = with(fragment) { - btn_scan_multiwallet.hide() - l_buttons_long.show() - btn_scan_long.setOnClickListener { store.dispatch(WalletAction.Scan) } - btn_confirm_long.setOnClickListener { store.dispatch(WalletAction.CreateWallet) } - btn_confirm_long.text = fragment.getText(R.string.wallet_button_create_wallet) - } + private fun configureButtonsForEmptyWalletState(binding: FragmentWalletBinding) = + with(binding) { + btnScanMultiwallet.hide() + lButtonsLong.root.show() + lButtonsLong.btnScanLong.setOnClickListener { store.dispatch(WalletAction.Scan) } + lButtonsLong.btnConfirmLong.setOnClickListener { store.dispatch(WalletAction.CreateWallet) } + lButtonsLong.btnConfirmLong.text = + fragment?.getText(R.string.wallet_button_create_wallet) + } private fun handleDialogs(walletDialog: StateDialog?) { val fragment = fragment ?: return diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt index d8ab4644df..84d2795401 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt @@ -5,7 +5,10 @@ import android.view.View import android.view.ViewGroup import android.widget.Button import androidx.recyclerview.widget.LinearLayoutManager -import com.tangem.tap.common.extensions.* +import com.tangem.tap.common.extensions.beginDelayedTransition +import com.tangem.tap.common.extensions.fitChipsByGroupWidth +import com.tangem.tap.common.extensions.hide +import com.tangem.tap.common.extensions.show import com.tangem.tap.common.redux.StateDialog import com.tangem.tap.domain.twins.TwinCardNumber import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState @@ -15,42 +18,43 @@ import com.tangem.tap.features.wallet.ui.BalanceWidget import com.tangem.tap.features.wallet.ui.MultipleAddressUiHelper import com.tangem.tap.features.wallet.ui.WalletFragment import com.tangem.tap.features.wallet.ui.adapters.PendingTransactionsAdapter -import com.tangem.tap.features.wallet.ui.dialogs.* +import com.tangem.tap.features.wallet.ui.dialogs.AmountToSendDialog +import com.tangem.tap.features.wallet.ui.dialogs.ChooseTradeActionDialog +import com.tangem.tap.features.wallet.ui.dialogs.SignedHashesWarningDialog import com.tangem.tap.store import com.tangem.wallet.R -import kotlinx.android.synthetic.main.card_balance.* -import kotlinx.android.synthetic.main.fragment_wallet.* -import kotlinx.android.synthetic.main.layout_address.* -import kotlinx.android.synthetic.main.layout_wallet_long_buttons.* -import kotlinx.android.synthetic.main.layout_wallet_short_buttons.* +import com.tangem.wallet.databinding.FragmentWalletBinding class SingleWalletView : WalletView { private lateinit var pendingTransactionAdapter: PendingTransactionsAdapter private var fragment: WalletFragment? = null + private var binding: FragmentWalletBinding? = null private var dialog: Dialog? = null - override fun setFragment(fragment: WalletFragment) { + override fun setFragment(fragment: WalletFragment, binding: FragmentWalletBinding) { this.fragment = fragment + this.binding = binding } override fun removeFragment() { fragment = null + binding = null } - override fun changeWalletView(fragment: WalletFragment) { - setFragment(fragment) + override fun changeWalletView(fragment: WalletFragment, binding: FragmentWalletBinding) { + setFragment(fragment, binding) onViewCreated() - showSingleWalletView(fragment) + showSingleWalletView(binding) } - private fun showSingleWalletView(fragment: WalletFragment) = with(fragment) { - rv_multiwallet.hide() - btn_add_token.hide() - btn_scan_multiwallet?.hide() - rv_pending_transaction.hide() - l_card_balance.show() - l_address.show() + private fun showSingleWalletView(binding: FragmentWalletBinding) = with(binding) { + rvMultiwallet.hide() + btnAddToken.hide() + btnScanMultiwallet.hide() + rvPendingTransaction.hide() + lCardBalance.root.show() + lAddress.root.show() } override fun onViewCreated() { @@ -61,17 +65,19 @@ class SingleWalletView : WalletView { private fun setupTransactionsRecyclerView() { val fragment = fragment ?: return pendingTransactionAdapter = PendingTransactionsAdapter() - fragment.rv_pending_transaction.layoutManager = LinearLayoutManager(fragment.requireContext()) - fragment.rv_pending_transaction.adapter = pendingTransactionAdapter + binding?.rvPendingTransaction?.layoutManager = + LinearLayoutManager(fragment.requireContext()) + binding?.rvPendingTransaction?.adapter = pendingTransactionAdapter } override fun onNewState(state: WalletState) { val fragment = fragment ?: return + val binding = binding ?: return state.primaryWallet ?: return - setupTwinCards(state.twinCardsState, fragment) - setupButtons(state.primaryWallet, state.isTangemTwins, fragment) - setupAddressCard(state.primaryWallet, fragment) + setupTwinCards(state.twinCardsState, binding) + setupButtons(state.primaryWallet, state.isTangemTwins, binding) + setupAddressCard(state.primaryWallet, binding) showPendingTransactionsIfPresent(state.primaryWallet.pendingTransactions) setupBalance(state, state.primaryWallet) handleDialogs(state.walletDialog, fragment) @@ -79,75 +85,81 @@ class SingleWalletView : WalletView { private fun showPendingTransactionsIfPresent(pendingTransactions: List) { pendingTransactionAdapter.submitList(pendingTransactions) - fragment?.rv_pending_transaction?.show(pendingTransactions.isNotEmpty()) + binding?.rvPendingTransaction?.show(pendingTransactions.isNotEmpty()) } private fun setupBalance(state: WalletState, primaryWallet: WalletData) { - fragment?.apply { - this.l_balance.show() - BalanceWidget(this, primaryWallet.currencyData, state.isTangemTwins).setup() + val fragment = fragment ?: return + binding?.apply { + lCardBalance.lBalance.root.show() + BalanceWidget( + binding = this.lCardBalance, + fragment = fragment, + data = primaryWallet.currencyData, + isTwinCard = state.isTangemTwins + ).setup() } } private fun setupTwinCards( - twinCardsState: TwinCardsState?, fragment: WalletFragment - ) = with(fragment) { + twinCardsState: TwinCardsState?, binding: FragmentWalletBinding + ) = with(binding) { twinCardsState?.cardNumber?.let { cardNumber -> - tv_twin_card_number.show() + tvTwinCardNumber.show() val number = when (cardNumber) { TwinCardNumber.First -> 1 TwinCardNumber.Second -> 2 } - tv_twin_card_number.text = - this.getString(R.string.wallet_twins_chip_format, number, 2) + tvTwinCardNumber.text = + fragment?.getString(R.string.wallet_twins_chip_format, number, 2) } if (twinCardsState?.cardNumber == null) { - tv_twin_card_number.hide() + tvTwinCardNumber.hide() } } private fun setupButtons( - state: WalletData, isTwinsWallet: Boolean, fragment: WalletFragment - ) = with(fragment){ + state: WalletData, isTwinsWallet: Boolean, binding: FragmentWalletBinding + ) = with(binding) { - setupButtonsType(state, fragment) + setupButtonsType(state, binding) val btnConfirm = if (state.tradeCryptoState.sellingAllowed || state.tradeCryptoState.buyingAllowed ) { - btn_confirm_short + lButtonsShort.btnConfirmShort } else { - btn_confirm_long + lButtonsLong.btnConfirmLong } val btnScan = if (state.tradeCryptoState.sellingAllowed || state.tradeCryptoState.buyingAllowed ) { - btn_scan_short + lButtonsShort.btnScanShort } else { - btn_scan_long + lButtonsLong.btnScanLong } - setupConfirmButton(state, btnConfirm, fragment, isTwinsWallet) + setupConfirmButton(state, btnConfirm, isTwinsWallet) btnScan.setOnClickListener { store.dispatch(WalletAction.Scan) } - btn_copy.setOnClickListener { + lAddress.btnCopy.setOnClickListener { state.walletAddresses?.selectedAddress?.address?.let { addressString -> - store.dispatch(WalletAction.CopyAddress(addressString, fragment.requireContext())) + store.dispatch(WalletAction.CopyAddress(addressString, fragment!!.requireContext())) } } - btn_show_qr.setOnClickListener { + lAddress.btnShowQr.setOnClickListener { store.dispatch(WalletAction.ShowDialog.QrCode) } - setupTradeButton(fragment, state.tradeCryptoState) + setupTradeButton(binding, state.tradeCryptoState) } - private fun setupTradeButton(fragment: WalletFragment, tradeCryptoState: TradeCryptoState) { + private fun setupTradeButton(binding: FragmentWalletBinding, tradeCryptoState: TradeCryptoState) { val allowedToBuy = tradeCryptoState.buyingAllowed val allowedToSell = tradeCryptoState.sellingAllowed val action = when { @@ -160,7 +172,7 @@ class SingleWalletView : WalletView { allowedToBuy && !allowedToSell -> R.string.wallet_button_buy !allowedToBuy && allowedToSell -> R.string.wallet_button_sell allowedToBuy && allowedToSell -> R.string.wallet_button_trade - else -> R.string.wallet_button_trade + else -> R.string.wallet_button_trade } val icon = when { allowedToBuy && !allowedToSell -> R.drawable.ic_arrow_up_short_btn @@ -168,27 +180,27 @@ class SingleWalletView : WalletView { allowedToBuy && allowedToSell -> R.drawable.ic_arrows_up_down_short_btn else -> null } - with(fragment) { - btn_trade.text = getText(text) - btn_trade.setCompoundDrawablesWithIntrinsicBounds(0, icon ?: 0, 0, 0) - btn_trade.setOnClickListener { if (action != null) store.dispatch(action) } + with(binding) { + lButtonsShort.btnTrade.text = fragment?.getText(text) + lButtonsShort.btnTrade.setCompoundDrawablesWithIntrinsicBounds(0, icon ?: 0, 0, 0) + lButtonsShort.btnTrade.setOnClickListener { if (action != null) store.dispatch(action) } } } - private fun setupButtonsType(state: WalletData, fragment: WalletFragment) = with(fragment) { + private fun setupButtonsType(state: WalletData, binding: FragmentWalletBinding) = with(binding) { if (state.tradeCryptoState.sellingAllowed || state.tradeCryptoState.buyingAllowed ) { - l_buttons_long.hide() - l_buttons_short.show() + lButtonsLong.root.hide() + lButtonsShort.root.show() } else { - l_buttons_long.show() - l_buttons_short.hide() + lButtonsLong.root.show() + lButtonsShort.root.hide() } } private fun setupConfirmButton( - state: WalletData, btnConfirm: Button, fragment: WalletFragment, isTwinsWallet: Boolean, + state: WalletData, btnConfirm: Button, isTwinsWallet: Boolean, ) { val buttonTitle = when (state.mainButton) { is WalletMainButton.SendButton -> R.string.wallet_button_send @@ -200,7 +212,7 @@ class SingleWalletView : WalletView { } } } - btnConfirm.text = fragment.getString(buttonTitle) + btnConfirm.text = fragment?.getString(buttonTitle) btnConfirm.isEnabled = state.mainButton.enabled btnConfirm.setOnClickListener { when (state.mainButton) { @@ -211,33 +223,38 @@ class SingleWalletView : WalletView { } - private fun setupAddressCard(state: WalletData, fragment: WalletFragment) = with(fragment) { + private fun setupAddressCard(state: WalletData, binding: FragmentWalletBinding) = with(binding.lAddress) { if (state.walletAddresses != null && state.currency is Currency.Blockchain) { - l_address?.show() + binding.lAddress.root.show() if (state.shouldShowMultipleAddress()) { - (l_address as? ViewGroup)?.beginDelayedTransition() - chip_group_address_type.show() - chip_group_address_type.fitChipsByGroupWidth() + (binding.lAddress.root as? ViewGroup)?.beginDelayedTransition() + chipGroupAddressType.show() + chipGroupAddressType.fitChipsByGroupWidth() - val checkedId = MultipleAddressUiHelper.typeToId(state.walletAddresses.selectedAddress.type) - if (checkedId != View.NO_ID) chip_group_address_type.check(checkedId) + val checkedId = + MultipleAddressUiHelper.typeToId(state.walletAddresses.selectedAddress.type) + if (checkedId != View.NO_ID) chipGroupAddressType.check(checkedId) - chip_group_address_type.setOnCheckedChangeListener { group, checkedId -> + chipGroupAddressType.setOnCheckedChangeListener { group, checkedId -> if (checkedId == -1) return@setOnCheckedChangeListener - val type = MultipleAddressUiHelper.idToType(checkedId, state.currency.blockchain) + val type = + MultipleAddressUiHelper.idToType(checkedId, state.currency.blockchain) type?.let { store.dispatch(WalletAction.ChangeSelectedAddress(type)) } } } else { - chip_group_address_type.hide() + chipGroupAddressType.hide() } - tv_address.text = state.walletAddresses.selectedAddress.address - tv_explore?.setOnClickListener { - store.dispatch(WalletAction.ExploreAddress( + tvAddress.text = state.walletAddresses.selectedAddress.address + tvExplore.setOnClickListener { + store.dispatch( + WalletAction.ExploreAddress( state.walletAddresses.selectedAddress.exploreUrl, - fragment.requireContext())) + fragment!!.requireContext() + ) + ) } } else { - l_address?.hide() + binding.lAddress.root.hide() } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/WalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/WalletView.kt index ab49865c02..1d9ea0eac0 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/WalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/WalletView.kt @@ -2,14 +2,15 @@ package com.tangem.tap.features.wallet.ui.wallet import com.tangem.tap.features.wallet.redux.WalletState import com.tangem.tap.features.wallet.ui.WalletFragment +import com.tangem.wallet.databinding.FragmentWalletBinding interface WalletView { - fun setFragment(fragment: WalletFragment) + fun setFragment(fragment: WalletFragment, binding: FragmentWalletBinding) fun removeFragment() - fun changeWalletView(fragment: WalletFragment) + fun changeWalletView(fragment: WalletFragment, binding: FragmentWalletBinding) fun onViewCreated() diff --git a/app/src/main/res/layout/fragment_onboarding_main.xml b/app/src/main/res/layout/fragment_onboarding_main.xml index 6d567ce91b..795b8ebe56 100644 --- a/app/src/main/res/layout/fragment_onboarding_main.xml +++ b/app/src/main/res/layout/fragment_onboarding_main.xml @@ -33,8 +33,9 @@ android:orientation="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior"> - diff --git a/app/src/main/res/layout/fragment_onboarding_wallet.xml b/app/src/main/res/layout/fragment_onboarding_wallet.xml index 50db217206..f1c1983eb1 100644 --- a/app/src/main/res/layout/fragment_onboarding_wallet.xml +++ b/app/src/main/res/layout/fragment_onboarding_wallet.xml @@ -225,6 +225,7 @@ diff --git a/app/src/main/res/layout/fragment_send.xml b/app/src/main/res/layout/fragment_send.xml index 78131a2e15..1026392257 100644 --- a/app/src/main/res/layout/fragment_send.xml +++ b/app/src/main/res/layout/fragment_send.xml @@ -39,12 +39,14 @@ android:orientation="vertical">