feat: 收藏页面状态

This commit is contained in:
HuanCheng65 2023-03-12 15:44:55 +08:00
parent 83a855b2d4
commit e3199c1d8d
No known key found for this signature in database
GPG Key ID: E9031EF91A805148
2 changed files with 88 additions and 55 deletions

View File

@ -20,7 +20,9 @@ import androidx.compose.material.pullrefresh.pullRefresh
import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.material.rememberScaffoldState
import androidx.compose.runtime.Composable
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.graphics.Color
@ -49,6 +51,7 @@ import com.huanchengfly.tieba.post.pxToSp
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
import com.huanchengfly.tieba.post.ui.widgets.compose.Avatar
import com.huanchengfly.tieba.post.ui.widgets.compose.BackNavigationIcon
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.LoadMoreLayout
import com.huanchengfly.tieba.post.ui.widgets.compose.LongClickMenu
@ -56,6 +59,7 @@ import com.huanchengfly.tieba.post.ui.widgets.compose.MyScaffold
import com.huanchengfly.tieba.post.ui.widgets.compose.Sizes
import com.huanchengfly.tieba.post.ui.widgets.compose.TitleCentredToolbar
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.StringUtil
import com.huanchengfly.tieba.post.utils.StringUtil.getUsernameAnnotatedString
import com.huanchengfly.tieba.post.utils.appPreferences
@ -100,12 +104,14 @@ fun ThreadStorePage(
prop1 = ThreadStoreUiState::data,
initial = emptyList()
)
val error by viewModel.uiState.collectPartialAsState(
prop1 = ThreadStoreUiState::error,
initial = null
)
val isError by remember { derivedStateOf { error != null } }
val context = LocalContext.current
val scaffoldState = rememberScaffoldState()
val pullRefreshState = rememberPullRefreshState(
refreshing = isRefreshing,
onRefresh = { viewModel.send(ThreadStoreUiIntent.Refresh) })
viewModel.onEvent<ThreadStoreUiEvent.Delete.Failure> {
scaffoldState.snackbarHostState.showSnackbar(
context.getString(
@ -128,16 +134,36 @@ fun ThreadStorePage(
}
)
}
) { paddingValues ->
) { contentPaddings ->
val textMeasurer = rememberTextMeasurer()
StateScreen(
isEmpty = data.isEmpty(),
isError = isError,
isLoading = isRefreshing,
modifier = Modifier.padding(contentPaddings),
onReload = {
viewModel.send(ThreadStoreUiIntent.Refresh)
},
errorScreen = {
error?.let {
val (e) = it
ErrorScreen(error = e)
}
}
) {
val pullRefreshState = rememberPullRefreshState(
refreshing = isRefreshing,
onRefresh = { viewModel.send(ThreadStoreUiIntent.Refresh) }
)
Box(modifier = Modifier.pullRefresh(pullRefreshState)) {
LoadMoreLayout(
isLoading = isLoadingMore,
onLoadMore = { viewModel.send(ThreadStoreUiIntent.LoadMore(currentPage + 1)) },
loadEnd = !hasMore
) {
LazyColumn(contentPadding = paddingValues) {
LazyColumn {
items(
items = data,
key = { it.threadId }
@ -171,7 +197,8 @@ fun ThreadStorePage(
info.author.lzUid?.let {
UserActivity.launch(
context,
it, StringUtil.getAvatarUrl(info.author.userPortrait)
it,
StringUtil.getAvatarUrl(info.author.userPortrait)
)
}
},
@ -181,6 +208,7 @@ fun ThreadStorePage(
}
}
}
PullRefreshIndicator(
refreshing = isRefreshing,
state = pullRefreshState,
@ -188,6 +216,7 @@ fun ThreadStorePage(
)
}
}
}
}
@OptIn(ExperimentalTextApi::class)

View File

@ -6,11 +6,13 @@ import com.huanchengfly.tieba.post.api.models.ThreadStoreBean
import com.huanchengfly.tieba.post.api.retrofit.exception.getErrorCode
import com.huanchengfly.tieba.post.api.retrofit.exception.getErrorMessage
import com.huanchengfly.tieba.post.arch.BaseViewModel
import com.huanchengfly.tieba.post.arch.ImmutableHolder
import com.huanchengfly.tieba.post.arch.PartialChange
import com.huanchengfly.tieba.post.arch.PartialChangeProducer
import com.huanchengfly.tieba.post.arch.UiEvent
import com.huanchengfly.tieba.post.arch.UiIntent
import com.huanchengfly.tieba.post.arch.UiState
import com.huanchengfly.tieba.post.arch.wrapImmutable
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.Flow
@ -103,13 +105,14 @@ sealed interface ThreadStoreUiIntent : UiIntent {
sealed interface ThreadStorePartialChange : PartialChange<ThreadStoreUiState> {
sealed class Refresh : ThreadStorePartialChange {
override fun reduce(oldState: ThreadStoreUiState): ThreadStoreUiState = when (this) {
is Failure -> oldState.copy(isRefreshing = false)
is Failure -> oldState.copy(isRefreshing = false, error = wrapImmutable(error))
Start -> oldState.copy(isRefreshing = true)
is Success -> oldState.copy(
isRefreshing = false,
data = data,
currentPage = 0,
hasMore = hasMore
hasMore = hasMore,
error = null
)
}
@ -171,7 +174,8 @@ data class ThreadStoreUiState(
val isLoadingMore: Boolean = false,
val hasMore: Boolean = true,
val currentPage: Int = 1,
val data: List<ThreadStoreBean.ThreadStoreInfo> = emptyList()
val data: List<ThreadStoreBean.ThreadStoreInfo> = emptyList(),
val error: ImmutableHolder<Throwable>? = null
) : UiState
sealed interface ThreadStoreUiEvent : UiEvent {