Skip to content

Commit 36273c7

Browse files
authored
Feature/redeemable alert (#305)
* Redeem alert * Fix alert view * Add validations to redeem alert * Code style
1 parent 0fae872 commit 36273c7

File tree

24 files changed

+269
-105
lines changed

24 files changed

+269
-105
lines changed

app/src/main/java/jp/co/soramitsu/app/root/navigation/Navigator.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ import jp.co.soramitsu.feature_staking_impl.presentation.staking.controller.conf
5050
import jp.co.soramitsu.feature_staking_impl.presentation.staking.main.model.StakingStoryModel
5151
import jp.co.soramitsu.feature_staking_impl.presentation.staking.rebond.confirm.ConfirmRebondFragment
5252
import jp.co.soramitsu.feature_staking_impl.presentation.staking.rebond.confirm.ConfirmRebondPayload
53+
import jp.co.soramitsu.feature_staking_impl.presentation.staking.redeem.RedeemFragment
54+
import jp.co.soramitsu.feature_staking_impl.presentation.staking.redeem.RedeemPayload
5355
import jp.co.soramitsu.feature_staking_impl.presentation.staking.rewardDestination.confirm.ConfirmRewardDestinationFragment
5456
import jp.co.soramitsu.feature_staking_impl.presentation.staking.rewardDestination.confirm.parcel.ConfirmRewardDestinationPayload
5557
import jp.co.soramitsu.feature_staking_impl.presentation.staking.unbond.confirm.ConfirmUnbondFragment
@@ -218,8 +220,8 @@ class Navigator :
218220
navController?.navigate(R.id.action_selectUnbondFragment_to_confirmUnbondFragment, ConfirmUnbondFragment.getBundle(payload))
219221
}
220222

221-
override fun openRedeem() {
222-
navController?.navigate(R.id.action_stakingBalanceFragment_to_redeemFragment)
223+
override fun openRedeem(payload: RedeemPayload) {
224+
navController?.navigate(R.id.action_open_redeemFragment, RedeemFragment.getBundle(payload))
223225
}
224226

225227
override fun openConfirmRebond(payload: ConfirmRebondPayload) {

app/src/main/res/navigation/main_nav_graph.xml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -551,13 +551,7 @@
551551
app:popEnterAnim="@anim/fragment_close_enter"
552552
app:popExitAnim="@anim/fragment_close_exit" />
553553

554-
<action
555-
android:id="@+id/action_stakingBalanceFragment_to_redeemFragment"
556-
app:destination="@id/redeemFragment"
557-
app:enterAnim="@anim/fragment_open_enter"
558-
app:exitAnim="@anim/fragment_open_exit"
559-
app:popEnterAnim="@anim/fragment_close_enter"
560-
app:popExitAnim="@anim/fragment_close_exit" />
554+
561555
<action
562556
android:id="@+id/action_stakingBalanceFragment_to_customRebondFragment"
563557
app:destination="@id/customRebondFragment"
@@ -637,6 +631,14 @@
637631
android:name="jp.co.soramitsu.feature_staking_impl.presentation.staking.unbond.confirm.ConfirmUnbondFragment"
638632
android:label="ConfirmUnbondFragment" />
639633

634+
<action
635+
android:id="@+id/action_open_redeemFragment"
636+
app:destination="@id/redeemFragment"
637+
app:enterAnim="@anim/fragment_open_enter"
638+
app:exitAnim="@anim/fragment_open_exit"
639+
app:popEnterAnim="@anim/fragment_close_enter"
640+
app:popExitAnim="@anim/fragment_close_exit" />
641+
640642
<fragment
641643
android:id="@+id/redeemFragment"
642644
android:name="jp.co.soramitsu.feature_staking_impl.presentation.staking.redeem.RedeemFragment"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="16dp"
3+
android:height="16dp"
4+
android:viewportWidth="16"
5+
android:viewportHeight="16">
6+
<path
7+
android:pathData="M1.12,12.5259L7.1199,2.5C7.4975,1.7988 8.5033,1.7988 8.8809,2.5L14.8809,12.5259C15.2396,13.1921 14.7571,14 14.0004,14H2.0004C1.2437,14 0.7612,13.1921 1.12,12.5259ZM7.0004,5H9.0004V9H7.0004V5ZM9.0004,10.5H7.0004V12.5H9.0004V10.5Z"
8+
android:fillColor="#FFD600"
9+
android:fillType="evenOdd"/>
10+
</vector>

common/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<resources>
3+
<string name="staking_alert_redeem_title">Redeem unbonded tokens.</string>
4+
35
<string name="staking_alert_title">Alerts</string>
46
<string name="staking_alert_no_alerts_now">Everything is fine now. Alerts will appear here.</string>
57
<string name="staking_alert_start_next_era">Your staking will start in the next era.</string>

feature-staking-impl/src/main/java/jp/co/soramitsu/feature_staking_impl/di/StakingFeatureModule.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ import jp.co.soramitsu.feature_staking_impl.data.repository.StakingRewardsReposi
3030
import jp.co.soramitsu.feature_staking_impl.data.repository.SubscanPagedSynchronizer
3131
import jp.co.soramitsu.feature_staking_impl.data.repository.datasource.StakingRewardsDataSource
3232
import jp.co.soramitsu.feature_staking_impl.data.repository.datasource.StakingRewardsSubscanDataSourceImpl
33-
import jp.co.soramitsu.feature_staking_impl.data.repository.datasource.SubqueryStakingRewardsDataSource
3433
import jp.co.soramitsu.feature_staking_impl.data.repository.datasource.StakingStoriesDataSource
3534
import jp.co.soramitsu.feature_staking_impl.data.repository.datasource.StakingStoriesDataSourceImpl
35+
import jp.co.soramitsu.feature_staking_impl.data.repository.datasource.SubqueryStakingRewardsDataSource
3636
import jp.co.soramitsu.feature_staking_impl.domain.AlertsInteractor
3737
import jp.co.soramitsu.feature_staking_impl.domain.StakingInteractor
3838
import jp.co.soramitsu.feature_staking_impl.domain.payout.PayoutInteractor
@@ -149,9 +149,10 @@ class StakingFeatureModule {
149149
@FeatureScope
150150
fun provideAlertsInteractor(
151151
stakingRepository: StakingRepository,
152-
stakingConstantsRepository: StakingConstantsRepository
152+
stakingConstantsRepository: StakingConstantsRepository,
153+
walletRepository: WalletRepository
153154
) = AlertsInteractor(
154-
stakingRepository, stakingConstantsRepository
155+
stakingRepository, stakingConstantsRepository, walletRepository
155156
)
156157

157158
@Provides

feature-staking-impl/src/main/java/jp/co/soramitsu/feature_staking_impl/domain/Alert.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package jp.co.soramitsu.feature_staking_impl.domain
22

3+
import jp.co.soramitsu.feature_wallet_api.domain.model.Token
4+
import java.math.BigDecimal
5+
36
sealed class Alert {
7+
8+
class RedeemTokens(val amount: BigDecimal, val token: Token) : Alert()
9+
410
object ChangeValidators : Alert()
511

612
object Election : Alert()

feature-staking-impl/src/main/java/jp/co/soramitsu/feature_staking_impl/domain/AlertsInteractor.kt

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,53 +6,71 @@ import jp.co.soramitsu.feature_staking_api.domain.model.Election
66
import jp.co.soramitsu.feature_staking_api.domain.model.Exposure
77
import jp.co.soramitsu.feature_staking_api.domain.model.StakingState
88
import jp.co.soramitsu.feature_staking_impl.data.repository.StakingConstantsRepository
9+
import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletRepository
10+
import jp.co.soramitsu.feature_wallet_api.domain.model.Asset
11+
import jp.co.soramitsu.feature_wallet_api.domain.model.Token
912
import kotlinx.coroutines.flow.Flow
1013
import kotlinx.coroutines.flow.combine
1114
import kotlinx.coroutines.flow.emitAll
1215
import kotlinx.coroutines.flow.flow
16+
import java.math.BigDecimal
1317

1418
class AlertsInteractor(
1519
private val stakingRepository: StakingRepository,
16-
private val stakingConstantsRepository: StakingConstantsRepository
20+
private val stakingConstantsRepository: StakingConstantsRepository,
21+
private val walletRepository: WalletRepository,
1722
) {
1823

1924
class AlertContext(
2025
val election: Election,
2126
val exposures: Map<String, Exposure>,
2227
val stakingState: StakingState,
2328
val maxRewardedNominatorsPerValidator: Int,
29+
val asset: Asset
2430
)
2531

2632
private fun produceElectionAlert(context: AlertContext): Alert? {
2733
return if (context.election == Election.OPEN) Alert.Election else null
2834
}
2935

30-
private fun produceValidatorsAlert(context: AlertContext): Alert? = requireState(context.stakingState) { stashState: StakingState.Stash ->
31-
with(context) {
32-
Alert.ChangeValidators.takeUnless {
33-
isNominationActive(stashState.stashId, exposures.values, maxRewardedNominatorsPerValidator)
36+
private fun produceChangeValidatorsAlert(context: AlertContext): Alert? {
37+
return requireState(context.stakingState) { nominatorState: StakingState.Stash.Nominator ->
38+
with(context) {
39+
Alert.ChangeValidators.takeUnless {
40+
isNominationActive(nominatorState.stashId, exposures.values, maxRewardedNominatorsPerValidator)
41+
}
3442
}
3543
}
3644
}
3745

46+
private fun produceRedeemableAlert(context: AlertContext): Alert? = requireState(context.stakingState) { _: StakingState.Stash ->
47+
with(context.asset) {
48+
if (redeemable > BigDecimal.ZERO) Alert.RedeemTokens(redeemable, token) else null
49+
}
50+
}
51+
3852
private val alertProducers = listOf(
3953
::produceElectionAlert,
40-
::produceValidatorsAlert
54+
::produceChangeValidatorsAlert,
55+
::produceRedeemableAlert
4156
)
4257

4358
fun getAlertsFlow(stakingState: StakingState): Flow<List<Alert>> = flow {
4459
val networkType = stakingState.accountAddress.networkType()
60+
val token = Token.Type.fromNetworkType(networkType)
4561
val maxRewardedNominatorsPerValidator = stakingConstantsRepository.maxRewardedNominatorPerValidator()
4662

4763
val alertsFlow = combine(
4864
stakingRepository.electionFlow(networkType),
49-
stakingRepository.electedExposuresInActiveEra
50-
) { electionStatus, changeValidators ->
65+
stakingRepository.electedExposuresInActiveEra,
66+
walletRepository.assetFlow(stakingState.accountAddress, token)
67+
) { electionStatus, changeValidators, asset ->
5168

52-
val context = AlertContext(electionStatus, changeValidators, stakingState, maxRewardedNominatorsPerValidator)
69+
val context = AlertContext(electionStatus, changeValidators, stakingState, maxRewardedNominatorsPerValidator, asset)
5370

5471
alertProducers.mapNotNull { it.invoke(context) }
5572
}
73+
5674
emitAll(alertsFlow)
5775
}
5876

feature-staking-impl/src/main/java/jp/co/soramitsu/feature_staking_impl/presentation/StakingRouter.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import jp.co.soramitsu.feature_staking_impl.presentation.staking.bond.confirm.Co
66
import jp.co.soramitsu.feature_staking_impl.presentation.staking.controller.confirm.ConfirmSetControllerPayload
77
import jp.co.soramitsu.feature_staking_impl.presentation.staking.main.model.StakingStoryModel
88
import jp.co.soramitsu.feature_staking_impl.presentation.staking.rebond.confirm.ConfirmRebondPayload
9+
import jp.co.soramitsu.feature_staking_impl.presentation.staking.redeem.RedeemPayload
910
import jp.co.soramitsu.feature_staking_impl.presentation.staking.rewardDestination.confirm.parcel.ConfirmRewardDestinationPayload
1011
import jp.co.soramitsu.feature_staking_impl.presentation.staking.unbond.confirm.ConfirmUnbondPayload
1112
import jp.co.soramitsu.feature_staking_impl.presentation.validators.parcel.ValidatorDetailsParcelModel
@@ -46,7 +47,7 @@ interface StakingRouter {
4647

4748
fun openConfirmUnbond(payload: ConfirmUnbondPayload)
4849

49-
fun openRedeem()
50+
fun openRedeem(payload: RedeemPayload)
5051

5152
fun openConfirmRebond(payload: ConfirmRebondPayload)
5253

feature-staking-impl/src/main/java/jp/co/soramitsu/feature_staking_impl/presentation/staking/alerts/AlertsAdapter.kt

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@ import androidx.recyclerview.widget.DiffUtil
66
import androidx.recyclerview.widget.ListAdapter
77
import androidx.recyclerview.widget.RecyclerView
88
import jp.co.soramitsu.common.utils.inflateChild
9+
import jp.co.soramitsu.common.utils.makeGone
910
import jp.co.soramitsu.common.utils.makeVisible
11+
import jp.co.soramitsu.common.utils.setVisible
1012
import jp.co.soramitsu.feature_staking_impl.R
1113
import jp.co.soramitsu.feature_staking_impl.presentation.staking.alerts.model.AlertModel
1214
import kotlinx.android.extensions.LayoutContainer
13-
import kotlinx.android.synthetic.main.item_alert.view.*
15+
import kotlinx.android.synthetic.main.item_alert.view.alertItemDivider
16+
import kotlinx.android.synthetic.main.item_alert.view.alertItemGoToFlowIcon
17+
import kotlinx.android.synthetic.main.item_alert.view.alertItemMessage
18+
import kotlinx.android.synthetic.main.item_alert.view.alertItemTitle
19+
import kotlinx.android.synthetic.main.item_alert.view.imageView
1420

1521
class AlertsAdapter : ListAdapter<AlertModel, AlertsAdapter.AlertViewHolder>(AlertDiffCallback()) {
1622

@@ -21,21 +27,30 @@ class AlertsAdapter : ListAdapter<AlertModel, AlertsAdapter.AlertViewHolder>(Ale
2127
}
2228

2329
override fun onBindViewHolder(holder: AlertViewHolder, position: Int) {
30+
val isLast = position == itemCount - 1
31+
2432
val item = getItem(position)
2533

26-
holder.bind(item)
34+
holder.bind(item, isLast)
2735
}
2836

2937
class AlertViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer {
30-
fun bind(alert: AlertModel) = with(containerView) {
38+
fun bind(alert: AlertModel, isLast: Boolean) = with(containerView) {
3139
imageView.setImageResource(alert.icon)
32-
alertItemTitle.setText(alert.title)
33-
alertItemMessage.setText(alert.extraMessage)
40+
alertItemTitle.text = alert.title
41+
alertItemMessage.text = alert.extraMessage
3442

3543
if (alert.type is AlertModel.Type.CallToAction) {
3644
alertItemGoToFlowIcon.makeVisible()
37-
setOnClickListener(alert.type.action)
45+
46+
setOnClickListener {
47+
alert.type.action()
48+
}
49+
} else {
50+
alertItemGoToFlowIcon.makeGone()
3851
}
52+
53+
alertItemDivider.setVisible(isLast.not())
3954
}
4055
}
4156
}
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
package jp.co.soramitsu.feature_staking_impl.presentation.staking.alerts.model
22

3-
import android.view.View
43
import androidx.annotation.DrawableRes
5-
import androidx.annotation.StringRes
64

75
class AlertModel(
86
@DrawableRes val icon: Int,
9-
@StringRes val title: Int,
10-
@StringRes val extraMessage: Int,
7+
val title: String,
8+
val extraMessage: String,
119
val type: Type
1210
) {
1311
sealed class Type {
1412
object Warning : Type()
1513

16-
class CallToAction(val action: (View) -> Unit) : Type()
14+
class CallToAction(val action: () -> Unit) : Type()
1715
}
1816
}

0 commit comments

Comments
 (0)