diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index ae7cbf8d96..7804c88500 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -308,10 +308,10 @@ Восстановление кода доступа Идентичные карты Код доступа - Группировка + Группы По балансу Сортировка токенов - Разгруппировать + Список %1$s %2$s адрес в сети %3$s %1$s (%2$s) в сети %3$s Участвовать diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensScreen.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensScreen.kt index b47d1fd500..63b4037673 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensScreen.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensScreen.kt @@ -244,7 +244,7 @@ private fun TopBar( iconResId = R.drawable.ic_sort_24, enabled = config.isEnabled, onClick = config.onSortClick, - dimContent = !config.isSortedByBalance, + dimContent = config.isSortedByBalance, ), modifier = Modifier.weight(1f), color = TangemTheme.colors.background.primary, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensStateHolder.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensStateHolder.kt index 25598c9983..b8d2dd73a2 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensStateHolder.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensStateHolder.kt @@ -73,12 +73,11 @@ internal class OrganizeTokensStateHolder( } fun updateStateWithManualSorting(itemsState: OrganizeTokensListState) { - updateState { - copy( - header = header.copy(isSortedByBalance = false), - itemsState = itemsState, - ) - } + updateState { copy(itemsState = itemsState) } + } + + fun disableSortingByBalance() { + updateState { copy(header = header.copy(isSortedByBalance = false)) } } fun updateStateWithError(error: TokenListError) { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensViewModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensViewModel.kt index 9fa199b6a1..5a1af707d2 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensViewModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensViewModel.kt @@ -77,11 +77,12 @@ internal class OrganizeTokensViewModel @Inject constructor( } override fun onSortClick() { + val list = tokenList ?: return + if (list.sortedBy == TokenList.SortType.BALANCE) return + analyticsEventsHandler.send(PortfolioOrganizeTokensAnalyticsEvent.ByBalance) viewModelScope.launch(dispatchers.default) { - val list = tokenList ?: return@launch - toggleTokenListSortingUseCase(list).fold( ifLeft = stateHolder::updateStateWithError, ifRight = { @@ -93,11 +94,11 @@ internal class OrganizeTokensViewModel @Inject constructor( } override fun onGroupClick() { + val list = tokenList ?: return + analyticsEventsHandler.send(PortfolioOrganizeTokensAnalyticsEvent.Group) viewModelScope.launch(dispatchers.default) { - val list = tokenList ?: return@launch - toggleTokenListGroupingUseCase(list).fold( ifLeft = stateHolder::updateStateWithError, ifRight = { @@ -166,13 +167,23 @@ internal class OrganizeTokensViewModel @Inject constructor( private fun bootstrapDragAndDropUpdates() { dragAndDropAdapter.dragAndDropUpdates .distinctUntilChanged() - .onEach { - stateHolder.updateStateWithManualSorting(it) - tokenList = tokenList?.disableSortingByBalance() + .onEach { (type, updatedListState) -> + disableSortingByBalanceIfListChanged(type) + + stateHolder.updateStateWithManualSorting(updatedListState) } .launchIn(viewModelScope) } + private fun disableSortingByBalanceIfListChanged(dragOperationType: DragAndDropAdapter.DragOperation.Type) { + if (dragOperationType !is DragAndDropAdapter.DragOperation.Type.End) return + + if (uiState.value.header.isSortedByBalance && dragOperationType.isItemsOrderChanged) { + tokenList = tokenList?.disableSortingByBalance() + stateHolder.disableSortingByBalance() + } + } + private fun createSelectedAppCurrencyFlow(): StateFlow { return getSelectedAppCurrencyUseCase() .map { maybeAppCurrency -> diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/utils/converter/InProgressStateConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/utils/converter/InProgressStateConverter.kt index 4c26e09a29..936385e8ea 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/utils/converter/InProgressStateConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/utils/converter/InProgressStateConverter.kt @@ -10,6 +10,9 @@ internal class InProgressStateConverter : TwoWayConverter = MutableSharedFlow( - replay = 1, - onBufferOverflow = BufferOverflow.DROP_OLDEST, - ) + private val dragAndDropUpdatesInternal: MutableStateFlow = MutableStateFlow(value = null) - private var currentDraggingItem: DraggableItem? = null + private var draggingItem: DraggableItem? = null + private var draggingListState: OrganizeTokensListState? = null - val dragAndDropUpdates: SharedFlow - get() = dragAndDropUpdatesInternal + val dragAndDropUpdates: Flow + get() = dragAndDropUpdatesInternal.filterNotNull() override fun canDragItemOver(dragOver: ItemPosition, dragging: ItemPosition): Boolean { - val items = when (val listState = currentListState) { + val items = when (val listState = externalListState) { is OrganizeTokensListState.GroupedByNetwork -> listState.items is OrganizeTokensListState.Empty, is OrganizeTokensListState.Ungrouped, @@ -58,10 +56,10 @@ internal class DragAndDropAdapter( } override fun onItemDraggingStart(item: DraggableItem) { - if (currentDraggingItem != null) return - currentDraggingItem = item + if (draggingItem != null) return + draggingItem = item - updateListState { + updateListState(DragOperation.Type.Start) { when (item) { is DraggableItem.Placeholder -> items is DraggableItem.GroupHeader -> draggableGroupsOperations.collapseGroup(items, item) @@ -72,12 +70,14 @@ internal class DragAndDropAdapter( } } } + + draggingListState = externalListState } override fun onItemDraggingEnd() { - val draggingItem = currentDraggingItem ?: return + val draggingItem = draggingItem ?: return - updateListState { + updateListState(DragOperation.Type.End(isItemsOrderChanged = checkIsItemsOrderChanged())) { when (draggingItem) { is DraggableItem.GroupHeader -> draggableGroupsOperations.expandGroups(items) is DraggableItem.Token -> items.uniteItems() @@ -85,19 +85,21 @@ internal class DragAndDropAdapter( } } - currentDraggingItem = null + this.draggingItem = null } - override fun onItemDragged(from: ItemPosition, to: ItemPosition) = updateListState { - items.mutate { - it.add(to.index, it.removeAt(from.index)) + override fun onItemDragged(from: ItemPosition, to: ItemPosition) { + updateListState(DragOperation.Type.Dragged) { + items.mutate { + it.add(to.index, it.removeAt(from.index)) + } } } - private fun updateListState(block: OrganizeTokensListState.() -> List) { - val updatedState = currentListState.updateItems { block(currentListState) } + private fun updateListState(type: DragOperation.Type, block: OrganizeTokensListState.() -> List) { + val updatedState = externalListState.updateItems { block(externalListState) } - dragAndDropUpdatesInternal.tryEmit(updatedState) + dragAndDropUpdatesInternal.value = DragOperation(type, updatedState) } private fun findItemsToMove( @@ -145,4 +147,31 @@ internal class DragAndDropAdapter( is DraggableItem.Placeholder -> false } } + + private fun checkIsItemsOrderChanged(): Boolean { + fun OrganizeTokensListState?.getItemsIds(): List? = this?.items?.mapNotNull { item -> + if (item is DraggableItem.Placeholder) { + null + } else { + item.id + } + } + + return externalListState.getItemsIds() != draggingListState.getItemsIds() + } + + data class DragOperation( + val type: Type, + val listState: OrganizeTokensListState, + ) { + + sealed class Type { + + object Start : Type() + + object Dragged : Type() + + data class End(val isItemsOrderChanged: Boolean) : Type() + } + } } \ No newline at end of file