diff --git a/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/Navigator.kt b/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/Navigator.kt index 93aa25fe..e5a970b2 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/Navigator.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/Navigator.kt @@ -108,6 +108,8 @@ import io.novafoundation.nova.feature_ledger_impl.presentation.account.addChain. import io.novafoundation.nova.feature_ledger_impl.presentation.account.common.selectLedger.SelectLedgerPayload import io.novafoundation.nova.feature_multisig_operations.presentation.created.MultisigCreatedBottomSheet import io.novafoundation.nova.feature_multisig_operations.presentation.created.MultisigCreatedPayload +import io.novafoundation.nova.feature_multisig_operations.presentation.details.general.MultisigOperationDetailsFragment +import io.novafoundation.nova.feature_multisig_operations.presentation.details.general.MultisigOperationDetailsPayload import io.novafoundation.nova.feature_onboarding_impl.OnboardingRouter import io.novafoundation.nova.feature_onboarding_impl.presentation.welcome.WelcomeFragment import io.novafoundation.nova.feature_swap_api.presentation.model.SwapSettingsPayload @@ -983,6 +985,12 @@ class Navigator( .navigateInFirstAttachedContext() } + override fun openMultisigOperationDetails(payload: MultisigOperationDetailsPayload) { + navigationBuilder().action(R.id.action_multisigOperationDetailsFragment) + .setArgs(MultisigOperationDetailsFragment.createPayload(payload)) + .navigateInFirstAttachedContext() + } + override fun openMainWithFinishMultisigTransaction(accountWasSwitched: Boolean) { val payload = MultisigCreatedBottomSheet.createPayload(MultisigCreatedPayload(accountWasSwitched)) openSplitScreenWithInstantAction(R.id.action_open_multisigCreatedDialog, nestedActionExtras = payload) diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index 8854432a..c7e95933 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -2778,6 +2778,9 @@ Score tracking started! Hejmara Kurd Le Cihane + Pending Signatures + Sign + Citizenship Application Full Name diff --git a/feature-assets/build.gradle b/feature-assets/build.gradle index 5d2c584f..eb8ffa47 100644 --- a/feature-assets/build.gradle +++ b/feature-assets/build.gradle @@ -48,6 +48,7 @@ dependencies { implementation project(':feature-deep-linking') implementation project(':feature-ahm-api') implementation project(':feature-gift-api') + implementation project(':feature-multisig:operations') implementation kotlinDep diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/di/AssetsFeatureComponent.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/di/AssetsFeatureComponent.kt index 2b7f4c82..d71111c6 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/di/AssetsFeatureComponent.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/di/AssetsFeatureComponent.kt @@ -53,6 +53,7 @@ import io.novafoundation.nova.feature_crowdloan_api.di.CrowdloanFeatureApi import io.novafoundation.nova.feature_currency_api.di.CurrencyFeatureApi import io.novafoundation.nova.feature_deep_linking.di.DeepLinkingFeatureApi import io.novafoundation.nova.feature_gift_api.di.GiftFeatureApi +import io.novafoundation.nova.feature_multisig_operations.di.MultisigOperationsFeatureApi import io.novafoundation.nova.feature_nft_api.NftFeatureApi import io.novafoundation.nova.feature_staking_api.di.StakingFeatureApi import io.novafoundation.nova.feature_swap_api.di.SwapFeatureApi @@ -175,7 +176,8 @@ interface AssetsFeatureComponent : AssetsFeatureApi { BannersFeatureApi::class, DeepLinkingFeatureApi::class, ChainMigrationFeatureApi::class, - GiftFeatureApi::class + GiftFeatureApi::class, + MultisigOperationsFeatureApi::class ] ) interface AssetsFeatureDependenciesComponent : AssetsFeatureDependencies diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/di/AssetsFeatureDependencies.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/di/AssetsFeatureDependencies.kt index 1b91d945..90b388c5 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/di/AssetsFeatureDependencies.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/di/AssetsFeatureDependencies.kt @@ -99,6 +99,7 @@ import io.novafoundation.nova.feature_account_api.data.fee.capability.CustomFeeC import io.novafoundation.nova.feature_ahm_api.domain.ChainMigrationInfoUseCase import io.novafoundation.nova.feature_gift_api.domain.GiftsAccountSupportedUseCase import io.novafoundation.nova.feature_gift_api.domain.AvailableGiftAssetsUseCase +import io.novafoundation.nova.feature_multisig_operations.presentation.callFormatting.MultisigCallFormatter import io.novafoundation.nova.feature_wallet_api.domain.SendUseCase import io.novafoundation.nova.feature_wallet_api.presentation.mixin.amountChooser.AmountChooserMixin import io.novafoundation.nova.feature_wallet_api.presentation.mixin.fee.FeeLoaderMixin @@ -240,6 +241,8 @@ interface AssetsFeatureDependencies { val multisigPendingOperationsService: MultisigPendingOperationsService + val multisigCallFormatter: MultisigCallFormatter + val automaticInteractionGate: AutomaticInteractionGate val linkBuilderFactory: LinkBuilderFactory diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/di/AssetsFeatureHolder.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/di/AssetsFeatureHolder.kt index 2f0ac8c0..5b176d94 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/di/AssetsFeatureHolder.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/di/AssetsFeatureHolder.kt @@ -15,6 +15,7 @@ import io.novafoundation.nova.feature_crowdloan_api.di.CrowdloanFeatureApi import io.novafoundation.nova.feature_currency_api.di.CurrencyFeatureApi import io.novafoundation.nova.feature_deep_linking.di.DeepLinkingFeatureApi import io.novafoundation.nova.feature_gift_api.di.GiftFeatureApi +import io.novafoundation.nova.feature_multisig_operations.di.MultisigOperationsFeatureApi import io.novafoundation.nova.feature_nft_api.NftFeatureApi import io.novafoundation.nova.feature_staking_api.di.StakingFeatureApi import io.novafoundation.nova.feature_swap_api.di.SwapFeatureApi @@ -51,6 +52,7 @@ class AssetsFeatureHolder @Inject constructor( .deepLinkingFeatureApi(getFeature(DeepLinkingFeatureApi::class.java)) .chainMigrationFeatureApi(getFeature(ChainMigrationFeatureApi::class.java)) .giftFeatureApi(getFeature(GiftFeatureApi::class.java)) + .multisigOperationsFeatureApi(getFeature(MultisigOperationsFeatureApi::class.java)) .build() return DaggerAssetsFeatureComponent.factory() diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/AssetsRouter.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/AssetsRouter.kt index e9a8f688..dadbfede 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/AssetsRouter.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/AssetsRouter.kt @@ -11,6 +11,7 @@ import io.novafoundation.nova.feature_assets.presentation.tokens.add.enterInfo.A import io.novafoundation.nova.feature_assets.presentation.tokens.manage.chain.ManageChainTokensPayload import io.novafoundation.nova.feature_assets.presentation.trade.webInterface.TradeWebPayload import io.novafoundation.nova.feature_assets.presentation.transaction.filter.TransactionHistoryFilterPayload +import io.novafoundation.nova.feature_multisig_operations.presentation.details.general.MultisigOperationDetailsPayload import io.novafoundation.nova.feature_swap_api.presentation.model.SwapSettingsPayload import io.novafoundation.nova.feature_wallet_api.presentation.model.AssetPayload @@ -120,6 +121,8 @@ interface AssetsRouter { fun openPendingMultisigOperations() + fun openMultisigOperationDetails(payload: MultisigOperationDetailsPayload) + fun openAssetDetailsFromDeepLink(payload: AssetPayload) fun openGifts() diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/BalanceListFragment.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/BalanceListFragment.kt index 1278f1e4..25e481e7 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/BalanceListFragment.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/BalanceListFragment.kt @@ -36,6 +36,9 @@ import android.content.Intent import android.widget.Toast import io.novafoundation.nova.feature_assets.presentation.balance.list.view.PezkuwiDashboardAdapter import io.novafoundation.nova.feature_assets.presentation.balance.list.view.PezkuwiDashboardHolder +import io.novafoundation.nova.feature_assets.presentation.balance.list.view.PendingSignaturesAdapter +import io.novafoundation.nova.feature_assets.presentation.balance.list.view.PendingSignaturesHolder +import io.novafoundation.nova.feature_assets.presentation.balance.list.model.PendingSignatureModel import io.novafoundation.nova.feature_assets.presentation.citizenship.CitizenshipBottomSheet import io.novafoundation.nova.feature_banners_api.presentation.BannerHolder import io.novafoundation.nova.feature_banners_api.presentation.PromotionBannerAdapter @@ -49,6 +52,7 @@ class BalanceListFragment : AssetsHeaderAdapter.Handler, ManageAssetsAdapter.Handler, PezkuwiDashboardAdapter.Handler, + PendingSignaturesAdapter.Handler, CitizenshipBottomSheet.CitizenshipDismissListener { override fun createBinding() = FragmentBalanceListBinding.inflate(layoutInflater) @@ -66,6 +70,10 @@ class BalanceListFragment : PezkuwiDashboardAdapter(this) } + private val pendingSignaturesAdapter by lazy(LazyThreadSafetyMode.NONE) { + PendingSignaturesAdapter(imageLoader, this) + } + private val bannerAdapter: PromotionBannerAdapter by lazy(LazyThreadSafetyMode.NONE) { PromotionBannerAdapter(closable = true) } @@ -86,7 +94,15 @@ class BalanceListFragment : } private val adapter by lazy(LazyThreadSafetyMode.NONE) { - ConcatAdapter(headerAdapter, pezkuwiDashboardAdapter, bannerAdapter, manageAssetsAdapter, emptyAssetsPlaceholder, assetsAdapter) + ConcatAdapter( + headerAdapter, + pezkuwiDashboardAdapter, + pendingSignaturesAdapter, + bannerAdapter, + manageAssetsAdapter, + emptyAssetsPlaceholder, + assetsAdapter + ) } override fun applyInsets(rootView: View) { @@ -143,6 +159,11 @@ class BalanceListFragment : } } + viewModel.pendingSignaturesFlow.observe { models -> + pendingSignaturesAdapter.setModels(models) + pendingSignaturesAdapter.show(models.isNotEmpty()) + } + viewModel.bannersMixin.bindWithAdapter(bannerAdapter) { binder.balanceListAssets.invalidateItemDecorations() } @@ -301,6 +322,10 @@ class BalanceListFragment : viewModel.startTrackingClicked() } + override fun onSignClicked(model: PendingSignatureModel) { + viewModel.pendingSignatureSignClicked(model) + } + private fun setupRecyclerViewSpacing() { binder.balanceListAssets.addSpaceItemDecoration { add(SpaceBetween(AssetsHeaderHolder, PezkuwiDashboardHolder, spaceDp = 8)) @@ -309,6 +334,11 @@ class BalanceListFragment : add(SpaceBetween(AssetsHeaderHolder, BannerHolder, spaceDp = 4)) add(SpaceBetween(BannerHolder, ManageAssetsHolder, spaceDp = 4)) add(SpaceBetween(AssetsHeaderHolder, ManageAssetsHolder, spaceDp = 24)) + + add(SpaceBetween(AssetsHeaderHolder, PendingSignaturesHolder, spaceDp = 8)) + add(SpaceBetween(PezkuwiDashboardHolder, PendingSignaturesHolder, spaceDp = 8)) + add(SpaceBetween(PendingSignaturesHolder, BannerHolder, spaceDp = 4)) + add(SpaceBetween(PendingSignaturesHolder, ManageAssetsHolder, spaceDp = 24)) } } diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/BalanceListViewModel.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/BalanceListViewModel.kt index 03d4305e..7b18ac21 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/BalanceListViewModel.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/BalanceListViewModel.kt @@ -20,10 +20,15 @@ import io.novafoundation.nova.common.utils.formatting.formatAsPercentage import io.novafoundation.nova.common.utils.inBackground import io.novafoundation.nova.common.utils.launchUnit import io.novafoundation.nova.common.utils.withSafeLoading +import io.novafoundation.nova.feature_account_api.data.mappers.mapChainToUi import io.novafoundation.nova.feature_account_api.data.multisig.MultisigPendingOperationsService +import io.novafoundation.nova.feature_account_api.data.multisig.model.MultisigAction +import io.novafoundation.nova.feature_account_api.data.multisig.model.PendingMultisigOperation +import io.novafoundation.nova.feature_account_api.data.multisig.model.userAction import io.novafoundation.nova.feature_account_api.domain.interfaces.SelectedAccountUseCase import io.novafoundation.nova.feature_account_api.domain.model.MetaAccount import io.novafoundation.nova.feature_account_api.domain.model.defaultSubstrateAddress +import io.novafoundation.nova.feature_account_api.domain.model.requireAccountIdKeyIn import io.novafoundation.nova.feature_assets.R import io.novafoundation.nova.feature_assets.domain.WalletInteractor import io.novafoundation.nova.feature_assets.domain.assets.list.AssetsListInteractor @@ -42,6 +47,7 @@ import io.novafoundation.nova.feature_assets.presentation.balance.common.buySell import io.novafoundation.nova.feature_assets.presentation.balance.common.buySell.BuySellSelectorMixinFactory import io.novafoundation.nova.feature_assets.presentation.citizenship.PendingCitizenshipReferrer import io.novafoundation.nova.feature_assets.presentation.balance.list.model.NftPreviewUi +import io.novafoundation.nova.feature_assets.presentation.balance.list.model.PendingSignatureModel import io.novafoundation.nova.feature_assets.presentation.balance.list.model.TotalBalanceModel import io.novafoundation.nova.feature_assets.presentation.balance.list.view.AssetViewModeModel import io.novafoundation.nova.feature_assets.presentation.balance.list.view.PendingOperationsCountModel @@ -52,6 +58,10 @@ import io.novafoundation.nova.feature_banners_api.presentation.source.assetsSour import io.novafoundation.nova.feature_currency_api.domain.CurrencyInteractor import io.novafoundation.nova.feature_currency_api.domain.model.Currency import io.novafoundation.nova.feature_currency_api.presentation.formatters.formatAsCurrency +import io.novafoundation.nova.feature_multisig_operations.presentation.callFormatting.MultisigCallFormatter +import io.novafoundation.nova.feature_multisig_operations.presentation.common.MultisigOperationPayload +import io.novafoundation.nova.feature_multisig_operations.presentation.common.fromOperationId +import io.novafoundation.nova.feature_multisig_operations.presentation.details.general.MultisigOperationDetailsPayload import io.novafoundation.nova.feature_nft_api.data.model.Nft import io.novafoundation.nova.feature_swap_api.domain.interactor.SwapAvailabilityInteractor import io.novafoundation.nova.feature_wallet_api.presentation.formatters.amount.AmountFormatter @@ -108,6 +118,7 @@ class BalanceListViewModel( private val maskableValueFormatterProvider: MaskableValueFormatterProvider, private val buySellSelectorMixinFactory: BuySellSelectorMixinFactory, private val multisigPendingOperationsService: MultisigPendingOperationsService, + private val multisigCallFormatter: MultisigCallFormatter, private val novaCardRestrictionCheckMixin: NovaCardRestrictionCheckMixin, private val maskingModeUseCase: MaskingModeUseCase, private val giftsRestrictionCheckMixin: GiftsRestrictionCheckMixin, @@ -248,6 +259,38 @@ class BalanceListViewModel( .combine(maskableAmountFormatterFlow, ::formatPendingOperationsCount) .shareInBackground() + val pendingSignaturesFlow = multisigPendingOperationsService.pendingOperations() + .mapLatest { operations -> + val account = selectedMetaAccount.first() + + // Only operations still awaiting THIS signatory's own approval - once signed, the + // item naturally drops out here on next sync (no client-side "turn green" state to + // maintain in parallel with the real, authoritative on-chain approval status). + operations + .filter { it.userAction() is MultisigAction.CanApprove } + .map { it.toPendingSignatureUi(account) } + } + .shareInBackground() + + fun pendingSignatureSignClicked(model: PendingSignatureModel) { + val operationPayload = MultisigOperationPayload.fromOperationId(model.id) + router.openMultisigOperationDetails(MultisigOperationDetailsPayload(operationPayload)) + } + + private suspend fun PendingMultisigOperation.toPendingSignatureUi(selectedAccount: MetaAccount): PendingSignatureModel { + val initialOrigin = selectedAccount.requireAccountIdKeyIn(chain) + val formattedCall = multisigCallFormatter.formatPreview(call, initialOrigin, chain) + + return PendingSignatureModel( + id = operationId, + chain = mapChainToUi(chain), + title = formattedCall.title, + subtitle = formattedCall.subtitle, + primaryValue = formattedCall.primaryValue, + progress = resourceManager.getString(R.string.multisig_operations_progress, approvals.size.format(), threshold.format()) + ) + } + val pezkuwiDashboardFlow = selectedMetaAccount .combine(dashboardRefreshSignal) { account, _ -> account } .mapLatest { metaAccount -> diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/di/BalanceListModule.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/di/BalanceListModule.kt index eb4ddf0d..9c9d51b0 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/di/BalanceListModule.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/di/BalanceListModule.kt @@ -13,6 +13,7 @@ import io.novafoundation.nova.common.di.viewmodel.ViewModelModule import io.novafoundation.nova.common.domain.usecase.MaskingModeUseCase import io.novafoundation.nova.common.resources.ResourceManager import io.novafoundation.nova.feature_account_api.data.multisig.MultisigPendingOperationsService +import io.novafoundation.nova.feature_multisig_operations.presentation.callFormatting.MultisigCallFormatter import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository import io.novafoundation.nova.feature_account_api.domain.interfaces.SelectedAccountUseCase import io.novafoundation.nova.feature_assets.data.repository.PezkuwiDashboardRepository @@ -122,6 +123,7 @@ class BalanceListModule { amountFormatter: AmountFormatter, buySellSelectorMixinFactory: BuySellSelectorMixinFactory, multisigPendingOperationsService: MultisigPendingOperationsService, + multisigCallFormatter: MultisigCallFormatter, novaCardRestrictionCheckMixin: NovaCardRestrictionCheckMixin, maskableValueFormatterProvider: MaskableValueFormatterProvider, maskingModeUseCase: MaskingModeUseCase, @@ -148,6 +150,7 @@ class BalanceListModule { maskableValueFormatterProvider = maskableValueFormatterProvider, buySellSelectorMixinFactory = buySellSelectorMixinFactory, multisigPendingOperationsService = multisigPendingOperationsService, + multisigCallFormatter = multisigCallFormatter, novaCardRestrictionCheckMixin = novaCardRestrictionCheckMixin, maskingModeUseCase = maskingModeUseCase, fiatFormatter = fiatFormatter, diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/model/PendingSignatureModel.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/model/PendingSignatureModel.kt new file mode 100644 index 00000000..b0d44863 --- /dev/null +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/model/PendingSignatureModel.kt @@ -0,0 +1,13 @@ +package io.novafoundation.nova.feature_assets.presentation.balance.list.model + +import io.novafoundation.nova.feature_account_api.data.multisig.model.PendingMultisigOperationId +import io.novafoundation.nova.feature_account_api.presenatation.chain.ChainUi + +data class PendingSignatureModel( + val id: PendingMultisigOperationId, + val chain: ChainUi, + val title: String, + val subtitle: String?, + val primaryValue: CharSequence?, + val progress: String, +) diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/view/PendingSignaturesAdapter.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/view/PendingSignaturesAdapter.kt new file mode 100644 index 00000000..251a86eb --- /dev/null +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/list/view/PendingSignaturesAdapter.kt @@ -0,0 +1,74 @@ +package io.novafoundation.nova.feature_assets.presentation.balance.list.view + +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import coil.ImageLoader +import io.novafoundation.nova.common.list.SingleItemAdapter +import io.novafoundation.nova.common.utils.inflater +import io.novafoundation.nova.common.utils.recyclerView.WithViewType +import io.novafoundation.nova.feature_account_api.presenatation.chain.loadChainIcon +import io.novafoundation.nova.feature_assets.R +import io.novafoundation.nova.feature_assets.databinding.ItemPendingSignatureRowBinding +import io.novafoundation.nova.feature_assets.databinding.ItemPendingSignaturesCardBinding +import io.novafoundation.nova.feature_assets.presentation.balance.list.model.PendingSignatureModel + +class PendingSignaturesAdapter( + private val imageLoader: ImageLoader, + private val handler: Handler +) : SingleItemAdapter(isShownByDefault = false) { + + interface Handler { + fun onSignClicked(model: PendingSignatureModel) + } + + private var models: List = emptyList() + + fun setModels(models: List) { + this.models = models + notifyChangedIfShown() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PendingSignaturesHolder { + val binding = ItemPendingSignaturesCardBinding.inflate(parent.inflater(), parent, false) + return PendingSignaturesHolder(binding, imageLoader, handler) + } + + override fun onBindViewHolder(holder: PendingSignaturesHolder, position: Int) { + holder.bind(models) + } + + override fun getItemViewType(position: Int): Int { + return PendingSignaturesHolder.viewType + } +} + +class PendingSignaturesHolder( + private val binder: ItemPendingSignaturesCardBinding, + private val imageLoader: ImageLoader, + private val handler: PendingSignaturesAdapter.Handler +) : RecyclerView.ViewHolder(binder.root) { + + companion object : WithViewType { + override val viewType: Int = R.layout.item_pending_signatures_card + } + + fun bind(models: List) { + val container = binder.pendingSignaturesRowsContainer + container.removeAllViews() + + models.forEach { model -> + val rowBinding = ItemPendingSignatureRowBinding.inflate(container.inflater(), container, false) + + rowBinding.pendingSignatureChainIcon.loadChainIcon(model.chain.icon, imageLoader) + // primaryValue (e.g. "100K USDT") is the amount - the whole point of this card - so it + // takes the prominent title line; the call's own title/action name ("Transfer") isn't + // shown at all here, only the destination (subtitle) is, to keep the row to two lines. + rowBinding.pendingSignatureTitle.text = model.primaryValue ?: model.title + rowBinding.pendingSignatureSubtitle.text = listOfNotNull(model.subtitle, model.chain.name, model.progress) + .joinToString(separator = " • ") + rowBinding.pendingSignatureSignButton.setOnClickListener { handler.onSignClicked(model) } + + container.addView(rowBinding.root) + } + } +} diff --git a/feature-assets/src/main/res/layout/item_pending_signature_row.xml b/feature-assets/src/main/res/layout/item_pending_signature_row.xml new file mode 100644 index 00000000..ca2245d7 --- /dev/null +++ b/feature-assets/src/main/res/layout/item_pending_signature_row.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + diff --git a/feature-assets/src/main/res/layout/item_pending_signatures_card.xml b/feature-assets/src/main/res/layout/item_pending_signatures_card.xml new file mode 100644 index 00000000..cc208529 --- /dev/null +++ b/feature-assets/src/main/res/layout/item_pending_signatures_card.xml @@ -0,0 +1,35 @@ + + + + + + + + + + +