auth to server-V25
This commit is contained in:
parent
acba929b6d
commit
b2e1fd800d
3 changed files with 58 additions and 19 deletions
|
|
@ -63,8 +63,7 @@ import kotlin.text.ifEmpty
|
||||||
@Composable
|
@Composable
|
||||||
fun LoginScreen(
|
fun LoginScreen(
|
||||||
paddingValues: PaddingValues,
|
paddingValues: PaddingValues,
|
||||||
viewModel: AuthViewModel = hiltViewModel(),
|
viewModel: AuthViewModel = hiltViewModel()
|
||||||
onLoginSuccess: () -> Unit
|
|
||||||
){
|
){
|
||||||
|
|
||||||
val uiState by viewModel.loginState.collectAsStateWithLifecycle()
|
val uiState by viewModel.loginState.collectAsStateWithLifecycle()
|
||||||
|
|
@ -265,11 +264,6 @@ fun LoginScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(uiState) {
|
|
||||||
if (uiState is LoginUiState.Success) {
|
|
||||||
onLoginSuccess() // 觸發跳轉邏輯
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,16 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.example.login_v3.data.repository.basic.TokenManager
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class MainViewModel : ViewModel() {
|
class MainViewModel : ViewModel() {
|
||||||
|
|
||||||
|
|
@ -20,22 +28,46 @@ class MainViewModel : ViewModel() {
|
||||||
|
|
||||||
//init navigation
|
//init navigation
|
||||||
enum class AppScreen {
|
enum class AppScreen {
|
||||||
PreReg, Login, Register, Home, ScreensTab
|
PreReg, Login, Register, Home, ScreensTab, Loading
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppViewModel : ViewModel() {
|
@HiltViewModel
|
||||||
private val _currentScreen = MutableStateFlow<AppScreen>(AppScreen.PreReg)
|
class AppViewModel @Inject constructor(
|
||||||
val currentScreen: StateFlow<AppScreen> = _currentScreen
|
private val tokenManager: TokenManager
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
private val _currentScreen = MutableStateFlow<AppScreen>(AppScreen.Loading) // 增加一個 Loading 狀態
|
||||||
|
val currentScreen: StateFlow<AppScreen> = _currentScreen.asStateFlow()
|
||||||
|
|
||||||
|
// 暴露 Token 給其他需要的 Screen 使用
|
||||||
|
val userToken: StateFlow<String?> = tokenManager.accessToken
|
||||||
|
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), null)
|
||||||
|
|
||||||
|
init {
|
||||||
|
checkLoginStatus()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkLoginStatus() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
// 讀取 DataStore 中的 isLogin 狀態
|
||||||
|
tokenManager.isLogin.collect { loggedIn ->
|
||||||
|
if (loggedIn) {
|
||||||
|
_currentScreen.value = AppScreen.ScreensTab
|
||||||
|
} else {
|
||||||
|
_currentScreen.value = AppScreen.PreReg // 或 AppScreen.Register
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun goTo(screen: AppScreen) {
|
fun goTo(screen: AppScreen) {
|
||||||
_currentScreen.value = screen
|
_currentScreen.value = screen
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onLoginSuccess() {
|
|
||||||
_currentScreen.value = AppScreen.Home
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onLogout() {
|
fun onLogout() {
|
||||||
_currentScreen.value = AppScreen.PreReg
|
viewModelScope.launch {
|
||||||
|
tokenManager.clearAuthData()
|
||||||
|
// 清除後,checkLoginStatus 的 collect 會自動觸發切換回 PreReg
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
package com.example.login_v3.navigation
|
package com.example.login_v3.navigation
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.example.login_v3.auth.login.LoginScreen
|
import com.example.login_v3.auth.login.LoginScreen
|
||||||
import com.example.login_v3.auth.Login_or_Reg_page
|
import com.example.login_v3.auth.Login_or_Reg_page
|
||||||
|
|
@ -15,11 +21,19 @@ import com.example.login_v3.home.HomeScreen
|
||||||
@Composable
|
@Composable
|
||||||
fun AppNavGraph(
|
fun AppNavGraph(
|
||||||
paddingValues: PaddingValues,
|
paddingValues: PaddingValues,
|
||||||
appViewModel: AppViewModel = viewModel()
|
appViewModel: AppViewModel = hiltViewModel()
|
||||||
) {
|
) {
|
||||||
val currentScreen by appViewModel.currentScreen.collectAsState()
|
val currentScreen by appViewModel.currentScreen.collectAsState()
|
||||||
|
|
||||||
when (currentScreen) {
|
when (currentScreen) {
|
||||||
|
|
||||||
|
AppScreen.Loading -> {
|
||||||
|
// 顯示一個簡單的載入圈圈
|
||||||
|
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||||
|
CircularProgressIndicator()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AppScreen.PreReg -> Login_or_Reg_page(
|
AppScreen.PreReg -> Login_or_Reg_page(
|
||||||
paddingValues = paddingValues,
|
paddingValues = paddingValues,
|
||||||
onLoginClick = { appViewModel.goTo(AppScreen.Login) },
|
onLoginClick = { appViewModel.goTo(AppScreen.Login) },
|
||||||
|
|
@ -27,8 +41,7 @@ fun AppNavGraph(
|
||||||
)
|
)
|
||||||
|
|
||||||
AppScreen.Login -> LoginScreen(
|
AppScreen.Login -> LoginScreen(
|
||||||
paddingValues = paddingValues,
|
paddingValues = paddingValues
|
||||||
onLoginSuccess = { appViewModel.goTo(AppScreen.ScreensTab) }
|
|
||||||
)
|
)
|
||||||
|
|
||||||
AppScreen.Register -> {
|
AppScreen.Register -> {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue