From 904cda3ae898d0077ebcd4f0845bd31ad9e2836e Mon Sep 17 00:00:00 2001 From: AllenTom Date: Tue, 11 Nov 2025 14:22:09 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9EAI=E6=99=BA=E8=83=BD?= =?UTF-8?q?=E4=BD=93=E4=B8=BB=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增全新设计的AI智能体主页界面(`AiProfileV3`),包括个人信息卡片、操作按钮和动态列表。 - 添加相应的 `AiProfileViewModel` 来处理数据加载、关注/取关以及动态列表分页逻辑。 - 创建 `AiProfileWrap` 作为页面入口,并根据 `isAiAccount` 参数在导航中分发至新的AI主页。 - 在 `AccountProfileEntity` 和 `Account` 数据模型中增加了AI角色背景图字段(`aiRoleAvatar`, `aiRoleAvatarMedium`, `aiRoleAvatarLarge`)。 --- .../aiosman/ravenow/data/AccountService.kt | 16 +- .../com/aiosman/ravenow/entity/Account.kt | 5 + .../main/java/com/aiosman/ravenow/ui/Navi.kt | 9 +- .../aiosman/ravenow/ui/profile/AiProfileV3.kt | 456 ++++++++++++++++++ .../ravenow/ui/profile/AiProfileViewModel.kt | 122 +++++ .../ravenow/ui/profile/AiProfileWrap.kt | 90 ++++ 6 files changed, 696 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/aiosman/ravenow/ui/profile/AiProfileV3.kt create mode 100644 app/src/main/java/com/aiosman/ravenow/ui/profile/AiProfileViewModel.kt create mode 100644 app/src/main/java/com/aiosman/ravenow/ui/profile/AiProfileWrap.kt diff --git a/app/src/main/java/com/aiosman/ravenow/data/AccountService.kt b/app/src/main/java/com/aiosman/ravenow/data/AccountService.kt index 5bb96e0..f4a4231 100644 --- a/app/src/main/java/com/aiosman/ravenow/data/AccountService.kt +++ b/app/src/main/java/com/aiosman/ravenow/data/AccountService.kt @@ -64,6 +64,11 @@ data class AccountProfile( val aiAccount: Boolean, val chatAIId: String, + + // AI角色背景图 + val aiRoleAvatar: String? = null, + val aiRoleAvatarMedium: String? = null, + val aiRoleAvatarLarge: String? = null, ) { /** * 转换为Entity @@ -89,7 +94,16 @@ data class AccountProfile( chatToken = openImToken, aiAccount = aiAccount, rawAvatar = avatar, - chatAIId = chatAIId + chatAIId = chatAIId, + aiRoleAvatar = aiRoleAvatar?.let { + if (it.isNotEmpty()) "${ApiClient.BASE_SERVER}$it" else null + }, + aiRoleAvatarMedium = aiRoleAvatarMedium?.let { + if (it.isNotEmpty()) "${ApiClient.BASE_SERVER}$it" else null + }, + aiRoleAvatarLarge = aiRoleAvatarLarge?.let { + if (it.isNotEmpty()) "${ApiClient.BASE_SERVER}$it" else null + } ) } } diff --git a/app/src/main/java/com/aiosman/ravenow/entity/Account.kt b/app/src/main/java/com/aiosman/ravenow/entity/Account.kt index db1c616..415cde2 100644 --- a/app/src/main/java/com/aiosman/ravenow/entity/Account.kt +++ b/app/src/main/java/com/aiosman/ravenow/entity/Account.kt @@ -67,6 +67,11 @@ data class AccountProfileEntity( val rawAvatar: String, val chatAIId: String, + + // AI角色背景图 + val aiRoleAvatar: String? = null, + val aiRoleAvatarMedium: String? = null, + val aiRoleAvatarLarge: String? = null, ) /** diff --git a/app/src/main/java/com/aiosman/ravenow/ui/Navi.kt b/app/src/main/java/com/aiosman/ravenow/ui/Navi.kt index deab30f..659e3b6 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/Navi.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/Navi.kt @@ -76,6 +76,7 @@ import com.aiosman.ravenow.ui.post.NewPostImageGridScreen import com.aiosman.ravenow.ui.post.NewPostScreen import com.aiosman.ravenow.ui.post.PostScreen import com.aiosman.ravenow.ui.profile.AccountProfileV2 +import com.aiosman.ravenow.ui.profile.AiProfileWrap import com.aiosman.ravenow.ui.index.tabs.profile.vip.VipSelPage import com.aiosman.ravenow.ui.notification.NotificationScreen import com.aiosman.ravenow.ui.scan.ScanQrScreen @@ -345,7 +346,13 @@ fun NavigationController( ) { val id = it.arguments?.getString("id")!! val isAiAccount = it.arguments?.getBoolean("isAiAccount") ?: false - AccountProfileV2(id, isAiAccount) + + // 根据isAiAccount参数分发到不同的Profile页面 + if (isAiAccount) { + AiProfileWrap(id) + } else { + AccountProfileV2(id, isAiAccount) + } } } composable( diff --git a/app/src/main/java/com/aiosman/ravenow/ui/profile/AiProfileV3.kt b/app/src/main/java/com/aiosman/ravenow/ui/profile/AiProfileV3.kt new file mode 100644 index 0000000..cd52a6b --- /dev/null +++ b/app/src/main/java/com/aiosman/ravenow/ui/profile/AiProfileV3.kt @@ -0,0 +1,456 @@ +package com.aiosman.ravenow.ui.profile + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.systemBars +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.grid.itemsIndexed +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.aiosman.ravenow.AppState +import com.aiosman.ravenow.GuestLoginCheckOut +import com.aiosman.ravenow.GuestLoginCheckOutScene +import com.aiosman.ravenow.LocalAppTheme +import com.aiosman.ravenow.LocalNavController +import com.aiosman.ravenow.R +import com.aiosman.ravenow.entity.AccountProfileEntity +import com.aiosman.ravenow.entity.MomentEntity +import com.aiosman.ravenow.ui.NavigationRoute +import com.aiosman.ravenow.ui.composables.CustomAsyncImage +import com.aiosman.ravenow.ui.composables.StatusBarSpacer +import com.aiosman.ravenow.ui.modifiers.noRippleClickable +import com.aiosman.ravenow.ui.navigateToPost +import java.text.NumberFormat +import java.util.Locale + +@Composable +fun AiProfileV3( + profile: AccountProfileEntity?, + moments: List, + postCount: Long? = null, + isSelf: Boolean = false, + onFollowClick: () -> Unit = {}, + onChatClick: () -> Unit = {}, + onShareClick: () -> Unit = {}, + onLoadMore: () -> Unit = {}, + onComment: (MomentEntity) -> Unit = {}, +) { + val appColors = LocalAppTheme.current + val numberFormat = remember { NumberFormat.getNumberInstance(Locale.getDefault()) } + + Box( + modifier = Modifier + .fillMaxSize() + .background(appColors.background) + ) { + LazyColumn( + modifier = Modifier.fillMaxSize() + ) { + // 顶部状态栏间距 + item { + val statusBarPadding = WindowInsets.systemBars.asPaddingValues() + Spacer(modifier = Modifier.height(statusBarPadding.calculateTopPadding())) + } + + // AI大卡片 + item { + AiProfileCard( + profile = profile, + postCount = postCount, + numberFormat = numberFormat + ) + } + + item { + Spacer(modifier = Modifier.height(16.dp)) + } + + // 三按钮交互区 + if (!isSelf) { + item { + AiProfileActions( + profile = profile, + onFollowClick = onFollowClick, + onChatClick = onChatClick, + onShareClick = onShareClick + ) + } + + item { + Spacer(modifier = Modifier.height(16.dp)) + } + } + + // 动态Grid - 使用items来渲染每个动态 + item { + LazyVerticalGrid( + columns = GridCells.Fixed(3), + modifier = Modifier + .fillMaxWidth() + .height(((moments.size / 3 + 1) * 130).dp) // 动态计算高度 + .padding(horizontal = 16.dp), + userScrollEnabled = false // 禁用内部滚动 + ) { + itemsIndexed(moments) { idx, moment -> + if (moment.images.isNotEmpty()) { + Box( + modifier = Modifier + .fillMaxWidth() + .aspectRatio(1f) + .padding(2.dp) + .noRippleClickable { + onComment(moment) + } + ) { + CustomAsyncImage( + imageUrl = moment.images[0].thumbnail, + contentDescription = "", + modifier = Modifier.fillMaxSize(), + context = LocalContext.current + ) + } + } + } + } + } + + // 底部间距 + item { + Spacer(modifier = Modifier.height(100.dp)) + } + } + + // 顶部返回按钮 + TopBar() + } +} + +@Composable +private fun TopBar() { + val navController = LocalNavController.current + val appColors = LocalAppTheme.current + + Box( + modifier = Modifier + .fillMaxWidth() + .background(Color.Transparent) + ) { + StatusBarSpacer() + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 12.dp) + .statusBarsPadding(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + // 返回按钮 + Box( + modifier = Modifier + .size(40.dp) + .clip(CircleShape) + .background(Color.Black.copy(alpha = 0.3f)) + .noRippleClickable { + navController.popBackStack() + }, + contentAlignment = Alignment.Center + ) { + Text( + text = "←", + fontSize = 24.sp, + color = Color.White, + fontWeight = FontWeight.Bold + ) + } + } + } +} + +@Composable +private fun AiProfileCard( + profile: AccountProfileEntity?, + postCount: Long?, + numberFormat: NumberFormat +) { + val appColors = LocalAppTheme.current + + Box( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) // 添加四边边距 + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .height(400.dp) + .clip(RoundedCornerShape(16.dp)) // 添加圆角 + ) { + // 背景图 - 使用aiRoleAvatar + val backgroundUrl = profile?.aiRoleAvatarLarge + ?: profile?.aiRoleAvatarMedium + ?: profile?.aiRoleAvatar + ?: profile?.avatar + + CustomAsyncImage( + context = LocalContext.current, + imageUrl = backgroundUrl ?: "", + contentDescription = "AI Background", + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop + ) + + // 底部渐变遮罩 + Box( + modifier = Modifier + .fillMaxSize() + .background( + Brush.verticalGradient( + colors = listOf( + Color.Transparent, + Color.Black.copy(alpha = 0.7f) + ), + startY = 200f, + endY = 1200f + ) + ) + ) + + // 左下角内容 + Column( + modifier = Modifier + .align(Alignment.BottomStart) + .padding(20.dp), + horizontalAlignment = Alignment.Start + ) { + // AI昵称 - 左对齐 + Text( + text = profile?.nickName ?: "", + fontSize = 22.sp, + fontWeight = FontWeight.Bold, + color = Color.White + ) + + Spacer(modifier = Modifier.height(6.dp)) + + // AI简介 - 左对齐 + if (!profile?.bio.isNullOrEmpty()) { + Text( + text = profile?.bio ?: "", + fontSize = 13.sp, + color = Color.White.copy(alpha = 0.85f), + textAlign = TextAlign.Start, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + lineHeight = 18.sp + ) + + Spacer(modifier = Modifier.height(12.dp)) + } + + // 统计数据行 - 左对齐 + Row( + horizontalArrangement = Arrangement.spacedBy(24.dp) + ) { + StatItem( + count = postCount ?: 0L, + label = stringResource(R.string.posts), + numberFormat = numberFormat + ) + StatItem( + count = profile?.followerCount?.toLong() ?: 0L, + label = stringResource(R.string.followers_upper), + numberFormat = numberFormat + ) + StatItem( + count = profile?.followingCount?.toLong() ?: 0L, + label = stringResource(R.string.following_upper), + numberFormat = numberFormat + ) + } + } + } + } +} + +@Composable +private fun StatItem( + count: Long, + label: String, + numberFormat: NumberFormat +) { + Column( + horizontalAlignment = Alignment.Start + ) { + Text( + text = formatNumber(count, numberFormat), + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + color = Color.White + ) + Spacer(modifier = Modifier.height(2.dp)) + Text( + text = label, + fontSize = 12.sp, + color = Color.White.copy(alpha = 0.8f) + ) + } +} + +private fun formatNumber(count: Long, numberFormat: NumberFormat): String { + return when { + count >= 1_000_000 -> String.format("%.1fM", count / 1_000_000.0) + count >= 1_000 -> String.format("%.1fK", count / 1_000.0) + else -> numberFormat.format(count) + } +} + +@Composable +private fun AiProfileActions( + profile: AccountProfileEntity?, + onFollowClick: () -> Unit, + onChatClick: () -> Unit, + onShareClick: () -> Unit +) { + val appColors = LocalAppTheme.current + val navController = LocalNavController.current + + // 定义渐变色 + val followGradient = Brush.horizontalGradient( + colors = listOf( + Color(0xFF7c45ed), + Color(0x777c68ef) + ) + ) + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(12.dp), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + ) { + // Follow按钮 + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center, + modifier = Modifier + .weight(1f) + .clip(RoundedCornerShape(8.dp)) + .let { modifier -> + if (profile?.isFollowing == true) { + // 已关注状态 - 透明背景 + modifier.background(Color.Transparent) + } else { + // 未关注状态 - 渐变背景 + modifier.background(brush = followGradient) + } + } + .let { modifier -> + if (profile?.isFollowing == true) { + modifier.border( + width = 1.dp, + color = appColors.text.copy(alpha = 0.3f), + shape = RoundedCornerShape(8.dp) + ) + } else { + modifier + } + } + .padding(horizontal = 16.dp, vertical = 12.dp) + .noRippleClickable { + if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.FOLLOW_USER)) { + navController.navigate(NavigationRoute.Login.route) + } else { + onFollowClick() + } + } + ) { + Text( + text = if (profile?.isFollowing == true) + stringResource(R.string.follow_upper_had) + else + stringResource(R.string.follow_upper), + fontSize = 14.sp, + fontWeight = FontWeight.W900, + color = if (profile?.isFollowing == true) { + appColors.text.copy(alpha = 0.6f) + } else { + Color.White + }, + ) + } + + // Chat按钮 + if (AppState.enableChat) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center, + modifier = Modifier + .weight(1f) + .clip(RoundedCornerShape(8.dp)) + .background(appColors.nonActive) + .padding(horizontal = 16.dp, vertical = 12.dp) + .noRippleClickable { + if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CHAT_WITH_AGENT)) { + navController.navigate(NavigationRoute.Login.route) + } else { + onChatClick() + } + } + ) { + Text( + text = stringResource(R.string.chat_upper), + fontSize = 14.sp, + fontWeight = FontWeight.W900, + color = appColors.text, + ) + } + } + + // Share按钮 + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center, + modifier = Modifier + .weight(1f) + .clip(RoundedCornerShape(8.dp)) + .background(appColors.nonActive) + .padding(horizontal = 16.dp, vertical = 12.dp) + .noRippleClickable { + if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CHAT_WITH_AGENT)) { + navController.navigate(NavigationRoute.Login.route) + } else { + onShareClick() + } + } + ) { + Text( + text = stringResource(R.string.share), + fontSize = 14.sp, + fontWeight = FontWeight.W900, + color = appColors.text, + ) + } + } +} + diff --git a/app/src/main/java/com/aiosman/ravenow/ui/profile/AiProfileViewModel.kt b/app/src/main/java/com/aiosman/ravenow/ui/profile/AiProfileViewModel.kt new file mode 100644 index 0000000..663bc79 --- /dev/null +++ b/app/src/main/java/com/aiosman/ravenow/ui/profile/AiProfileViewModel.kt @@ -0,0 +1,122 @@ +package com.aiosman.ravenow.ui.profile + +import android.util.Log +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.aiosman.ravenow.data.AccountService +import com.aiosman.ravenow.data.AccountServiceImpl +import com.aiosman.ravenow.data.UserServiceImpl +import com.aiosman.ravenow.entity.AccountProfileEntity +import com.aiosman.ravenow.entity.MomentEntity +import com.aiosman.ravenow.entity.MomentLoader +import com.aiosman.ravenow.entity.MomentLoaderExtraArgs +import com.aiosman.ravenow.event.FollowChangeEvent +import kotlinx.coroutines.launch +import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.Subscribe + +class AiProfileViewModel : ViewModel() { + var profileId by mutableStateOf(0) + val accountService: AccountService = AccountServiceImpl() + val userService = UserServiceImpl() + var profile by mutableStateOf(null) + var refreshing by mutableStateOf(false) + + var momentLoader = MomentLoader().apply { + pageSize = 20 + onListChanged = { + moments = it + } + } + var moments by mutableStateOf>(listOf()) + + init { + EventBus.getDefault().register(this) + } + + fun loadProfile(id: String, pullRefresh: Boolean = false) { + viewModelScope.launch { + if (pullRefresh) { + refreshing = true + } + + try { + profile = userService.getUserProfile(id) + profileId = id.toInt() + } catch (e: Exception) { + Log.e("AiProfileViewModel", "Error loading profile", e) + e.printStackTrace() + } + + refreshing = false + + profile?.let { + try { + momentLoader.loadData(MomentLoaderExtraArgs(authorId = it.id)) + } catch (e: Exception) { + Log.e("AiProfileViewModel", "Error loading moments", e) + e.printStackTrace() + } + } + } + } + + fun loadMoreMoment() { + viewModelScope.launch { + profile?.let { profileData -> + try { + Log.d("AiProfileViewModel", "loadMoreMoment: 开始加载更多, 当前moments数量: ${moments.size}, hasNext: ${momentLoader.hasNext}") + momentLoader.loadMore(extra = MomentLoaderExtraArgs(authorId = profileData.id)) + Log.d("AiProfileViewModel", "loadMoreMoment: 加载完成, 新的moments数量: ${moments.size}") + } catch (e: Exception) { + Log.e("AiProfileViewModel", "loadMoreMoment: ", e) + } + } ?: Log.w("AiProfileViewModel", "loadMoreMoment: profile为null,无法加载更多") + } + } + + @Subscribe + fun onFollowChangeEvent(event: FollowChangeEvent) { + if (event.userId == profile?.id) { + profile = profile?.copy( + followerCount = profile!!.followerCount + if (event.isFollow) 1 else -1, + isFollowing = event.isFollow + ) + } + } + + fun followUser(userId: String) { + viewModelScope.launch { + try { + userService.followUser(userId) + EventBus.getDefault().post(FollowChangeEvent(userId.toInt(), true)) + } catch (e: Exception) { + Log.e("AiProfileViewModel", "Error following user", e) + } + } + } + + fun unFollowUser(userId: String) { + viewModelScope.launch { + try { + userService.unFollowUser(userId) + EventBus.getDefault().post(FollowChangeEvent(userId.toInt(), false)) + } catch (e: Exception) { + Log.e("AiProfileViewModel", "Error unfollowing user", e) + } + } + } + + val bio get() = profile?.bio ?: "" + val nickName get() = profile?.nickName ?: "" + val avatar get() = profile?.avatar + + override fun onCleared() { + super.onCleared() + EventBus.getDefault().unregister(this) + } +} + diff --git a/app/src/main/java/com/aiosman/ravenow/ui/profile/AiProfileWrap.kt b/app/src/main/java/com/aiosman/ravenow/ui/profile/AiProfileWrap.kt new file mode 100644 index 0000000..5f0c17c --- /dev/null +++ b/app/src/main/java/com/aiosman/ravenow/ui/profile/AiProfileWrap.kt @@ -0,0 +1,90 @@ +package com.aiosman.ravenow.ui.profile + +import android.util.Log +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.rememberCoroutineScope +import androidx.lifecycle.viewmodel.compose.viewModel +import com.aiosman.ravenow.GuestLoginCheckOut +import com.aiosman.ravenow.GuestLoginCheckOutScene +import com.aiosman.ravenow.LocalNavController +import com.aiosman.ravenow.data.UserServiceImpl +import com.aiosman.ravenow.exp.viewModelFactory +import com.aiosman.ravenow.ui.NavigationRoute +import com.aiosman.ravenow.ui.index.tabs.ai.tabs.mine.MineAgentViewModel +import com.aiosman.ravenow.ui.index.tabs.profile.MyProfileViewModel +import com.aiosman.ravenow.ui.navigateToChatAi +import com.aiosman.ravenow.ui.navigateToPost +import kotlinx.coroutines.launch + +@Composable +fun AiProfileWrap(id: String) { + val model: AiProfileViewModel = viewModel(factory = viewModelFactory { + AiProfileViewModel() + }, key = "aiViewModel_${id}") + + val navController = LocalNavController.current + val scope = rememberCoroutineScope() + + LaunchedEffect(Unit) { + model.loadProfile(id) + MyProfileViewModel.loadProfile() + } + + val isSelf = id == MyProfileViewModel.profile?.id.toString() + + AiProfileV3( + profile = model.profile, + moments = model.moments, + postCount = model.momentLoader.total, + isSelf = isSelf, + onFollowClick = { + model.profile?.let { + if (it.isFollowing) { + model.unFollowUser(id) + } else { + model.followUser(id) + } + } + }, + onChatClick = { + // 检查游客模式 + if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CHAT_WITH_AGENT)) { + navController.navigate(NavigationRoute.Login.route) + } else { + model.profile?.let { profile -> + scope.launch { + try { + // 参考主页逻辑:使用chatAIId作为openId创建单聊并导航 + // 创建单聊 + MineAgentViewModel.createSingleChat(profile.chatAIId) + + // 通过chatAIId获取完整的AI profile(类似主页的goToChatAi逻辑) + val userService = UserServiceImpl() + val aiProfile = userService.getUserProfileByOpenId(profile.chatAIId) + + // 导航到AI聊天页面 + navController.navigateToChatAi(aiProfile.id.toString()) + } catch (e: Exception) { + Log.e("AiProfileWrap", "Error navigating to AI chat", e) + // 如果获取失败,直接使用当前profile的id + navController.navigateToChatAi(profile.id.toString()) + } + } + } + } + }, + onShareClick = { + // TODO: 实现分享逻辑 + Log.d("AiProfileWrap", "分享功能待实现") + }, + onLoadMore = { + Log.d("AiProfileWrap", "onLoadMore被调用") + model.loadMoreMoment() + }, + onComment = { moment -> + navController.navigateToPost(moment.id) + } + ) +} +