feat: 状态屏

This commit is contained in:
HuanCheng65 2023-01-24 15:51:33 +08:00
parent d07feb9ecb
commit 77dbab6483
No known key found for this signature in database
GPG Key ID: E9031EF91A805148
3 changed files with 103 additions and 32 deletions

View File

@ -47,12 +47,12 @@ import com.google.accompanist.placeholder.material.placeholder
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import com.huanchengfly.tieba.post.R import com.huanchengfly.tieba.post.R
import com.huanchengfly.tieba.post.arch.collectPartialAsState import com.huanchengfly.tieba.post.arch.collectPartialAsState
import com.huanchengfly.tieba.post.arch.onEvent
import com.huanchengfly.tieba.post.arch.pageViewModel import com.huanchengfly.tieba.post.arch.pageViewModel
import com.huanchengfly.tieba.post.models.database.Block import com.huanchengfly.tieba.post.models.database.Block
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
import com.huanchengfly.tieba.post.ui.page.main.BottomNavigationDivider import com.huanchengfly.tieba.post.ui.page.main.BottomNavigationDivider
import com.huanchengfly.tieba.post.ui.widgets.compose.BackNavigationIcon import com.huanchengfly.tieba.post.ui.widgets.compose.BackNavigationIcon
import com.huanchengfly.tieba.post.ui.widgets.compose.EmptyPlaceholder
import com.huanchengfly.tieba.post.ui.widgets.compose.LocalSnackbarHostState import com.huanchengfly.tieba.post.ui.widgets.compose.LocalSnackbarHostState
import com.huanchengfly.tieba.post.ui.widgets.compose.LongClickMenu import com.huanchengfly.tieba.post.ui.widgets.compose.LongClickMenu
import com.huanchengfly.tieba.post.ui.widgets.compose.MyScaffold import com.huanchengfly.tieba.post.ui.widgets.compose.MyScaffold
@ -60,10 +60,10 @@ import com.huanchengfly.tieba.post.ui.widgets.compose.PagerTabIndicator
import com.huanchengfly.tieba.post.ui.widgets.compose.PromptDialog import com.huanchengfly.tieba.post.ui.widgets.compose.PromptDialog
import com.huanchengfly.tieba.post.ui.widgets.compose.TitleCentredToolbar import com.huanchengfly.tieba.post.ui.widgets.compose.TitleCentredToolbar
import com.huanchengfly.tieba.post.ui.widgets.compose.rememberDialogState import com.huanchengfly.tieba.post.ui.widgets.compose.rememberDialogState
import com.huanchengfly.tieba.post.ui.widgets.compose.states.StateScreen
import com.huanchengfly.tieba.post.utils.GsonUtil import com.huanchengfly.tieba.post.utils.GsonUtil
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@OptIn(ExperimentalPagerApi::class) @OptIn(ExperimentalPagerApi::class)
@ -186,10 +186,7 @@ fun BlockSettingsPage(
) { paddingValues -> ) { paddingValues ->
val snackbarHostState = LocalSnackbarHostState.current val snackbarHostState = LocalSnackbarHostState.current
LaunchedEffect(null) { LaunchedEffect(null) {
coroutineScope.launch { onEvent<BlockSettingsUiEvent.Success>(viewModel) {
viewModel.uiEventFlow
.filterIsInstance<BlockSettingsUiEvent.Success>()
.collect {
snackbarHostState.showSnackbar( snackbarHostState.showSnackbar(
when (it) { when (it) {
is BlockSettingsUiEvent.Success.Add -> context.getString(R.string.toast_add_success) is BlockSettingsUiEvent.Success.Add -> context.getString(R.string.toast_add_success)
@ -198,7 +195,6 @@ fun BlockSettingsPage(
) )
} }
} }
}
HorizontalPager( HorizontalPager(
count = 2, count = 2,
state = pagerState, state = pagerState,
@ -206,19 +202,30 @@ fun BlockSettingsPage(
contentPadding = paddingValues, contentPadding = paddingValues,
verticalAlignment = Alignment.Top verticalAlignment = Alignment.Top
) { position -> ) { position ->
if (isLoading) { val items = if (position == 0) blackList else whiteList
LazyColumn { StateScreen(
isEmpty = items.isEmpty(),
isError = false,
isLoading = isLoading,
onReload = { viewModel.send(BlockSettingsUiIntent.Load) },
loadingScreen = {
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(4) { items(4) {
BlockItemPlaceholder() BlockItemPlaceholder()
} }
} }
} else { }
val items = if (position == 0) blackList else whiteList ) {
if (items.isNotEmpty()) {
LazyColumn { LazyColumn {
items(items, key = { it.id }) { items(items, key = { it.id }) {
LongClickMenu(menuContent = { LongClickMenu(menuContent = {
DropdownMenuItem(onClick = { viewModel.send(BlockSettingsUiIntent.Delete(it.id)) }) { DropdownMenuItem(onClick = {
viewModel.send(
BlockSettingsUiIntent.Delete(
it.id
)
)
}) {
Text(text = stringResource(id = R.string.title_delete)) Text(text = stringResource(id = R.string.title_delete))
} }
}) { }) {
@ -226,9 +233,6 @@ fun BlockSettingsPage(
} }
} }
} }
} else {
EmptyPlaceholder(modifier = Modifier.fillMaxSize())
}
} }
} }
} }

View File

@ -0,0 +1,66 @@
package com.huanchengfly.tieba.post.ui.widgets.compose.states
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.huanchengfly.tieba.post.R
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
import com.huanchengfly.tieba.post.ui.widgets.compose.EmptyPlaceholder
val DefaultLoadingScreen: @Composable () -> Unit = {
CircularProgressIndicator(modifier = Modifier.size(48.dp), color = MaterialTheme.colors.primary)
}
val DefaultEmptyScreen: @Composable () -> Unit = {
EmptyPlaceholder()
}
val DefaultErrorScreen: @Composable () -> Unit = {
Text(
text = stringResource(id = R.string.error_tip),
style = MaterialTheme.typography.body1,
color = ExtendedTheme.colors.textSecondary
)
}
@Composable
fun StateScreen(
isEmpty: Boolean,
isError: Boolean,
isLoading: Boolean,
onReload: () -> Unit,
modifier: Modifier = Modifier,
emptyScreen: @Composable () -> Unit = DefaultEmptyScreen,
errorScreen: @Composable () -> Unit = DefaultErrorScreen,
loadingScreen: @Composable () -> Unit = DefaultLoadingScreen,
content: @Composable () -> Unit,
) {
Box(
modifier = Modifier
.fillMaxSize()
.then(modifier)
.clickable(enabled = isEmpty && !isLoading, onClick = onReload),
contentAlignment = Alignment.Center
) {
if (!isEmpty) {
content()
} else {
if (isLoading) {
loadingScreen()
} else if (isError) {
errorScreen()
} else {
emptyScreen()
}
}
}
}

View File

@ -628,4 +628,5 @@
<string name="delete_store_failure">取消收藏失败 %s</string> <string name="delete_store_failure">取消收藏失败 %s</string>
<string name="delete_history_failure">删除历史记录失败 %s</string> <string name="delete_history_failure">删除历史记录失败 %s</string>
<string name="delete_history_success">删除历史记录成功</string> <string name="delete_history_success">删除历史记录成功</string>
<string name="error_tip">出错了</string>
</resources> </resources>