auth to server-V97

This commit is contained in:
Eric85710 2026-05-14 14:20:25 +08:00
parent 54ba82ebeb
commit 51a4d3512c
3 changed files with 36 additions and 15 deletions

View file

@ -251,7 +251,7 @@ fun AddAccountScreen(
) )
) { ) {
Text( text = "Login") Text( text = "Add")
} }
} }

View file

@ -37,21 +37,32 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
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.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import coil.compose.AsyncImage
import com.example.login_v3.R
import com.example.login_v3.auth.login.AuthViewModel import com.example.login_v3.auth.login.AuthViewModel
import com.example.login_v3.data.api.api_class.UserProfile
import com.example.login_v3.data.api.api_class.fullAvatarUrl
import com.example.login_v3.home.setting.setting_detail_page.viewmodel.PersonalProfileViewModel
import com.example.login_v3.home.setting.setting_detail_page.viewmodel.ProfileUiState
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun AccountSwitchScreen( fun AccountSwitchScreen(
viewModel: AuthViewModel = hiltViewModel<AuthViewModel>(), viewModel: AuthViewModel = hiltViewModel(),
profileViewModel: PersonalProfileViewModel = hiltViewModel(),
onAddAccountClick: () -> Unit, onAddAccountClick: () -> Unit,
onBack: () -> Unit onBack: () -> Unit
) { ) {
// 觀察 ViewModel 中的狀態 // 觀察 ViewModel 中的狀態
val allUsers by viewModel.allUserIds.collectAsState() val allUsers by viewModel.allUserIds.collectAsState()
val currentUserId by viewModel.currentUserId.collectAsState() val currentUserId by viewModel.currentUserId.collectAsState()
val uiState by profileViewModel.uiState.collectAsState()
Scaffold( Scaffold(
topBar = { topBar = {
@ -74,7 +85,7 @@ fun AccountSwitchScreen(
Text( Text(
text = "已登入的帳號", text = "已登入的帳號",
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.primary color = MaterialTheme.colorScheme.onBackground
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
@ -87,8 +98,10 @@ fun AccountSwitchScreen(
// 這裡加上明確的 items(items = ...) // 這裡加上明確的 items(items = ...)
items(items = allUsers.toList()) { userId -> items(items = allUsers.toList()) { userId ->
val isCurrent = (userId == currentUserId) // 這裡解決 == 類型問題 val isCurrent = (userId == currentUserId) // 這裡解決 == 類型問題
val currentProfile = (uiState as? ProfileUiState.Success)?.profile
AccountItem( AccountItem(
profile = currentProfile,
userId = userId, userId = userId,
isCurrent = isCurrent, isCurrent = isCurrent,
onSelect = { viewModel.switchAccount(userId) }, onSelect = { viewModel.switchAccount(userId) },
@ -115,6 +128,7 @@ fun AccountSwitchScreen(
@Composable @Composable
fun AccountItem( fun AccountItem(
profile: UserProfile?,
userId: String, userId: String,
isCurrent: Boolean, isCurrent: Boolean,
onSelect: () -> Unit, onSelect: () -> Unit,
@ -140,16 +154,23 @@ fun AccountItem(
horizontalArrangement = Arrangement.SpaceBetween horizontalArrangement = Arrangement.SpaceBetween
) { ) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
// 模擬頭像 // 頭像
Surface( AsyncImage(
shape = CircleShape, // 使用 ?. 確保 profile 不為空時才讀取屬性,若為空則傳回 null
color = MaterialTheme.colorScheme.secondary, model = profile?.fullAvatarUrl,
modifier = Modifier.size(40.dp)
) { // contentDescription 也要處理,可以用 ?: 提供預設字串
Box(contentAlignment = Alignment.Center) { contentDescription = "Avatar of ${profile?.display_name ?: "Unknown"}",
Text(userId.take(1).uppercase(), color = Color.White)
} modifier = Modifier
} .size(40.dp)
.clip(CircleShape),
contentScale = ContentScale.Crop,
// 當 model 為 null 或載入失敗時,會顯示這個預設圖
error = painterResource(R.drawable.avatar_v1),
placeholder = painterResource(R.drawable.avatar_v1)
)
Spacer(modifier = Modifier.width(12.dp)) Spacer(modifier = Modifier.width(12.dp))

View file

@ -118,13 +118,13 @@ fun Loaded_setting_profile_page(
val context = LocalContext.current // 務必獲取 Context,uploadAvatar 需要它來解析 Uri val context = LocalContext.current // 務必獲取 Context,uploadAvatar 需要它來解析 Uri
//avatar //avatar
val avatarLauncher = rememberLauncherForActivityResult( val avatarLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.PickVisualMedia() // 這裡改掉 contract = ActivityResultContracts.PickVisualMedia()
) { uri: Uri? -> ) { uri: Uri? ->
uri?.let { viewModel.uploadAvatar(context, it) } uri?.let { viewModel.uploadAvatar(context, it) }
} }
//banner //banner
val bannerLauncher = rememberLauncherForActivityResult( val bannerLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.PickVisualMedia() // 這裡改掉 contract = ActivityResultContracts.PickVisualMedia()
) { uri: Uri? -> ) { uri: Uri? ->
uri?.let { viewModel.uploadBanner(context, it) } uri?.let { viewModel.uploadBanner(context, it) }
} }