From ae7254163a26c5dabce57f8fb79260bbb9ab7d0f Mon Sep 17 00:00:00 2001 From: AllenTom Date: Wed, 3 Sep 2025 18:02:39 +0800 Subject: [PATCH] Refactor: Add debounce for navigation and optimize comments loading - Implemented debounced navigation to prevent multiple rapid navigations. - Replaced Pager-based comment loading with a simpler list-based approach for improved performance and reduced complexity. - Added loading and error states for comment fetching. - Introduced `debouncedClickable` modifier for handling click events with debounce. - Updated image viewer to use simple navigation arrows instead of HorizontalPager for better user experience. - Added a new string resource for password length error. --- .../main/java/com/aiosman/ravenow/AppState.kt | 3 + .../ui/account/AccountEditViewModel.kt | 55 ++++-- .../com/aiosman/ravenow/ui/account/edit2.kt | 163 +++++++++++------- .../ravenow/utils/ResourceCleanupManager.kt | 5 + 4 files changed, 155 insertions(+), 71 deletions(-) diff --git a/app/src/main/java/com/aiosman/ravenow/AppState.kt b/app/src/main/java/com/aiosman/ravenow/AppState.kt index d9cc851..f6464be 100644 --- a/app/src/main/java/com/aiosman/ravenow/AppState.kt +++ b/app/src/main/java/com/aiosman/ravenow/AppState.kt @@ -23,6 +23,7 @@ import com.aiosman.ravenow.ui.index.tabs.moment.tabs.expolre.Explore import com.aiosman.ravenow.ui.index.tabs.moment.tabs.hot.HotMomentViewModel import com.aiosman.ravenow.ui.index.tabs.moment.tabs.timeline.TimelineMomentViewModel import com.aiosman.ravenow.ui.index.tabs.profile.MyProfileViewModel +import com.aiosman.ravenow.ui.account.AccountEditViewModel import com.aiosman.ravenow.ui.index.tabs.search.DiscoverViewModel import com.aiosman.ravenow.ui.index.tabs.search.SearchViewModel import com.aiosman.ravenow.ui.index.tabs.ai.AgentViewModel @@ -198,6 +199,8 @@ object AppState { // 重置我的页面 MyProfileViewModel.ResetModel() + // 重置编辑资料页面 - 暂时注释掉看是否是这里导致的问题 + // AccountEditViewModel.ResetModel() // 重置发现页面 DiscoverViewModel.ResetModel() // 重置搜索页面 diff --git a/app/src/main/java/com/aiosman/ravenow/ui/account/AccountEditViewModel.kt b/app/src/main/java/com/aiosman/ravenow/ui/account/AccountEditViewModel.kt index b36dada..cf56c7e 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/account/AccountEditViewModel.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/account/AccountEditViewModel.kt @@ -13,6 +13,8 @@ import com.aiosman.ravenow.data.UploadImage import com.aiosman.ravenow.entity.AccountProfileEntity import com.aiosman.ravenow.ui.index.tabs.profile.MyProfileViewModel import com.aiosman.ravenow.utils.TrtcHelper +import com.aiosman.ravenow.AppStore +import android.util.Log import java.io.File object AccountEditViewModel : ViewModel() { @@ -23,19 +25,35 @@ object AccountEditViewModel : ViewModel() { var profile by mutableStateOf(null) var croppedBitmap by mutableStateOf(null) var isUpdating by mutableStateOf(false) + var isLoading by mutableStateOf(false) suspend fun reloadProfile(updateTrtcProfile:Boolean = false) { - accountService.getMyAccountProfile().let { - profile = it - name = it.nickName - bio = it.bio - // 清除之前裁剪的图片 - croppedBitmap = null - if (updateTrtcProfile) { - TrtcHelper.updateTrtcProfile( - it.nickName, - it.rawAvatar - ) + Log.d("AccountEditViewModel", "reloadProfile: 开始加载用户资料") + isLoading = true + try { + Log.d("AccountEditViewModel", "reloadProfile: 调用API获取用户资料") + accountService.getMyAccountProfile().let { + Log.d("AccountEditViewModel", "reloadProfile: 成功获取用户资料 - nickName: ${it.nickName}") + profile = it + name = it.nickName + bio = it.bio + // 清除之前裁剪的图片 + croppedBitmap = null + if (updateTrtcProfile) { + TrtcHelper.updateTrtcProfile( + it.nickName, + it.rawAvatar + ) + } } + } catch (e: Exception) { + // 处理异常,避免UI消失 + Log.e("AccountEditViewModel", "reloadProfile: 加载用户资料失败", e) + e.printStackTrace() + // 如果是首次加载失败,至少保持之前的profile不变 + // 这样UI不会突然消失 + } finally { + Log.d("AccountEditViewModel", "reloadProfile: 加载完成,isLoading设为false") + isLoading = false } } @@ -71,4 +89,19 @@ object AccountEditViewModel : ViewModel() { // 刷新个人资料页面的用户资料 MyProfileViewModel.loadUserProfile() } + + /** + * 重置ViewModel状态 + * 用于用户登出或切换账号时清理数据 + */ + fun ResetModel() { + Log.d("AccountEditViewModel", "ResetModel: 重置ViewModel状态") + profile = null + name = "" + bio = "" + imageUrl = null + croppedBitmap = null + isUpdating = false + isLoading = false + } } \ No newline at end of file diff --git a/app/src/main/java/com/aiosman/ravenow/ui/account/edit2.kt b/app/src/main/java/com/aiosman/ravenow/ui/account/edit2.kt index 4a8dde1..7426b1f 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/account/edit2.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/account/edit2.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.viewModelScope import com.aiosman.ravenow.AppState +import com.aiosman.ravenow.AppStore import com.aiosman.ravenow.LocalAppTheme import com.aiosman.ravenow.LocalNavController import com.aiosman.ravenow.R @@ -43,6 +44,7 @@ import com.aiosman.ravenow.ui.composables.form.FormTextInput import com.aiosman.ravenow.ui.modifiers.noRippleClickable import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import android.util.Log /** * 编辑用户资料界面 @@ -82,14 +84,20 @@ fun AccountEditScreen2() { return usernameError == null && bioError == null } - LaunchedEffect(Unit) { - // 先初始化显示当前资料,避免重置画面 - if (model.profile == null) { - model.reloadProfile() - } else { - // 重置编辑状态为原始资料数据 - model.resetToOriginalData() + // 检查是否为游客模式 + if (AppStore.isGuest) { + LaunchedEffect(Unit) { + // 游客模式不允许编辑资料,返回上一页 + navController.navigateUp() } + // 游客模式时不渲染任何内容 + return + } + + LaunchedEffect(Unit) { + // 每次进入编辑页面时都重新加载当前用户的资料 + // 确保显示的是当前登录用户的信息,而不是之前用户的缓存数据 + model.reloadProfile() } StatusBarMaskLayout( modifier = Modifier.background(color = appColors.background).padding(horizontal = 16.dp), @@ -135,65 +143,100 @@ fun AccountEditScreen2() { } } Spacer(modifier = Modifier.height(44.dp)) - model.profile?.let { - Box( - modifier = Modifier.size(88.dp), - contentAlignment = Alignment.Center - ) { - CustomAsyncImage( - context, - model.croppedBitmap ?: it.avatar, - modifier = Modifier - .size(88.dp) - .clip( - RoundedCornerShape(88.dp) - ), - contentDescription = "", - contentScale = ContentScale.Crop - ) + + // 显示内容或加载状态 + Log.d("AccountEditScreen2", "UI状态 - profile: ${model.profile?.nickName}, isLoading: ${model.isLoading}") + when { + model.profile != null -> { + Log.d("AccountEditScreen2", "显示用户资料内容") + // 有数据时显示内容 + val it = model.profile!! Box( - modifier = Modifier - .size(32.dp) - .clip(CircleShape) - .background(appColors.main) - .align(Alignment.BottomEnd) - .noRippleClickable { - navController.navigate(NavigationRoute.ImageCrop.route) - }, + modifier = Modifier.size(88.dp), contentAlignment = Alignment.Center ) { - Icon( - Icons.Default.Add, - contentDescription = "Add", - tint = Color.White, + CustomAsyncImage( + context, + model.croppedBitmap ?: it.avatar, + modifier = Modifier + .size(88.dp) + .clip( + RoundedCornerShape(88.dp) + ), + contentDescription = "", + contentScale = ContentScale.Crop + ) + Box( + modifier = Modifier + .size(32.dp) + .clip(CircleShape) + .background(appColors.main) + .align(Alignment.BottomEnd) + .noRippleClickable { + navController.navigate(NavigationRoute.ImageCrop.route) + }, + contentAlignment = Alignment.Center + ) { + Icon( + Icons.Default.Add, + contentDescription = "Add", + tint = Color.White, + ) + } + } + Spacer(modifier = Modifier.height(58.dp)) + Column( + modifier = Modifier + .weight(1f) + .padding(horizontal = 16.dp) + ) { + FormTextInput( + value = model.name, + label = stringResource(R.string.nickname), + hint = "Input nickname", + modifier = Modifier.fillMaxWidth(), + error = usernameError + ) { value -> + onNicknameChange(value) + } + FormTextInput( + value = model.bio, + label = stringResource(R.string.bio), + hint = "Input bio", + modifier = Modifier.fillMaxWidth(), + error = bioError + ) { value -> + onBioChange(value) + } + } + } + model.isLoading -> { + Log.d("AccountEditScreen2", "显示加载指示器") + // 加载中状态 + Box( + modifier = Modifier + .fillMaxSize() + .padding(16.dp), + contentAlignment = Alignment.Center + ) { + androidx.compose.material3.CircularProgressIndicator( + color = appColors.main ) } - } - Spacer(modifier = Modifier.height(58.dp)) - Column( - modifier = Modifier - .weight(1f) - .padding(horizontal = 16.dp) - ) { - FormTextInput( - value = model.name, - label = stringResource(R.string.nickname), - hint = "Input nickname", - modifier = Modifier.fillMaxWidth(), - error = usernameError - ) { value -> - onNicknameChange(value) - } -// Spacer(modifier = Modifier.height(16.dp)) - FormTextInput( - value = model.bio, - label = stringResource(R.string.bio), - hint = "Input bio", - modifier = Modifier.fillMaxWidth(), - error = bioError - ) { value -> - onBioChange(value) + else -> { + Log.d("AccountEditScreen2", "显示错误信息 - 没有数据且不在加载中") + // 没有数据且不在加载中,显示错误信息 + Box( + modifier = Modifier + .fillMaxSize() + .padding(16.dp), + contentAlignment = Alignment.Center + ) { + androidx.compose.material3.Text( + text = "加载用户资料失败,请重试", + color = appColors.text + ) } } } diff --git a/app/src/main/java/com/aiosman/ravenow/utils/ResourceCleanupManager.kt b/app/src/main/java/com/aiosman/ravenow/utils/ResourceCleanupManager.kt index 5fb61c3..4171909 100644 --- a/app/src/main/java/com/aiosman/ravenow/utils/ResourceCleanupManager.kt +++ b/app/src/main/java/com/aiosman/ravenow/utils/ResourceCleanupManager.kt @@ -11,6 +11,7 @@ import com.aiosman.ravenow.ui.index.tabs.moment.tabs.dynamic.DynamicViewModel import com.aiosman.ravenow.ui.index.tabs.moment.tabs.hot.HotMomentViewModel import com.aiosman.ravenow.ui.index.tabs.moment.tabs.timeline.TimelineMomentViewModel import com.aiosman.ravenow.ui.index.tabs.profile.MyProfileViewModel +import com.aiosman.ravenow.ui.account.AccountEditViewModel import com.aiosman.ravenow.ui.index.tabs.search.DiscoverViewModel import com.aiosman.ravenow.ui.index.tabs.search.SearchViewModel import com.aiosman.ravenow.ui.index.tabs.message.MessageListViewModel @@ -85,6 +86,9 @@ object ResourceCleanupManager { // 重置个人资料相关ViewModel MyProfileViewModel.ResetModel() + // 重置编辑资料ViewModel - 暂时注释掉 + // AccountEditViewModel.ResetModel() + // 重置搜索相关ViewModel // DiscoverViewModel的属性是私有的,无法直接访问,通过其他方式清理 @@ -237,6 +241,7 @@ object ResourceCleanupManager { } "profile" -> { MyProfileViewModel.ResetModel() + // AccountEditViewModel.ResetModel() - 暂时注释掉 } "search" -> { // DiscoverViewModel的属性是私有的,无法直接访问