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 6534cf28..b00c1feb 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 @@ -72,6 +72,8 @@ import androidx.compose.ui.util.fastForEachIndexed import com.huanchengfly.tieba.post.R import com.huanchengfly.tieba.post.arch.collectPartialAsState import com.huanchengfly.tieba.post.arch.emitGlobalEvent +import com.huanchengfly.tieba.post.arch.emitGlobalEventSuspend +import com.huanchengfly.tieba.post.arch.onEvent import com.huanchengfly.tieba.post.arch.pageViewModel import com.huanchengfly.tieba.post.models.database.SearchHistory import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme @@ -134,12 +136,17 @@ fun SearchPage( derivedStateOf { keyword.isEmpty() } } var inputKeyword by remember { mutableStateOf("") } + var expanded by remember { mutableStateOf(false) } val initialSortType = remember { SearchThreadSortType.SORT_TYPE_NEWEST } var searchThreadSortType by remember { mutableIntStateOf(initialSortType) } LaunchedEffect(searchThreadSortType) { emitGlobalEvent(SearchThreadUiEvent.SwitchSortType(searchThreadSortType)) } + viewModel.onEvent { + inputKeyword = it.keyword + emitGlobalEventSuspend(it) + } val pages by remember { derivedStateOf { @@ -234,6 +241,8 @@ fun SearchPage( inputKeyword = it.content viewModel.send(SearchUiIntent.SubmitKeyword(it.content)) }, + expanded = expanded, + onToggleExpand = { expanded = !expanded }, onClear = { viewModel.send(SearchUiIntent.ClearSearchHistory) } ) } 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 5099ee10..10ba207a 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 @@ -47,6 +47,8 @@ class SearchViewModel : App.INSTANCE.getString(R.string.toast_clear_failure, partialChange.errorMessage) ) + is SearchPartialChange.SubmitKeyword -> SearchUiEvent.KeywordChanged(partialChange.keyword) + else -> null } @@ -145,4 +147,6 @@ data class SearchUiState( val searchHistories: ImmutableList = persistentListOf(), ) : UiState -sealed interface SearchUiEvent : UiEvent \ No newline at end of file +sealed interface SearchUiEvent : UiEvent { + data class KeywordChanged(val keyword: String) : SearchUiEvent +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/forum/SearchForumPage.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/forum/SearchForumPage.kt index c827cc22..215e3e71 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/forum/SearchForumPage.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/forum/SearchForumPage.kt @@ -30,16 +30,20 @@ import androidx.compose.ui.unit.dp import com.huanchengfly.tieba.post.R import com.huanchengfly.tieba.post.api.models.SearchForumBean import com.huanchengfly.tieba.post.arch.collectPartialAsState +import com.huanchengfly.tieba.post.arch.onGlobalEvent import com.huanchengfly.tieba.post.arch.pageViewModel import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme import com.huanchengfly.tieba.post.ui.common.theme.compose.pullRefreshIndicator import com.huanchengfly.tieba.post.ui.page.LocalNavigator import com.huanchengfly.tieba.post.ui.page.destinations.ForumPageDestination +import com.huanchengfly.tieba.post.ui.page.search.SearchUiEvent import com.huanchengfly.tieba.post.ui.widgets.Chip import com.huanchengfly.tieba.post.ui.widgets.compose.Avatar +import com.huanchengfly.tieba.post.ui.widgets.compose.ErrorScreen import com.huanchengfly.tieba.post.ui.widgets.compose.LazyLoad import com.huanchengfly.tieba.post.ui.widgets.compose.LocalShouldLoad import com.huanchengfly.tieba.post.ui.widgets.compose.Sizes +import com.huanchengfly.tieba.post.ui.widgets.compose.states.StateScreen import kotlinx.collections.immutable.persistentListOf @OptIn(ExperimentalMaterialApi::class, ExperimentalFoundationApi::class) @@ -53,20 +57,17 @@ fun SearchForumPage( viewModel.send(SearchForumUiIntent.Refresh(keyword)) viewModel.initialized = true } - - val shouldLoad = LocalShouldLoad.current - LaunchedEffect(keyword) { - if (viewModel.initialized) { - if (shouldLoad) { - viewModel.send(SearchForumUiIntent.Refresh(keyword)) - } else { - viewModel.initialized = false - } - } - } + val currentKeyword by viewModel.uiState.collectPartialAsState( + prop1 = SearchForumUiState::keyword, + initial = "" + ) val isRefreshing by viewModel.uiState.collectPartialAsState( prop1 = SearchForumUiState::isRefreshing, - initial = false + initial = true + ) + val error by viewModel.uiState.collectPartialAsState( + prop1 = SearchForumUiState::error, + initial = null ) val exactMatchForum by viewModel.uiState.collectPartialAsState( prop1 = SearchForumUiState::exactMatchForum, @@ -89,68 +90,100 @@ fun SearchForumPage( onRefresh = { viewModel.send(SearchForumUiIntent.Refresh(keyword)) } ) - Box( - modifier = Modifier - .fillMaxSize() - .pullRefresh(pullRefreshState) - ) { - LazyColumn(modifier = Modifier.fillMaxSize()) { - if (showExactMatchResult) { - stickyHeader(key = "ExactMatchHeader") { - Column( - modifier = Modifier - .fillMaxWidth() - .background(ExtendedTheme.colors.background) - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - Chip( - text = stringResource(id = R.string.title_exact_match), - invertColor = true - ) - } - } - item(key = "ExactMatch") { - SearchForumItem( - item = exactMatchForum!!, - onClick = { - navigator.navigate(ForumPageDestination(exactMatchForum!!.forumName.orEmpty())) - } - ) - } - } - if (showFuzzyMatchResult) { - stickyHeader(key = "FuzzyMatchHeader") { - Column( - modifier = Modifier - .fillMaxWidth() - .background(ExtendedTheme.colors.background) - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - Chip( - text = stringResource(id = R.string.title_fuzzy_match), - invertColor = false - ) - } - } - items(fuzzyMatchForumList) { - SearchForumItem( - item = it, - onClick = { - navigator.navigate(ForumPageDestination(it.forumName.orEmpty())) - } - ) - } + val isEmpty by remember { + derivedStateOf { !showExactMatchResult && !showFuzzyMatchResult } + } + + onGlobalEvent { + viewModel.send(SearchForumUiIntent.Refresh(it.keyword)) + } + val shouldLoad = LocalShouldLoad.current + LaunchedEffect(currentKeyword) { + if (currentKeyword.isNotEmpty() && keyword != currentKeyword) { + if (shouldLoad) { + viewModel.send(SearchForumUiIntent.Refresh(keyword)) + } else { + viewModel.initialized = false } } - - PullRefreshIndicator( - refreshing = isRefreshing, - state = pullRefreshState, - modifier = Modifier.align(Alignment.TopCenter), - backgroundColor = ExtendedTheme.colors.pullRefreshIndicator, - contentColor = ExtendedTheme.colors.primary, - ) } + + StateScreen( + isEmpty = isEmpty, + isError = error != null, + isLoading = isRefreshing, + onReload = { viewModel.send(SearchForumUiIntent.Refresh(keyword)) }, + errorScreen = { + error?.let { + val (e) = it + ErrorScreen(error = e) + } + } + ) { + Box( + modifier = Modifier + .fillMaxSize() + .pullRefresh(pullRefreshState) + ) { + LazyColumn(modifier = Modifier.fillMaxSize()) { + if (showExactMatchResult) { + stickyHeader(key = "ExactMatchHeader") { + Column( + modifier = Modifier + .fillMaxWidth() + .background(ExtendedTheme.colors.background) + .padding(horizontal = 16.dp, vertical = 8.dp) + ) { + Chip( + text = stringResource(id = R.string.title_exact_match), + invertColor = true + ) + } + } + item(key = "ExactMatch") { + SearchForumItem( + item = exactMatchForum!!, + onClick = { + navigator.navigate(ForumPageDestination(exactMatchForum!!.forumName.orEmpty())) + } + ) + } + } + if (showFuzzyMatchResult) { + stickyHeader(key = "FuzzyMatchHeader") { + Column( + modifier = Modifier + .fillMaxWidth() + .background(ExtendedTheme.colors.background) + .padding(horizontal = 16.dp, vertical = 8.dp) + ) { + Chip( + text = stringResource(id = R.string.title_fuzzy_match), + invertColor = false + ) + } + } + items(fuzzyMatchForumList) { + SearchForumItem( + item = it, + onClick = { + navigator.navigate(ForumPageDestination(it.forumName.orEmpty())) + } + ) + } + } + } + + PullRefreshIndicator( + refreshing = isRefreshing, + state = pullRefreshState, + modifier = Modifier.align(Alignment.TopCenter), + backgroundColor = ExtendedTheme.colors.pullRefreshIndicator, + contentColor = ExtendedTheme.colors.primary, + ) + } + } + } @Composable diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/forum/SearchForumViewModel.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/forum/SearchForumViewModel.kt index f4cf4295..9b0b6515 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/forum/SearchForumViewModel.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/forum/SearchForumViewModel.kt @@ -93,7 +93,7 @@ data class SearchForumUiState( val keyword: String = "", val exactMatchForum: SearchForumBean.ForumInfoBean? = null, val fuzzyMatchForumList: List = persistentListOf(), - val isRefreshing: Boolean = false, + val isRefreshing: Boolean = true, val error: ImmutableHolder? = null, ) : UiState diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/thread/SearchThreadPage.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/thread/SearchThreadPage.kt index ea877736..3a03a775 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/thread/SearchThreadPage.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/thread/SearchThreadPage.kt @@ -16,7 +16,9 @@ import androidx.compose.material.pullrefresh.pullRefresh import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -30,8 +32,10 @@ import com.huanchengfly.tieba.post.ui.common.theme.compose.pullRefreshIndicator import com.huanchengfly.tieba.post.ui.page.LocalNavigator import com.huanchengfly.tieba.post.ui.page.destinations.ForumPageDestination import com.huanchengfly.tieba.post.ui.page.destinations.ThreadPageDestination +import com.huanchengfly.tieba.post.ui.page.search.SearchUiEvent import com.huanchengfly.tieba.post.ui.widgets.compose.Avatar import com.huanchengfly.tieba.post.ui.widgets.compose.Card +import com.huanchengfly.tieba.post.ui.widgets.compose.ErrorScreen import com.huanchengfly.tieba.post.ui.widgets.compose.ForumInfoChip import com.huanchengfly.tieba.post.ui.widgets.compose.LazyLoad import com.huanchengfly.tieba.post.ui.widgets.compose.LoadMoreLayout @@ -42,6 +46,7 @@ import com.huanchengfly.tieba.post.ui.widgets.compose.ThreadContent import com.huanchengfly.tieba.post.ui.widgets.compose.ThreadReplyBtn import com.huanchengfly.tieba.post.ui.widgets.compose.ThreadShareBtn import com.huanchengfly.tieba.post.ui.widgets.compose.UserHeader +import com.huanchengfly.tieba.post.ui.widgets.compose.states.StateScreen import com.huanchengfly.tieba.post.utils.DateTimeUtils import com.huanchengfly.tieba.post.utils.StringUtil import kotlinx.collections.immutable.ImmutableList @@ -60,9 +65,13 @@ fun SearchThreadPage( viewModel.send(SearchThreadUiIntent.Refresh(keyword, initialSortType)) viewModel.initialized = true } + val currentKeyword by viewModel.uiState.collectPartialAsState( + prop1 = SearchThreadUiState::keyword, + initial = "" + ) val isRefreshing by viewModel.uiState.collectPartialAsState( prop1 = SearchThreadUiState::isRefreshing, - initial = false + initial = true ) val isLoadingMore by viewModel.uiState.collectPartialAsState( prop1 = SearchThreadUiState::isLoadingMore, @@ -88,9 +97,13 @@ fun SearchThreadPage( prop1 = SearchThreadUiState::sortType, initial = initialSortType ) + + onGlobalEvent { + viewModel.send(SearchThreadUiIntent.Refresh(keyword, it.sortType)) + } val shouldLoad = LocalShouldLoad.current - LaunchedEffect(keyword) { - if (viewModel.initialized) { + LaunchedEffect(currentKeyword) { + if (currentKeyword.isNotEmpty() && keyword != currentKeyword) { if (shouldLoad) { viewModel.send(SearchThreadUiIntent.Refresh(keyword, sortType)) } else { @@ -99,60 +112,77 @@ fun SearchThreadPage( } } - onGlobalEvent { - viewModel.send(SearchThreadUiIntent.Refresh(keyword, it.sortType)) - } - val pullRefreshState = rememberPullRefreshState( refreshing = isRefreshing, onRefresh = { viewModel.send(SearchThreadUiIntent.Refresh(keyword, sortType)) } ) val lazyListState = rememberLazyListState() - Box( - modifier = Modifier - .fillMaxSize() - .pullRefresh(pullRefreshState) - ) { - LoadMoreLayout( - isLoading = isLoadingMore, - onLoadMore = { - viewModel.send( - SearchThreadUiIntent.LoadMore(keyword, currentPage, sortType) - ) - }, - loadEnd = !hasMore, - lazyListState = lazyListState, - ) { - SearchThreadList( - data = data, - lazyListState = lazyListState, - onItemClick = { - navigator.navigate( - ThreadPageDestination( - threadId = it.tid.toLong() - ) - ) - }, - onItemUserClick = { - UserActivity.launch(context, it.userId) - }, - onItemForumClick = { - navigator.navigate( - ForumPageDestination( - it.forumName - ) - ) - }, - ) + val isEmpty by remember { + derivedStateOf { data.isEmpty() } + } - PullRefreshIndicator( - refreshing = isRefreshing, - state = pullRefreshState, - modifier = Modifier.align(Alignment.TopCenter), - backgroundColor = ExtendedTheme.colors.pullRefreshIndicator, - contentColor = ExtendedTheme.colors.primary, - ) + onGlobalEvent { + viewModel.send(SearchThreadUiIntent.Refresh(it.keyword, sortType)) + } + + StateScreen( + isEmpty = isEmpty, + isError = error != null, + isLoading = isRefreshing, + onReload = { viewModel.send(SearchThreadUiIntent.Refresh(keyword, sortType)) }, + errorScreen = { + error?.let { + val (e) = it + ErrorScreen(error = e) + } + } + ) { + Box( + modifier = Modifier + .fillMaxSize() + .pullRefresh(pullRefreshState) + ) { + LoadMoreLayout( + isLoading = isLoadingMore, + onLoadMore = { + viewModel.send( + SearchThreadUiIntent.LoadMore(keyword, currentPage, sortType) + ) + }, + loadEnd = !hasMore, + lazyListState = lazyListState, + ) { + SearchThreadList( + data = data, + lazyListState = lazyListState, + onItemClick = { + navigator.navigate( + ThreadPageDestination( + threadId = it.tid.toLong() + ) + ) + }, + onItemUserClick = { + UserActivity.launch(context, it.userId) + }, + onItemForumClick = { + navigator.navigate( + ForumPageDestination( + it.forumName + ) + ) + }, + ) + + PullRefreshIndicator( + refreshing = isRefreshing, + state = pullRefreshState, + modifier = Modifier.align(Alignment.TopCenter), + backgroundColor = ExtendedTheme.colors.pullRefreshIndicator, + contentColor = ExtendedTheme.colors.primary, + ) + } } } } diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/thread/SearchThreadViewModel.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/thread/SearchThreadViewModel.kt index 97e6fffe..9a71b26f 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/thread/SearchThreadViewModel.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/thread/SearchThreadViewModel.kt @@ -136,7 +136,7 @@ sealed interface SearchThreadPartialChange : PartialChange } data class SearchThreadUiState( - val isRefreshing: Boolean = false, + val isRefreshing: Boolean = true, val isLoadingMore: Boolean = false, val error: ImmutableHolder? = null, val currentPage: Int = 1, diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/user/SearchUserPage.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/user/SearchUserPage.kt index a812046b..71b9f86c 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/user/SearchUserPage.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/user/SearchUserPage.kt @@ -31,15 +31,19 @@ import androidx.compose.ui.unit.dp import com.huanchengfly.tieba.post.R import com.huanchengfly.tieba.post.api.models.SearchUserBean import com.huanchengfly.tieba.post.arch.collectPartialAsState +import com.huanchengfly.tieba.post.arch.onGlobalEvent import com.huanchengfly.tieba.post.arch.pageViewModel import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme import com.huanchengfly.tieba.post.ui.common.theme.compose.pullRefreshIndicator import com.huanchengfly.tieba.post.ui.page.LocalNavigator +import com.huanchengfly.tieba.post.ui.page.search.SearchUiEvent import com.huanchengfly.tieba.post.ui.widgets.Chip import com.huanchengfly.tieba.post.ui.widgets.compose.Avatar +import com.huanchengfly.tieba.post.ui.widgets.compose.ErrorScreen import com.huanchengfly.tieba.post.ui.widgets.compose.LazyLoad import com.huanchengfly.tieba.post.ui.widgets.compose.LocalShouldLoad import com.huanchengfly.tieba.post.ui.widgets.compose.Sizes +import com.huanchengfly.tieba.post.ui.widgets.compose.states.StateScreen import com.huanchengfly.tieba.post.utils.StringUtil import kotlinx.collections.immutable.persistentListOf @@ -55,19 +59,17 @@ fun SearchUserPage( viewModel.send(SearchUserUiIntent.Refresh(keyword)) viewModel.initialized = true } - val shouldLoad = LocalShouldLoad.current - LaunchedEffect(keyword) { - if (viewModel.initialized) { - if (shouldLoad) { - viewModel.send(SearchUserUiIntent.Refresh(keyword)) - } else { - viewModel.initialized = false - } - } - } + val currentKeyword by viewModel.uiState.collectPartialAsState( + prop1 = SearchUserUiState::keyword, + initial = "" + ) val isRefreshing by viewModel.uiState.collectPartialAsState( prop1 = SearchUserUiState::isRefreshing, - initial = false + initial = true + ) + val error by viewModel.uiState.collectPartialAsState( + prop1 = SearchUserUiState::error, + initial = null ) val pullRefreshState = rememberPullRefreshState( refreshing = isRefreshing, @@ -89,65 +91,96 @@ fun SearchUserPage( derivedStateOf { fuzzyMatch.isNotEmpty() } } - Box( - modifier = Modifier - .fillMaxSize() - .pullRefresh(pullRefreshState) - ) { - LazyColumn(modifier = Modifier.fillMaxSize()) { - if (showExactMatchResult) { - stickyHeader(key = "ExactMatchHeader") { - Column( - modifier = Modifier - .fillMaxWidth() - .background(ExtendedTheme.colors.background) - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - Chip( - text = stringResource(id = R.string.title_exact_match), - invertColor = true - ) - } - } - item(key = "ExactMatch") { - SearchUserItem( - item = exactMatch!!, - onClick = { - } - ) - } - } - if (showFuzzyMatchResult) { - stickyHeader(key = "FuzzyMatchHeader") { - Column( - modifier = Modifier - .fillMaxWidth() - .background(ExtendedTheme.colors.background) - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - Chip( - text = stringResource(id = R.string.title_fuzzy_match_user), - invertColor = false - ) - } - } - items(fuzzyMatch) { - SearchUserItem( - item = it, - onClick = { - } - ) - } + onGlobalEvent { + viewModel.send(SearchUserUiIntent.Refresh(it.keyword)) + } + val shouldLoad = LocalShouldLoad.current + LaunchedEffect(currentKeyword) { + if (currentKeyword.isNotEmpty() && keyword != currentKeyword) { + if (shouldLoad) { + viewModel.send(SearchUserUiIntent.Refresh(keyword)) + } else { + viewModel.initialized = false } } + } - PullRefreshIndicator( - refreshing = isRefreshing, - state = pullRefreshState, - modifier = Modifier.align(Alignment.TopCenter), - backgroundColor = ExtendedTheme.colors.pullRefreshIndicator, - contentColor = ExtendedTheme.colors.primary, - ) + val isEmpty by remember { + derivedStateOf { !showExactMatchResult && !showFuzzyMatchResult } + } + + StateScreen( + isEmpty = isEmpty, + isError = error != null, + isLoading = isRefreshing, + onReload = { viewModel.send(SearchUserUiIntent.Refresh(keyword)) }, + errorScreen = { + error?.let { + val (e) = it + ErrorScreen(error = e) + } + } + ) { + Box( + modifier = Modifier + .fillMaxSize() + .pullRefresh(pullRefreshState) + ) { + LazyColumn(modifier = Modifier.fillMaxSize()) { + if (showExactMatchResult) { + stickyHeader(key = "ExactMatchHeader") { + Column( + modifier = Modifier + .fillMaxWidth() + .background(ExtendedTheme.colors.background) + .padding(horizontal = 16.dp, vertical = 8.dp) + ) { + Chip( + text = stringResource(id = R.string.title_exact_match), + invertColor = true + ) + } + } + item(key = "ExactMatch") { + SearchUserItem( + item = exactMatch!!, + onClick = { + } + ) + } + } + if (showFuzzyMatchResult) { + stickyHeader(key = "FuzzyMatchHeader") { + Column( + modifier = Modifier + .fillMaxWidth() + .background(ExtendedTheme.colors.background) + .padding(horizontal = 16.dp, vertical = 8.dp) + ) { + Chip( + text = stringResource(id = R.string.title_fuzzy_match_user), + invertColor = false + ) + } + } + items(fuzzyMatch) { + SearchUserItem( + item = it, + onClick = { + } + ) + } + } + } + + PullRefreshIndicator( + refreshing = isRefreshing, + state = pullRefreshState, + modifier = Modifier.align(Alignment.TopCenter), + backgroundColor = ExtendedTheme.colors.pullRefreshIndicator, + contentColor = ExtendedTheme.colors.primary, + ) + } } } diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/user/SearchUserViewModel.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/user/SearchUserViewModel.kt index c86ffbd5..829e54a0 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/user/SearchUserViewModel.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/search/user/SearchUserViewModel.kt @@ -91,7 +91,7 @@ sealed interface SearchUserPartialChange : PartialChange { } data class SearchUserUiState( - val isRefreshing: Boolean = false, + val isRefreshing: Boolean = true, val error: ImmutableHolder? = null, val keyword: String = "", val exactMatch: SearchUserBean.UserBean? = null, diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/LazyLoad.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/LazyLoad.kt index 0b0006f2..eb76b5c9 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/LazyLoad.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/LazyLoad.kt @@ -12,7 +12,9 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.compositionLocalOf +import androidx.compose.runtime.getValue import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.NestedScrollConnection @@ -27,8 +29,11 @@ fun LazyLoad( onLoad: () -> Unit, ) { val shouldLoad = LocalShouldLoad.current - LaunchedEffect(loaded, shouldLoad, onLoad) { - if (!loaded && shouldLoad) onLoad() + val curOnLoad by rememberUpdatedState(newValue = onLoad) + LaunchedEffect(loaded, shouldLoad) { + if (!loaded && shouldLoad) { + curOnLoad() + } } }