auth to server-V97
This commit is contained in:
parent
54ba82ebeb
commit
51a4d3512c
3 changed files with 36 additions and 15 deletions
|
|
@ -251,7 +251,7 @@ fun AddAccountScreen(
|
||||||
)
|
)
|
||||||
|
|
||||||
) {
|
) {
|
||||||
Text( text = "Login")
|
Text( text = "Add")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue