feat: 「打卡」未登录自动跳转「我的」
This commit is contained in:
@@ -77,7 +77,9 @@ fun AppNavHost() {
|
|||||||
onNavigateToProfile = { navigateToTab(PROFILE_ROUTE) },
|
onNavigateToProfile = { navigateToTab(PROFILE_ROUTE) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(CHECKIN_ROUTE) { CheckinScreen() }
|
composable(CHECKIN_ROUTE) {
|
||||||
|
CheckinScreen(onNavigateToProfile = { navigateToTab(PROFILE_ROUTE) })
|
||||||
|
}
|
||||||
composable(PLAN_ROUTE) {
|
composable(PLAN_ROUTE) {
|
||||||
PlanScreen(
|
PlanScreen(
|
||||||
onNavigateToPlanSubmit = { type, periodKey ->
|
onNavigateToPlanSubmit = { type, periodKey ->
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import androidx.compose.foundation.lazy.LazyColumn
|
|||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
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
|
||||||
@@ -33,6 +34,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
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.SectionCard
|
import com.mingyuan.android_client.core.designsystem.component.SectionCard
|
||||||
import com.mingyuan.android_client.core.designsystem.component.SkeletonBox
|
import com.mingyuan.android_client.core.designsystem.component.SkeletonBox
|
||||||
import com.mingyuan.android_client.core.designsystem.theme.BrandAmber
|
import com.mingyuan.android_client.core.designsystem.theme.BrandAmber
|
||||||
@@ -56,6 +58,7 @@ const val CHECKIN_ROUTE = "checkin"
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CheckinScreen(
|
fun CheckinScreen(
|
||||||
|
onNavigateToProfile: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
viewModel: CheckinViewModel = hiltViewModel(),
|
viewModel: CheckinViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
@@ -63,8 +66,15 @@ fun CheckinScreen(
|
|||||||
val selectedStatus by viewModel.selectedStatus.collectAsStateWithLifecycle()
|
val selectedStatus by viewModel.selectedStatus.collectAsStateWithLifecycle()
|
||||||
val submitting by viewModel.submitting.collectAsStateWithLifecycle()
|
val submitting by viewModel.submitting.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
|
LaunchedEffect(uiState) {
|
||||||
|
if (uiState is CheckinUiState.LoggedOut) {
|
||||||
|
onNavigateToProfile()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
when (val state = uiState) {
|
when (val state = uiState) {
|
||||||
is CheckinUiState.Loading -> CheckinSkeleton(modifier)
|
is CheckinUiState.Loading -> CheckinSkeleton(modifier)
|
||||||
|
is CheckinUiState.LoggedOut -> LoggedOutState(modifier = modifier)
|
||||||
is CheckinUiState.Error -> ErrorState(
|
is CheckinUiState.Error -> ErrorState(
|
||||||
message = state.message,
|
message = state.message,
|
||||||
onRetry = {},
|
onRetry = {},
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.mingyuan.android_client.feature.checkin
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.mingyuan.android_client.core.domain.repository.CheckinRepository
|
import com.mingyuan.android_client.core.domain.repository.CheckinRepository
|
||||||
|
import com.mingyuan.android_client.core.domain.repository.SessionRepository
|
||||||
import com.mingyuan.android_client.core.model.CheckinRecord
|
import com.mingyuan.android_client.core.model.CheckinRecord
|
||||||
import com.mingyuan.android_client.core.model.CheckinStatus
|
import com.mingyuan.android_client.core.model.CheckinStatus
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
@@ -11,6 +12,8 @@ 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.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,12 +23,14 @@ import javax.inject.Inject
|
|||||||
sealed interface CheckinUiState {
|
sealed interface CheckinUiState {
|
||||||
data object Loading : CheckinUiState
|
data object Loading : CheckinUiState
|
||||||
data class Success(val record: CheckinRecord) : CheckinUiState
|
data class Success(val record: CheckinRecord) : CheckinUiState
|
||||||
|
data object LoggedOut : CheckinUiState
|
||||||
data class Error(val message: String) : CheckinUiState
|
data class Error(val message: String) : CheckinUiState
|
||||||
}
|
}
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class CheckinViewModel @Inject constructor(
|
class CheckinViewModel @Inject constructor(
|
||||||
private val checkinRepository: CheckinRepository,
|
private val checkinRepository: CheckinRepository,
|
||||||
|
private val sessionRepository: SessionRepository,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val _selectedStatus = MutableStateFlow(CheckinStatus.NORMAL)
|
private val _selectedStatus = MutableStateFlow(CheckinStatus.NORMAL)
|
||||||
@@ -34,13 +39,20 @@ class CheckinViewModel @Inject constructor(
|
|||||||
private val _submitting = MutableStateFlow(false)
|
private val _submitting = MutableStateFlow(false)
|
||||||
val submitting: StateFlow<Boolean> = _submitting.asStateFlow()
|
val submitting: StateFlow<Boolean> = _submitting.asStateFlow()
|
||||||
|
|
||||||
val uiState: StateFlow<CheckinUiState> = checkinRepository.observeCheckin()
|
val uiState: StateFlow<CheckinUiState> = sessionRepository.isLoggedIn
|
||||||
|
.flatMapLatest { loggedIn ->
|
||||||
|
if (loggedIn) {
|
||||||
|
checkinRepository.observeCheckin()
|
||||||
.map<CheckinRecord, CheckinUiState>(CheckinUiState::Success)
|
.map<CheckinRecord, CheckinUiState>(CheckinUiState::Success)
|
||||||
.onStart { emit(CheckinUiState.Loading) }
|
.onStart { emit(CheckinUiState.Loading) }
|
||||||
|
} else {
|
||||||
|
flowOf(CheckinUiState.LoggedOut)
|
||||||
|
}
|
||||||
|
}
|
||||||
.catch { emit(CheckinUiState.Error(it.message ?: "加载失败,请稍后再试")) }
|
.catch { emit(CheckinUiState.Error(it.message ?: "加载失败,请稍后再试")) }
|
||||||
.stateIn(
|
.stateIn(
|
||||||
scope = viewModelScope,
|
scope = viewModelScope,
|
||||||
started = SharingStarted.WhileSubscribed(5_000),
|
started = SharingStarted.Eagerly,
|
||||||
initialValue = CheckinUiState.Loading,
|
initialValue = CheckinUiState.Loading,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user