From 4e6d9aab705ec50831a21081ec8e3439079fb53d Mon Sep 17 00:00:00 2001 From: HuanCheng65 <22636177+HuanCheng65@users.noreply.github.com> Date: Sat, 23 Sep 2023 15:55:46 +0800 Subject: [PATCH] =?UTF-8?q?pref:=20=E4=BA=A4=E6=8D=A2=E6=B8=85=E9=99=A4?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E5=92=8C=E5=B1=95=E5=BC=80=E6=9B=B4=E5=A4=9A?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../post/ui/common/theme/compose/Type.kt | 21 ++-- .../tieba/post/ui/page/search/SearchPage.kt | 102 +++++++++++------- .../post/ui/page/search/SearchViewModel.kt | 14 ++- app/src/main/res/values/strings.xml | 3 + 4 files changed, 87 insertions(+), 53 deletions(-) diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/common/theme/compose/Type.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/common/theme/compose/Type.kt index b7563501..ece0c7e0 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/common/theme/compose/Type.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/common/theme/compose/Type.kt @@ -6,28 +6,23 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp +internal val DefaultTextStyle = TextStyle.Default.copy() + // Set of Material typography styles to start with val Typography = Typography( - body1 = TextStyle( + body1 = DefaultTextStyle.copy( fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, fontSize = 16.sp ), - subtitle1 = TextStyle( + subtitle1 = DefaultTextStyle.copy( fontWeight = FontWeight.Bold, fontSize = 16.sp, letterSpacing = 0.15.sp ), - /* Other default text styles to override - button = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.W500, - fontSize = 14.sp - ), - caption = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 12.sp + button = DefaultTextStyle.copy( + fontWeight = FontWeight.Medium, + fontSize = 14.sp, + letterSpacing = 0.15.sp ) - */ ) \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/SearchPage.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/SearchPage.kt index b00c1feb..b79bcf4d 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/SearchPage.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/SearchPage.kt @@ -38,8 +38,9 @@ import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.ArrowBack import androidx.compose.material.icons.rounded.ArrowDropDown -import androidx.compose.material.icons.rounded.CleaningServices import androidx.compose.material.icons.rounded.Clear +import androidx.compose.material.icons.rounded.ExpandLess +import androidx.compose.material.icons.rounded.ExpandMore import androidx.compose.material.icons.rounded.Search import androidx.compose.material.ripple.rememberRipple import androidx.compose.runtime.Composable @@ -79,6 +80,7 @@ import com.huanchengfly.tieba.post.models.database.SearchHistory import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme import com.huanchengfly.tieba.post.ui.common.theme.compose.TiebaLiteTheme import com.huanchengfly.tieba.post.ui.page.ProvideNavigator +import com.huanchengfly.tieba.post.ui.page.destinations.SearchPageDestination import com.huanchengfly.tieba.post.ui.page.search.forum.SearchForumPage import com.huanchengfly.tieba.post.ui.page.search.thread.SearchThreadPage import com.huanchengfly.tieba.post.ui.page.search.thread.SearchThreadSortType @@ -88,6 +90,7 @@ import com.huanchengfly.tieba.post.ui.widgets.compose.BaseTextField import com.huanchengfly.tieba.post.ui.widgets.compose.Button import com.huanchengfly.tieba.post.ui.widgets.compose.ClickMenu import com.huanchengfly.tieba.post.ui.widgets.compose.LazyLoadHorizontalPager +import com.huanchengfly.tieba.post.ui.widgets.compose.MyBackHandler import com.huanchengfly.tieba.post.ui.widgets.compose.MyScaffold import com.huanchengfly.tieba.post.ui.widgets.compose.PagerTabIndicator import com.huanchengfly.tieba.post.ui.widgets.compose.TopAppBarContainer @@ -132,10 +135,25 @@ fun SearchPage( prop1 = SearchUiState::keyword, initial = "" ) - val isKeywordEmpty by remember { - derivedStateOf { keyword.isEmpty() } - } + + val isKeywordEmpty by viewModel.uiState.collectPartialAsState( + prop1 = SearchUiState::isKeywordEmpty, + initial = true + ) var inputKeyword by remember { mutableStateOf("") } + LaunchedEffect(keyword) { + if (keyword.isNotEmpty() && keyword != inputKeyword) { + inputKeyword = keyword + } + } + + MyBackHandler( + enabled = !isKeywordEmpty, + currentScreen = SearchPageDestination + ) { + viewModel.send(SearchUiIntent.SubmitKeyword("")) + } + var expanded by remember { mutableStateOf(false) } val initialSortType = remember { SearchThreadSortType.SORT_TYPE_NEWEST } @@ -145,7 +163,7 @@ fun SearchPage( } viewModel.onEvent { inputKeyword = it.keyword - emitGlobalEventSuspend(it) + if (it.keyword.isNotBlank()) emitGlobalEventSuspend(it) } val pages by remember { @@ -213,7 +231,13 @@ fun SearchPage( onKeywordSubmit = { viewModel.send(SearchUiIntent.SubmitKeyword(it)) }, - onBack = { navigator.navigateUp() } + onBack = { + if (isKeywordEmpty) { + navigator.navigateUp() + } else { + viewModel.send(SearchUiIntent.SubmitKeyword("")) + } + } ) } }, @@ -224,27 +248,32 @@ fun SearchPage( } } ) { - if (!isKeywordEmpty) { - ProvideNavigator(navigator = navigator) { - LazyLoadHorizontalPager( - state = pagerState, - key = { pages[it].id } - ) { - pages[it].content() + Box(modifier = Modifier.fillMaxSize()) { + if (!isKeywordEmpty) { + ProvideNavigator(navigator = navigator) { + LazyLoadHorizontalPager( + state = pagerState, + key = { pages[it].id }, + modifier = Modifier.fillMaxSize(), + ) { + pages[it].content() + } + } + } else { + Column( + modifier = Modifier.fillMaxSize() + ) { + SearchHistoryList( + searchHistories = searchHistories, + onSearchHistoryClick = { + inputKeyword = it.content + viewModel.send(SearchUiIntent.SubmitKeyword(it.content)) + }, + expanded = expanded, + onToggleExpand = { expanded = !expanded }, + onClear = { viewModel.send(SearchUiIntent.ClearSearchHistory) } + ) } - } - } else { - Column { - SearchHistoryList( - searchHistories = searchHistories, - onSearchHistoryClick = { - inputKeyword = it.content - viewModel.send(SearchUiIntent.SubmitKeyword(it.content)) - }, - expanded = expanded, - onToggleExpand = { expanded = !expanded }, - onClear = { viewModel.send(SearchUiIntent.ClearSearchHistory) } - ) } } } @@ -390,12 +419,10 @@ private fun SearchHistoryList( .weight(1f), style = MaterialTheme.typography.subtitle1 ) - if (hasMore) { + if (hasItem) { Text( - text = if (!expanded) stringResource(id = R.string.button_expand) else stringResource( - id = R.string.button_collapse - ), - modifier = Modifier.clickable(onClick = onToggleExpand), + text = stringResource(id = R.string.button_clear_all), + modifier = Modifier.clickable(onClick = onClear), style = MaterialTheme.typography.button ) } @@ -421,9 +448,9 @@ private fun SearchHistoryList( } } } - if (hasItem) { + if (hasMore) { Button( - onClick = onClear, + onClick = onToggleExpand, modifier = Modifier.fillMaxWidth(), colors = ButtonDefaults.textButtonColors( backgroundColor = Color.Transparent, @@ -435,18 +462,21 @@ private fun SearchHistoryList( horizontalArrangement = Arrangement.spacedBy(8.dp) ) { Icon( - imageVector = Icons.Rounded.CleaningServices, + imageVector = if (expanded) Icons.Rounded.ExpandLess else Icons.Rounded.ExpandMore, contentDescription = null, modifier = Modifier.size(16.dp) ) Text( - text = stringResource(id = R.string.title_clear_search_history), + text = stringResource( + id = if (expanded) R.string.button_expand_less_history else R.string.button_expand_more_history + ), style = MaterialTheme.typography.button, fontWeight = FontWeight.Bold ) } } - } else { + } + if (!hasItem) { Box( modifier = Modifier .fillMaxWidth() diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/SearchViewModel.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/SearchViewModel.kt index 10ba207a..e7602cdd 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/SearchViewModel.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/SearchViewModel.kt @@ -84,10 +84,14 @@ class SearchViewModel : }.flowOn(Dispatchers.IO) private fun SearchUiIntent.SubmitKeyword.producePartialChange() = - flowOf(SearchPartialChange.SubmitKeyword(keyword)) + flowOf(SearchPartialChange.SubmitKeyword(keyword.trim())) .onEach { runCatching { - SearchHistory(keyword).saveOrUpdate("content = ?", keyword) + val trimKeyword = keyword.trim() + if (trimKeyword.isNotBlank()) SearchHistory(trimKeyword).saveOrUpdate( + "content = ?", + trimKeyword + ) } } } @@ -119,7 +123,7 @@ sealed interface SearchPartialChange : PartialChange { is Failure -> oldState } - object Success : ClearSearchHistory() + data object Success : ClearSearchHistory() data class Failure( val errorMessage: String, @@ -129,13 +133,14 @@ sealed interface SearchPartialChange : PartialChange { data class SubmitKeyword(val keyword: String) : SearchPartialChange { override fun reduce(oldState: SearchUiState): SearchUiState { if (keyword.isEmpty()) { - return oldState.copy(keyword = keyword) + return oldState.copy(isKeywordEmpty = true) } val newSearchHistories = (oldState.searchHistories .filterNot { it.content == keyword } + SearchHistory(content = keyword)) .sortedByDescending { it.timestamp } return oldState.copy( keyword = keyword, + isKeywordEmpty = false, searchHistories = newSearchHistories.toImmutableList() ) } @@ -144,6 +149,7 @@ sealed interface SearchPartialChange : PartialChange { data class SearchUiState( val keyword: String = "", + val isKeywordEmpty: Boolean = true, val searchHistories: ImmutableList = persistentListOf(), ) : UiState diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c7584b25..121f7fb1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -716,4 +716,7 @@ 清除失败 %s 推荐 相关用户 + 展开历史 + 收起历史 + 清除全部