Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add periods to Watchlist #6959

Merged
merged 2 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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:e351444'
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<Boolean>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,27 @@ import androidx.compose.animation.Crossfade
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Divider
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
Expand All @@ -32,7 +44,22 @@ import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Loading
import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme
import io.horizontalsystems.bankwallet.ui.compose.Select
import io.horizontalsystems.bankwallet.ui.compose.TranslatableString
import io.horizontalsystems.bankwallet.ui.compose.components.*
import io.horizontalsystems.bankwallet.ui.compose.components.AppBar
import io.horizontalsystems.bankwallet.ui.compose.components.ButtonPrimaryYellow
import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryCircle
import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryToggle
import io.horizontalsystems.bankwallet.ui.compose.components.DescriptionCard
import io.horizontalsystems.bankwallet.ui.compose.components.HSpacer
import io.horizontalsystems.bankwallet.ui.compose.components.HeaderSorting
import io.horizontalsystems.bankwallet.ui.compose.components.ListEmptyView
import io.horizontalsystems.bankwallet.ui.compose.components.ListErrorView
import io.horizontalsystems.bankwallet.ui.compose.components.MenuItem
import io.horizontalsystems.bankwallet.ui.compose.components.RowUniversal
import io.horizontalsystems.bankwallet.ui.compose.components.ScreenMessageWithAction
import io.horizontalsystems.bankwallet.ui.compose.components.VSpacer
import io.horizontalsystems.bankwallet.ui.compose.components.body_leah
import io.horizontalsystems.bankwallet.ui.compose.components.captionSB_grey
import io.horizontalsystems.bankwallet.ui.compose.components.subhead2_grey

class CoinRankFragment : BaseComposeFragment() {

Expand Down Expand Up @@ -84,7 +111,7 @@ private fun CoinRankScreen(
)
)
)
Crossfade(uiState.viewState) { viewItemState ->
Crossfade(uiState.viewState, label = "") { viewItemState ->
when (viewItemState) {
ViewState.Loading -> {
Loading()
Expand Down Expand Up @@ -121,7 +148,7 @@ private fun CoinRankScreen(
HeaderSorting {
ButtonSecondaryCircle(
modifier = Modifier.padding(start = 16.dp),
icon = if (uiState.sortDescending) R.drawable.ic_arrow_down_20 else R.drawable.ic_arrow_up_20,
icon = if (uiState.sortDescending) R.drawable.ic_sort_l2h_20 else R.drawable.ic_sort_h2l_20,
onClick = { viewModel.toggleSortType() }
)
Spacer(Modifier.weight(1f))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class CoinTreasuriesFragment : BaseComposeFragment() {
}
ButtonSecondaryCircle(
modifier = Modifier.padding(end = 16.dp),
icon = if (sortDescending) R.drawable.ic_arrow_down_20 else R.drawable.ic_arrow_up_20,
icon = if (sortDescending) R.drawable.ic_sort_h2l_20 else R.drawable.ic_sort_l2h_20,
onClick = { onToggleSortType() }
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
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(
private val localStorage: ILocalStorage,
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()
}
}
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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<SortingField>,
val marketFieldSelect: Select<MarketField>,
val sortingDescending: Boolean,
val periodSelect: Select<Period>,
val marketItems: List<MarketViewItem>
)

sealed class SelectorDialogState {
object Closed : SelectorDialogState()
class Opened(val select: Select<SortingField>) : 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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,45 @@ 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

class MarketFavoritesRepository(
private val marketKit: MarketKitWrapper,
private val manager: MarketFavoritesManager
) {
private var cache: List<MarketItem> = listOf()

val dataUpdatedObservable by manager::dataUpdatedAsync

private fun getFavorites(
forceRefresh: Boolean,
currency: Currency
): List<MarketItem> =
if (forceRefresh) {
val favoriteCoins = manager.getAll()
var marketItems = listOf<MarketItem>()
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<MarketItem> {
val favoriteCoins = manager.getAll()
var marketItems = listOf<MarketItem>()
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<List<MarketItem>> =
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)
)
Expand Down
Loading