merge conflict

This commit is contained in:
2025-09-09 17:57:28 +08:00
28 changed files with 528 additions and 373 deletions

View File

@@ -13,7 +13,7 @@
android:allowBackup="false" android:allowBackup="false"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/rider_pro_logo_next" android:icon="@mipmap/invalid_name"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/rider_pro_logo_next_round" android:roundIcon="@mipmap/rider_pro_logo_next_round"
android:supportsRtl="true" android:supportsRtl="true"

View File

@@ -3,9 +3,9 @@ package com.aiosman.ravenow
object ConstVars { object ConstVars {
// api 地址 // api 地址
// const val BASE_SERVER = "http://192.168.31.131:8088" // const val BASE_SERVER = "http://192.168.31.131:8088"
// const val BASE_SERVER = "http://192.168.142.141:8088" const val BASE_SERVER = "http://192.168.0.201:8088"
// const val BASE_SERVER = "http://192.168.0.228:8088" // const val BASE_SERVER = "http://192.168.0.228:8088"
const val BASE_SERVER = "https://rider-pro.aiosman.com/beta_api" // const val BASE_SERVER = "https://rider-pro.aiosman.com/beta_api"
const val MOMENT_LIKE_CHANNEL_ID = "moment_like" const val MOMENT_LIKE_CHANNEL_ID = "moment_like"
const val MOMENT_LIKE_CHANNEL_NAME = "Moment Like" const val MOMENT_LIKE_CHANNEL_NAME = "Moment Like"

View File

@@ -160,7 +160,7 @@ fun EditCommentBottomModal(
painter = painterResource(id = R.mipmap.rider_pro_moment_post), painter = painterResource(id = R.mipmap.rider_pro_moment_post),
contentDescription = "Send", contentDescription = "Send",
modifier = Modifier modifier = Modifier
.size(25.dp) .size(20.dp)
.align(Alignment.Top) .align(Alignment.Top)
.noRippleClickable { .noRippleClickable {
if (text.isNotEmpty()) { if (text.isNotEmpty()) {
@@ -168,7 +168,7 @@ fun EditCommentBottomModal(
text = "" text = ""
} }
}, },
tint = if (isNotEmpty) AppColors.main else AppColors.nonActive tint = if (isNotEmpty) Color.Unspecified else AppColors.nonActive
) )
} }
} }

View File

@@ -37,12 +37,12 @@ fun TabItem(
) { ) {
Text( Text(
text = text, text = text,
fontSize = 14.sp, fontSize = 15.sp,
color = if (isSelected) AppColors.tabSelectedText else AppColors.tabUnselectedText, color = if (isSelected) AppColors.tabSelectedText else AppColors.tabUnselectedText,
modifier = Modifier modifier = Modifier
.clip(RoundedCornerShape(8.dp)) .clip(RoundedCornerShape(12.dp))
.background(if (isSelected) AppColors.tabSelectedBackground else AppColors.tabUnselectedBackground) .background(if (isSelected) AppColors.tabSelectedBackground else AppColors.tabUnselectedBackground)
.padding(horizontal = 11.dp, vertical = 4.dp) .padding(horizontal = 16.dp, vertical = 8.dp)
) )
} }
} }

View File

@@ -18,7 +18,11 @@ import com.aiosman.ravenow.data.AccountService
import com.aiosman.ravenow.data.AccountServiceImpl import com.aiosman.ravenow.data.AccountServiceImpl
import com.aiosman.ravenow.data.UserService import com.aiosman.ravenow.data.UserService
import com.aiosman.ravenow.data.UserServiceImpl import com.aiosman.ravenow.data.UserServiceImpl
import com.aiosman.ravenow.entity.CommentEntity
import com.aiosman.ravenow.exp.formatChatTime
import com.aiosman.ravenow.ui.NavigationRoute
import com.aiosman.ravenow.ui.navigateToChat
import com.aiosman.ravenow.utils.TrtcHelper
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch

View File

@@ -91,6 +91,7 @@ fun IndexScreen() {
val navController = LocalNavController.current val navController = LocalNavController.current
val item = listOf( val item = listOf(
NavigationItem.Home, NavigationItem.Home,
//NavigationItem.Dynamic,
NavigationItem.Ai, NavigationItem.Ai,
NavigationItem.Add, NavigationItem.Add,
NavigationItem.Notification, NavigationItem.Notification,
@@ -378,8 +379,8 @@ fun IndexScreen() {
userScrollEnabled = false userScrollEnabled = false
) { page -> ) { page ->
when (page) { when (page) {
0 -> Home() 0 -> Agent()
1 -> Agent() 1 -> Home()
2 -> Add() 2 -> Add()
3 -> Notifications() 3 -> Notifications()
4 -> Profile() 4 -> Profile()

View File

@@ -22,10 +22,15 @@ sealed class NavigationItem(
) )
data object Ai : NavigationItem("Ai", data object Ai : NavigationItem("Ai",
icon = { R.drawable.rider_pro_nav_ai }, icon = { R.mipmap.bars_x_buttons_discover_bold},
selectedIcon = { R.mipmap.rider_pro_nav_ai_hl }, selectedIcon = { R.mipmap.dynamic_hl },
label = { stringResource(R.string.main_ai) } label = { stringResource(R.string.index_dynamic) }
) )
// data object Ai : NavigationItem("Ai",
// icon = { R.drawable.rider_pro_nav_ai },
// selectedIcon = { R.mipmap.rider_pro_nav_ai_hl },
// label = { stringResource(R.string.main_ai) }
// )
data object Add : NavigationItem("Add", data object Add : NavigationItem("Add",
icon = { R.drawable.ic_nav_add }, icon = { R.drawable.ic_nav_add },

View File

@@ -43,6 +43,7 @@ import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource 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.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
@@ -60,6 +61,7 @@ import com.aiosman.ravenow.ui.index.tabs.ai.tabs.hot.HotAgent
import com.aiosman.ravenow.ui.modifiers.noRippleClickable import com.aiosman.ravenow.ui.modifiers.noRippleClickable
import com.aiosman.ravenow.ui.composables.TabItem import com.aiosman.ravenow.ui.composables.TabItem
import com.aiosman.ravenow.ui.composables.TabSpacer import com.aiosman.ravenow.ui.composables.TabSpacer
import com.aiosman.ravenow.ui.index.tabs.moment.CustomTabItem
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.expolre.AgentItem import com.aiosman.ravenow.ui.index.tabs.moment.tabs.expolre.AgentItem
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.expolre.ExploreViewModel import com.aiosman.ravenow.ui.index.tabs.moment.tabs.expolre.ExploreViewModel
import com.aiosman.ravenow.utils.DebounceUtils import com.aiosman.ravenow.utils.DebounceUtils
@@ -101,7 +103,7 @@ fun Agent() {
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding( .padding(
top = statusBarPaddingValues.calculateTopPadding()+18.dp, top = statusBarPaddingValues.calculateTopPadding(),
bottom = navigationBarPaddings, bottom = navigationBarPaddings,
start = 16.dp, start = 16.dp,
end = 16.dp end = 16.dp
@@ -111,92 +113,178 @@ fun Agent() {
Row( Row(
modifier = Modifier modifier = Modifier
.wrapContentHeight() .wrapContentHeight()
.height(44.dp)
.fillMaxWidth(), .fillMaxWidth(),
horizontalArrangement = Arrangement.Start, horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
// 搜索框 androidx.compose.material3.Text(
Row( text = "Rave AI",
fontSize = 20.sp,
fontWeight = FontWeight.W900,
color = AppColors.text,
modifier = Modifier modifier = Modifier
.height(36.dp) .align(Alignment.CenterVertically)
.weight(1f) )
.clip(shape = RoundedCornerShape(8.dp))
.background(AppColors.inputBackground) Spacer(modifier = Modifier.weight(1f))
.padding(horizontal = 8.dp, vertical = 0.dp)
.noRippleClickable { Image(
// 搜索框点击事件 painter = painterResource(id = R.drawable.rider_pro_nav_search),
}, contentDescription = "search",
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.rider_pro_nav_search),
contentDescription = null,
tint = AppColors.inputHint
)
Box {
Text(
text = stringResource(R.string.search),
modifier = Modifier.padding(start = 8.dp),
color = AppColors.inputHint,
fontSize = 17.sp
)
}
}
Spacer(modifier = Modifier.width(16.dp))
// 新增
Icon(
modifier = Modifier modifier = Modifier
.size(36.dp) .size(24.dp)
.noRippleClickable { .noRippleClickable {
if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) { navController.navigate(NavigationRoute.Search.route)
// 检查游客模式,如果是游客则跳转登录
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CREATE_AGENT)) {
navController.navigate(NavigationRoute.Login.route)
} else {
// 导航到添加智能体页面
navController.navigate(
NavigationRoute.AddAgent.route
)
}
}) {
lastClickTime = System.currentTimeMillis()
}
}, },
painter = painterResource(id = R.drawable.rider_pro_new_post_add_pic), colorFilter = ColorFilter.tint(AppColors.text)
contentDescription = null,
tint = AppColors.text
) )
} }
// 推荐Agent Spacer(modifier = Modifier.height(15.dp))
// // 搜索框
// Row(
// modifier = Modifier
// .height(36.dp)
// .weight(1f)
// .clip(shape = RoundedCornerShape(8.dp))
// .background(AppColors.inputBackground)
// .padding(horizontal = 8.dp, vertical = 0.dp)
// .noRippleClickable {
// // 搜索框点击事件
// },
// verticalAlignment = Alignment.CenterVertically
// ) {
// Icon(
// painter = painterResource(id = R.drawable.rider_pro_nav_search),
// contentDescription = null,
// tint = AppColors.inputHint
// )
// Box {
// Text(
// text = stringResource(R.string.search),
// modifier = Modifier.padding(start = 8.dp),
// color = AppColors.inputHint,
// fontSize = 17.sp
// )
// }
// }
// Spacer(modifier = Modifier.width(16.dp))
// // 创建智能体
// Icon(
// modifier = Modifier
// .size(36.dp)
// .noRippleClickable {
// if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
// // 检查游客模式,如果是游客则跳转登录
// if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CREATE_AGENT)) {
// navController.navigate(NavigationRoute.Login.route)
// } else {
// // 导航到添加智能体页面
// navController.navigate(
// NavigationRoute.AddAgent.route
// )
// }
// }) {
// lastClickTime = System.currentTimeMillis()
// }
// },
// painter = painterResource(id = R.drawable.rider_pro_new_post_add_pic),
// contentDescription = null,
// tint = AppColors.text
// )
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(260.dp) .height(400.dp)
.padding(vertical = 8.dp) .padding(vertical = 8.dp)
) { ) {
// 标题
// // 标题
// Row(
// verticalAlignment = Alignment.CenterVertically,
// modifier = Modifier.padding(bottom = 12.dp)
// ) {
// Image(
// painter = painterResource(R.mipmap.rider_pro_agent2),
// contentDescription = "agent",
// modifier = Modifier.size(28.dp),
//
// )
// Spacer(modifier = Modifier.width(4.dp))
// androidx.compose.material3.Text(
// text = stringResource(R.string.agent_recommend_agent),
// fontSize = 16.sp,
// fontWeight = androidx.compose.ui.text.font.FontWeight.W600,
// color = AppColors.text
// )
// }
// 标签页
Row( Row(
verticalAlignment = Alignment.CenterVertically, modifier = Modifier
modifier = Modifier.padding(bottom = 12.dp) .fillMaxWidth()
.wrapContentHeight()
.padding( bottom = 16.dp),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.Bottom
) { ) {
Image( // 推荐标签(默认选中)
painter = painterResource(R.mipmap.rider_pro_agent2), CustomTabItem(
contentDescription = "agent", text = stringResource(R.string.agent_recommend),
modifier = Modifier.size(28.dp), isSelected = true,
onClick = {
) // TODO: 实现点击切换逻辑
Spacer(modifier = Modifier.width(4.dp)) }
androidx.compose.material3.Text(
text = stringResource(R.string.agent_recommend_agent),
fontSize = 16.sp,
fontWeight = androidx.compose.ui.text.font.FontWeight.W600,
color = AppColors.text
) )
}
TabSpacer()
// Scenes标签
CustomTabItem(
text = "scenes",
isSelected = false,
onClick = {
// TODO: 实现点击切换逻辑
}
)
TabSpacer()
// Voices标签
CustomTabItem(
text = "voices",
isSelected = false,
onClick = {
// TODO: 实现点击切换逻辑
}
)
TabSpacer()
// Anime标签
CustomTabItem(
text = "anime",
isSelected = false,
onClick = {
// TODO: 实现点击切换逻辑
}
)
// TabSpacer()
//
// // Assist标签
// CustomTabItem(
// text = "assist",
// isSelected = false,
// onClick = {
// // TODO: 实现点击切换逻辑
// }
// )
}
// Agent ViewPager // Agent ViewPager
AgentViewPagerSection(agentItems = viewModel.agentItems.take(9),viewModel) AgentViewPagerSection(agentItems = viewModel.agentItems.take(15),viewModel)
} }
Spacer(modifier = Modifier.height(0.dp)) Spacer(modifier = Modifier.height(0.dp))
@@ -312,8 +400,8 @@ fun Agent() {
fun AgentViewPagerSection(agentItems: List<AgentItem>,viewModel: AgentViewModel) { fun AgentViewPagerSection(agentItems: List<AgentItem>,viewModel: AgentViewModel) {
val AppColors = LocalAppTheme.current val AppColors = LocalAppTheme.current
// 每页显示3个agent // 每页显示5个agent
val itemsPerPage = 3 val itemsPerPage = 5
val totalPages = (agentItems.size + itemsPerPage - 1) / itemsPerPage val totalPages = (agentItems.size + itemsPerPage - 1) / itemsPerPage
if (totalPages > 0) { if (totalPages > 0) {
@@ -323,7 +411,7 @@ fun AgentViewPagerSection(agentItems: List<AgentItem>,viewModel: AgentViewModel)
// Agent内容 // Agent内容
Box( Box(
modifier = Modifier modifier = Modifier
.height(180.dp) .height(300.dp)
) { ) {
HorizontalPager( HorizontalPager(
state = pagerState, state = pagerState,
@@ -344,7 +432,8 @@ fun AgentViewPagerSection(agentItems: List<AgentItem>,viewModel: AgentViewModel)
viewModel = viewModel, viewModel = viewModel,
agentItems = agentItems.drop(page * itemsPerPage).take(itemsPerPage), agentItems = agentItems.drop(page * itemsPerPage).take(itemsPerPage),
page = page, page = page,
modifier = Modifier.height(180.dp) modifier = Modifier
.height(300.dp)
.graphicsLayer { .graphicsLayer {
scaleX = scale scaleX = scale
scaleY = scale scaleY = scale
@@ -368,7 +457,9 @@ fun AgentViewPagerSection(agentItems: List<AgentItem>,viewModel: AgentViewModel)
.padding(horizontal = 4.dp) .padding(horizontal = 4.dp)
.size(3.dp) .size(3.dp)
.background( .background(
color = if (pagerState.currentPage == index) AppColors.text else AppColors.secondaryText.copy(alpha = 0.3f), color = if (pagerState.currentPage == index) AppColors.text else AppColors.secondaryText.copy(
alpha = 0.3f
),
shape = androidx.compose.foundation.shape.CircleShape shape = androidx.compose.foundation.shape.CircleShape
) )
) )
@@ -416,8 +507,8 @@ fun AgentCard2(viewModel: AgentViewModel,agentItem: AgentItem,navController: Nav
.background(Color(0xFFF5F5F5), RoundedCornerShape(24.dp)) .background(Color(0xFFF5F5F5), RoundedCornerShape(24.dp))
.clickable { .clickable {
if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) { if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
viewModel.goToProfile(agentItem.openId, navController) viewModel.goToProfile(agentItem.openId, navController)
}) { }) {
lastClickTime = System.currentTimeMillis() lastClickTime = System.currentTimeMillis()
} }
}, },
@@ -482,14 +573,17 @@ fun AgentCard2(viewModel: AgentViewModel,agentItem: AgentItem,navController: Nav
) )
.clickable { .clickable {
if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) { if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
// 检查游客模式,如果是游客则跳转登录 // 检查游客模式,如果是游客则跳转登录
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CHAT_WITH_AGENT)) { if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CHAT_WITH_AGENT)) {
navController.navigate(NavigationRoute.Login.route) navController.navigate(NavigationRoute.Login.route)
} else { } else {
viewModel.createSingleChat(agentItem.openId) viewModel.createSingleChat(agentItem.openId)
viewModel.goToChatAi(agentItem.openId, navController = navController) viewModel.goToChatAi(
} agentItem.openId,
}) { navController = navController
)
}
}) {
lastClickTime = System.currentTimeMillis() lastClickTime = System.currentTimeMillis()
} }
}, },

View File

@@ -140,143 +140,183 @@ fun NotificationsScreen() {
Column( Column(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
) { ) {
Row( Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 15.dp),
verticalAlignment = Alignment.CenterVertically
) {
Box(
modifier = Modifier modifier = Modifier
.size(24.dp) .fillMaxWidth()
) .height(44.dp)
Column( .padding(horizontal = 16.dp),
modifier = Modifier horizontalArrangement = Arrangement.Start,
.weight(1f) verticalAlignment = Alignment.CenterVertically
.align(Alignment.CenterVertically),
horizontalAlignment = Alignment.CenterHorizontally
) { ) {
Text( Text(
text = stringResource(R.string.main_message), text = stringResource(R.string.main_message),
fontSize = 17.sp, fontSize = 20.sp,
fontWeight = FontWeight.W700, fontWeight = FontWeight.W900,
color = AppColors.text color = AppColors.text
) )
}
Image( Spacer(modifier = Modifier.weight(1f))
painter = painterResource(id = R.drawable.rider_pro_group),
contentDescription = "add",
modifier = Modifier
.size(24.dp)
.noRippleClickable {
debouncer {
navController.navigate(NavigationRoute.CreateGroupChat.route)
}
},
colorFilter = ColorFilter.tint(AppColors.text)
)
Image(
}
// 搜索栏//
Box(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp)
.height(40.dp)
.noRippleClickable {
},
contentAlignment = Alignment.CenterStart
) {
Row(
modifier = Modifier
.height(36.dp)
.fillMaxWidth()
.clip(shape = RoundedCornerShape(8.dp))
.background(AppColors.inputBackground)
.padding(horizontal = 8.dp, vertical = 0.dp)
.noRippleClickable {
// 搜索框点击事件
},
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.rider_pro_nav_search), painter = painterResource(id = R.drawable.rider_pro_nav_search),
contentDescription = null, contentDescription = "search",
tint = AppColors.inputHint modifier = Modifier
.size(24.dp)
.noRippleClickable {
// TODO: 实现搜索功能
},
colorFilter = ColorFilter.tint(AppColors.text)
) )
Spacer(modifier = Modifier.width(16.dp))
Box { Box {
androidx.compose.material.Text( Image(
text = stringResource(R.string.search), painter = painterResource(id = R.drawable.rider_pro_notification),
modifier = Modifier.padding(start = 8.dp), contentDescription = "notifications",
color = AppColors.inputHint, modifier = Modifier
fontSize = 17.sp .size(24.dp)
.noRippleClickable {
// TODO: 实现通知功能
},
colorFilter = ColorFilter.tint(AppColors.text)
) )
}
}
}
Row( // 通知红点
modifier = Modifier val totalNoticeCount = MessageListViewModel.likeNoticeCount +
.fillMaxWidth() MessageListViewModel.followNoticeCount +
.padding(horizontal = 16.dp), MessageListViewModel.commentNoticeCount +
horizontalArrangement = Arrangement.SpaceBetween, MessageListViewModel.favouriteNoticeCount
) {
val likeDebouncer = rememberDebouncer()
val followDebouncer = rememberDebouncer()
val commentDebouncer = rememberDebouncer()
NotificationIndicator( if (totalNoticeCount > 0) {
MessageListViewModel.likeNoticeCount, Box(
R.mipmap.rider_pro_like, modifier = Modifier
stringResource(R.string.like_upper), .size(8.dp)
Color(0xFFFAFD5D) .background(
) { color = Color(0xFFFF3B30),
likeDebouncer { shape = CircleShape
if (MessageListViewModel.likeNoticeCount > 0) { )
// 刷新点赞消息列表 .align(Alignment.TopEnd)
LikeNoticeViewModel.isFirstLoad = true .offset(x = 8.dp, y = (-4).dp)
// 清除点赞消息数量 )
MessageListViewModel.clearLikeNoticeCount()
} }
navController.navigate(NavigationRoute.Likes.route)
} }
} }
NotificationIndicator(
MessageListViewModel.followNoticeCount, //创建群聊//
R.mipmap.rider_pro_followers, // Image(
stringResource(R.string.followers_upper), // painter = painterResource(id = R.drawable.rider_pro_group),
Color(0xFFF470FE) // contentDescription = "add",
) { // modifier = Modifier
followDebouncer { // .size(24.dp)
if (MessageListViewModel.followNoticeCount > 0) { // .noRippleClickable {
// 刷新关注消息列表 // debouncer {
FollowerNoticeViewModel.isFirstLoad = true // navController.navigate(NavigationRoute.CreateGroupChat.route)
MessageListViewModel.clearFollowNoticeCount() // }
} // },
navController.navigate(NavigationRoute.Followers.route) // colorFilter = ColorFilter.tint(AppColors.text)
} // )
}
NotificationIndicator(
MessageListViewModel.commentNoticeCount, // // 搜索栏//
R.mipmap.rider_pro_comment, // Box(
stringResource(R.string.comment).uppercase(), // modifier = Modifier
Color(0xFF6246FF) // .fillMaxWidth()
) { // .padding(horizontal = 16.dp, vertical = 8.dp)
commentDebouncer { // .height(40.dp)
navController.navigate(NavigationRoute.CommentNoticeScreen.route) //
} // .noRippleClickable {
} // },
} // contentAlignment = Alignment.CenterStart
// )
// {
// Row(
// modifier = Modifier
// .height(36.dp)
// .fillMaxWidth()
// .clip(shape = RoundedCornerShape(8.dp))
// .background(AppColors.inputBackground)
// .padding(horizontal = 8.dp, vertical = 0.dp)
// .noRippleClickable {
// // 搜索框点击事件
// },
// verticalAlignment = Alignment.CenterVertically
// ) {
// Icon(
// painter = painterResource(id = R.drawable.rider_pro_nav_search),
// contentDescription = null,
// tint = AppColors.inputHint
// )
// Box {
// androidx.compose.material.Text(
// text = stringResource(R.string.search),
// modifier = Modifier.padding(start = 8.dp),
// color = AppColors.inputHint,
// fontSize = 17.sp
// )
// }
// }
// }
//赞、粉丝、评论//
// Row(
// modifier = Modifier
// .fillMaxWidth()
// .padding(horizontal = 16.dp),
// horizontalArrangement = Arrangement.SpaceBetween,
// ) {
// val likeDebouncer = rememberDebouncer()
// val followDebouncer = rememberDebouncer()
// val commentDebouncer = rememberDebouncer()
//
// NotificationIndicator(
// MessageListViewModel.likeNoticeCount,
// R.mipmap.rider_pro_like,
// stringResource(R.string.like_upper),
// Color(0xFFFAFD5D)
// ) {
// likeDebouncer {
// if (MessageListViewModel.likeNoticeCount > 0) {
// // 刷新点赞消息列表
// LikeNoticeViewModel.isFirstLoad = true
// // 清除点赞消息数量
// MessageListViewModel.clearLikeNoticeCount()
// }
// navController.navigate(NavigationRoute.Likes.route)
// }
// }
// NotificationIndicator(
// MessageListViewModel.followNoticeCount,
// R.mipmap.rider_pro_followers,
// stringResource(R.string.followers_upper),
// Color(0xFFF470FE)
// ) {
// followDebouncer {
// if (MessageListViewModel.followNoticeCount > 0) {
// // 刷新关注消息列表
// FollowerNoticeViewModel.isFirstLoad = true
// MessageListViewModel.clearFollowNoticeCount()
// }
// navController.navigate(NavigationRoute.Followers.route)
// }
// }
// NotificationIndicator(
// MessageListViewModel.commentNoticeCount,
// R.mipmap.rider_pro_comment,
// stringResource(R.string.comment).uppercase(),
// Color(0xFF6246FF)
// ) {
// commentDebouncer {
// navController.navigate(NavigationRoute.CommentNoticeScreen.route)
// }
// }
// }
Spacer(modifier = Modifier.height(23.dp))
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.wrapContentHeight() .wrapContentHeight()
.padding(start = 16.dp,bottom = 16.dp), .padding(start = 16.dp,bottom = 16.dp),
// center the tabs
horizontalArrangement = Arrangement.Start, horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.Bottom verticalAlignment = Alignment.Bottom
) { ) {

View File

@@ -30,9 +30,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource import androidx.compose.ui.res.vectorResource
@@ -51,6 +48,12 @@ import com.aiosman.ravenow.ui.index.tabs.moment.tabs.timeline.TimelineMomentsLis
import com.aiosman.ravenow.ui.index.tabs.search.SearchViewModel import com.aiosman.ravenow.ui.index.tabs.search.SearchViewModel
import com.aiosman.ravenow.ui.modifiers.noRippleClickable import com.aiosman.ravenow.ui.modifiers.noRippleClickable
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import com.aiosman.ravenow.ui.composables.TabItem
import com.aiosman.ravenow.ui.composables.TabSpacer
import com.aiosman.ravenow.ui.composables.rememberDebouncer
/** /**
* 动态列表 * 动态列表
@@ -63,8 +66,8 @@ fun MomentsList() {
val navigationBarPaddings = val navigationBarPaddings =
WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() + 48.dp WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() + 48.dp
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues() val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
// 游客模式下不显示timeline只显示3个tabExplore、Dynamic、Hot // 游客模式下不显示timeline只显示2个tabDynamic、Hot // 游客模式下不显示timeline只显示3个tabExplore、Dynamic、Hot
val tabCount = if (AppStore.isGuest) 3 else 4 val tabCount = if (AppStore.isGuest) 2 else 3 // val tabCount = if (AppStore.isGuest) 3 else 4
var pagerState = rememberPagerState { tabCount } var pagerState = rememberPagerState { tabCount }
var scope = rememberCoroutineScope() var scope = rememberCoroutineScope()
Column( Column(
@@ -79,154 +82,143 @@ fun MomentsList() {
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(44.dp), .height(44.dp)
.padding(horizontal = 16.dp),
// center the tabs // center the tabs
horizontalArrangement = Arrangement.Start, horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Column( //原探索//
// Column(
// modifier = Modifier
// .noRippleClickable {
// scope.launch {
// pagerState.animateScrollToPage(0)
// }
// }.padding(start = 16.dp),
// verticalArrangement = Arrangement.Center,
// horizontalAlignment = Alignment.CenterHorizontally
//
// ) {
// Text(
// text = stringResource(R.string.index_worldwide),
// fontSize = if (pagerState.currentPage == 0)18.sp else 16.sp,
// color = if (pagerState.currentPage == 0) AppColors.text else AppColors.nonActiveText,
// fontWeight = FontWeight.W600)
// Spacer(modifier = Modifier.height(4.dp))
//
// Image(
// painter = painterResource(
// if (pagerState.currentPage == 0) R.mipmap.tab_indicator_selected
// else R.drawable.tab_indicator_unselected
// ),
// contentDescription = "tab indicator",
// modifier = Modifier
// .width(34.dp)
// .height(4.dp)
// )
//
// }
// Spacer(modifier = Modifier.width(16.dp))
Text(
text = stringResource(R.string.moment),
fontSize = 20.sp,
fontWeight = FontWeight.W900,
color = AppColors.text,
modifier = Modifier modifier = Modifier
.noRippleClickable { .align(Alignment.CenterVertically)
scope.launch { )
pagerState.animateScrollToPage(0)
}
}.padding(start = 16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) { Spacer(modifier = Modifier.weight(1f))
Text(
text = stringResource(R.string.index_worldwide),
fontSize = if (pagerState.currentPage == 0)18.sp else 16.sp,
color = if (pagerState.currentPage == 0) AppColors.text else AppColors.nonActiveText,
fontWeight = FontWeight.W600)
Spacer(modifier = Modifier.height(4.dp))
Image( Image(
painter = painterResource( painter = painterResource(id = R.drawable.rider_pro_nav_search),
if (pagerState.currentPage == 0) R.mipmap.tab_indicator_selected contentDescription = "search",
else R.drawable.tab_indicator_unselected
),
contentDescription = "tab indicator",
modifier = Modifier
.width(34.dp)
.height(4.dp)
)
}
Spacer(modifier = Modifier.width(16.dp))
Column(
modifier = Modifier modifier = Modifier
.size(24.dp)
.noRippleClickable { .noRippleClickable {
scope.launch { navController.navigate(NavigationRoute.Search.route)
pagerState.animateScrollToPage(1)
}
}, },
verticalArrangement = Arrangement.Center, colorFilter = ColorFilter.tint(AppColors.text)
horizontalAlignment = Alignment.CenterHorizontally )
) { }
Text(
text = stringResource(R.string.index_dynamic),
fontSize = if (pagerState.currentPage == 1)18.sp else 16.sp,
color = if (pagerState.currentPage == 1) AppColors.text else AppColors.nonActiveText,
fontWeight = FontWeight.W600)
Spacer(modifier = Modifier.height(4.dp))
Image( Spacer(modifier = Modifier.height(23.dp))
painter = painterResource(
if (pagerState.currentPage == 1) R.mipmap.tab_indicator_selected Row(
else R.drawable.tab_indicator_unselected modifier = Modifier
), .fillMaxWidth()
contentDescription = "tab indicator", .wrapContentHeight()
modifier = Modifier .padding(start = 16.dp, bottom = 16.dp),
.width(34.dp) horizontalArrangement = Arrangement.Start,
.height(4.dp) verticalAlignment = Alignment.Bottom
) {
val tabDebouncer = rememberDebouncer()
// 新探索标签
Box {
CustomTabItem(
text = stringResource(R.string.index_worldwide),
isSelected = pagerState.currentPage == 0,
onClick = {
tabDebouncer {
scope.launch {
pagerState.animateScrollToPage(0)
}
}
}
) )
} }
TabSpacer()
// 只有非游客用户才显示"关注"tab // 只有非游客用户才显示"关注"tab
if (!AppStore.isGuest) { if (!AppStore.isGuest) {
//关注tab Box {
Spacer(modifier = Modifier.width(16.dp)) CustomTabItem(
Column(
modifier = Modifier
.noRippleClickable {
scope.launch {
pagerState.animateScrollToPage(2)
}
},
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = stringResource(R.string.index_following), text = stringResource(R.string.index_following),
fontSize = if (pagerState.currentPage == 2)18.sp else 16.sp, isSelected = pagerState.currentPage == 1,
color = if (pagerState.currentPage == 2) AppColors.text else AppColors.nonActiveText, onClick = {
fontWeight = FontWeight.W600) tabDebouncer {
Spacer(modifier = Modifier.height(4.dp)) scope.launch {
pagerState.animateScrollToPage(1)
Image( }
painter = painterResource( }
if (pagerState.currentPage == 2) R.mipmap.tab_indicator_selected }
else R.drawable.tab_indicator_unselected
),
contentDescription = "tab indicator",
modifier = Modifier
.width(34.dp)
.height(4.dp)
) )
} }
}
//热门tab
Spacer(modifier = Modifier.width(16.dp))
Column(
modifier = Modifier
.noRippleClickable {
scope.launch {
val targetPage = if (AppStore.isGuest) 2 else 3
pagerState.animateScrollToPage(targetPage)
}
},
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = stringResource(R.string.index_hot),
fontSize = if ((AppStore.isGuest && pagerState.currentPage == 2) || (!AppStore.isGuest && pagerState.currentPage == 3)) 18.sp else 16.sp,
color = if ((AppStore.isGuest && pagerState.currentPage == 2) || (!AppStore.isGuest && pagerState.currentPage == 3)) AppColors.text else AppColors.nonActiveText,
fontWeight = FontWeight.W600)
Spacer(modifier = Modifier.height(4.dp))
Image( TabSpacer()
painter = painterResource(
if ((AppStore.isGuest && pagerState.currentPage == 2) || (!AppStore.isGuest && pagerState.currentPage == 3)) R.mipmap.tab_indicator_selected
else R.drawable.tab_indicator_unselected
),
contentDescription = "tab indicator",
modifier = Modifier
.width(34.dp)
.height(4.dp)
)
} // 热门标签
//搜索按钮 Box {
Column( CustomTabItem(
modifier = Modifier text = stringResource(R.string.index_hot),
.padding(bottom = 8.dp, end = 16.dp) isSelected = pagerState.currentPage == 2,
.fillMaxWidth(), onClick = {
horizontalAlignment = Alignment.End tabDebouncer {
) { scope.launch {
Icon( pagerState.animateScrollToPage(2)
ImageVector.vectorResource(R.drawable.rider_pro_nav_search), }
contentDescription = "Clickable Icon", }
tint = AppColors.text,
modifier = Modifier.size(24.dp)
.noRippleClickable {
navController.navigate(NavigationRoute.Search.route)
} }
) )
}
} else {
// 热门标签 (游客模式)
Box {
CustomTabItem(
text = stringResource(R.string.index_hot),
isSelected = pagerState.currentPage == 1,
onClick = {
tabDebouncer {
scope.launch {
pagerState.animateScrollToPage(1)
}
}
}
)
}
} }
} }
@@ -237,31 +229,25 @@ fun MomentsList() {
.weight(1f) .weight(1f)
) { ) {
if (AppStore.isGuest) { if (AppStore.isGuest) {
// 游客模式:Explore(0), Dynamic(1), Hot(2) // 游客模式Dynamic(0), Hot(1)
when (it) { when (it) {
0 -> { 0 -> {
Explore()
}
1 -> {
Dynamic() Dynamic()
} }
2 -> { 1 -> {
HotMomentsList() HotMomentsList()
} }
} }
} else { } else {
// 正常用户:Explore(0), Dynamic(1), Timeline(2), Hot(3) // 正常用户Dynamic(0), Timeline(1), Hot(2)
when (it) { when (it) {
0 -> { 0 -> {
Explore()
}
1 -> {
Dynamic() Dynamic()
} }
2 -> { 1 -> {
TimelineMomentsList() TimelineMomentsList()
} }
3 -> { 2 -> {
HotMomentsList() HotMomentsList()
} }
} }
@@ -269,5 +255,30 @@ fun MomentsList() {
} }
} }
} }
@Composable
fun CustomTabItem(
text: String,
isSelected: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
val AppColors = LocalAppTheme.current
Column(
modifier = modifier
.noRippleClickable { onClick() },
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = text,
fontSize = 15.sp,
color = if (isSelected) AppColors.tabSelectedText else AppColors.tabUnselectedText,
modifier = Modifier
.clip(RoundedCornerShape(12.dp))
.background(if (isSelected) AppColors.tabSelectedBackground else AppColors.tabUnselectedBackground)
.padding(horizontal = 16.dp, vertical = 8.dp)
)
}
}

View File

@@ -93,7 +93,7 @@ fun GalleryItem(
Text( Text(
text = "故事还没开始", text = "故事还没开始",
fontSize = 12.sp, fontSize = 16.sp,
color = AppColors.text, color = AppColors.text,
fontWeight = FontWeight.W600 fontWeight = FontWeight.W600
) )
@@ -150,7 +150,7 @@ fun GalleryGrid(
Text( Text(
text = "故事还没开始", text = "故事还没开始",
fontSize = 12.sp, fontSize = 16.sp,
color = AppColors.text, color = AppColors.text,
fontWeight = FontWeight.W600 fontWeight = FontWeight.W600
) )

View File

@@ -275,7 +275,7 @@ fun LoginPage() {
) { ) {
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
Image( Image(
painter = painterResource(id = R.mipmap.rider_pro_color_logo_next), painter = painterResource(id = R.mipmap.invalid_name),
contentDescription = "Rave Now", contentDescription = "Rave Now",
modifier = Modifier modifier = Modifier
.size(52.dp) .size(52.dp)

View File

@@ -96,7 +96,7 @@ fun NewPostScreen() {
var isAiEnabled by remember { mutableStateOf(false) } var isAiEnabled by remember { mutableStateOf(false) }
var isRotating by remember { mutableStateOf(false) } var isRotating by remember { mutableStateOf(false) }
var isRequesting by remember { mutableStateOf(false) } var isRequesting by remember { mutableStateOf(false) }
val keyboardController = LocalSoftwareKeyboardController.current // 添加这行 val keyboardController = LocalSoftwareKeyboardController.current
val model = NewPostViewModel val model = NewPostViewModel
val systemUiController = rememberSystemUiController() val systemUiController = rememberSystemUiController()

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB