auth to server-V76
This commit is contained in:
parent
d0e978416e
commit
a35d4412f3
4 changed files with 64 additions and 2 deletions
|
|
@ -66,6 +66,7 @@ data class PendingFriendApiModel(
|
||||||
val createdAt: String?
|
val createdAt: String?
|
||||||
)
|
)
|
||||||
//add friends
|
//add friends
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
data class AddFriendRequest(
|
data class AddFriendRequest(
|
||||||
@Json(name = "friend_id") val friendId: String
|
@Json(name = "friend_id") val friendId: String
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ class FriendsRepository @Inject constructor(
|
||||||
Result.failure(e)
|
Result.failure(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//add friends
|
//add friends
|
||||||
suspend fun sendFriendRequest(friendId: String): Result<Unit> {
|
suspend fun sendFriendRequest(friendId: String): Result<Unit> {
|
||||||
return safeApiCall {
|
return safeApiCall {
|
||||||
|
|
|
||||||
|
|
@ -10,23 +10,29 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Check
|
import androidx.compose.material.icons.filled.Check
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.ListItem
|
import androidx.compose.material3.ListItem
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
|
@ -72,6 +78,14 @@ fun Message_contact_list(
|
||||||
// 頂部間距
|
// 頂部間距
|
||||||
item { Spacer(modifier = Modifier.height(60.dp)) }
|
item { Spacer(modifier = Modifier.height(60.dp)) }
|
||||||
|
|
||||||
|
//add friends
|
||||||
|
item {
|
||||||
|
AddUserBar(
|
||||||
|
isLoading = uiState.isLoading,
|
||||||
|
onSendRequest = { id -> contactListViewModel.sendFriendRequest(id) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// --- 區塊一:待處理好友 (只有在有資料時才顯示) ---
|
// --- 區塊一:待處理好友 (只有在有資料時才顯示) ---
|
||||||
if (uiState.pendingRequests.isNotEmpty()) {
|
if (uiState.pendingRequests.isNotEmpty()) {
|
||||||
item {
|
item {
|
||||||
|
|
@ -130,6 +144,7 @@ fun Message_contact_list(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//friends list
|
||||||
@Composable
|
@Composable
|
||||||
fun FriendRow(friend: Friend) {
|
fun FriendRow(friend: Friend) {
|
||||||
ListItem(
|
ListItem(
|
||||||
|
|
@ -197,3 +212,50 @@ fun PendingFriendRow(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add friends
|
||||||
|
@Composable
|
||||||
|
fun AddUserBar(
|
||||||
|
isLoading: Boolean,
|
||||||
|
onSendRequest: (String) -> Unit
|
||||||
|
) {
|
||||||
|
var userIdText by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(8.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
OutlinedTextField(
|
||||||
|
value = userIdText,
|
||||||
|
onValueChange = { userIdText = it },
|
||||||
|
label = { Text("輸入好友 ID") },
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
singleLine = true,
|
||||||
|
enabled = !isLoading
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
if (userIdText.isNotBlank()) {
|
||||||
|
onSendRequest(userIdText)
|
||||||
|
userIdText = "" // 發送後清空輸入框
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enabled = !isLoading && userIdText.isNotBlank()
|
||||||
|
) {
|
||||||
|
if (isLoading) {
|
||||||
|
CircularProgressIndicator(
|
||||||
|
modifier = Modifier.size(16.dp),
|
||||||
|
color = MaterialTheme.colorScheme.onPrimary,
|
||||||
|
strokeWidth = 2.dp
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Text("新增")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -68,7 +68,6 @@ class ContactListViewModel @Inject constructor(
|
||||||
// 關鍵:重新整理資料,讓 UI 自動更新
|
// 關鍵:重新整理資料,讓 UI 自動更新
|
||||||
refreshAll()
|
refreshAll()
|
||||||
}.onFailure { error ->
|
}.onFailure { error ->
|
||||||
Log.e("DEBUG_API", "接受請求錯誤: ${error.message}")
|
|
||||||
_uiState.update { it.copy(error = "無法接受請求:${error.message}") }
|
_uiState.update { it.copy(error = "無法接受請求:${error.message}") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +82,6 @@ class ContactListViewModel @Inject constructor(
|
||||||
result.onSuccess {
|
result.onSuccess {
|
||||||
refreshAll() // 刷新列表,該筆請求會消失
|
refreshAll() // 刷新列表,該筆請求會消失
|
||||||
}.onFailure { error ->
|
}.onFailure { error ->
|
||||||
Log.e("DEBUG_API", "拒絕請求錯誤: ${error.message}")
|
|
||||||
_uiState.update { it.copy(error = "無法拒絕請求:${error.message}") }
|
_uiState.update { it.copy(error = "無法拒絕請求:${error.message}") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue