diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/news/models/response/NewsDetailsResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/news/models/response/NewsDetailsResponse.kt index c3f8338224..dd3ccb7001 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/news/models/response/NewsDetailsResponse.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/news/models/response/NewsDetailsResponse.kt @@ -16,14 +16,14 @@ data class NewsDetailsResponse( @Json(name = "newsUrl") val newsUrl: String, @Json(name = "shortContent") val shortContent: String, @Json(name = "content") val content: String, - @Json(name = "originalArticles") val originalArticles: List, + @Json(name = "relatedArticles") val relatedArticles: List, ) @JsonClass(generateAdapter = true) -data class NewsOriginalArticleDto( +data class NewsRelatedArticleDto( @Json(name = "id") val id: Int, @Json(name = "title") val title: String, - @Json(name = "source") val source: Source, + @Json(name = "media") val media: Media, @Json(name = "language") val language: String, @Json(name = "publishedAt") val publishedAt: String, @Json(name = "url") val url: String, @@ -31,7 +31,7 @@ data class NewsOriginalArticleDto( ) @JsonClass(generateAdapter = true) -data class Source( +data class Media( @Json(name = "id") val id: Int, @Json(name = "name") val name: String, ) \ No newline at end of file diff --git a/data/news/src/main/java/com/tangem/data/news/repository/NewsMapper.kt b/data/news/src/main/java/com/tangem/data/news/repository/NewsMapper.kt index 50a571f289..fd25f87723 100644 --- a/data/news/src/main/java/com/tangem/data/news/repository/NewsMapper.kt +++ b/data/news/src/main/java/com/tangem/data/news/repository/NewsMapper.kt @@ -2,7 +2,7 @@ package com.tangem.data.news.repository import com.tangem.datasource.api.news.models.response.NewsArticleDto import com.tangem.datasource.api.news.models.response.NewsDetailsResponse -import com.tangem.datasource.api.news.models.response.NewsOriginalArticleDto +import com.tangem.datasource.api.news.models.response.NewsRelatedArticleDto import com.tangem.datasource.api.news.models.response.NewsRelatedTokenDto import com.tangem.domain.models.news.* @@ -19,7 +19,7 @@ internal fun NewsDetailsResponse.toDomainDetailedArticle(isLiked: Boolean): Deta newsUrl = newsUrl, shortContent = shortContent, content = content, - originalArticles = originalArticles.map { it.toDomainOriginalArticle() }, + relatedArticles = relatedArticles.map { it.toDomainRelatedArticle() }, isLiked = isLiked, ) } @@ -47,13 +47,13 @@ internal fun NewsRelatedTokenDto.toDomainRelatedToken(): RelatedToken { ) } -internal fun NewsOriginalArticleDto.toDomainOriginalArticle(): OriginalArticle { - return OriginalArticle( +internal fun NewsRelatedArticleDto.toDomainRelatedArticle(): RelatedArticle { + return RelatedArticle( id = id, title = title, - source = Source( - id = source.id, - name = source.name, + media = Media( + id = media.id, + name = media.name, ), locale = language, publishedAt = publishedAt, diff --git a/domain/models/src/main/kotlin/com/tangem/domain/models/news/DetailedArticle.kt b/domain/models/src/main/kotlin/com/tangem/domain/models/news/DetailedArticle.kt index 94cc02be56..85c4d8dd94 100644 --- a/domain/models/src/main/kotlin/com/tangem/domain/models/news/DetailedArticle.kt +++ b/domain/models/src/main/kotlin/com/tangem/domain/models/news/DetailedArticle.kt @@ -17,7 +17,7 @@ import kotlinx.serialization.Serializable * @param newsUrl - link for article to share * @param shortContent - short description * @param content - main text of the article - * @param originalArticles - original articles, which were base to build detailed article. + * @param relatedArticles - articles, which were base to build detailed article. * @param isLiked - flag indicating whether the news is liked or not */ @Serializable @@ -33,6 +33,6 @@ data class DetailedArticle( val newsUrl: String, val shortContent: String, val content: String, - val originalArticles: List, + val relatedArticles: List, val isLiked: Boolean, ) \ No newline at end of file diff --git a/domain/models/src/main/kotlin/com/tangem/domain/models/news/OriginalArticle.kt b/domain/models/src/main/kotlin/com/tangem/domain/models/news/RelatedArticle.kt similarity index 74% rename from domain/models/src/main/kotlin/com/tangem/domain/models/news/OriginalArticle.kt rename to domain/models/src/main/kotlin/com/tangem/domain/models/news/RelatedArticle.kt index 83c59e20c0..2aa90f5cf0 100644 --- a/domain/models/src/main/kotlin/com/tangem/domain/models/news/OriginalArticle.kt +++ b/domain/models/src/main/kotlin/com/tangem/domain/models/news/RelatedArticle.kt @@ -3,22 +3,22 @@ package com.tangem.domain.models.news import kotlinx.serialization.Serializable /** - * Represents an original article, which was base to build detailed article. + * Represents an related article, which was base to build detailed article. * [REDACTED_AUTHOR] * @param id - unique identifier of the article * @param title - article title - * @param source - object of source name and identifier + * @param media - object of media name and identifier * @param locale - language of the article * @param publishedAt - date of article publishing * @param url - link to source of original article * @param imageUrl - image from source of original article */ @Serializable -data class OriginalArticle( +data class RelatedArticle( val id: Int, val title: String, - val source: Source, + val media: Media, val locale: String, val publishedAt: String, val url: String, @@ -26,7 +26,7 @@ data class OriginalArticle( ) @Serializable -data class Source( +data class Media( val id: Int, val name: String, ) \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/add/impl/model/AddToPortfolioModel.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/add/impl/model/AddToPortfolioModel.kt index 4e71735618..6b48ddb0ab 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/add/impl/model/AddToPortfolioModel.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/add/impl/model/AddToPortfolioModel.kt @@ -179,7 +179,6 @@ internal class AddToPortfolioModel @Inject constructor( callbackDelegate.onChangePortfolioClick.receiveAsFlow() .onEach { middleNavigationJob?.cancel() - setSelectedAccountToSelectorController() middleNavigationJob = changePortfolioNavigationFlow(data).launchIn(this) logAccountSelector(isAccountMode) navigation.pushNew(AddToPortfolioRoutes.PortfolioSelector) @@ -229,24 +228,15 @@ internal class AddToPortfolioModel @Inject constructor( } } - private fun setSelectedAccountToSelectorController() { - modelScope.launch(dispatchers.default) { - val selectedAccount = selectedPortfolio - .first() - .account - .account - .account - .accountId - portfolioSelectorController.selectAccount(selectedAccount) - } - } - - private fun changePortfolioNavigationFlow(data: AvailableToAddData): Flow { + private fun changePortfolioNavigationFlow(data: AvailableToAddData): Flow = flow { + val selectedPortfolioValue = selectedPortfolio.first() + val selectedAccount = selectedPortfolioValue.account.account.account.accountId + portfolioSelectorController.selectAccount(selectedAccount) val changedPortfolio = setupPortfolioFlow(data) .drop(1) .onEach { portfolio -> navigation.pushNew(routeToNetworkSelector(portfolio)) } val changedNetwork = setupNetworkFlow(changedPortfolio) - return combine( + combine( flow = changedPortfolio, flow2 = changedNetwork, transform = { newPortfolio, newNetwork -> @@ -254,7 +244,7 @@ internal class AddToPortfolioModel @Inject constructor( selectedNetwork.tryEmit(newNetwork) navigation.popToFirst() }, - ) + ).collect { emit(it) } } private fun setupTokenActionsFlow( diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/analytics/PortfolioAnalyticsEvent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/analytics/PortfolioAnalyticsEvent.kt index ee93e97a0c..87ea980421 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/analytics/PortfolioAnalyticsEvent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/analytics/PortfolioAnalyticsEvent.kt @@ -22,11 +22,11 @@ internal class PortfolioAnalyticsEvent( ) fun popupToChooseAccount() = PortfolioAnalyticsEvent( - event = "Popup to choose account", + event = "Choose Account Opened", ) fun addToNotMainAccount() = PortfolioAnalyticsEvent( - event = "Button - Add (token not to main Account)", + event = "Button - Add To Account", ) fun addToPortfolioWalletChanged() = PortfolioAnalyticsEvent(event = "Wallet Selected") diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/analytics/FeedAnalyticsEvent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/analytics/FeedAnalyticsEvent.kt index 7c9792e701..0cd8be35d7 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/analytics/FeedAnalyticsEvent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/analytics/FeedAnalyticsEvent.kt @@ -78,16 +78,7 @@ internal sealed class FeedAnalyticsEvent( ), ) - data class AllWidgetsLoadError( - private val code: Int?, - private val message: String, - ) : FeedAnalyticsEvent( - event = "All Widgets Load Error", - params = mapOf( - ERROR_CODE to (code ?: IS_NOT_HTTP_ERROR).toString(), - ERROR_MESSAGE to message, - ), - ) + class AllWidgetsLoadError : FeedAnalyticsEvent(event = "All Widgets Load Error") class TokenSearchedClicked : FeedAnalyticsEvent(event = "Token Searched Clicked") } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/state/transformers/UpdateGlobalFeedStateTransformer.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/state/transformers/UpdateGlobalFeedStateTransformer.kt index ee8c1226fe..d6e5ec6be2 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/state/transformers/UpdateGlobalFeedStateTransformer.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/state/transformers/UpdateGlobalFeedStateTransformer.kt @@ -1,7 +1,6 @@ package com.tangem.features.feed.model.feed.state.transformers import com.tangem.core.analytics.api.AnalyticsEventHandler -import com.tangem.datasource.api.common.response.ApiResponseError import com.tangem.domain.models.news.TrendingNews import com.tangem.features.feed.model.feed.analytics.FeedAnalyticsEvent import com.tangem.features.feed.model.market.list.state.SortByTypeUM @@ -38,7 +37,7 @@ internal class UpdateGlobalFeedStateTransformer( isNewsError && areAllChartsLoading -> GlobalFeedState.Loading isNewsError && areAllChartsError -> { if (previousGlobalState !is GlobalFeedState.Error) { - sendErrorAnalytics(errorStatesByOrder) + sendErrorAnalytics() } GlobalFeedState.Error( onRetryClicked = onRetryClicked, @@ -58,19 +57,9 @@ internal class UpdateGlobalFeedStateTransformer( ) } - private fun sendErrorAnalytics(errorStatesByOrder: Map) { - val firstError: Throwable? = errorStatesByOrder.values.firstNotNullOfOrNull { it } - firstError?.let { error -> - val (code, message) = when (error) { - is ApiResponseError.HttpException -> error.code.numericCode to error.message - else -> null to "" - } - analyticsEventHandler.send( - FeedAnalyticsEvent.AllWidgetsLoadError( - code = code, - message = message.orEmpty(), - ), - ) - } + private fun sendErrorAnalytics() { + analyticsEventHandler.send( + FeedAnalyticsEvent.AllWidgetsLoadError(), + ) } } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/list/MarketsListModel.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/list/MarketsListModel.kt index 2daaa70082..1692ec40b1 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/list/MarketsListModel.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/list/MarketsListModel.kt @@ -1,6 +1,7 @@ package com.tangem.features.feed.model.market.list import androidx.compose.runtime.Stable +import arrow.core.Either import arrow.core.getOrElse import com.tangem.common.ui.markets.models.MarketsListItemUM import com.tangem.core.analytics.api.AnalyticsEventHandler @@ -16,6 +17,10 @@ import com.tangem.domain.markets.TokenMarketListConfig import com.tangem.domain.markets.toSerializableParam import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.promo.PromoRepository +import com.tangem.domain.settings.usercountry.GetUserCountryUseCase +import com.tangem.domain.settings.usercountry.models.UserCountry +import com.tangem.domain.settings.usercountry.models.UserCountryError +import com.tangem.domain.settings.usercountry.models.needApplyFCARestrictions import com.tangem.features.feed.components.market.list.DefaultMarketsTokenListComponent import com.tangem.features.feed.model.market.list.analytics.MarketsListAnalyticsEvent import com.tangem.features.feed.model.market.list.state.ListUM @@ -48,6 +53,7 @@ internal class MarketsListModel @Inject constructor( paramsContainer: ParamsContainer, private val promoRepository: PromoRepository, private val analyticsEventHandler: AnalyticsEventHandler, + private val getUserCountryUseCase: GetUserCountryUseCase, ) : Model() { private val updateQuotesJob = JobHolder() @@ -124,12 +130,14 @@ internal class MarketsListModel @Inject constructor( appCurrency = currentAppCurrency.value, interval = marketsListUMStateManager.selectedInterval.toBatchRequestInterval(), ).conflate(), - ) { uiItems, isInInitialLoadingErrorState, isSearchNotFoundState, isYieldModePromo -> + flow5 = getUserCountryUseCase.invoke(), + ) { uiItems, isInInitialLoadingErrorState, isSearchNotFoundState, isYieldModePromo, userCountry -> MarketsItemsData( items = uiItems, isInErrorState = isInInitialLoadingErrorState, isSearchNotFound = isSearchNotFoundState, shouldShowYieldModePromo = isYieldModePromo, + userCountry = userCountry, ) } } else { @@ -140,17 +148,20 @@ internal class MarketsListModel @Inject constructor( appCurrency = currentAppCurrency.value, interval = marketsListUMStateManager.selectedInterval.toBatchRequestInterval(), ).conflate(), - ) { uiItems, isInInitialLoadingErrorState, shouldShowYieldModePromo -> + flow4 = getUserCountryUseCase.invoke(), + ) { uiItems, isInInitialLoadingErrorState, shouldShowYieldModePromo, userCountry -> MarketsItemsData( items = uiItems, isInErrorState = isInInitialLoadingErrorState, isSearchNotFound = false, shouldShowYieldModePromo = shouldShowYieldModePromo, + userCountry = userCountry, ) } } }.collect { marketsItemsData -> - val shouldShowYieldModePromo = marketsItemsData.shouldShowYieldModePromo + val isApplyFCARestrictions = marketsItemsData.userCountry.getOrNull().needApplyFCARestrictions() + val shouldShowYieldModePromo = marketsItemsData.shouldShowYieldModePromo && !isApplyFCARestrictions if (marketsListUMStateManager.state.value.marketsNotificationUM == null && shouldShowYieldModePromo) { analyticsEventHandler.send(MarketsListAnalyticsEvent.YieldModePromoShown()) } @@ -332,5 +343,6 @@ internal class MarketsListModel @Inject constructor( val isInErrorState: Boolean, val isSearchNotFound: Boolean, val shouldShowYieldModePromo: Boolean, + val userCountry: Either, ) } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/NewsDetailsModel.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/NewsDetailsModel.kt index 91f9fa30d2..3ea4a9c266 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/NewsDetailsModel.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/NewsDetailsModel.kt @@ -14,7 +14,7 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.GetTokenMarketInfoUseCase import com.tangem.domain.markets.GetTokenPriceChartUseCase -import com.tangem.domain.models.news.OriginalArticle +import com.tangem.domain.models.news.RelatedArticle import com.tangem.domain.news.usecase.GetNewsListBatchFlowUseCase import com.tangem.domain.news.usecase.MarkArticleAsViewedUseCase import com.tangem.domain.news.usecase.ObserveNewsDetailsUseCase @@ -60,7 +60,7 @@ internal class NewsDetailsModel @Inject constructor( private val params = paramsContainer.require() private val currentLanguage = Locale.getDefault().language - private val newsDetailsConverter = NewsDetailsConverter(onSourceClick = ::onOriginalArticleClick) + private val newsDetailsConverter = NewsDetailsConverter(onRelatedArticleClick = ::onRelatedArticleClick) private val paginationManager: NewsDetailsPaginationManager? = params.paginationConfig?.let { config -> NewsDetailsPaginationManager( @@ -139,14 +139,14 @@ internal class NewsDetailsModel @Inject constructor( } } - private fun onOriginalArticleClick(originalArticle: OriginalArticle) { + private fun onRelatedArticleClick(relatedArticle: RelatedArticle) { analyticsEventHandler.send( NewsDetailsAnalyticsEvent.RelatedNewsClicked( newsId = params.articleId, - relatedNewsId = originalArticle.id, + relatedNewsId = relatedArticle.id, ), ) - urlOpener.openUrl(originalArticle.url) + urlOpener.openUrl(relatedArticle.url) } private fun onArticleIndexChanged(newIndex: Int) { diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/converter/NewsDetailsConverter.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/converter/NewsDetailsConverter.kt index 95fd1b69b0..ee57aec32a 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/converter/NewsDetailsConverter.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/converter/NewsDetailsConverter.kt @@ -11,11 +11,11 @@ import com.tangem.core.ui.utils.getFormattedDate import com.tangem.data.common.currency.getTokenIconUrlFromDefaultHost import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.news.DetailedArticle -import com.tangem.domain.models.news.OriginalArticle +import com.tangem.domain.models.news.RelatedArticle import com.tangem.features.feed.impl.R import com.tangem.features.feed.ui.news.details.state.ArticleUM -import com.tangem.features.feed.ui.news.details.state.Source -import com.tangem.features.feed.ui.news.details.state.SourceUM +import com.tangem.features.feed.ui.news.details.state.Media +import com.tangem.features.feed.ui.news.details.state.RelatedArticleUM import com.tangem.utils.StringsSigns import com.tangem.utils.converter.Converter import kotlinx.collections.immutable.ImmutableList @@ -24,7 +24,7 @@ import org.joda.time.DateTime @Stable internal class NewsDetailsConverter( - private val onSourceClick: (OriginalArticle) -> Unit, + private val onRelatedArticleClick: (RelatedArticle) -> Unit, ) : Converter { override fun convert(value: DetailedArticle): ArticleUM { @@ -36,7 +36,7 @@ internal class NewsDetailsConverter( tags = buildTags(value), shortContent = value.shortContent, content = value.content, - sources = buildSources(value), + relatedArticles = buildRelatedArticles(value), newsUrl = value.newsUrl, relatedTokens = value.relatedTokens.toImmutableList(), isLiked = value.isLiked, @@ -60,16 +60,16 @@ internal class NewsDetailsConverter( return (categoryLabels + tokenLabels).toImmutableList() } - private fun buildSources(article: DetailedArticle): ImmutableList { - return article.originalArticles.map { originalArticle -> - SourceUM( - id = originalArticle.id, - title = originalArticle.title, - source = Source(id = originalArticle.source.id, name = originalArticle.source.name), - publishedAt = mapFormattedDate(originalArticle.publishedAt), - url = originalArticle.url, - onClick = { onSourceClick(originalArticle) }, - imageUrl = originalArticle.imageUrl, + private fun buildRelatedArticles(article: DetailedArticle): ImmutableList { + return article.relatedArticles.map { relatedArticle -> + RelatedArticleUM( + id = relatedArticle.id, + title = relatedArticle.title, + media = Media(id = relatedArticle.media.id, name = relatedArticle.media.name), + publishedAt = mapFormattedDate(relatedArticle.publishedAt), + url = relatedArticle.url, + onClick = { onRelatedArticleClick(relatedArticle) }, + imageUrl = relatedArticle.imageUrl, ) }.toImmutableList() } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/NewsDetailsContent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/NewsDetailsContent.kt index 2aad7230ef..c1ba03727c 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/NewsDetailsContent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/NewsDetailsContent.kt @@ -211,7 +211,7 @@ private fun ArticleDetail( modifier = Modifier.padding(horizontal = 16.dp), ) - if (article.sources.isNotEmpty()) { + if (article.relatedArticles.isNotEmpty()) { SpacerH(24.dp) Row( modifier = Modifier.padding(horizontal = 16.dp), @@ -223,7 +223,7 @@ private fun ArticleDetail( color = TangemTheme.colors.text.primary1, ) Text( - text = "${article.sources.size}", + text = "${article.relatedArticles.size}", style = TangemTheme.typography.h3, color = TangemTheme.colors.text.tertiary, ) @@ -231,8 +231,8 @@ private fun ArticleDetail( } } - if (article.sources.isNotEmpty()) { - item("sources") { + if (article.relatedArticles.isNotEmpty()) { + item("relatedArticles") { LazyRow( modifier = Modifier.padding(vertical = 12.dp), state = rememberLazyListState(), @@ -240,11 +240,11 @@ private fun ArticleDetail( horizontalArrangement = Arrangement.spacedBy(12.dp), ) { items( - items = article.sources, - key = SourceUM::id, - ) { source -> - SourceItem( - source = source, + items = article.relatedArticles, + key = RelatedArticleUM::id, + ) { article -> + RelatedNewsItem( + relatedArticle = article, modifier = Modifier.fillParentMaxHeight(), ) } @@ -301,12 +301,12 @@ private fun QuickRecap(content: String, modifier: Modifier = Modifier) { } @Composable -private fun SourceItem(source: SourceUM, modifier: Modifier = Modifier) { +private fun RelatedNewsItem(relatedArticle: RelatedArticleUM, modifier: Modifier = Modifier) { Column( modifier = modifier .sizeIn(maxWidth = 256.dp, minHeight = 132.dp) .background(color = TangemTheme.colors.background.action, shape = RoundedCornerShape(12.dp)) - .clickable(onClick = source.onClick) + .clickable(onClick = relatedArticle.onClick) .padding(12.dp), ) { Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { @@ -320,17 +320,17 @@ private fun SourceItem(source: SourceUM, modifier: Modifier = Modifier) { ) SpacerW(4.dp) Text( - text = source.source.name, + text = relatedArticle.media.name, style = TangemTheme.typography.caption1, maxLines = 1, overflow = TextOverflow.Ellipsis, color = TangemTheme.colors.text.tertiary, ) } - if (source.title.isNotEmpty()) { + if (relatedArticle.title.isNotEmpty()) { SpacerH(4.dp) Text( - text = source.title, + text = relatedArticle.title, style = TangemTheme.typography.subtitle2, color = TangemTheme.colors.text.primary1, maxLines = 3, @@ -338,14 +338,14 @@ private fun SourceItem(source: SourceUM, modifier: Modifier = Modifier) { ) } } - if (source.imageUrl != null) { + if (relatedArticle.imageUrl != null) { SubcomposeAsyncImage( modifier = Modifier .size(40.dp) .clip(RoundedCornerShape(4.dp)), contentScale = ContentScale.Crop, model = ImageRequest.Builder(context = LocalContext.current) - .data(source.imageUrl) + .data(relatedArticle.imageUrl) .crossfade(enable = false) .allowHardware(true) .memoryCachePolicy(CachePolicy.DISABLED) @@ -357,13 +357,13 @@ private fun SourceItem(source: SourceUM, modifier: Modifier = Modifier) { ) }, error = {}, - contentDescription = source.source.name, + contentDescription = relatedArticle.media.name, ) } } SpacerHMax() Text( - text = source.publishedAt.resolveReference(), + text = relatedArticle.publishedAt.resolveReference(), style = TangemTheme.typography.caption2, color = TangemTheme.colors.text.tertiary, ) diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/state/MockArticlesFactory.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/state/MockArticlesFactory.kt index 7f051d52fc..e0d620f33b 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/state/MockArticlesFactory.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/state/MockArticlesFactory.kt @@ -20,11 +20,11 @@ internal object MockArticlesFactory { ).toPersistentList(), shortContent = "Bitwise has updated its Solana ETF, adding staking and setting a low management fee of 0.20%.", content = "Bitwise Asset Management has revised its filing to launch a Solana ETF, renaming it \"Bitwise Solana Staking ETF\" and setting an exceptionally low management fee of just 0.20%.\n\nThe update comes as the SEC prepares to review several Solana ETF applications.", - sources = listOf( - SourceUM( + relatedArticles = listOf( + RelatedArticleUM( id = 1, title = "Deeper liquidity could drive crypto market beyond \$6T", - source = Source( + media = Media( id = 11, name = "Coin-telegraph", ), @@ -33,10 +33,10 @@ internal object MockArticlesFactory { onClick = {}, imageUrl = null, ), - SourceUM( + RelatedArticleUM( id = 2, title = "Top gainers and losers in crypto this week", - source = Source( + media = Media( id = 10, name = "Investing", ), @@ -61,11 +61,11 @@ internal object MockArticlesFactory { ).toPersistentList(), shortContent = "Bitcoin spot ETFs recorded fourth consecutive day of positive inflows.", content = "Bitcoin spot ETFs continue their impressive streak with \$550 million in net positive inflows.\n\nBlackRock's IBIT led with \$250M.", - sources = listOf( - SourceUM( + relatedArticles = listOf( + RelatedArticleUM( id = 3, title = "Bitcoin ETFs see massive inflows", - source = Source( + media = Media( id = 12, name = "Bloomberg", ), @@ -90,11 +90,11 @@ internal object MockArticlesFactory { ).toPersistentList(), shortContent = "Ethereum developers announced major network upgrade.", content = "The Ethereum Foundation announced a significant upgrade for Q2 2025.\n\nKey improvements include EVM enhancements.", - sources = listOf( - SourceUM( + relatedArticles = listOf( + RelatedArticleUM( id = 4, title = "Ethereum core devs announce upgrade", - source = Source( + media = Media( id = 15, name = "CoinDesk", ), @@ -119,11 +119,11 @@ internal object MockArticlesFactory { ).toPersistentList(), shortContent = "Solana achieved new milestone processing more daily transactions than Ethereum.", content = "Solana processed over 50 million transactions in a single day.\n\nDriven by DeFi and NFT activity.", - sources = listOf( - SourceUM( + relatedArticles = listOf( + RelatedArticleUM( id = 5, title = "Solana transactions hit record", - source = Source( + media = Media( id = 18, name = "Times", ), @@ -147,7 +147,7 @@ internal object MockArticlesFactory { ).toPersistentList(), shortContent = "New DeFi protocol introduced innovative yield farming approach.", content = "A newly launched protocol unveiled innovative yield farming mechanism.\n\nAPY rates range from 15% to 30%.", - sources = persistentListOf(), + relatedArticles = persistentListOf(), newsUrl = "", relatedTokens = persistentListOf(), isLiked = false, @@ -163,7 +163,7 @@ internal object MockArticlesFactory { ).toPersistentList(), shortContent = "Comprehensive cryptocurrency regulation bill passed Senate Banking Committee.", content = "The US Senate Banking Committee advanced landmark crypto regulation bill.\n\nKey provisions include asset definitions.", - sources = persistentListOf(), + relatedArticles = persistentListOf(), newsUrl = "", relatedTokens = persistentListOf(), isLiked = false, @@ -178,7 +178,7 @@ internal object MockArticlesFactory { ).toPersistentList(), shortContent = "World's largest bank announced cryptocurrency custody services.", content = "Major financial institution announced comprehensive crypto custody services.\n\nSupporting Bitcoin and Ethereum initially.", - sources = persistentListOf(), + relatedArticles = persistentListOf(), newsUrl = "", relatedTokens = persistentListOf(), isLiked = false, @@ -193,7 +193,7 @@ internal object MockArticlesFactory { ).toPersistentList(), shortContent = "Leading NFT marketplace experienced dramatic surge in trading activity.", content = "Prominent NFT marketplace reported 300% increase in trading volume.\n\nNew features include lower fees.", - sources = persistentListOf(), + relatedArticles = persistentListOf(), newsUrl = "", relatedTokens = persistentListOf(), isLiked = false, @@ -209,7 +209,7 @@ internal object MockArticlesFactory { ).toPersistentList(), shortContent = "New Layer 2 scaling solution achieved 100,000 TPS in testing.", content = "Layer 2 solution processed 100,000 transactions per second.\n\nUsing zero-knowledge proof technology.", - sources = persistentListOf(), + relatedArticles = persistentListOf(), newsUrl = "", relatedTokens = persistentListOf(), isLiked = false, @@ -225,7 +225,7 @@ internal object MockArticlesFactory { ).toPersistentList(), shortContent = "Total stablecoin market capitalization surpassed \$180 billion.", content = "Stablecoin market cap reached \$180 billion all-time high.\n\nDriven by DeFi activity and institutional adoption.", - sources = persistentListOf(), + relatedArticles = persistentListOf(), newsUrl = "", relatedTokens = persistentListOf(), isLiked = false, diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/state/NewsDetailsUM.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/state/NewsDetailsUM.kt index a3402431c2..b83bea4e2e 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/state/NewsDetailsUM.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/state/NewsDetailsUM.kt @@ -33,16 +33,16 @@ internal data class ArticleUM( val tags: ImmutableList, val shortContent: String, val content: String, - val sources: ImmutableList, + val relatedArticles: ImmutableList, val newsUrl: String, val relatedTokens: ImmutableList, val isLiked: Boolean, ) -internal data class SourceUM( +internal data class RelatedArticleUM( val id: Int, val title: String, - val source: Source, + val media: Media, val publishedAt: TextReference, val url: String, val onClick: () -> Unit, @@ -62,7 +62,7 @@ internal sealed interface RelatedTokensUM { data object LoadingError : RelatedTokensUM } -internal data class Source( +internal data class Media( val id: Int, val name: String, ) \ No newline at end of file