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.
This commit is contained in:
2025-09-03 18:02:39 +08:00
parent d703b5ae05
commit ae7254163a
4 changed files with 155 additions and 71 deletions

View File

@@ -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.hot.HotMomentViewModel
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.timeline.TimelineMomentViewModel 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.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.DiscoverViewModel
import com.aiosman.ravenow.ui.index.tabs.search.SearchViewModel import com.aiosman.ravenow.ui.index.tabs.search.SearchViewModel
import com.aiosman.ravenow.ui.index.tabs.ai.AgentViewModel import com.aiosman.ravenow.ui.index.tabs.ai.AgentViewModel
@@ -198,6 +199,8 @@ object AppState {
// 重置我的页面 // 重置我的页面
MyProfileViewModel.ResetModel() MyProfileViewModel.ResetModel()
// 重置编辑资料页面 - 暂时注释掉看是否是这里导致的问题
// AccountEditViewModel.ResetModel()
// 重置发现页面 // 重置发现页面
DiscoverViewModel.ResetModel() DiscoverViewModel.ResetModel()
// 重置搜索页面 // 重置搜索页面

View File

@@ -13,6 +13,8 @@ import com.aiosman.ravenow.data.UploadImage
import com.aiosman.ravenow.entity.AccountProfileEntity import com.aiosman.ravenow.entity.AccountProfileEntity
import com.aiosman.ravenow.ui.index.tabs.profile.MyProfileViewModel import com.aiosman.ravenow.ui.index.tabs.profile.MyProfileViewModel
import com.aiosman.ravenow.utils.TrtcHelper import com.aiosman.ravenow.utils.TrtcHelper
import com.aiosman.ravenow.AppStore
import android.util.Log
import java.io.File import java.io.File
object AccountEditViewModel : ViewModel() { object AccountEditViewModel : ViewModel() {
@@ -23,8 +25,14 @@ object AccountEditViewModel : ViewModel() {
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) var isUpdating by mutableStateOf(false)
var isLoading by mutableStateOf(false)
suspend fun reloadProfile(updateTrtcProfile:Boolean = false) { suspend fun reloadProfile(updateTrtcProfile:Boolean = false) {
Log.d("AccountEditViewModel", "reloadProfile: 开始加载用户资料")
isLoading = true
try {
Log.d("AccountEditViewModel", "reloadProfile: 调用API获取用户资料")
accountService.getMyAccountProfile().let { accountService.getMyAccountProfile().let {
Log.d("AccountEditViewModel", "reloadProfile: 成功获取用户资料 - nickName: ${it.nickName}")
profile = it profile = it
name = it.nickName name = it.nickName
bio = it.bio bio = it.bio
@@ -37,6 +45,16 @@ object AccountEditViewModel : ViewModel() {
) )
} }
} }
} catch (e: Exception) {
// 处理异常避免UI消失
Log.e("AccountEditViewModel", "reloadProfile: 加载用户资料失败", e)
e.printStackTrace()
// 如果是首次加载失败至少保持之前的profile不变
// 这样UI不会突然消失
} finally {
Log.d("AccountEditViewModel", "reloadProfile: 加载完成isLoading设为false")
isLoading = false
}
} }
fun resetToOriginalData() { fun resetToOriginalData() {
@@ -71,4 +89,19 @@ object AccountEditViewModel : ViewModel() {
// 刷新个人资料页面的用户资料 // 刷新个人资料页面的用户资料
MyProfileViewModel.loadUserProfile() MyProfileViewModel.loadUserProfile()
} }
/**
* 重置ViewModel状态
* 用于用户登出或切换账号时清理数据
*/
fun ResetModel() {
Log.d("AccountEditViewModel", "ResetModel: 重置ViewModel状态")
profile = null
name = ""
bio = ""
imageUrl = null
croppedBitmap = null
isUpdating = false
isLoading = false
}
} }

View File

@@ -31,6 +31,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.aiosman.ravenow.AppState import com.aiosman.ravenow.AppState
import com.aiosman.ravenow.AppStore
import com.aiosman.ravenow.LocalAppTheme import com.aiosman.ravenow.LocalAppTheme
import com.aiosman.ravenow.LocalNavController import com.aiosman.ravenow.LocalNavController
import com.aiosman.ravenow.R 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 com.aiosman.ravenow.ui.modifiers.noRippleClickable
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import android.util.Log
/** /**
* 编辑用户资料界面 * 编辑用户资料界面
@@ -82,14 +84,20 @@ fun AccountEditScreen2() {
return usernameError == null && bioError == null return usernameError == null && bioError == null
} }
// 检查是否为游客模式
if (AppStore.isGuest) {
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
// 先初始化显示当前资料,避免重置画面 // 游客模式不允许编辑资料,返回上一页
if (model.profile == null) { navController.navigateUp()
model.reloadProfile()
} else {
// 重置编辑状态为原始资料数据
model.resetToOriginalData()
} }
// 游客模式时不渲染任何内容
return
}
LaunchedEffect(Unit) {
// 每次进入编辑页面时都重新加载当前用户的资料
// 确保显示的是当前登录用户的信息,而不是之前用户的缓存数据
model.reloadProfile()
} }
StatusBarMaskLayout( StatusBarMaskLayout(
modifier = Modifier.background(color = appColors.background).padding(horizontal = 16.dp), modifier = Modifier.background(color = appColors.background).padding(horizontal = 16.dp),
@@ -135,7 +143,14 @@ fun AccountEditScreen2() {
} }
} }
Spacer(modifier = Modifier.height(44.dp)) Spacer(modifier = Modifier.height(44.dp))
model.profile?.let {
// 显示内容或加载状态
Log.d("AccountEditScreen2", "UI状态 - profile: ${model.profile?.nickName}, isLoading: ${model.isLoading}")
when {
model.profile != null -> {
Log.d("AccountEditScreen2", "显示用户资料内容")
// 有数据时显示内容
val it = model.profile!!
Box( Box(
modifier = Modifier.size(88.dp), modifier = Modifier.size(88.dp),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
@@ -168,7 +183,6 @@ fun AccountEditScreen2() {
tint = Color.White, tint = Color.White,
) )
} }
} }
Spacer(modifier = Modifier.height(58.dp)) Spacer(modifier = Modifier.height(58.dp))
Column( Column(
@@ -185,7 +199,6 @@ fun AccountEditScreen2() {
) { value -> ) { value ->
onNicknameChange(value) onNicknameChange(value)
} }
// Spacer(modifier = Modifier.height(16.dp))
FormTextInput( FormTextInput(
value = model.bio, value = model.bio,
label = stringResource(R.string.bio), label = stringResource(R.string.bio),
@@ -197,6 +210,36 @@ fun AccountEditScreen2() {
} }
} }
} }
model.isLoading -> {
Log.d("AccountEditScreen2", "显示加载指示器")
// 加载中状态
Box(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
contentAlignment = Alignment.Center
) {
androidx.compose.material3.CircularProgressIndicator(
color = appColors.main
)
}
}
else -> {
Log.d("AccountEditScreen2", "显示错误信息 - 没有数据且不在加载中")
// 没有数据且不在加载中,显示错误信息
Box(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
contentAlignment = Alignment.Center
) {
androidx.compose.material3.Text(
text = "加载用户资料失败,请重试",
color = appColors.text
)
}
}
}
}} }}

View File

@@ -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.hot.HotMomentViewModel
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.timeline.TimelineMomentViewModel 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.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.DiscoverViewModel
import com.aiosman.ravenow.ui.index.tabs.search.SearchViewModel import com.aiosman.ravenow.ui.index.tabs.search.SearchViewModel
import com.aiosman.ravenow.ui.index.tabs.message.MessageListViewModel import com.aiosman.ravenow.ui.index.tabs.message.MessageListViewModel
@@ -85,6 +86,9 @@ object ResourceCleanupManager {
// 重置个人资料相关ViewModel // 重置个人资料相关ViewModel
MyProfileViewModel.ResetModel() MyProfileViewModel.ResetModel()
// 重置编辑资料ViewModel - 暂时注释掉
// AccountEditViewModel.ResetModel()
// 重置搜索相关ViewModel // 重置搜索相关ViewModel
// DiscoverViewModel的属性是私有的无法直接访问通过其他方式清理 // DiscoverViewModel的属性是私有的无法直接访问通过其他方式清理
@@ -237,6 +241,7 @@ object ResourceCleanupManager {
} }
"profile" -> { "profile" -> {
MyProfileViewModel.ResetModel() MyProfileViewModel.ResetModel()
// AccountEditViewModel.ResetModel() - 暂时注释掉
} }
"search" -> { "search" -> {
// DiscoverViewModel的属性是私有的无法直接访问 // DiscoverViewModel的属性是私有的无法直接访问