From ec7491c5e3f8ab45bbae50cbeecfda2bc16fcbfb Mon Sep 17 00:00:00 2001 From: antonijzelinskij Date: Fri, 4 Oct 2024 13:35:30 +0200 Subject: [PATCH 1/6] Referendum Summary Backend --- .../di/modules/shared/MarkdownFullModule.kt | 4 +- .../di/modules/shared/MarkdownShortModule.kt | 4 +- .../nova/common/utils/SpannableExt.kt | 2 +- .../common/utils/markdown/BoldStylePlugin.kt | 36 ++++ .../{StylePlugin.kt => LinkStylePlugin.kt} | 2 +- common/src/main/res/values/colors.xml | 1 + .../summary/ReferendaSummaryInteractor.kt | 9 + .../tindergov/TinderGovBasketInteractor.kt | 28 +++ .../domain/tindergov/TinderGovInteractor.kt | 22 +- feature-governance-impl/build.gradle | 4 +- .../summary/v2/ReferendumSummaryApi.kt | 22 +- .../summary/v2/ReferendumSummaryDataSource.kt | 38 +++- .../summary/v2/ReferendumSummaryResponse.kt | 3 - .../v2/request/ReferendumSummariesRequest.kt | 7 + .../v2/request/ReferendumSummaryRequest.kt | 7 + .../v2/response/ReferendumSummaryResponse.kt | 3 + .../di/modules/screens/TinderGovModule.kt | 60 +++++- .../details/ReferendumDetailsRepository.kt | 13 +- .../RealTinderGovBasketInteractor.kt | 125 ++++++++++++ .../tindergov/RealTinderGovInteractor.kt | 85 +------- .../ReferendaSummarySharedComputation.kt | 30 +++ .../summary/ReferendumSummaryInteractor.kt | 17 ++ .../common/info/di/DescriptionComponent.kt | 1 + .../common/info/di/DescriptionModule.kt | 2 +- .../referenda/list/ReferendaListViewModel.kt | 25 ++- .../referenda/list/di/ReferendaListModule.kt | 7 +- .../basket/TinderGovBasketViewModel.kt | 12 +- .../basket/di/TinderGovBasketModule.kt | 7 +- .../cards/TinderGovCardDetailsLoader.kt | 131 ------------ .../cards/TinderGovCardsViewModel.kt | 191 +++++------------- .../cards/adapter/TinderGovCardRvItem.kt | 5 +- .../cards/adapter/TinderGovCardsAdapter.kt | 14 +- .../cards/di/TinderGovCardsModule.kt | 48 +++-- .../tindergov/cards/model/CardWithDetails.kt | 25 +++ .../cards/model/ReferendaCounterModel.kt | 14 ++ .../cards/model/ReferendaWithBasket.kt | 9 + .../confirm/ConfirmTinderGovVoteViewModel.kt | 6 +- .../confirm/di/ConfirmTinderGovVoteModule.kt | 3 + .../main/res/layout/item_tinder_gov_card.xml | 77 +------ 39 files changed, 558 insertions(+), 541 deletions(-) create mode 100644 common/src/main/java/io/novafoundation/nova/common/utils/markdown/BoldStylePlugin.kt rename common/src/main/java/io/novafoundation/nova/common/utils/markdown/{StylePlugin.kt => LinkStylePlugin.kt} (83%) create mode 100644 feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/referendum/summary/ReferendaSummaryInteractor.kt create mode 100644 feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovBasketInteractor.kt delete mode 100644 feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryResponse.kt create mode 100644 feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/request/ReferendumSummariesRequest.kt create mode 100644 feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/request/ReferendumSummaryRequest.kt create mode 100644 feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/response/ReferendumSummaryResponse.kt create mode 100644 feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovBasketInteractor.kt create mode 100644 feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummarySharedComputation.kt create mode 100644 feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendumSummaryInteractor.kt delete mode 100644 feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/TinderGovCardDetailsLoader.kt create mode 100644 feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/CardWithDetails.kt create mode 100644 feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/ReferendaCounterModel.kt create mode 100644 feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/ReferendaWithBasket.kt diff --git a/common/src/main/java/io/novafoundation/nova/common/di/modules/shared/MarkdownFullModule.kt b/common/src/main/java/io/novafoundation/nova/common/di/modules/shared/MarkdownFullModule.kt index a7ff47a32c..021e90d6a1 100644 --- a/common/src/main/java/io/novafoundation/nova/common/di/modules/shared/MarkdownFullModule.kt +++ b/common/src/main/java/io/novafoundation/nova/common/di/modules/shared/MarkdownFullModule.kt @@ -12,7 +12,7 @@ import io.noties.markwon.html.HtmlPlugin import io.noties.markwon.image.coil.CoilImagesPlugin import io.noties.markwon.linkify.LinkifyPlugin import io.novafoundation.nova.common.di.scope.ScreenScope -import io.novafoundation.nova.common.utils.markdown.StylePlugin +import io.novafoundation.nova.common.utils.markdown.LinkStylePlugin @Module class MarkdownFullModule { @@ -22,7 +22,7 @@ class MarkdownFullModule { fun provideMarkwon(context: Context, imageLoader: ImageLoader): Markwon { return Markwon.builder(context) .usePlugin(LinkifyPlugin.create(Linkify.EMAIL_ADDRESSES or Linkify.WEB_URLS)) - .usePlugin(StylePlugin(context)) + .usePlugin(LinkStylePlugin(context)) .usePlugin(CoilImagesPlugin.create(context, imageLoader)) .usePlugin(StrikethroughPlugin.create()) .usePlugin(TablePlugin.create(context)) diff --git a/common/src/main/java/io/novafoundation/nova/common/di/modules/shared/MarkdownShortModule.kt b/common/src/main/java/io/novafoundation/nova/common/di/modules/shared/MarkdownShortModule.kt index 1e99ea3d23..8b7c46127d 100644 --- a/common/src/main/java/io/novafoundation/nova/common/di/modules/shared/MarkdownShortModule.kt +++ b/common/src/main/java/io/novafoundation/nova/common/di/modules/shared/MarkdownShortModule.kt @@ -10,7 +10,7 @@ import io.noties.markwon.html.HtmlPlugin import io.noties.markwon.linkify.LinkifyPlugin import io.novafoundation.nova.common.di.scope.ScreenScope import io.novafoundation.nova.common.utils.markdown.RemoveHtmlTagsPlugin -import io.novafoundation.nova.common.utils.markdown.StylePlugin +import io.novafoundation.nova.common.utils.markdown.LinkStylePlugin private const val IMG_HTML_TAG = "img" private const val TABLE_HTML_TAG = "table" @@ -24,7 +24,7 @@ class MarkdownShortModule { return Markwon.builder(context) .usePlugin(RemoveHtmlTagsPlugin(IMG_HTML_TAG, TABLE_HTML_TAG)) .usePlugin(LinkifyPlugin.create(Linkify.EMAIL_ADDRESSES or Linkify.WEB_URLS)) - .usePlugin(StylePlugin(context)) + .usePlugin(LinkStylePlugin(context)) .usePlugin(StrikethroughPlugin.create()) .usePlugin(HtmlPlugin.create()) .build() diff --git a/common/src/main/java/io/novafoundation/nova/common/utils/SpannableExt.kt b/common/src/main/java/io/novafoundation/nova/common/utils/SpannableExt.kt index cd6628b004..2e07f471bd 100644 --- a/common/src/main/java/io/novafoundation/nova/common/utils/SpannableExt.kt +++ b/common/src/main/java/io/novafoundation/nova/common/utils/SpannableExt.kt @@ -91,7 +91,7 @@ fun CharSequence.formatAsSpannable(vararg args: Any): SpannedString { private fun typefaceSpanCompatV28(typeface: Typeface) = TypefaceSpan(typeface) -private class CustomTypefaceSpan(private val typeface: Typeface?) : MetricAffectingSpan() { +class CustomTypefaceSpan(private val typeface: Typeface?) : MetricAffectingSpan() { override fun updateDrawState(paint: TextPaint) { paint.typeface = typeface } diff --git a/common/src/main/java/io/novafoundation/nova/common/utils/markdown/BoldStylePlugin.kt b/common/src/main/java/io/novafoundation/nova/common/utils/markdown/BoldStylePlugin.kt new file mode 100644 index 0000000000..175aa58839 --- /dev/null +++ b/common/src/main/java/io/novafoundation/nova/common/utils/markdown/BoldStylePlugin.kt @@ -0,0 +1,36 @@ +package io.novafoundation.nova.common.utils.markdown + +import android.content.Context +import androidx.annotation.ColorRes +import androidx.annotation.FontRes +import androidx.core.content.res.ResourcesCompat +import io.noties.markwon.AbstractMarkwonPlugin +import io.noties.markwon.MarkwonConfiguration +import io.noties.markwon.MarkwonSpansFactory +import io.noties.markwon.RenderProps +import io.noties.markwon.SpanFactory +import io.novafoundation.nova.common.utils.colorSpan +import io.novafoundation.nova.common.utils.fontSpan +import org.commonmark.node.StrongEmphasis + +class BoldStylePlugin( + private val context: Context, + @FontRes private val typefaceRes: Int, + @ColorRes private val colorRes: Int +) : AbstractMarkwonPlugin() { + + override fun configureSpansFactory(builder: MarkwonSpansFactory.Builder) { + builder.setFactory(StrongEmphasis::class.java, BoldSpanFactory(context, typefaceRes, colorRes)) + } +} + +private class BoldSpanFactory(private val context: Context, private val typefaceRes: Int, private val colorRes: Int) : SpanFactory { + + override fun getSpans(configuration: MarkwonConfiguration, props: RenderProps): Any { + val font = ResourcesCompat.getFont(context, typefaceRes) + return arrayOf( + fontSpan(font), + colorSpan(context.getColor(colorRes)) + ) + } +} diff --git a/common/src/main/java/io/novafoundation/nova/common/utils/markdown/StylePlugin.kt b/common/src/main/java/io/novafoundation/nova/common/utils/markdown/LinkStylePlugin.kt similarity index 83% rename from common/src/main/java/io/novafoundation/nova/common/utils/markdown/StylePlugin.kt rename to common/src/main/java/io/novafoundation/nova/common/utils/markdown/LinkStylePlugin.kt index 35342a35aa..20dd2afce4 100644 --- a/common/src/main/java/io/novafoundation/nova/common/utils/markdown/StylePlugin.kt +++ b/common/src/main/java/io/novafoundation/nova/common/utils/markdown/LinkStylePlugin.kt @@ -5,7 +5,7 @@ import io.noties.markwon.AbstractMarkwonPlugin import io.noties.markwon.core.MarkwonTheme import io.novafoundation.nova.common.R -class StylePlugin(private val context: Context) : AbstractMarkwonPlugin() { +class LinkStylePlugin(private val context: Context) : AbstractMarkwonPlugin() { override fun configureTheme(builder: MarkwonTheme.Builder) { builder.isLinkUnderlined(false) diff --git a/common/src/main/res/values/colors.xml b/common/src/main/res/values/colors.xml index d4a61eff3a..65457f8835 100644 --- a/common/src/main/res/values/colors.xml +++ b/common/src/main/res/values/colors.xml @@ -36,6 +36,7 @@ #A3FFFFFF #A3FFFFFF #52FFFFFF + #A3FFFFFF #BD387F #FF7A00 diff --git a/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/referendum/summary/ReferendaSummaryInteractor.kt b/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/referendum/summary/ReferendaSummaryInteractor.kt new file mode 100644 index 0000000000..f48bd44c41 --- /dev/null +++ b/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/referendum/summary/ReferendaSummaryInteractor.kt @@ -0,0 +1,9 @@ +package io.novafoundation.nova.feature_governance_api.domain.referendum.summary + +import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId +import kotlinx.coroutines.CoroutineScope + +interface ReferendaSummaryInteractor { + + suspend fun getReferendaSummaries(ids: List, coroutineScope: CoroutineScope): Map +} diff --git a/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovBasketInteractor.kt b/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovBasketInteractor.kt new file mode 100644 index 0000000000..5b50b879b4 --- /dev/null +++ b/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovBasketInteractor.kt @@ -0,0 +1,28 @@ +package io.novafoundation.nova.feature_governance_api.domain.tindergov + +import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem +import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId +import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.VoteType +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow + +interface TinderGovBasketInteractor { + + fun observeTinderGovBasket(): Flow> + + suspend fun getTinderGovBasket(): List + + suspend fun addItemToBasket(referendumId: ReferendumId, voteType: VoteType) + + suspend fun removeReferendumFromBasket(item: TinderGovBasketItem) + + suspend fun removeBasketItems(items: Collection) + + suspend fun isBasketEmpty(): Boolean + + suspend fun clearBasket() + + suspend fun getBasketItemsToRemove(coroutineScope: CoroutineScope): List + + suspend fun awaitAllItemsVoted(coroutineScope: CoroutineScope, basket: List) +} diff --git a/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovInteractor.kt b/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovInteractor.kt index e5b0590e07..b39ff415cd 100644 --- a/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovInteractor.kt +++ b/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovInteractor.kt @@ -2,8 +2,6 @@ package io.novafoundation.nova.feature_governance_api.domain.tindergov import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem import io.novafoundation.nova.feature_governance_api.data.model.VotingPower -import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId -import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.VoteType import io.novafoundation.nova.feature_governance_api.domain.referendum.details.ReferendumCall import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendaState import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendumPreview @@ -26,15 +24,7 @@ interface TinderGovInteractor { fun observeReferendaAvailableToVote(coroutineScope: CoroutineScope): Flow> - fun observeTinderGovBasket(): Flow> - - suspend fun getTinderGovBasket(): List - - suspend fun addItemToBasket(referendumId: ReferendumId, voteType: VoteType) - - suspend fun loadReferendumSummary(id: ReferendumId): String? - - suspend fun loadReferendumAmount(referendumPreview: ReferendumPreview): ReferendumCall.TreasuryRequest? + suspend fun getReferendumAmount(referendumPreview: ReferendumPreview): ReferendumCall.TreasuryRequest? suspend fun setVotingPower(votingPower: VotingPower) @@ -42,15 +32,5 @@ interface TinderGovInteractor { suspend fun getVotingPowerState(): VotingPowerState - suspend fun removeReferendumFromBasket(item: TinderGovBasketItem) - - suspend fun removeBasketItems(items: Collection) - - suspend fun isBasketEmpty(): Boolean - - suspend fun clearBasket() - - suspend fun getBasketItemsToRemove(coroutineScope: CoroutineScope): List - suspend fun awaitAllItemsVoted(coroutineScope: CoroutineScope, basket: List) } diff --git a/feature-governance-impl/build.gradle b/feature-governance-impl/build.gradle index 732507ae42..1762eb3543 100644 --- a/feature-governance-impl/build.gradle +++ b/feature-governance-impl/build.gradle @@ -19,7 +19,7 @@ android { buildConfigField "String", "DELEGATION_TUTORIAL_URL", "\"https://docs.novawallet.io/nova-wallet-wiki/governance/add-delegate-information\"" - buildConfigField "String", "SUMMARY_API_KEY", readStringSecret("POLKASSEMBLY_SUMMARY_API_KEY") + buildConfigField "String", "OPENGOV_API_URL", "\"https://opengov-backend-dev.novasama-tech.org\"" } buildTypes { @@ -28,6 +28,8 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' buildConfigField "String", "GOVERNANCE_DAPPS_URL", "\"https://raw.githubusercontent.com/novasamatech/nova-utils/master/governance/v2/dapps.json\"" + + buildConfigField "String", "OPENGOV_API_URL", "\"https://opengov-backend.novasama-tech.org\"" } } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryApi.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryApi.kt index 27762de251..82ebd4da05 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryApi.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryApi.kt @@ -1,18 +1,20 @@ package io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2 -import retrofit2.http.GET -import retrofit2.http.Header -import retrofit2.http.Query -import retrofit2.http.Url +import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request.ReferendumSummariesRequest +import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request.ReferendumSummaryRequest +import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.response.ReferendumSummaryResponse +import retrofit2.http.Body +import retrofit2.http.POST interface ReferendumSummaryApi { - @GET + @POST("/not-secure/api/v1/referendum-summaries/single") suspend fun getReferendumSummary( - @Url url: String, - @Header("x-network") networkHeader: String?, - @Header("x-ai-summary-api-key") summaryApiKey: String, - @Query("postId") postId: Int, - @Query("proposalType") proposalType: String = "referendums_v2" + @Body body: ReferendumSummaryRequest ): ReferendumSummaryResponse + + @POST("/not-secure/api/v1/referendum-summaries/list") + suspend fun getReferendumSummaries( + @Body body: ReferendumSummariesRequest + ): List } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt index f54d2ec555..6296f902eb 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt @@ -1,27 +1,43 @@ package io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2 import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId -import io.novafoundation.nova.feature_governance_impl.BuildConfig -import io.novafoundation.nova.runtime.ext.summaryApiOrNull +import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request.ReferendumSummariesRequest +import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request.ReferendumSummaryRequest import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain interface ReferendumSummaryDataSource { - suspend fun loadSummary(chain: Chain, id: ReferendumId, baseUrl: String): String + suspend fun loadSummary(chain: Chain, id: ReferendumId, languageCode: String): String + + suspend fun loadSummaries(chain: Chain, ids: List, languageCode: String): Map } class RealReferendumSummaryDataSource( val api: ReferendumSummaryApi ) : ReferendumSummaryDataSource { - override suspend fun loadSummary(chain: Chain, id: ReferendumId, baseUrl: String): String { - val externalApi = chain.summaryApiOrNull()!! + override suspend fun loadSummary(chain: Chain, id: ReferendumId, languageCode: String): String { + val response = api.getReferendumSummary( + ReferendumSummaryRequest( + chainId = chain.id, + languageIsoCode = languageCode, + referendumId = id.value.toString() + ) + ) + + return response.summary + } + + override suspend fun loadSummaries(chain: Chain, ids: List, languageCode: String): Map { + val response = api.getReferendumSummaries( + ReferendumSummariesRequest( + chainId = chain.id, + languageIsoCode = languageCode, + referendumIds = ids.map { it.value.toString() } + ) + ) - return api.getReferendumSummary( - baseUrl, - networkHeader = externalApi.network, - summaryApiKey = BuildConfig.SUMMARY_API_KEY, - postId = id.value.toInt() - ).summary + return response.associateBy { ReferendumId(it.referendumId.toBigInteger()) } + .mapValues { it.value.summary } } } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryResponse.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryResponse.kt deleted file mode 100644 index 1e5beed9e8..0000000000 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryResponse.kt +++ /dev/null @@ -1,3 +0,0 @@ -package io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2 - -class ReferendumSummaryResponse(val summary: String) diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/request/ReferendumSummariesRequest.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/request/ReferendumSummariesRequest.kt new file mode 100644 index 0000000000..ac7acfa234 --- /dev/null +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/request/ReferendumSummariesRequest.kt @@ -0,0 +1,7 @@ +package io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request + +class ReferendumSummariesRequest( + val chainId: String, + val languageIsoCode: String, + val referendumIds: List +) diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/request/ReferendumSummaryRequest.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/request/ReferendumSummaryRequest.kt new file mode 100644 index 0000000000..a25e2113fb --- /dev/null +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/request/ReferendumSummaryRequest.kt @@ -0,0 +1,7 @@ +package io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request + +class ReferendumSummaryRequest( + val chainId: String, + val languageIsoCode: String, + val referendumId: String +) diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/response/ReferendumSummaryResponse.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/response/ReferendumSummaryResponse.kt new file mode 100644 index 0000000000..d1fcb1ec92 --- /dev/null +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/response/ReferendumSummaryResponse.kt @@ -0,0 +1,3 @@ +package io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.response + +class ReferendumSummaryResponse(val referendumId: Int, val summary: String) diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt index 1027cd974c..f30467b97c 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt @@ -2,11 +2,15 @@ package io.novafoundation.nova.feature_governance_impl.di.modules.screens import dagger.Module import dagger.Provides +import io.novafoundation.nova.common.data.memory.ComputationalCache import io.novafoundation.nova.common.data.network.NetworkApiCreator import io.novafoundation.nova.common.di.scope.FeatureScope import io.novafoundation.nova.core_db.dao.TinderGovDao import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository +import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor +import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor +import io.novafoundation.nova.feature_governance_impl.BuildConfig import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.RealReferendumSummaryDataSource import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.ReferendumSummaryApi @@ -20,9 +24,11 @@ import io.novafoundation.nova.feature_governance_impl.domain.referendum.details. import io.novafoundation.nova.feature_governance_impl.domain.referendum.details.call.ReferendumPreImageParser import io.novafoundation.nova.feature_governance_impl.domain.referendum.list.ReferendaSharedComputation import io.novafoundation.nova.feature_governance_impl.domain.referendum.list.filtering.ReferendaFilteringProvider +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.RealTinderGovBasketInteractor import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.RealTinderGovInteractor +import io.novafoundation.nova.feature_governance_impl.domain.summary.RealReferendaSummaryInteractor +import io.novafoundation.nova.feature_governance_impl.domain.summary.ReferendaSummarySharedComputation import io.novafoundation.nova.feature_wallet_api.domain.AssetUseCase -import io.novafoundation.nova.feature_wallet_api.domain.interfaces.WalletRepository @Module class TinderGovModule { @@ -30,7 +36,7 @@ class TinderGovModule { @Provides @FeatureScope fun provideReferendumSummaryApi(apiCreator: NetworkApiCreator): ReferendumSummaryApi { - return apiCreator.create(ReferendumSummaryApi::class.java) + return apiCreator.create(ReferendumSummaryApi::class.java, customBaseUrl = BuildConfig.OPENGOV_API_URL) } @Provides @@ -69,10 +75,7 @@ class TinderGovModule { governanceSharedState: GovernanceSharedState, referendaSharedComputation: ReferendaSharedComputation, accountRepository: AccountRepository, - referendumDetailsRepository: ReferendumDetailsRepository, preImageParser: ReferendumPreImageParser, - tinderGovBasketRepository: TinderGovBasketRepository, - walletRepository: WalletRepository, tinderGovVotingPowerRepository: TinderGovVotingPowerRepository, referendaFilteringProvider: ReferendaFilteringProvider, assetUseCase: AssetUseCase @@ -80,12 +83,53 @@ class TinderGovModule { governanceSharedState, referendaSharedComputation, accountRepository, - referendumDetailsRepository, preImageParser, - tinderGovBasketRepository, - walletRepository, tinderGovVotingPowerRepository, referendaFilteringProvider, assetUseCase ) + + @Provides + @FeatureScope + fun provideReferendaSummarySharedComputation( + computationalCache: ComputationalCache, + referendumDetailsRepository: ReferendumDetailsRepository, + accountRepository: AccountRepository + ) = ReferendaSummarySharedComputation( + computationalCache, + referendumDetailsRepository, + accountRepository + ) + + @Provides + @FeatureScope + fun provideReferendaSummaryInteractor( + governanceSharedState: GovernanceSharedState, + referendaSummarySharedComputation: ReferendaSummarySharedComputation + ): ReferendaSummaryInteractor = RealReferendaSummaryInteractor( + governanceSharedState, + referendaSummarySharedComputation + ) + + @Provides + @FeatureScope + fun provideTinderGovBasketInteractor( + governanceSharedState: GovernanceSharedState, + referendaSharedComputation: ReferendaSharedComputation, + accountRepository: AccountRepository, + tinderGovBasketRepository: TinderGovBasketRepository, + tinderGovVotingPowerRepository: TinderGovVotingPowerRepository, + referendaFilteringProvider: ReferendaFilteringProvider, + assetUseCase: AssetUseCase, + tinderGovInteractor: TinderGovInteractor + ): TinderGovBasketInteractor = RealTinderGovBasketInteractor( + governanceSharedState = governanceSharedState, + referendaSharedComputation = referendaSharedComputation, + accountRepository = accountRepository, + tinderGovBasketRepository = tinderGovBasketRepository, + tinderGovVotingPowerRepository = tinderGovVotingPowerRepository, + referendaFilteringProvider = referendaFilteringProvider, + assetUseCase = assetUseCase, + tinderGovInteractor = tinderGovInteractor + ) } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/details/ReferendumDetailsRepository.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/details/ReferendumDetailsRepository.kt index e3aaf1dcd4..2aa19932e3 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/details/ReferendumDetailsRepository.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/details/ReferendumDetailsRepository.kt @@ -1,19 +1,26 @@ package io.novafoundation.nova.feature_governance_impl.domain.referendum.details +import io.novafoundation.nova.core.model.Language import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.ReferendumSummaryDataSource import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain interface ReferendumDetailsRepository { - suspend fun loadSummary(chain: Chain, id: ReferendumId, baseUrl: String): String + suspend fun loadSummary(chain: Chain, id: ReferendumId, selectedLanguage: Language): String + + suspend fun loadSummaries(chain: Chain, ids: List, selectedLanguage: Language): Map } class RealReferendumDetailsRepository( private val referendumSummaryDataSource: ReferendumSummaryDataSource ) : ReferendumDetailsRepository { - override suspend fun loadSummary(chain: Chain, id: ReferendumId, baseUrl: String): String { - return referendumSummaryDataSource.loadSummary(chain, id, baseUrl) + override suspend fun loadSummary(chain: Chain, id: ReferendumId, selectedLanguage: Language): String { + return referendumSummaryDataSource.loadSummary(chain, id, selectedLanguage.iso639Code) + } + + override suspend fun loadSummaries(chain: Chain, ids: List, selectedLanguage: Language): Map { + return referendumSummaryDataSource.loadSummaries(chain, ids, selectedLanguage.iso639Code) } } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovBasketInteractor.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovBasketInteractor.kt new file mode 100644 index 0000000000..6fc41f2cac --- /dev/null +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovBasketInteractor.kt @@ -0,0 +1,125 @@ +package io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov + +import io.novafoundation.nova.common.utils.flowOfAll +import io.novafoundation.nova.common.utils.mapToSet +import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository +import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem +import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId +import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.VoteType +import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor +import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor +import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState +import io.novafoundation.nova.feature_governance_impl.data.repository.tindergov.TinderGovBasketRepository +import io.novafoundation.nova.feature_governance_impl.data.repository.tindergov.TinderGovVotingPowerRepository +import io.novafoundation.nova.feature_governance_impl.domain.referendum.list.ReferendaSharedComputation +import io.novafoundation.nova.feature_governance_impl.domain.referendum.list.filtering.ReferendaFilteringProvider +import io.novafoundation.nova.feature_wallet_api.domain.AssetUseCase +import io.novafoundation.nova.feature_wallet_api.domain.getCurrentAsset +import io.novafoundation.nova.feature_wallet_api.domain.model.Asset +import io.novafoundation.nova.feature_wallet_api.domain.model.availableToVote +import io.novafoundation.nova.runtime.state.chain +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.first + +class RealTinderGovBasketInteractor( + private val governanceSharedState: GovernanceSharedState, + private val referendaSharedComputation: ReferendaSharedComputation, + private val accountRepository: AccountRepository, + private val tinderGovBasketRepository: TinderGovBasketRepository, + private val tinderGovVotingPowerRepository: TinderGovVotingPowerRepository, + private val referendaFilteringProvider: ReferendaFilteringProvider, + private val assetUseCase: AssetUseCase, + private val tinderGovInteractor: TinderGovInteractor +) : TinderGovBasketInteractor { + + override fun observeTinderGovBasket(): Flow> { + return flowOfAll { + val metaAccount = accountRepository.getSelectedMetaAccount() + val chain = governanceSharedState.chain() + + tinderGovBasketRepository.observeBasket(metaAccount.id, chain.id) + } + } + + override suspend fun getTinderGovBasket(): List { + val metaAccount = accountRepository.getSelectedMetaAccount() + val chain = governanceSharedState.chain() + + return tinderGovBasketRepository.getBasket(metaAccount.id, chain.id) + } + + override suspend fun addItemToBasket(referendumId: ReferendumId, voteType: VoteType) { + val metaAccount = accountRepository.getSelectedMetaAccount() + val chain = governanceSharedState.chain() + + val votingPower = tinderGovVotingPowerRepository.getVotingPower(metaAccount.id, chain.id)!! + + tinderGovBasketRepository.add( + TinderGovBasketItem( + metaId = metaAccount.id, + chainId = chain.id, + referendumId = referendumId, + voteType = voteType, + conviction = votingPower.conviction, + amount = votingPower.amount + ) + ) + } + + override suspend fun removeReferendumFromBasket(item: TinderGovBasketItem) { + tinderGovBasketRepository.remove(item) + } + + override suspend fun removeBasketItems(items: Collection) { + tinderGovBasketRepository.remove(items) + } + + override suspend fun isBasketEmpty(): Boolean { + val metaAccount = accountRepository.getSelectedMetaAccount() + val chain = governanceSharedState.chain() + + return tinderGovBasketRepository.isBasketEmpty(metaAccount.id, chain.id) + } + + override suspend fun clearBasket() { + val metaAccount = accountRepository.getSelectedMetaAccount() + val chain = governanceSharedState.chain() + + tinderGovBasketRepository.clearBasket(metaAccount.id, chain.id) + } + + override suspend fun getBasketItemsToRemove(coroutineScope: CoroutineScope): List { + val metaAccount = accountRepository.getSelectedMetaAccount() + val chain = governanceSharedState.chain() + val asset = assetUseCase.getCurrentAsset() + val basket = tinderGovBasketRepository.getBasket(metaAccount.id, chain.id) + + val availableToVoteReferenda = tinderGovInteractor.observeReferendaAvailableToVote(coroutineScope).first() + .mapToSet { it.id } + + return basket.filter { it.isItemNotAvailableToVote(availableToVoteReferenda, asset) } + } + + override suspend fun awaitAllItemsVoted(coroutineScope: CoroutineScope, basket: List) { + tinderGovInteractor.observeReferendaState(coroutineScope) + .filter { referendaState -> + val referenda = referendaState.referenda.associateBy { it.id } + val allBasketItemsVoted = basket.all { + val referendum = referenda[it.referendumId] + referendum?.referendumVote != null + } + + allBasketItemsVoted + }.first() + } + + private fun TinderGovBasketItem.isItemNotAvailableToVote( + availableToVoteReferenda: Set, + asset: Asset + ): Boolean { + val notEnoughBalance = this.amount > asset.availableToVote() + return (this.referendumId !in availableToVoteReferenda) || notEnoughBalance + } +} diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovInteractor.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovInteractor.kt index fe8a9e616b..da58e90c66 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovInteractor.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovInteractor.kt @@ -2,12 +2,10 @@ package io.novafoundation.nova.feature_governance_impl.domain.referendum.tinderg import io.novafoundation.nova.common.domain.filterLoaded import io.novafoundation.nova.common.utils.flowOfAll -import io.novafoundation.nova.common.utils.mapToSet import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem import io.novafoundation.nova.feature_governance_api.data.model.VotingPower import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId -import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.VoteType import io.novafoundation.nova.feature_governance_api.domain.referendum.details.ReferendumCall import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendaState import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendumPreview @@ -17,18 +15,14 @@ import io.novafoundation.nova.feature_governance_api.domain.referendum.list.user import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_api.domain.tindergov.VotingPowerState import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState -import io.novafoundation.nova.feature_governance_impl.data.repository.tindergov.TinderGovBasketRepository import io.novafoundation.nova.feature_governance_impl.data.repository.tindergov.TinderGovVotingPowerRepository -import io.novafoundation.nova.feature_governance_impl.domain.referendum.details.ReferendumDetailsRepository import io.novafoundation.nova.feature_governance_impl.domain.referendum.details.call.ReferendumPreImageParser import io.novafoundation.nova.feature_governance_impl.domain.referendum.list.ReferendaSharedComputation import io.novafoundation.nova.feature_governance_impl.domain.referendum.list.filtering.ReferendaFilteringProvider import io.novafoundation.nova.feature_wallet_api.domain.AssetUseCase import io.novafoundation.nova.feature_wallet_api.domain.getCurrentAsset -import io.novafoundation.nova.feature_wallet_api.domain.interfaces.WalletRepository import io.novafoundation.nova.feature_wallet_api.domain.model.Asset import io.novafoundation.nova.feature_wallet_api.domain.model.availableToVote -import io.novafoundation.nova.runtime.ext.summaryApiOrNull import io.novafoundation.nova.runtime.multiNetwork.chain.model.ChainId import io.novafoundation.nova.runtime.state.chain import io.novafoundation.nova.runtime.state.selectedOption @@ -42,10 +36,7 @@ class RealTinderGovInteractor( private val governanceSharedState: GovernanceSharedState, private val referendaSharedComputation: ReferendaSharedComputation, private val accountRepository: AccountRepository, - private val referendumDetailsRepository: ReferendumDetailsRepository, private val preImageParser: ReferendumPreImageParser, - private val tinderGovBasketRepository: TinderGovBasketRepository, - private val walletRepository: WalletRepository, private val tinderGovVotingPowerRepository: TinderGovVotingPowerRepository, private val referendaFilteringProvider: ReferendaFilteringProvider, private val assetUseCase: AssetUseCase @@ -70,47 +61,7 @@ class RealTinderGovInteractor( .map { filterAvailableToVoteReferenda(it) } } - override fun observeTinderGovBasket(): Flow> { - return flowOfAll { - val metaAccount = accountRepository.getSelectedMetaAccount() - val chain = governanceSharedState.chain() - - tinderGovBasketRepository.observeBasket(metaAccount.id, chain.id) - } - } - - override suspend fun getTinderGovBasket(): List { - val metaAccount = accountRepository.getSelectedMetaAccount() - val chain = governanceSharedState.chain() - - return tinderGovBasketRepository.getBasket(metaAccount.id, chain.id) - } - - override suspend fun addItemToBasket(referendumId: ReferendumId, voteType: VoteType) { - val metaAccount = accountRepository.getSelectedMetaAccount() - val chain = governanceSharedState.chain() - - val votingPower = getVotingPower(metaAccount.id, chain.id)!! - - tinderGovBasketRepository.add( - TinderGovBasketItem( - metaId = metaAccount.id, - chainId = chain.id, - referendumId = referendumId, - voteType = voteType, - conviction = votingPower.conviction, - amount = votingPower.amount - ) - ) - } - - override suspend fun loadReferendumSummary(id: ReferendumId): String? { - val chain = governanceSharedState.chain() - val summaryApi = chain.summaryApiOrNull() ?: return null - return referendumDetailsRepository.loadSummary(chain, id, summaryApi.url) - } - - override suspend fun loadReferendumAmount(referendumPreview: ReferendumPreview): ReferendumCall.TreasuryRequest? { + override suspend fun getReferendumAmount(referendumPreview: ReferendumPreview): ReferendumCall.TreasuryRequest? { val selectedGovernanceOption = governanceSharedState.selectedOption() val chain = selectedGovernanceOption.assetWithChain.chain @@ -142,40 +93,6 @@ class RealTinderGovInteractor( } } - override suspend fun removeReferendumFromBasket(item: TinderGovBasketItem) { - tinderGovBasketRepository.remove(item) - } - - override suspend fun removeBasketItems(items: Collection) { - tinderGovBasketRepository.remove(items) - } - - override suspend fun isBasketEmpty(): Boolean { - val metaAccount = accountRepository.getSelectedMetaAccount() - val chain = governanceSharedState.chain() - - return tinderGovBasketRepository.isBasketEmpty(metaAccount.id, chain.id) - } - - override suspend fun clearBasket() { - val metaAccount = accountRepository.getSelectedMetaAccount() - val chain = governanceSharedState.chain() - - tinderGovBasketRepository.clearBasket(metaAccount.id, chain.id) - } - - override suspend fun getBasketItemsToRemove(coroutineScope: CoroutineScope): List { - val metaAccount = accountRepository.getSelectedMetaAccount() - val chain = governanceSharedState.chain() - val asset = assetUseCase.getCurrentAsset() - val basket = tinderGovBasketRepository.getBasket(metaAccount.id, chain.id) - - val availableToVoteReferenda = observeReferendaAvailableToVote(coroutineScope).first() - .mapToSet { it.id } - - return basket.filter { it.isItemNotAvailableToVote(availableToVoteReferenda, asset) } - } - override suspend fun awaitAllItemsVoted(coroutineScope: CoroutineScope, basket: List) { observeReferendaState(coroutineScope) .filter { referendaState -> diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummarySharedComputation.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummarySharedComputation.kt new file mode 100644 index 0000000000..af77cac537 --- /dev/null +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummarySharedComputation.kt @@ -0,0 +1,30 @@ +package io.novafoundation.nova.feature_governance_impl.domain.summary + +import io.novafoundation.nova.common.data.memory.ComputationalCache +import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository +import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId +import io.novafoundation.nova.feature_governance_api.data.source.SupportedGovernanceOption +import io.novafoundation.nova.feature_governance_impl.domain.referendum.details.ReferendumDetailsRepository +import kotlinx.coroutines.CoroutineScope + +class ReferendaSummarySharedComputation( + private val computationalCache: ComputationalCache, + private val referendumDetailsRepository: ReferendumDetailsRepository, + private val accountRepository: AccountRepository +) { + + suspend fun summaries( + governanceOption: SupportedGovernanceOption, + referendaIds: List, + scope: CoroutineScope + ): Map { + val chainId = governanceOption.assetWithChain.chain.id + val referendaSet = referendaIds.toSet() + val selectedLanguage = accountRepository.selectedLanguage() + val key = "REFERENDA_SUMMARIES:$chainId:$referendaSet:${selectedLanguage.iso639Code}" + + return computationalCache.useCache(key, scope) { + referendumDetailsRepository.loadSummaries(governanceOption.assetWithChain.chain, referendaIds, selectedLanguage) + } + } +} diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendumSummaryInteractor.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendumSummaryInteractor.kt new file mode 100644 index 0000000000..bed3e023f0 --- /dev/null +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendumSummaryInteractor.kt @@ -0,0 +1,17 @@ +package io.novafoundation.nova.feature_governance_impl.domain.summary + +import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId +import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor +import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState +import io.novafoundation.nova.runtime.state.selectedOption +import kotlinx.coroutines.CoroutineScope + +class RealReferendaSummaryInteractor( + private val governanceSharedState: GovernanceSharedState, + private val referendaSummarySharedComputation: ReferendaSummarySharedComputation +) : ReferendaSummaryInteractor { + + override suspend fun getReferendaSummaries(ids: List, coroutineScope: CoroutineScope): Map { + return referendaSummarySharedComputation.summaries(governanceSharedState.selectedOption(), ids, coroutineScope) + } +} diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/common/info/di/DescriptionComponent.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/common/info/di/DescriptionComponent.kt index b0d00f142b..059aad55b5 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/common/info/di/DescriptionComponent.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/common/info/di/DescriptionComponent.kt @@ -6,6 +6,7 @@ import dagger.Subcomponent import io.novafoundation.nova.common.di.scope.ScreenScope import io.novafoundation.nova.feature_governance_impl.presentation.common.info.ReferendumInfoFragment import io.novafoundation.nova.feature_governance_impl.presentation.common.info.ReferendumInfoPayload +import io.novafoundation.nova.feature_governance_impl.presentation.common.info.di.ReferendumInfoModule @Subcomponent( modules = [ diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/common/info/di/DescriptionModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/common/info/di/DescriptionModule.kt index 8d153eb1a5..d880690c65 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/common/info/di/DescriptionModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/common/info/di/DescriptionModule.kt @@ -1,4 +1,4 @@ -package io.novafoundation.nova.feature_governance_impl.presentation.common.description.di +package io.novafoundation.nova.feature_governance_impl.presentation.common.info.di import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModel diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/ReferendaListViewModel.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/ReferendaListViewModel.kt index 4bde911e6c..3f3cd1b4e0 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/ReferendaListViewModel.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/ReferendaListViewModel.kt @@ -1,6 +1,7 @@ package io.novafoundation.nova.feature_governance_impl.presentation.referenda.list import android.util.Log +import androidx.lifecycle.viewModelScope import io.novafoundation.nova.common.base.BaseViewModel import io.novafoundation.nova.common.domain.dataOrNull import io.novafoundation.nova.common.list.toListWithHeaders @@ -15,6 +16,7 @@ import io.novafoundation.nova.common.utils.withItemScope import io.novafoundation.nova.common.view.PlaceholderModel import io.novafoundation.nova.core.updater.UpdateSystem import io.novafoundation.nova.feature_account_api.domain.interfaces.SelectedAccountUseCase +import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId import io.novafoundation.nova.feature_governance_api.domain.referendum.list.DelegatedState import io.novafoundation.nova.feature_governance_api.domain.referendum.list.GovernanceLocksOverview import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendaListInteractor @@ -26,6 +28,7 @@ import io.novafoundation.nova.feature_governance_impl.domain.filters.ReferendaFi import io.novafoundation.nova.feature_governance_api.domain.referendum.filters.ReferendumType import io.novafoundation.nova.feature_governance_api.domain.referendum.filters.ReferendumTypeFilter import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendaListState +import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter import io.novafoundation.nova.feature_governance_impl.presentation.referenda.common.ReferendumFormatter import io.novafoundation.nova.feature_governance_impl.presentation.referenda.common.list.ReferendaListStateModel @@ -59,7 +62,8 @@ class ReferendaListViewModel( private val updateSystem: UpdateSystem, private val governanceRouter: GovernanceRouter, private val referendumFormatter: ReferendumFormatter, - private val governanceDAppsInteractor: GovernanceDAppsInteractor + private val governanceDAppsInteractor: GovernanceDAppsInteractor, + private val referendaSummaryInteractor: ReferendaSummaryInteractor ) : BaseViewModel(), WithAssetSelector { override val assetSelectorMixin = assetSelectorFactory.create( @@ -103,9 +107,14 @@ class ReferendaListViewModel( .inBackground() .shareWhileSubscribed() - val tinderGovBanner = referendaListStateFlow.map { referenda -> + private val referendaSummariesFlow = referendaListStateFlow.mapLoading { referenda -> + val referendaIds = referenda.availableToVoteReferenda.map { it.id } + referendaSummaryInteractor.getReferendaSummaries(referendaIds, viewModelScope) + }.shareInBackground() + + val tinderGovBanner = referendaSummariesFlow.map { summaries -> val chain = selectedAssetSharedState.chain() - mapTinderGovToUi(chain, referenda.dataOrNull) + mapTinderGovToUi(chain, summaries.dataOrNull) } .inBackground() .shareWhileSubscribed() @@ -170,17 +179,15 @@ class ReferendaListViewModel( } } - private fun mapTinderGovToUi(chain: Chain, referendaListState: ReferendaListState?): TinderGovBannerModel? { + private fun mapTinderGovToUi(chain: Chain, referendaSummaries: Map?): TinderGovBannerModel? { if (!chain.supportTinderGov()) return null - if (referendaListState == null) return null - - val availableToVote = referendaListState.availableToVoteReferenda + if (referendaSummaries == null) return null return TinderGovBannerModel( - chipText = if (availableToVote.isEmpty()) { + if (referendaSummaries.isEmpty()) { null } else { - resourceManager.getString(R.string.referenda_swipe_gov_banner_chip, availableToVote.size) + resourceManager.getString(R.string.referenda_swipe_gov_banner_chip, referendaSummaries.size) } ) } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/di/ReferendaListModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/di/ReferendaListModule.kt index e355572148..05fb3b415c 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/di/ReferendaListModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/di/ReferendaListModule.kt @@ -12,6 +12,7 @@ import io.novafoundation.nova.common.resources.ResourceManager import io.novafoundation.nova.core.updater.UpdateSystem import io.novafoundation.nova.feature_account_api.domain.interfaces.SelectedAccountUseCase import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendaListInteractor +import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.domain.dapp.GovernanceDAppsInteractor import io.novafoundation.nova.feature_governance_impl.domain.filters.ReferendaFiltersInteractor @@ -36,7 +37,8 @@ class ReferendaListModule { updateSystem: UpdateSystem, governanceRouter: GovernanceRouter, referendumFormatter: ReferendumFormatter, - governanceDAppsInteractor: GovernanceDAppsInteractor + governanceDAppsInteractor: GovernanceDAppsInteractor, + summaryInteractor: ReferendaSummaryInteractor ): ViewModel { return ReferendaListViewModel( assetSelectorFactory = assetSelectorFactory, @@ -48,7 +50,8 @@ class ReferendaListModule { updateSystem = updateSystem, governanceRouter = governanceRouter, referendumFormatter = referendumFormatter, - governanceDAppsInteractor = governanceDAppsInteractor + governanceDAppsInteractor = governanceDAppsInteractor, + referendaSummaryInteractor = summaryInteractor ) } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/TinderGovBasketViewModel.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/TinderGovBasketViewModel.kt index ae7f974ab9..c31b67d5aa 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/TinderGovBasketViewModel.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/TinderGovBasketViewModel.kt @@ -14,6 +14,7 @@ import io.novafoundation.nova.common.utils.toggle import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.VoteType import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendumPreview +import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.R import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState @@ -38,6 +39,7 @@ class TinderGovBasketViewModel( private val governanceSharedState: GovernanceSharedState, private val router: GovernanceRouter, private val interactor: TinderGovInteractor, + private val basketInteractor: TinderGovBasketInteractor, private val votersFormatter: VotersFormatter, private val referendumFormatter: ReferendumFormatter, private val actionAwaitableMixinFactory: ActionAwaitableMixin.Factory, @@ -55,7 +57,7 @@ class TinderGovBasketViewModel( .map { it.associateBy { it.id } } .shareInBackground() - private val basketItemsFlow = interactor.observeTinderGovBasket() + private val basketItemsFlow = basketInteractor.observeTinderGovBasket() .shareInBackground() val editModeButtonText = inEditModeFlow.map { @@ -107,7 +109,7 @@ class TinderGovBasketViewModel( .firstOrNull { it.referendumId == item.id } ?: return@launch - interactor.removeReferendumFromBasket(referendum) + basketInteractor.removeReferendumFromBasket(referendum) closeScreenIfBasketIsEmpty() } @@ -151,10 +153,10 @@ class TinderGovBasketViewModel( private fun validateReferendaAndRemove() { launch { - val removedReferenda = interactor.getBasketItemsToRemove(coroutineScope) + val removedReferenda = basketInteractor.getBasketItemsToRemove(coroutineScope) if (removedReferenda.isNotEmpty()) { - interactor.removeBasketItems(removedReferenda) + basketInteractor.removeBasketItems(removedReferenda) itemsWasRemovedFromBasketAction.awaitAction(getFormattedAmountAvailableToVote()) @@ -169,7 +171,7 @@ class TinderGovBasketViewModel( } private suspend fun closeScreenIfBasketIsEmpty() { - if (interactor.isBasketEmpty()) { + if (basketInteractor.isBasketEmpty()) { router.back() } } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/di/TinderGovBasketModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/di/TinderGovBasketModule.kt index 1e2dbbfdcd..acebdc6a49 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/di/TinderGovBasketModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/di/TinderGovBasketModule.kt @@ -10,6 +10,7 @@ import io.novafoundation.nova.common.di.viewmodel.ViewModelKey import io.novafoundation.nova.common.di.viewmodel.ViewModelModule import io.novafoundation.nova.common.mixin.actionAwaitable.ActionAwaitableMixin import io.novafoundation.nova.common.resources.ResourceManager +import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter @@ -32,17 +33,19 @@ class TinderGovBasketModule { referendumFormatter: ReferendumFormatter, actionAwaitableMixinFactory: ActionAwaitableMixin.Factory, resourceManager: ResourceManager, - assetUseCase: AssetUseCase + assetUseCase: AssetUseCase, + basketInteractor: TinderGovBasketInteractor ): ViewModel { return TinderGovBasketViewModel( governanceSharedState = governanceSharedState, router = router, interactor = interactor, + basketInteractor = basketInteractor, votersFormatter = votersFormatter, referendumFormatter = referendumFormatter, actionAwaitableMixinFactory = actionAwaitableMixinFactory, resourceManager = resourceManager, - assetUseCase + assetUseCase = assetUseCase ) } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/TinderGovCardDetailsLoader.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/TinderGovCardDetailsLoader.kt deleted file mode 100644 index 30f63c667f..0000000000 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/TinderGovCardDetailsLoader.kt +++ /dev/null @@ -1,131 +0,0 @@ -package io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards - -import android.util.Log -import io.novafoundation.nova.common.domain.ExtendedLoadingState -import io.novafoundation.nova.common.domain.ExtendedLoadingState.Error -import io.novafoundation.nova.common.domain.ExtendedLoadingState.Loaded -import io.novafoundation.nova.common.domain.ExtendedLoadingState.Loading -import io.novafoundation.nova.common.domain.map -import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId -import io.novafoundation.nova.feature_governance_api.domain.referendum.details.ReferendumCall.TreasuryRequest -import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendumPreview -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor -import io.novafoundation.nova.feature_wallet_api.domain.TokenUseCase -import io.novafoundation.nova.feature_wallet_api.presentation.model.AmountModel -import io.novafoundation.nova.feature_wallet_api.presentation.model.mapAmountToAmountModel -import io.novafoundation.nova.runtime.ext.fullId -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.launch -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock - -private typealias SummaryLoadingState = Map> -private typealias AmountLoadingState = Map> - -class TinderGovCardsDetailsLoaderFactory( - private val interactor: TinderGovInteractor, - private val tokenUseCase: TokenUseCase -) { - - fun create(coroutineScope: CoroutineScope): TinderGovCardDetailsLoader { - return TinderGovCardDetailsLoader(interactor, tokenUseCase, coroutineScope) - } -} - -class TinderGovCardDetailsLoader( - private val interactor: TinderGovInteractor, - private val tokenUseCase: TokenUseCase, - private val coroutineScope: CoroutineScope -) : CoroutineScope by coroutineScope { - - private val summaryMutex = Mutex() - private val amountMutex = Mutex() - - private val _cardsSummary = MutableStateFlow(emptyMap()) - private val _cardsAmount = MutableStateFlow(emptyMap()) - - val cardsSummaryFlow: Flow = _cardsSummary - val cardsAmountFlow: Flow = _cardsAmount - - suspend fun reloadSummary(referendumPreview: ReferendumPreview) { - summaryMutex.withLock { - _cardsSummary.update { it - referendumPreview.id } - } - - loadSummary(referendumPreview) - } - - suspend fun reloadAmount(referendumPreview: ReferendumPreview) { - amountMutex.withLock { - _cardsAmount.update { it - referendumPreview.id } - } - - loadAmount(referendumPreview) - } - - fun loadSummary(referendumPreview: ReferendumPreview) { - coroutineScope.launch { - val id = referendumPreview.id - if (containsSummary(id)) return@launch - - setSummaryLoadingState(id, Loading) - runCatching { interactor.loadReferendumSummary(id) } - .onSuccess { setSummaryLoadingState(id, Loaded(it)) } - .onFailure { - Log.e("TinderGovCardDetailsLoader", "Failed to load referendum summary", it) - - setSummaryLoadingState(id, Error(it)) - } - } - } - - fun loadAmount(referendumPreview: ReferendumPreview) { - coroutineScope.launch { - val id = referendumPreview.id - if (containsAmount(id)) return@launch - - setAmountLoadingState(id, Loading) - runCatching { interactor.loadReferendumAmount(referendumPreview) } - .onSuccess { setAmountLoadingState(id, Loaded(it)) } - .onFailure { - Log.e("TinderGovCardDetailsLoader", "Failed to load referendum amount", it) - - setAmountLoadingState(id, Error(it)) - } - } - } - - private suspend fun containsSummary(id: ReferendumId): Boolean { - return summaryMutex.withLock { _cardsSummary.first().containsKey(id) } - } - - private suspend fun containsAmount(id: ReferendumId): Boolean { - return amountMutex.withLock { _cardsAmount.first().containsKey(id) } - } - - private suspend fun setSummaryLoadingState(id: ReferendumId, summary: ExtendedLoadingState) { - summaryMutex.withLock { - _cardsSummary.update { it.plus(id to summary) } - } - } - - private suspend fun setAmountLoadingState(id: ReferendumId, treasuryRequestState: ExtendedLoadingState) { - amountMutex.withLock { - val amountModel = treasuryRequestState.map { treasuryRequest -> - treasuryRequest?.let { - val token = tokenUseCase.getToken(treasuryRequest.chainAsset.fullId) - mapAmountToAmountModel(treasuryRequest.amount, token) - } - } - - _cardsAmount.update { it.plus(id to amountModel) } - } - } -} - -private fun MutableStateFlow.update(updater: (T) -> T) { - value = updater(value) -} diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/TinderGovCardsViewModel.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/TinderGovCardsViewModel.kt index af2b77678c..d176dcff32 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/TinderGovCardsViewModel.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/TinderGovCardsViewModel.kt @@ -2,13 +2,10 @@ package io.novafoundation.nova.feature_governance_impl.presentation.tindergov.ca import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope +import io.noties.markwon.Markwon import io.novafoundation.nova.common.base.BaseViewModel import io.novafoundation.nova.common.base.TitleAndMessage -import io.novafoundation.nova.common.domain.ExtendedLoadingState -import io.novafoundation.nova.common.domain.isError -import io.novafoundation.nova.common.domain.isLoaded -import io.novafoundation.nova.common.domain.map -import io.novafoundation.nova.common.domain.orLoading import io.novafoundation.nova.common.mixin.actionAwaitable.ActionAwaitableMixin import io.novafoundation.nova.common.mixin.actionAwaitable.confirmingOrDenyingAction import io.novafoundation.nova.common.navigation.awaitResponse @@ -17,7 +14,6 @@ import io.novafoundation.nova.common.utils.Event import io.novafoundation.nova.common.utils.formatTokenAmount import io.novafoundation.nova.common.utils.formatting.format import io.novafoundation.nova.common.utils.onEachWithPrevious -import io.novafoundation.nova.common.utils.safeSubList import io.novafoundation.nova.common.utils.sendEvent import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem import io.novafoundation.nova.feature_governance_api.data.model.VotingPower @@ -25,40 +21,46 @@ import io.novafoundation.nova.feature_governance_api.data.network.blockhain.mode import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.VoteType import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.amountMultiplier import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendumPreview +import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor +import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_api.domain.tindergov.VotingPowerState import io.novafoundation.nova.feature_governance_impl.R import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter import io.novafoundation.nova.feature_governance_impl.presentation.common.info.ReferendumInfoPayload -import io.novafoundation.nova.feature_governance_impl.presentation.referenda.common.ReferendumFormatter import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.setup.tindergov.TinderGovVoteRequester import io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.adapter.TinderGovCardRvItem +import io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.model.CardWithDetails +import io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.model.ReferendaCounterModel +import io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.model.ReferendaWithBasket import io.novafoundation.nova.feature_wallet_api.domain.AssetUseCase +import io.novafoundation.nova.feature_wallet_api.domain.TokenUseCase import io.novafoundation.nova.feature_wallet_api.domain.getCurrentAsset import io.novafoundation.nova.feature_wallet_api.domain.model.amountFromPlanks import io.novafoundation.nova.feature_wallet_api.presentation.model.AmountModel +import io.novafoundation.nova.feature_wallet_api.presentation.model.mapAmountToAmountModel +import io.novafoundation.nova.runtime.ext.fullId import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch class TinderGovCardsViewModel( private val router: GovernanceRouter, - private val tinderGovCardDetailsLoaderFactory: TinderGovCardsDetailsLoaderFactory, private val interactor: TinderGovInteractor, - private val referendumFormatter: ReferendumFormatter, + private val basketInteractor: TinderGovBasketInteractor, private val actionAwaitableMixinFactory: ActionAwaitableMixin.Factory, private val tinderGovVoteRequester: TinderGovVoteRequester, private val assetUseCase: AssetUseCase, - private val resourceManager: ResourceManager + private val resourceManager: ResourceManager, + private val referendaSummaryInteractor: ReferendaSummaryInteractor, + private val tokenUseCase: TokenUseCase, + private val cardsMarkdown: Markwon, ) : BaseViewModel() { companion object { @@ -67,27 +69,14 @@ class TinderGovCardsViewModel( private val cardsBackground = createCardsBackground() - private val tinderGovCardDetailsLoader = tinderGovCardDetailsLoaderFactory.create(coroutineScope = this) - - private val cardsSummaryFlow = tinderGovCardDetailsLoader.cardsSummaryFlow - .shareInBackground() - - private val cardsAmountFlow = tinderGovCardDetailsLoader.cardsAmountFlow - .shareInBackground() - private val topCardIndex = MutableStateFlow(0) - private val sortedReferendaFlow = MutableStateFlow(listOf()) + private val sortedReferendaFlow = MutableStateFlow(listOf()) - private val basketFlow = interactor.observeTinderGovBasket() + private val basketFlow = basketInteractor.observeTinderGovBasket() .map { it.associateBy { it.referendumId } } .shareInBackground() - val cardsFlow = combine( - sortedReferendaFlow, - cardsSummaryFlow, - cardsAmountFlow, - ::mapCards - ).shareInBackground() + val cardsFlow = sortedReferendaFlow.map { mapCards(it) } val retryReferendumInfoLoadingAction = actionAwaitableMixinFactory.confirmingOrDenyingAction() @@ -102,12 +91,8 @@ class TinderGovCardsViewModel( private val _resetCards = MutableLiveData>() val resetCardsEvent: LiveData> = _resetCards - private val topReferendumWithDetails = combine(topCardIndex, cardsSummaryFlow, cardsAmountFlow) { topCardIndex, cardsSummary, cardsAmount -> - val referendum = sortedReferendaFlow.value.getOrNull(topCardIndex) ?: return@combine null - val cardSummary = cardsSummary.getOrDefault(referendum.id, ExtendedLoadingState.Loading) - val cardAmount = cardsAmount.getOrDefault(referendum.id, ExtendedLoadingState.Loading) - - CardWithDetails(referendum, cardSummary, cardAmount) + private val topReferendumWithDetails = combine(topCardIndex, sortedReferendaFlow) { topCardIndex, referenda -> + referenda.getOrNull(topCardIndex) ?: return@combine null } .distinctUntilChanged() .shareInBackground() @@ -116,11 +101,7 @@ class TinderGovCardsViewModel( val manageVotingPowerAvailable = topReferendumWithDetails.map { it != null } - val isCardDraggingAvailable = combine(isVotingInProgress, topReferendumWithDetails.filterNotNull()) { isVotingInProgress, cardWithDetails -> - val summaryLoaded = cardWithDetails.summary.isLoaded() - val amountLoaded = cardWithDetails.summary.isLoaded() - !isVotingInProgress && summaryLoaded && amountLoaded - } + val isCardDraggingAvailable = isVotingInProgress.map { !it } val basketModelFlow = basketFlow .map { items -> mapBasketModel(items.values.toList()) } @@ -157,8 +138,6 @@ class TinderGovCardsViewModel( init { observeReferendaAndAddToCards() - setupReferendumRetryAction() - loadFirstCards() } @@ -178,15 +157,6 @@ class TinderGovCardsViewModel( fun onCardAppeared(position: Int) { topCardIndex.value = position - - // Get 3 first referenda to load content for - val referenda = sortedReferendaFlow.value.safeSubList(position, position + CARD_STACK_SIZE) - - // Load summary and amount for each referendum - referenda.forEach { - tinderGovCardDetailsLoader.loadSummary(it) - tinderGovCardDetailsLoader.loadAmount(it) - } } fun onBasketClicked() { @@ -200,7 +170,7 @@ class TinderGovCardsViewModel( fun editVotingPowerClicked() { launch { val topReferendum = topReferendumWithDetails.first() - val topReferendumId = topReferendum?.referendum?.id?.value ?: return@launch + val topReferendumId = topReferendum?.id?.value ?: return@launch val request = TinderGovVoteRequester.Request(topReferendumId) tinderGovVoteRequester.openRequest(request) } @@ -241,7 +211,7 @@ class TinderGovCardsViewModel( } if (isSufficientAmount) { - interactor.addItemToBasket(referendum.id, voteType) + basketInteractor.addItemToBasket(referendum.id, voteType) checkAllReferendaWasVotedAndOpenBasket() } else { _rewindCardEvent.sendEvent() @@ -277,7 +247,7 @@ class TinderGovCardsViewModel( } private suspend fun checkAllReferendaWasVotedAndOpenBasket() { - val basket = interactor.getTinderGovBasket() + val basket = basketInteractor.getTinderGovBasket() .associateBy { it.referendumId } val referenda = sortedReferendaFlow.value @@ -288,67 +258,24 @@ class TinderGovCardsViewModel( } private fun mapReferendumToUi( - referendumPreview: ReferendumPreview, - summary: ExtendedLoadingState?, - amount: ExtendedLoadingState?, + referendumPreview: CardWithDetails, backgroundRes: Int ): TinderGovCardRvItem { return TinderGovCardRvItem( referendumPreview.id, - summary = summary?.map { mapSummaryToUi(it, referendumPreview) }.orLoading(), - requestedAmount = amount.orLoading(), + summary = cardsMarkdown.toMarkdown(referendumPreview.summary), + requestedAmount = referendumPreview.amount, backgroundRes = backgroundRes, ) } - private fun mapSummaryToUi(summary: String?, referendumPreview: ReferendumPreview): String { - return if (summary.isNullOrBlank()) { - referendumFormatter.formatReferendumName(referendumPreview) - } else { - summary - } - } - - private fun setupReferendumRetryAction() { - topReferendumWithDetails - .filterNotNull() - .map { - val isLoadingError = it.summary.isError() || it.amount.isError() - it.referendum to isLoadingError - } - .distinctUntilChangedBy { (referendum, isLoadingError) -> referendum.id to isLoadingError } - .onEach { (referendum, isLoadingError) -> - if (isLoadingError) { - showRetryDialog(referendum) - } - }.launchIn(this) - } - - private suspend fun showRetryDialog(referendum: ReferendumPreview) { - val retryConfirmed = retryReferendumInfoLoadingAction.awaitAction(Unit) - if (retryConfirmed) { - reloadDetailsForReferendum(referendum) - } else { - skipCard() - } - } - - private fun reloadDetailsForReferendum(referendum: ReferendumPreview) = launch { - tinderGovCardDetailsLoader.reloadSummary(referendum) - tinderGovCardDetailsLoader.reloadAmount(referendum) - } - private fun mapCards( - sortedReferenda: List, - summaries: Map>, - amounts: Map> + sortedReferenda: List ): List { return sortedReferenda.mapIndexed { index, referendum -> val backgroundRes = cardsBackground[index % cardsBackground.size] - val summary = summaries[referendum.id] - val amount = amounts[referendum.id] - mapReferendumToUi(referendum, summary, amount, backgroundRes) + mapReferendumToUi(referendum, backgroundRes) } } @@ -364,12 +291,38 @@ class TinderGovCardsViewModel( private fun observeReferendaAndAddToCards() { combine(interactor.observeReferendaAvailableToVote(this), basketFlow) { referenda, basket -> - ReferendaWithBasket(referenda, basket) + val referendaIds = referenda.map { it.id } + val summaries = referendaSummaryInteractor.getReferendaSummaries(referendaIds, viewModelScope) + val amounts = referenda.associate { it.id to it.getAmountModel() } + + val referendaCards = referenda.mapToCardWithDetails(summaries, amounts) + .filterNotNull() + + ReferendaWithBasket(referendaCards, basket) } .addNewReferendaToCards() .launchIn(this) } + private fun List.mapToCardWithDetails( + summaries: Map, + amounts: Map + ): List { + return map { + val summary = summaries[it.id] ?: return@map null + + CardWithDetails(it.id, summary, amounts[it.id]) + } + } + + private suspend fun ReferendumPreview.getAmountModel(): AmountModel? { + val treasuryRequest = interactor.getReferendumAmount(this) + return treasuryRequest?.let { + val token = tokenUseCase.getToken(treasuryRequest.chainAsset.fullId) + mapAmountToAmountModel(treasuryRequest.amount, token) + } + } + private fun Flow.addNewReferendaToCards(): Flow { return onEachWithPrevious { old, new -> val oldBasket = old?.basket.orEmpty() @@ -414,35 +367,3 @@ class TinderGovCardsViewModel( ) } } - -private class ReferendaWithBasket( - val referenda: List, - val basket: Map -) - -private class CardWithDetails( - val referendum: ReferendumPreview, - val summary: ExtendedLoadingState, - val amount: ExtendedLoadingState -) { - - override fun equals(other: Any?): Boolean { - return other is CardWithDetails && - referendum.id == other.referendum.id && - summary == other.summary && - amount == other.amount - } -} - -private class ReferendaCounterModel( - val itemsInBasket: Int, - val referendaSize: Int -) { - - val remainingReferendaToVote: Int - get() = referendaSize - itemsInBasket - - fun hasReferendaToVote(): Boolean { - return referendaSize > itemsInBasket - } -} diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/adapter/TinderGovCardRvItem.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/adapter/TinderGovCardRvItem.kt index a8e87121d3..c047e5f116 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/adapter/TinderGovCardRvItem.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/adapter/TinderGovCardRvItem.kt @@ -1,13 +1,12 @@ package io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.adapter import androidx.annotation.DrawableRes -import io.novafoundation.nova.common.domain.ExtendedLoadingState import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId import io.novafoundation.nova.feature_wallet_api.presentation.model.AmountModel data class TinderGovCardRvItem( val id: ReferendumId, - val summary: ExtendedLoadingState, - val requestedAmount: ExtendedLoadingState, + val summary: CharSequence?, + val requestedAmount: AmountModel?, @DrawableRes val backgroundRes: Int ) diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/adapter/TinderGovCardsAdapter.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/adapter/TinderGovCardsAdapter.kt index 23e729dab4..7b48c4e342 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/adapter/TinderGovCardsAdapter.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/adapter/TinderGovCardsAdapter.kt @@ -2,12 +2,9 @@ package io.novafoundation.nova.feature_governance_impl.presentation.tindergov.ca import android.view.View import android.view.ViewGroup -import androidx.core.view.isVisible import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter -import io.novafoundation.nova.common.domain.dataOrNull -import io.novafoundation.nova.common.domain.isLoadingOrError import io.novafoundation.nova.common.list.GroupedListHolder import io.novafoundation.nova.common.utils.inflateChild import io.novafoundation.nova.common.utils.letOrHide @@ -15,12 +12,9 @@ import io.novafoundation.nova.common.utils.setTextOrHide import io.novafoundation.nova.feature_governance_impl.R import io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.adapter.TinderGovCardsAdapter.Handler import kotlinx.android.synthetic.main.item_tinder_gov_card.view.itemTinderGovCardAmountContainer -import kotlinx.android.synthetic.main.item_tinder_gov_card.view.itemTinderGovCardAmountShimmering -import kotlinx.android.synthetic.main.item_tinder_gov_card.view.itemTinderGovCardDivider import kotlinx.android.synthetic.main.item_tinder_gov_card.view.itemTinderGovCardRequestedAmount import kotlinx.android.synthetic.main.item_tinder_gov_card.view.itemTinderGovCardRequestedFiat import kotlinx.android.synthetic.main.item_tinder_gov_card.view.itemTinderGovCardSummary -import kotlinx.android.synthetic.main.item_tinder_gov_card.view.itemTinderGovCardSummaryShimmering import kotlinx.android.synthetic.main.item_tinder_gov_card.view.tinderGovCardContainer import kotlinx.android.synthetic.main.item_tinder_gov_card.view.tinderGovCardReadMore @@ -53,16 +47,12 @@ class TinderGovCardViewHolder( } fun bind(item: TinderGovCardRvItem) { - itemView.itemTinderGovCardSummary.setTextOrHide(item.summary.dataOrNull) - itemView.itemTinderGovCardSummaryShimmering.isVisible = item.summary.isLoadingOrError() - - itemView.itemTinderGovCardAmountContainer.letOrHide(item.requestedAmount.dataOrNull) { + itemView.itemTinderGovCardSummary.text = item.summary + itemView.itemTinderGovCardAmountContainer.letOrHide(item.requestedAmount) { itemView.itemTinderGovCardRequestedAmount.setTextOrHide(it.token) itemView.itemTinderGovCardRequestedFiat.setTextOrHide(it.fiat) } - itemView.itemTinderGovCardDivider.isVisible = item.requestedAmount.isLoadingOrError() || item.requestedAmount.dataOrNull != null - itemView.itemTinderGovCardAmountShimmering.isVisible = item.requestedAmount.isLoadingOrError() itemView.tinderGovCardContainer.setBackgroundResource(item.backgroundRes) itemView.tinderGovCardReadMore.setOnClickListener { handler.onReadMoreClicked(item) } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/di/TinderGovCardsModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/di/TinderGovCardsModule.kt index 49814cf4f9..d38910c19a 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/di/TinderGovCardsModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/di/TinderGovCardsModule.kt @@ -1,20 +1,25 @@ package io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.di +import android.content.Context import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import dagger.Module import dagger.Provides import dagger.multibindings.IntoMap +import io.noties.markwon.Markwon +import io.novafoundation.nova.common.R +import io.novafoundation.nova.common.di.scope.ScreenScope import io.novafoundation.nova.common.di.viewmodel.ViewModelKey import io.novafoundation.nova.common.di.viewmodel.ViewModelModule import io.novafoundation.nova.common.mixin.actionAwaitable.ActionAwaitableMixin import io.novafoundation.nova.common.resources.ResourceManager +import io.novafoundation.nova.common.utils.markdown.BoldStylePlugin +import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor +import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter -import io.novafoundation.nova.feature_governance_impl.presentation.referenda.common.ReferendumFormatter import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.setup.tindergov.TinderGovVoteCommunicator -import io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.TinderGovCardsDetailsLoaderFactory import io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.TinderGovCardsViewModel import io.novafoundation.nova.feature_wallet_api.domain.AssetUseCase import io.novafoundation.nova.feature_wallet_api.domain.TokenUseCase @@ -23,14 +28,11 @@ import io.novafoundation.nova.feature_wallet_api.domain.TokenUseCase class TinderGovCardsModule { @Provides - fun provideTinderGovCardsDataHelper( - interactor: TinderGovInteractor, - tokenUseCase: TokenUseCase, - ): TinderGovCardsDetailsLoaderFactory { - return TinderGovCardsDetailsLoaderFactory( - interactor, - tokenUseCase - ) + @ScreenScope + fun provideMarkwon(context: Context): Markwon { + return Markwon.builder(context) + .usePlugin(BoldStylePlugin(context, R.font.public_sans_semi_bold, R.color.text_primary)) + .build() } @Provides @@ -39,22 +41,26 @@ class TinderGovCardsModule { fun provideViewModel( router: GovernanceRouter, tinderGovInteractor: TinderGovInteractor, - tinderGovCardDetailsLoaderFactory: TinderGovCardsDetailsLoaderFactory, - referendumFormatter: ReferendumFormatter, actionAwaitableMixinFactory: ActionAwaitableMixin.Factory, tinderGovVoteCommunicator: TinderGovVoteCommunicator, resourceManager: ResourceManager, - assetUseCase: AssetUseCase + assetUseCase: AssetUseCase, + referendaSummaryInteractor: ReferendaSummaryInteractor, + tokenUseCase: TokenUseCase, + basketInteractor: TinderGovBasketInteractor, + markwon: Markwon ): ViewModel { return TinderGovCardsViewModel( - router, - tinderGovCardDetailsLoaderFactory, - tinderGovInteractor, - referendumFormatter, - actionAwaitableMixinFactory, - tinderGovVoteCommunicator, - assetUseCase, - resourceManager + router = router, + interactor = tinderGovInteractor, + basketInteractor = basketInteractor, + actionAwaitableMixinFactory = actionAwaitableMixinFactory, + tinderGovVoteRequester = tinderGovVoteCommunicator, + assetUseCase = assetUseCase, + resourceManager = resourceManager, + referendaSummaryInteractor = referendaSummaryInteractor, + tokenUseCase = tokenUseCase, + cardsMarkdown = markwon ) } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/CardWithDetails.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/CardWithDetails.kt new file mode 100644 index 0000000000..d8f1e92005 --- /dev/null +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/CardWithDetails.kt @@ -0,0 +1,25 @@ +package io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.model + +import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId +import io.novafoundation.nova.feature_wallet_api.presentation.model.AmountModel + +class CardWithDetails( + val id: ReferendumId, + val summary: String, + val amount: AmountModel? +) { + + override fun equals(other: Any?): Boolean { + return other is CardWithDetails && + id == other.id && + summary == other.summary && + amount == other.amount + } + + override fun hashCode(): Int { + var result = id.hashCode() + result = 31 * result + summary.hashCode() + result = 31 * result + amount.hashCode() + return result + } +} diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/ReferendaCounterModel.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/ReferendaCounterModel.kt new file mode 100644 index 0000000000..d03894f261 --- /dev/null +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/ReferendaCounterModel.kt @@ -0,0 +1,14 @@ +package io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.model + +class ReferendaCounterModel( + val itemsInBasket: Int, + val referendaSize: Int +) { + + val remainingReferendaToVote: Int + get() = referendaSize - itemsInBasket + + fun hasReferendaToVote(): Boolean { + return referendaSize > itemsInBasket + } +} diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/ReferendaWithBasket.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/ReferendaWithBasket.kt new file mode 100644 index 0000000000..12dfcb7d11 --- /dev/null +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/ReferendaWithBasket.kt @@ -0,0 +1,9 @@ +package io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.model + +import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem +import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId + +data class ReferendaWithBasket( + val referenda: List, + val basket: Map +) diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/ConfirmTinderGovVoteViewModel.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/ConfirmTinderGovVoteViewModel.kt index 9d9ade9730..bb6b2d48a7 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/ConfirmTinderGovVoteViewModel.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/ConfirmTinderGovVoteViewModel.kt @@ -13,6 +13,7 @@ import io.novafoundation.nova.feature_account_api.presenatation.actions.External import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem import io.novafoundation.nova.feature_governance_api.data.model.accountVote import io.novafoundation.nova.feature_governance_api.domain.referendum.vote.VoteReferendumInteractor +import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.R import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState @@ -55,6 +56,7 @@ class ConfirmTinderGovVoteViewModel( private val resourceManager: ResourceManager, private val locksChangeFormatter: LocksChangeFormatter, private val tinderGovInteractor: TinderGovInteractor, + private val tinderGovBasketInteractor: TinderGovBasketInteractor, partialRetriableMixinFactory: PartialRetriableMixin.Factory, ) : ConfirmVoteViewModel( router, @@ -69,7 +71,7 @@ class ConfirmTinderGovVoteViewModel( validationExecutor ) { - private val basketFlow = tinderGovInteractor.observeTinderGovBasket() + private val basketFlow = tinderGovBasketInteractor.observeTinderGovBasket() .map { it.associateBy { it.referendumId } } .shareInBackground() @@ -157,7 +159,7 @@ class ConfirmTinderGovVoteViewModel( awaitVotedReferendaStateUpdate(basket) showMessage(resourceManager.getString(R.string.swipe_gov_convirm_votes_success_message, basket.size)) - tinderGovInteractor.clearBasket() + tinderGovBasketInteractor.clearBasket() router.backToTinderGovCards() } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/di/ConfirmTinderGovVoteModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/di/ConfirmTinderGovVoteModule.kt index 33224fc264..3efb4111eb 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/di/ConfirmTinderGovVoteModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/di/ConfirmTinderGovVoteModule.kt @@ -18,6 +18,7 @@ import io.novafoundation.nova.feature_account_api.presenatation.account.wallet.W import io.novafoundation.nova.feature_account_api.presenatation.actions.ExternalActions import io.novafoundation.nova.feature_governance_api.data.source.GovernanceSourceRegistry import io.novafoundation.nova.feature_governance_api.domain.referendum.vote.VoteReferendumInteractor +import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.domain.referendum.vote.validations.tindergov.VoteTinderGovValidationSystem @@ -57,6 +58,7 @@ class ConfirmTinderGovVoteModule { feeLoaderMixinFactory: FeeLoaderMixin.Factory, locksChangeFormatter: LocksChangeFormatter, tinderGovInteractor: TinderGovInteractor, + tinderGovBasketInteractor: TinderGovBasketInteractor, partialRetriableMixinFactory: PartialRetriableMixin.Factory, ): ViewModel { return ConfirmTinderGovVoteViewModel( @@ -75,6 +77,7 @@ class ConfirmTinderGovVoteModule { resourceManager = resourceManager, locksChangeFormatter = locksChangeFormatter, tinderGovInteractor = tinderGovInteractor, + tinderGovBasketInteractor = tinderGovBasketInteractor, partialRetriableMixinFactory = partialRetriableMixinFactory ) } diff --git a/feature-governance-impl/src/main/res/layout/item_tinder_gov_card.xml b/feature-governance-impl/src/main/res/layout/item_tinder_gov_card.xml index d98308eb03..886ed927cd 100644 --- a/feature-governance-impl/src/main/res/layout/item_tinder_gov_card.xml +++ b/feature-governance-impl/src/main/res/layout/item_tinder_gov_card.xml @@ -25,39 +25,12 @@ android:autoSizeMinTextSize="16sp" android:autoSizeTextType="uniform" android:ellipsize="end" - android:textColor="@color/text_primary" - android:visibility="gone" + android:textColor="@color/tinder_gov_banner_secondary_text" app:layout_constraintBottom_toTopOf="@+id/guideline" app:layout_constraintTop_toTopOf="parent" tools:text="Sovereign Nature proposes DOTphin Event Multipass with WalletConnect integration and dynamic NFTs by Unique Network for Polkadot events, aiming for unified proof of attendance and immersive engagement." tools:visibility="visible" /> - - - - - - - - - - - - - + + - - - - - - - - - Date: Fri, 4 Oct 2024 13:54:17 +0200 Subject: [PATCH 2/6] Changed api to chains api --- feature-governance-impl/build.gradle | 4 ---- .../summary/v2/ReferendumSummaryApi.kt | 7 +++++-- .../summary/v2/ReferendumSummaryDataSource.kt | 16 ++++++++++++---- .../di/modules/screens/TinderGovModule.kt | 2 +- .../details/ReferendumDetailsRepository.kt | 8 ++++---- .../summary/ReferendaSummarySharedComputation.kt | 2 +- .../summary/ReferendumSummaryInteractor.kt | 9 ++++++++- .../chain/mappers/LocalToDomainChainMapper.kt | 4 +--- .../mappers/utils/SummaryReferendaParameters.kt | 3 --- .../runtime/multiNetwork/chain/model/Chain.kt | 2 +- 10 files changed, 33 insertions(+), 24 deletions(-) delete mode 100644 runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/chain/mappers/utils/SummaryReferendaParameters.kt diff --git a/feature-governance-impl/build.gradle b/feature-governance-impl/build.gradle index 1762eb3543..8786c21eaa 100644 --- a/feature-governance-impl/build.gradle +++ b/feature-governance-impl/build.gradle @@ -18,8 +18,6 @@ android { buildConfigField "String", "GOVERNANCE_DAPPS_URL", "\"https://raw.githubusercontent.com/novasamatech/nova-utils/master/governance/v2/dapps_dev.json\"" buildConfigField "String", "DELEGATION_TUTORIAL_URL", "\"https://docs.novawallet.io/nova-wallet-wiki/governance/add-delegate-information\"" - - buildConfigField "String", "OPENGOV_API_URL", "\"https://opengov-backend-dev.novasama-tech.org\"" } buildTypes { @@ -28,8 +26,6 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' buildConfigField "String", "GOVERNANCE_DAPPS_URL", "\"https://raw.githubusercontent.com/novasamatech/nova-utils/master/governance/v2/dapps.json\"" - - buildConfigField "String", "OPENGOV_API_URL", "\"https://opengov-backend.novasama-tech.org\"" } } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryApi.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryApi.kt index 82ebd4da05..6581e1c2eb 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryApi.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryApi.kt @@ -5,16 +5,19 @@ import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.s import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.response.ReferendumSummaryResponse import retrofit2.http.Body import retrofit2.http.POST +import retrofit2.http.Url interface ReferendumSummaryApi { - @POST("/not-secure/api/v1/referendum-summaries/single") + @POST suspend fun getReferendumSummary( + @Url url: String, @Body body: ReferendumSummaryRequest ): ReferendumSummaryResponse - @POST("/not-secure/api/v1/referendum-summaries/list") + @POST suspend fun getReferendumSummaries( + @Url url: String, @Body body: ReferendumSummariesRequest ): List } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt index 6296f902eb..7cf60028ff 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt @@ -3,21 +3,26 @@ package io.novafoundation.nova.feature_governance_impl.data.offchain.referendum. import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request.ReferendumSummariesRequest import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request.ReferendumSummaryRequest +import io.novafoundation.nova.runtime.ext.isSwapSupported +import io.novafoundation.nova.runtime.ext.summaryApiOrNull import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain interface ReferendumSummaryDataSource { - suspend fun loadSummary(chain: Chain, id: ReferendumId, languageCode: String): String + suspend fun loadSummary(chain: Chain, id: ReferendumId, languageCode: String): String? - suspend fun loadSummaries(chain: Chain, ids: List, languageCode: String): Map + suspend fun loadSummaries(chain: Chain, ids: List, languageCode: String): Map? } class RealReferendumSummaryDataSource( val api: ReferendumSummaryApi ) : ReferendumSummaryDataSource { - override suspend fun loadSummary(chain: Chain, id: ReferendumId, languageCode: String): String { + override suspend fun loadSummary(chain: Chain, id: ReferendumId, languageCode: String): String? { + val summaryApi = chain.summaryApiOrNull() ?: return null + val response = api.getReferendumSummary( + summaryApi.url, ReferendumSummaryRequest( chainId = chain.id, languageIsoCode = languageCode, @@ -28,8 +33,11 @@ class RealReferendumSummaryDataSource( return response.summary } - override suspend fun loadSummaries(chain: Chain, ids: List, languageCode: String): Map { + override suspend fun loadSummaries(chain: Chain, ids: List, languageCode: String): Map? { + val summaryApi = chain.summaryApiOrNull() ?: return null + val response = api.getReferendumSummaries( + summaryApi.url, ReferendumSummariesRequest( chainId = chain.id, languageIsoCode = languageCode, diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt index f30467b97c..1ae9ad234a 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt @@ -36,7 +36,7 @@ class TinderGovModule { @Provides @FeatureScope fun provideReferendumSummaryApi(apiCreator: NetworkApiCreator): ReferendumSummaryApi { - return apiCreator.create(ReferendumSummaryApi::class.java, customBaseUrl = BuildConfig.OPENGOV_API_URL) + return apiCreator.create(ReferendumSummaryApi::class.java) } @Provides diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/details/ReferendumDetailsRepository.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/details/ReferendumDetailsRepository.kt index 2aa19932e3..f3f28aef4b 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/details/ReferendumDetailsRepository.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/details/ReferendumDetailsRepository.kt @@ -7,20 +7,20 @@ import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain interface ReferendumDetailsRepository { - suspend fun loadSummary(chain: Chain, id: ReferendumId, selectedLanguage: Language): String + suspend fun loadSummary(chain: Chain, id: ReferendumId, selectedLanguage: Language): String? - suspend fun loadSummaries(chain: Chain, ids: List, selectedLanguage: Language): Map + suspend fun loadSummaries(chain: Chain, ids: List, selectedLanguage: Language): Map? } class RealReferendumDetailsRepository( private val referendumSummaryDataSource: ReferendumSummaryDataSource ) : ReferendumDetailsRepository { - override suspend fun loadSummary(chain: Chain, id: ReferendumId, selectedLanguage: Language): String { + override suspend fun loadSummary(chain: Chain, id: ReferendumId, selectedLanguage: Language): String? { return referendumSummaryDataSource.loadSummary(chain, id, selectedLanguage.iso639Code) } - override suspend fun loadSummaries(chain: Chain, ids: List, selectedLanguage: Language): Map { + override suspend fun loadSummaries(chain: Chain, ids: List, selectedLanguage: Language): Map? { return referendumSummaryDataSource.loadSummaries(chain, ids, selectedLanguage.iso639Code) } } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummarySharedComputation.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummarySharedComputation.kt index af77cac537..7d7876549f 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummarySharedComputation.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummarySharedComputation.kt @@ -17,7 +17,7 @@ class ReferendaSummarySharedComputation( governanceOption: SupportedGovernanceOption, referendaIds: List, scope: CoroutineScope - ): Map { + ): Map? { val chainId = governanceOption.assetWithChain.chain.id val referendaSet = referendaIds.toSet() val selectedLanguage = accountRepository.selectedLanguage() diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendumSummaryInteractor.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendumSummaryInteractor.kt index bed3e023f0..d68ec94fe9 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendumSummaryInteractor.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendumSummaryInteractor.kt @@ -12,6 +12,13 @@ class RealReferendaSummaryInteractor( ) : ReferendaSummaryInteractor { override suspend fun getReferendaSummaries(ids: List, coroutineScope: CoroutineScope): Map { - return referendaSummarySharedComputation.summaries(governanceSharedState.selectedOption(), ids, coroutineScope) + return runCatching { + referendaSummarySharedComputation.summaries( + governanceSharedState.selectedOption(), + ids, + coroutineScope + ) + }.getOrNull() + .orEmpty() } } diff --git a/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/chain/mappers/LocalToDomainChainMapper.kt b/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/chain/mappers/LocalToDomainChainMapper.kt index a2167d4122..aa89dd769a 100644 --- a/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/chain/mappers/LocalToDomainChainMapper.kt +++ b/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/chain/mappers/LocalToDomainChainMapper.kt @@ -24,7 +24,6 @@ import io.novafoundation.nova.core_db.model.chain.NodeSelectionPreferencesLocal import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.utils.EVM_TRANSFER_PARAMETER import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.utils.GovernanceReferendaParameters import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.utils.SUBSTRATE_TRANSFER_PARAMETER -import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.utils.SummaryReferendaParameters import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.utils.TransferParameters import io.novafoundation.nova.runtime.multiNetwork.chain.model.BuyProviderArguments import io.novafoundation.nova.runtime.multiNetwork.chain.model.BuyProviderId @@ -155,8 +154,7 @@ private fun mapExternalApiLocalToExternalApi(externalApiLocal: ChainExternalApiL } ApiType.REFERENDUM_SUMMARY -> { - val parameters = externalApiLocal.parsedParameters(gson) - ExternalApi.ReferendumSummary(externalApiLocal.url, parameters?.network) + ExternalApi.ReferendumSummary(externalApiLocal.url) } ApiType.UNKNOWN -> null diff --git a/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/chain/mappers/utils/SummaryReferendaParameters.kt b/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/chain/mappers/utils/SummaryReferendaParameters.kt deleted file mode 100644 index d6a776afcc..0000000000 --- a/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/chain/mappers/utils/SummaryReferendaParameters.kt +++ /dev/null @@ -1,3 +0,0 @@ -package io.novafoundation.nova.runtime.multiNetwork.chain.mappers.utils - -class SummaryReferendaParameters(val network: String?) diff --git a/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/chain/model/Chain.kt b/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/chain/model/Chain.kt index 57e4d690aa..cdaf7acf91 100644 --- a/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/chain/model/Chain.kt +++ b/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/chain/model/Chain.kt @@ -195,7 +195,7 @@ data class Chain( data class GovernanceDelegations(override val url: String) : ExternalApi() - data class ReferendumSummary(override val url: String, val network: String?) : ExternalApi() + data class ReferendumSummary(override val url: String) : ExternalApi() } enum class Governance { From 97dcc5cd70bbd764156630efd42cb6303ca2535f Mon Sep 17 00:00:00 2001 From: antonijzelinskij Date: Fri, 4 Oct 2024 13:55:17 +0200 Subject: [PATCH 3/6] Run ktlint --- .../referendum/summary/v2/ReferendumSummaryDataSource.kt | 1 - .../di/modules/screens/TinderGovModule.kt | 1 - 2 files changed, 2 deletions(-) diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt index 7cf60028ff..8bcded9e8d 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt @@ -3,7 +3,6 @@ package io.novafoundation.nova.feature_governance_impl.data.offchain.referendum. import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request.ReferendumSummariesRequest import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request.ReferendumSummaryRequest -import io.novafoundation.nova.runtime.ext.isSwapSupported import io.novafoundation.nova.runtime.ext.summaryApiOrNull import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt index 1ae9ad234a..0bb65f1ade 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt @@ -10,7 +10,6 @@ import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepos import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor -import io.novafoundation.nova.feature_governance_impl.BuildConfig import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.RealReferendumSummaryDataSource import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.ReferendumSummaryApi From 0623d5a8a73d4671f0e56e2da4ebf8149d9a1d5b Mon Sep 17 00:00:00 2001 From: antonijzelinskij Date: Fri, 4 Oct 2024 14:14:59 +0200 Subject: [PATCH 4/6] Update SpannableExt.kt --- .../java/io/novafoundation/nova/common/utils/SpannableExt.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/io/novafoundation/nova/common/utils/SpannableExt.kt b/common/src/main/java/io/novafoundation/nova/common/utils/SpannableExt.kt index 2e07f471bd..cd6628b004 100644 --- a/common/src/main/java/io/novafoundation/nova/common/utils/SpannableExt.kt +++ b/common/src/main/java/io/novafoundation/nova/common/utils/SpannableExt.kt @@ -91,7 +91,7 @@ fun CharSequence.formatAsSpannable(vararg args: Any): SpannedString { private fun typefaceSpanCompatV28(typeface: Typeface) = TypefaceSpan(typeface) -class CustomTypefaceSpan(private val typeface: Typeface?) : MetricAffectingSpan() { +private class CustomTypefaceSpan(private val typeface: Typeface?) : MetricAffectingSpan() { override fun updateDrawState(paint: TextPaint) { paint.typeface = typeface } From 143af64a595ed5f20a96c31807798a6e5f65eb66 Mon Sep 17 00:00:00 2001 From: antonijzelinskij Date: Fri, 4 Oct 2024 14:29:59 +0200 Subject: [PATCH 5/6] Remove single referendum fetching --- .../summary/v2/ReferendumSummaryApi.kt | 7 ------- .../summary/v2/ReferendumSummaryDataSource.kt | 18 ------------------ .../v2/request/ReferendumSummaryRequest.kt | 7 ------- .../details/ReferendumDetailsRepository.kt | 6 ------ 4 files changed, 38 deletions(-) delete mode 100644 feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/request/ReferendumSummaryRequest.kt diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryApi.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryApi.kt index 6581e1c2eb..a2058632f0 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryApi.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryApi.kt @@ -1,7 +1,6 @@ package io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2 import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request.ReferendumSummariesRequest -import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request.ReferendumSummaryRequest import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.response.ReferendumSummaryResponse import retrofit2.http.Body import retrofit2.http.POST @@ -9,12 +8,6 @@ import retrofit2.http.Url interface ReferendumSummaryApi { - @POST - suspend fun getReferendumSummary( - @Url url: String, - @Body body: ReferendumSummaryRequest - ): ReferendumSummaryResponse - @POST suspend fun getReferendumSummaries( @Url url: String, diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt index 8bcded9e8d..3db1a4fa60 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/ReferendumSummaryDataSource.kt @@ -2,14 +2,11 @@ package io.novafoundation.nova.feature_governance_impl.data.offchain.referendum. import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request.ReferendumSummariesRequest -import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request.ReferendumSummaryRequest import io.novafoundation.nova.runtime.ext.summaryApiOrNull import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain interface ReferendumSummaryDataSource { - suspend fun loadSummary(chain: Chain, id: ReferendumId, languageCode: String): String? - suspend fun loadSummaries(chain: Chain, ids: List, languageCode: String): Map? } @@ -17,21 +14,6 @@ class RealReferendumSummaryDataSource( val api: ReferendumSummaryApi ) : ReferendumSummaryDataSource { - override suspend fun loadSummary(chain: Chain, id: ReferendumId, languageCode: String): String? { - val summaryApi = chain.summaryApiOrNull() ?: return null - - val response = api.getReferendumSummary( - summaryApi.url, - ReferendumSummaryRequest( - chainId = chain.id, - languageIsoCode = languageCode, - referendumId = id.value.toString() - ) - ) - - return response.summary - } - override suspend fun loadSummaries(chain: Chain, ids: List, languageCode: String): Map? { val summaryApi = chain.summaryApiOrNull() ?: return null diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/request/ReferendumSummaryRequest.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/request/ReferendumSummaryRequest.kt deleted file mode 100644 index a25e2113fb..0000000000 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/data/offchain/referendum/summary/v2/request/ReferendumSummaryRequest.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.request - -class ReferendumSummaryRequest( - val chainId: String, - val languageIsoCode: String, - val referendumId: String -) diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/details/ReferendumDetailsRepository.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/details/ReferendumDetailsRepository.kt index f3f28aef4b..92d366a975 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/details/ReferendumDetailsRepository.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/details/ReferendumDetailsRepository.kt @@ -7,8 +7,6 @@ import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain interface ReferendumDetailsRepository { - suspend fun loadSummary(chain: Chain, id: ReferendumId, selectedLanguage: Language): String? - suspend fun loadSummaries(chain: Chain, ids: List, selectedLanguage: Language): Map? } @@ -16,10 +14,6 @@ class RealReferendumDetailsRepository( private val referendumSummaryDataSource: ReferendumSummaryDataSource ) : ReferendumDetailsRepository { - override suspend fun loadSummary(chain: Chain, id: ReferendumId, selectedLanguage: Language): String? { - return referendumSummaryDataSource.loadSummary(chain, id, selectedLanguage.iso639Code) - } - override suspend fun loadSummaries(chain: Chain, ids: List, selectedLanguage: Language): Map? { return referendumSummaryDataSource.loadSummaries(chain, ids, selectedLanguage.iso639Code) } From b1722e4c788278c977c5dcf308dd7c42b3d29612 Mon Sep 17 00:00:00 2001 From: antonijzelinskij Date: Fri, 4 Oct 2024 16:36:18 +0200 Subject: [PATCH 6/6] Fixed pr notes --- .../summary/ReferendaSummaryInteractor.kt | 9 ----- .../tindergov/TinderGovBasketInteractor.kt | 28 --------------- .../domain/tindergov/TinderGovInteractor.kt | 36 ------------------- .../di/modules/screens/TinderGovModule.kt | 6 ++-- ...ractor.kt => TinderGovBasketInteractor.kt} | 23 ++++++++++-- ...ovInteractor.kt => TinderGovInteractor.kt} | 28 +++++++++++++-- ...actor.kt => ReferendaSummaryInteractor.kt} | 6 +++- .../ReferendaSummarySharedComputation.kt | 4 +-- .../referenda/list/ReferendaListViewModel.kt | 14 ++++---- .../referenda/list/di/ReferendaListModule.kt | 2 +- .../tindergov/SetupTinderGovVoteViewModel.kt | 2 +- .../tindergov/di/SetupTinderGovVoteModule.kt | 2 +- .../basket/TinderGovBasketViewModel.kt | 4 +-- .../basket/di/TinderGovBasketModule.kt | 4 +-- .../cards/TinderGovCardsViewModel.kt | 25 +++++++------ .../cards/di/TinderGovCardsModule.kt | 6 ++-- .../tindergov/cards/model/CardWithDetails.kt | 19 ++-------- .../confirm/ConfirmTinderGovVoteViewModel.kt | 4 +-- .../confirm/di/ConfirmTinderGovVoteModule.kt | 4 +-- 19 files changed, 93 insertions(+), 133 deletions(-) delete mode 100644 feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/referendum/summary/ReferendaSummaryInteractor.kt delete mode 100644 feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovBasketInteractor.kt delete mode 100644 feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovInteractor.kt rename feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/{RealTinderGovBasketInteractor.kt => TinderGovBasketInteractor.kt} (89%) rename feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/{RealTinderGovInteractor.kt => TinderGovInteractor.kt} (87%) rename feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/{ReferendumSummaryInteractor.kt => ReferendaSummaryInteractor.kt} (85%) diff --git a/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/referendum/summary/ReferendaSummaryInteractor.kt b/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/referendum/summary/ReferendaSummaryInteractor.kt deleted file mode 100644 index f48bd44c41..0000000000 --- a/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/referendum/summary/ReferendaSummaryInteractor.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.novafoundation.nova.feature_governance_api.domain.referendum.summary - -import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId -import kotlinx.coroutines.CoroutineScope - -interface ReferendaSummaryInteractor { - - suspend fun getReferendaSummaries(ids: List, coroutineScope: CoroutineScope): Map -} diff --git a/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovBasketInteractor.kt b/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovBasketInteractor.kt deleted file mode 100644 index 5b50b879b4..0000000000 --- a/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovBasketInteractor.kt +++ /dev/null @@ -1,28 +0,0 @@ -package io.novafoundation.nova.feature_governance_api.domain.tindergov - -import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem -import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId -import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.VoteType -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.Flow - -interface TinderGovBasketInteractor { - - fun observeTinderGovBasket(): Flow> - - suspend fun getTinderGovBasket(): List - - suspend fun addItemToBasket(referendumId: ReferendumId, voteType: VoteType) - - suspend fun removeReferendumFromBasket(item: TinderGovBasketItem) - - suspend fun removeBasketItems(items: Collection) - - suspend fun isBasketEmpty(): Boolean - - suspend fun clearBasket() - - suspend fun getBasketItemsToRemove(coroutineScope: CoroutineScope): List - - suspend fun awaitAllItemsVoted(coroutineScope: CoroutineScope, basket: List) -} diff --git a/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovInteractor.kt b/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovInteractor.kt deleted file mode 100644 index b39ff415cd..0000000000 --- a/feature-governance-api/src/main/java/io/novafoundation/nova/feature_governance_api/domain/tindergov/TinderGovInteractor.kt +++ /dev/null @@ -1,36 +0,0 @@ -package io.novafoundation.nova.feature_governance_api.domain.tindergov - -import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem -import io.novafoundation.nova.feature_governance_api.data.model.VotingPower -import io.novafoundation.nova.feature_governance_api.domain.referendum.details.ReferendumCall -import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendaState -import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendumPreview -import io.novafoundation.nova.runtime.multiNetwork.chain.model.ChainId -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.Flow - -sealed interface VotingPowerState { - - object Empty : VotingPowerState - - class InsufficientAmount(val votingPower: VotingPower) : VotingPowerState - - class SufficientAmount(val votingPower: VotingPower) : VotingPowerState -} - -interface TinderGovInteractor { - - fun observeReferendaState(coroutineScope: CoroutineScope): Flow - - fun observeReferendaAvailableToVote(coroutineScope: CoroutineScope): Flow> - - suspend fun getReferendumAmount(referendumPreview: ReferendumPreview): ReferendumCall.TreasuryRequest? - - suspend fun setVotingPower(votingPower: VotingPower) - - suspend fun getVotingPower(metaId: Long, chainId: ChainId): VotingPower? - - suspend fun getVotingPowerState(): VotingPowerState - - suspend fun awaitAllItemsVoted(coroutineScope: CoroutineScope, basket: List) -} diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt index 0bb65f1ade..b02d0df8b5 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/di/modules/screens/TinderGovModule.kt @@ -7,9 +7,9 @@ import io.novafoundation.nova.common.data.network.NetworkApiCreator import io.novafoundation.nova.common.di.scope.FeatureScope import io.novafoundation.nova.core_db.dao.TinderGovDao import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository -import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor +import io.novafoundation.nova.feature_governance_impl.domain.summary.ReferendaSummaryInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovBasketInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.RealReferendumSummaryDataSource import io.novafoundation.nova.feature_governance_impl.data.offchain.referendum.summary.v2.ReferendumSummaryApi diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovBasketInteractor.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/TinderGovBasketInteractor.kt similarity index 89% rename from feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovBasketInteractor.kt rename to feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/TinderGovBasketInteractor.kt index 6fc41f2cac..76dd09c339 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovBasketInteractor.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/TinderGovBasketInteractor.kt @@ -6,8 +6,6 @@ import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepos import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.VoteType -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.data.repository.tindergov.TinderGovBasketRepository import io.novafoundation.nova.feature_governance_impl.data.repository.tindergov.TinderGovVotingPowerRepository @@ -23,6 +21,27 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first +interface TinderGovBasketInteractor { + + fun observeTinderGovBasket(): Flow> + + suspend fun getTinderGovBasket(): List + + suspend fun addItemToBasket(referendumId: ReferendumId, voteType: VoteType) + + suspend fun removeReferendumFromBasket(item: TinderGovBasketItem) + + suspend fun removeBasketItems(items: Collection) + + suspend fun isBasketEmpty(): Boolean + + suspend fun clearBasket() + + suspend fun getBasketItemsToRemove(coroutineScope: CoroutineScope): List + + suspend fun awaitAllItemsVoted(coroutineScope: CoroutineScope, basket: List) +} + class RealTinderGovBasketInteractor( private val governanceSharedState: GovernanceSharedState, private val referendaSharedComputation: ReferendaSharedComputation, diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovInteractor.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/TinderGovInteractor.kt similarity index 87% rename from feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovInteractor.kt rename to feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/TinderGovInteractor.kt index da58e90c66..76beae00a3 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/RealTinderGovInteractor.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/referendum/tindergov/TinderGovInteractor.kt @@ -12,8 +12,6 @@ import io.novafoundation.nova.feature_governance_api.domain.referendum.list.Refe import io.novafoundation.nova.feature_governance_api.domain.referendum.list.Voter import io.novafoundation.nova.feature_governance_api.domain.referendum.list.toCallOrNull import io.novafoundation.nova.feature_governance_api.domain.referendum.list.user -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.VotingPowerState import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.data.repository.tindergov.TinderGovVotingPowerRepository import io.novafoundation.nova.feature_governance_impl.domain.referendum.details.call.ReferendumPreImageParser @@ -32,6 +30,32 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map +sealed interface VotingPowerState { + + object Empty : VotingPowerState + + class InsufficientAmount(val votingPower: VotingPower) : VotingPowerState + + class SufficientAmount(val votingPower: VotingPower) : VotingPowerState +} + +interface TinderGovInteractor { + + fun observeReferendaState(coroutineScope: CoroutineScope): Flow + + fun observeReferendaAvailableToVote(coroutineScope: CoroutineScope): Flow> + + suspend fun getReferendumAmount(referendumPreview: ReferendumPreview): ReferendumCall.TreasuryRequest? + + suspend fun setVotingPower(votingPower: VotingPower) + + suspend fun getVotingPower(metaId: Long, chainId: ChainId): VotingPower? + + suspend fun getVotingPowerState(): VotingPowerState + + suspend fun awaitAllItemsVoted(coroutineScope: CoroutineScope, basket: List) +} + class RealTinderGovInteractor( private val governanceSharedState: GovernanceSharedState, private val referendaSharedComputation: ReferendaSharedComputation, diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendumSummaryInteractor.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummaryInteractor.kt similarity index 85% rename from feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendumSummaryInteractor.kt rename to feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummaryInteractor.kt index d68ec94fe9..7f8bc87241 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendumSummaryInteractor.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummaryInteractor.kt @@ -1,11 +1,15 @@ package io.novafoundation.nova.feature_governance_impl.domain.summary import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId -import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.runtime.state.selectedOption import kotlinx.coroutines.CoroutineScope +interface ReferendaSummaryInteractor { + + suspend fun getReferendaSummaries(ids: List, coroutineScope: CoroutineScope): Map +} + class RealReferendaSummaryInteractor( private val governanceSharedState: GovernanceSharedState, private val referendaSummarySharedComputation: ReferendaSummarySharedComputation diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummarySharedComputation.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummarySharedComputation.kt index 7d7876549f..8237e87b3b 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummarySharedComputation.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/domain/summary/ReferendaSummarySharedComputation.kt @@ -19,9 +19,9 @@ class ReferendaSummarySharedComputation( scope: CoroutineScope ): Map? { val chainId = governanceOption.assetWithChain.chain.id - val referendaSet = referendaIds.toSet() + val referendaHashCode = referendaIds.toSet().hashCode() val selectedLanguage = accountRepository.selectedLanguage() - val key = "REFERENDA_SUMMARIES:$chainId:$referendaSet:${selectedLanguage.iso639Code}" + val key = "REFERENDA_SUMMARIES:$chainId:$referendaHashCode:${selectedLanguage.iso639Code}" return computationalCache.useCache(key, scope) { referendumDetailsRepository.loadSummaries(governanceOption.assetWithChain.chain, referendaIds, selectedLanguage) diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/ReferendaListViewModel.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/ReferendaListViewModel.kt index 3f3cd1b4e0..176e60a989 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/ReferendaListViewModel.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/ReferendaListViewModel.kt @@ -3,6 +3,7 @@ package io.novafoundation.nova.feature_governance_impl.presentation.referenda.li import android.util.Log import androidx.lifecycle.viewModelScope import io.novafoundation.nova.common.base.BaseViewModel +import io.novafoundation.nova.common.domain.ExtendedLoadingState import io.novafoundation.nova.common.domain.dataOrNull import io.novafoundation.nova.common.list.toListWithHeaders import io.novafoundation.nova.common.domain.mapLoading @@ -28,7 +29,7 @@ import io.novafoundation.nova.feature_governance_impl.domain.filters.ReferendaFi import io.novafoundation.nova.feature_governance_api.domain.referendum.filters.ReferendumType import io.novafoundation.nova.feature_governance_api.domain.referendum.filters.ReferendumTypeFilter import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendaListState -import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor +import io.novafoundation.nova.feature_governance_impl.domain.summary.ReferendaSummaryInteractor import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter import io.novafoundation.nova.feature_governance_impl.presentation.referenda.common.ReferendumFormatter import io.novafoundation.nova.feature_governance_impl.presentation.referenda.common.list.ReferendaListStateModel @@ -114,7 +115,7 @@ class ReferendaListViewModel( val tinderGovBanner = referendaSummariesFlow.map { summaries -> val chain = selectedAssetSharedState.chain() - mapTinderGovToUi(chain, summaries.dataOrNull) + mapTinderGovToUi(chain, summaries) } .inBackground() .shareWhileSubscribed() @@ -179,15 +180,16 @@ class ReferendaListViewModel( } } - private fun mapTinderGovToUi(chain: Chain, referendaSummaries: Map?): TinderGovBannerModel? { + private fun mapTinderGovToUi(chain: Chain, referendaSummariesLoadingState: ExtendedLoadingState>): TinderGovBannerModel? { if (!chain.supportTinderGov()) return null - if (referendaSummaries == null) return null + + val referendumSummaries = referendaSummariesLoadingState.dataOrNull ?: return null return TinderGovBannerModel( - if (referendaSummaries.isEmpty()) { + if (referendumSummaries.isEmpty()) { null } else { - resourceManager.getString(R.string.referenda_swipe_gov_banner_chip, referendaSummaries.size) + resourceManager.getString(R.string.referenda_swipe_gov_banner_chip, referendumSummaries.size) } ) } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/di/ReferendaListModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/di/ReferendaListModule.kt index 05fb3b415c..38f39b5a48 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/di/ReferendaListModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/list/di/ReferendaListModule.kt @@ -12,7 +12,7 @@ import io.novafoundation.nova.common.resources.ResourceManager import io.novafoundation.nova.core.updater.UpdateSystem import io.novafoundation.nova.feature_account_api.domain.interfaces.SelectedAccountUseCase import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendaListInteractor -import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor +import io.novafoundation.nova.feature_governance_impl.domain.summary.ReferendaSummaryInteractor import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.domain.dapp.GovernanceDAppsInteractor import io.novafoundation.nova.feature_governance_impl.domain.filters.ReferendaFiltersInteractor diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/vote/setup/tindergov/SetupTinderGovVoteViewModel.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/vote/setup/tindergov/SetupTinderGovVoteViewModel.kt index ec911efca8..6778b09057 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/vote/setup/tindergov/SetupTinderGovVoteViewModel.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/vote/setup/tindergov/SetupTinderGovVoteViewModel.kt @@ -7,7 +7,7 @@ import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepos import io.novafoundation.nova.feature_governance_api.data.model.VotingPower import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.VoteType import io.novafoundation.nova.feature_governance_api.domain.referendum.vote.VoteReferendumInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.R import io.novafoundation.nova.feature_governance_impl.domain.referendum.vote.validations.referendum.VoteReferendaValidationPayload import io.novafoundation.nova.feature_governance_impl.domain.referendum.vote.validations.referendum.VoteReferendumValidationSystem diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/vote/setup/tindergov/di/SetupTinderGovVoteModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/vote/setup/tindergov/di/SetupTinderGovVoteModule.kt index 5b012ed54f..7632a1668d 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/vote/setup/tindergov/di/SetupTinderGovVoteModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/referenda/vote/setup/tindergov/di/SetupTinderGovVoteModule.kt @@ -12,7 +12,7 @@ import io.novafoundation.nova.common.resources.ResourceManager import io.novafoundation.nova.common.validation.ValidationExecutor import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository import io.novafoundation.nova.feature_governance_api.domain.referendum.vote.VoteReferendumInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.domain.referendum.vote.validations.referendum.VoteReferendumValidationSystem import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter import io.novafoundation.nova.feature_governance_impl.presentation.common.conviction.ConvictionValuesProvider diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/TinderGovBasketViewModel.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/TinderGovBasketViewModel.kt index c31b67d5aa..ea7f491875 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/TinderGovBasketViewModel.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/TinderGovBasketViewModel.kt @@ -14,8 +14,8 @@ import io.novafoundation.nova.common.utils.toggle import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.VoteType import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendumPreview -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovBasketInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.R import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/di/TinderGovBasketModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/di/TinderGovBasketModule.kt index acebdc6a49..cdf5c28ea6 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/di/TinderGovBasketModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/basket/di/TinderGovBasketModule.kt @@ -10,8 +10,8 @@ import io.novafoundation.nova.common.di.viewmodel.ViewModelKey import io.novafoundation.nova.common.di.viewmodel.ViewModelModule import io.novafoundation.nova.common.mixin.actionAwaitable.ActionAwaitableMixin import io.novafoundation.nova.common.resources.ResourceManager -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovBasketInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter import io.novafoundation.nova.feature_governance_impl.presentation.common.voters.VotersFormatter diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/TinderGovCardsViewModel.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/TinderGovCardsViewModel.kt index d176dcff32..434a2c3ded 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/TinderGovCardsViewModel.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/TinderGovCardsViewModel.kt @@ -21,10 +21,10 @@ import io.novafoundation.nova.feature_governance_api.data.network.blockhain.mode import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.VoteType import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.amountMultiplier import io.novafoundation.nova.feature_governance_api.domain.referendum.list.ReferendumPreview -import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.VotingPowerState +import io.novafoundation.nova.feature_governance_impl.domain.summary.ReferendaSummaryInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovBasketInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.VotingPowerState import io.novafoundation.nova.feature_governance_impl.R import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter import io.novafoundation.nova.feature_governance_impl.presentation.common.info.ReferendumInfoPayload @@ -91,7 +91,7 @@ class TinderGovCardsViewModel( private val _resetCards = MutableLiveData>() val resetCardsEvent: LiveData> = _resetCards - private val topReferendumWithDetails = combine(topCardIndex, sortedReferendaFlow) { topCardIndex, referenda -> + private val topCardFlow = combine(topCardIndex, sortedReferendaFlow) { topCardIndex, referenda -> referenda.getOrNull(topCardIndex) ?: return@combine null } .distinctUntilChanged() @@ -99,7 +99,7 @@ class TinderGovCardsViewModel( private var isVotingInProgress = MutableStateFlow(false) - val manageVotingPowerAvailable = topReferendumWithDetails.map { it != null } + val manageVotingPowerAvailable = topCardFlow.map { it != null } val isCardDraggingAvailable = isVotingInProgress.map { !it } @@ -169,7 +169,7 @@ class TinderGovCardsViewModel( fun editVotingPowerClicked() { launch { - val topReferendum = topReferendumWithDetails.first() + val topReferendum = topCardFlow.first() val topReferendumId = topReferendum?.id?.value ?: return@launch val request = TinderGovVoteRequester.Request(topReferendumId) tinderGovVoteRequester.openRequest(request) @@ -295,8 +295,7 @@ class TinderGovCardsViewModel( val summaries = referendaSummaryInteractor.getReferendaSummaries(referendaIds, viewModelScope) val amounts = referenda.associate { it.id to it.getAmountModel() } - val referendaCards = referenda.mapToCardWithDetails(summaries, amounts) - .filterNotNull() + val referendaCards = referenda.mapToCardsAndFilterBySummaries(summaries, amounts) ReferendaWithBasket(referendaCards, basket) } @@ -304,12 +303,12 @@ class TinderGovCardsViewModel( .launchIn(this) } - private fun List.mapToCardWithDetails( + private fun List.mapToCardsAndFilterBySummaries( summaries: Map, amounts: Map - ): List { - return map { - val summary = summaries[it.id] ?: return@map null + ): List { + return mapNotNull { + val summary = summaries[it.id] ?: return@mapNotNull null CardWithDetails(it.id, summary, amounts[it.id]) } diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/di/TinderGovCardsModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/di/TinderGovCardsModule.kt index d38910c19a..72c2f53c88 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/di/TinderGovCardsModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/di/TinderGovCardsModule.kt @@ -15,9 +15,9 @@ import io.novafoundation.nova.common.di.viewmodel.ViewModelModule import io.novafoundation.nova.common.mixin.actionAwaitable.ActionAwaitableMixin import io.novafoundation.nova.common.resources.ResourceManager import io.novafoundation.nova.common.utils.markdown.BoldStylePlugin -import io.novafoundation.nova.feature_governance_api.domain.referendum.summary.ReferendaSummaryInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor +import io.novafoundation.nova.feature_governance_impl.domain.summary.ReferendaSummaryInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovBasketInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.setup.tindergov.TinderGovVoteCommunicator import io.novafoundation.nova.feature_governance_impl.presentation.tindergov.cards.TinderGovCardsViewModel diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/CardWithDetails.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/CardWithDetails.kt index d8f1e92005..8f0607f756 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/CardWithDetails.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/cards/model/CardWithDetails.kt @@ -3,23 +3,8 @@ package io.novafoundation.nova.feature_governance_impl.presentation.tindergov.ca import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId import io.novafoundation.nova.feature_wallet_api.presentation.model.AmountModel -class CardWithDetails( +data class CardWithDetails( val id: ReferendumId, val summary: String, val amount: AmountModel? -) { - - override fun equals(other: Any?): Boolean { - return other is CardWithDetails && - id == other.id && - summary == other.summary && - amount == other.amount - } - - override fun hashCode(): Int { - var result = id.hashCode() - result = 31 * result + summary.hashCode() - result = 31 * result + amount.hashCode() - return result - } -} +) diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/ConfirmTinderGovVoteViewModel.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/ConfirmTinderGovVoteViewModel.kt index bb6b2d48a7..e54116bfd4 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/ConfirmTinderGovVoteViewModel.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/ConfirmTinderGovVoteViewModel.kt @@ -13,8 +13,8 @@ import io.novafoundation.nova.feature_account_api.presenatation.actions.External import io.novafoundation.nova.feature_governance_api.data.model.TinderGovBasketItem import io.novafoundation.nova.feature_governance_api.data.model.accountVote import io.novafoundation.nova.feature_governance_api.domain.referendum.vote.VoteReferendumInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovBasketInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.R import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.domain.referendum.vote.validations.tindergov.VoteTinderGovValidationPayload diff --git a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/di/ConfirmTinderGovVoteModule.kt b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/di/ConfirmTinderGovVoteModule.kt index 3efb4111eb..51052adcb1 100644 --- a/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/di/ConfirmTinderGovVoteModule.kt +++ b/feature-governance-impl/src/main/java/io/novafoundation/nova/feature_governance_impl/presentation/tindergov/confirm/di/ConfirmTinderGovVoteModule.kt @@ -18,8 +18,8 @@ import io.novafoundation.nova.feature_account_api.presenatation.account.wallet.W import io.novafoundation.nova.feature_account_api.presenatation.actions.ExternalActions import io.novafoundation.nova.feature_governance_api.data.source.GovernanceSourceRegistry import io.novafoundation.nova.feature_governance_api.domain.referendum.vote.VoteReferendumInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovBasketInteractor -import io.novafoundation.nova.feature_governance_api.domain.tindergov.TinderGovInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovBasketInteractor +import io.novafoundation.nova.feature_governance_impl.domain.referendum.tindergov.TinderGovInteractor import io.novafoundation.nova.feature_governance_impl.data.GovernanceSharedState import io.novafoundation.nova.feature_governance_impl.domain.referendum.vote.validations.tindergov.VoteTinderGovValidationSystem import io.novafoundation.nova.feature_governance_impl.domain.referendum.vote.validations.tindergov.voteTinderGovValidationSystem