diff --git a/common/ui/src/main/java/com/tangem/common/ui/news/ArticleCard.kt b/common/ui/src/main/java/com/tangem/common/ui/news/ArticleCard.kt
index 91e26bb895..3b3f257ab5 100644
--- a/common/ui/src/main/java/com/tangem/common/ui/news/ArticleCard.kt
+++ b/common/ui/src/main/java/com/tangem/common/ui/news/ArticleCard.kt
@@ -1,6 +1,7 @@
package com.tangem.common.ui.news
import android.content.res.Configuration
+import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
@@ -12,6 +13,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -100,6 +103,41 @@ private fun TrendingArticle(articleConfigUM: ArticleConfigUM) {
}
}
+@Composable
+fun ShowMoreArticlesCard(modifier: Modifier = Modifier, onClick: () -> Unit) {
+ BlockCard(
+ modifier = modifier,
+ onClick = onClick,
+ colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action),
+ ) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(vertical = 31.dp, horizontal = 12.dp),
+ ) {
+ Image(
+ imageVector = ImageVector.vectorResource(R.drawable.ic_show_more_news_48),
+ contentDescription = stringResourceSafe(R.string.common_show_more),
+ )
+
+ SpacerH(16.dp)
+
+ Text(
+ text = stringResourceSafe(R.string.news_all_news),
+ style = TangemTheme.typography.subtitle1,
+ color = TangemTheme.colors.text.primary1,
+ )
+
+ Text(
+ text = stringResourceSafe(R.string.news_stay_in_the_loop),
+ style = TangemTheme.typography.caption2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ }
+ }
+}
+
@Composable
private fun DefaultArticle(articleConfigUM: ArticleConfigUM) {
Column(modifier = Modifier.padding(12.dp)) {
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/fields/SearchBar.kt b/core/ui/src/main/java/com/tangem/core/ui/components/fields/SearchBar.kt
index c0390dfda0..17ddadc6ff 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/fields/SearchBar.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/fields/SearchBar.kt
@@ -10,9 +10,8 @@ import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.Stable
-import androidx.compose.runtime.remember
+import androidx.compose.runtime.*
+import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.focus.FocusRequester
@@ -51,16 +50,22 @@ fun SearchBar(
val keyboardController = LocalSoftwareKeyboardController.current
val focusManager = LocalFocusManager.current
val interactionSource = remember { MutableInteractionSource() }
+ var isInitialComposition by rememberSaveable { mutableStateOf(true) }
+ LaunchedEffect(Unit) {
+ isInitialComposition = false
+ }
BasicTextField(
modifier = modifier
.fillMaxWidth()
.heightIn(min = TangemTheme.dimens.size48)
.onFocusChanged { focusState ->
- if (focusState.isFocused) {
- state.onActiveChange(true)
- } else {
- state.onActiveChange(false)
+ if (!isInitialComposition) {
+ if (focusState.isFocused) {
+ state.onActiveChange(true)
+ } else {
+ state.onActiveChange(false)
+ }
}
}
.focusRequester(focusRequester)
@@ -163,6 +168,7 @@ private fun ClearButton(
focusManager.clearFocus()
keyboardController?.hide()
state.onActiveChange(false)
+ state.onClearClick()
},
) {
Icon(
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/fields/entity/SearchBarUM.kt b/core/ui/src/main/java/com/tangem/core/ui/components/fields/entity/SearchBarUM.kt
index d2ac8fcc8b..158c768fe8 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/fields/entity/SearchBarUM.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/fields/entity/SearchBarUM.kt
@@ -8,4 +8,5 @@ data class SearchBarUM(
val onQueryChange: (String) -> Unit,
val isActive: Boolean,
val onActiveChange: (Boolean) -> Unit,
+ val onClearClick: () -> Unit = {},
)
\ No newline at end of file
diff --git a/core/ui/src/main/res/drawable/ic_show_more_news_48.xml b/core/ui/src/main/res/drawable/ic_show_more_news_48.xml
new file mode 100644
index 0000000000..fe0417c568
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_show_more_news_48.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/DefaultFeedEntryComponent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/DefaultFeedEntryComponent.kt
index 0519eeeaf2..c3f6755841 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/DefaultFeedEntryComponent.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/DefaultFeedEntryComponent.kt
@@ -60,14 +60,14 @@ internal class DefaultFeedEntryComponent @AssistedInject constructor(
)
}
- override fun onMarketOpenClick(sortBy: SortByTypeUM) {
+ override fun onMarketOpenClick(sortBy: SortByTypeUM?) {
innerRouter.push(
route = FeedEntryChildFactory.Child.TokenList(
params = DefaultMarketsTokenListComponent.Params(
onBackClicked = { onChildBack() },
onTokenClick = { token, currency -> onMarketItemClick(token, currency) },
- preselectedSortType = sortBy,
- shouldAlwaysShowSearchBar = sortBy == SortByTypeUM.Rating,
+ preselectedSortType = sortBy ?: SortByTypeUM.Rating,
+ shouldAlwaysShowSearchBar = sortBy == null,
),
),
)
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/feed/DefaultFeedComponent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/feed/DefaultFeedComponent.kt
index 0b6ca24074..9257a465b1 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/feed/DefaultFeedComponent.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/feed/DefaultFeedComponent.kt
@@ -23,7 +23,7 @@ internal class DefaultFeedComponent(
@Composable
override fun Title() {
val state by feedComponentModel.state.collectAsStateWithLifecycle()
- FeedListHeader(state.searchBar)
+ FeedListHeader(state.feedListSearchBar)
}
@Composable
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/list/DefaultMarketsTokenListComponent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/list/DefaultMarketsTokenListComponent.kt
index a2f2670051..75c9ca0587 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/list/DefaultMarketsTokenListComponent.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/list/DefaultMarketsTokenListComponent.kt
@@ -26,7 +26,11 @@ internal class DefaultMarketsTokenListComponent(
@Composable
override fun Title() {
val state by model.state.collectAsStateWithLifecycle()
- TopBarWithSearch(state.searchBar)
+ TopBarWithSearch(
+ onBackClick = params.onBackClicked,
+ onSearchClick = state.onSearchClicked,
+ marketsSearchBar = state.marketsSearchBar,
+ )
}
@Composable
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/FeedComponentModel.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/FeedComponentModel.kt
index 9c7a9c96b1..e61e95a217 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/FeedComponentModel.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/FeedComponentModel.kt
@@ -5,7 +5,6 @@ import arrow.core.getOrElse
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
-import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.utils.DateTimeFormatters
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
@@ -31,7 +30,6 @@ import kotlinx.coroutines.launch
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import javax.inject.Inject
-import kotlin.collections.all
@Stable
@ModelScoped
@@ -66,13 +64,6 @@ internal class FeedComponentModel @Inject constructor(
internal val state: StateFlow
field = MutableStateFlow(initialState())
- private val searchBarStateFactory by lazy(LazyThreadSafetyMode.NONE) {
- SearchBarStateFactory(
- currentStateProvider = Provider { state.value },
- onStateUpdate = { newState -> state.update { newState } },
- )
- }
-
private val trendingNewsStateFactory by lazy(LazyThreadSafetyMode.NONE) {
TrendingNewsStateFactory(
currentStateProvider = Provider { state.value },
@@ -137,14 +128,9 @@ internal class FeedComponentModel @Inject constructor(
private fun initialState(): FeedListUM {
return FeedListUM(
currentDate = getCurrentDate(),
- searchBar = SearchBarUM(
+ feedListSearchBar = FeedListSearchBar(
placeholderText = resourceReference(R.string.markets_search_header_title),
- query = "",
- onQueryChange = {},
- isActive = false,
- onActiveChange = {
- if (it) params.feedClickIntents.onMarketOpenClick(SortByTypeUM.Rating)
- },
+ onBarClick = { params.feedClickIntents.onMarketOpenClick(null) },
),
feedListCallbacks = FeedListCallbacks(
onSearchClick = {},
@@ -307,7 +293,6 @@ internal class FeedComponentModel @Inject constructor(
private fun updateCallbacks() {
state.update { feedListUM ->
feedListUM.copy(
- searchBar = state.value.searchBar.copy(onQueryChange = searchBarStateFactory::onSearchQueryChange),
feedListCallbacks = feedListUM.feedListCallbacks.copy(
onSortTypeClick = ::onSortTypeClick,
onMarketItemClick = { item ->
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/FeedModelClickIntents.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/FeedModelClickIntents.kt
index 4b4c342fe0..97621a1ef9 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/FeedModelClickIntents.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/FeedModelClickIntents.kt
@@ -9,7 +9,7 @@ import com.tangem.features.feed.ui.market.list.state.SortByTypeUM
*/
internal interface FeedModelClickIntents {
fun onMarketItemClick(token: TokenMarketParams, appCurrency: AppCurrency)
- fun onMarketOpenClick(sortBy: SortByTypeUM)
+ fun onMarketOpenClick(sortBy: SortByTypeUM?)
fun onArticleClick(articleId: Int)
fun onOpenAllNews()
}
\ 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 ca976fa47b..f7ae1d61d4 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
@@ -73,6 +73,7 @@ internal class MarketsListModel @Inject constructor(
onShowTokensUnder100kClicked = { analyticsEventHandler.send(MarketsListAnalyticsEvent.ShowTokens()) },
shouldAlwaysShowSearchBar = Provider { params.shouldAlwaysShowSearchBar },
preselectedSortType = Provider { params.preselectedSortType },
+ onBackClick = params.onBackClicked,
)
}
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/list/statemanager/MarketsListUMStateManager.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/list/statemanager/MarketsListUMStateManager.kt
index 5ecb6df31a..2e269facb3 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/list/statemanager/MarketsListUMStateManager.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/list/statemanager/MarketsListUMStateManager.kt
@@ -29,6 +29,7 @@ internal class MarketsListUMStateManager(
private val onRetryButtonClicked: () -> Unit,
private val onTokenClick: (MarketsListItemUM) -> Unit,
private val onShowTokensUnder100kClicked: () -> Unit,
+ private val onBackClick: () -> Unit,
) {
val state = MutableStateFlow(state())
@@ -38,19 +39,17 @@ internal class MarketsListUMStateManager(
set(value) = state.update { it.copy(sortByBottomSheet = it.sortByBottomSheet.copy(isShown = value)) }
var searchQuery
- get() = state.value.searchBar.query
+ get() = state.value.marketsSearchBar.searchBarUM.query
private set(value) = state.update { marketsListUM ->
marketsListUM.copy(
- searchBar = marketsListUM.searchBar.copy(
- query = value,
- isActive = value.isNotEmpty(),
+ marketsSearchBar = marketsListUM.marketsSearchBar.copy(
+ searchBarUM = marketsListUM.marketsSearchBar.searchBarUM.copy(query = value),
),
)
}
- var isInSearchState
- get() = state.value.searchBar.isActive
- private set(value) = state.update { it.copy(searchBar = it.searchBar.copy(isActive = value)) }
+ val isInSearchState
+ get() = state.value.marketsSearchBar.searchBarUM.isActive
var selectedSortByType
get() = state.value.selectedSortBy
@@ -91,7 +90,7 @@ internal class MarketsListUMStateManager(
}
val isInSearchStateFlow = state.map { it.isInSearchMode }.distinctUntilChanged()
- val searchQueryFlow = state.map { it.searchBar.query }.distinctUntilChanged()
+ val searchQueryFlow = state.map { it.marketsSearchBar.searchBarUM.query }.distinctUntilChanged()
fun onUiItemsChanged(
isInErrorState: Boolean,
@@ -214,12 +213,20 @@ internal class MarketsListUMStateManager(
private fun state(): MarketsListUM = MarketsListUM(
list = ListUM.Loading,
- searchBar = SearchBarUM(
- placeholderText = resourceReference(R.string.markets_search_header_title),
- query = "",
- onQueryChange = { searchQuery = it },
- isActive = false,
- onActiveChange = { },
+ marketsSearchBar = MarketsSearchBar(
+ searchBarUM = SearchBarUM(
+ placeholderText = resourceReference(R.string.markets_search_header_title),
+ query = "",
+ onQueryChange = { searchQuery = it },
+ isActive = false,
+ onActiveChange = ::changeSearchBarIsActive,
+ onClearClick = {
+ if (shouldAlwaysShowSearchBar()) {
+ onBackClick()
+ }
+ },
+ ),
+ shouldAlwaysShowSearchBar = shouldAlwaysShowSearchBar(),
),
selectedSortBy = preselectedSortType(),
selectedInterval = MarketsListUM.TrendInterval.H24,
@@ -234,7 +241,7 @@ internal class MarketsListUMStateManager(
),
),
marketsNotificationUM = null,
- shouldAlwaysShowSearchBar = shouldAlwaysShowSearchBar(),
+ onSearchClicked = { changeSearchBarIsActive(true) },
)
private fun onBottomSheetOptionClicked(sortByTypeUM: SortByTypeUM) {
@@ -264,4 +271,14 @@ internal class MarketsListUMStateManager(
)
}
}
+
+ private fun changeSearchBarIsActive(isActive: Boolean) {
+ state.update { marketsListUM ->
+ marketsListUM.copy(
+ marketsSearchBar = marketsListUM.marketsSearchBar.copy(
+ searchBarUM = marketsListUM.marketsSearchBar.searchBarUM.copy(isActive = isActive),
+ ),
+ )
+ }
+ }
}
\ No newline at end of file
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/FeedList.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/FeedList.kt
index 49bd19e7af..4cc64dcbba 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/FeedList.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/FeedList.kt
@@ -8,6 +8,7 @@ import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
@@ -33,6 +34,7 @@ import com.tangem.common.ui.markets.MarketsListItemPlaceholder
import com.tangem.common.ui.markets.models.MarketsListItemUM
import com.tangem.common.ui.news.ArticleCard
import com.tangem.common.ui.news.ArticleConfigUM
+import com.tangem.common.ui.news.ShowMoreArticlesCard
import com.tangem.core.ui.R
import com.tangem.core.ui.components.SpacerH
import com.tangem.core.ui.components.SpacerW
@@ -41,9 +43,6 @@ import com.tangem.core.ui.components.block.BlockCard
import com.tangem.core.ui.components.block.TangemBlockCardColors
import com.tangem.core.ui.components.buttons.SecondarySmallButton
import com.tangem.core.ui.components.buttons.SmallButtonConfig
-import com.tangem.core.ui.components.fields.SearchBar
-import com.tangem.core.ui.components.fields.TangemSearchBarDefaults
-import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringResourceSafe
@@ -55,25 +54,20 @@ import com.tangem.features.feed.ui.feed.state.*
import com.tangem.features.feed.ui.market.list.state.SortByTypeUM
@Composable
-internal fun FeedListHeader(searchBarUM: SearchBarUM, modifier: Modifier = Modifier) {
+internal fun FeedListHeader(feedListSearchBar: FeedListSearchBar, modifier: Modifier = Modifier) {
val background = LocalMainBottomSheetColor.current.value
- SearchBar(
+ FeedSearchBar(
+ feedListSearchBar = feedListSearchBar,
modifier = modifier
.drawBehind { drawRect(background) }
.padding(horizontal = 16.dp)
.padding(bottom = 12.dp),
- state = searchBarUM,
- colors = TangemSearchBarDefaults.defaultTextFieldColors.copy(
- focusedContainerColor = TangemTheme.colors.field.focused,
- unfocusedContainerColor = TangemTheme.colors.field.focused,
- ),
)
}
@Composable
internal fun FeedList(state: FeedListUM, modifier: Modifier = Modifier) {
val background = LocalMainBottomSheetColor.current.value
-
AnimatedContent(
modifier = modifier,
targetState = state.globalState,
@@ -103,6 +97,33 @@ internal fun FeedList(state: FeedListUM, modifier: Modifier = Modifier) {
}
}
+@Composable
+private fun FeedSearchBar(feedListSearchBar: FeedListSearchBar, modifier: Modifier = Modifier) {
+ Row(
+ modifier = modifier
+ .fillMaxWidth()
+ .clip(RoundedCornerShape(36.dp))
+ .background(color = TangemTheme.colors.field.focused)
+ .clickable(onClick = feedListSearchBar.onBarClick)
+ .padding(14.dp),
+ ) {
+ Icon(
+ modifier = Modifier.size(TangemTheme.dimens.size20),
+ imageVector = ImageVector.vectorResource(id = R.drawable.ic_search_24),
+ tint = TangemTheme.colors.icon.informative,
+ contentDescription = null,
+ )
+
+ SpacerW(14.dp)
+
+ Text(
+ text = feedListSearchBar.placeholderText.resolveReference(),
+ style = TangemTheme.typography.body2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ }
+}
+
@Composable
private fun FeeListContent(state: FeedListUM, modifier: Modifier = Modifier) {
val background = LocalMainBottomSheetColor.current.value
@@ -308,7 +329,7 @@ private fun NewsContentBlock(
append(stringResourceSafe(R.string.feed_tangem_ai))
}
},
- style = TangemTheme.typography.h3,
+ style = TangemTheme.typography.subtitle1,
)
}
},
@@ -345,10 +366,17 @@ private fun NewsContentBlock(
onArticleClick = { feedListCallbacks.onArticleClick(article.id) },
modifier = Modifier
.height(164.dp)
- .widthIn(max = 216.dp),
+ .width(216.dp),
colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action),
)
}
+
+ item {
+ ShowMoreArticlesCard(
+ modifier = Modifier.size(width = 216.dp, height = 164.dp),
+ onClick = feedListCallbacks.onOpenAllNews,
+ )
+ }
}
SpacerH(32.dp)
}
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/preview/FeedListPreviewDataProvider.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/preview/FeedListPreviewDataProvider.kt
index d0d833fcd1..50b22f6f46 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/preview/FeedListPreviewDataProvider.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/preview/FeedListPreviewDataProvider.kt
@@ -3,7 +3,6 @@ package com.tangem.features.feed.ui.feed.preview
import com.tangem.common.ui.charts.state.MarketChartRawData
import com.tangem.common.ui.markets.models.MarketsListItemUM
import com.tangem.common.ui.news.ArticleConfigUM
-import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.core.ui.components.label.entity.LabelLeadingContentUM
import com.tangem.core.ui.components.label.entity.LabelUM
import com.tangem.core.ui.components.marketprice.PriceChangeType
@@ -22,12 +21,9 @@ internal object FeedListPreviewDataProvider {
val marketItems = createSampleMarketItems()
return FeedListUM(
currentDate = "20 November",
- searchBar = SearchBarUM(
+ feedListSearchBar = FeedListSearchBar(
placeholderText = TextReference.Str("Search tokens & news"),
- query = "",
- onQueryChange = {},
- isActive = false,
- onActiveChange = {},
+ onBarClick = {},
),
feedListCallbacks = FeedListCallbacks(
onSearchClick = {},
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/state/FeedListUM.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/state/FeedListUM.kt
index 269fcb8d30..3c05e90f30 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/state/FeedListUM.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/state/FeedListUM.kt
@@ -3,7 +3,7 @@ package com.tangem.features.feed.ui.feed.state
import androidx.compose.runtime.Immutable
import com.tangem.common.ui.markets.models.MarketsListItemUM
import com.tangem.common.ui.news.ArticleConfigUM
-import com.tangem.core.ui.components.fields.entity.SearchBarUM
+import com.tangem.core.ui.extensions.TextReference
import com.tangem.features.feed.ui.market.list.state.SortByTypeUM
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableMap
@@ -11,7 +11,7 @@ import kotlinx.collections.immutable.toPersistentList
internal data class FeedListUM(
val currentDate: String,
- val searchBar: SearchBarUM,
+ val feedListSearchBar: FeedListSearchBar,
val feedListCallbacks: FeedListCallbacks,
val news: NewsUM,
val trendingArticle: ArticleConfigUM?,
@@ -28,6 +28,11 @@ internal data class FeedListCallbacks(
val onSortTypeClick: (SortByTypeUM) -> Unit,
)
+internal data class FeedListSearchBar(
+ val onBarClick: () -> Unit,
+ val placeholderText: TextReference,
+)
+
@Immutable
internal sealed interface NewsUM {
data object Loading : NewsUM
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/state/SearchBarStateFactory.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/state/SearchBarStateFactory.kt
deleted file mode 100644
index bd33df97cc..0000000000
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/state/SearchBarStateFactory.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.tangem.features.feed.ui.feed.state
-
-import com.tangem.utils.Provider
-
-internal class SearchBarStateFactory(
- private val currentStateProvider: Provider,
- private val onStateUpdate: (FeedListUM) -> Unit,
-) {
-
- val searchQuery: String
- get() = currentStateProvider().searchBar.query
-
- fun onSearchQueryChange(query: String) {
- val currentState = currentStateProvider()
- onStateUpdate(
- currentState.copy(
- searchBar = currentState.searchBar.copy(
- query = query,
- isActive = query.isNotEmpty(),
- ),
- ),
- )
- }
-}
\ No newline at end of file
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/MarketsList.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/MarketsList.kt
index 1c86bc2b22..b4024d9bce 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/MarketsList.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/MarketsList.kt
@@ -2,6 +2,7 @@ package com.tangem.features.feed.ui.market.list
import android.content.res.Configuration
import androidx.activity.compose.BackHandler
+import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
@@ -10,6 +11,7 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
@@ -19,6 +21,7 @@ import com.tangem.common.ui.markets.preview.MarketChartListItemPreviewDataProvid
import com.tangem.core.ui.components.Keyboard
import com.tangem.core.ui.components.SpacerH12
import com.tangem.core.ui.components.SpacerH8
+import com.tangem.core.ui.components.appbar.AppBarWithBackButtonAndIcon
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.buttons.SecondarySmallButton
import com.tangem.core.ui.components.buttons.SmallButtonConfig
@@ -41,23 +44,47 @@ import com.tangem.features.feed.ui.market.list.components.YieldSupplyInMarketsPr
import com.tangem.features.feed.ui.market.list.state.*
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
+import kotlinx.coroutines.delay
private const val SHOW_MORE_KEY = "privacyPolicy"
@Composable
-internal fun TopBarWithSearch(searchBarUM: SearchBarUM) {
+internal fun TopBarWithSearch(onBackClick: () -> Unit, onSearchClick: () -> Unit, marketsSearchBar: MarketsSearchBar) {
val background = LocalMainBottomSheetColor.current.value
- SearchBar(
- modifier = Modifier
- .drawBehind { drawRect(background) }
- .padding(horizontal = 16.dp)
- .padding(bottom = 12.dp),
- state = searchBarUM,
- colors = TangemSearchBarDefaults.defaultTextFieldColors.copy(
- focusedContainerColor = TangemTheme.colors.field.focused,
- unfocusedContainerColor = TangemTheme.colors.field.focused,
- ),
- )
+ val focusRequester: FocusRequester = remember { FocusRequester() }
+
+ AnimatedContent(
+ targetState = !marketsSearchBar.shouldAlwaysShowSearchBar && !marketsSearchBar.searchBarUM.isActive,
+ ) { showAppBarWithBackIcon ->
+ if (showAppBarWithBackIcon) {
+ AppBarWithBackButtonAndIcon(
+ onBackClick = onBackClick,
+ text = stringResourceSafe(R.string.markets_common_title),
+ iconRes = R.drawable.ic_search_24,
+ onIconClick = onSearchClick,
+ backgroundColor = background,
+ )
+ } else {
+ SearchBar(
+ modifier = Modifier
+ .drawBehind { drawRect(background) }
+ .padding(horizontal = 16.dp)
+ .padding(bottom = 12.dp),
+ state = marketsSearchBar.searchBarUM,
+ colors = TangemSearchBarDefaults.defaultTextFieldColors.copy(
+ focusedContainerColor = TangemTheme.colors.field.focused,
+ unfocusedContainerColor = TangemTheme.colors.field.focused,
+ ),
+ focusRequester = focusRequester,
+ )
+ LaunchedEffect(marketsSearchBar.shouldAlwaysShowSearchBar) {
+ if (marketsSearchBar.shouldAlwaysShowSearchBar) {
+ delay(timeMillis = 200)
+ focusRequester.requestFocus()
+ }
+ }
+ }
+ }
}
@Composable
@@ -83,16 +110,22 @@ private fun ColumnScope.Content(state: MarketsListUM, modifier: Modifier = Modif
Column(modifier.padding(horizontal = TangemTheme.dimens.size16)) {
AnimatedVisibility(
- visible = scrolledState.value.not(),
+ visible = scrolledState.value.not() &&
+ state.isInSearchMode &&
+ state.marketsSearchBar.searchBarUM.query.isNotEmpty(),
) {
Column {
SpacerH8()
- Title(isInSearchMode = state.isInSearchMode)
+ Text(
+ text = stringResourceSafe(id = R.string.markets_search_result_title),
+ style = TangemTheme.typography.h3,
+ color = TangemTheme.colors.text.primary1,
+ )
SpacerH12()
}
}
Column {
- AnimatedVisibility(state.isInSearchMode.not()) {
+ AnimatedVisibility(!state.isInSearchMode && !state.marketsSearchBar.shouldAlwaysShowSearchBar) {
Options(
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
sortByTypeUM = state.selectedSortBy,
@@ -161,20 +194,6 @@ private fun ColumnScope.Content(state: MarketsListUM, modifier: Modifier = Modif
)
}
-@Composable
-private fun Title(isInSearchMode: Boolean, modifier: Modifier = Modifier) {
- Text(
- modifier = modifier,
- text = if (isInSearchMode) {
- stringResourceSafe(id = R.string.markets_search_result_title)
- } else {
- stringResourceSafe(id = R.string.markets_common_title)
- },
- style = TangemTheme.typography.h3,
- color = TangemTheme.colors.text.primary1,
- )
-}
-
@Composable
private fun Options(
sortByTypeUM: SortByTypeUM,
@@ -320,12 +339,15 @@ private fun Preview() {
triggerScrollReset = consumedEvent(),
onItemClick = {},
),
- searchBar = SearchBarUM(
- placeholderText = resourceReference(R.string.markets_search_header_title),
- query = "",
- onQueryChange = {},
- isActive = false,
- onActiveChange = { },
+ marketsSearchBar = MarketsSearchBar(
+ searchBarUM = SearchBarUM(
+ placeholderText = resourceReference(R.string.markets_search_header_title),
+ query = "",
+ onQueryChange = {},
+ isActive = false,
+ onActiveChange = { },
+ ),
+ shouldAlwaysShowSearchBar = true,
),
selectedSortBy = SortByTypeUM.Rating,
selectedInterval = MarketsListUM.TrendInterval.H24,
@@ -340,7 +362,7 @@ private fun Preview() {
onClick = {},
onCloseClick = {},
),
- shouldAlwaysShowSearchBar = true,
+ onSearchClicked = {},
),
)
}
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/state/MarketsListUM.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/state/MarketsListUM.kt
index 17fc25d214..9ae4f28516 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/state/MarketsListUM.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/state/MarketsListUM.kt
@@ -13,17 +13,18 @@ import kotlinx.collections.immutable.ImmutableList
internal data class MarketsListUM(
val list: ListUM,
- val searchBar: SearchBarUM,
+ val marketsSearchBar: MarketsSearchBar,
val selectedSortBy: SortByTypeUM,
val sortByBottomSheet: TangemBottomSheetConfig,
val selectedInterval: TrendInterval,
- val shouldAlwaysShowSearchBar: Boolean,
val onIntervalClick: (TrendInterval) -> Unit,
val onSortByButtonClick: () -> Unit,
val marketsNotificationUM: MarketsNotificationUM?,
+ val onSearchClicked: () -> Unit,
) {
val isInSearchMode
- get() = searchBar.isActive
+ get() = marketsSearchBar.searchBarUM.isActive &&
+ marketsSearchBar.searchBarUM.query.isNotEmpty()
enum class TrendInterval(val text: TextReference) {
H24(resourceReference(R.string.markets_selector_interval_24h_title)),
@@ -32,7 +33,12 @@ internal data class MarketsListUM(
}
}
-enum class SortByTypeUM(val text: TextReference) {
+internal data class MarketsSearchBar(
+ val searchBarUM: SearchBarUM,
+ val shouldAlwaysShowSearchBar: Boolean,
+)
+
+internal enum class SortByTypeUM(val text: TextReference) {
Rating(resourceReference(R.string.markets_sort_by_rating_title)),
Trending(resourceReference(R.string.markets_sort_by_trending_title)),
ExperiencedBuyers(resourceReference(R.string.markets_sort_by_experienced_buyers_title)),
@@ -43,7 +49,7 @@ enum class SortByTypeUM(val text: TextReference) {
}
@Immutable
-sealed class ListUM {
+internal sealed class ListUM {
data class Content(
val items: ImmutableList,
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/state/SortByBottomSheetContentUM.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/state/SortByBottomSheetContentUM.kt
index 75e79d5844..947ee23844 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/state/SortByBottomSheetContentUM.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/state/SortByBottomSheetContentUM.kt
@@ -2,7 +2,7 @@ package com.tangem.features.feed.ui.market.list.state
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
-data class SortByBottomSheetContentUM(
+internal data class SortByBottomSheetContentUM(
val selectedOption: SortByTypeUM,
val onOptionClicked: (SortByTypeUM) -> Unit,
) : TangemBottomSheetConfigContent
\ No newline at end of file