From f8becdb7de778439a3e6dc8f326e8d8e8bf1650a Mon Sep 17 00:00:00 2001 From: AllenTom Date: Sun, 1 Sep 2024 19:39:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=B6=8B=E5=8A=BF=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现了趋势动态功能,包括前端和后端支持。允许用户查看和获取趋势动态。 --- .../aiosman/riderpro/data/MomentService.kt | 4 ++- .../aiosman/riderpro/data/api/RiderProAPI.kt | 1 + .../com/aiosman/riderpro/entity/Moment.kt | 34 ++++++++++++++----- .../ui/index/tabs/search/DiscoverScreen.kt | 18 ++++++++-- .../ui/index/tabs/search/DiscoverViewModel.kt | 18 ++++++++++ 5 files changed, 63 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/aiosman/riderpro/data/MomentService.kt b/app/src/main/java/com/aiosman/riderpro/data/MomentService.kt index eec939c..0a321bc 100644 --- a/app/src/main/java/com/aiosman/riderpro/data/MomentService.kt +++ b/app/src/main/java/com/aiosman/riderpro/data/MomentService.kt @@ -112,13 +112,15 @@ interface MomentService { * @param author 作者ID,过滤条件 * @param timelineId 用户时间线ID,指定用户 ID 的时间线 * @param contentSearch 内容搜索,过滤条件 + * @param trend 是否趋势动态 * @return 动态列表 */ suspend fun getMoments( pageNumber: Int, author: Int? = null, timelineId: Int? = null, - contentSearch: String? = null + contentSearch: String? = null, + trend: Boolean? = false ): ListContainer /** diff --git a/app/src/main/java/com/aiosman/riderpro/data/api/RiderProAPI.kt b/app/src/main/java/com/aiosman/riderpro/data/api/RiderProAPI.kt index 3f6a437..2f2584a 100644 --- a/app/src/main/java/com/aiosman/riderpro/data/api/RiderProAPI.kt +++ b/app/src/main/java/com/aiosman/riderpro/data/api/RiderProAPI.kt @@ -102,6 +102,7 @@ interface RiderProAPI { @Query("authorId") authorId: Int? = null, @Query("contentSearch") contentSearch: String? = null, @Query("postUser") postUser: Int? = null, + @Query("trend") trend: String? = null, ): Response> @Multipart diff --git a/app/src/main/java/com/aiosman/riderpro/entity/Moment.kt b/app/src/main/java/com/aiosman/riderpro/entity/Moment.kt index f5309d6..76f5133 100644 --- a/app/src/main/java/com/aiosman/riderpro/entity/Moment.kt +++ b/app/src/main/java/com/aiosman/riderpro/entity/Moment.kt @@ -24,7 +24,8 @@ class MomentPagingSource( private val remoteDataSource: MomentRemoteDataSource, private val author: Int? = null, private val timelineId: Int? = null, - private val contentSearch: String? = null + private val contentSearch: String? = null, + private val trend: Boolean? = false ) : PagingSource() { override suspend fun load(params: LoadParams): LoadResult { return try { @@ -33,7 +34,8 @@ class MomentPagingSource( pageNumber = currentPage, author = author, timelineId = timelineId, - contentSearch = contentSearch + contentSearch = contentSearch, + trend = trend ) LoadResult.Page( @@ -59,9 +61,16 @@ class MomentRemoteDataSource( pageNumber: Int, author: Int?, timelineId: Int?, - contentSearch: String? + contentSearch: String?, + trend: Boolean? ): ListContainer { - return momentService.getMoments(pageNumber, author, timelineId, contentSearch) + return momentService.getMoments( + pageNumber = pageNumber, + author = author, + timelineId = timelineId, + contentSearch = contentSearch, + trend = trend + ) } } @@ -72,9 +81,16 @@ class MomentServiceImpl() : MomentService { pageNumber: Int, author: Int?, timelineId: Int?, - contentSearch: String? + contentSearch: String?, + trend: Boolean? ): ListContainer { - return momentBackend.fetchMomentItems(pageNumber, author, timelineId, contentSearch) + return momentBackend.fetchMomentItems( + pageNumber = pageNumber, + author = author, + timelineId = timelineId, + contentSearch = contentSearch, + trend = trend + ) } override suspend fun getMomentById(id: Int): MomentEntity { @@ -115,14 +131,16 @@ class MomentBackend { pageNumber: Int, author: Int? = null, timelineId: Int?, - contentSearch: String? + contentSearch: String?, + trend: Boolean? ): ListContainer { val resp = ApiClient.api.getPosts( pageSize = DataBatchSize, page = pageNumber, timelineId = timelineId, authorId = author, - contentSearch = contentSearch + contentSearch = contentSearch, + trend = if (trend == true) "true" else "" ) val body = resp.body() ?: throw ServiceException("Failed to get moments") return ListContainer( diff --git a/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/search/DiscoverScreen.kt b/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/search/DiscoverScreen.kt index 8571f65..0f0fcff 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/search/DiscoverScreen.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/search/DiscoverScreen.kt @@ -24,13 +24,21 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Icon import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Search +import androidx.compose.material.pullrefresh.PullRefreshIndicator +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.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -52,7 +60,7 @@ import com.aiosman.riderpro.ui.post.PostViewModel import com.google.accompanist.systemuicontroller.rememberSystemUiController -@OptIn(ExperimentalFoundationApi::class) +@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class) @Preview @Composable fun DiscoverScreen() { @@ -66,11 +74,16 @@ fun DiscoverScreen() { LaunchedEffect(Unit) { systemUiController.setStatusBarColor(Color.Transparent, darkIcons = true) } + var refreshing by remember { mutableStateOf(false) } + val state = rememberPullRefreshState(refreshing, onRefresh = { + model.refreshPager() + }) Column( modifier = Modifier .background(Color.White) .fillMaxSize() + .pullRefresh(state) .padding(bottom = navigationBarPaddings) ) { Spacer(modifier = Modifier.height(statusBarPaddingValues.calculateTopPadding())) @@ -89,9 +102,8 @@ fun DiscoverScreen() { .weight(1f) ) { DiscoverView() + PullRefreshIndicator(refreshing, state, Modifier.align(Alignment.TopCenter)) } - - } } diff --git a/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/search/DiscoverViewModel.kt b/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/search/DiscoverViewModel.kt index 017ada9..4a1dc2a 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/search/DiscoverViewModel.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/search/DiscoverViewModel.kt @@ -11,6 +11,7 @@ import com.aiosman.riderpro.entity.MomentEntity import com.aiosman.riderpro.entity.MomentPagingSource import com.aiosman.riderpro.entity.MomentRemoteDataSource import com.aiosman.riderpro.entity.MomentServiceImpl +import com.aiosman.riderpro.ui.index.tabs.moment.MomentViewModel.accountService import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.collectLatest @@ -28,6 +29,23 @@ object DiscoverViewModel:ViewModel() { pagingSourceFactory = { MomentPagingSource( MomentRemoteDataSource(momentService), + trend = true + ) + } + ).flow.cachedIn(viewModelScope).collectLatest { + _discoverMomentsFlow.value = it + } + } + } + fun refreshPager() { + viewModelScope.launch { + val profile = accountService.getMyAccountProfile() + Pager( + config = PagingConfig(pageSize = 5, enablePlaceholders = false), + pagingSourceFactory = { + MomentPagingSource( + MomentRemoteDataSource(momentService), + trend = true ) } ).flow.cachedIn(viewModelScope).collectLatest {