From 90b8b6da1327a01687bcb9758b092b193f8791b5 Mon Sep 17 00:00:00 2001 From: Eric85710 Date: Thu, 30 Apr 2026 16:58:58 +0800 Subject: [PATCH] auth to server-V20 --- .../auth/login/Login_Page_ViewModel.kt | 54 ++++++++++++++++++- .../api/api_class/AuthRequest_Response.kt | 27 +++++++++- 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/example/login_v3/auth/login/Login_Page_ViewModel.kt b/app/src/main/java/com/example/login_v3/auth/login/Login_Page_ViewModel.kt index 26f9993..fcb8e9e 100644 --- a/app/src/main/java/com/example/login_v3/auth/login/Login_Page_ViewModel.kt +++ b/app/src/main/java/com/example/login_v3/auth/login/Login_Page_ViewModel.kt @@ -1 +1,53 @@ -package com.example.login_v3.auth.login \ No newline at end of file +package com.example.login_v3.auth.login + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.login_v3.data.api.api_class.LoginRequest +import com.example.login_v3.data.api.api_class.UserInfo +import com.example.login_v3.data.repository.basic.AuthRepository +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +sealed class LoginUiState { + object Idle : LoginUiState() + object Loading : LoginUiState() + data class Success(val user: UserInfo) : LoginUiState() + data class Error(val message: String) : LoginUiState() +} + +@HiltViewModel +class AuthViewModel @Inject constructor( + private val repository: AuthRepository +) : ViewModel() { + + // 用於內部修改的私有狀態 + private val _loginState = MutableStateFlow(LoginUiState.Idle) + // 暴露給 Compose 觀察的公開狀態 + val loginState: StateFlow = _loginState.asStateFlow() + + fun login(username: String, password: String) { + viewModelScope.launch { + _loginState.value = LoginUiState.Loading + + try { + val request = LoginRequest(username = username, password = password) + val response = repository.login(request) + + if (response.isSuccessful && response.body() != null) { + // 登入成功,儲存 User 資訊 + _loginState.value = LoginUiState.Success(response.body()!!.user) + + // 提示:通常這裡還會處理 Token 持久化(儲存在 DataStore 或 EncryptedSharedPreferences) + } else { + _loginState.value = LoginUiState.Error("登入失敗:${response.code()}") + } + } catch (e: Exception) { + _loginState.value = LoginUiState.Error("網路異常:${e.localizedMessage}") + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/login_v3/data/api/api_class/AuthRequest_Response.kt b/app/src/main/java/com/example/login_v3/data/api/api_class/AuthRequest_Response.kt index 488d7f6..21a68b9 100644 --- a/app/src/main/java/com/example/login_v3/data/api/api_class/AuthRequest_Response.kt +++ b/app/src/main/java/com/example/login_v3/data/api/api_class/AuthRequest_Response.kt @@ -2,6 +2,10 @@ package com.example.login_v3.data.api.api_class import com.squareup.moshi.Json import com.squareup.moshi.JsonClass + + + +//login data @JsonClass(generateAdapter = true) data class LoginRequest( val username: String, @@ -9,10 +13,30 @@ data class LoginRequest( ) @JsonClass(generateAdapter = true) data class LoginResponse( + val access_token: String, + val expires_in: Int, + val refresh_token: String, val token: String, - val userId: String + val user: UserInfo +) +@JsonClass(generateAdapter = true) +data class UserInfo( + val id: String, + val username: String, + val display_name: String, + val email: String, + val avatar_url: String, + val banner_url: String, + val bio: String, + val status: String, + val is_verified: Boolean, + val created_at: String ) + + + +//register data @JsonClass(generateAdapter = true) data class RegisterRequest( val display_name: String, @@ -20,7 +44,6 @@ data class RegisterRequest( val password: String, val username: String ) - @JsonClass(generateAdapter = true) data class RegisterResponse( @field:Json(name = "id") val id: String,