pref: 首页未登录 & 空状态优化
This commit is contained in:
parent
3a897cd4d1
commit
afe5d19e44
|
|
@ -107,6 +107,9 @@ fun MainPage(
|
|||
}
|
||||
}
|
||||
|
||||
val pagerState = rememberPagerState()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val themeColors = ExtendedTheme.colors
|
||||
val windowSizeClass = LocalWindowSizeClass.current
|
||||
val foldingDevicePosture by devicePostureFlow.collectAsState()
|
||||
val navigationItems = listOfNotNull(
|
||||
|
|
@ -114,7 +117,14 @@ fun MainPage(
|
|||
icon = { if (it) Icons.Rounded.Inventory2 else Icons.Outlined.Inventory2 },
|
||||
title = stringResource(id = R.string.title_main),
|
||||
content = {
|
||||
HomePage()
|
||||
HomePage(
|
||||
canOpenExplore = !LocalContext.current.appPreferences.hideExplore,
|
||||
onOpenExplore = {
|
||||
coroutineScope.launch {
|
||||
pagerState.scrollToPage(1)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
),
|
||||
if (LocalContext.current.appPreferences.hideExplore) null
|
||||
|
|
@ -149,9 +159,6 @@ fun MainPage(
|
|||
}
|
||||
),
|
||||
)
|
||||
val pagerState = rememberPagerState()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val themeColors = ExtendedTheme.colors
|
||||
|
||||
val navigationType = when (windowSizeClass.widthSizeClass) {
|
||||
WindowWidthSizeClass.Compact -> {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@ import androidx.compose.animation.animateContentSize
|
|||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
|
|
@ -26,6 +28,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||
import androidx.compose.material.DropdownMenuItem
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
|
|
@ -54,12 +57,18 @@ import androidx.compose.ui.platform.LocalContext
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.airbnb.lottie.compose.LottieAnimation
|
||||
import com.airbnb.lottie.compose.LottieCompositionSpec
|
||||
import com.airbnb.lottie.compose.LottieConstants
|
||||
import com.airbnb.lottie.compose.rememberLottieComposition
|
||||
import com.google.accompanist.drawablepainter.rememberDrawablePainter
|
||||
import com.google.accompanist.placeholder.placeholder
|
||||
import com.huanchengfly.tieba.post.R
|
||||
import com.huanchengfly.tieba.post.activities.LoginActivity
|
||||
import com.huanchengfly.tieba.post.activities.NewSearchActivity
|
||||
import com.huanchengfly.tieba.post.arch.collectPartialAsState
|
||||
import com.huanchengfly.tieba.post.arch.pageViewModel
|
||||
|
|
@ -70,12 +79,14 @@ import com.huanchengfly.tieba.post.ui.page.destinations.ForumPageDestination
|
|||
import com.huanchengfly.tieba.post.ui.widgets.Chip
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.ActionItem
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.Avatar
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.Button
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.ConfirmDialog
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.LongClickMenu
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.Toolbar
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.accountNavIconIfCompact
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.rememberDialogState
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.rememberMenuState
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.states.StateScreen
|
||||
import com.huanchengfly.tieba.post.utils.AccountUtil.LocalAccount
|
||||
import com.huanchengfly.tieba.post.utils.ImageUtil
|
||||
import com.huanchengfly.tieba.post.utils.TiebaUtil
|
||||
|
|
@ -362,8 +373,10 @@ fun HomePage(
|
|||
HomeUiIntent.Refresh
|
||||
)
|
||||
),
|
||||
canOpenExplore: Boolean = false,
|
||||
onOpenExplore: () -> Unit = {},
|
||||
) {
|
||||
LocalAccount.current
|
||||
val account = LocalAccount.current
|
||||
val context = LocalContext.current
|
||||
val isLoading by viewModel.uiState.collectPartialAsState(
|
||||
prop1 = HomeUiState::isLoading,
|
||||
|
|
@ -379,6 +392,7 @@ fun HomePage(
|
|||
)
|
||||
var listSingle by remember { mutableStateOf(context.appPreferences.listSingle) }
|
||||
val gridCells by remember { derivedStateOf { getGridCells(context, listSingle) } }
|
||||
|
||||
Scaffold(
|
||||
backgroundColor = Color.Transparent,
|
||||
topBar = {
|
||||
|
|
@ -404,12 +418,29 @@ fun HomePage(
|
|||
},
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
) { contentPaddings ->
|
||||
StateScreen(
|
||||
isEmpty = forums.isEmpty(),
|
||||
isError = false,
|
||||
isLoading = isLoading,
|
||||
modifier = Modifier.padding(contentPaddings),
|
||||
emptyScreen = {
|
||||
EmptyScreen(
|
||||
loggedIn = account != null,
|
||||
canOpenExplore = canOpenExplore,
|
||||
onOpenExplore = onOpenExplore
|
||||
)
|
||||
},
|
||||
loadingScreen = {
|
||||
HomePageSkeletonScreen(listSingle = listSingle, gridCells = gridCells)
|
||||
}
|
||||
) {
|
||||
val pullRefreshState = rememberPullRefreshState(
|
||||
refreshing = isLoading,
|
||||
onRefresh = { viewModel.send(HomeUiIntent.Refresh) })
|
||||
Box(modifier = Modifier
|
||||
.padding(contentPaddings)
|
||||
.pullRefresh(pullRefreshState)) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.pullRefresh(pullRefreshState)
|
||||
) {
|
||||
val gridState = rememberLazyGridState()
|
||||
LazyVerticalGrid(
|
||||
state = gridState,
|
||||
|
|
@ -423,7 +454,6 @@ fun HomePage(
|
|||
context.goToActivity<NewSearchActivity>()
|
||||
}
|
||||
}
|
||||
if (!isLoading || forums.isNotEmpty()) {
|
||||
if (topForums.isNotEmpty()) {
|
||||
item(key = "TopForumHeader", span = { GridItemSpan(maxLineSpan) }) {
|
||||
Column {
|
||||
|
|
@ -458,13 +488,38 @@ fun HomePage(
|
|||
val item = forums[it]
|
||||
ForumItem(viewModel, item, listSingle)
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
PullRefreshIndicator(
|
||||
refreshing = isLoading,
|
||||
state = pullRefreshState,
|
||||
modifier = Modifier.align(Alignment.TopCenter)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HomePageSkeletonScreen(
|
||||
listSingle: Boolean,
|
||||
gridCells: GridCells
|
||||
) {
|
||||
LazyVerticalGrid(
|
||||
columns = gridCells,
|
||||
contentPadding = PaddingValues(bottom = 12.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
item(key = "TopForumHeaderPlaceholder", span = { GridItemSpan(maxLineSpan) }) {
|
||||
Column {
|
||||
Header(
|
||||
text = stringResource(id = R.string.title_top_forum),
|
||||
invert = true,
|
||||
modifier = Modifier.placeholder(visible = true, color = ExtendedTheme.colors.chip)
|
||||
modifier = Modifier.placeholder(
|
||||
visible = true,
|
||||
color = ExtendedTheme.colors.chip
|
||||
)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
}
|
||||
|
|
@ -500,11 +555,59 @@ fun HomePage(
|
|||
}
|
||||
}
|
||||
|
||||
PullRefreshIndicator(
|
||||
refreshing = isLoading,
|
||||
state = pullRefreshState,
|
||||
modifier = Modifier.align(Alignment.TopCenter)
|
||||
@Composable
|
||||
fun EmptyScreen(
|
||||
loggedIn: Boolean,
|
||||
canOpenExplore: Boolean,
|
||||
onOpenExplore: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp, alignment = CenterVertically)
|
||||
) {
|
||||
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.lottie_astronaut))
|
||||
LottieAnimation(
|
||||
composition = composition,
|
||||
iterations = LottieConstants.IterateForever,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(2f)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.title_empty),
|
||||
style = MaterialTheme.typography.h6,
|
||||
color = ExtendedTheme.colors.text,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
if (!loggedIn) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.title_empty_login),
|
||||
style = MaterialTheme.typography.body1,
|
||||
color = ExtendedTheme.colors.textSecondary,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Button(
|
||||
onClick = {
|
||||
context.goToActivity<LoginActivity>()
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.button_login))
|
||||
}
|
||||
}
|
||||
if (canOpenExplore) {
|
||||
Button(
|
||||
onClick = onOpenExplore,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.button_go_to_explore))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.PaddingValues
|
|||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.ButtonColors
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.ButtonElevation
|
||||
|
|
@ -23,6 +24,7 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
|
|
@ -31,10 +33,13 @@ fun Button(
|
|||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
elevation: ButtonElevation? = ButtonDefaults.elevation(),
|
||||
shape: Shape = MaterialTheme.shapes.small,
|
||||
elevation: ButtonElevation? = ButtonDefaults.elevation(0.dp, 0.dp, 0.dp, 0.dp, 0.dp),
|
||||
shape: Shape = RoundedCornerShape(100),
|
||||
border: BorderStroke? = null,
|
||||
colors: ButtonColors = ButtonDefaults.buttonColors(),
|
||||
colors: ButtonColors = ButtonDefaults.buttonColors(
|
||||
backgroundColor = ExtendedTheme.colors.accent,
|
||||
contentColor = ExtendedTheme.colors.onAccent
|
||||
),
|
||||
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
|
||||
content: @Composable RowScope.() -> Unit
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -642,4 +642,10 @@
|
|||
<string name="message_dialog_oksign_battery_optimization">在 Android 12 及以上版本中,后台启动前台服务被严格限制。为了避免一键签到无法正常启动,请忽略本应用的“电池优化”。</string>
|
||||
<string name="button_go_to_ignore_battery_optimization">好的,去忽略</string>
|
||||
<string name="button_dont_remind_again">不再提示</string>
|
||||
<string name="link">链接</string>
|
||||
<string name="user">用户</string>
|
||||
<string name="title_empty">这里什么都没有</string>
|
||||
<string name="title_empty_login">请登录之后查看你的关注。\n或者你也可以先去逛逛发现?</string>
|
||||
<string name="button_login">去登录</string>
|
||||
<string name="button_go_to_explore">随便看看</string>
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Reference in New Issue