auth to server-V69
This commit is contained in:
parent
a9a17915c5
commit
041fa0bd9c
3 changed files with 31 additions and 45 deletions
|
|
@ -6,7 +6,8 @@ import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class FriendListResponse(
|
data class FriendListResponse(
|
||||||
val friends: List<Friend>
|
// 這樣寫最安全:即便 JSON 裡少了這個欄位,也會變成 emptyList
|
||||||
|
val friends: List<Friend> = emptyList()
|
||||||
)
|
)
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class Friend(
|
data class Friend(
|
||||||
|
|
@ -15,10 +16,10 @@ data class Friend(
|
||||||
|
|
||||||
val username: String?, // 建議 username 也改可空
|
val username: String?, // 建議 username 也改可空
|
||||||
|
|
||||||
@field:Json(name = "display_name")
|
@Json(name = "display_name") // 移除 field: 試試看
|
||||||
val displayName: String?,
|
val displayName: String?,
|
||||||
|
|
||||||
@field:Json(name = "avatar_url")
|
@Json(name = "avatar_url")
|
||||||
val avatarUrl: String?,
|
val avatarUrl: String?,
|
||||||
|
|
||||||
val status: String?,
|
val status: String?,
|
||||||
|
|
@ -27,12 +28,13 @@ data class Friend(
|
||||||
val acceptedAt: String?
|
val acceptedAt: String?
|
||||||
)
|
)
|
||||||
val Friend.fullFriendsAvatarUrl: Any
|
val Friend.fullFriendsAvatarUrl: Any
|
||||||
get() = if (avatarUrl.isNullOrBlank()) {
|
get() {
|
||||||
R.drawable.avatar_v1
|
val url = avatarUrl ?: ""
|
||||||
} else if (avatarUrl.startsWith("http")) {
|
return when {
|
||||||
avatarUrl
|
url.isBlank() -> R.drawable.avatar_v1
|
||||||
} else {
|
url.startsWith("http") -> url
|
||||||
"http://192.168.0.217$avatarUrl"
|
else -> "http://192.168.0.217$url"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,11 @@ class FriendsRepository @Inject constructor(
|
||||||
suspend fun getFriendList(): Result<List<Friend>> {
|
suspend fun getFriendList(): Result<List<Friend>> {
|
||||||
return try {
|
return try {
|
||||||
val response = apiService.getFriends()
|
val response = apiService.getFriends()
|
||||||
// 回傳成功,並直接提取裡面的 List<Friend>
|
// 如果 apiService 直接回傳 FriendListResponse (非 Response 封裝)
|
||||||
Result.success(response.friends)
|
// 則直接取用,並處理 null
|
||||||
|
Result.success(response.friends ?: emptyList())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// 處理連線超時、404、500 等各種錯誤
|
// 這裡可以根據 e 的型別做額外處理,例如 HttpException 或 IOException
|
||||||
Result.failure(e)
|
Result.failure(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -23,8 +24,8 @@ class FriendsRepository @Inject constructor(
|
||||||
suspend fun getPendingRequests(): Result<List<PendingFriendApiModel>> {
|
suspend fun getPendingRequests(): Result<List<PendingFriendApiModel>> {
|
||||||
return try {
|
return try {
|
||||||
val response = apiService.getFriendsPending()
|
val response = apiService.getFriendsPending()
|
||||||
// 這裡回傳 API Model,轉換邏輯可以放在 ViewModel
|
// 這裡同樣建議處理可能為 null 的情況
|
||||||
Result.success(response.pendingRequests)
|
Result.success(response.pendingRequests ?: emptyList())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Result.failure(e)
|
Result.failure(e)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,44 +29,27 @@ class ContactListViewModel @Inject constructor(
|
||||||
private val _uiState = MutableStateFlow(ContactUiState())
|
private val _uiState = MutableStateFlow(ContactUiState())
|
||||||
val uiState: StateFlow<ContactUiState> = _uiState.asStateFlow()
|
val uiState: StateFlow<ContactUiState> = _uiState.asStateFlow()
|
||||||
|
|
||||||
// 🚩 建議刪除獨立的 _friends,全部統一使用 _uiState
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
refreshAll()
|
refreshAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refreshAll() {
|
fun refreshAll() {
|
||||||
fetchFriends()
|
|
||||||
fetchPendingRequests()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fetchFriends() {
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
_uiState.update { it.copy(isLoading = true) }
|
// 1. 開始 Loading 並清除舊錯誤
|
||||||
|
_uiState.update { it.copy(isLoading = true, error = null) }
|
||||||
|
|
||||||
val result = repository.getFriendList()
|
// 2. 使用 zip 或單獨 fetch,這裡示範簡單的循序或並行處理
|
||||||
|
val friendsResult = repository.getFriendList()
|
||||||
|
val pendingResult = repository.getPendingRequests()
|
||||||
|
|
||||||
result.onSuccess { list ->
|
// 3. 統一處理結果
|
||||||
Log.d("DEBUG_API", "好友列表抓取成功,數量: ${list.size}")
|
_uiState.update { state ->
|
||||||
_uiState.update { it.copy(isLoading = false, friends = list) }
|
state.copy(
|
||||||
}.onFailure { error ->
|
isLoading = false,
|
||||||
Log.e("DEBUG_API", "好友列表抓取失敗: ${error.message}")
|
friends = friendsResult.getOrDefault(state.friends),
|
||||||
_uiState.update { it.copy(isLoading = false, error = error.message) }
|
pendingRequests = pendingResult.getOrDefault(state.pendingRequests),
|
||||||
}
|
error = (friendsResult.exceptionOrNull() ?: pendingResult.exceptionOrNull())?.message
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
fun fetchPendingRequests() {
|
|
||||||
viewModelScope.launch {
|
|
||||||
val result = repository.getPendingRequests()
|
|
||||||
|
|
||||||
result.onSuccess { requests ->
|
|
||||||
Log.d("DEBUG_API", "待處理請求抓取成功,數量: ${requests.size}")
|
|
||||||
_uiState.update { it.copy(pendingRequests = requests) }
|
|
||||||
}.onFailure { error ->
|
|
||||||
// 🚩 這裡一定要加 Log,否則 API 壞了你不知道
|
|
||||||
Log.e("DEBUG_API", "待處理請求抓取失敗: ${error.message}")
|
|
||||||
_uiState.update { it.copy(error = error.message) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue