feat: 「首页」支持游客模式
This commit is contained in:
@@ -74,6 +74,7 @@ fun AppNavHost() {
|
||||
HomeScreen(
|
||||
onNavigateToCheckin = { navigateToTab(CHECKIN_ROUTE) },
|
||||
onNavigateToPlan = { navigateToTab(PLAN_ROUTE) },
|
||||
onNavigateToProfile = { navigateToTab(PROFILE_ROUTE) },
|
||||
)
|
||||
}
|
||||
composable(CHECKIN_ROUTE) { CheckinScreen() }
|
||||
|
||||
@@ -18,16 +18,34 @@ class FakeHomeRepository @Inject constructor() : HomeRepository {
|
||||
emit(seedHome())
|
||||
}
|
||||
|
||||
override fun observeGuestHome(): Flow<HomeData> = flow {
|
||||
delay(250)
|
||||
emit(seedGuestHome())
|
||||
}
|
||||
|
||||
private fun seedHome() = HomeData(
|
||||
greeting = "晚上好",
|
||||
displayName = "张三",
|
||||
encouragement = "坚持每周打卡,与小组共同进步。",
|
||||
modules = listOf(
|
||||
modules = modules(),
|
||||
intros = intros(),
|
||||
)
|
||||
|
||||
private fun seedGuestHome() = HomeData(
|
||||
greeting = "欢迎来到明缘云道场",
|
||||
displayName = "游客",
|
||||
encouragement = "登录后即可打卡、提交计划",
|
||||
modules = modules(),
|
||||
intros = intros(),
|
||||
)
|
||||
|
||||
private fun modules() = listOf(
|
||||
HomeModule("checkin", "📋", "打卡介绍", "每日打卡记录", ModuleDestination.CHECKIN),
|
||||
HomeModule("plan", "📝", "计划介绍", "周/月/年计划", ModuleDestination.PLAN),
|
||||
HomeModule("about", "ℹ️", "关于我们", "了解明缘云道场", ModuleDestination.ABOUT),
|
||||
),
|
||||
intros = listOf(
|
||||
)
|
||||
|
||||
private fun intros() = listOf(
|
||||
IntroCard(
|
||||
"📚 学习成长工具",
|
||||
"明缘云道场是一款专注于个人成长的效率工具,通过每周打卡与计划管理,帮助你养成良好的学习习惯,实现持续进步。好好学习,天天向上。",
|
||||
@@ -44,6 +62,5 @@ class FakeHomeRepository @Inject constructor() : HomeRepository {
|
||||
"👥 小组共学",
|
||||
"加入学习小组,查看组员的打卡与计划完成情况。在集体的氛围中保持学习动力,与志同道合的伙伴一起成长。",
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,4 +5,6 @@ import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface HomeRepository {
|
||||
fun observeHome(): Flow<HomeData>
|
||||
|
||||
fun observeGuestHome(): Flow<HomeData>
|
||||
}
|
||||
|
||||
@@ -16,9 +16,14 @@ import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.shadow
|
||||
@@ -51,10 +56,12 @@ const val HOME_ROUTE = "home"
|
||||
fun HomeScreen(
|
||||
onNavigateToCheckin: () -> Unit,
|
||||
onNavigateToPlan: () -> Unit,
|
||||
onNavigateToProfile: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: HomeViewModel = hiltViewModel(),
|
||||
) {
|
||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||
var showLoginDialog by remember { mutableStateOf(false) }
|
||||
|
||||
when (val state = uiState) {
|
||||
is HomeUiState.Loading -> HomeSkeleton(modifier)
|
||||
@@ -67,15 +74,40 @@ fun HomeScreen(
|
||||
is HomeUiState.Success -> HomeContent(
|
||||
data = state.data,
|
||||
onModuleClick = { module ->
|
||||
if (state.isGuest) {
|
||||
showLoginDialog = true
|
||||
} else {
|
||||
when (module.destination) {
|
||||
ModuleDestination.CHECKIN -> onNavigateToCheckin()
|
||||
ModuleDestination.PLAN -> onNavigateToPlan()
|
||||
ModuleDestination.ABOUT -> Unit
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
if (showLoginDialog) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { showLoginDialog = false },
|
||||
title = { Text("登录提示") },
|
||||
text = { Text("登录后使用此功能,是否前往登录?") },
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
showLoginDialog = false
|
||||
onNavigateToProfile()
|
||||
},
|
||||
) {
|
||||
Text("去登录")
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { showLoginDialog = false }) { Text("取消") }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -3,11 +3,13 @@ package com.mingyuan.android_client.feature.home
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.mingyuan.android_client.core.domain.repository.HomeRepository
|
||||
import com.mingyuan.android_client.core.domain.repository.SessionRepository
|
||||
import com.mingyuan.android_client.core.model.HomeData
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
@@ -15,22 +17,31 @@ import javax.inject.Inject
|
||||
|
||||
sealed interface HomeUiState {
|
||||
data object Loading : HomeUiState
|
||||
data class Success(val data: HomeData) : HomeUiState
|
||||
data class Success(val data: HomeData, val isGuest: Boolean) : HomeUiState
|
||||
data class Error(val message: String) : HomeUiState
|
||||
}
|
||||
|
||||
@HiltViewModel
|
||||
class HomeViewModel @Inject constructor(
|
||||
homeRepository: HomeRepository,
|
||||
sessionRepository: SessionRepository,
|
||||
) : ViewModel() {
|
||||
|
||||
val uiState: StateFlow<HomeUiState> = homeRepository.observeHome()
|
||||
.map<HomeData, HomeUiState>(HomeUiState::Success)
|
||||
val uiState: StateFlow<HomeUiState> = sessionRepository.isLoggedIn
|
||||
.flatMapLatest { loggedIn ->
|
||||
val source = if (loggedIn) {
|
||||
homeRepository.observeHome()
|
||||
} else {
|
||||
homeRepository.observeGuestHome()
|
||||
}
|
||||
source
|
||||
.map<HomeData, HomeUiState> { HomeUiState.Success(it, isGuest = !loggedIn) }
|
||||
.onStart { emit(HomeUiState.Loading) }
|
||||
}
|
||||
.catch { emit(HomeUiState.Error(it.message ?: "加载失败,请稍后再试")) }
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(5_000),
|
||||
started = SharingStarted.Eagerly,
|
||||
initialValue = HomeUiState.Loading,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user