Updated on 2026-08-14

This commit is contained in:
Tangem 2026-03-05 17:10:01 +05:00
commit 282ab7a56a
21 changed files with 193 additions and 195 deletions

View file

@ -1,10 +1,6 @@
package com.tangem.core.ui.ds.contextmenu
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@ -35,12 +31,13 @@ fun TangemContextMenuCheckboxItem(title: TextReference, isChecked: Boolean, onCl
text = title.resolveReference(),
style = TangemTheme.typography2.headingSemibold17,
color = TangemTheme.colors2.text.neutral.primary,
maxLines = 1,
)
TangemCheckbox(
modifier = Modifier,
isRounded = true,
isChecked = isChecked,
onCheckedChange = { /* no-op */ },
onCheckedChange = { onClick() },
)
}
}

View file

@ -14,7 +14,7 @@ import com.arkivanov.decompose.value.Value
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.feature.wallet.child.organizetokens.OrganizeTokensComponent
import com.tangem.feature.wallet.child.organizetokens.OrganizeTokensComponentLegacy
import com.tangem.feature.wallet.child.wallet.WalletComponent
import com.tangem.feature.wallet.navigation.WalletRoute
import com.tangem.features.wallet.WalletEntryComponent
@ -40,9 +40,9 @@ internal class DefaultWalletEntryComponent @AssistedInject constructor(
appComponentContext = childByContext(context),
navigate = { navigation.pushNew(it) },
)
is WalletRoute.OrganizeTokens -> OrganizeTokensComponent(
is WalletRoute.OrganizeTokens -> OrganizeTokensComponentLegacy(
appComponentContext = childByContext(context),
params = OrganizeTokensComponent.Params(route.userWalletId),
params = OrganizeTokensComponentLegacy.Params(route.userWalletId),
onBack = { navigation.pop() },
)
}

View file

@ -8,17 +8,17 @@ import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.feature.wallet.child.organizetokens.model.OrganizeTokensModel
import com.tangem.feature.wallet.child.organizetokens.model.OrganizeTokensModelLegacy
import com.tangem.feature.wallet.child.organizetokens.ui.OrganizeTokensScreen
import kotlinx.coroutines.launch
internal class OrganizeTokensComponent(
internal class OrganizeTokensComponentLegacy(
appComponentContext: AppComponentContext,
params: Params,
onBack: () -> Unit,
) : ComposableContentComponent, AppComponentContext by appComponentContext {
private val model: OrganizeTokensModel = getOrCreateModel(params)
private val model: OrganizeTokensModelLegacy = getOrCreateModel(params)
init {
componentScope.launch {

View file

@ -0,0 +1,20 @@
package com.tangem.feature.wallet.child.organizetokens.di
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.feature.wallet.child.organizetokens.model.OrganizeTokensModelLegacy
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(ModelComponent::class)
internal interface OrganizeTokensModule {
@Binds
@IntoMap
@ClassKey(OrganizeTokensModelLegacy::class)
fun bindOrganizeTokensModelLegacy(model: OrganizeTokensModelLegacy): Model
}

View file

@ -11,13 +11,13 @@ import com.tangem.feature.wallet.impl.R
* Helper class for the DND list items
*
* @property id ID of the item
* @property roundingMode item [RoundingMode]
* @property roundingModeUM item [RoundingModeUM]
* @property showShadow if true then item should be elevated
* */
@Immutable
internal sealed class DraggableItem {
abstract val id: Any
abstract val roundingMode: RoundingMode
abstract val roundingModeUM: RoundingModeUM
abstract val showShadow: Boolean
/**
@ -26,14 +26,14 @@ internal sealed class DraggableItem {
* @property id ID of the network group
* @property networkName network group name
* @property accountId account id
* @property roundingMode item [RoundingMode]
* @property roundingModeUM item [RoundingModeUM]
* @property showShadow if true then item should be elevated
* */
data class GroupHeader(
override val id: Int,
val networkName: String,
val accountId: String = "",
override val roundingMode: RoundingMode = RoundingMode.None,
override val roundingModeUM: RoundingModeUM = RoundingModeUM.None,
override val showShadow: Boolean = false,
) : DraggableItem() {
@ -53,7 +53,7 @@ internal sealed class DraggableItem {
* @property groupId ID of the network group which contains this token
* @property accountId account id
* @property id ID of the token
* @property roundingMode item [RoundingMode]
* @property roundingModeUM item [RoundingModeUM]
* @property showShadow if true then item should be elevated
* */
data class Token(
@ -61,7 +61,7 @@ internal sealed class DraggableItem {
val groupId: Int,
val accountId: String = "",
override val showShadow: Boolean = false,
override val roundingMode: RoundingMode = RoundingMode.None,
override val roundingModeUM: RoundingModeUM = RoundingModeUM.None,
) : DraggableItem() {
override val id: String = tokenItemState.id
}
@ -77,7 +77,7 @@ internal sealed class DraggableItem {
val accountId: String = "",
) : DraggableItem() {
override val showShadow: Boolean = false
override val roundingMode: RoundingMode = RoundingMode.None
override val roundingModeUM: RoundingModeUM = RoundingModeUM.None
}
/**
@ -85,11 +85,11 @@ internal sealed class DraggableItem {
*
* @property tokenItemState state of the portfolio item
* @property id ID of the portfolio
* @property roundingMode item [RoundingMode]
* @property roundingModeUM item [RoundingModeUM]
* @property showShadow if true then item should be elevated
* */
data class Portfolio(
override val roundingMode: RoundingMode = RoundingMode.None,
override val roundingModeUM: RoundingModeUM = RoundingModeUM.None,
val tokenItemState: TokenItemState,
) : DraggableItem() {
override val id: String = tokenItemState.id
@ -97,55 +97,17 @@ internal sealed class DraggableItem {
}
/**
* Rounding mode of the [DraggableItem]
* Update item [RoundingModeUM]
*
* @property showGap if true then item should have padding on rounded side
* */
@Immutable
sealed class RoundingMode {
abstract val showGap: Boolean
/**
* In this mode, item is not rounded
* */
object None : RoundingMode() {
override val showGap: Boolean = false
}
/**
* In this mode, item should have a rounded top side
*
* @property showGap if true then item should have top padding
* */
data class Top(override val showGap: Boolean = false) : RoundingMode()
/**
* In this mode, item should have a rounded bottom side
*
* @property showGap if true then item should have bottom padding
* */
data class Bottom(override val showGap: Boolean = false) : RoundingMode()
/**
* In this mode, item should have a rounded all sides
*
* @property showGap if true then item should have top and bottom padding
* */
data class All(override val showGap: Boolean = false) : RoundingMode()
}
/**
* Update item [RoundingMode]
*
* @param mode new [RoundingMode]
* @param mode new [RoundingModeUM]
*
* @return updated [DraggableItem]
* */
fun updateRoundingMode(mode: RoundingMode): DraggableItem = when (this) {
fun updateRoundingMode(mode: RoundingModeUM): DraggableItem = when (this) {
is Placeholder -> this
is Portfolio -> this.copy(roundingMode = mode)
is GroupHeader -> this.copy(roundingMode = mode)
is Token -> this.copy(roundingMode = mode)
is Portfolio -> this.copy(roundingModeUM = mode)
is GroupHeader -> this.copy(roundingModeUM = mode)
is Token -> this.copy(roundingModeUM = mode)
}
/**

View file

@ -0,0 +1,41 @@
package com.tangem.feature.wallet.child.organizetokens.entity
import androidx.compose.runtime.Immutable
/**
* Rounding mode of the [DraggableItem]
*
* @property isShowGap if true then item should have padding on rounded side
* */
@Immutable
internal sealed class RoundingModeUM {
abstract val isShowGap: Boolean
/**
* In this mode, item is not rounded
* */
object None : RoundingModeUM() {
override val isShowGap: Boolean = false
}
/**
* In this mode, item should have a rounded top side
*
* @property isShowGap if true then item should have top padding
* */
data class Top(override val isShowGap: Boolean = false) : RoundingModeUM()
/**
* In this mode, item should have a rounded bottom side
*
* @property isShowGap if true then item should have bottom padding
* */
data class Bottom(override val isShowGap: Boolean = false) : RoundingModeUM()
/**
* In this mode, item should have a rounded all sides
*
* @property isShowGap if true then item should have top and bottom padding
* */
data class All(override val isShowGap: Boolean = false) : RoundingModeUM()
}

View file

@ -9,7 +9,10 @@ import com.tangem.feature.wallet.child.organizetokens.entity.OrganizeTokensListU
internal class CryptoCurrenciesIdsResolver {
fun resolve(tokensListUM: OrganizeTokensListUM, accountStatusList: AccountStatusList?): AccountCryptoCurrencies {
fun resolveLegacy(
tokensListUM: OrganizeTokensListUM,
accountStatusList: AccountStatusList?,
): AccountCryptoCurrencies {
if (accountStatusList == null) return emptyMap()
val draggableTokens = when (tokensListUM) {

View file

@ -1,5 +1,6 @@
package com.tangem.feature.wallet.child.organizetokens.model
import androidx.compose.runtime.Stable
import com.tangem.feature.wallet.child.organizetokens.entity.DraggableItem
import org.burnoutcrew.reorderable.ItemPosition
@ -16,13 +17,14 @@ internal interface OrganizeTokensIntents {
fun onCancelClick()
}
@Stable
internal interface DragAndDropIntents {
fun onItemDragged(from: ItemPosition, to: ItemPosition)
fun canDragItemOver(dragOver: ItemPosition, dragging: ItemPosition): Boolean
fun onItemDraggingStart(item: DraggableItem)
fun onItemDraggingStartLegacy(item: DraggableItem)
fun onItemDraggingEnd()
}

View file

@ -18,10 +18,10 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.models.TokensSortType
import com.tangem.feature.wallet.child.organizetokens.OrganizeTokensComponent
import com.tangem.feature.wallet.child.organizetokens.OrganizeTokensComponentLegacy
import com.tangem.feature.wallet.child.organizetokens.analytics.PortfolioOrganizeTokensAnalyticsEvent
import com.tangem.feature.wallet.child.organizetokens.entity.OrganizeTokensState
import com.tangem.feature.wallet.child.organizetokens.model.dnd.DragAndDropAdapter
import com.tangem.feature.wallet.child.organizetokens.model.dnd.DragAndDropAdapterLegacy
import com.tangem.utils.Provider
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.*
@ -31,7 +31,7 @@ import javax.inject.Inject
@Suppress("LongParameterList")
@Stable
@ModelScoped
internal class OrganizeTokensModel @Inject constructor(
internal class OrganizeTokensModelLegacy @Inject constructor(
paramsContainer: ParamsContainer,
getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
override val dispatchers: CoroutineDispatcherProvider,
@ -48,17 +48,18 @@ internal class OrganizeTokensModel @Inject constructor(
private var isBalanceHidden = true
private val dragAndDropAdapter = DragAndDropAdapter(
@Suppress("PropertyUsedBeforeDeclaration")
private val dragAndDropAdapterLegacy = DragAndDropAdapterLegacy(
tokenListUMProvider = Provider { uiState.value.tokenListUM },
)
private val stateHolder = OrganizeTokensStateHolder(
intents = this,
dragAndDropAdapter = dragAndDropAdapter,
dragAndDropAdapterLegacy = dragAndDropAdapterLegacy,
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
)
private val userWalletId = paramsContainer.require<OrganizeTokensComponent.Params>().userWalletId
private val userWalletId = paramsContainer.require<OrganizeTokensComponentLegacy.Params>().userWalletId
private var cachedAccountStatusList: AccountStatusList? = null
@ -72,8 +73,8 @@ internal class OrganizeTokensModel @Inject constructor(
analyticsEventsHandler.send(PortfolioOrganizeTokensAnalyticsEvent.ScreenOpened())
getBalanceHidingSettingsUseCase()
.onEach {
isBalanceHidden = it.isBalanceHidden
.onEach { balanceHidingSettings ->
isBalanceHidden = balanceHidingSettings.isBalanceHidden
stateHolder.updateHiddenState(isBalanceHidden)
}
.launchIn(modelScope)
@ -134,7 +135,7 @@ internal class OrganizeTokensModel @Inject constructor(
)
val result = applyTokenListSortingUseCase(
sortedTokensIdsByAccount = resolver.resolve(tokensListUM, cachedAccountStatusList),
sortedTokensIdsByAccount = resolver.resolveLegacy(tokensListUM, cachedAccountStatusList),
isGroupedByNetwork = isGroupedByNetwork,
isSortedByBalance = isSortedByBalance,
)
@ -173,7 +174,7 @@ internal class OrganizeTokensModel @Inject constructor(
}
private fun bootstrapDragAndDropUpdates() {
dragAndDropAdapter.dragAndDropUpdates
dragAndDropAdapterLegacy.dragAndDropUpdates
.distinctUntilChanged()
.onEach { (type, updatedListState) ->
disableSortingByBalanceIfListChanged(type)
@ -183,8 +184,8 @@ internal class OrganizeTokensModel @Inject constructor(
.launchIn(modelScope)
}
private fun disableSortingByBalanceIfListChanged(dragOperationType: DragAndDropAdapter.DragOperation.Type) {
if (dragOperationType !is DragAndDropAdapter.DragOperation.Type.End) return
private fun disableSortingByBalanceIfListChanged(dragOperationType: DragAndDropAdapterLegacy.DragOperation.Type) {
if (dragOperationType !is DragAndDropAdapterLegacy.DragOperation.Type.End) return
if (uiState.value.header.isSortedByBalance && dragOperationType.isItemsOrderChanged) {
cachedAccountStatusList = cachedAccountStatusList?.copy(sortType = TokensSortType.NONE)

View file

@ -10,7 +10,7 @@ import com.tangem.feature.wallet.child.organizetokens.entity.OrganizeTokensState
import com.tangem.feature.wallet.child.organizetokens.model.converter.InProgressStateConverter
import com.tangem.feature.wallet.child.organizetokens.model.converter.TokenListToStateConverter
import com.tangem.feature.wallet.child.organizetokens.model.converter.error.TokenListSortingErrorConverter
import com.tangem.feature.wallet.child.organizetokens.model.dnd.DragAndDropAdapter
import com.tangem.feature.wallet.child.organizetokens.model.dnd.DragAndDropAdapterLegacy
import com.tangem.utils.Provider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@ -18,7 +18,7 @@ import kotlinx.coroutines.flow.update
internal class OrganizeTokensStateHolder(
private val intents: OrganizeTokensIntents,
private val dragAndDropAdapter: DragAndDropAdapter,
private val dragAndDropAdapterLegacy: DragAndDropAdapterLegacy,
private val appCurrencyProvider: Provider<AppCurrency>,
) {
@ -91,10 +91,10 @@ internal class OrganizeTokensStateHolder(
onCancelClick = intents::onCancelClick,
),
dndConfig = OrganizeTokensState.DragAndDropConfig(
onItemDragged = dragAndDropAdapter::onItemDragged,
onItemDragStart = dragAndDropAdapter::onItemDraggingStart,
onItemDragEnd = dragAndDropAdapter::onItemDraggingEnd,
canDragItemOver = dragAndDropAdapter::canDragItemOver,
onItemDragged = dragAndDropAdapterLegacy::onItemDragged,
onItemDragStart = dragAndDropAdapterLegacy::onItemDraggingStartLegacy,
onItemDragEnd = dragAndDropAdapterLegacy::onItemDraggingEnd,
canDragItemOver = dragAndDropAdapterLegacy::canDragItemOver,
),
scrollListToTop = consumedEvent(),
isBalanceHidden = true,

View file

@ -2,7 +2,7 @@ package com.tangem.feature.wallet.child.organizetokens.model.common
import com.tangem.feature.wallet.child.organizetokens.entity.DraggableItem
internal fun getGroupPlaceholder(index: Int, accountId: String = ""): DraggableItem.Placeholder {
internal fun getGroupPlaceholderLegacy(index: Int, accountId: String = ""): DraggableItem.Placeholder {
return DraggableItem.Placeholder(
id = "placeholder_${accountId}_${index.inc()}",
accountId = accountId,

View file

@ -1,8 +1,9 @@
package com.tangem.feature.wallet.child.organizetokens.model.common
import com.tangem.feature.wallet.child.organizetokens.entity.DraggableItem
import com.tangem.feature.wallet.child.organizetokens.entity.RoundingModeUM
internal fun List<DraggableItem>.uniteItems(isAccountsMode: Boolean): List<DraggableItem> {
internal fun List<DraggableItem>.uniteItemsLegacy(isAccountsMode: Boolean): List<DraggableItem> {
val items = this
val lastItemIndex = items.lastIndex
@ -11,30 +12,30 @@ internal fun List<DraggableItem>.uniteItems(isAccountsMode: Boolean): List<Dragg
.mapIndexed { index, item ->
val mode = when (index) {
0 -> if (item is DraggableItem.Placeholder) {
DraggableItem.RoundingMode.None
RoundingModeUM.None
} else {
DraggableItem.RoundingMode.Top()
RoundingModeUM.Top()
}
lastItemIndex -> DraggableItem.RoundingMode.Bottom()
lastItemIndex -> RoundingModeUM.Bottom()
1 -> if (items.first() is DraggableItem.Placeholder) {
DraggableItem.RoundingMode.Top()
RoundingModeUM.Top()
} else {
DraggableItem.RoundingMode.None
RoundingModeUM.None
}
else -> when (item) {
is DraggableItem.Placeholder -> DraggableItem.RoundingMode.None
is DraggableItem.Placeholder -> RoundingModeUM.None
is DraggableItem.GroupHeader -> if (isAccountsMode) {
DraggableItem.RoundingMode.None
RoundingModeUM.None
} else {
DraggableItem.RoundingMode.Top(showGap = true)
RoundingModeUM.Top(isShowGap = true)
}
is DraggableItem.Token -> applyRoundingModeToToken(
is DraggableItem.Token -> applyRoundingModeToTokenLegacy(
isAccountsMode = isAccountsMode,
items = items,
index = index,
lastItemIndex = lastItemIndex,
)
is DraggableItem.Portfolio -> DraggableItem.RoundingMode.Top(showGap = true)
is DraggableItem.Portfolio -> RoundingModeUM.Top(isShowGap = true)
}
}
@ -53,7 +54,7 @@ internal fun List<DraggableItem>.divideMovingItem(movingItem: DraggableItem): Li
if (item.id == movingItem.id) {
val dividedItem = movingItem
.updateRoundingMode(DraggableItem.RoundingMode.All())
.updateRoundingMode(RoundingModeUM.All())
.updateShadowVisibility(show = true)
listIterator.set(dividedItem)
@ -94,7 +95,7 @@ internal fun List<DraggableItem>.divideMovingItem(movingItem: DraggableItem): Li
* * TOKEN <- add rounding
* * PLACEHOLDER index + 1 is PLACEHOLDER
*/
private fun applyRoundingModeToToken(
private fun applyRoundingModeToTokenLegacy(
isAccountsMode: Boolean,
items: List<DraggableItem>,
index: Int,
@ -103,10 +104,10 @@ private fun applyRoundingModeToToken(
isAccountsMode && index + 1 < lastItemIndex &&
(items[index + 1] is DraggableItem.Portfolio ||
items[index + 1] is DraggableItem.Placeholder && items[index + 2] is DraggableItem.Portfolio) -> {
DraggableItem.RoundingMode.Bottom(showGap = true)
RoundingModeUM.Bottom(isShowGap = true)
}
(!isAccountsMode || index + 1 == lastItemIndex) && items[index + 1] is DraggableItem.Placeholder -> {
DraggableItem.RoundingMode.Bottom(showGap = true)
RoundingModeUM.Bottom(isShowGap = true)
}
else -> DraggableItem.RoundingMode.None
else -> RoundingModeUM.None
}

View file

@ -1,12 +0,0 @@
package com.tangem.feature.wallet.child.organizetokens.model.common
import com.tangem.domain.models.TokensSortType
import com.tangem.domain.models.tokenlist.TokenList
internal fun TokenList.disableSortingByBalance(): TokenList {
return when (this) {
is TokenList.GroupedByNetwork -> this.copy(sortedBy = TokensSortType.NONE)
is TokenList.Ungrouped -> this.copy(sortedBy = TokensSortType.NONE)
is TokenList.Empty -> this
}
}

View file

@ -11,8 +11,8 @@ import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.feature.wallet.child.organizetokens.entity.DraggableItem
import com.tangem.feature.wallet.child.organizetokens.entity.OrganizeTokensListUM
import com.tangem.feature.wallet.child.organizetokens.entity.OrganizeTokensState
import com.tangem.feature.wallet.child.organizetokens.model.common.getGroupPlaceholder
import com.tangem.feature.wallet.child.organizetokens.model.common.uniteItems
import com.tangem.feature.wallet.child.organizetokens.model.common.getGroupPlaceholderLegacy
import com.tangem.feature.wallet.child.organizetokens.model.common.uniteItemsLegacy
import com.tangem.feature.wallet.child.organizetokens.model.converter.items.OrganizedTokenListConverter
import com.tangem.utils.converter.Converter
import com.tangem.utils.transformer.Transformer
@ -74,7 +74,12 @@ internal class AccountTokenItemConverter(
),
)
if (isGrouping) {
add(getGroupPlaceholder(accountId = accountStatus.accountId.value, index = -1))
add(
getGroupPlaceholderLegacy(
accountId = accountStatus.accountId.value,
index = -1,
),
)
}
addAll(organizedTokenListConverter.convert(accountStatus))
}
@ -82,17 +87,17 @@ internal class AccountTokenItemConverter(
emptyList()
}
}.toList()
.uniteItems(true).toPersistentList(),
.uniteItemsLegacy(true).toPersistentList(),
)
} else {
OrganizeTokensListUM.TokensList(
isGrouped = isGrouping,
items = buildList {
if (isGrouping) {
add(getGroupPlaceholder(accountId = value.mainAccount.accountId.value, index = -1))
add(getGroupPlaceholderLegacy(accountId = value.mainAccount.accountId.value, index = -1))
}
addAll(organizedTokenListConverter.convert(value.mainAccount))
}.uniteItems(false)
}.uniteItemsLegacy(false)
.toPersistentList(),
)
}

View file

@ -1,17 +0,0 @@
package com.tangem.feature.wallet.child.organizetokens.model.converter.error
import com.tangem.domain.tokens.error.TokenListError
import com.tangem.feature.wallet.child.organizetokens.entity.OrganizeTokensState
import com.tangem.feature.wallet.child.organizetokens.model.converter.InProgressStateConverter
import com.tangem.utils.Provider
import com.tangem.utils.converter.Converter
internal class TokenListErrorConverter(
private val currentState: Provider<OrganizeTokensState>,
private val inProgressStateConverter: InProgressStateConverter,
) : Converter<TokenListError, OrganizeTokensState> {
override fun convert(value: TokenListError): OrganizeTokensState {
return inProgressStateConverter.convertBack(currentState())
}
}

View file

@ -6,7 +6,7 @@ import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.tokenlist.TokenList.GroupedByNetwork.NetworkGroup
import com.tangem.feature.wallet.child.organizetokens.entity.DraggableItem
import com.tangem.feature.wallet.child.organizetokens.model.common.getGroupHeaderId
import com.tangem.feature.wallet.child.organizetokens.model.common.getGroupPlaceholder
import com.tangem.feature.wallet.child.organizetokens.model.common.getGroupPlaceholderLegacy
import com.tangem.utils.converter.Converter
internal class NetworkGroupToDraggableItemsConverter(
@ -28,7 +28,7 @@ internal class NetworkGroupToDraggableItemsConverter(
convert(pair).toMutableList()
.also { mutableGroup ->
mutableGroup.add(
getGroupPlaceholder(accountId = pair.first.accountId.value, index = index),
getGroupPlaceholderLegacy(accountId = pair.first.accountId.value, index = index),
)
}
}

View file

@ -4,7 +4,7 @@ import com.tangem.feature.wallet.child.organizetokens.entity.DraggableItem
import com.tangem.feature.wallet.child.organizetokens.entity.OrganizeTokensListUM
import com.tangem.feature.wallet.child.organizetokens.model.DragAndDropIntents
import com.tangem.feature.wallet.child.organizetokens.model.common.divideMovingItem
import com.tangem.feature.wallet.child.organizetokens.model.common.uniteItems
import com.tangem.feature.wallet.child.organizetokens.model.common.uniteItemsLegacy
import com.tangem.feature.wallet.child.organizetokens.model.common.updateItems
import com.tangem.utils.Provider
import kotlinx.collections.immutable.mutate
@ -13,7 +13,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.filterNotNull
import org.burnoutcrew.reorderable.ItemPosition
internal class DragAndDropAdapter(
internal class DragAndDropAdapterLegacy(
private val tokenListUMProvider: Provider<OrganizeTokensListUM>,
) : DragAndDropIntents {
@ -72,7 +72,7 @@ internal class DragAndDropAdapter(
return canDrag
}
override fun onItemDraggingStart(item: DraggableItem) {
override fun onItemDraggingStartLegacy(item: DraggableItem) {
if (draggingItem != null) return
draggingItem = item
@ -81,7 +81,7 @@ internal class DragAndDropAdapter(
is DraggableItem.Placeholder,
is DraggableItem.Portfolio,
-> items
is DraggableItem.GroupHeader -> draggableGroupsOperations.collapseGroup(items, item)
is DraggableItem.GroupHeader -> draggableGroupsOperations.collapseGroupLegacy(items, item)
.divideMovingItem(item)
is DraggableItem.Token -> items.divideMovingItem(item)
}
@ -96,11 +96,11 @@ internal class DragAndDropAdapter(
updateListState(DragOperation.Type.End(isItemsOrderChanged = checkIsItemsOrderChanged())) {
when (draggingItem) {
is DraggableItem.GroupHeader -> {
draggableGroupsOperations.expandGroups(items)
.uniteItems(tokenListUM is OrganizeTokensListUM.AccountList)
draggableGroupsOperations.expandGroupsLegacy(items)
.uniteItemsLegacy(tokenListUM is OrganizeTokensListUM.AccountList)
}
is DraggableItem.Token -> {
items.uniteItems(tokenListUM is OrganizeTokensListUM.AccountList)
items.uniteItemsLegacy(tokenListUM is OrganizeTokensListUM.AccountList)
}
is DraggableItem.Placeholder,
is DraggableItem.Portfolio,

View file

@ -2,16 +2,16 @@ package com.tangem.feature.wallet.child.organizetokens.model.dnd
import com.tangem.feature.wallet.child.organizetokens.entity.DraggableItem
import com.tangem.feature.wallet.child.organizetokens.model.common.divideMovingItem
import com.tangem.feature.wallet.child.organizetokens.model.common.getGroupPlaceholder
import com.tangem.feature.wallet.child.organizetokens.model.common.getGroupPlaceholderLegacy
internal class DraggableGroupsOperations {
private var groupIdToTokens: Map<Int, List<DraggableItem.Token>>? = null
private var groupIdToTokensLegacy: Map<Int, List<DraggableItem.Token>>? = null
fun collapseGroup(items: List<DraggableItem>, movingGroup: DraggableItem.GroupHeader): List<DraggableItem> {
if (!groupIdToTokens.isNullOrEmpty()) return items
fun collapseGroupLegacy(items: List<DraggableItem>, movingGroup: DraggableItem.GroupHeader): List<DraggableItem> {
if (!groupIdToTokensLegacy.isNullOrEmpty()) return items
groupIdToTokens = items
groupIdToTokensLegacy = items
.asSequence()
.filterIsInstance<DraggableItem.Token>()
.groupBy { it.groupId }
@ -23,8 +23,8 @@ internal class DraggableGroupsOperations {
return itemsWithoutGroupTokens.divideMovingItem(movingGroup)
}
fun expandGroups(items: List<DraggableItem>): List<DraggableItem> {
if (groupIdToTokens.isNullOrEmpty()) return items
fun expandGroupsLegacy(items: List<DraggableItem>): List<DraggableItem> {
if (groupIdToTokensLegacy.isNullOrEmpty()) return items
val accountList = items.filterIsInstance<DraggableItem.Portfolio>()
val currentGroups = items.filterIsInstance<DraggableItem.GroupHeader>()
@ -40,11 +40,11 @@ internal class DraggableGroupsOperations {
.filter { it.accountId == account.id }
.forEachIndexed { index, group ->
if (index == 0) {
add(getGroupPlaceholder(accountId = group.accountId, index = -1))
add(getGroupPlaceholderLegacy(accountId = group.accountId, index = -1))
}
add(group)
addAll(groupIdToTokens?.get(group.id).orEmpty())
add(getGroupPlaceholder(accountId = group.accountId, index = index))
addAll(groupIdToTokensLegacy?.get(group.id).orEmpty())
add(getGroupPlaceholderLegacy(accountId = group.accountId, index = index))
}
}
}
@ -54,16 +54,16 @@ internal class DraggableGroupsOperations {
.flatMapIndexed { index, group ->
buildList {
if (index == 0) {
add(getGroupPlaceholder(accountId = group.accountId, index = -1))
add(getGroupPlaceholderLegacy(accountId = group.accountId, index = -1))
}
add(group)
addAll(groupIdToTokens?.get(group.id).orEmpty())
add(getGroupPlaceholder(accountId = group.accountId, index = index))
addAll(groupIdToTokensLegacy?.get(group.id).orEmpty())
add(getGroupPlaceholderLegacy(accountId = group.accountId, index = index))
}
}
}.toList()
groupIdToTokens = null
groupIdToTokensLegacy = null
return expandedGroups
}

View file

@ -47,7 +47,8 @@ import com.tangem.core.ui.utils.lazyListItemPosition
import com.tangem.feature.wallet.child.organizetokens.entity.DraggableItem
import com.tangem.feature.wallet.child.organizetokens.entity.OrganizeTokensListUM
import com.tangem.feature.wallet.child.organizetokens.entity.OrganizeTokensState
import com.tangem.feature.wallet.child.organizetokens.ui.preview.OrganizeTokensPreview
import com.tangem.feature.wallet.child.organizetokens.entity.RoundingModeUM
import com.tangem.feature.wallet.child.organizetokens.ui.preview.OrganizeTokensPreviewLegacy
import com.tangem.feature.wallet.impl.R
import org.burnoutcrew.reorderable.ReorderableLazyListState
import org.burnoutcrew.reorderable.rememberReorderableLazyListState
@ -181,7 +182,7 @@ private fun LazyItemScope.DraggableItem(
mutableStateOf(value = false)
}
val itemModifier = Modifier.applyShapeAndShadow(item.roundingMode, item.showShadow)
val itemModifier = Modifier.applyShapeAndShadow(item.roundingModeUM, item.showShadow)
ReorderableItem(
reorderableState = reorderableState,
@ -335,14 +336,14 @@ private fun Actions(config: OrganizeTokensState.ActionsConfig, modifier: Modifie
}
}
private fun Modifier.applyShapeAndShadow(roundingMode: DraggableItem.RoundingMode, showShadow: Boolean): Modifier {
private fun Modifier.applyShapeAndShadow(roundingMode: RoundingModeUM, showShadow: Boolean): Modifier {
return composed {
val radius by animateDpAsState(
targetValue = when (roundingMode) {
is DraggableItem.RoundingMode.None -> TangemTheme.dimens.radius0
is DraggableItem.RoundingMode.All -> TangemTheme.dimens.radius12
is DraggableItem.RoundingMode.Bottom,
is DraggableItem.RoundingMode.Top,
is RoundingModeUM.None -> TangemTheme.dimens.radius0
is RoundingModeUM.All -> TangemTheme.dimens.radius12
is RoundingModeUM.Bottom,
is RoundingModeUM.Top,
-> TangemTheme.dimens.radius16
},
label = "item_shape_radius",
@ -368,15 +369,15 @@ private fun Modifier.applyShapeAndShadow(roundingMode: DraggableItem.RoundingMod
@Composable
@ReadOnlyComposable
private fun getItemGap(roundingMode: DraggableItem.RoundingMode): PaddingValues {
private fun getItemGap(roundingMode: RoundingModeUM): PaddingValues {
val paddingValue = TangemTheme.dimens.spacing4
return if (roundingMode.showGap) {
return if (roundingMode.isShowGap) {
when (roundingMode) {
is DraggableItem.RoundingMode.None -> PaddingValues(all = 0.dp)
is DraggableItem.RoundingMode.All -> PaddingValues(vertical = paddingValue)
is DraggableItem.RoundingMode.Top -> PaddingValues(top = paddingValue)
is DraggableItem.RoundingMode.Bottom -> PaddingValues(bottom = paddingValue)
is RoundingModeUM.None -> PaddingValues(all = 0.dp)
is RoundingModeUM.All -> PaddingValues(vertical = paddingValue)
is RoundingModeUM.Top -> PaddingValues(top = paddingValue)
is RoundingModeUM.Bottom -> PaddingValues(bottom = paddingValue)
}
} else {
PaddingValues(all = 0.dp)
@ -384,18 +385,18 @@ private fun getItemGap(roundingMode: DraggableItem.RoundingMode): PaddingValues
}
@Stable
private fun getItemShape(roundingMode: DraggableItem.RoundingMode, radius: Dp): Shape {
private fun getItemShape(roundingMode: RoundingModeUM, radius: Dp): Shape {
return when (roundingMode) {
is DraggableItem.RoundingMode.None -> RectangleShape
is DraggableItem.RoundingMode.Top -> RoundedCornerShape(
is RoundingModeUM.None -> RectangleShape
is RoundingModeUM.Top -> RoundedCornerShape(
topStart = radius,
topEnd = radius,
)
is DraggableItem.RoundingMode.Bottom -> RoundedCornerShape(
is RoundingModeUM.Bottom -> RoundedCornerShape(
bottomStart = radius,
bottomEnd = radius,
)
is DraggableItem.RoundingMode.All -> RoundedCornerShape(
is RoundingModeUM.All -> RoundedCornerShape(
size = radius,
)
}
@ -416,8 +417,8 @@ private fun OrganizeTokensScreenPreview(
private class OrganizeTokensStateProvider : CollectionPreviewParameterProvider<OrganizeTokensState>(
collection = listOf(
OrganizeTokensPreview.stateAccounts,
OrganizeTokensPreview.state,
OrganizeTokensPreviewLegacy.stateAccounts,
OrganizeTokensPreviewLegacy.state,
),
)
// endregion Preview

View file

@ -8,12 +8,13 @@ import com.tangem.core.ui.res.TangemColorPalette
import com.tangem.feature.wallet.child.organizetokens.entity.DraggableItem
import com.tangem.feature.wallet.child.organizetokens.entity.OrganizeTokensListUM
import com.tangem.feature.wallet.child.organizetokens.entity.OrganizeTokensState
import com.tangem.feature.wallet.child.organizetokens.entity.RoundingModeUM
import com.tangem.feature.wallet.impl.R
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.toPersistentList
import java.util.UUID
internal object OrganizeTokensPreview {
internal object OrganizeTokensPreviewLegacy {
private const val networksSize = 10
private const val tokensSize = 3
@ -44,11 +45,10 @@ internal object OrganizeTokensPreview {
val group = DraggableItem.GroupHeader(
id = networkNumber,
networkName = "$networkNumber",
roundingMode = when (index) {
0 -> DraggableItem.RoundingMode.Top()
lastNetworkIndex -> DraggableItem.RoundingMode.Bottom()
else -> DraggableItem.RoundingMode.None
roundingModeUM = when (index) {
0 -> RoundingModeUM.Top()
lastNetworkIndex -> RoundingModeUM.Bottom()
else -> RoundingModeUM.None
},
accountId = "account_$networkNumber",
)
@ -66,9 +66,9 @@ internal object OrganizeTokensPreview {
),
groupId = group.id,
accountId = "account_$networkNumber",
roundingMode = when {
i == lastTokenIndex && index == lastNetworkIndex -> DraggableItem.RoundingMode.Bottom()
else -> DraggableItem.RoundingMode.None
roundingModeUM = when {
i == lastTokenIndex && index == lastNetworkIndex -> RoundingModeUM.Bottom()
else -> RoundingModeUM.None
},
),
)

View file

@ -2,7 +2,6 @@ package com.tangem.feature.wallet.di
import com.tangem.core.decompose.model.Model
import com.tangem.feature.wallet.DefaultWalletEntryComponent
import com.tangem.feature.wallet.child.organizetokens.model.OrganizeTokensModel
import com.tangem.feature.wallet.child.wallet.model.WalletModel
import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.KycRejectedModel
import com.tangem.feature.wallet.utils.DefaultUserWalletImageFetcher
@ -41,9 +40,4 @@ internal interface WalletFeatureModule {
@IntoMap
@ClassKey(KycRejectedModel::class)
fun bindKycRejectedModel(model: KycRejectedModel): Model
@Binds
@IntoMap
@ClassKey(OrganizeTokensModel::class)
fun bindOrganizeTokensModel(model: OrganizeTokensModel): Model
}