fix #9 修正多次点击的白屏,添加修改用户资料防抖

This commit is contained in:
2024-11-03 12:48:37 +08:00
parent d5e210b080
commit 7152bfd9c1
12 changed files with 53 additions and 17 deletions

View File

@@ -21,6 +21,7 @@ object AccountEditViewModel : ViewModel() {
val accountService: AccountService = AccountServiceImpl() val accountService: AccountService = AccountServiceImpl()
var profile by mutableStateOf<AccountProfileEntity?>(null) var profile by mutableStateOf<AccountProfileEntity?>(null)
var croppedBitmap by mutableStateOf<Bitmap?>(null) var croppedBitmap by mutableStateOf<Bitmap?>(null)
var isUpdating by mutableStateOf(false)
suspend fun reloadProfile() { suspend fun reloadProfile() {
accountService.getMyAccountProfile().let { accountService.getMyAccountProfile().let {
profile = it profile = it
@@ -30,7 +31,6 @@ object AccountEditViewModel : ViewModel() {
} }
suspend fun updateUserProfile(context: Context) { suspend fun updateUserProfile(context: Context) {
val newAvatar = croppedBitmap?.let { val newAvatar = croppedBitmap?.let {
val file = File(context.cacheDir, "avatar.jpg") val file = File(context.cacheDir, "avatar.jpg")
it.compress(Bitmap.CompressFormat.JPEG, 100, file.outputStream()) it.compress(Bitmap.CompressFormat.JPEG, 100, file.outputStream())
@@ -47,6 +47,5 @@ object AccountEditViewModel : ViewModel() {
reloadProfile() reloadProfile()
// 刷新个人资料页面的用户资料 // 刷新个人资料页面的用户资料
MyProfileViewModel.loadUserProfile() MyProfileViewModel.loadUserProfile()
} }
} }

View File

@@ -194,7 +194,7 @@ fun ResetPasswordScreen() {
text = stringResource(R.string.back_upper), text = stringResource(R.string.back_upper),
contentPadding = PaddingValues(0.dp), contentPadding = PaddingValues(0.dp),
) { ) {
navController.popBackStack() navController.navigateUp()
} }
} }

View File

@@ -140,7 +140,7 @@ fun ChangePasswordScreen() {
try { try {
viewModel.changePassword(currentPassword, newPassword) viewModel.changePassword(currentPassword, newPassword)
navController.popBackStack() navController.navigateUp()
} catch (e: ServiceException) { } catch (e: ServiceException) {
when (e.errorType) { when (e.errorType) {
ErrorCode.IncorrectOldPassword -> ErrorCode.IncorrectOldPassword ->

View File

@@ -39,6 +39,7 @@ import com.aiosman.riderpro.ui.composables.CustomAsyncImage
import com.aiosman.riderpro.ui.composables.StatusBarSpacer import com.aiosman.riderpro.ui.composables.StatusBarSpacer
import com.aiosman.riderpro.ui.composables.form.FormTextInput import com.aiosman.riderpro.ui.composables.form.FormTextInput
import com.aiosman.riderpro.ui.modifiers.noRippleClickable import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
/** /**
@@ -60,6 +61,7 @@ fun AccountEditScreen2() {
else -> null else -> null
} }
} }
val appColors = LocalAppTheme.current val appColors = LocalAppTheme.current
fun onBioChange(value: String) { fun onBioChange(value: String) {
@@ -75,7 +77,7 @@ fun AccountEditScreen2() {
} }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
if (model.profile == null){ if (model.profile == null) {
model.reloadProfile() model.reloadProfile()
} }
@@ -99,14 +101,22 @@ fun AccountEditScreen2() {
modifier = Modifier modifier = Modifier
.size(24.dp) .size(24.dp)
.noRippleClickable { .noRippleClickable {
model.viewModelScope.launch {
model.updateUserProfile(context) if (validate() && !model.isUpdating) {
navController.popBackStack() model.viewModelScope.launch {
model.isUpdating = true
model.updateUserProfile(context)
model.viewModelScope.launch(Dispatchers.Main) {
navController.navigateUp()
model.isUpdating = false
}
}
} }
}, },
imageVector = Icons.Default.Check, imageVector = Icons.Default.Check,
contentDescription = "保存", contentDescription = "保存",
tint = if (validate()) Color.Black else Color.Gray tint = if (validate() && !model.isUpdating) Color.Black else Color.Gray
) )
} }
} }

View File

@@ -176,7 +176,7 @@ fun ChatScreen(userId: String) {
modifier = Modifier modifier = Modifier
.size(28.dp) .size(28.dp)
.noRippleClickable { .noRippleClickable {
navController.popBackStack() navController.navigateUp()
}, },
contentDescription = null, contentDescription = null,
colorFilter = ColorFilter.tint( colorFilter = ColorFilter.tint(

View File

@@ -81,7 +81,7 @@ fun NoticeScreenHeader(
indication = null, indication = null,
interactionSource = remember { MutableInteractionSource() } interactionSource = remember { MutableInteractionSource() }
) { ) {
nav.popBackStack() nav.navigateUp()
}, },
colorFilter = ColorFilter.tint(AppColors.text) colorFilter = ColorFilter.tint(AppColors.text)
) )

View File

@@ -115,6 +115,7 @@ fun ImageCropScreen() {
AccountEditViewModel.viewModelScope.launch { AccountEditViewModel.viewModelScope.launch {
AccountEditViewModel.updateUserProfile(context) AccountEditViewModel.updateUserProfile(context)
navController.popBackStack() navController.popBackStack()
} }
} }

View File

@@ -94,7 +94,7 @@ fun ImageViewer() {
.zoomable( .zoomable(
zoomState = zoomState, zoomState = zoomState,
onTap = { onTap = {
navController.popBackStack() navController.navigateUp()
} }
) )
, ,

View File

@@ -131,7 +131,7 @@ fun SearchScreen() {
stringResource(R.string.cancel), stringResource(R.string.cancel),
fontSize = 16.sp, fontSize = 16.sp,
modifier = Modifier.noRippleClickable { modifier = Modifier.noRippleClickable {
navController.popBackStack() navController.navigateUp()
}, },
color = AppColors.text color = AppColors.text
) )

View File

@@ -229,7 +229,7 @@ fun SignupScreen() {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.noRippleClickable { modifier = Modifier.noRippleClickable {
navController.popBackStack() navController.navigateUp()
} }
) { ) {
Image( Image(

View File

@@ -3,12 +3,38 @@ package com.aiosman.riderpro.ui.modifiers
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.composed import androidx.compose.ui.composed
import com.aiosman.riderpro.LocalNavController
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
inline fun Modifier.noRippleClickable(crossinline onClick: () -> Unit): Modifier = composed { inline fun Modifier.noRippleClickable(crossinline onClick: () -> Unit): Modifier = composed {
this.clickable(indication = null, this.clickable(indication = null,
interactionSource = remember { MutableInteractionSource() }) { interactionSource = remember { MutableInteractionSource() }) {
onClick() onClick()
} }
} }
inline fun Modifier.noRippleClickable(
debounceTime: Long = 300L,
crossinline onClick: () -> Unit
): Modifier = composed {
var job: Job? = null
val scope = rememberCoroutineScope()
this.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
) {
job?.cancel()
job = scope.launch {
delay(debounceTime)
onClick()
}
}
}

View File

@@ -331,7 +331,7 @@ fun PostScreen(
}, },
onDeleteClick = { onDeleteClick = {
viewModel.deleteMoment { viewModel.deleteMoment {
navController.popBackStack() navController.navigateUp()
} }
} }
) )
@@ -682,7 +682,7 @@ fun Header(
contentDescription = "Back", contentDescription = "Back",
modifier = Modifier modifier = Modifier
.noRippleClickable { .noRippleClickable {
navController.popBackStack() navController.navigateUp()
} }
.size(32.dp), .size(32.dp),
colorFilter = ColorFilter.tint(AppColors.text) colorFilter = ColorFilter.tint(AppColors.text)