From fcdeb9fe9ed2c0129577a7b7b9ed6d41951eb101 Mon Sep 17 00:00:00 2001 From: Rafael Muhamedzyanov Date: Mon, 15 Jan 2024 16:11:57 +0600 Subject: [PATCH] Add time periods to WatchList --- app/build.gradle | 2 +- .../bankwallet/core/Interfaces.kt | 7 +- .../core/managers/LocalStorageManager.kt | 23 ++-- .../bankwallet/modules/market/MarketModule.kt | 22 ++++ .../modules/market/MarketViewItem.kt | 16 +++ .../favorites/MarketFavoritesMenuService.kt | 15 ++- .../market/favorites/MarketFavoritesModule.kt | 25 ++-- .../favorites/MarketFavoritesRepository.kt | 44 +++---- .../market/favorites/MarketFavoritesScreen.kt | 58 +++++---- .../favorites/MarketFavoritesService.kt | 37 +++--- .../favorites/MarketFavoritesViewModel.kt | 49 +++----- .../bankwallet/widgets/MarketWidget.kt | 111 ++++-------------- .../widgets/MarketWidgetRepository.kt | 40 ++----- .../bankwallet/widgets/MarketWidgetState.kt | 4 +- 14 files changed, 190 insertions(+), 263 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b1b5b1f62cd..979586e9e4b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -280,7 +280,7 @@ dependencies { implementation 'com.github.horizontalsystems:ethereum-kit-android:3a02f3a' implementation 'com.github.horizontalsystems:blockchain-fee-rate-kit-android:1d3bd49' implementation 'com.github.horizontalsystems:binance-chain-kit-android:c1509a2' - implementation 'com.github.horizontalsystems:market-kit-android:1092d9d' + implementation 'com.github.horizontalsystems:market-kit-android:3de7e54' implementation 'com.github.horizontalsystems:solana-kit-android:34ef394' implementation 'com.github.horizontalsystems:tron-kit-android:5eb6395' // Zcash SDK diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/Interfaces.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/Interfaces.kt index 29dc5eba5a1..11dbdea7f26 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/core/Interfaces.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/Interfaces.kt @@ -26,10 +26,9 @@ import io.horizontalsystems.bankwallet.modules.amount.AmountInputType import io.horizontalsystems.bankwallet.modules.balance.BalanceSortType import io.horizontalsystems.bankwallet.modules.balance.BalanceViewType import io.horizontalsystems.bankwallet.modules.main.MainModule -import io.horizontalsystems.bankwallet.modules.market.MarketField import io.horizontalsystems.bankwallet.modules.market.MarketModule -import io.horizontalsystems.bankwallet.modules.market.SortingField import io.horizontalsystems.bankwallet.modules.market.Value +import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesModule.Period import io.horizontalsystems.bankwallet.modules.settings.appearance.AppIcon import io.horizontalsystems.bankwallet.modules.settings.security.autolock.AutoLockInterval import io.horizontalsystems.bankwallet.modules.settings.security.tor.TorStatus @@ -108,8 +107,8 @@ interface ILocalStorage { var launchPage: LaunchPage? var appIcon: AppIcon? var mainTab: MainModule.MainNavigation? - var marketFavoritesSortingField: SortingField? - var marketFavoritesMarketField: MarketField? + var marketFavoritesSortDescending: Boolean + var marketFavoritesPeriod: Period? var relaunchBySettingChange: Boolean var marketsTabEnabled: Boolean val marketsTabEnabledFlow: StateFlow diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/LocalStorageManager.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/LocalStorageManager.kt index 9289df33cc2..ad491f1abd6 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/LocalStorageManager.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/LocalStorageManager.kt @@ -14,9 +14,8 @@ import io.horizontalsystems.bankwallet.modules.amount.AmountInputType import io.horizontalsystems.bankwallet.modules.balance.BalanceSortType import io.horizontalsystems.bankwallet.modules.balance.BalanceViewType import io.horizontalsystems.bankwallet.modules.main.MainModule -import io.horizontalsystems.bankwallet.modules.market.MarketField import io.horizontalsystems.bankwallet.modules.market.MarketModule -import io.horizontalsystems.bankwallet.modules.market.SortingField +import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesModule.Period import io.horizontalsystems.bankwallet.modules.settings.appearance.AppIcon import io.horizontalsystems.bankwallet.modules.settings.security.autolock.AutoLockInterval import io.horizontalsystems.bankwallet.modules.theme.ThemeType @@ -70,8 +69,8 @@ class LocalStorageManager( private val LAUNCH_PAGE = "launch_page" private val APP_ICON = "app_icon" private val MAIN_TAB = "main_tab" - private val MARKET_FAVORITES_SORTING_FIELD = "market_favorites_sorting_field" - private val MARKET_FAVORITES_MARKET_FIELD = "market_favorites_market_field" + private val MARKET_FAVORITES_SORT_DESCENDING = "market_favorites_sort_descending" + private val MARKET_FAVORITES_TIME_DURATION = "market_favorites_time_duration" private val RELAUNCH_BY_SETTING_CHANGE = "relaunch_by_setting_change" private val MARKETS_TAB_ENABLED = "markets_tab_enabled" private val BALANCE_AUTO_HIDE_ENABLED = "balance_auto_hide_enabled" @@ -429,20 +428,18 @@ class LocalStorageManager( preferences.edit().putString(MAIN_TAB, value?.name).apply() } - override var marketFavoritesSortingField: SortingField? - get() = preferences.getString(MARKET_FAVORITES_SORTING_FIELD, null)?.let { - SortingField.fromString(it) - } + override var marketFavoritesSortDescending: Boolean + get() = preferences.getBoolean(MARKET_FAVORITES_SORT_DESCENDING, true) set(value) { - preferences.edit().putString(MARKET_FAVORITES_SORTING_FIELD, value?.name).apply() + preferences.edit().putBoolean(MARKET_FAVORITES_SORT_DESCENDING, value).apply() } - override var marketFavoritesMarketField: MarketField? - get() = preferences.getString(MARKET_FAVORITES_MARKET_FIELD, null)?.let { - MarketField.fromString(it) + override var marketFavoritesPeriod: Period? + get() = preferences.getString(MARKET_FAVORITES_TIME_DURATION, null)?.let { + Period.valueOf(it) } set(value) { - preferences.edit().putString(MARKET_FAVORITES_MARKET_FIELD, value?.name).apply() + preferences.edit().putString(MARKET_FAVORITES_TIME_DURATION, value?.name).apply() } override var relaunchBySettingChange: Boolean diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/MarketModule.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/MarketModule.kt index 91f42101c66..c3b22a8156c 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/MarketModule.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/MarketModule.kt @@ -13,6 +13,7 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.App import io.horizontalsystems.bankwallet.entities.Currency import io.horizontalsystems.bankwallet.entities.CurrencyValue +import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesModule.Period import io.horizontalsystems.bankwallet.modules.market.filters.TimePeriod import io.horizontalsystems.bankwallet.ui.compose.TranslatableString import io.horizontalsystems.bankwallet.ui.compose.WithTranslatableTitle @@ -67,6 +68,21 @@ data class MarketItem( val rank: Int? ) { companion object { + fun createFromCoinMarket( + marketInfo: MarketInfo, + currency: Currency, + period: Period, + ): MarketItem { + return MarketItem( + fullCoin = marketInfo.fullCoin, + volume = CurrencyValue(currency, marketInfo.totalVolume ?: BigDecimal.ZERO), + rate = CurrencyValue(currency, marketInfo.price ?: BigDecimal.ZERO), + diff = marketInfo.priceChangeValue(period), + marketCap = CurrencyValue(currency, marketInfo.marketCap ?: BigDecimal.ZERO), + rank = marketInfo.marketCapRank + ) + } + fun createFromCoinMarket( marketInfo: MarketInfo, currency: Currency, @@ -183,6 +199,12 @@ fun MarketInfo.priceChangeValue(period: TimePeriod) = when (period) { TimePeriod.TimePeriod_1Y -> priceChange1y } +fun MarketInfo.priceChangeValue(period: Period) = when (period) { + Period.OneDay -> priceChange24h + Period.SevenDay -> priceChange7d + Period.ThirtyDay -> priceChange30d +} + @Parcelize enum class TimeDuration(val titleResId: Int) : WithTranslatableTitle, Parcelable { OneDay(R.string.CoinPage_TimeDuration_Day), diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/MarketViewItem.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/MarketViewItem.kt index d40dc5a9e72..13af267b330 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/MarketViewItem.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/MarketViewItem.kt @@ -39,6 +39,22 @@ data class MarketViewItem( } companion object { + fun create( + marketItem: MarketItem, + favorited: Boolean = false + ): MarketViewItem { + return MarketViewItem( + marketItem.fullCoin, + App.numberFormatter.formatFiatFull( + marketItem.rate.value, + marketItem.rate.currency.symbol + ), + MarketDataValue.Diff(marketItem.diff), + marketItem.rank?.toString(), + favorited + ) + } + fun create( marketItem: MarketItem, marketField: MarketField, diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesMenuService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesMenuService.kt index 4436bb5e92c..5e677e4c08c 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesMenuService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesMenuService.kt @@ -1,8 +1,7 @@ package io.horizontalsystems.bankwallet.modules.market.favorites import io.horizontalsystems.bankwallet.core.ILocalStorage -import io.horizontalsystems.bankwallet.modules.market.MarketField -import io.horizontalsystems.bankwallet.modules.market.SortingField +import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesModule.Period import io.horizontalsystems.bankwallet.widgets.MarketWidgetManager class MarketFavoritesMenuService( @@ -10,17 +9,17 @@ class MarketFavoritesMenuService( private val marketWidgetManager: MarketWidgetManager ) { - var sortingField: SortingField - get() = localStorage.marketFavoritesSortingField ?: SortingField.HighestCap + var sortDescending: Boolean + get() = localStorage.marketFavoritesSortDescending set(value) { - localStorage.marketFavoritesSortingField = value + localStorage.marketFavoritesSortDescending = value marketWidgetManager.updateWatchListWidgets() } - var marketField: MarketField - get() = localStorage.marketFavoritesMarketField ?: MarketField.PriceDiff + var period: Period + get() = localStorage.marketFavoritesPeriod ?: Period.OneDay set(value) { - localStorage.marketFavoritesMarketField = value + localStorage.marketFavoritesPeriod = value marketWidgetManager.updateWatchListWidgets() } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesModule.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesModule.kt index 6dd54797693..39e58cafcc7 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesModule.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesModule.kt @@ -1,12 +1,16 @@ package io.horizontalsystems.bankwallet.modules.market.favorites +import android.os.Parcelable import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.App -import io.horizontalsystems.bankwallet.modules.market.MarketField import io.horizontalsystems.bankwallet.modules.market.MarketViewItem -import io.horizontalsystems.bankwallet.modules.market.SortingField import io.horizontalsystems.bankwallet.ui.compose.Select +import io.horizontalsystems.bankwallet.ui.compose.TranslatableString +import io.horizontalsystems.bankwallet.ui.compose.WithTranslatableTitle +import kotlinx.parcelize.IgnoredOnParcel +import kotlinx.parcelize.Parcelize import javax.annotation.concurrent.Immutable object MarketFavoritesModule { @@ -17,19 +21,24 @@ object MarketFavoritesModule { val repository = MarketFavoritesRepository(App.marketKit, App.marketFavoritesManager) val menuService = MarketFavoritesMenuService(App.localStorage, App.marketWidgetManager) val service = MarketFavoritesService(repository, menuService, App.currencyManager, App.backgroundManager) - return MarketFavoritesViewModel(service, menuService) as T + return MarketFavoritesViewModel(service) as T } } @Immutable data class ViewItem( - val sortingFieldSelect: Select, - val marketFieldSelect: Select, + val sortingDescending: Boolean, + val periodSelect: Select, val marketItems: List ) - sealed class SelectorDialogState { - object Closed : SelectorDialogState() - class Opened(val select: Select) : SelectorDialogState() + @Parcelize + enum class Period(val titleResId: Int) : WithTranslatableTitle, Parcelable { + OneDay(R.string.CoinPage_TimeDuration_Day), + SevenDay(R.string.CoinPage_TimeDuration_Week), + ThirtyDay(R.string.CoinPage_TimeDuration_Month); + + @IgnoredOnParcel + override val title = TranslatableString.ResString(titleResId) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesRepository.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesRepository.kt index c3e3dc659ea..7dd549a4908 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesRepository.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesRepository.kt @@ -5,6 +5,7 @@ import io.horizontalsystems.bankwallet.core.managers.MarketKitWrapper import io.horizontalsystems.bankwallet.entities.Currency import io.horizontalsystems.bankwallet.modules.market.MarketItem import io.horizontalsystems.bankwallet.modules.market.SortingField +import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesModule.Period import io.horizontalsystems.bankwallet.modules.market.sort import io.reactivex.Single @@ -12,38 +13,37 @@ class MarketFavoritesRepository( private val marketKit: MarketKitWrapper, private val manager: MarketFavoritesManager ) { - private var cache: List = listOf() - val dataUpdatedObservable by manager::dataUpdatedAsync private fun getFavorites( - forceRefresh: Boolean, - currency: Currency - ): List = - if (forceRefresh) { - val favoriteCoins = manager.getAll() - var marketItems = listOf() - if (favoriteCoins.isNotEmpty()) { - val favoriteCoinUids = favoriteCoins.map { it.coinUid } - marketItems = marketKit.marketInfosSingle(favoriteCoinUids, currency.code, "watchlist").blockingGet() - .map { marketInfo -> - MarketItem.createFromCoinMarket(marketInfo, currency) - } - } - cache = marketItems - marketItems - } else { - cache + currency: Currency, + period: Period + ): List { + val favoriteCoins = manager.getAll() + var marketItems = listOf() + if (favoriteCoins.isNotEmpty()) { + val favoriteCoinUids = favoriteCoins.map { it.coinUid } + marketItems = marketKit.marketInfosSingle(favoriteCoinUids, currency.code, "watchlist").blockingGet() + .map { marketInfo -> + MarketItem.createFromCoinMarket( + marketInfo = marketInfo, + currency = currency, + period = period + ) + } } + return marketItems + } fun get( - sortingField: SortingField, + sortDescending: Boolean, + period: Period, currency: Currency, - forceRefresh: Boolean ): Single> = Single.create { emitter -> + val sortingField = if (sortDescending) SortingField.TopGainers else SortingField.TopLosers try { - val marketItems = getFavorites(forceRefresh, currency) + val marketItems = getFavorites(currency, period) emitter.onSuccess( marketItems.sort(sortingField) ) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesScreen.kt index ae0ed52c2ba..f4732578b12 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesScreen.kt @@ -21,12 +21,16 @@ import io.horizontalsystems.bankwallet.core.slideFromRight import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.coin.CoinFragment import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Loading -import io.horizontalsystems.bankwallet.modules.market.MarketField -import io.horizontalsystems.bankwallet.modules.market.SortingField +import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesModule.Period import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.HSSwipeRefresh import io.horizontalsystems.bankwallet.ui.compose.Select -import io.horizontalsystems.bankwallet.ui.compose.components.* +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryCircle +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryToggle +import io.horizontalsystems.bankwallet.ui.compose.components.CoinList +import io.horizontalsystems.bankwallet.ui.compose.components.HeaderSorting +import io.horizontalsystems.bankwallet.ui.compose.components.ListEmptyView +import io.horizontalsystems.bankwallet.ui.compose.components.ListErrorView @OptIn(ExperimentalFoundationApi::class) @Composable @@ -37,7 +41,6 @@ fun MarketFavoritesScreen( val viewState by viewModel.viewStateLiveData.observeAsState() val isRefreshing by viewModel.isRefreshingLiveData.observeAsState(false) val marketFavoritesData by viewModel.viewItemLiveData.observeAsState() - val sortingFieldDialogState by viewModel.sortingFieldSelectorStateLiveData.observeAsState() var scrollToTopAfterUpdate by rememberSaveable { mutableStateOf(false) } HSSwipeRefresh( @@ -48,15 +51,18 @@ fun MarketFavoritesScreen( ) { Crossfade( targetState = viewState, - modifier = Modifier.background(color = ComposeAppTheme.colors.tyler) + modifier = Modifier.background(color = ComposeAppTheme.colors.tyler), + label = "" ) { viewState -> when (viewState) { ViewState.Loading -> { Loading() } + is ViewState.Error -> { ListErrorView(stringResource(R.string.SyncError), viewModel::onErrorClick) } + ViewState.Success -> { marketFavoritesData?.let { data -> if (data.marketItems.isEmpty()) { @@ -77,10 +83,10 @@ fun MarketFavoritesScreen( preItems = { stickyHeader { MarketFavoritesMenu( - data.sortingFieldSelect, - data.marketFieldSelect, - viewModel::onClickSortingField, - viewModel::onSelectMarketField + sortDescending = data.sortingDescending, + periodSelect = data.periodSelect, + onSortingToggle = viewModel::onSortToggle, + onSelectPeriod = viewModel::onSelectTimeDuration ) } } @@ -91,44 +97,34 @@ fun MarketFavoritesScreen( } } } + null -> {} } } } - when (val option = sortingFieldDialogState) { - is MarketFavoritesModule.SelectorDialogState.Opened -> { - AlertGroup( - R.string.Market_Sort_PopupTitle, - option.select, - { selected -> - scrollToTopAfterUpdate = true - viewModel.onSelectSortingField(selected) - }, - { viewModel.onSortingFieldDialogDismiss() } - ) - } - MarketFavoritesModule.SelectorDialogState.Closed, - null -> {} - } } @Composable fun MarketFavoritesMenu( - sortingFieldSelect: Select, - marketFieldSelect: Select, - onClickSortingField: () -> Unit, - onSelectMarketField: (MarketField) -> Unit + sortDescending: Boolean, + periodSelect: Select, + onSortingToggle: () -> Unit, + onSelectPeriod: (Period) -> Unit ) { HeaderSorting(borderTop = true, borderBottom = true) { Box(modifier = Modifier.weight(1f)) { - SortMenu(sortingFieldSelect.selected.title, onClickSortingField) + ButtonSecondaryCircle( + modifier = Modifier.padding(start = 16.dp), + icon = if (sortDescending) R.drawable.ic_sort_h2l_20 else R.drawable.ic_sort_l2h_20, + onClick = onSortingToggle + ) } ButtonSecondaryToggle( modifier = Modifier.padding(end = 16.dp), - select = marketFieldSelect, - onSelect = onSelectMarketField + select = periodSelect, + onSelect = onSelectPeriod ) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesService.kt index ec7c5ab961a..678f79c2c4d 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesService.kt @@ -3,7 +3,6 @@ package io.horizontalsystems.bankwallet.modules.market.favorites import io.horizontalsystems.bankwallet.core.managers.CurrencyManager import io.horizontalsystems.bankwallet.core.subscribeIO import io.horizontalsystems.bankwallet.entities.DataState -import io.horizontalsystems.bankwallet.modules.market.SortingField import io.horizontalsystems.bankwallet.modules.market.category.MarketItemWrapper import io.horizontalsystems.core.BackgroundManager import io.reactivex.Observable @@ -25,18 +24,24 @@ class MarketFavoritesService( val marketItemsObservable: Observable>> get() = marketItemsSubject - val sortingFieldTypes = SortingField.values().toList() - var sortingField: SortingField = menuService.sortingField + var sortDescending: Boolean = menuService.sortDescending set(value) { field = value - menuService.sortingField = value - rebuildItems() + menuService.sortDescending = value + fetch() } - private fun fetch(forceRefresh: Boolean) { + var period: MarketFavoritesModule.Period = menuService.period + set(value) { + field = value + menuService.period = value + fetch() + } + + private fun fetch() { favoritesDisposable?.dispose() - repository.get(sortingField, currencyManager.baseCurrency, forceRefresh) + repository.get(sortDescending, period, currencyManager.baseCurrency) .subscribeIO({ marketItems -> marketItemsSubject.onNext(DataState.Success(marketItems.map { MarketItemWrapper(it, true) @@ -48,34 +53,26 @@ class MarketFavoritesService( } } - private fun rebuildItems() { - fetch(false) - } - - private fun forceRefresh() { - fetch(true) - } - fun removeFavorite(uid: String) { repository.removeFavorite(uid) } fun refresh() { - forceRefresh() + fetch() } fun start() { backgroundManager.registerListener(this) currencyManager.baseCurrencyUpdatedSignal - .subscribeIO { forceRefresh() } + .subscribeIO { fetch() } .let { currencyManagerDisposable = it } repository.dataUpdatedObservable - .subscribeIO { forceRefresh() } + .subscribeIO { fetch() } .let { repositoryDisposable = it } - forceRefresh() + fetch() } fun stop() { @@ -85,6 +82,6 @@ class MarketFavoritesService( } override fun willEnterForeground() { - forceRefresh() + fetch() } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesViewModel.kt index 17abafd0035..9417ffee992 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesViewModel.kt @@ -6,11 +6,9 @@ import androidx.lifecycle.viewModelScope import io.horizontalsystems.bankwallet.core.subscribeIO import io.horizontalsystems.bankwallet.entities.DataState import io.horizontalsystems.bankwallet.entities.ViewState -import io.horizontalsystems.bankwallet.modules.market.MarketField import io.horizontalsystems.bankwallet.modules.market.MarketViewItem -import io.horizontalsystems.bankwallet.modules.market.SortingField import io.horizontalsystems.bankwallet.modules.market.category.MarketItemWrapper -import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesModule.SelectorDialogState +import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesModule.Period import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesModule.ViewItem import io.horizontalsystems.bankwallet.ui.compose.Select import io.reactivex.disposables.CompositeDisposable @@ -19,25 +17,19 @@ import kotlinx.coroutines.launch class MarketFavoritesViewModel( private val service: MarketFavoritesService, - private val menuService: MarketFavoritesMenuService ) : ViewModel() { private val disposables = CompositeDisposable() - - private val marketFieldTypes = MarketField.values().toList() - private var marketField: MarketField by menuService::marketField private var marketItemsWrapper: List = listOf() - - private val marketFieldSelect: Select - get() = Select(marketField, marketFieldTypes) - - private val sortingFieldSelect: Select - get() = Select(service.sortingField, service.sortingFieldTypes) + private val timeDurationOptions: List = listOf( + Period.OneDay, + Period.SevenDay, + Period.ThirtyDay, + ) val viewStateLiveData = MutableLiveData(ViewState.Loading) val isRefreshingLiveData = MutableLiveData() val viewItemLiveData = MutableLiveData() - val sortingFieldSelectorStateLiveData = MutableLiveData() init { service.marketItemsObservable @@ -48,9 +40,11 @@ class MarketFavoritesViewModel( marketItemsWrapper = state.data syncViewItem() } + is DataState.Error -> { viewStateLiveData.postValue(ViewState.Error(state.error)) } + DataState.Loading -> {} } }.let { disposables.add(it) } @@ -70,10 +64,10 @@ class MarketFavoritesViewModel( private fun syncViewItem() { viewItemLiveData.postValue( ViewItem( - sortingFieldSelect, - marketFieldSelect, - marketItemsWrapper.map { - MarketViewItem.create(it.marketItem, marketField, true) + sortingDescending = service.sortDescending, + periodSelect = Select(service.period, timeDurationOptions), + marketItems = marketItemsWrapper.map { + MarketViewItem.create(it.marketItem, true) } ) ) @@ -87,23 +81,12 @@ class MarketFavoritesViewModel( refreshWithMinLoadingSpinnerPeriod() } - fun onClickSortingField() { - sortingFieldSelectorStateLiveData.postValue(SelectorDialogState.Opened(sortingFieldSelect)) - } - - fun onSelectSortingField(sortingField: SortingField) { - service.sortingField = sortingField - sortingFieldSelectorStateLiveData.postValue(SelectorDialogState.Closed) - } - - fun onSelectMarketField(marketField: MarketField) { - this.marketField = marketField - - syncViewItem() + fun onSortToggle() { + service.sortDescending = !service.sortDescending } - fun onSortingFieldDialogDismiss() { - sortingFieldSelectorStateLiveData.postValue(SelectorDialogState.Closed) + fun onSelectTimeDuration(period: Period) { + service.period = period } override fun onCleared() { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidget.kt b/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidget.kt index 6d463570f23..f9dcdcc8829 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidget.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidget.kt @@ -21,6 +21,8 @@ import androidx.glance.appwidget.SizeMode import androidx.glance.appwidget.action.ActionCallback import androidx.glance.appwidget.action.actionRunCallback import androidx.glance.appwidget.action.actionStartActivity +import androidx.glance.appwidget.lazy.LazyColumn +import androidx.glance.appwidget.lazy.items import androidx.glance.appwidget.provideContent import androidx.glance.appwidget.state.updateAppWidgetState import androidx.glance.background @@ -101,22 +103,6 @@ class MarketWidget : GlanceAppWidget() { text = context.getString(state.type.title), style = AppWidgetTheme.textStyles.d1() ) - /* - Image( - modifier = GlanceModifier - .size(20.dp) - .clickable( - actionStartActivity( - actionParametersOf( - ActionParameters.Key(AppWidgetManager.EXTRA_APPWIDGET_ID) to state.widgetId - ) - ) - ), - provider = ImageProvider(R.drawable.ic_edit_20), - contentDescription = null - ) - Spacer(modifier = GlanceModifier.width(16.dp)) - */ Box( modifier = GlanceModifier .fillMaxHeight() @@ -128,10 +114,7 @@ class MarketWidget : GlanceAppWidget() { CircularProgressIndicator(modifier = GlanceModifier.size(20.dp)) } else { Image( - modifier = GlanceModifier - .size(20.dp) - //todo remove after upgrade to glance-appwidget:1.0.0-alpha06 - .clickable(actionRunCallback()), + modifier = GlanceModifier.size(20.dp), provider = ImageProvider(R.drawable.ic_refresh), contentDescription = null ) @@ -150,25 +133,19 @@ class MarketWidget : GlanceAppWidget() { text = state.error, ) } else { - state.items.forEach { item -> - val deeplinkUri = getDeeplinkUri(item, state.type, deeplinkScheme) - Box( - modifier = GlanceModifier - .height(60.dp) - .background(ImageProvider(R.drawable.widget_list_item_background)) - .clickable( - actionStartActivity(Intent(Intent.ACTION_VIEW, deeplinkUri)) - ) - ) { - Item(item = item) - //todo remove after upgrade to glance-appwidget:1.0.0-alpha06 - Spacer( - GlanceModifier - .fillMaxSize() + LazyColumn { + items(state.items) { item -> + val deeplinkUri = getDeeplinkUri(item, state.type, deeplinkScheme) + Box( + modifier = GlanceModifier + .height(60.dp) + .background(ImageProvider(R.drawable.widget_list_item_background)) .clickable( actionStartActivity(Intent(Intent.ACTION_VIEW, deeplinkUri)) ) - ) + ) { + Item(item = item) + } } } } @@ -190,9 +167,11 @@ class MarketWidget : GlanceAppWidget() { MarketWidgetType.TopGainers -> { "$deeplinkScheme://coin-page?uid=${item.uid}".toUri() } + MarketWidgetType.TopNfts -> { "$deeplinkScheme://nft-collection?uid=${item.uid}&blockchainTypeUid=${item.blockchainTypeUid}".toUri() } + MarketWidgetType.TopPlatforms -> { "$deeplinkScheme://top-platforms?uid=${item.uid}&title=${item.title}".toUri() } @@ -220,8 +199,6 @@ class MarketWidget : GlanceAppWidget() { subtitle = item.subtitle, label = item.label, diff = item.diff, - marketCap = item.marketCap, - volume = item.volume ) } } @@ -259,8 +236,6 @@ class MarketWidget : GlanceAppWidget() { subtitle: String, label: String?, diff: BigDecimal?, - marketCap: String?, - volume: String? ) { Row( modifier = GlanceModifier.fillMaxWidth(), @@ -276,7 +251,13 @@ class MarketWidget : GlanceAppWidget() { style = AppWidgetTheme.textStyles.d1() ) Spacer(modifier = GlanceModifier.defaultWeight()) - MarketDataValueComponent(diff, marketCap, volume) + diff?.let { + Text( + text = App.numberFormatter.formatValueAsDiff(Value.Percent(diff)), + style = TextStyle(color = diffColor(diff), fontSize = 14.sp, fontWeight = FontWeight.Normal), + maxLines = 1 + ) + } } } @@ -288,54 +269,6 @@ class MarketWidget : GlanceAppWidget() { AppWidgetTheme.colors.lucian } - @Composable - private fun MarketDataValueComponent( - diff: BigDecimal?, - marketCap: String?, - volume: String? - ) { - - when { - diff != null -> { - Text( - text = App.numberFormatter.formatValueAsDiff(Value.Percent(diff)), - style = TextStyle(color = diffColor(diff), fontSize = 14.sp, fontWeight = FontWeight.Normal), - maxLines = 1 - ) - } - marketCap != null -> { - Row { - Text( - text = "MCap", - style = AppWidgetTheme.textStyles.c3(), - maxLines = 1 - ) - Spacer(modifier = GlanceModifier.width(4.dp)) - Text( - text = marketCap, - style = AppWidgetTheme.textStyles.d1(), - maxLines = 1 - ) - } - } - volume != null -> { - Row { - Text( - text = "Vol", - style = AppWidgetTheme.textStyles.d3(), - maxLines = 1 - ) - Spacer(modifier = GlanceModifier.width(4.dp)) - Text( - text = volume, - style = AppWidgetTheme.textStyles.d1(), - maxLines = 1 - ) - } - } - } - } - @Composable private fun Badge(text: String) { Text( diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidgetRepository.kt b/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidgetRepository.kt index e41b2771784..b67d8758c77 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidgetRepository.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidgetRepository.kt @@ -8,17 +8,16 @@ import io.horizontalsystems.bankwallet.core.managers.CurrencyManager import io.horizontalsystems.bankwallet.core.managers.MarketFavoritesManager import io.horizontalsystems.bankwallet.core.managers.MarketKitWrapper import io.horizontalsystems.bankwallet.core.providers.Translator -import io.horizontalsystems.bankwallet.modules.market.MarketField import io.horizontalsystems.bankwallet.modules.market.MarketItem import io.horizontalsystems.bankwallet.modules.market.SortingField import io.horizontalsystems.bankwallet.modules.market.TimeDuration import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesMenuService +import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesModule.Period import io.horizontalsystems.bankwallet.modules.market.sort import io.horizontalsystems.bankwallet.modules.market.topnftcollections.TopNftCollectionsRepository import io.horizontalsystems.bankwallet.modules.market.topnftcollections.TopNftCollectionsViewItemFactory import io.horizontalsystems.bankwallet.modules.market.topplatforms.TopPlatformsRepository import kotlinx.coroutines.rx2.await -import java.math.BigDecimal class MarketWidgetRepository( private val marketKit: MarketKitWrapper, @@ -40,7 +39,7 @@ class MarketWidgetRepository( suspend fun getMarketItems(marketWidgetType: MarketWidgetType): List = when (marketWidgetType) { MarketWidgetType.Watchlist -> { - getWatchlist() + getWatchlist(favoritesMenuService.sortDescending, favoritesMenuService.period) } MarketWidgetType.TopGainers -> { getTopGainers() @@ -72,8 +71,6 @@ class MarketWidgetRepository( 2 ), diff = item.changeDiff, - marketCap = null, - volume = null, blockchainTypeUid = null, imageRemoteUrl = item.platform.iconUrl ) @@ -97,9 +94,7 @@ class MarketWidgetRepository( subtitle = it.floorPrice, label = it.order.toString(), value = it.volume, - marketCap = null, diff = it.volumeDiff, - volume = null, blockchainTypeUid = it.blockchainType.uid, imageRemoteUrl = it.imageUrl ?: "" ) @@ -116,45 +111,30 @@ class MarketWidgetRepository( .sort(SortingField.TopGainers) .subList(0, Integer.min(marketItems.size, itemsLimit)) - return sortedMarketItems.map { marketWidgetItem(it, MarketField.PriceDiff) } + return sortedMarketItems.map { marketWidgetItem(it) } } - private suspend fun getWatchlist(): List { + private suspend fun getWatchlist(sortDescending: Boolean, period: Period): List { val favoriteCoins = favoritesManager.getAll() var marketItems = listOf() if (favoriteCoins.isNotEmpty()) { val favoriteCoinUids = favoriteCoins.map { it.coinUid } + val sortingField = if(sortDescending) SortingField.TopGainers else SortingField.TopLosers marketItems = marketKit.marketInfosSingle(favoriteCoinUids, currency.code, "widget") .await() .map { marketInfo -> - MarketItem.createFromCoinMarket(marketInfo, currency) + MarketItem.createFromCoinMarket(marketInfo, currency, period) } - .sort(favoritesMenuService.sortingField) + .sort(sortingField) } - return marketItems.map { marketWidgetItem(it, favoritesMenuService.marketField) } + return marketItems.map { marketWidgetItem(it) } } private fun marketWidgetItem( marketItem: MarketItem, - marketField: MarketField, ): MarketWidgetItem { - var marketCap: String? = null - var volume: String? = null - var diff: BigDecimal? = null - - when (marketField) { - MarketField.MarketCap -> { - marketCap = App.numberFormatter.formatFiatShort(marketItem.marketCap.value, marketItem.marketCap.currency.symbol, 2) - } - MarketField.Volume -> { - volume = App.numberFormatter.formatFiatShort(marketItem.volume.value, marketItem.volume.currency.symbol, 2) - } - MarketField.PriceDiff -> { - diff = marketItem.diff - } - } return MarketWidgetItem( uid = marketItem.fullCoin.coin.uid, @@ -165,9 +145,7 @@ class MarketWidgetRepository( marketItem.rate.value, marketItem.rate.currency.symbol ), - marketCap = marketCap, - volume = volume, - diff = diff, + diff = marketItem.diff, blockchainTypeUid = null, imageRemoteUrl = marketItem.fullCoin.coin.imageUrl ) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidgetState.kt b/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidgetState.kt index f7d7e2fe5ec..bbde86387cc 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidgetState.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidgetState.kt @@ -43,8 +43,6 @@ data class MarketWidgetItem( val label: String, val value: String, - val marketCap: String?, - val volume: String?, val diff: BigDecimal?, val blockchainTypeUid: String?, @@ -52,7 +50,7 @@ data class MarketWidgetItem( val imageLocalPath: String? = null ) { override fun toString(): String { - return "( title: $title, subtitle: $subtitle, label: $label, value: $value, marketCap: $marketCap, volume: $volume, diff: $diff, imageRemoteUrl: $imageRemoteUrl, imageLocalPath: $imageLocalPath )" + return "( title: $title, subtitle: $subtitle, label: $label, value: $value, diff: $diff, imageRemoteUrl: $imageRemoteUrl, imageLocalPath: $imageLocalPath )" } }