Compare commits
15 Commits
add_news
...
agent_scro
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a24136c35 | |||
| 742410223c | |||
| bd5aff7564 | |||
| b43c1585c4 | |||
| cb582393f1 | |||
| a200d00587 | |||
| 6d2133545f | |||
| 2aad126010 | |||
| b7b777d2d0 | |||
| e804c8be0c | |||
| 228a74695e | |||
| 41a51b85da | |||
| e74e8615a5 | |||
| 349d39daf2 | |||
| 8154a0ddc4 |
4
.idea/deploymentTargetSelector.xml
generated
@@ -4,10 +4,10 @@
|
|||||||
<selectionStates>
|
<selectionStates>
|
||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<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">
|
<Target type="DEFAULT_BOOT">
|
||||||
<handle>
|
<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>
|
</handle>
|
||||||
</Target>
|
</Target>
|
||||||
</DropdownSelection>
|
</DropdownSelection>
|
||||||
|
|||||||
@@ -271,6 +271,44 @@ data class RemoveAccountRequestBody(
|
|||||||
val password: String,
|
val password: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class CategoryTemplate(
|
||||||
|
@SerializedName("id")
|
||||||
|
val id: Int,
|
||||||
|
@SerializedName("name")
|
||||||
|
val name: String,
|
||||||
|
@SerializedName("description")
|
||||||
|
val description: String,
|
||||||
|
@SerializedName("avatar")
|
||||||
|
val avatar: String,
|
||||||
|
@SerializedName("parentId")
|
||||||
|
val parentId: Int?,
|
||||||
|
@SerializedName("parent")
|
||||||
|
val parent: CategoryTemplate?,
|
||||||
|
@SerializedName("children")
|
||||||
|
val children: List<CategoryTemplate>?,
|
||||||
|
@SerializedName("sort")
|
||||||
|
val sort: Int,
|
||||||
|
@SerializedName("isActive")
|
||||||
|
val isActive: Boolean,
|
||||||
|
@SerializedName("promptCount")
|
||||||
|
val promptCount: Int?,
|
||||||
|
@SerializedName("createdAt")
|
||||||
|
val createdAt: String,
|
||||||
|
@SerializedName("updatedAt")
|
||||||
|
val updatedAt: String
|
||||||
|
)
|
||||||
|
|
||||||
|
data class CategoryListResponse(
|
||||||
|
@SerializedName("page")
|
||||||
|
val page: Int,
|
||||||
|
@SerializedName("pageSize")
|
||||||
|
val pageSize: Int,
|
||||||
|
@SerializedName("total")
|
||||||
|
val total: Int,
|
||||||
|
@SerializedName("list")
|
||||||
|
val list: List<CategoryTemplate>
|
||||||
|
)
|
||||||
|
|
||||||
interface RaveNowAPI {
|
interface RaveNowAPI {
|
||||||
@GET("membership/config")
|
@GET("membership/config")
|
||||||
@retrofit2.http.Headers("X-Requires-Auth: true")
|
@retrofit2.http.Headers("X-Requires-Auth: true")
|
||||||
@@ -552,6 +590,7 @@ interface RaveNowAPI {
|
|||||||
@Query("pageSize") pageSize: Int = 20,
|
@Query("pageSize") pageSize: Int = 20,
|
||||||
@Query("withWorkflow") withWorkflow: Int = 1,
|
@Query("withWorkflow") withWorkflow: Int = 1,
|
||||||
@Query("authorId") authorId: Int? = null,
|
@Query("authorId") authorId: Int? = null,
|
||||||
|
@Query("categoryIds") categoryIds: List<Int>? = null,
|
||||||
): Response<DataContainer<ListContainer<Agent>>>
|
): Response<DataContainer<ListContainer<Agent>>>
|
||||||
|
|
||||||
@GET("outside/my/prompts")
|
@GET("outside/my/prompts")
|
||||||
@@ -605,7 +644,38 @@ interface RaveNowAPI {
|
|||||||
suspend fun joinRoom(@Body body: JoinGroupChatRequestBody,
|
suspend fun joinRoom(@Body body: JoinGroupChatRequestBody,
|
||||||
): Response<DataContainer<Room>>
|
): Response<DataContainer<Room>>
|
||||||
|
|
||||||
|
@GET("outside/categories")
|
||||||
|
suspend fun getCategories(
|
||||||
|
@Query("page") page: Int? = null,
|
||||||
|
@Query("pageSize") pageSize: Int? = null,
|
||||||
|
@Query("parentId") parentId: Int? = null,
|
||||||
|
@Query("isActive") isActive: Boolean? = null,
|
||||||
|
@Query("name") name: String? = null,
|
||||||
|
@Query("withChildren") withChildren: Boolean? = null,
|
||||||
|
@Query("withParent") withParent: Boolean? = null,
|
||||||
|
@Query("withCount") withCount: Boolean? = null,
|
||||||
|
@Query("hideEmpty") hideEmpty: Boolean? = null
|
||||||
|
): Response<DataContainer<CategoryListResponse>>
|
||||||
|
|
||||||
|
@GET("outside/categories/tree")
|
||||||
|
suspend fun getCategoryTree(
|
||||||
|
@Query("withCount") withCount: Boolean? = null,
|
||||||
|
@Query("hideEmpty") hideEmpty: Boolean? = null
|
||||||
|
): Response<DataContainer<List<CategoryTemplate>>>
|
||||||
|
|
||||||
|
@GET("outside/categories/{id}")
|
||||||
|
suspend fun getCategoryById(
|
||||||
|
@Path("id") id: Int
|
||||||
|
): Response<DataContainer<CategoryTemplate>>
|
||||||
|
|
||||||
|
@GET("outside/prompts")
|
||||||
|
suspend fun getPromptsByCategory(
|
||||||
|
@Query("categoryIds") categoryIds: List<Int>? = null,
|
||||||
|
@Query("categoryName") categoryName: String? = null,
|
||||||
|
@Query("uncategorized") uncategorized: String? = null,
|
||||||
|
@Query("page") page: Int? = null,
|
||||||
|
@Query("pageSize") pageSize: Int? = null
|
||||||
|
): Response<ListContainer<Agent>>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,10 +29,12 @@ import androidx.activity.compose.BackHandler
|
|||||||
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.draw.clip
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.graphics.Brush
|
import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
@@ -61,7 +63,17 @@ import com.aiosman.ravenow.ui.composables.form.FormTextInput2
|
|||||||
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
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
|
||||||
/**
|
/**
|
||||||
* 添加智能体界面
|
* 添加智能体界面
|
||||||
*/
|
*/
|
||||||
@@ -73,7 +85,8 @@ fun AddAgentScreen() {
|
|||||||
var agnetNameError by remember { mutableStateOf<String?>(null) }
|
var agnetNameError by remember { mutableStateOf<String?>(null) }
|
||||||
var agnetDescError by remember { mutableStateOf<String?>(null) }
|
var agnetDescError by remember { mutableStateOf<String?>(null) }
|
||||||
var errorMessage 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) {
|
fun onNameChange(value: String) {
|
||||||
@@ -118,9 +131,10 @@ fun AddAgentScreen() {
|
|||||||
.background(color = appColors.decentBackground),
|
.background(color = appColors.decentBackground),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
|
var showManualCreation by remember { mutableStateOf(false) }
|
||||||
StatusBarSpacer()
|
StatusBarSpacer()
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp)
|
modifier = Modifier.padding(horizontal = 14.dp, vertical = 16.dp)
|
||||||
.background(color = appColors.decentBackground)
|
.background(color = appColors.decentBackground)
|
||||||
) {
|
) {
|
||||||
// 自定义header,控制返回按钮行为
|
// 自定义header,控制返回按钮行为
|
||||||
@@ -148,47 +162,355 @@ fun AddAgentScreen() {
|
|||||||
stringResource(R.string.agent_add),
|
stringResource(R.string.agent_add),
|
||||||
fontWeight = FontWeight.W600,
|
fontWeight = FontWeight.W600,
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
fontSize = 17.sp,
|
fontSize = 17.sp,
|
||||||
color = appColors.text
|
color = appColors.text
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.size(12.dp))
|
}
|
||||||
Icon(
|
}
|
||||||
|
Spacer(modifier = Modifier.height(1.dp))
|
||||||
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(24.dp)
|
.fillMaxWidth()
|
||||||
.noRippleClickable {
|
.height(50.dp)
|
||||||
// 提交创建智能体的逻辑可以在这里实现
|
.padding(horizontal = 20.dp),
|
||||||
},
|
) {
|
||||||
imageVector = Icons.Default.Check,
|
Image(
|
||||||
contentDescription = "Add",
|
painter = painterResource(id = R.mipmap.group_copy),
|
||||||
tint = appColors.text
|
contentDescription = "",
|
||||||
|
modifier = Modifier
|
||||||
|
.size(48.dp)
|
||||||
|
.clip(
|
||||||
|
RoundedCornerShape(48.dp)
|
||||||
|
),
|
||||||
|
contentScale = ContentScale.Crop
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
.padding(start = 20.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "${AppState.profile?.nickName ?: "User"} 你好呀!今天想创造什么?",
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.W600
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
.padding(start = 20.dp)
|
||||||
|
) {
|
||||||
|
if (!showManualCreation) {
|
||||||
|
Text(
|
||||||
|
text = "只需要一句话,你的专属AI将在这里诞生。",
|
||||||
|
fontSize = 14.sp,
|
||||||
|
color = LocalAppTheme.current.text.copy(alpha = 0.6f),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(44.dp))
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
Box(
|
|
||||||
modifier = Modifier.size(88.dp),
|
|
||||||
contentAlignment = Alignment.Center
|
if (!showManualCreation) {
|
||||||
) {
|
Column(
|
||||||
CustomAsyncImage(
|
|
||||||
context,
|
|
||||||
model.croppedBitmap,
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(88.dp)
|
.padding(horizontal = 20.dp)
|
||||||
.clip(
|
) {
|
||||||
RoundedCornerShape(88.dp)
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(95.dp)
|
||||||
|
.shadow(
|
||||||
|
elevation = 10.dp,
|
||||||
|
shape = RoundedCornerShape(10.dp),
|
||||||
|
spotColor = Color(0x33F563FF),
|
||||||
|
ambientColor = Color(0x99F563FF),
|
||||||
|
clip = false
|
||||||
|
)
|
||||||
|
.background(
|
||||||
|
brush = Brush.linearGradient(
|
||||||
|
listOf(
|
||||||
|
Color(0xFF6246FF),
|
||||||
|
Color(0xFF7C45ED)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
contentDescription = "",
|
shape = RoundedCornerShape(10.dp)
|
||||||
contentScale = ContentScale.Crop,
|
)
|
||||||
placeholderRes = R.mipmap.rider_pro_agent_avatar
|
.padding(0.5.dp)
|
||||||
|
.background(
|
||||||
|
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)
|
||||||
|
.padding(end = 12.dp, bottom = 12.dp)
|
||||||
|
.noRippleClickable {
|
||||||
|
if (!isProcessing && model.desc.isNotEmpty()) {
|
||||||
|
isProcessing = true
|
||||||
|
model.viewModelScope.launch {
|
||||||
|
try {
|
||||||
|
//AI美化功能待实现
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
} finally {
|
||||||
|
isProcessing = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.mipmap.icons_info_magic),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(16.dp),
|
||||||
|
tint = Color.Unspecified
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(5.dp))
|
||||||
|
Text(
|
||||||
|
text = "AI美化",
|
||||||
|
color = Color(0xFF6246FF),
|
||||||
|
fontSize = 14.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
.size(6.dp)
|
||||||
|
.align(Alignment.BottomStart)
|
||||||
|
.offset(y = dot1Translation.dp)
|
||||||
|
.background(Color(0xFFFFD400), CircleShape)
|
||||||
)
|
)
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(32.dp)
|
.size(6.dp)
|
||||||
.clip(CircleShape)
|
.align(Alignment.BottomCenter)
|
||||||
.background(appColors.main)
|
.offset(y = dot2Translation.dp)
|
||||||
|
.background(Color(0xFF2F80FF), CircleShape)
|
||||||
|
)
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(6.dp)
|
||||||
.align(Alignment.BottomEnd)
|
.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,
|
||||||
|
color = Color(0x33858B98),
|
||||||
|
shape = RoundedCornerShape(12.dp)
|
||||||
|
)
|
||||||
|
.background(
|
||||||
|
color = appColors.background,
|
||||||
|
shape = RoundedCornerShape(12.dp),
|
||||||
|
)
|
||||||
|
.noRippleClickable {
|
||||||
|
showManualCreation = true
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(horizontal = 18.dp, vertical = 12.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.mipmap.icons_infor_edit),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(18.dp),
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
Text(
|
||||||
|
text = "手动创造Ai",
|
||||||
|
color = Color.Black,
|
||||||
|
fontWeight = FontWeight.W600,
|
||||||
|
fontSize = 14.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.align(Alignment.Start)
|
||||||
|
) {
|
||||||
|
// 添加新的一句话创造AI按钮
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.Start)
|
||||||
|
.width(140.dp)
|
||||||
|
.height(40.dp)
|
||||||
|
.shadow(
|
||||||
|
elevation = 10.dp,
|
||||||
|
shape = RoundedCornerShape(10.dp),
|
||||||
|
spotColor = Color(0x33F563FF),
|
||||||
|
ambientColor = Color(0x99F563FF),
|
||||||
|
clip = false
|
||||||
|
)
|
||||||
|
.background(
|
||||||
|
brush = Brush.linearGradient(
|
||||||
|
listOf(
|
||||||
|
Color(0xFF6246FF),
|
||||||
|
Color(0xFF7C45ED)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
shape = RoundedCornerShape(10.dp)
|
||||||
|
)
|
||||||
|
.padding(0.5.dp)
|
||||||
|
.background(
|
||||||
|
color = appColors.background,
|
||||||
|
shape = RoundedCornerShape(10.dp),
|
||||||
|
)
|
||||||
|
.noRippleClickable {
|
||||||
|
showManualCreation = false
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(horizontal = 12.dp, vertical = 8.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.mipmap.icons_info_magic),
|
||||||
|
contentDescription = null,
|
||||||
|
tint = Color.Black,
|
||||||
|
modifier = Modifier.size(18.dp),
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
Text(
|
||||||
|
text = "一句话创造AI",
|
||||||
|
color = Color.Black,
|
||||||
|
fontWeight = FontWeight.W600,
|
||||||
|
fontSize = 14.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
Text(
|
||||||
|
text = "头像",
|
||||||
|
fontSize = 12.sp,
|
||||||
|
fontWeight = FontWeight.W600
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(72.dp)
|
||||||
|
.clip(CircleShape)
|
||||||
|
.background(
|
||||||
|
brush = Brush.linearGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color(0x777c45ed),
|
||||||
|
Color(0x777c68ef),
|
||||||
|
Color(0x557bd8f8)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.align(Alignment.Start)
|
||||||
.noRippleClickable {
|
.noRippleClickable {
|
||||||
// 设置正在选择头像的标志
|
// 设置正在选择头像的标志
|
||||||
model.isSelectingAvatar = true
|
model.isSelectingAvatar = true
|
||||||
@@ -197,31 +519,41 @@ fun AddAgentScreen() {
|
|||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.Add,
|
painter = painterResource(id = R.mipmap.icons_infor_edit),
|
||||||
contentDescription = "Add",
|
contentDescription = "Edit",
|
||||||
tint = Color.White,
|
tint = Color.White,
|
||||||
|
modifier = Modifier.size(20.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(58.dp))
|
Spacer(modifier = Modifier.height(18.dp))
|
||||||
|
// 原版两个输入框
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(horizontal = 16.dp)
|
.padding(horizontal = 16.dp)
|
||||||
) {
|
) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.agent_name),
|
||||||
|
fontSize = 12.sp,
|
||||||
|
fontWeight = FontWeight.W600
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
FormTextInput(
|
FormTextInput(
|
||||||
value = model.name,
|
value = model.name,
|
||||||
label = stringResource(R.string.agent_name),
|
hint = "给它取个名字,让它成为独一无二的你",
|
||||||
hint = stringResource(R.string.agent_name_hint),
|
|
||||||
background = appColors.inputBackground2,
|
background = appColors.inputBackground2,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
) { value ->
|
) { value ->
|
||||||
onNameChange(value)
|
onNameChange(value)
|
||||||
}
|
}
|
||||||
// Spacer(modifier = Modifier.height(16.dp))
|
Text(
|
||||||
|
text = stringResource(R.string.agent_desc),
|
||||||
|
fontSize = 12.sp,
|
||||||
|
fontWeight = FontWeight.W600
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
FormTextInput2(
|
FormTextInput2(
|
||||||
value = model.desc,
|
value = model.desc,
|
||||||
label = stringResource(R.string.agent_desc),
|
|
||||||
hint = stringResource(R.string.agent_desc_hint),
|
hint = stringResource(R.string.agent_desc_hint),
|
||||||
background = appColors.inputBackground2,
|
background = appColors.inputBackground2,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
@@ -229,38 +561,41 @@ fun AddAgentScreen() {
|
|||||||
onDescChange(value)
|
onDescChange(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(58.dp))
|
}
|
||||||
|
|
||||||
// 错误信息显示
|
// 错误信息显示
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
Box(modifier = Modifier.fillMaxWidth()) {
|
||||||
errorMessage?.let { error ->
|
errorMessage?.let { error ->
|
||||||
Text(
|
Text(
|
||||||
text = error,
|
text = error,
|
||||||
color = Color.Red,
|
color = Color.Red,
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
modifier = Modifier
|
||||||
|
.padding(bottom = 20.dp)
|
||||||
|
.align(Alignment.Center),
|
||||||
fontSize = 14.sp
|
fontSize = 14.sp
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionButton(
|
ActionButton(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(345.dp)
|
.width(345.dp)
|
||||||
.padding(horizontal = 16.dp)
|
.padding(bottom = 40.dp)
|
||||||
.background(
|
.background(
|
||||||
brush = Brush.linearGradient(
|
brush = Brush.linearGradient(
|
||||||
colors = listOf(
|
colors = listOf(
|
||||||
Color(0xFFEE2A33),
|
Color(0x777c45ed),
|
||||||
Color(0xFFD80264),
|
Color(0x777c68ef),
|
||||||
Color(0xFF8468BC)
|
Color(0x557bd8f8)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
shape = RoundedCornerShape(24.dp)
|
shape = RoundedCornerShape(24.dp)
|
||||||
),
|
),
|
||||||
color = Color.White,
|
color = Color.White,
|
||||||
backgroundColor = Color.Transparent,
|
backgroundColor = Color.Transparent,
|
||||||
text = stringResource(R.string.agent_create),
|
text = stringResource(R.string.create_confirm),
|
||||||
isLoading = model.isUpdating,
|
isLoading = model.isUpdating,
|
||||||
loadingText = stringResource(R.string.agent_createing),
|
|
||||||
enabled = !model.isUpdating && validate()
|
enabled = !model.isUpdating && validate()
|
||||||
) {
|
) {
|
||||||
// 验证输入
|
// 验证输入
|
||||||
@@ -268,12 +603,19 @@ fun AddAgentScreen() {
|
|||||||
if (validationError != null) {
|
if (validationError != null) {
|
||||||
// 显示验证错误
|
// 显示验证错误
|
||||||
errorMessage = validationError
|
errorMessage = validationError
|
||||||
|
model.viewModelScope.launch {
|
||||||
|
kotlinx.coroutines.delay(3000)
|
||||||
|
errorMessage = null
|
||||||
|
}
|
||||||
return@ActionButton
|
return@ActionButton
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清除之前的错误信息
|
// 清除之前的错误信息
|
||||||
errorMessage = null
|
errorMessage = null
|
||||||
|
|
||||||
|
// 显示波动动画
|
||||||
|
showWaveAnimation = true
|
||||||
|
|
||||||
// 调用创建智能体API
|
// 调用创建智能体API
|
||||||
model.viewModelScope.launch {
|
model.viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
@@ -284,6 +626,9 @@ fun AddAgentScreen() {
|
|||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
// 隐藏波动动画
|
||||||
|
showWaveAnimation = false
|
||||||
|
|
||||||
// 显示错误信息
|
// 显示错误信息
|
||||||
errorMessage = "创建智能体失败: ${e.message}"
|
errorMessage = "创建智能体失败: ${e.message}"
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|||||||
@@ -66,9 +66,9 @@ object AddAgentViewModel : ViewModel() {
|
|||||||
|
|
||||||
fun validate(): String? {
|
fun validate(): String? {
|
||||||
return when {
|
return when {
|
||||||
name.isEmpty() -> "智能体名称不能为空"
|
// name.isEmpty() -> "智能体名称不能为空"
|
||||||
name.length < 2 -> "智能体名称长度不能少于2个字符"
|
// name.length < 2 -> "智能体名称长度不能少于2个字符"
|
||||||
name.length > 20 -> "智能体名称长度不能超过20个字符"
|
// name.length > 20 -> "智能体名称长度不能超过20个字符"
|
||||||
desc.isEmpty() -> "智能体描述不能为空"
|
desc.isEmpty() -> "智能体描述不能为空"
|
||||||
desc.length > 100 -> "智能体描述长度不能超过100个字符"
|
desc.length > 100 -> "智能体描述长度不能超过100个字符"
|
||||||
else -> null
|
else -> null
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ fun ChatAiScreen(userId: String) {
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(AppColors.decentBackground)
|
.background(Color.White)
|
||||||
.padding(paddingValues)
|
.padding(paddingValues)
|
||||||
) {
|
) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
|
|||||||
@@ -69,72 +69,22 @@ fun EditCommentBottomModal(
|
|||||||
.background(AppColors.background)
|
.background(AppColors.background)
|
||||||
.padding(horizontal = 16.dp, vertical = 16.dp)
|
.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(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.Top
|
verticalAlignment = Alignment.Top
|
||||||
) {
|
) {
|
||||||
Box(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clip(RoundedCornerShape(20.dp))
|
.clip(RoundedCornerShape(20.dp))
|
||||||
.background(Color.White)
|
.background(Color.Gray.copy(alpha = 0.1f))
|
||||||
.border(1.dp, Color.Black, RoundedCornerShape(20.dp))
|
|
||||||
.padding(horizontal = 16.dp, vertical = 16.dp)
|
.padding(horizontal = 16.dp, vertical = 16.dp)
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.Top
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
BasicTextField(
|
BasicTextField(
|
||||||
value = text,
|
value = text,
|
||||||
@@ -149,30 +99,39 @@ fun EditCommentBottomModal(
|
|||||||
color = Color.Black,
|
color = Color.Black,
|
||||||
fontWeight = FontWeight.Normal
|
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(
|
Icon(
|
||||||
painter = painterResource(id = R.mipmap.rider_pro_moment_post),
|
painter = painterResource(id = R.mipmap.btn),
|
||||||
contentDescription = "Send",
|
contentDescription = "Send",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(20.dp)
|
.size(40.dp)
|
||||||
.align(Alignment.Top)
|
.padding(top = 13.dp)
|
||||||
.noRippleClickable {
|
.noRippleClickable {
|
||||||
if (text.isNotEmpty()) {
|
if (text.isNotEmpty()) {
|
||||||
onSend(text)
|
onSend(text)
|
||||||
text = ""
|
text = ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tint = if (isNotEmpty) Color.Unspecified else AppColors.nonActive
|
tint = Color.Unspecified
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(navBarHeight))
|
Spacer(modifier = Modifier.height(navBarHeight))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,16 +92,22 @@ fun MomentCard(
|
|||||||
showFollowButton = showFollowButton
|
showFollowButton = showFollowButton
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
val lastClickTime = remember { mutableStateOf(0L) }
|
||||||
|
val clickDelay = 500L
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.noRippleClickable {
|
.noRippleClickable {
|
||||||
|
val currentTime = System.currentTimeMillis()
|
||||||
|
if (currentTime - lastClickTime.value > clickDelay) {
|
||||||
|
lastClickTime.value = currentTime
|
||||||
navController.navigateToPost(
|
navController.navigateToPost(
|
||||||
momentEntity.id,
|
momentEntity.id,
|
||||||
highlightCommentId = 0,
|
highlightCommentId = 0,
|
||||||
initImagePagerIndex = imageIndex
|
initImagePagerIndex = imageIndex
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
MomentContentGroup(
|
MomentContentGroup(
|
||||||
momentEntity = momentEntity,
|
momentEntity = momentEntity,
|
||||||
@@ -213,7 +219,6 @@ fun MomentPostLocation(location: String) {
|
|||||||
text = location,
|
text = location,
|
||||||
color = AppColors.secondaryText,
|
color = AppColors.secondaryText,
|
||||||
fontSize = 12.sp,
|
fontSize = 12.sp,
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,6 +243,8 @@ fun MomentTopRowGroup(
|
|||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
) {
|
) {
|
||||||
|
val lastClickTime = remember { mutableStateOf(0L) }
|
||||||
|
val clickDelay = 500L
|
||||||
CustomAsyncImage(
|
CustomAsyncImage(
|
||||||
context,
|
context,
|
||||||
momentEntity.avatar,
|
momentEntity.avatar,
|
||||||
@@ -246,12 +253,16 @@ fun MomentTopRowGroup(
|
|||||||
.size(40.dp)
|
.size(40.dp)
|
||||||
.clip(RoundedCornerShape(40.dp))
|
.clip(RoundedCornerShape(40.dp))
|
||||||
.noRippleClickable {
|
.noRippleClickable {
|
||||||
|
val currentTime = System.currentTimeMillis()
|
||||||
|
if (currentTime - lastClickTime.value > clickDelay) {
|
||||||
|
lastClickTime.value = currentTime
|
||||||
navController.navigate(
|
navController.navigate(
|
||||||
NavigationRoute.AccountProfile.route.replace(
|
NavigationRoute.AccountProfile.route.replace(
|
||||||
"{id}",
|
"{id}",
|
||||||
momentEntity.authorId.toString()
|
momentEntity.authorId.toString()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
contentScale = ContentScale.Crop
|
contentScale = ContentScale.Crop
|
||||||
)
|
)
|
||||||
@@ -267,7 +278,19 @@ fun MomentTopRowGroup(
|
|||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
MomentName(
|
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
|
name = momentEntity.nickname
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(16.dp))
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
@@ -416,6 +439,8 @@ fun MomentBottomOperateRowGroup(
|
|||||||
momentEntity: MomentEntity,
|
momentEntity: MomentEntity,
|
||||||
imageIndex: Int = 0
|
imageIndex: Int = 0
|
||||||
) {
|
) {
|
||||||
|
val lastClickTime = remember { mutableStateOf(0L) }
|
||||||
|
val clickDelay = 500L
|
||||||
var showCommentModal by remember { mutableStateOf(false) }
|
var showCommentModal by remember { mutableStateOf(false) }
|
||||||
if (showCommentModal) {
|
if (showCommentModal) {
|
||||||
ModalBottomSheet(
|
ModalBottomSheet(
|
||||||
@@ -451,58 +476,14 @@ fun MomentBottomOperateRowGroup(
|
|||||||
.height(56.dp)
|
.height(56.dp)
|
||||||
.padding(start = 16.dp, end = 0.dp)
|
.padding(start = 16.dp, end = 0.dp)
|
||||||
) {
|
) {
|
||||||
Row(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize()
|
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) {
|
if (momentEntity.images.size > 1) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(1f),
|
||||||
horizontalArrangement = Arrangement.Center,
|
horizontalArrangement = Arrangement.Center,
|
||||||
verticalAlignment = Alignment.CenterVertically
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,11 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.height
|
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.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
@@ -52,7 +54,7 @@ fun FormTextInput(
|
|||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
.clip(RoundedCornerShape(16.dp))
|
.clip(RoundedCornerShape(25.dp))
|
||||||
.background(background ?: AppColors.inputBackground)
|
.background(background ?: AppColors.inputBackground)
|
||||||
.let {
|
.let {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
@@ -79,13 +81,27 @@ fun FormTextInput(
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.padding(start = 16.dp)
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.mipmap.icons_infor_edit),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier
|
||||||
|
.size(16.dp)
|
||||||
|
.align(Alignment.TopStart),
|
||||||
|
tint = Color.Unspecified.copy(alpha = 0.4f)
|
||||||
|
)
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Spacer(modifier = Modifier.width(24.dp))
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) {
|
||||||
if (value.isEmpty()) {
|
if (value.isEmpty()) {
|
||||||
Text(
|
Text(
|
||||||
text = hint ?: "",
|
text = hint ?: "",
|
||||||
style = TextStyle(
|
style = TextStyle(
|
||||||
fontSize = 16.sp,
|
fontSize = 14.sp,
|
||||||
fontWeight = FontWeight.Normal,
|
fontWeight = FontWeight.Normal,
|
||||||
color = AppColors.inputHint
|
color = AppColors.inputHint
|
||||||
)
|
)
|
||||||
@@ -100,13 +116,14 @@ fun FormTextInput(
|
|||||||
},
|
},
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 16.sp,
|
fontSize = 14.sp,
|
||||||
fontWeight = FontWeight.Normal,
|
fontWeight = FontWeight.Normal,
|
||||||
color = AppColors.text
|
color = AppColors.text
|
||||||
),
|
),
|
||||||
cursorBrush = SolidColor(AppColors.text),
|
cursorBrush = SolidColor(AppColors.text),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,14 +15,18 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.height
|
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.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
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.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.Color
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
@@ -44,6 +48,7 @@ fun FormTextInput2(
|
|||||||
error: String? = null,
|
error: String? = null,
|
||||||
hint: String? = null,
|
hint: String? = null,
|
||||||
background: Color? = null,
|
background: Color? = null,
|
||||||
|
focusRequester: FocusRequester? = null,
|
||||||
onValueChange: (String) -> Unit
|
onValueChange: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
val AppColors = LocalAppTheme.current
|
val AppColors = LocalAppTheme.current
|
||||||
@@ -52,7 +57,7 @@ fun FormTextInput2(
|
|||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
.clip(RoundedCornerShape(16.dp))
|
.clip(RoundedCornerShape(25.dp))
|
||||||
.background(background ?: AppColors.inputBackground)
|
.background(background ?: AppColors.inputBackground)
|
||||||
.let {
|
.let {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
@@ -79,13 +84,27 @@ fun FormTextInput2(
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.padding(top = 8.dp)
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.mipmap.icons_infor_edit),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier
|
||||||
|
.size(16.dp)
|
||||||
|
.align(Alignment.TopStart),
|
||||||
|
tint = Color.Unspecified.copy(alpha = 0.4f)
|
||||||
|
)
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Spacer(modifier = Modifier.width(24.dp))
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) {
|
||||||
if (value.isEmpty()) {
|
if (value.isEmpty()) {
|
||||||
Text(
|
Text(
|
||||||
text = hint ?: "",
|
text = hint ?: "",
|
||||||
style = TextStyle(
|
style = TextStyle(
|
||||||
fontSize = 16.sp,
|
fontSize = 14.sp,
|
||||||
fontWeight = FontWeight.Normal,
|
fontWeight = FontWeight.Normal,
|
||||||
color = AppColors.inputHint
|
color = AppColors.inputHint
|
||||||
)
|
)
|
||||||
@@ -98,15 +117,24 @@ fun FormTextInput2(
|
|||||||
onValueChange = {
|
onValueChange = {
|
||||||
onValueChange(it)
|
onValueChange(it)
|
||||||
},
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.let {
|
||||||
|
if (focusRequester != null) {
|
||||||
|
it.focusRequester(focusRequester)
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
},
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontSize = 16.sp,
|
fontSize = 14.sp,
|
||||||
fontWeight = FontWeight.Normal,
|
fontWeight = FontWeight.Normal,
|
||||||
color = AppColors.text,
|
color = AppColors.text,
|
||||||
lineHeight = 20.sp
|
lineHeight = 20.sp
|
||||||
),
|
),
|
||||||
cursorBrush = SolidColor(AppColors.text),
|
cursorBrush = SolidColor(AppColors.text),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ fun IndexScreen() {
|
|||||||
Text(
|
Text(
|
||||||
text = it.label(),
|
text = it.label(),
|
||||||
fontSize = 10.sp,
|
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
|
fontWeight = if (isSelected) FontWeight.W600 else FontWeight.Normal
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ sealed class NavigationItem(
|
|||||||
|
|
||||||
data object Home : NavigationItem("Home",
|
data object Home : NavigationItem("Home",
|
||||||
icon = { R.drawable.rider_pro_nav_home },
|
icon = { R.drawable.rider_pro_nav_home },
|
||||||
selectedIcon = { R.mipmap.rider_pro_nav_home_hl },
|
selectedIcon = { R.mipmap.bars_x_buttons_home_s },
|
||||||
label = { stringResource(R.string.main_home) }
|
label = { stringResource(R.string.main_home) }
|
||||||
)
|
)
|
||||||
|
|
||||||
data object Ai : NavigationItem("Ai",
|
data object Ai : NavigationItem("Ai",
|
||||||
icon = { R.mipmap.bars_x_buttons_discover_bold},
|
icon = { R.mipmap.bars_x_buttons_discover_bold},
|
||||||
selectedIcon = { R.mipmap.dynamic_hl },
|
selectedIcon = { R.mipmap.bars_x_buttons_discover_fill },
|
||||||
label = { stringResource(R.string.index_dynamic) }
|
label = { stringResource(R.string.index_dynamic) }
|
||||||
)
|
)
|
||||||
// data object Ai : NavigationItem("Ai",
|
// data object Ai : NavigationItem("Ai",
|
||||||
@@ -40,13 +40,13 @@ sealed class NavigationItem(
|
|||||||
|
|
||||||
data object Notification : NavigationItem("Notification",
|
data object Notification : NavigationItem("Notification",
|
||||||
icon = { R.drawable.rider_pro_nav_notification },
|
icon = { R.drawable.rider_pro_nav_notification },
|
||||||
selectedIcon = { R.mipmap.rider_pro_nav_message_hl },
|
selectedIcon = { R.mipmap.bars_x_buttons_chat_s },
|
||||||
label = { stringResource(R.string.main_message) }
|
label = { stringResource(R.string.main_message) }
|
||||||
)
|
)
|
||||||
|
|
||||||
data object Profile : NavigationItem("Profile",
|
data object Profile : NavigationItem("Profile",
|
||||||
icon = { R.drawable.rider_pro_nav_profile },
|
icon = { R.drawable.rider_pro_nav_profile },
|
||||||
selectedIcon = { R.mipmap.rider_pro_nav_profile_hl },
|
selectedIcon = { R.mipmap.bars_x_buttons_user_s },
|
||||||
label = { stringResource(R.string.main_profile) }
|
label = { stringResource(R.string.main_profile) }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,14 @@ import androidx.compose.foundation.pager.rememberPagerState
|
|||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@@ -69,13 +74,24 @@ import com.aiosman.ravenow.utils.DebounceUtils
|
|||||||
import com.aiosman.ravenow.utils.ResourceCleanupManager
|
import com.aiosman.ravenow.utils.ResourceCleanupManager
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import androidx.compose.foundation.lazy.LazyRow
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.lazy.grid.GridCells
|
import androidx.compose.foundation.lazy.grid.GridCells
|
||||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.lazy.grid.items as gridItems
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.foundation.lazy.grid.items
|
|
||||||
|
|
||||||
@OptIn( ExperimentalFoundationApi::class)
|
// 检测是否接近列表底部的扩展函数
|
||||||
|
fun LazyListState.isScrolledToEnd(buffer: Int = 3): Boolean {
|
||||||
|
val layoutInfo = this.layoutInfo
|
||||||
|
val totalItemsCount = layoutInfo.totalItemsCount
|
||||||
|
val lastVisibleItemIndex = layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0
|
||||||
|
|
||||||
|
return lastVisibleItemIndex >= (totalItemsCount - buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun Agent() {
|
fun Agent() {
|
||||||
val AppColors = LocalAppTheme.current
|
val AppColors = LocalAppTheme.current
|
||||||
@@ -89,7 +105,6 @@ fun Agent() {
|
|||||||
var scope = rememberCoroutineScope()
|
var scope = rememberCoroutineScope()
|
||||||
|
|
||||||
val viewModel: AgentViewModel = viewModel()
|
val viewModel: AgentViewModel = viewModel()
|
||||||
val scrollState = rememberScrollState()
|
|
||||||
|
|
||||||
// 确保推荐Agent数据已加载
|
// 确保推荐Agent数据已加载
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
@@ -107,37 +122,38 @@ fun Agent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(
|
val agentItems = viewModel.agentItems
|
||||||
modifier = Modifier
|
var selectedTabIndex by remember { mutableStateOf(0) }
|
||||||
.fillMaxSize()
|
|
||||||
.verticalScroll(scrollState)
|
// 无限滚动状态
|
||||||
.padding(
|
val listState = rememberLazyListState()
|
||||||
top = statusBarPaddingValues.calculateTopPadding(),
|
|
||||||
bottom = navigationBarPaddings,
|
// 创建一个可观察的滚动到底部状态
|
||||||
start = 16.dp,
|
val isScrolledToEnd by remember {
|
||||||
end = 16.dp
|
derivedStateOf {
|
||||||
),
|
listState.isScrolledToEnd()
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
}
|
||||||
) {
|
}
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
// 检测滚动到底部并加载更多数据
|
||||||
.wrapContentHeight()
|
LaunchedEffect(isScrolledToEnd) {
|
||||||
.height(44.dp)
|
if (isScrolledToEnd && !viewModel.isLoadingMore && agentItems.isNotEmpty() && viewModel.hasMoreData) {
|
||||||
.fillMaxWidth(),
|
viewModel.loadMoreAgents()
|
||||||
horizontalArrangement = Arrangement.Start,
|
}
|
||||||
verticalAlignment = Alignment.CenterVertically
|
}
|
||||||
) {
|
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
TopAppBar(
|
||||||
|
title = {
|
||||||
androidx.compose.material3.Text(
|
androidx.compose.material3.Text(
|
||||||
text = "Rave AI",
|
text = "Rave AI",
|
||||||
fontSize = 20.sp,
|
fontSize = 20.sp,
|
||||||
fontWeight = FontWeight.W900,
|
fontWeight = FontWeight.W900,
|
||||||
color = AppColors.text,
|
color = AppColors.text
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.CenterVertically)
|
|
||||||
)
|
)
|
||||||
|
},
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
actions = {
|
||||||
|
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(id = R.drawable.rider_pro_nav_search),
|
painter = painterResource(id = R.drawable.rider_pro_nav_search),
|
||||||
contentDescription = "search",
|
contentDescription = "search",
|
||||||
@@ -148,95 +164,40 @@ fun Agent() {
|
|||||||
},
|
},
|
||||||
colorFilter = ColorFilter.tint(AppColors.text)
|
colorFilter = ColorFilter.tint(AppColors.text)
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
Spacer(modifier = Modifier.height(15.dp))
|
colors = TopAppBarDefaults.topAppBarColors(
|
||||||
// // 搜索框
|
containerColor = AppColors.background
|
||||||
// Row(
|
)
|
||||||
// modifier = Modifier
|
)
|
||||||
// .height(36.dp)
|
},
|
||||||
// .weight(1f)
|
containerColor = AppColors.background,
|
||||||
// .clip(shape = RoundedCornerShape(8.dp))
|
contentWindowInsets = WindowInsets(0, 0, 0, 0)
|
||||||
// .background(AppColors.inputBackground)
|
) { paddingValues ->
|
||||||
// .padding(horizontal = 8.dp, vertical = 0.dp)
|
LazyColumn(
|
||||||
// .noRippleClickable {
|
state = listState,
|
||||||
// // 搜索框点击事件
|
modifier = Modifier
|
||||||
// },
|
.fillMaxSize()
|
||||||
// verticalAlignment = Alignment.CenterVertically
|
.padding(paddingValues)
|
||||||
// ) {
|
.padding(
|
||||||
// Icon(
|
bottom = navigationBarPaddings,
|
||||||
// painter = painterResource(id = R.drawable.rider_pro_nav_search),
|
start = 16.dp,
|
||||||
// contentDescription = null,
|
end = 16.dp
|
||||||
// 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
|
|
||||||
// )
|
|
||||||
|
|
||||||
|
// 类别标签页 - 吸顶
|
||||||
|
stickyHeader(key = "category_tabs") {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 8.dp)
|
.background(AppColors.background)
|
||||||
|
.padding(top = 4.dp, bottom = 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
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
|
|
||||||
var selectedTabIndex by remember { mutableStateOf(0) }
|
|
||||||
|
|
||||||
// 标签页
|
|
||||||
LazyRow(
|
LazyRow(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.wrapContentHeight()
|
.wrapContentHeight()
|
||||||
.padding(bottom = 16.dp),
|
.padding(bottom = 8.dp),
|
||||||
horizontalArrangement = Arrangement.Start,
|
horizontalArrangement = Arrangement.Start,
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
@@ -246,6 +207,7 @@ fun Agent() {
|
|||||||
isSelected = selectedTabIndex == 0,
|
isSelected = selectedTabIndex == 0,
|
||||||
onClick = {
|
onClick = {
|
||||||
selectedTabIndex = 0
|
selectedTabIndex = 0
|
||||||
|
viewModel.loadAllAgents()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -254,6 +216,24 @@ fun Agent() {
|
|||||||
TabSpacer()
|
TabSpacer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 动态添加分类标签
|
||||||
|
viewModel.categories.take(4).forEachIndexed { index, category ->
|
||||||
|
item {
|
||||||
|
CustomTabItem(
|
||||||
|
text = category.name,
|
||||||
|
isSelected = selectedTabIndex == index + 1,
|
||||||
|
onClick = {
|
||||||
|
selectedTabIndex = index + 1
|
||||||
|
viewModel.loadAgentsByCategory(category.id)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
TabSpacer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
item {
|
item {
|
||||||
CustomTabItem(
|
CustomTabItem(
|
||||||
text = "scenes",
|
text = "scenes",
|
||||||
@@ -271,9 +251,9 @@ fun Agent() {
|
|||||||
item {
|
item {
|
||||||
CustomTabItem(
|
CustomTabItem(
|
||||||
text = "voices",
|
text = "voices",
|
||||||
isSelected = selectedTabIndex == 2,
|
isSelected = selectedTabIndex == 6,
|
||||||
onClick = {
|
onClick = {
|
||||||
selectedTabIndex = 2
|
selectedTabIndex = 6
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -285,9 +265,9 @@ fun Agent() {
|
|||||||
item {
|
item {
|
||||||
CustomTabItem(
|
CustomTabItem(
|
||||||
text = "anime",
|
text = "anime",
|
||||||
isSelected = selectedTabIndex == 3,
|
isSelected = selectedTabIndex == 7,
|
||||||
onClick = {
|
onClick = {
|
||||||
selectedTabIndex = 3
|
selectedTabIndex = 7
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -299,16 +279,27 @@ fun Agent() {
|
|||||||
item {
|
item {
|
||||||
CustomTabItem(
|
CustomTabItem(
|
||||||
text = "assist",
|
text = "assist",
|
||||||
isSelected = selectedTabIndex == 4,
|
isSelected = selectedTabIndex == 8,
|
||||||
onClick = {
|
onClick = {
|
||||||
selectedTabIndex = 4
|
selectedTabIndex = 8
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
when (selectedTabIndex) {
|
}
|
||||||
0 -> {
|
// 推荐内容区域
|
||||||
|
item {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp)
|
||||||
|
) {
|
||||||
|
when {
|
||||||
|
selectedTabIndex == 0 -> {
|
||||||
|
AgentViewPagerSection(agentItems = viewModel.agentItems.take(15), viewModel)
|
||||||
|
}
|
||||||
|
selectedTabIndex in 1..viewModel.categories.size -> {
|
||||||
AgentViewPagerSection(agentItems = viewModel.agentItems.take(15), viewModel)
|
AgentViewPagerSection(agentItems = viewModel.agentItems.take(15), viewModel)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@@ -317,12 +308,16 @@ fun Agent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// "发现更多" 标题 - 吸顶
|
||||||
|
stickyHeader(key = "discover_more") {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.wrapContentHeight(),
|
.background(AppColors.background)
|
||||||
// center the tabs
|
.padding(top = 8.dp, bottom = 12.dp),
|
||||||
horizontalArrangement = Arrangement.Start,
|
horizontalArrangement = Arrangement.Start,
|
||||||
verticalAlignment = Alignment.Bottom
|
verticalAlignment = Alignment.Bottom
|
||||||
) {
|
) {
|
||||||
@@ -330,7 +325,6 @@ fun Agent() {
|
|||||||
painter = painterResource(R.mipmap.rider_pro_agent2),
|
painter = painterResource(R.mipmap.rider_pro_agent2),
|
||||||
contentDescription = "agent",
|
contentDescription = "agent",
|
||||||
modifier = Modifier.size(28.dp),
|
modifier = Modifier.size(28.dp),
|
||||||
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(4.dp))
|
Spacer(modifier = Modifier.width(4.dp))
|
||||||
androidx.compose.material3.Text(
|
androidx.compose.material3.Text(
|
||||||
@@ -339,22 +333,24 @@ fun Agent() {
|
|||||||
fontWeight = androidx.compose.ui.text.font.FontWeight.W600,
|
fontWeight = androidx.compose.ui.text.font.FontWeight.W600,
|
||||||
color = AppColors.text
|
color = AppColors.text
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(50.dp))
|
}
|
||||||
Column(
|
|
||||||
|
// Agent网格 - 使用行式布局
|
||||||
|
items(
|
||||||
|
items = agentItems.chunked(2),
|
||||||
|
key = { row -> row.firstOrNull()?.openId ?: "" }
|
||||||
|
) { rowItems ->
|
||||||
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.weight(1f)
|
.padding(vertical = 16.dp),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
) {
|
) {
|
||||||
val agentItems = viewModel.agentItems.take(15)
|
rowItems.forEach { agentItem ->
|
||||||
LazyVerticalGrid(
|
Box(
|
||||||
columns = GridCells.Fixed(2),
|
modifier = Modifier.weight(1f)
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(50.dp)
|
|
||||||
) {
|
) {
|
||||||
items(agentItems) { agentItem ->
|
|
||||||
AgentCardSquare(
|
AgentCardSquare(
|
||||||
agentItem = agentItem,
|
agentItem = agentItem,
|
||||||
viewModel = viewModel,
|
viewModel = viewModel,
|
||||||
@@ -362,6 +358,36 @@ fun Agent() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 如果这一行只有一个item,添加一个空的占位符
|
||||||
|
if (rowItems.size == 1) {
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载更多指示器
|
||||||
|
if (viewModel.isLoadingMore) {
|
||||||
|
item {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 24.dp),
|
||||||
|
horizontalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
|
androidx.compose.material3.CircularProgressIndicator(
|
||||||
|
modifier = Modifier.size(24.dp),
|
||||||
|
color = AppColors.text,
|
||||||
|
strokeWidth = 2.dp
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(12.dp))
|
||||||
|
androidx.compose.material3.Text(
|
||||||
|
text = "加载中...",
|
||||||
|
color = AppColors.secondaryText,
|
||||||
|
fontSize = 14.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -369,7 +395,7 @@ fun Agent() {
|
|||||||
@Composable
|
@Composable
|
||||||
fun AgentCardSquare(agentItem: AgentItem, viewModel: AgentViewModel, navController: NavHostController) {
|
fun AgentCardSquare(agentItem: AgentItem, viewModel: AgentViewModel, navController: NavHostController) {
|
||||||
val AppColors = LocalAppTheme.current
|
val AppColors = LocalAppTheme.current
|
||||||
val cardHeight = 180.dp
|
val cardHeight = 200.dp
|
||||||
val avatarSize = cardHeight / 3 // 头像大小为方块高度的三分之一
|
val avatarSize = cardHeight / 3 // 头像大小为方块高度的三分之一
|
||||||
|
|
||||||
// 防抖状态
|
// 防抖状态
|
||||||
@@ -378,8 +404,9 @@ fun AgentCardSquare(agentItem: AgentItem, viewModel: AgentViewModel, navControll
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
.padding(top = avatarSize / 2)
|
||||||
.height(cardHeight)
|
.height(cardHeight)
|
||||||
.background(Color(0xFFE0E0E0), RoundedCornerShape(12.dp)) // 灰色背景
|
.background(AppColors.nonActive, RoundedCornerShape(12.dp)) // 修改背景颜色
|
||||||
.clickable {
|
.clickable {
|
||||||
if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
|
if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
|
||||||
viewModel.goToProfile(agentItem.openId, navController)
|
viewModel.goToProfile(agentItem.openId, navController)
|
||||||
@@ -426,7 +453,7 @@ fun AgentCardSquare(agentItem: AgentItem, viewModel: AgentViewModel, navControll
|
|||||||
) {
|
) {
|
||||||
androidx.compose.material3.Text(
|
androidx.compose.material3.Text(
|
||||||
text = agentItem.title,
|
text = agentItem.title,
|
||||||
fontSize = 16.sp,
|
fontSize = 14.sp,
|
||||||
fontWeight = androidx.compose.ui.text.font.FontWeight.W600,
|
fontWeight = androidx.compose.ui.text.font.FontWeight.W600,
|
||||||
color = AppColors.text,
|
color = AppColors.text,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
@@ -435,21 +462,26 @@ fun AgentCardSquare(agentItem: AgentItem, viewModel: AgentViewModel, navControll
|
|||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.height(85.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
) {
|
||||||
androidx.compose.material3.Text(
|
androidx.compose.material3.Text(
|
||||||
text = agentItem.desc,
|
text = agentItem.desc,
|
||||||
fontSize = 14.sp,
|
fontSize = 12.sp,
|
||||||
color = AppColors.secondaryText,
|
color = AppColors.secondaryText,
|
||||||
maxLines = 2,
|
maxLines = 5,
|
||||||
overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis,
|
overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis,
|
||||||
modifier = Modifier.weight(1f, fill = false)
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
// 聊天按钮,位于底部居中
|
// 聊天按钮,位于底部居中
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(80.dp)
|
.width(60.dp)
|
||||||
.height(32.dp)
|
.height(32.dp)
|
||||||
.background(
|
.background(
|
||||||
color = Color(0X147c7480),
|
color = Color(0X147c7480),
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
|
import com.aiosman.ravenow.data.Agent
|
||||||
|
import com.aiosman.ravenow.data.ListContainer
|
||||||
import com.aiosman.ravenow.data.api.ApiClient
|
import com.aiosman.ravenow.data.api.ApiClient
|
||||||
|
import com.aiosman.ravenow.data.api.CategoryTemplate
|
||||||
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
|
||||||
@@ -22,6 +25,8 @@ object AgentViewModel: ViewModel() {
|
|||||||
var agentItems by mutableStateOf<List<AgentItem>>(emptyList())
|
var agentItems by mutableStateOf<List<AgentItem>>(emptyList())
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var categories by mutableStateOf<List<CategoryItem>>(emptyList())
|
||||||
|
private set
|
||||||
|
|
||||||
var errorMessage by mutableStateOf<String?>(null)
|
var errorMessage by mutableStateOf<String?>(null)
|
||||||
private set
|
private set
|
||||||
@@ -33,31 +38,140 @@ object AgentViewModel: ViewModel() {
|
|||||||
var isLoading by mutableStateOf(false)
|
var isLoading by mutableStateOf(false)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
// 分页相关状态
|
||||||
|
var isLoadingMore by mutableStateOf(false)
|
||||||
|
private set
|
||||||
|
|
||||||
|
var currentPage by mutableStateOf(1)
|
||||||
|
private set
|
||||||
|
|
||||||
|
var hasMoreData by mutableStateOf(true)
|
||||||
|
private set
|
||||||
|
|
||||||
|
private val pageSize = 20
|
||||||
|
private var currentCategoryId: Int? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
loadAgentData()
|
loadAgentData()
|
||||||
|
loadCategories()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadAgentData() {
|
private fun loadAgentData(categoryId: Int? = null, page: Int = 1, isLoadMore: Boolean = false) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
if (isLoadMore) {
|
||||||
|
isLoadingMore = true
|
||||||
|
} else {
|
||||||
isLoading = true
|
isLoading = true
|
||||||
|
// 重置分页状态
|
||||||
|
currentPage = 1
|
||||||
|
hasMoreData = true
|
||||||
|
currentCategoryId = categoryId
|
||||||
|
}
|
||||||
|
|
||||||
errorMessage = null
|
errorMessage = null
|
||||||
try {
|
try {
|
||||||
val response = apiClient.getAgent(page = 1, pageSize = 20, withWorkflow = 1)
|
val response = if (categoryId != null) {
|
||||||
|
// 根据分类ID获取智能体
|
||||||
|
apiClient.getAgent(
|
||||||
|
page = page,
|
||||||
|
pageSize = pageSize,
|
||||||
|
withWorkflow = 1,
|
||||||
|
categoryIds = listOf(categoryId)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// 获取所有智能体
|
||||||
|
apiClient.getAgent(page = page, pageSize = pageSize, withWorkflow = 1)
|
||||||
|
}
|
||||||
|
|
||||||
if (response.isSuccessful) {
|
if (response.isSuccessful) {
|
||||||
val agents = response.body()?.data?.list ?: emptyList()
|
val responseData = response.body()?.data
|
||||||
agentItems = agents.map { agent ->
|
val agents = responseData?.list ?: emptyList<Agent>()
|
||||||
|
val newAgentItems = agents.map { agent ->
|
||||||
AgentItem.fromAgent(agent)
|
AgentItem.fromAgent(agent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isLoadMore) {
|
||||||
|
// 加载更多:追加到现有列表
|
||||||
|
agentItems = agentItems + newAgentItems
|
||||||
|
currentPage = page
|
||||||
|
} else {
|
||||||
|
// 首次加载或刷新:替换整个列表
|
||||||
|
agentItems = newAgentItems
|
||||||
|
currentPage = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否还有更多数据
|
||||||
|
hasMoreData = agents.size >= pageSize
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
errorMessage = "获取Agent数据失败: ${response.code()}"
|
errorMessage = "获取Agent数据失败: ${response.code()}"
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
errorMessage = "网络请求失败: ${e.message}"
|
errorMessage = "网络请求失败: ${e.message}"
|
||||||
} finally {
|
} finally {
|
||||||
|
if (isLoadMore) {
|
||||||
|
isLoadingMore = false
|
||||||
|
} else {
|
||||||
isLoading = false
|
isLoading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadCategories() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
try {
|
||||||
|
val response = apiClient.getCategories(
|
||||||
|
pageSize = 20,
|
||||||
|
withChildren = false,
|
||||||
|
withParent = false,
|
||||||
|
withCount = true,
|
||||||
|
hideEmpty = true
|
||||||
|
)
|
||||||
|
println("分类数据请求完成,响应成功: ${response.isSuccessful}")
|
||||||
|
if (response.isSuccessful) {
|
||||||
|
val categoryList = response.body()?.data?.list ?: emptyList()
|
||||||
|
println("获取到 ${categoryList.size} 个分类")
|
||||||
|
categories = categoryList.map { category ->
|
||||||
|
CategoryItem.fromCategoryTemplate(category)
|
||||||
|
}
|
||||||
|
println("成功处理并映射了 ${categories.size} 个分类")
|
||||||
|
} else {
|
||||||
|
errorMessage = "获取分类数据失败: ${response.code()}"
|
||||||
|
println("获取分类数据失败: ${response.code()}")
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
errorMessage = "获取分类数据失败: ${e.message}"
|
||||||
|
println("获取分类数据异常: ${e.message}")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadAgentsByCategory(categoryId: Int) {
|
||||||
|
loadAgentData(categoryId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadAllAgents() {
|
||||||
|
loadAgentData()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载更多Agent数据
|
||||||
|
*/
|
||||||
|
fun loadMoreAgents() {
|
||||||
|
// 检查是否正在加载或没有更多数据
|
||||||
|
if (isLoadingMore || !hasMoreData) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val nextPage = currentPage + 1
|
||||||
|
loadAgentData(
|
||||||
|
categoryId = currentCategoryId,
|
||||||
|
page = nextPage,
|
||||||
|
isLoadMore = true
|
||||||
|
)
|
||||||
|
}
|
||||||
fun createSingleChat(
|
fun createSingleChat(
|
||||||
openId: String,
|
openId: String,
|
||||||
) {
|
) {
|
||||||
@@ -119,6 +233,29 @@ object AgentViewModel: ViewModel() {
|
|||||||
errorMessage = null
|
errorMessage = null
|
||||||
isRefreshing = false
|
isRefreshing = false
|
||||||
isLoading = false
|
isLoading = false
|
||||||
|
isLoadingMore = false
|
||||||
|
currentPage = 1
|
||||||
|
hasMoreData = true
|
||||||
|
currentCategoryId = null
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
data class CategoryItem(
|
||||||
|
val id: Int,
|
||||||
|
val name: String,
|
||||||
|
val description: String,
|
||||||
|
val avatar: String,
|
||||||
|
val promptCount: Int?
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun fromCategoryTemplate(template: CategoryTemplate): CategoryItem {
|
||||||
|
return CategoryItem(
|
||||||
|
id = template.id,
|
||||||
|
name = template.name,
|
||||||
|
description = template.description,
|
||||||
|
avatar = "${ApiClient.BASE_API_URL}${template.avatar}",
|
||||||
|
promptCount = template.promptCount
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ 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.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
import com.aiosman.ravenow.ui.composables.TabItem
|
import com.aiosman.ravenow.ui.composables.TabItem
|
||||||
@@ -120,6 +122,8 @@ fun MomentsList() {
|
|||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
// Spacer(modifier = Modifier.width(16.dp))
|
// Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
val lastClickTime = remember { mutableStateOf(0L) }
|
||||||
|
val clickDelay = 500L
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.moment),
|
text = stringResource(R.string.moment),
|
||||||
fontSize = 20.sp,
|
fontSize = 20.sp,
|
||||||
@@ -137,7 +141,11 @@ fun MomentsList() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(24.dp)
|
.size(24.dp)
|
||||||
.noRippleClickable {
|
.noRippleClickable {
|
||||||
|
val currentTime = System.currentTimeMillis()
|
||||||
|
if (currentTime - lastClickTime.value > clickDelay) {
|
||||||
|
lastClickTime.value = currentTime
|
||||||
navController.navigate(NavigationRoute.Search.route)
|
navController.navigate(NavigationRoute.Search.route)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
colorFilter = ColorFilter.tint(AppColors.text)
|
colorFilter = ColorFilter.tint(AppColors.text)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -50,10 +50,12 @@ 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.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.draw.drawWithContent
|
||||||
import androidx.compose.ui.draw.shadow
|
import androidx.compose.ui.draw.shadow
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
|
import androidx.compose.ui.graphics.nativeCanvas
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.layout.onGloballyPositioned
|
import androidx.compose.ui.layout.onGloballyPositioned
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
@@ -369,39 +371,6 @@ fun ProfileV3(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isSelf&&isMain) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.TopEnd)
|
|
||||||
.padding(
|
|
||||||
top = statusBarPaddingValues.calculateTopPadding(),
|
|
||||||
start = 8.dp,
|
|
||||||
end = 8.dp
|
|
||||||
)
|
|
||||||
.noRippleClickable {
|
|
||||||
IndexViewModel.openDrawer = true
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(16.dp)
|
|
||||||
.clip(RoundedCornerShape(8.dp))
|
|
||||||
.background(
|
|
||||||
AppColors.background.copy(
|
|
||||||
alpha = 0.7f
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = R.drawable.rider_pro_more_horizon),
|
|
||||||
contentDescription = "",
|
|
||||||
|
|
||||||
tint = AppColors.text
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Box(
|
Box(
|
||||||
@@ -509,6 +478,7 @@ fun ProfileV3(
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Box(modifier = Modifier.fillMaxWidth()) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -566,7 +536,24 @@ fun ProfileV3(
|
|||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
if (isSelf&&isMain) {
|
if (isSelf&&isMain) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.noRippleClickable {
|
modifier = Modifier
|
||||||
|
.size(24.dp)
|
||||||
|
.padding(16.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
}
|
||||||
|
if (isSelf&&isMain) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.TopEnd)
|
||||||
|
.padding(
|
||||||
|
top = 32.dp ,
|
||||||
|
end = 16.dp
|
||||||
|
)
|
||||||
|
.noRippleClickable {
|
||||||
IndexViewModel.openDrawer = true
|
IndexViewModel.openDrawer = true
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
@@ -584,9 +571,6 @@ fun ProfileV3(
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ fun LoginPage() {
|
|||||||
contentDescription = "Rave Now",
|
contentDescription = "Rave Now",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(52.dp)
|
.size(52.dp)
|
||||||
|
.clip(RoundedCornerShape(10.dp))
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
Text(
|
Text(
|
||||||
|
|||||||
@@ -917,7 +917,20 @@ fun Header(
|
|||||||
Text(
|
Text(
|
||||||
text = nickname ?: "",
|
text = nickname ?: "",
|
||||||
fontWeight = FontWeight.Bold,
|
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,
|
color = AppColors.text,
|
||||||
fontSize = 17.sp
|
fontSize = 17.sp
|
||||||
)
|
)
|
||||||
@@ -1196,7 +1209,7 @@ fun PostImageView(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Navigation and Indicator container
|
// 图片导航控件
|
||||||
if (images.size > 1) {
|
if (images.size > 1) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -1347,91 +1360,19 @@ fun CommentItem(
|
|||||||
}
|
}
|
||||||
) {}
|
) {}
|
||||||
) {
|
) {
|
||||||
Row {
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = commentEntity.name,
|
text = commentEntity.name,
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
fontSize = 11.sp,
|
fontSize = 11.sp,
|
||||||
color = AppColors.text
|
color = AppColors.text
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
Column(
|
||||||
Text(
|
horizontalAlignment = Alignment.End
|
||||||
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)
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
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(
|
AnimatedLikeIcon(
|
||||||
liked = commentEntity.liked,
|
liked = commentEntity.liked,
|
||||||
onClick = {
|
onClick = {
|
||||||
@@ -1446,29 +1387,54 @@ fun CommentItem(
|
|||||||
},
|
},
|
||||||
modifier = Modifier.size(16.dp)
|
modifier = Modifier.size(16.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(4.dp))
|
|
||||||
Text(
|
Text(
|
||||||
text = commentEntity.likes.toString(),
|
text = commentEntity.likes.toString(),
|
||||||
fontSize = 12.sp,
|
fontSize = 12.sp,
|
||||||
fontWeight = FontWeight.Bold,
|
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),
|
Text(
|
||||||
contentDescription = "",
|
text = commentEntity.comment,
|
||||||
modifier = Modifier.size(16.dp),
|
fontSize = 13.sp,
|
||||||
tint = AppColors.nonActiveText
|
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(
|
||||||
text = stringResource(R.string.reply),
|
text = stringResource(R.string.reply),
|
||||||
fontSize = 12.sp,
|
fontSize = 12.sp,
|
||||||
@@ -1541,6 +1507,7 @@ fun CommentItem(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PostBottomBar(
|
fun PostBottomBar(
|
||||||
onCreateCommentClick: () -> Unit = {},
|
onCreateCommentClick: () -> Unit = {},
|
||||||
@@ -1607,6 +1574,24 @@ fun PostBottomBar(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.width(16.dp))
|
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(
|
AnimatedLikeIcon(
|
||||||
liked = momentEntity?.liked == true,
|
liked = momentEntity?.liked == true,
|
||||||
onClick = {
|
onClick = {
|
||||||
@@ -1623,24 +1608,6 @@ fun PostBottomBar(
|
|||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(4.dp))
|
Spacer(modifier = Modifier.width(4.dp))
|
||||||
Text(text = momentEntity?.likeCount.toString(), color = AppColors.text)
|
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(
|
BottomNavigationPlaceholder(
|
||||||
color = AppColors.background
|
color = AppColors.background
|
||||||
|
|||||||
BIN
app/src/main/res/mipmap-hdpi/bars_x_buttons_chat_s.png
Normal file
|
After Width: | Height: | Size: 773 B |
BIN
app/src/main/res/mipmap-hdpi/bars_x_buttons_discover_fill.png
Normal file
|
After Width: | Height: | Size: 927 B |
BIN
app/src/main/res/mipmap-hdpi/bars_x_buttons_home_n_copy.png
Normal file
|
After Width: | Height: | Size: 535 B |
BIN
app/src/main/res/mipmap-hdpi/bars_x_buttons_home_n_copy_2.png
Normal file
|
After Width: | Height: | Size: 772 B |
BIN
app/src/main/res/mipmap-hdpi/bars_x_buttons_user_s.png
Normal file
|
After Width: | Height: | Size: 631 B |
BIN
app/src/main/res/mipmap-hdpi/btn.png
Normal file
|
After Width: | Height: | Size: 975 B |
BIN
app/src/main/res/mipmap-hdpi/group_copy.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
app/src/main/res/mipmap-hdpi/icons_info_magic.png
Normal file
|
After Width: | Height: | Size: 327 B |
BIN
app/src/main/res/mipmap-hdpi/icons_infor_edit.png
Normal file
|
After Width: | Height: | Size: 294 B |
BIN
app/src/main/res/mipmap-mdpi/bars_x_buttons_chat_s.png
Normal file
|
After Width: | Height: | Size: 581 B |
BIN
app/src/main/res/mipmap-mdpi/bars_x_buttons_discover_fill.png
Normal file
|
After Width: | Height: | Size: 634 B |
BIN
app/src/main/res/mipmap-mdpi/bars_x_buttons_home_n_copy.png
Normal file
|
After Width: | Height: | Size: 414 B |
BIN
app/src/main/res/mipmap-mdpi/bars_x_buttons_home_n_copy_2.png
Normal file
|
After Width: | Height: | Size: 602 B |
BIN
app/src/main/res/mipmap-mdpi/bars_x_buttons_user_s.png
Normal file
|
After Width: | Height: | Size: 421 B |
BIN
app/src/main/res/mipmap-mdpi/btn.png
Normal file
|
After Width: | Height: | Size: 660 B |
BIN
app/src/main/res/mipmap-mdpi/group_copy.png
Normal file
|
After Width: | Height: | Size: 768 B |
BIN
app/src/main/res/mipmap-mdpi/icons_info_magic.png
Normal file
|
After Width: | Height: | Size: 276 B |
BIN
app/src/main/res/mipmap-mdpi/icons_infor_edit.png
Normal file
|
After Width: | Height: | Size: 260 B |
BIN
app/src/main/res/mipmap-xhdpi/bars_x_buttons_chat_s.png
Normal file
|
After Width: | Height: | Size: 912 B |
BIN
app/src/main/res/mipmap-xhdpi/bars_x_buttons_discover_fill.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
app/src/main/res/mipmap-xhdpi/bars_x_buttons_home_n_copy.png
Normal file
|
After Width: | Height: | Size: 623 B |
BIN
app/src/main/res/mipmap-xhdpi/bars_x_buttons_home_n_copy_2.png
Normal file
|
After Width: | Height: | Size: 967 B |
BIN
app/src/main/res/mipmap-xhdpi/bars_x_buttons_user_s.png
Normal file
|
After Width: | Height: | Size: 726 B |
BIN
app/src/main/res/mipmap-xhdpi/btn.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/mipmap-xhdpi/group_copy.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/mipmap-xhdpi/icons_info_magic.png
Normal file
|
After Width: | Height: | Size: 374 B |
BIN
app/src/main/res/mipmap-xhdpi/icons_infor_edit.png
Normal file
|
After Width: | Height: | Size: 330 B |
BIN
app/src/main/res/mipmap-xxhdpi/bars_x_buttons_chat_s.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/bars_x_buttons_discover_fill.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/bars_x_buttons_home_n_copy.png
Normal file
|
After Width: | Height: | Size: 816 B |
BIN
app/src/main/res/mipmap-xxhdpi/bars_x_buttons_home_n_copy_2.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/bars_x_buttons_user_s.png
Normal file
|
After Width: | Height: | Size: 966 B |
BIN
app/src/main/res/mipmap-xxhdpi/btn.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/group_copy.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/icons_info_magic.png
Normal file
|
After Width: | Height: | Size: 470 B |
BIN
app/src/main/res/mipmap-xxhdpi/icons_infor_edit.png
Normal file
|
After Width: | Height: | Size: 372 B |
BIN
app/src/main/res/mipmap-xxxhdpi/bars_x_buttons_chat_s.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/bars_x_buttons_discover_fill.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/bars_x_buttons_home_n_copy.png
Normal file
|
After Width: | Height: | Size: 1022 B |
BIN
app/src/main/res/mipmap-xxxhdpi/bars_x_buttons_home_n_copy_2.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/bars_x_buttons_user_s.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/btn.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/group_copy.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/icons_info_magic.png
Normal file
|
After Width: | Height: | Size: 569 B |
BIN
app/src/main/res/mipmap-xxxhdpi/icons_infor_edit.png
Normal file
|
After Width: | Height: | Size: 443 B |
@@ -17,7 +17,7 @@
|
|||||||
<string name="following_upper">关注</string>
|
<string name="following_upper">关注</string>
|
||||||
<string name="unfollow_upper">取消关注</string>
|
<string name="unfollow_upper">取消关注</string>
|
||||||
<string name="comment_count">%d条评论</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="follow_upper">关注</string>
|
||||||
<string name="login_upper">登录</string>
|
<string name="login_upper">登录</string>
|
||||||
<string name="lets_ride_upper">确认</string>
|
<string name="lets_ride_upper">确认</string>
|
||||||
@@ -133,12 +133,13 @@
|
|||||||
<string name="agent_hot">热门</string>
|
<string name="agent_hot">热门</string>
|
||||||
<string name="agent_recommend">推荐</string>
|
<string name="agent_recommend">推荐</string>
|
||||||
<string name="agent_other">其他</string>
|
<string name="agent_other">其他</string>
|
||||||
<string name="agent_add">创建智能体</string>
|
<string name="agent_add">创建AI</string>
|
||||||
<string name="agent_name">名称</string>
|
<string name="agent_name">名称</string>
|
||||||
<string name="agent_name_hint">请输入名称</string>
|
<string name="agent_name_hint">请输入名称</string>
|
||||||
<string name="agent_desc">设定描述</string>
|
<string name="agent_desc">设定描述</string>
|
||||||
<string name="agent_desc_hint">示例: 一位经验丰富的销售员,擅长通过幽默风趣的语言和生动的案例,将复杂的产品转化为客户易于理解并感兴趣的话题</string>
|
<string name="agent_desc_hint">示例: 一位经验丰富的销售员,擅长通过幽默风趣的语言和生动的案例,将复杂的产品转化为客户易于理解并感兴趣的话题</string>
|
||||||
<string name="agent_create">创建智能体</string>
|
<string name="agent_create">创建智能体</string>
|
||||||
|
<string name="create_confirm">好的,就它了</string>
|
||||||
<string name="moment_content_hint">需要一些灵感来写文章吗?让人工智能来帮你!</string>
|
<string name="moment_content_hint">需要一些灵感来写文章吗?让人工智能来帮你!</string>
|
||||||
<string name="moment_ai_co">AI文案优化</string>
|
<string name="moment_ai_co">AI文案优化</string>
|
||||||
<string name="moment_ai_delete">删除</string>
|
<string name="moment_ai_delete">删除</string>
|
||||||
|
|||||||
@@ -178,6 +178,7 @@
|
|||||||
<string name="agent_recommend_agent">推荐给你的智能体</string>
|
<string name="agent_recommend_agent">推荐给你的智能体</string>
|
||||||
<string name="hot_chat_room">正在高能对话中</string>
|
<string name="hot_chat_room">正在高能对话中</string>
|
||||||
<string name="create_agent">创建智能体</string>
|
<string name="create_agent">创建智能体</string>
|
||||||
|
<string name="create_confirm">confirm</string>
|
||||||
<string name="publish_dynamic">发布动态</string>
|
<string name="publish_dynamic">发布动态</string>
|
||||||
<string name="hot_agent">热门智能体</string>
|
<string name="hot_agent">热门智能体</string>
|
||||||
<string name="group_room_enter">进入</string>
|
<string name="group_room_enter">进入</string>
|
||||||
|
|||||||