Skip to content

Commit

Permalink
Show SubscriptionInfo page in Coin Analytics page
Browse files Browse the repository at this point in the history
  • Loading branch information
omurovch committed Jul 27, 2023
1 parent 061ab58 commit bf3dba3
Show file tree
Hide file tree
Showing 16 changed files with 286 additions and 206 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ dependencies {
implementation 'com.github.horizontalsystems:ethereum-kit-android:04bd4ff'
implementation 'com.github.horizontalsystems:blockchain-fee-rate-kit-android:1.0.0'
implementation 'com.github.horizontalsystems:binance-chain-kit-android:7e4d7c0'
implementation 'com.github.horizontalsystems:market-kit-android:f53bfdc'
implementation 'com.github.horizontalsystems:market-kit-android:25e9aaa'
implementation 'com.github.horizontalsystems:solana-kit-android:97dcdba'
implementation 'com.github.horizontalsystems:tron-kit-android:1cc0ebe'
// Zcash SDK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class NoDataException() : Exception() {
}

class NoAuthTokenException(override val message: String = "Auth Token is not set or empty") : Exception()
class InvalidAuthTokenException(override val message: String = "Auth Token is expired or invalid") : Exception()

sealed class EvmError(message: String? = null) : Throwable(message) {
object InsufficientBalanceWithFee : EvmError()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.horizontalsystems.bankwallet.core.managers

import android.content.Context
import io.horizontalsystems.bankwallet.core.InvalidAuthTokenException
import io.horizontalsystems.bankwallet.core.NoAuthTokenException
import io.horizontalsystems.bankwallet.core.customCoinPrefix
import io.horizontalsystems.marketkit.MarketKit
Expand All @@ -14,6 +15,7 @@ import io.horizontalsystems.marketkit.models.NftTopCollection
import io.horizontalsystems.marketkit.models.TokenQuery
import io.reactivex.Observable
import io.reactivex.Single
import retrofit2.HttpException
import retrofit2.Response
import java.math.BigDecimal

Expand All @@ -35,7 +37,15 @@ class MarketKitWrapper(

private fun <T> requestWithAuthToken(f: (String) -> Single<T>) =
subscriptionManager.authToken?.let { authToken ->
f.invoke(authToken)
f.invoke(authToken).onErrorResumeNext { error ->
if (error is HttpException && (error.code() == 401 || error.code() == 403)) {
subscriptionManager.authToken = null

Single.error(InvalidAuthTokenException())
} else {
Single.error(error)
}
}
} ?: run {
Single.error(NoAuthTokenException())
}
Expand Down Expand Up @@ -212,7 +222,8 @@ class MarketKitWrapper(

fun chartStartTimeSingle(coinUid: String) = marketKit.chartStartTimeSingle(coinUid)

fun chartPointsSingle(coinUid: String, currencyCode: String, periodType: HsPeriodType) = marketKit.chartPointsSingle(coinUid, currencyCode, periodType)
fun chartPointsSingle(coinUid: String, currencyCode: String, periodType: HsPeriodType) =
marketKit.chartPointsSingle(coinUid, currencyCode, periodType)

// Global Market Info

Expand All @@ -233,7 +244,12 @@ class MarketKitWrapper(
suspend fun nftCollections(): List<NftTopCollection> =
marketKit.nftTopCollections()

fun authKey(address: String) = marketKit.authGetSignMessage(address)
fun subscriptionsSingle(addresses: List<String>) =
marketKit.subscriptionsSingle(addresses)

fun authGetSignMessage(address: String) =
marketKit.authGetSignMessage(address)

fun authenticate(signature: String, address: String) =
marketKit.authenticate(signature, address)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ import com.google.accompanist.pager.HorizontalPager
import com.google.accompanist.pager.rememberPagerState
import io.horizontalsystems.bankwallet.R
import io.horizontalsystems.bankwallet.core.BaseFragment
import io.horizontalsystems.bankwallet.core.slideFromBottom
import io.horizontalsystems.bankwallet.modules.coin.analytics.CoinAnalyticsScreen
import io.horizontalsystems.bankwallet.modules.coin.coinmarkets.CoinMarketsScreen
import io.horizontalsystems.bankwallet.modules.coin.overview.ui.CoinOverviewScreen
import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme
import io.horizontalsystems.bankwallet.ui.compose.TranslatableString
import io.horizontalsystems.bankwallet.ui.compose.components.*
import io.horizontalsystems.core.helpers.HudHelper
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class CoinFragment : BaseFragment() {
Expand Down Expand Up @@ -143,9 +145,16 @@ fun CoinTabs(
val tabItems = tabs.map {
TabItem(stringResource(id = it.titleResId), it == selectedTab, it)
}
Tabs(tabItems, onClick = {
Tabs(tabItems, onClick = { tab ->
coroutineScope.launch {
pagerState.scrollToPage(it.ordinal)
pagerState.scrollToPage(tab.ordinal)

if (tab == CoinModule.Tab.Details && viewModel.shouldShowSubscriptionInfo()) {
viewModel.subscriptionInfoShown()

delay(1000)
navController.slideFromBottom(R.id.subscriptionInfoFragment)
}
}
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ object CoinModule {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
val fullCoin = App.marketKit.fullCoins(coinUids = listOf(coinUid)).first()
val service = CoinService(fullCoin, App.marketFavoritesManager)
return CoinViewModel(service, listOf(service), App.localStorage) as T
return CoinViewModel(service, listOf(service), App.localStorage, App.subscriptionManager) as T
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.lifecycle.viewModelScope
import io.horizontalsystems.bankwallet.R
import io.horizontalsystems.bankwallet.core.Clearable
import io.horizontalsystems.bankwallet.core.ILocalStorage
import io.horizontalsystems.bankwallet.core.managers.SubscriptionManager
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
import kotlinx.coroutines.rx2.asFlow
Expand All @@ -16,6 +17,7 @@ class CoinViewModel(
private val service: CoinService,
private val clearables: List<Clearable>,
private val localStorage: ILocalStorage,
private val subscriptionManager: SubscriptionManager
) : ViewModel() {

val tabs = CoinModule.Tab.values()
Expand All @@ -27,6 +29,8 @@ class CoinViewModel(
var successMessage by mutableStateOf<Int?>(null)
private set

private var subscriptionInfoShown: Boolean = false

init {
viewModelScope.launch {
val isFavoriteFlow: Flow<Boolean> = service.isFavorite.asFlow()
Expand Down Expand Up @@ -54,4 +58,12 @@ class CoinViewModel(
successMessage = null
}

fun shouldShowSubscriptionInfo():Boolean {
return !subscriptionManager.hasSubscription() && !subscriptionInfoShown
}

fun subscriptionInfoShown() {
subscriptionInfoShown = true
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ object CoinAnalyticsModule {
App.currencyManager,
App.subscriptionManager,
App.accountManager,
App.appConfigProvider,
)


Expand Down Expand Up @@ -144,7 +143,7 @@ object CoinAnalyticsModule {
)

sealed class AnalyticsViewItem {
class Preview(val blocks: List<PreviewBlockViewItem>, val subscriptionAddress: String?) : AnalyticsViewItem()
class Preview(val blocks: List<PreviewBlockViewItem>) : AnalyticsViewItem()
class Analytics(val blocks: List<BlockViewItem>) : AnalyticsViewItem()
object NoData : AnalyticsViewItem()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.fragment.app.FragmentManager
Expand All @@ -28,8 +27,6 @@ import io.horizontalsystems.bankwallet.modules.coin.analytics.ui.AnalyticsBlockH
import io.horizontalsystems.bankwallet.modules.coin.analytics.ui.AnalyticsChart
import io.horizontalsystems.bankwallet.modules.coin.analytics.ui.AnalyticsContainer
import io.horizontalsystems.bankwallet.modules.coin.analytics.ui.AnalyticsContentNumber
import io.horizontalsystems.bankwallet.modules.coin.analytics.ui.AnalyticsDataLockedBlockNoSubscription
import io.horizontalsystems.bankwallet.modules.coin.analytics.ui.AnalyticsDataLockedBlockNotActivated
import io.horizontalsystems.bankwallet.modules.coin.analytics.ui.AnalyticsFooterCell
import io.horizontalsystems.bankwallet.modules.coin.audits.CoinAuditsFragment
import io.horizontalsystems.bankwallet.modules.coin.investments.CoinInvestmentsFragment
Expand All @@ -40,7 +37,6 @@ import io.horizontalsystems.bankwallet.modules.coin.reports.CoinReportsFragment
import io.horizontalsystems.bankwallet.modules.coin.treasuries.CoinTreasuriesFragment
import io.horizontalsystems.bankwallet.modules.info.CoinAnalyticsInfoFragment
import io.horizontalsystems.bankwallet.modules.metricchart.ProChartFragment
import io.horizontalsystems.bankwallet.modules.subscription.ActivateSubscriptionFragment
import io.horizontalsystems.bankwallet.ui.compose.HSSwipeRefresh
import io.horizontalsystems.bankwallet.ui.compose.components.InfoText
import io.horizontalsystems.bankwallet.ui.compose.components.ListEmptyView
Expand All @@ -58,9 +54,7 @@ fun CoinAnalyticsScreen(
fragmentManager: FragmentManager
) {
val viewModel = viewModel<CoinAnalyticsViewModel>(factory = CoinAnalyticsModule.Factory(fullCoin))

val uiState = viewModel.uiState
val uriHandler = LocalUriHandler.current

HSSwipeRefresh(
refreshing = uiState.isRefreshing,
Expand All @@ -84,13 +78,6 @@ fun CoinAnalyticsScreen(
is AnalyticsViewItem.Preview -> {
AnalyticsDataPreview(
previewBlocks = item.blocks,
subscriptionAddress = item.subscriptionAddress,
onClickLearnMore = {
uriHandler.openUri(viewModel.analyticsLink)
},
onClickActivate = {
navController.slideFromBottom(R.id.activateSubscription, ActivateSubscriptionFragment.prepareParams(it))
},
navController = navController
)
}
Expand Down Expand Up @@ -136,25 +123,9 @@ private fun AnalyticsData(
@Composable
private fun AnalyticsDataPreview(
previewBlocks: List<CoinAnalyticsModule.PreviewBlockViewItem>,
subscriptionAddress: String?,
onClickLearnMore: () -> Unit,
onClickActivate: (String) -> Unit,
navController: NavController,
) {
LazyColumn(modifier = Modifier.fillMaxSize()) {
item {
if (subscriptionAddress != null) {
AnalyticsDataLockedBlockNotActivated(
onClickActivate = {
onClickActivate.invoke(subscriptionAddress)
}
)
} else {
AnalyticsDataLockedBlockNoSubscription(
onClickLearnMore = onClickLearnMore
)
}
}
items(previewBlocks) { block ->
AnalyticsPreviewBlock(block, navController)
}
Expand Down Expand Up @@ -288,7 +259,7 @@ private fun FooterCell(
}

CoinAnalyticsModule.ActionType.Preview -> {

navController.slideFromBottom(R.id.subscriptionInfoFragment)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,33 @@ package io.horizontalsystems.bankwallet.modules.coin.analytics

import io.horizontalsystems.bankwallet.core.App
import io.horizontalsystems.bankwallet.core.IAccountManager
import io.horizontalsystems.bankwallet.core.InvalidAuthTokenException
import io.horizontalsystems.bankwallet.core.NoAuthTokenException
import io.horizontalsystems.bankwallet.core.managers.CurrencyManager
import io.horizontalsystems.bankwallet.core.managers.MarketKitWrapper
import io.horizontalsystems.bankwallet.core.managers.SubscriptionManager
import io.horizontalsystems.bankwallet.core.providers.AppConfigProvider
import io.horizontalsystems.bankwallet.core.subscribeIO
import io.horizontalsystems.bankwallet.entities.Currency
import io.horizontalsystems.bankwallet.entities.DataState
import io.horizontalsystems.marketkit.models.*
import io.horizontalsystems.marketkit.models.Analytics
import io.horizontalsystems.marketkit.models.AnalyticsPreview
import io.horizontalsystems.marketkit.models.Blockchain
import io.horizontalsystems.marketkit.models.BlockchainType
import io.horizontalsystems.marketkit.models.FullCoin
import io.horizontalsystems.marketkit.models.TokenType
import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.subjects.BehaviorSubject
import retrofit2.HttpException

class CoinAnalyticsService(
val fullCoin: FullCoin,
private val marketKit: MarketKitWrapper,
private val currencyManager: CurrencyManager,
private val subscriptionManager: SubscriptionManager,
private val accountManager: IAccountManager,
appConfigProvider: AppConfigProvider,
) {
private val disposables = CompositeDisposable()

val analyticsLink = appConfigProvider.analyticsLink

private val stateSubject = BehaviorSubject.create<DataState<AnalyticData>>()
val stateObservable: Observable<DataState<AnalyticData>>
get() = stateSubject
Expand Down Expand Up @@ -84,10 +86,15 @@ class CoinAnalyticsService(
}

private fun handleError(error: Throwable) {
if (error is HttpException && (error.code() == 401 || error.code() == 403)) {
preview()
} else {
stateSubject.onNext(DataState.Error(error))
when (error) {
is NoAuthTokenException,
is InvalidAuthTokenException -> {
preview()
}

else -> {
stateSubject.onNext(DataState.Error(error))
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ class CoinAnalyticsViewModel(
private val code: String
) : ViewModel() {

val analyticsLink by service::analyticsLink
private val disposables = CompositeDisposable()

private val currency = service.currency
Expand Down Expand Up @@ -127,12 +126,7 @@ class CoinAnalyticsViewModel(
if (item.analyticsPreview != null) {
val viewItems = getPreviewViewItems(item.analyticsPreview)
if (viewItems.isNotEmpty()) {
val subscriptionAddress = item.analyticsPreview.subscriptions
?.sortedByDescending { it.deadline }
?.firstOrNull()
?.address

return AnalyticsViewItem.Preview(viewItems, subscriptionAddress)
return AnalyticsViewItem.Preview(viewItems)
}
} else if (item.analytics != null) {
val viewItems = getViewItems(item.analytics)
Expand Down Expand Up @@ -464,13 +458,13 @@ class CoinAnalyticsViewModel(
}

private fun getFormattedSum(values: List<BigDecimal>, currency: Currency? = null): String {
return currency?.let { currency ->
return currency?.let {
numberFormatter.formatFiatShort(values.sumOf { it }, currency.symbol, 2)
} ?: numberFormatter.formatCoinShort(values.sumOf { it }, null, 0)
}

private fun getFormattedValue(value: BigDecimal, currency: Currency? = null): String {
return currency?.let { currency ->
return currency?.let {
numberFormatter.formatFiatShort(value, currency.symbol, 2)
} ?: numberFormatter.formatCoinShort(value, null, 0)
}
Expand Down
Loading

0 comments on commit bf3dba3

Please sign in to comment.