feat: 「计划」未登录自动跳转「我的」
This commit is contained in:
@@ -85,6 +85,7 @@ fun AppNavHost() {
|
|||||||
onNavigateToPlanSubmit = { type, periodKey ->
|
onNavigateToPlanSubmit = { type, periodKey ->
|
||||||
navController.navigate(planSubmitRoute(type, periodKey))
|
navController.navigate(planSubmitRoute(type, periodKey))
|
||||||
},
|
},
|
||||||
|
onNavigateToProfile = { navigateToTab(PROFILE_ROUTE) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(
|
composable(
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import androidx.compose.material3.AlertDialog
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
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.Avatar
|
||||||
import com.mingyuan.android_client.core.designsystem.component.EmptyState
|
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.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.MingyuanButton
|
||||||
import com.mingyuan.android_client.core.designsystem.component.SectionCard
|
import com.mingyuan.android_client.core.designsystem.component.SectionCard
|
||||||
import com.mingyuan.android_client.core.designsystem.component.SegmentedControl
|
import com.mingyuan.android_client.core.designsystem.component.SegmentedControl
|
||||||
@@ -66,12 +68,24 @@ const val PLAN_ROUTE = "plan"
|
|||||||
@Composable
|
@Composable
|
||||||
fun PlanScreen(
|
fun PlanScreen(
|
||||||
onNavigateToPlanSubmit: (PlanType, String) -> Unit,
|
onNavigateToPlanSubmit: (PlanType, String) -> Unit,
|
||||||
|
onNavigateToProfile: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
viewModel: PlanViewModel = hiltViewModel(),
|
viewModel: PlanViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
val selectedType by viewModel.selectedType.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)) {
|
Column(modifier = modifier.fillMaxSize().background(PlanBackground)) {
|
||||||
Box(Modifier.fillMaxWidth().padding(16.dp)) {
|
Box(Modifier.fillMaxWidth().padding(16.dp)) {
|
||||||
SegmentedControl(
|
SegmentedControl(
|
||||||
@@ -94,6 +108,8 @@ fun PlanScreen(
|
|||||||
selectedType = selectedType,
|
selectedType = selectedType,
|
||||||
onNavigateToPlanSubmit = onNavigateToPlanSubmit,
|
onNavigateToPlanSubmit = onNavigateToPlanSubmit,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
is PlanUiState.LoggedOut -> Unit // handled above
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.mingyuan.android_client.feature.plan
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.mingyuan.android_client.core.domain.repository.PlanRepository
|
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.PlanRecord
|
||||||
import com.mingyuan.android_client.core.model.PlanType
|
import com.mingyuan.android_client.core.model.PlanType
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
@@ -11,7 +12,9 @@ import kotlinx.coroutines.flow.SharingStarted
|
|||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onStart
|
import kotlinx.coroutines.flow.onStart
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
@@ -20,25 +23,34 @@ import javax.inject.Inject
|
|||||||
sealed interface PlanUiState {
|
sealed interface PlanUiState {
|
||||||
data object Loading : PlanUiState
|
data object Loading : PlanUiState
|
||||||
data class Success(val record: PlanRecord) : PlanUiState
|
data class Success(val record: PlanRecord) : PlanUiState
|
||||||
|
data object LoggedOut : PlanUiState
|
||||||
data class Error(val message: String) : PlanUiState
|
data class Error(val message: String) : PlanUiState
|
||||||
}
|
}
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class PlanViewModel @Inject constructor(
|
class PlanViewModel @Inject constructor(
|
||||||
private val planRepository: PlanRepository,
|
private val planRepository: PlanRepository,
|
||||||
|
private val sessionRepository: SessionRepository,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val _selectedType = MutableStateFlow(PlanType.WEEKLY)
|
private val _selectedType = MutableStateFlow(PlanType.WEEKLY)
|
||||||
val selectedType: StateFlow<PlanType> = _selectedType.asStateFlow()
|
val selectedType: StateFlow<PlanType> = _selectedType.asStateFlow()
|
||||||
|
|
||||||
val uiState: StateFlow<PlanUiState> = _selectedType
|
val uiState: StateFlow<PlanUiState> =
|
||||||
.flatMapLatest { type -> planRepository.observePlan(type) }
|
combine(sessionRepository.isLoggedIn, _selectedType) { loggedIn, type -> loggedIn to type }
|
||||||
|
.flatMapLatest { (loggedIn, type) ->
|
||||||
|
if (loggedIn) {
|
||||||
|
planRepository.observePlan(type)
|
||||||
.map<PlanRecord, PlanUiState>(PlanUiState::Success)
|
.map<PlanRecord, PlanUiState>(PlanUiState::Success)
|
||||||
.onStart { emit(PlanUiState.Loading) }
|
.onStart { emit(PlanUiState.Loading) }
|
||||||
|
} else {
|
||||||
|
flowOf(PlanUiState.LoggedOut)
|
||||||
|
}
|
||||||
|
}
|
||||||
.catch { emit(PlanUiState.Error(it.message ?: "加载失败,请稍后再试")) }
|
.catch { emit(PlanUiState.Error(it.message ?: "加载失败,请稍后再试")) }
|
||||||
.stateIn(
|
.stateIn(
|
||||||
scope = viewModelScope,
|
scope = viewModelScope,
|
||||||
started = SharingStarted.WhileSubscribed(5_000),
|
started = SharingStarted.Eagerly,
|
||||||
initialValue = PlanUiState.Loading,
|
initialValue = PlanUiState.Loading,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user