Skip to content

Conversation

@yasin-ce
Copy link
Collaborator

Summary

  • Add AccountIconResource.JOINT with dedicated icon styling
  • Add JointAccountBadgeViewHolder for account list items
  • Add JointAccountDetailFragment and JointAccountDetailScreen
  • Add JointAccountDetailViewModel with processor pattern
  • Update GetAccountIconDrawablePreview for joint accounts
  • Update account detail summary for joint accounts
  • Add export/share account fragment

Test Plan

  • Verify joint account displays correct icon in account list
  • Verify joint account badge shows participant count
  • Verify joint account detail screen shows all participants
  • Test navigation to joint account detail

@yasin-ce yasin-ce self-assigned this Jan 20, 2026
@yasin-ce yasin-ce force-pushed the multisig/05-data-models branch from 014714a to c3e316e Compare January 20, 2026 09:32
@yasin-ce yasin-ce force-pushed the multisig/06-account-pages-support branch from 4b6f926 to f44cf3b Compare January 20, 2026 09:32
@yasin-ce yasin-ce force-pushed the multisig/05-data-models branch from c3e316e to 6b1b4d5 Compare January 20, 2026 09:48
@yasin-ce yasin-ce force-pushed the multisig/06-account-pages-support branch from f44cf3b to c787611 Compare January 20, 2026 09:49
- Update AccountIconResource with JOINT type
- Add joint account badge to account list items
- Update account detail screens for joint accounts
- Add joint account icon drawable preview
- Update account type detection in existing flows
- Add TransactionSigner.Joint handling
@yasin-ce yasin-ce force-pushed the multisig/05-data-models branch from 6b1b4d5 to a997278 Compare January 20, 2026 13:49
@yasin-ce yasin-ce force-pushed the multisig/06-account-pages-support branch from c787611 to 8bd9179 Compare January 20, 2026 13:49
…-support

Resolve merge conflicts:
- DefaultAccountDetailAccountsItemProcessor: keep 06's joint account features with HasInboxItemsForAddress
- AccountStatusDetailPreviewDecider: keep 06's proper Joint account handling
- Restore use cases removed by merge: GetJointAccount, GetJointAccountUseCase, GetJointAccountParticipantCount, GetJointAccountParticipantCountUseCase
- Update DefaultJointAccountDetailProcessor to use InboxMessages instead of InboxMessagesDTO
- Add internal modifier to AssetInboxRepositoryImplTest
- Update HasInboxItemsForAddressUseCaseTest to use AssetInbox and JointAccount instead of DTO versions
…unt bindings

Add Dagger @provides methods for GetJointAccount and GetJointAccountParticipantCount
use cases in JointAccountModule to fix missing binding errors.
Comment on lines 23 to 26
override suspend fun invoke(address: String): Int {
val jointAccount = getLocalAccount(address) as? LocalAccount.Joint
return jointAccount?.participantAddresses?.size ?: 0
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be done in repository. JointAccountRepository can return this value. No need to use getLocalAccount

) : GetJointAccount {

override suspend fun invoke(address: String): LocalAccount.Joint? {
return getLocalAccount(address) as? LocalAccount.Joint
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JointAccountRepository can return this instead of calling getLocalAccount

Comment on lines 180 to 181
val participants: List<JointAccountParticipantItem>,
val participantAddresses: List<String>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these contain the same addresses? If so, we shouldn't use different parameters for them

stateDelegate.updateState { contentState }
}

private suspend fun getInvitationData(): JointAccountDetailProcessor.InvitationData? {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function name is not only doing what it is supposed to do, it also updates state.

private val contactRepository: ContactRepository
) : CreateJointAccountParticipantItem {

override suspend fun getLocalAccountAddresses(): List<String> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no point of this function. We can inject getLocalAccountAddresses into where we call this function.

Comment on lines 20 to 26
class JointAccountInboxOperationsUseCase @Inject constructor(
private val deviceIdUseCase: DeviceIdUseCase,
@param:Named(JointAccountRepository.INJECTION_NAME)
private val jointAccountRepository: JointAccountRepository,
) {

fun getDeviceId(): String? = deviceIdUseCase.getSelectedNodeDeviceId()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary use case


package com.algorand.android.modules.accountdetail.jointaccountdetail.ui.model

data class JointAccountDetailUiState(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused class

Comment on lines 84 to 98
override fun onEditAddressClick(address: String) {
viewModel.onEditContactClick(address)
}

override fun onCopyAddressClick(address: String) {
onAccountAddressCopied(address)
}

override fun onIgnoreClick() {
viewModel.onIgnoreClick()
}

override fun onAddClick() {
viewModel.onAddClick()
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do these viewmodel calls in screen composable, since we already pass viewmodel. There is no value of sending these events to Fragment and call VM function.

import javax.inject.Inject

// ISO-8601 ISO_DATE_TIME
class InboxLastOpenedTimeLocalSource @Inject constructor(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use PersistentCacheProvider instead of shared pref local source

Comment on lines 123 to 127
val eligibleSigners = participantAddresses.mapNotNull { address ->
allLocalAccounts.find { it.algoAddress == address }
}.filter { localAccount ->
localAccount is LocalAccount.Algo25 || localAccount is LocalAccount.HdKey
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary iterations. Can be use single iteration. Also we can create a db query instead of getting all the accounts every single time

…-support

* multisig/05-data-models:
  Address PR #515 comments for data models
  Fix detekt issues without @Suppress
  Fix pre-existing detekt issues
  Use Go SDK for transaction signing and return signature directly
  fix: Address remaining PR #514 review comments
  fix: Address PR #514 review comments
  fix: Address PR #514 feedback
  docs: Add refactoring restrictions to prevent unwanted changes
@yasin-ce yasin-ce requested a review from mitsinsar January 23, 2026 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants