feat: 「首页」支持游客模式

This commit is contained in:
AndyChen1024
2026-09-09 22:19:12 +08:00
parent 03410d7ea2
commit 0b8bcfe800
5 changed files with 93 additions and 30 deletions

View File

@@ -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 ->
when (module.destination) {
ModuleDestination.CHECKIN -> onNavigateToCheckin()
ModuleDestination.PLAN -> onNavigateToPlan()
ModuleDestination.ABOUT -> Unit
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

View File

@@ -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)
.onStart { emit(HomeUiState.Loading) }
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,
)
}