Enhance AI Agent Profile Interaction
This commit introduces several enhancements to how AI agent profiles are displayed and interacted with:
**Profile Display:**
- **AI Account Distinction:** Profile pages now differentiate between regular user accounts and AI agent accounts.
- AI agent profiles will not display the "Agents" tab in their profile.
- The profile header height is adjusted for AI accounts.
- **Navigation Parameter:** An `isAiAccount` boolean parameter is added to the `AccountProfile` navigation route to indicate if the profile being viewed belongs to an AI.
**Interaction & Navigation:**
- **Avatar Click Navigation:**
- Clicking an AI agent's avatar in various lists (Hot Agents, My Agents, User Agents Row, User Agents List) now navigates to the agent's dedicated profile page.
- When navigating to an agent's profile from an agent list, `isAiAccount` is set to `true`.
- **Chat Initiation:** Clicking the chat button on AI agent cards in the "Agent" tab (both Hot and My Agents) now correctly initiates a chat with the respective AI.
- **ViewModel Updates:**
- `AgentViewModel`, `MineAgentViewModel`, and `HotAgentViewModel` now include a `goToProfile` function to handle navigation to agent profiles, correctly passing the `isAiAccount` flag.
**Code Refinements:**
- Click handlers for agent avatars and chat buttons are now wrapped with `DebounceUtils.simpleDebounceClick` to prevent multiple rapid clicks.
- The `UserContentPageIndicator` now conditionally hides the "Agent" tab based on the `isAiAccount` status.
- `UserAgentsRow` and `UserAgentsList` now accept an `onAvatarClick` callback for navigating to agent profiles.
- `AgentItem` (used in `UserAgentsRow`) and `UserAgentCard` (used in `UserAgentsList`) now handle avatar clicks.
- The general `Agent` composable (used in `AiPostComposable`) now also supports an `onAvatarClick` callback.
This commit is contained in:
@@ -85,7 +85,7 @@ sealed class NavigationRoute(
|
|||||||
data object NewPost : NavigationRoute("NewPost")
|
data object NewPost : NavigationRoute("NewPost")
|
||||||
data object EditModification : NavigationRoute("EditModification")
|
data object EditModification : NavigationRoute("EditModification")
|
||||||
data object Login : NavigationRoute("Login")
|
data object Login : NavigationRoute("Login")
|
||||||
data object AccountProfile : NavigationRoute("AccountProfile/{id}")
|
data object AccountProfile : NavigationRoute("AccountProfile/{id}?isAiAccount={isAiAccount}")
|
||||||
data object SignUp : NavigationRoute("SignUp")
|
data object SignUp : NavigationRoute("SignUp")
|
||||||
data object UserAuth : NavigationRoute("UserAuth")
|
data object UserAuth : NavigationRoute("UserAuth")
|
||||||
data object EmailSignUp : NavigationRoute("EmailSignUp")
|
data object EmailSignUp : NavigationRoute("EmailSignUp")
|
||||||
@@ -284,7 +284,13 @@ fun NavigationController(
|
|||||||
}
|
}
|
||||||
composable(
|
composable(
|
||||||
route = NavigationRoute.AccountProfile.route,
|
route = NavigationRoute.AccountProfile.route,
|
||||||
arguments = listOf(navArgument("id") { type = NavType.StringType }),
|
arguments = listOf(
|
||||||
|
navArgument("id") { type = NavType.StringType },
|
||||||
|
navArgument("isAiAccount") {
|
||||||
|
type = NavType.BoolType
|
||||||
|
defaultValue = false
|
||||||
|
}
|
||||||
|
),
|
||||||
enterTransition = {
|
enterTransition = {
|
||||||
// iOS push: new screen slides in from the right
|
// iOS push: new screen slides in from the right
|
||||||
slideInHorizontally(
|
slideInHorizontally(
|
||||||
@@ -317,7 +323,9 @@ fun NavigationController(
|
|||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalAnimatedContentScope provides this,
|
LocalAnimatedContentScope provides this,
|
||||||
) {
|
) {
|
||||||
AccountProfileV2(it.arguments?.getString("id")!!)
|
val id = it.arguments?.getString("id")!!
|
||||||
|
val isAiAccount = it.arguments?.getBoolean("isAiAccount") ?: false
|
||||||
|
AccountProfileV2(id, isAiAccount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
composable(
|
composable(
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ fun AgentCard(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
agentEntity: AgentEntity,
|
agentEntity: AgentEntity,
|
||||||
onClick: () -> Unit = {},
|
onClick: () -> Unit = {},
|
||||||
|
onAvatarClick: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val AppColors = LocalAppTheme.current
|
val AppColors = LocalAppTheme.current
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
@@ -63,6 +64,9 @@ fun AgentCard(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(40.dp)
|
.size(40.dp)
|
||||||
.clip(RoundedCornerShape(40.dp))
|
.clip(RoundedCornerShape(40.dp))
|
||||||
|
.noRippleClickable {
|
||||||
|
onAvatarClick()
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
CustomAsyncImage(
|
CustomAsyncImage(
|
||||||
context,
|
context,
|
||||||
|
|||||||
@@ -389,7 +389,14 @@ fun AgentCard2(viewModel: AgentViewModel,agentItem: AgentItem,navController: Nav
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(48.dp)
|
.size(48.dp)
|
||||||
.background(Color(0xFFF5F5F5), RoundedCornerShape(24.dp)),
|
.background(Color(0xFFF5F5F5), RoundedCornerShape(24.dp))
|
||||||
|
.clickable {
|
||||||
|
if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
|
||||||
|
viewModel.goToProfile(agentItem.openId, navController)
|
||||||
|
}) {
|
||||||
|
lastClickTime = System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
},
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
if (agentItem.avatar.isNotEmpty()) {
|
if (agentItem.avatar.isNotEmpty()) {
|
||||||
@@ -451,8 +458,8 @@ fun AgentCard2(viewModel: AgentViewModel,agentItem: AgentItem,navController: Nav
|
|||||||
)
|
)
|
||||||
.clickable {
|
.clickable {
|
||||||
if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
|
if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
|
||||||
/* viewModel.createSingleChat(agentItem.trtcId)
|
viewModel.createSingleChat(agentItem.openId)
|
||||||
viewModel.goToChatAi(agentItem.trtcId, navController = navController)*/
|
viewModel.goToChatAi(agentItem.openId, navController = navController)
|
||||||
}) {
|
}) {
|
||||||
lastClickTime = System.currentTimeMillis()
|
lastClickTime = System.currentTimeMillis()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.aiosman.ravenow.data.api.ApiClient
|
|||||||
import com.aiosman.ravenow.data.api.RaveNowAPI
|
import com.aiosman.ravenow.data.api.RaveNowAPI
|
||||||
import com.aiosman.ravenow.data.api.SingleChatRequestBody
|
import com.aiosman.ravenow.data.api.SingleChatRequestBody
|
||||||
import com.aiosman.ravenow.ui.index.tabs.ai.tabs.mine.MineAgentViewModel.createGroup2ChatAi
|
import com.aiosman.ravenow.ui.index.tabs.ai.tabs.mine.MineAgentViewModel.createGroup2ChatAi
|
||||||
|
import com.aiosman.ravenow.ui.NavigationRoute
|
||||||
import com.aiosman.ravenow.ui.index.tabs.message.MessageListViewModel.userService
|
import com.aiosman.ravenow.ui.index.tabs.message.MessageListViewModel.userService
|
||||||
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.expolre.AgentItem
|
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.expolre.AgentItem
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -75,4 +76,23 @@ object AgentViewModel: ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun goToProfile(
|
||||||
|
openId: String,
|
||||||
|
navController: NavHostController
|
||||||
|
) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
try {
|
||||||
|
val profile = userService.getUserProfileByOpenId(openId)
|
||||||
|
// 从Agent列表点击进去的一定是智能体,直接传递isAiAccount = true
|
||||||
|
navController.navigate(
|
||||||
|
NavigationRoute.AccountProfile.route
|
||||||
|
.replace("{id}", profile.id.toString())
|
||||||
|
.replace("{isAiAccount}", "true")
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// swallow error to avoid crash on navigation attempt failures
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -120,6 +120,9 @@ fun HotAgent() {
|
|||||||
model.createSingleChat(agentItem.openId)
|
model.createSingleChat(agentItem.openId)
|
||||||
model.goToChatAi(agentItem.openId,navController)
|
model.goToChatAi(agentItem.openId,navController)
|
||||||
},
|
},
|
||||||
|
onAvatarClick = {
|
||||||
|
model.goToProfile(agentItem.openId, navController)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import com.aiosman.ravenow.data.api.SingleChatRequestBody
|
|||||||
import com.aiosman.ravenow.entity.AgentEntity
|
import com.aiosman.ravenow.entity.AgentEntity
|
||||||
import com.aiosman.ravenow.ui.index.tabs.ai.tabs.mine.MineAgentViewModel.createGroup2ChatAi
|
import com.aiosman.ravenow.ui.index.tabs.ai.tabs.mine.MineAgentViewModel.createGroup2ChatAi
|
||||||
import com.aiosman.ravenow.ui.index.tabs.message.MessageListViewModel.userService
|
import com.aiosman.ravenow.ui.index.tabs.message.MessageListViewModel.userService
|
||||||
|
import com.aiosman.ravenow.ui.NavigationRoute
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
object HotAgentViewModel : ViewModel() {
|
object HotAgentViewModel : ViewModel() {
|
||||||
@@ -128,6 +129,25 @@ object HotAgentViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun goToProfile(
|
||||||
|
openId: String,
|
||||||
|
navController: NavHostController
|
||||||
|
) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
try {
|
||||||
|
val profile = userService.getUserProfileByOpenId(openId)
|
||||||
|
// 从Agent列表点击进去的一定是智能体,直接传递isAiAccount = true
|
||||||
|
navController.navigate(
|
||||||
|
NavigationRoute.AccountProfile.route
|
||||||
|
.replace("{id}", profile.id.toString())
|
||||||
|
.replace("{isAiAccount}", "true")
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// swallow error to avoid crash on navigation attempt failures
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 预加载图片,避免滑动时重复加载
|
// 预加载图片,避免滑动时重复加载
|
||||||
fun preloadImages(context: android.content.Context) {
|
fun preloadImages(context: android.content.Context) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
|||||||
@@ -111,6 +111,9 @@ fun MineAgent() {
|
|||||||
model.createSingleChat(agent.openId)
|
model.createSingleChat(agent.openId)
|
||||||
model.goToChatAi(agent.openId,navController)
|
model.goToChatAi(agent.openId,navController)
|
||||||
},
|
},
|
||||||
|
onAvatarClick = {
|
||||||
|
model.goToProfile(agent.openId, navController)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import com.aiosman.ravenow.entity.MomentRemoteDataSource
|
|||||||
import com.aiosman.ravenow.entity.MomentServiceImpl
|
import com.aiosman.ravenow.entity.MomentServiceImpl
|
||||||
import com.aiosman.ravenow.ui.index.tabs.message.MessageListViewModel.userService
|
import com.aiosman.ravenow.ui.index.tabs.message.MessageListViewModel.userService
|
||||||
import com.aiosman.ravenow.ui.navigateToChatAi
|
import com.aiosman.ravenow.ui.navigateToChatAi
|
||||||
|
import com.aiosman.ravenow.ui.NavigationRoute
|
||||||
import com.tencent.imsdk.v2.V2TIMConversationOperationResult
|
import com.tencent.imsdk.v2.V2TIMConversationOperationResult
|
||||||
import com.tencent.imsdk.v2.V2TIMManager
|
import com.tencent.imsdk.v2.V2TIMManager
|
||||||
import com.tencent.imsdk.v2.V2TIMValueCallback
|
import com.tencent.imsdk.v2.V2TIMValueCallback
|
||||||
@@ -119,5 +120,24 @@ object MineAgentViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun goToProfile(
|
||||||
|
openId: String,
|
||||||
|
navController: NavHostController
|
||||||
|
) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
try {
|
||||||
|
val profile = userService.getUserProfileByOpenId(openId)
|
||||||
|
// 从Agent列表点击进去的一定是智能体,直接传递isAiAccount = true
|
||||||
|
navController.navigate(
|
||||||
|
NavigationRoute.AccountProfile.route
|
||||||
|
.replace("{id}", profile.id.toString())
|
||||||
|
.replace("{isAiAccount}", "true")
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// swallow error to avoid crash on navigation attempt failures
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -101,6 +101,7 @@ fun ProfileV3(
|
|||||||
agents: List<AgentEntity> = emptyList(),
|
agents: List<AgentEntity> = emptyList(),
|
||||||
isSelf: Boolean = true,
|
isSelf: Boolean = true,
|
||||||
isMain:Boolean = false,
|
isMain:Boolean = false,
|
||||||
|
isAiAccount: Boolean = false, // 新增参数判断是否为AI账户
|
||||||
onLoadMore: () -> Unit = {},
|
onLoadMore: () -> Unit = {},
|
||||||
onLike: (MomentEntity) -> Unit = {},
|
onLike: (MomentEntity) -> Unit = {},
|
||||||
onComment: (MomentEntity) -> Unit = {},
|
onComment: (MomentEntity) -> Unit = {},
|
||||||
@@ -109,7 +110,7 @@ fun ProfileV3(
|
|||||||
) {
|
) {
|
||||||
val model = MyProfileViewModel
|
val model = MyProfileViewModel
|
||||||
val state = rememberCollapsingToolbarScaffoldState()
|
val state = rememberCollapsingToolbarScaffoldState()
|
||||||
val pagerState = rememberPagerState(pageCount = { 2 })
|
val pagerState = rememberPagerState(pageCount = { if (isAiAccount) 1 else 2 })
|
||||||
val enabled by remember { mutableStateOf(true) }
|
val enabled by remember { mutableStateOf(true) }
|
||||||
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
|
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
|
||||||
var expanded by remember { mutableStateOf(false) }
|
var expanded by remember { mutableStateOf(false) }
|
||||||
@@ -227,7 +228,7 @@ fun ProfileV3(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.parallax(0.5f)
|
.parallax(0.5f)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.height(700.dp)
|
.height(if (isAiAccount) 600.dp else 700.dp)
|
||||||
.background(AppColors.profileBackground)
|
.background(AppColors.profileBackground)
|
||||||
.verticalScroll(toolbarScrollState)
|
.verticalScroll(toolbarScrollState)
|
||||||
) {
|
) {
|
||||||
@@ -387,7 +388,8 @@ fun ProfileV3(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加用户智能体行
|
// 添加用户智能体行(智能体用户不显示)
|
||||||
|
if (!isAiAccount) {
|
||||||
UserAgentsRow(
|
UserAgentsRow(
|
||||||
userId = if (isSelf) null else profile?.id,
|
userId = if (isSelf) null else profile?.id,
|
||||||
modifier = Modifier.padding(top = 16.dp),
|
modifier = Modifier.padding(top = 16.dp),
|
||||||
@@ -398,9 +400,26 @@ fun ProfileV3(
|
|||||||
onAgentClick = { agent ->
|
onAgentClick = { agent ->
|
||||||
// 导航到智能体详情页面
|
// 导航到智能体详情页面
|
||||||
// TODO: 实现导航逻辑
|
// TODO: 实现导航逻辑
|
||||||
|
},
|
||||||
|
onAvatarClick = { agent ->
|
||||||
|
// 导航到智能体个人主页
|
||||||
|
scope.launch {
|
||||||
|
try {
|
||||||
|
val userService = com.aiosman.ravenow.data.UserServiceImpl()
|
||||||
|
val profile = userService.getUserProfileByOpenId(agent.openId)
|
||||||
|
navController.navigate(
|
||||||
|
NavigationRoute.AccountProfile.route
|
||||||
|
.replace("{id}", profile.id.toString())
|
||||||
|
.replace("{isAiAccount}", "true")
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// 处理错误
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,6 +516,7 @@ fun ProfileV3(
|
|||||||
) {
|
) {
|
||||||
UserContentPageIndicator(
|
UserContentPageIndicator(
|
||||||
pagerState = pagerState,
|
pagerState = pagerState,
|
||||||
|
showAgentTab = !isAiAccount
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
@@ -555,6 +575,22 @@ fun ProfileV3(
|
|||||||
UserAgentsList(
|
UserAgentsList(
|
||||||
agents = agents,
|
agents = agents,
|
||||||
onAgentClick = onAgentClick,
|
onAgentClick = onAgentClick,
|
||||||
|
onAvatarClick = { agent ->
|
||||||
|
// 导航到智能体个人主页,需要通过openId获取用户ID
|
||||||
|
scope.launch {
|
||||||
|
try {
|
||||||
|
val userService = com.aiosman.ravenow.data.UserServiceImpl()
|
||||||
|
val profile = userService.getUserProfileByOpenId(agent.openId)
|
||||||
|
navController.navigate(
|
||||||
|
NavigationRoute.AccountProfile.route
|
||||||
|
.replace("{id}", profile.id.toString())
|
||||||
|
.replace("{isAiAccount}", "true")
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// 处理错误
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ fun ProfileWrap(
|
|||||||
}
|
}
|
||||||
ProfileV3(
|
ProfileV3(
|
||||||
isMain = true,
|
isMain = true,
|
||||||
|
isAiAccount = MyProfileViewModel.profile?.aiAccount == true, // 传入AI账户判断
|
||||||
postCount = MyProfileViewModel.momentLoader.total,
|
postCount = MyProfileViewModel.momentLoader.total,
|
||||||
onUpdateBanner = { uri, file, context ->
|
onUpdateBanner = { uri, file, context ->
|
||||||
MyProfileViewModel.updateUserProfileBanner(uri, file, context)
|
MyProfileViewModel.updateUserProfileBanner(uri, file, context)
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import com.aiosman.ravenow.utils.DebounceUtils
|
|||||||
fun UserAgentsList(
|
fun UserAgentsList(
|
||||||
agents: List<AgentEntity>,
|
agents: List<AgentEntity>,
|
||||||
onAgentClick: (AgentEntity) -> Unit = {},
|
onAgentClick: (AgentEntity) -> Unit = {},
|
||||||
|
onAvatarClick: (AgentEntity) -> Unit = {},
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
val AppColors = LocalAppTheme.current
|
val AppColors = LocalAppTheme.current
|
||||||
@@ -61,7 +62,8 @@ fun UserAgentsList(
|
|||||||
items(agents) { agent ->
|
items(agents) { agent ->
|
||||||
UserAgentCard(
|
UserAgentCard(
|
||||||
agent = agent,
|
agent = agent,
|
||||||
onAgentClick = onAgentClick
|
onAgentClick = onAgentClick,
|
||||||
|
onAvatarClick = onAvatarClick
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,7 +78,8 @@ fun UserAgentsList(
|
|||||||
@Composable
|
@Composable
|
||||||
fun UserAgentCard(
|
fun UserAgentCard(
|
||||||
agent: AgentEntity,
|
agent: AgentEntity,
|
||||||
onAgentClick: (AgentEntity) -> Unit
|
onAgentClick: (AgentEntity) -> Unit,
|
||||||
|
onAvatarClick: (AgentEntity) -> Unit = {}
|
||||||
) {
|
) {
|
||||||
val AppColors = LocalAppTheme.current
|
val AppColors = LocalAppTheme.current
|
||||||
|
|
||||||
@@ -93,7 +96,14 @@ fun UserAgentCard(
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(48.dp)
|
.size(48.dp)
|
||||||
.background(AppColors.nonActive, RoundedCornerShape(24.dp)),
|
.background(AppColors.nonActive, RoundedCornerShape(24.dp))
|
||||||
|
.clickable {
|
||||||
|
if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
|
||||||
|
onAvatarClick(agent)
|
||||||
|
}) {
|
||||||
|
lastClickTime = System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
},
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
if (agent.avatar.isNotEmpty()) {
|
if (agent.avatar.isNotEmpty()) {
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ fun UserAgentsRow(
|
|||||||
userId: Int?,
|
userId: Int?,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onMoreClick: () -> Unit = {},
|
onMoreClick: () -> Unit = {},
|
||||||
onAgentClick: (AgentEntity) -> Unit = {}
|
onAgentClick: (AgentEntity) -> Unit = {},
|
||||||
|
onAvatarClick: (AgentEntity) -> Unit = {}
|
||||||
) {
|
) {
|
||||||
val AppColors = LocalAppTheme.current
|
val AppColors = LocalAppTheme.current
|
||||||
val viewModel: UserAgentsViewModel = viewModel(key = "UserAgentsViewModel_${userId ?: "self"}")
|
val viewModel: UserAgentsViewModel = viewModel(key = "UserAgentsViewModel_${userId ?: "self"}")
|
||||||
@@ -128,7 +129,8 @@ fun UserAgentsRow(
|
|||||||
items(viewModel.agents) { agent ->
|
items(viewModel.agents) { agent ->
|
||||||
AgentItem(
|
AgentItem(
|
||||||
agent = agent,
|
agent = agent,
|
||||||
onClick = { onAgentClick(agent) }
|
onClick = { onAgentClick(agent) },
|
||||||
|
onAvatarClick = { onAvatarClick(agent) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,19 +152,21 @@ fun UserAgentsRow(
|
|||||||
private fun AgentItem(
|
private fun AgentItem(
|
||||||
agent: AgentEntity,
|
agent: AgentEntity,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onClick: () -> Unit = {}
|
onClick: () -> Unit = {},
|
||||||
|
onAvatarClick: () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
val AppColors = LocalAppTheme.current
|
val AppColors = LocalAppTheme.current
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier = modifier.noRippleClickable { onClick() }
|
modifier = modifier
|
||||||
) {
|
) {
|
||||||
// 头像
|
// 头像
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(48.dp)
|
.size(48.dp)
|
||||||
.clip(CircleShape)
|
.clip(CircleShape)
|
||||||
|
.noRippleClickable { onAvatarClick() }
|
||||||
) {
|
) {
|
||||||
CustomAsyncImage(
|
CustomAsyncImage(
|
||||||
context = LocalContext.current,
|
context = LocalContext.current,
|
||||||
@@ -185,7 +189,9 @@ private fun AgentItem(
|
|||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
modifier = Modifier.width(48.dp)
|
modifier = Modifier
|
||||||
|
.width(48.dp)
|
||||||
|
.noRippleClickable { onClick() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ import kotlinx.coroutines.launch
|
|||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun UserContentPageIndicator(
|
fun UserContentPageIndicator(
|
||||||
pagerState: PagerState
|
pagerState: PagerState,
|
||||||
|
showAgentTab: Boolean = true
|
||||||
){
|
){
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val AppColors = LocalAppTheme.current
|
val AppColors = LocalAppTheme.current
|
||||||
@@ -71,7 +72,8 @@ fun UserContentPageIndicator(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Agent Tab
|
// Agent Tab (只在非智能体用户时显示)
|
||||||
|
if (showAgentTab) {
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -91,6 +93,7 @@ fun UserContentPageIndicator(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 下划线指示器
|
// 下划线指示器
|
||||||
Row(
|
Row(
|
||||||
@@ -106,6 +109,7 @@ fun UserContentPageIndicator(
|
|||||||
if (pagerState.currentPage == 0) AppColors.text else Color.Transparent
|
if (pagerState.currentPage == 0) AppColors.text else Color.Transparent
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
if (showAgentTab) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
@@ -116,4 +120,5 @@ fun UserContentPageIndicator(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ import com.aiosman.ravenow.ui.navigateToChat
|
|||||||
import com.aiosman.ravenow.ui.navigateToPost
|
import com.aiosman.ravenow.ui.navigateToPost
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AccountProfileV2(id: String){
|
fun AccountProfileV2(id: String, isAiAccount: Boolean = false){
|
||||||
val model: AccountProfileViewModel = viewModel(factory = viewModelFactory {
|
val model: AccountProfileViewModel = viewModel(factory = viewModelFactory {
|
||||||
AccountProfileViewModel()
|
AccountProfileViewModel()
|
||||||
}, key = "viewModel_${id}")
|
}, key = "viewModel_${id}")
|
||||||
@@ -30,6 +30,7 @@ fun AccountProfileV2(id: String){
|
|||||||
agents = model.agents,
|
agents = model.agents,
|
||||||
profile = model.profile,
|
profile = model.profile,
|
||||||
isSelf = isSelf,
|
isSelf = isSelf,
|
||||||
|
isAiAccount = isAiAccount, // 从参数传入AI账户判断
|
||||||
postCount = model.momentLoader.total,
|
postCount = model.momentLoader.total,
|
||||||
onLoadMore = {
|
onLoadMore = {
|
||||||
Log.d("AccountProfileV2", "onLoadMore被调用")
|
Log.d("AccountProfileV2", "onLoadMore被调用")
|
||||||
|
|||||||
Reference in New Issue
Block a user