feat: 「首页」支持游客模式
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user