Merge pull request #28 from Zhong202501/main

创建AI界面UI兼容;动态页面调整
This commit is contained in:
2025-09-22 10:48:57 +08:00
committed by GitHub
15 changed files with 562 additions and 382 deletions

View File

@@ -4,10 +4,10 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-09-09T09:51:06.656104400Z">
<DropdownSelection timestamp="2025-09-17T06:25:35.585100400Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="Default" identifier="serial=192.168.0.227:45035;connection=094cb92e" />
<DeviceId pluginId="Default" identifier="serial=192.168.0.216:5555;connection=698a7727" />
</handle>
</Target>
</DropdownSelection>

View File

@@ -29,10 +29,12 @@ import androidx.activity.compose.BackHandler
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
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.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@@ -63,6 +65,15 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import androidx.compose.foundation.border
import androidx.compose.ui.draw.shadow
import com.aiosman.ravenow.AppState
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.StartOffset
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.offset
/**
* 添加智能体界面
*/
@@ -75,6 +86,7 @@ fun AddAgentScreen() {
var agnetDescError by remember { mutableStateOf<String?>(null) }
var errorMessage by remember { mutableStateOf<String?>(null) }
var isProcessing by remember { mutableStateOf(false) }
var showWaveAnimation by remember { mutableStateOf(false) }
fun onNameChange(value: String) {
@@ -158,46 +170,44 @@ fun AddAgentScreen() {
Column(
modifier = Modifier
.fillMaxWidth()
.height(113.dp)
.height(90.dp)
.padding(horizontal = 20.dp),
) {
CustomAsyncImage(
context,
model.croppedBitmap,
Image(
painter = painterResource(id = R.mipmap.group_copy),
contentDescription = "",
modifier = Modifier
.size(48.dp)
.clip(
RoundedCornerShape(48.dp)
),
contentDescription = "",
contentScale = ContentScale.Crop,
placeholderRes = R.mipmap.group_copy
contentScale = ContentScale.Crop
)
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "Aoisan 你好呀!今天想创造什么?",
text = "${AppState.profile?.nickName ?: "User"} 你好呀!今天想创造什么?",
fontSize = 16.sp,
fontWeight = FontWeight.W600
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "只需要一句话你的专属AI将在这里诞生.",
fontSize = 14.sp
)
}
Spacer(modifier = Modifier.height(24.dp))
Spacer(modifier = Modifier.height(8.dp))
var showManualCreation by remember { mutableStateOf(false) }
if (!showManualCreation) {
Column(
modifier = Modifier
.padding(horizontal = 20.dp)
) {
Box {
FormTextInput2(
value = model.desc,
hint = "一个会写诗的AI一个懂你笑点的AI...",
background = appColors.inputBackground2,
modifier = Modifier.fillMaxWidth().height(95.dp)
// 阴影效果
Text(
text = "只需要一句话你的专属AI将在这里诞生。",
fontSize = 14.sp,
color = LocalAppTheme.current.text.copy(alpha = 0.6f),
)
Spacer(modifier = Modifier.height(24.dp))
Box(
modifier = Modifier
.fillMaxWidth()
.height(95.dp)
.shadow(
elevation = 10.dp,
shape = RoundedCornerShape(10.dp),
@@ -219,9 +229,33 @@ fun AddAgentScreen() {
color = appColors.inputBackground2,
shape = RoundedCornerShape(10.dp)
)
) {
val focusRequester = remember { FocusRequester() }
val keyboardController = LocalSoftwareKeyboardController.current
Box(
modifier = Modifier
.fillMaxSize()
.noRippleClickable {
model.viewModelScope.launch {
focusRequester.requestFocus()
keyboardController?.show()
}
}
)
FormTextInput2(
value = model.desc,
hint = "一个会写诗的AI一个懂你笑点的AI...",
background = appColors.inputBackground2,
focusRequester = focusRequester,
modifier = Modifier
.fillMaxWidth()
.height(95.dp)
) { value ->
onDescChange(value)
}
Row(
modifier = Modifier
.align(Alignment.BottomEnd)
@@ -231,6 +265,7 @@ fun AddAgentScreen() {
isProcessing = true
model.viewModelScope.launch {
try {
//AI美化功能待实现
} catch (e: Exception) {
e.printStackTrace()
} finally {
@@ -255,12 +290,98 @@ fun AddAgentScreen() {
)
}
}
}
Spacer(modifier = Modifier.height(24.dp))
if (showWaveAnimation) {
Row(
modifier = Modifier
.align(Alignment.Start)
.padding(start = 20.dp),
verticalAlignment = Alignment.CenterVertically
) {
Box(
modifier = Modifier.size(18.dp)
) {
val infiniteTransition = rememberInfiniteTransition()
val dot1Translation by infiniteTransition.animateFloat(
initialValue = 0f,
targetValue = -12f,
animationSpec = infiniteRepeatable(
animation = tween(
durationMillis = 1000,
easing = FastOutSlowInEasing
),
repeatMode = RepeatMode.Reverse,
initialStartOffset = StartOffset(0)
)
)
val dot2Translation by infiniteTransition.animateFloat(
initialValue = 0f,
targetValue = -12f,
animationSpec = infiniteRepeatable(
animation = tween(
durationMillis = 1000,
easing = FastOutSlowInEasing
),
repeatMode = RepeatMode.Reverse,
initialStartOffset = StartOffset(333)
)
)
val dot3Translation by infiniteTransition.animateFloat(
initialValue = 0f,
targetValue = -12f,
animationSpec = infiniteRepeatable(
animation = tween(
durationMillis = 1000,
easing = FastOutSlowInEasing
),
repeatMode = RepeatMode.Reverse,
initialStartOffset = StartOffset(666)
)
)
// 三个彩色圆点
Box(
modifier = Modifier
.padding(start = 20.dp, top = 24.dp,end = 213.dp)
.width(126.dp)
.size(6.dp)
.align(Alignment.BottomStart)
.offset(y = dot1Translation.dp)
.background(Color(0xFFFFD400), CircleShape)
)
Box(
modifier = Modifier
.size(6.dp)
.align(Alignment.BottomCenter)
.offset(y = dot2Translation.dp)
.background(Color(0xFF2F80FF), CircleShape)
)
Box(
modifier = Modifier
.size(6.dp)
.align(Alignment.BottomEnd)
.offset(y = dot3Translation.dp)
.background(Color(0xFF27C84D), CircleShape)
)
}
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "正在为你构思",
color = Color.Black.copy(alpha = 0.6f),
fontSize = 14.sp
)
}
} else {
Box(
modifier = Modifier
.align(Alignment.Start)
.padding(start = 20.dp)
.width(136.dp)
.height(40.dp)
.border(
width = 1.dp,
@@ -271,17 +392,20 @@ fun AddAgentScreen() {
color = appColors.background,
shape = RoundedCornerShape(12.dp),
)
.noRippleClickable {
showManualCreation = true
}
) {
Row(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp, vertical = 10.dp),
.padding(horizontal = 18.dp, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.mipmap.icons_infor_edit),
contentDescription = null,
modifier = Modifier.size(16.dp),
modifier = Modifier.size(18.dp),
)
Spacer(modifier = Modifier.width(8.dp))
Text(
@@ -292,23 +416,82 @@ fun AddAgentScreen() {
)
}
}
Spacer(modifier = Modifier.height(280.dp))
}
}else {
// 原版头像的加号
Box(
modifier = Modifier
.size(72.dp)
.clip(CircleShape)
.background(
brush = Brush.linearGradient(
colors = listOf(
Color(0x777c45ed),
Color(0x777c68ef),
Color(0x557bd8f8)
)
)
)
.align(Alignment.Start)
.noRippleClickable {
// 设置正在选择头像的标志
model.isSelectingAvatar = true
navController.navigate(NavigationRoute.AgentImageCrop.route)
},
contentAlignment = Alignment.Center
) {
Icon(
Icons.Default.Add,
contentDescription = "Add",
tint = Color.White,
)
}
Spacer(modifier = Modifier.height(18.dp))
// 原版两个输入框
Column(
modifier = Modifier
.padding(horizontal = 16.dp)
) {
FormTextInput(
value = model.name,
label = stringResource(R.string.agent_name),
hint = stringResource(R.string.agent_name_hint),
background = appColors.inputBackground2,
modifier = Modifier.fillMaxWidth(),
) { value ->
onNameChange(value)
}
FormTextInput2(
value = model.desc,
label = stringResource(R.string.agent_desc),
hint = stringResource(R.string.agent_desc_hint),
background = appColors.inputBackground2,
modifier = Modifier.fillMaxWidth(),
) { value ->
onDescChange(value)
}
}
}
// 错误信息显示
Spacer(modifier = Modifier.weight(1f))
Box(modifier = Modifier.fillMaxWidth()) {
errorMessage?.let { error ->
Text(
text = error,
color = Color.Red,
modifier = Modifier.padding(horizontal = 16.dp),
modifier = Modifier
.padding(bottom = 20.dp)
.align(Alignment.Center),
fontSize = 14.sp
)
Spacer(modifier = Modifier.height(16.dp))
}
}
ActionButton(
modifier = Modifier
.width(345.dp)
.padding(horizontal = 16.dp)
.padding(bottom = 40.dp)
.background(
brush = Brush.linearGradient(
colors = listOf(
@@ -330,12 +513,19 @@ fun AddAgentScreen() {
if (validationError != null) {
// 显示验证错误
errorMessage = validationError
model.viewModelScope.launch {
kotlinx.coroutines.delay(3000)
errorMessage = null
}
return@ActionButton
}
// 清除之前的错误信息
errorMessage = null
// 显示波动动画
showWaveAnimation = true
// 调用创建智能体API
model.viewModelScope.launch {
try {
@@ -346,6 +536,9 @@ fun AddAgentScreen() {
navController.popBackStack()
}
} catch (e: Exception) {
// 隐藏波动动画
showWaveAnimation = false
// 显示错误信息
errorMessage = "创建智能体失败: ${e.message}"
e.printStackTrace()

View File

@@ -69,72 +69,22 @@ fun EditCommentBottomModal(
.background(AppColors.background)
.padding(horizontal = 16.dp, vertical = 16.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Text(
if (replyComment == null) "Comment" else "Reply",
fontWeight = FontWeight.W600,
modifier = Modifier.weight(1f),
fontSize = 20.sp,
fontStyle = FontStyle.Italic,
color = AppColors.text
)
}
Spacer(modifier = Modifier.height(16.dp))
if (replyComment != null) {
Row(
verticalAlignment = Alignment.CenterVertically
) {
Box(
modifier = Modifier
.size(24.dp)
.clip(CircleShape)
) {
CustomAsyncImage(
context,
replyComment.avatar,
modifier = Modifier.fillMaxSize(),
contentDescription = "Avatar",
)
}
Spacer(modifier = Modifier.width(8.dp))
Text(
replyComment.name,
fontWeight = FontWeight.Bold,
fontSize = 16.sp,
color = AppColors.text
)
}
Spacer(modifier = Modifier.height(4.dp))
Text(
replyComment.comment,
maxLines = 1,
modifier = Modifier
.fillMaxWidth()
.padding(start = 32.dp),
overflow = TextOverflow.Ellipsis,
color = AppColors.text
)
Spacer(modifier = Modifier.height(16.dp))
}
Row(
modifier = Modifier
.fillMaxWidth(),
verticalAlignment = Alignment.Top
) {
Box(
Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.clip(RoundedCornerShape(20.dp))
.background(Color.White)
.border(1.dp, Color.Black, RoundedCornerShape(20.dp))
.background(Color.Gray.copy(alpha = 0.1f))
.padding(horizontal = 16.dp, vertical = 16.dp)
) {
Row(
verticalAlignment = Alignment.Top
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
BasicTextField(
value = text,
@@ -149,30 +99,39 @@ fun EditCommentBottomModal(
color = Color.Black,
fontWeight = FontWeight.Normal
),
minLines = 1
decorationBox = { innerTextField ->
Box(
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.CenterStart
) {
innerTextField()
if (text.isEmpty()) {
Text(
text = if (replyComment == null) "快来互动吧..." else "回复@${replyComment.name}",
color = AppColors.text.copy(alpha = 0.3f), // 30%透明度
)
Spacer(modifier = Modifier.width(8.dp))
Crossfade(
targetState = text.isNotEmpty(), animationSpec = tween(500),
label = ""
) { isNotEmpty ->
}
}
}
)
}
}
Spacer(modifier = Modifier.width(12.dp))
Icon(
painter = painterResource(id = R.mipmap.rider_pro_moment_post),
painter = painterResource(id = R.mipmap.btn),
contentDescription = "Send",
modifier = Modifier
.size(20.dp)
.align(Alignment.Top)
.size(40.dp)
.padding(top = 13.dp)
.noRippleClickable {
if (text.isNotEmpty()) {
onSend(text)
text = ""
}
},
tint = if (isNotEmpty) Color.Unspecified else AppColors.nonActive
tint = Color.Unspecified
)
}
}
}
}
Spacer(modifier = Modifier.height(navBarHeight))
}

View File

@@ -92,16 +92,22 @@ fun MomentCard(
showFollowButton = showFollowButton
)
}
val lastClickTime = remember { mutableStateOf(0L) }
val clickDelay = 500L
Column(
modifier = Modifier
.fillMaxWidth()
.noRippleClickable {
val currentTime = System.currentTimeMillis()
if (currentTime - lastClickTime.value > clickDelay) {
lastClickTime.value = currentTime
navController.navigateToPost(
momentEntity.id,
highlightCommentId = 0,
initImagePagerIndex = imageIndex
)
}
}
) {
MomentContentGroup(
momentEntity = momentEntity,
@@ -213,7 +219,6 @@ fun MomentPostLocation(location: String) {
text = location,
color = AppColors.secondaryText,
fontSize = 12.sp,
)
}
@@ -238,6 +243,8 @@ fun MomentTopRowGroup(
Row(
modifier = Modifier
) {
val lastClickTime = remember { mutableStateOf(0L) }
val clickDelay = 500L
CustomAsyncImage(
context,
momentEntity.avatar,
@@ -246,12 +253,16 @@ fun MomentTopRowGroup(
.size(40.dp)
.clip(RoundedCornerShape(40.dp))
.noRippleClickable {
val currentTime = System.currentTimeMillis()
if (currentTime - lastClickTime.value > clickDelay) {
lastClickTime.value = currentTime
navController.navigate(
NavigationRoute.AccountProfile.route.replace(
"{id}",
momentEntity.authorId.toString()
)
)
}
},
contentScale = ContentScale.Crop
)
@@ -267,7 +278,19 @@ fun MomentTopRowGroup(
verticalAlignment = Alignment.CenterVertically
) {
MomentName(
modifier = Modifier.weight(1f),
modifier = Modifier.weight(1f)
.noRippleClickable {
val currentTime = System.currentTimeMillis()
if (currentTime - lastClickTime.value > clickDelay) {
lastClickTime.value = currentTime
navController.navigate(
NavigationRoute.AccountProfile.route.replace(
"{id}",
momentEntity.authorId.toString()
)
)
}
},
name = momentEntity.nickname
)
Spacer(modifier = Modifier.width(16.dp))
@@ -416,6 +439,8 @@ fun MomentBottomOperateRowGroup(
momentEntity: MomentEntity,
imageIndex: Int = 0
) {
val lastClickTime = remember { mutableStateOf(0L) }
val clickDelay = 500L
var showCommentModal by remember { mutableStateOf(false) }
if (showCommentModal) {
ModalBottomSheet(
@@ -451,58 +476,14 @@ fun MomentBottomOperateRowGroup(
.height(56.dp)
.padding(start = 16.dp, end = 0.dp)
) {
Row(
Column(
modifier = Modifier.fillMaxSize()
) {
Box(
modifier = Modifier.fillMaxHeight(),
contentAlignment = Alignment.Center
) {
MomentOperateBtn(count = momentEntity.likeCount.toString()) {
AnimatedLikeIcon(
modifier = Modifier.size(24.dp),
liked = momentEntity.liked
) {
onLikeClick()
}
}
}
Spacer(modifier = Modifier.width(4.dp))
Box(
modifier = Modifier
.fillMaxHeight()
.noRippleClickable {
onCommentClick()
},
contentAlignment = Alignment.Center
) {
MomentOperateBtn(
icon = R.drawable.rider_pro_comment,
count = momentEntity.commentCount.toString()
)
}
Box(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
,
contentAlignment = Alignment.CenterEnd
) {
MomentOperateBtn(count = momentEntity.favoriteCount.toString()) {
AnimatedFavouriteIcon(
modifier = Modifier.size(24.dp),
isFavourite = momentEntity.isFavorite
) {
onFavoriteClick()
}
}
}
}
if (momentEntity.images.size > 1) {
Row(
modifier = Modifier.fillMaxSize(),
modifier = Modifier
.fillMaxWidth()
.weight(1f),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
@@ -523,8 +504,68 @@ fun MomentBottomOperateRowGroup(
}
}
Row(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
verticalAlignment = Alignment.CenterVertically
) {
Box(
modifier = Modifier
.weight(1f)
.fillMaxHeight(),
contentAlignment = Alignment.CenterStart
) {
MomentOperateBtn(count = momentEntity.favoriteCount.toString()) {
AnimatedFavouriteIcon(
modifier = Modifier.size(24.dp),
isFavourite = momentEntity.isFavorite
) {
onFavoriteClick()
}
}
}
Box(
modifier = Modifier
.wrapContentWidth()
.fillMaxHeight()
.noRippleClickable {
val currentTime = System.currentTimeMillis()
if (currentTime - lastClickTime.value > clickDelay) {
lastClickTime.value = currentTime
onCommentClick()
}
},
contentAlignment = Alignment.CenterEnd
) {
MomentOperateBtn(
icon = R.drawable.rider_pro_comment,
count = momentEntity.commentCount.toString()
)
}
Spacer(modifier = Modifier.width(24.dp))
Box(
modifier = Modifier
.wrapContentWidth()
.fillMaxHeight(),
contentAlignment = Alignment.CenterEnd
) {
MomentOperateBtn(count = momentEntity.likeCount.toString()) {
AnimatedLikeIcon(
modifier = Modifier.size(24.dp),
liked = momentEntity.liked
) {
onLikeClick()
}
}
}
}
}
}
}

View File

@@ -23,6 +23,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.res.painterResource
@@ -44,6 +46,7 @@ fun FormTextInput2(
error: String? = null,
hint: String? = null,
background: Color? = null,
focusRequester: FocusRequester? = null,
onValueChange: (String) -> Unit
) {
val AppColors = LocalAppTheme.current
@@ -97,6 +100,14 @@ fun FormTextInput2(
onValueChange = {
onValueChange(it)
},
modifier = Modifier
.let {
if (focusRequester != null) {
it.focusRequester(focusRequester)
} else {
it
}
},
textStyle = TextStyle(
fontSize = 16.sp,
fontWeight = FontWeight.Normal,

View File

@@ -362,7 +362,7 @@ fun IndexScreen() {
Text(
text = it.label(),
fontSize = 10.sp,
color = if (isSelected) AppColors.brandColorsColor else AppColors.text,
color = if (isSelected) Color.Blue else AppColors.text,
fontWeight = if (isSelected) FontWeight.W600 else FontWeight.Normal
)
}

View File

@@ -49,6 +49,8 @@ import com.aiosman.ravenow.ui.index.tabs.search.SearchViewModel
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
import kotlinx.coroutines.launch
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import com.aiosman.ravenow.ui.composables.TabItem
@@ -120,6 +122,8 @@ fun MomentsList() {
//
// }
// Spacer(modifier = Modifier.width(16.dp))
val lastClickTime = remember { mutableStateOf(0L) }
val clickDelay = 500L
Text(
text = stringResource(R.string.moment),
fontSize = 20.sp,
@@ -137,7 +141,11 @@ fun MomentsList() {
modifier = Modifier
.size(24.dp)
.noRippleClickable {
val currentTime = System.currentTimeMillis()
if (currentTime - lastClickTime.value > clickDelay) {
lastClickTime.value = currentTime
navController.navigate(NavigationRoute.Search.route)
}
},
colorFilter = ColorFilter.tint(AppColors.text)
)

View File

@@ -279,6 +279,7 @@ fun LoginPage() {
contentDescription = "Rave Now",
modifier = Modifier
.size(52.dp)
.clip(RoundedCornerShape(10.dp))
)
Spacer(modifier = Modifier.height(8.dp))
Text(

View File

@@ -917,7 +917,20 @@ fun Header(
Text(
text = nickname ?: "",
fontWeight = FontWeight.Bold,
modifier = Modifier.weight(1f),
modifier = Modifier
.weight(1f)
.debouncedClickable(debounceTime = 1000L) {
userId?.let {
debouncedNavigation {
navController.navigate(
NavigationRoute.AccountProfile.route.replace(
"{id}",
userId.toString()
)
)
}
}
},
color = AppColors.text,
fontSize = 17.sp
)
@@ -1196,7 +1209,7 @@ fun PostImageView(
)
}
// Navigation and Indicator container
// 图片导航控件
if (images.size > 1) {
Row(
modifier = Modifier
@@ -1347,91 +1360,19 @@ fun CommentItem(
}
) {}
) {
Row {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = commentEntity.name,
fontWeight = FontWeight.Bold,
fontSize = 11.sp,
color = AppColors.text
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = commentEntity.date.timeAgo(context),
fontSize = 11.sp,
color = Color.Gray
)
}
Row (modifier = Modifier.padding(top = 4.dp)){
if (isChild) {
val annotatedText = buildAnnotatedString {
if (commentEntity.replyUserId != null) {
pushStringAnnotation(
tag = "replyUser",
annotation = commentEntity.replyUserId.toString()
)
withStyle(
style = SpanStyle(
fontWeight = FontWeight.W600,
color = Color(0xFF6F94AE)
)
Column(
horizontalAlignment = Alignment.End
) {
append("@${commentEntity.replyUserNickname}")
}
pop()
}
append(" ${commentEntity.comment}")
}
Box {
CustomClickableText(
text = annotatedText,
onClick = { offset ->
annotatedText.getStringAnnotations(
tag = "replyUser",
start = offset,
end = offset
).firstOrNull()?.let {
debouncedNavigation {
navController.navigate(
NavigationRoute.AccountProfile.route.replace(
"{id}",
it.item
)
)
}
}
},
style = TextStyle(fontSize = 14.sp, color = AppColors.text),
onLongPress = {
onLongClick(commentEntity)
},
)
}
} else {
Text(
text = commentEntity.comment,
fontSize = 13.sp,
maxLines = Int.MAX_VALUE,
softWrap = true,
lineHeight = 20.sp,
color = AppColors.text,
modifier = Modifier.combinedClickable(
interactionSource = remember { MutableInteractionSource() },
indication = null,
onLongClick = {
onLongClick(
commentEntity
)
},
) {
}
)
}
}
Row (modifier = Modifier.padding(top = 12.dp),
verticalAlignment = Alignment.CenterVertically,){
AnimatedLikeIcon(
liked = commentEntity.liked,
onClick = {
@@ -1446,29 +1387,54 @@ fun CommentItem(
},
modifier = Modifier.size(16.dp)
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = commentEntity.likes.toString(),
fontSize = 12.sp,
fontWeight = FontWeight.Bold,
color = AppColors.text
color = AppColors.text,
modifier = Modifier.padding(top = 4.dp,end = 4.dp)
)
Text(
text = stringResource(R.string.like),
fontSize = 12.sp,
fontWeight = FontWeight.Bold,
color = AppColors.nonActiveText,
)
Spacer(modifier = Modifier.width(27.dp))
}
}
Icon(
painter = painterResource(id = R.drawable.rider_pro_comment),
contentDescription = "",
modifier = Modifier.size(16.dp),
tint = AppColors.nonActiveText
Text(
text = commentEntity.comment,
fontSize = 13.sp,
maxLines = Int.MAX_VALUE,
softWrap = true,
lineHeight = 20.sp,
color = AppColors.text,
modifier = Modifier
.fillMaxWidth()
.padding(end = 50.dp)
.padding(top = 0.dp)
.combinedClickable(
interactionSource = remember { MutableInteractionSource() },
indication = null,
onLongClick = {
onLongClick(
commentEntity
)
Spacer(modifier = Modifier.width(4.dp))
},
) {
}
)
Row (
modifier = Modifier.padding(top = 12.dp),
verticalAlignment = Alignment.CenterVertically,
){
Text(
text = commentEntity.date.timeAgo(context),
fontSize = 12.sp,
color = Color.Gray
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = stringResource(R.string.reply),
fontSize = 12.sp,
@@ -1541,6 +1507,7 @@ fun CommentItem(
}
}
@Composable
fun PostBottomBar(
onCreateCommentClick: () -> Unit = {},
@@ -1607,6 +1574,24 @@ fun PostBottomBar(
}
}
Spacer(modifier = Modifier.width(16.dp))
AnimatedFavouriteIcon(
isFavourite = momentEntity?.isFavorite == true,
onClick = {
// 检查游客模式,如果是游客则跳转登录
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.LIKE_MOMENT)) {
debouncedNavigation {
navController.navigate(NavigationRoute.Login.route)
}
} else {
onFavoriteClick()
}
},
modifier = Modifier.size(24.dp)
)
Spacer(modifier = Modifier.width(4.dp))
Text(text = momentEntity?.favoriteCount.toString(), color = AppColors.text)
Spacer(modifier = Modifier.width(16.dp))
AnimatedLikeIcon(
liked = momentEntity?.liked == true,
onClick = {
@@ -1623,24 +1608,6 @@ fun PostBottomBar(
)
Spacer(modifier = Modifier.width(4.dp))
Text(text = momentEntity?.likeCount.toString(), color = AppColors.text)
Spacer(modifier = Modifier.width(16.dp))
AnimatedFavouriteIcon(
isFavourite = momentEntity?.isFavorite == true,
onClick = {
// 检查游客模式,如果是游客则跳转登录
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.LIKE_MOMENT)) {
debouncedNavigation {
navController.navigate(NavigationRoute.Login.route)
}
} else {
onFavoriteClick()
}
},
modifier = Modifier.size(24.dp)
)
Spacer(modifier = Modifier.width(4.dp))
Text(text = momentEntity?.favoriteCount.toString(), color = AppColors.text)
}
BottomNavigationPlaceholder(
color = AppColors.background

Binary file not shown.

After

Width:  |  Height:  |  Size: 975 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -17,7 +17,7 @@
<string name="following_upper">关注</string>
<string name="unfollow_upper">取消关注</string>
<string name="comment_count">%d条评论</string>
<string name="post_comment_hint">说点什么</string>
<string name="post_comment_hint">快来互动吧...</string>
<string name="follow_upper">关注</string>
<string name="login_upper">登录</string>
<string name="lets_ride_upper">确认</string>