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 @@
+
+
+
+
+
+
+
+
+
+
+