fix #9 修正多次点击的白屏,添加修改用户资料防抖
This commit is contained in:
@@ -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()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 ->
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ fun ImageCropScreen() {
|
|||||||
AccountEditViewModel.viewModelScope.launch {
|
AccountEditViewModel.viewModelScope.launch {
|
||||||
AccountEditViewModel.updateUserProfile(context)
|
AccountEditViewModel.updateUserProfile(context)
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ fun ImageViewer() {
|
|||||||
.zoomable(
|
.zoomable(
|
||||||
zoomState = zoomState,
|
zoomState = zoomState,
|
||||||
onTap = {
|
onTap = {
|
||||||
navController.popBackStack()
|
navController.navigateUp()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
,
|
,
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user