Refactor: 优化智能体操作交互
- 个人主页智能体列表项增加长按操作,用于弹出操作菜单。 - 实现智能体操作菜单弹窗,提供删除等操作选项。 - 增加删除智能体确认对话框,防止误操作。 - 移除账号页面密码输入框重构为通用组件。
This commit is contained in:
@@ -4,18 +4,11 @@ import android.widget.Toast
|
|||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
|
||||||
import androidx.compose.ui.text.TextStyle
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -25,9 +18,7 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.res.stringResource
|
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.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
@@ -46,6 +37,7 @@ import com.aiosman.ravenow.ui.NavigationRoute
|
|||||||
import com.aiosman.ravenow.ui.comment.NoticeScreenHeader
|
import com.aiosman.ravenow.ui.comment.NoticeScreenHeader
|
||||||
import com.aiosman.ravenow.ui.composables.ActionButton
|
import com.aiosman.ravenow.ui.composables.ActionButton
|
||||||
import com.aiosman.ravenow.ui.composables.StatusBarSpacer
|
import com.aiosman.ravenow.ui.composables.StatusBarSpacer
|
||||||
|
import com.aiosman.ravenow.ui.composables.TextInputField
|
||||||
import com.aiosman.ravenow.utils.PasswordValidator
|
import com.aiosman.ravenow.utils.PasswordValidator
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -129,70 +121,19 @@ fun RemoveAccountScreen() {
|
|||||||
color = appColors.text
|
color = appColors.text
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Text(
|
TextInputField(
|
||||||
stringResource(R.string.remove_account_password_hint),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
fontSize = 16.sp,
|
text = inputPassword,
|
||||||
modifier = Modifier
|
onValueChange = {
|
||||||
.fillMaxWidth()
|
inputPassword = it
|
||||||
.padding(top = 16.dp, bottom = 4.dp),
|
if (passwordError != null) {
|
||||||
color = appColors.text
|
passwordError = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
password = true,
|
||||||
|
hint = stringResource(R.string.remove_account_password_hint),
|
||||||
|
error = passwordError
|
||||||
)
|
)
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.background(
|
|
||||||
appColors.inputBackground,
|
|
||||||
shape = RoundedCornerShape(24.dp)
|
|
||||||
)
|
|
||||||
.padding(vertical = 16.dp, horizontal = 16.dp)
|
|
||||||
){
|
|
||||||
|
|
||||||
BasicTextField(
|
|
||||||
value = inputPassword,
|
|
||||||
onValueChange = {
|
|
||||||
inputPassword = it
|
|
||||||
if (passwordError != null) {
|
|
||||||
passwordError = null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
textStyle = TextStyle(color = appColors.text),
|
|
||||||
cursorBrush = SolidColor(appColors.text)
|
|
||||||
)
|
|
||||||
if (inputPassword.isEmpty()) {
|
|
||||||
Text(
|
|
||||||
"Please enter your correct password",
|
|
||||||
modifier = Modifier.padding(start = 5.dp),
|
|
||||||
color = appColors.inputHint,
|
|
||||||
fontWeight = FontWeight.W600
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 显示密码错误信息
|
|
||||||
passwordError?.let {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(top = 4.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
|
||||||
androidx.compose.foundation.Image(
|
|
||||||
painter = painterResource(id = R.mipmap.rider_pro_input_error),
|
|
||||||
contentDescription = "Error",
|
|
||||||
modifier = Modifier.size(8.dp)
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.size(4.dp))
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = it,
|
|
||||||
color = androidx.compose.ui.graphics.Color.Red,
|
|
||||||
fontSize = 14.sp,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(top = 4.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
ActionButton(
|
ActionButton(
|
||||||
|
|||||||
@@ -35,7 +35,10 @@ import androidx.compose.material.Text
|
|||||||
import androidx.compose.material.pullrefresh.PullRefreshIndicator
|
import androidx.compose.material.pullrefresh.PullRefreshIndicator
|
||||||
import androidx.compose.material.pullrefresh.pullRefresh
|
import androidx.compose.material.pullrefresh.pullRefresh
|
||||||
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.ModalBottomSheet
|
||||||
|
import androidx.compose.material3.rememberModalBottomSheetState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
@@ -57,6 +60,7 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import com.aiosman.ravenow.AppState
|
import com.aiosman.ravenow.AppState
|
||||||
@@ -78,6 +82,7 @@ import com.aiosman.ravenow.ui.composables.toolbar.CollapsingToolbarScaffold
|
|||||||
import com.aiosman.ravenow.ui.composables.toolbar.ScrollStrategy
|
import com.aiosman.ravenow.ui.composables.toolbar.ScrollStrategy
|
||||||
import com.aiosman.ravenow.ui.composables.toolbar.rememberCollapsingToolbarScaffoldState
|
import com.aiosman.ravenow.ui.composables.toolbar.rememberCollapsingToolbarScaffoldState
|
||||||
import com.aiosman.ravenow.ui.index.IndexViewModel
|
import com.aiosman.ravenow.ui.index.IndexViewModel
|
||||||
|
import com.aiosman.ravenow.ui.post.MenuActionItem
|
||||||
import com.aiosman.ravenow.ui.index.tabs.profile.composable.OtherProfileAction
|
import com.aiosman.ravenow.ui.index.tabs.profile.composable.OtherProfileAction
|
||||||
import com.aiosman.ravenow.ui.index.tabs.profile.composable.SelfProfileAction
|
import com.aiosman.ravenow.ui.index.tabs.profile.composable.SelfProfileAction
|
||||||
import com.aiosman.ravenow.ui.index.tabs.profile.composable.UserAgentsList
|
import com.aiosman.ravenow.ui.index.tabs.profile.composable.UserAgentsList
|
||||||
@@ -91,7 +96,7 @@ import kotlinx.coroutines.delay
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class)
|
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ProfileV3(
|
fun ProfileV3(
|
||||||
onUpdateBanner: ((Uri, File, Context) -> Unit)? = null,
|
onUpdateBanner: ((Uri, File, Context) -> Unit)? = null,
|
||||||
@@ -117,6 +122,9 @@ fun ProfileV3(
|
|||||||
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
|
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
|
||||||
var expanded by remember { mutableStateOf(false) }
|
var expanded by remember { mutableStateOf(false) }
|
||||||
var minibarExpanded by remember { mutableStateOf(false) }
|
var minibarExpanded by remember { mutableStateOf(false) }
|
||||||
|
var showAgentMenu by remember { mutableStateOf(false) }
|
||||||
|
var contextAgent by remember { mutableStateOf<AgentEntity?>(null) }
|
||||||
|
var showDeleteConfirmDialog by remember { mutableStateOf(false) }
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
@@ -132,6 +140,7 @@ fun ProfileV3(
|
|||||||
val refreshState = rememberPullRefreshState(model.refreshing, onRefresh = {
|
val refreshState = rememberPullRefreshState(model.refreshing, onRefresh = {
|
||||||
model.loadProfile(pullRefresh = true)
|
model.loadProfile(pullRefresh = true)
|
||||||
})
|
})
|
||||||
|
val agentMenuModalState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||||
var miniToolbarHeight by remember { mutableStateOf(0) }
|
var miniToolbarHeight by remember { mutableStateOf(0) }
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
val appTheme = LocalAppTheme.current
|
val appTheme = LocalAppTheme.current
|
||||||
@@ -205,6 +214,67 @@ fun ProfileV3(
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Agent菜单弹窗
|
||||||
|
if (showAgentMenu) {
|
||||||
|
Log.d("ProfileV3", "Showing agent menu for: ${contextAgent?.title}")
|
||||||
|
ModalBottomSheet(
|
||||||
|
onDismissRequest = {
|
||||||
|
showAgentMenu = false
|
||||||
|
},
|
||||||
|
containerColor = AppColors.background,
|
||||||
|
sheetState = agentMenuModalState,
|
||||||
|
dragHandle = {},
|
||||||
|
shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
|
||||||
|
windowInsets = WindowInsets(0)
|
||||||
|
) {
|
||||||
|
AgentMenuModal(
|
||||||
|
agent = contextAgent,
|
||||||
|
onDeleteClick = {
|
||||||
|
scope.launch {
|
||||||
|
agentMenuModalState.hide()
|
||||||
|
showAgentMenu = false
|
||||||
|
showDeleteConfirmDialog = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onCloseClick = {
|
||||||
|
scope.launch {
|
||||||
|
agentMenuModalState.hide()
|
||||||
|
showAgentMenu = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isSelf = isSelf
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除确认对话框
|
||||||
|
if (showDeleteConfirmDialog) {
|
||||||
|
DeleteConfirmDialog(
|
||||||
|
agentName = contextAgent?.title ?: "",
|
||||||
|
onConfirm = {
|
||||||
|
// TODO: 实现删除逻辑
|
||||||
|
contextAgent?.let { agent ->
|
||||||
|
// 调用删除API
|
||||||
|
scope.launch {
|
||||||
|
try {
|
||||||
|
// 这里应该调用删除智能体的API
|
||||||
|
// agentService.deleteAgent(agent.id)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
showDeleteConfirmDialog = false
|
||||||
|
contextAgent = null
|
||||||
|
},
|
||||||
|
onDismiss = {
|
||||||
|
showDeleteConfirmDialog = false
|
||||||
|
contextAgent = null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.pullRefresh(refreshState)
|
modifier = Modifier.pullRefresh(refreshState)
|
||||||
) {
|
) {
|
||||||
@@ -418,6 +488,14 @@ fun ProfileV3(
|
|||||||
// 处理错误
|
// 处理错误
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onAgentLongClick = { agent ->
|
||||||
|
Log.d("ProfileV3", "onAgentLongClick called for agent: ${agent.title}, isSelf: $isSelf")
|
||||||
|
if (isSelf) { // 只有自己的智能体才能长按
|
||||||
|
Log.d("ProfileV3", "Setting contextAgent and showing menu")
|
||||||
|
contextAgent = agent
|
||||||
|
showAgentMenu = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -608,3 +686,159 @@ fun ProfileV3(
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Agent菜单弹窗
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun AgentMenuModal(
|
||||||
|
agent: AgentEntity?,
|
||||||
|
onDeleteClick: () -> Unit = {},
|
||||||
|
onCloseClick: () -> Unit = {},
|
||||||
|
isSelf: Boolean = true
|
||||||
|
) {
|
||||||
|
val AppColors = LocalAppTheme.current
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.background(AppColors.background)
|
||||||
|
.padding(vertical = 24.dp, horizontal = 20.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
"智能体",
|
||||||
|
fontSize = 18.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = AppColors.text
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
|
|
||||||
|
agent?.let {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.clip(RoundedCornerShape(8.dp))
|
||||||
|
.background(AppColors.nonActive)
|
||||||
|
.padding(8.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(24.dp)
|
||||||
|
.clip(CircleShape)
|
||||||
|
) {
|
||||||
|
CustomAsyncImage(
|
||||||
|
context = LocalContext.current,
|
||||||
|
imageUrl = it.avatar,
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentDescription = "Avatar",
|
||||||
|
defaultRes = R.mipmap.rider_pro_agent
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
Text(
|
||||||
|
it.title,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
color = AppColors.text
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
Text(
|
||||||
|
it.desc.ifEmpty { "暂无描述" },
|
||||||
|
maxLines = 2,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 32.dp),
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
color = AppColors.text,
|
||||||
|
fontSize = 14.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(32.dp))
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
if (isSelf) {
|
||||||
|
MenuActionItem(
|
||||||
|
icon = R.drawable.rider_pro_moment_delete,
|
||||||
|
text = "删除"
|
||||||
|
) {
|
||||||
|
onDeleteClick()
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.width(48.dp))
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuActionItem(
|
||||||
|
icon = R.drawable.rider_pro_more_horizon,
|
||||||
|
text = "更多"
|
||||||
|
) {
|
||||||
|
// TODO: 实现更多功能
|
||||||
|
onCloseClick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(48.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除确认对话框
|
||||||
|
*/
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun DeleteConfirmDialog(
|
||||||
|
agentName: String,
|
||||||
|
onConfirm: () -> Unit,
|
||||||
|
onDismiss: () -> Unit
|
||||||
|
) {
|
||||||
|
val AppColors = LocalAppTheme.current
|
||||||
|
|
||||||
|
androidx.compose.material3.AlertDialog(
|
||||||
|
onDismissRequest = onDismiss,
|
||||||
|
title = {
|
||||||
|
Text(
|
||||||
|
text = "确认删除",
|
||||||
|
color = AppColors.text,
|
||||||
|
fontSize = 18.sp,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
Text(
|
||||||
|
text = "确定要删除智能体「$agentName」吗?删除后无法恢复。",
|
||||||
|
color = AppColors.text,
|
||||||
|
fontSize = 14.sp
|
||||||
|
)
|
||||||
|
},
|
||||||
|
confirmButton = {
|
||||||
|
androidx.compose.material3.TextButton(
|
||||||
|
onClick = {
|
||||||
|
onConfirm()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
"删除",
|
||||||
|
color = AppColors.error,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
androidx.compose.material3.TextButton(
|
||||||
|
onClick = onDismiss
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
"取消",
|
||||||
|
color = AppColors.text
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
containerColor = AppColors.background
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package com.aiosman.ravenow.ui.index.tabs.profile.composable
|
package com.aiosman.ravenow.ui.index.tabs.profile.composable
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -46,7 +50,8 @@ fun UserAgentsRow(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onMoreClick: () -> Unit = {},
|
onMoreClick: () -> Unit = {},
|
||||||
onAgentClick: (AgentEntity) -> Unit = {},
|
onAgentClick: (AgentEntity) -> Unit = {},
|
||||||
onAvatarClick: (AgentEntity) -> Unit = {}
|
onAvatarClick: (AgentEntity) -> Unit = {},
|
||||||
|
onAgentLongClick: (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"}")
|
||||||
@@ -130,7 +135,8 @@ fun UserAgentsRow(
|
|||||||
AgentItem(
|
AgentItem(
|
||||||
agent = agent,
|
agent = agent,
|
||||||
onClick = { onAgentClick(agent) },
|
onClick = { onAgentClick(agent) },
|
||||||
onAvatarClick = { onAvatarClick(agent) }
|
onAvatarClick = { onAvatarClick(agent) },
|
||||||
|
onLongClick = { onAgentLongClick(agent) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,25 +154,50 @@ fun UserAgentsRow(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun AgentItem(
|
private fun AgentItem(
|
||||||
agent: AgentEntity,
|
agent: AgentEntity,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onClick: () -> Unit = {},
|
onClick: () -> Unit = {},
|
||||||
onAvatarClick: () -> Unit = {}
|
onAvatarClick: () -> Unit = {},
|
||||||
|
onLongClick: () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
val AppColors = LocalAppTheme.current
|
val AppColors = LocalAppTheme.current
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
.combinedClickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = null,
|
||||||
|
onClick = {
|
||||||
|
Log.d("AgentItem", "onClick triggered for agent: ${agent.title}")
|
||||||
|
onClick()
|
||||||
|
},
|
||||||
|
onLongClick = {
|
||||||
|
Log.d("AgentItem", "onLongClick triggered for agent: ${agent.title}")
|
||||||
|
onLongClick()
|
||||||
|
}
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
// 头像
|
// 头像
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(48.dp)
|
.size(48.dp)
|
||||||
.clip(CircleShape)
|
.clip(CircleShape)
|
||||||
.noRippleClickable { onAvatarClick() }
|
.combinedClickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = null,
|
||||||
|
onClick = {
|
||||||
|
Log.d("AgentItem", "Avatar clicked for agent: ${agent.title}")
|
||||||
|
onAvatarClick()
|
||||||
|
},
|
||||||
|
onLongClick = {
|
||||||
|
Log.d("AgentItem", "Avatar long clicked for agent: ${agent.title}")
|
||||||
|
onLongClick()
|
||||||
|
}
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
CustomAsyncImage(
|
CustomAsyncImage(
|
||||||
context = LocalContext.current,
|
context = LocalContext.current,
|
||||||
@@ -189,9 +220,7 @@ private fun AgentItem(
|
|||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
modifier = Modifier
|
modifier = Modifier.width(48.dp)
|
||||||
.width(48.dp)
|
|
||||||
.noRippleClickable { onClick() }
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user