feat: 「计划」未登录自动跳转「我的」

This commit is contained in:
AndyChen1024
2026-09-09 22:20:01 +08:00
parent 84c4bf64b3
commit e033c18aca
3 changed files with 39 additions and 10 deletions

View File

@@ -22,6 +22,7 @@ import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -39,6 +40,7 @@ import com.mingyuan.android_client.core.designsystem.component.AmberProgressBar
import com.mingyuan.android_client.core.designsystem.component.Avatar
import com.mingyuan.android_client.core.designsystem.component.EmptyState
import com.mingyuan.android_client.core.designsystem.component.ErrorState
import com.mingyuan.android_client.core.designsystem.component.LoggedOutState
import com.mingyuan.android_client.core.designsystem.component.MingyuanButton
import com.mingyuan.android_client.core.designsystem.component.SectionCard
import com.mingyuan.android_client.core.designsystem.component.SegmentedControl
@@ -66,12 +68,24 @@ const val PLAN_ROUTE = "plan"
@Composable
fun PlanScreen(
onNavigateToPlanSubmit: (PlanType, String) -> Unit,
onNavigateToProfile: () -> Unit,
modifier: Modifier = Modifier,
viewModel: PlanViewModel = hiltViewModel(),
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
val selectedType by viewModel.selectedType.collectAsStateWithLifecycle()
LaunchedEffect(uiState) {
if (uiState is PlanUiState.LoggedOut) {
onNavigateToProfile()
}
}
if (uiState is PlanUiState.LoggedOut) {
LoggedOutState(modifier = modifier.fillMaxSize().background(PlanBackground))
return
}
Column(modifier = modifier.fillMaxSize().background(PlanBackground)) {
Box(Modifier.fillMaxWidth().padding(16.dp)) {
SegmentedControl(
@@ -94,6 +108,8 @@ fun PlanScreen(
selectedType = selectedType,
onNavigateToPlanSubmit = onNavigateToPlanSubmit,
)
is PlanUiState.LoggedOut -> Unit // handled above
}
}
}

View File

@@ -3,6 +3,7 @@ package com.mingyuan.android_client.feature.plan
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.mingyuan.android_client.core.domain.repository.PlanRepository
import com.mingyuan.android_client.core.domain.repository.SessionRepository
import com.mingyuan.android_client.core.model.PlanRecord
import com.mingyuan.android_client.core.model.PlanType
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -11,7 +12,9 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
@@ -20,27 +23,36 @@ import javax.inject.Inject
sealed interface PlanUiState {
data object Loading : PlanUiState
data class Success(val record: PlanRecord) : PlanUiState
data object LoggedOut : PlanUiState
data class Error(val message: String) : PlanUiState
}
@HiltViewModel
class PlanViewModel @Inject constructor(
private val planRepository: PlanRepository,
private val sessionRepository: SessionRepository,
) : ViewModel() {
private val _selectedType = MutableStateFlow(PlanType.WEEKLY)
val selectedType: StateFlow<PlanType> = _selectedType.asStateFlow()
val uiState: StateFlow<PlanUiState> = _selectedType
.flatMapLatest { type -> planRepository.observePlan(type) }
.map<PlanRecord, PlanUiState>(PlanUiState::Success)
.onStart { emit(PlanUiState.Loading) }
.catch { emit(PlanUiState.Error(it.message ?: "加载失败,请稍后再试")) }
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = PlanUiState.Loading,
)
val uiState: StateFlow<PlanUiState> =
combine(sessionRepository.isLoggedIn, _selectedType) { loggedIn, type -> loggedIn to type }
.flatMapLatest { (loggedIn, type) ->
if (loggedIn) {
planRepository.observePlan(type)
.map<PlanRecord, PlanUiState>(PlanUiState::Success)
.onStart { emit(PlanUiState.Loading) }
} else {
flowOf(PlanUiState.LoggedOut)
}
}
.catch { emit(PlanUiState.Error(it.message ?: "加载失败,请稍后再试")) }
.stateIn(
scope = viewModelScope,
started = SharingStarted.Eagerly,
initialValue = PlanUiState.Loading,
)
fun selectType(type: PlanType) {
_selectedType.value = type