我的界面ui设置,新加群聊标签以及缺省图

This commit is contained in:
2025-11-07 21:19:17 +08:00
parent 4f588483c0
commit 75eb38b188
37 changed files with 647 additions and 127 deletions

View File

@@ -87,8 +87,8 @@ import com.aiosman.ravenow.ui.composables.toolbar.rememberCollapsingToolbarScaff
import com.aiosman.ravenow.ui.index.IndexViewModel
import com.aiosman.ravenow.ui.index.tabs.profile.composable.GalleryGrid
import com.aiosman.ravenow.ui.post.MenuActionItem
import com.aiosman.ravenow.ui.index.tabs.profile.composable.GroupChatEmptyContent
import com.aiosman.ravenow.ui.index.tabs.profile.composable.OtherProfileAction
import com.aiosman.ravenow.ui.index.tabs.profile.composable.SelfProfileAction
import com.aiosman.ravenow.ui.index.tabs.profile.composable.UserAgentsList
import com.aiosman.ravenow.ui.index.tabs.profile.composable.UserAgentsRow
import com.aiosman.ravenow.ui.index.tabs.profile.composable.UserContentPageIndicator
@@ -129,7 +129,8 @@ fun ProfileV3(
postCount: Long? = null, // 新增参数用于传递帖子总数
) {
val model = MyProfileViewModel
val pagerState = rememberPagerState(pageCount = { if (isAiAccount) 1 else 2 })
// Tabs: 动态、(可选)智能体、群聊
val pagerState = rememberPagerState(pageCount = { if (isAiAccount) 2 else 3 })
val enabled by remember { mutableStateOf(true) }
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
var expanded by remember { mutableStateOf(false) }
@@ -370,41 +371,34 @@ fun ProfileV3(
profile?.let {
UserItem(
accountProfileEntity = it,
postCount = postCount ?: if (isSelf) MyProfileViewModel.momentLoader.total else moments.size.toLong()
postCount = postCount ?: if (isSelf) MyProfileViewModel.momentLoader.total else moments.size.toLong(),
isSelf = isSelf,
onEditClick = {
navController.navigate(NavigationRoute.AccountEdit.route)
}
)
}
}
Spacer(modifier = Modifier.height(20.dp))
// 操作按钮
// 操作按钮(仅其他用户显示)
profile?.let {
Box(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
) {
if (isSelf) {
SelfProfileAction(
onEditProfile = {
navController.navigate(NavigationRoute.AccountEdit.route)
if (!isSelf && it.id != AppState.UserId) {
Box(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
) {
OtherProfileAction(
it,
onFollow = {
onFollowClick()
},
onPremiumClick = {
navController.navigate(NavigationRoute.VipSelPage.route)
onChat = {
onChatClick()
}
)
} else {
if (it.id != AppState.UserId) {
OtherProfileAction(
it,
onFollow = {
onFollowClick()
},
onChat = {
onChatClick()
}
)
}
}
}
}
@@ -458,36 +452,44 @@ fun ProfileV3(
pagerState = pagerState,
showAgentTab = !isAiAccount
)
Spacer(modifier = Modifier.height(8.dp))
HorizontalPager(
state = pagerState,
modifier = Modifier.height(500.dp) // 固定滚动高度
) { idx ->
when (idx) {
0 ->
GalleryGrid(moments = moments)
1 ->
UserAgentsList(
agents = agents,
onAgentClick = onAgentClick,
onAvatarClick = { agent ->
// 导航到智能体个人主页需要通过openId获取用户ID
scope.launch {
try {
val userService = com.aiosman.ravenow.data.UserServiceImpl()
val profile = userService.getUserProfileByOpenId(agent.openId)
navController.navigate(
NavigationRoute.AccountProfile.route
.replace("{id}", profile.id.toString())
.replace("{isAiAccount}", "true")
)
} catch (e: Exception) {
// 处理错误
0 -> GalleryGrid(moments = moments)
1 -> {
if (!isAiAccount) {
UserAgentsList(
agents = agents,
onAgentClick = onAgentClick,
onAvatarClick = { agent ->
// 导航到智能体个人主页需要通过openId获取用户ID
scope.launch {
try {
val userService = com.aiosman.ravenow.data.UserServiceImpl()
val profile = userService.getUserProfileByOpenId(agent.openId)
navController.navigate(
NavigationRoute.AccountProfile.route
.replace("{id}", profile.id.toString())
.replace("{isAiAccount}", "true")
)
} catch (e: Exception) {
// 处理错误
}
}
}
},
modifier = Modifier.fillMaxSize()
)
},
modifier = Modifier.fillMaxSize()
)
} else {
GroupChatPlaceholder()
}
}
2 -> {
if (!isAiAccount) {
GroupChatPlaceholder()
}
}
}
}
}
@@ -582,6 +584,11 @@ fun ProfileV3(
}
}
@Composable
private fun GroupChatPlaceholder() {
GroupChatEmptyContent()
}
//顶部导航栏组件
@Composable
fun TopNavigationBar(

View File

@@ -0,0 +1,167 @@
package com.aiosman.ravenow.ui.index.tabs.profile.composable
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Divider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.ravenow.R
@Composable
fun GroupChatEmptyContent() {
var selectedSegment by remember { mutableStateOf(0) } // 0: 全部, 1: 公开, 2: 私有
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp)
) {
// 分割线(紧贴上方栏)
Divider(
color = Color(0xFFF0F0F0), // 更浅的灰色
thickness = 1.dp,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
// 分段控制器
SegmentedControl(
selectedIndex = selectedSegment,
onSegmentSelected = { selectedSegment = it },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
// 空状态内容(居中)
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
// 空状态插图
EmptyStateIllustration()
Spacer(modifier = Modifier.height(9.dp))
// 空状态文本
Text(
text = "空空如也~",
fontSize = 16.sp,
fontWeight = FontWeight.SemiBold,
color = Color(0xFF000000)
)
}
}
}
@Composable
private fun SegmentedControl(
selectedIndex: Int,
onSegmentSelected: (Int) -> Unit,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier
.height(32.dp),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically
) {
// 全部
SegmentButton(
text = "全部",
isSelected = selectedIndex == 0,
onClick = { onSegmentSelected(0) },
width = 54.dp
)
Spacer(modifier = Modifier.width(8.dp))
// 公开
SegmentButton(
text = "公开",
isSelected = selectedIndex == 1,
onClick = { onSegmentSelected(1) },
width = 59.dp
)
Spacer(modifier = Modifier.width(8.dp))
// 私有
SegmentButton(
text = "私有",
isSelected = selectedIndex == 2,
onClick = { onSegmentSelected(2) },
width = 54.dp
)
}
}
@Composable
private fun SegmentButton(
text: String,
isSelected: Boolean,
onClick: () -> Unit,
width: androidx.compose.ui.unit.Dp
) {
Box(
modifier = Modifier
.width(width)
.height(32.dp)
.background(
color = if (isSelected) {
Color(0xFF110C13) // RGB(17, 12, 19)
} else {
Color(0x147C7480) // RGB(124, 116, 128, alpha 0.08)
},
shape = RoundedCornerShape(1000.dp)
)
.clickable(onClick = onClick),
contentAlignment = Alignment.Center
) {
Text(
text = text,
fontSize = 13.sp,
fontWeight = FontWeight.Normal,
color = if (isSelected) Color(0xFFFFFFFF) else Color(0xFF000000)
)
}
}
@Composable
private fun EmptyStateIllustration() {
Image(
painter = painterResource(id = R.mipmap.l_empty_img),
contentDescription = "空状态",
modifier = Modifier
.width(181.dp)
.height(153.dp),
contentScale = ContentScale.Fit
)
}

View File

@@ -17,6 +17,7 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Divider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -60,15 +61,14 @@ fun UserAgentsList(
) {
val AppColors = LocalAppTheme.current
LazyColumn(
modifier = modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
if (agents.isEmpty()) {
item {
EmptyAgentsView()
}
} else {
if (agents.isEmpty()) {
// 使用带分段控制器的空状态布局
AgentEmptyContentWithSegments()
} else {
LazyColumn(
modifier = modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(agents) { agent ->
UserAgentCard(
agent = agent,
@@ -76,11 +76,11 @@ fun UserAgentsList(
onAvatarClick = onAvatarClick
)
}
}
// 底部间距
item {
Spacer(modifier = Modifier.height(120.dp))
// 底部间距
item {
Spacer(modifier = Modifier.height(120.dp))
}
}
}
}
@@ -198,6 +198,178 @@ fun UserAgentCard(
}
}
@Composable
fun AgentEmptyContentWithSegments() {
var selectedSegment by remember { mutableStateOf(0) } // 0: 全部, 1: 公开, 2: 私有
val AppColors = LocalAppTheme.current
val isNetworkAvailable = NetworkUtils.isNetworkAvailable(LocalContext.current)
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp)
) {
// 分割线(紧贴上方栏)
Divider(
color = Color(0xFFF0F0F0), // 更浅的灰色
thickness = 1.dp,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
// 分段控制器
AgentSegmentedControl(
selectedIndex = selectedSegment,
onSegmentSelected = { selectedSegment = it },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
// 空状态内容(使用智能体原本的图标和文字)
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
if (isNetworkAvailable) {
Image(
painter = painterResource(
id = if(AppState.darkMode) R.mipmap.ai_dark
else R.mipmap.ai),
contentDescription = "暂无Agent",
modifier = Modifier
.size(width = 181.dp, height = 153.dp)
.align(Alignment.CenterHorizontally),
)
// 根据是否为深色模式调整间距
Spacer(modifier = Modifier.height(if(AppState.darkMode) 9.dp else 24.dp))
Text(
text = "专属AI等你召唤",
fontSize = 16.sp,
color = AppColors.text,
fontWeight = FontWeight.W600
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "AI将成为你的伙伴而不是工具",
fontSize = 14.sp,
color = AppColors.secondaryText,
fontWeight = FontWeight.W400
)
} else {
Image(
painter = painterResource(id = R.mipmap.invalid_name_10),
contentDescription = "network error",
modifier = Modifier.size(181.dp),
)
Spacer(modifier = Modifier.height(24.dp))
Text(
text = stringResource(R.string.friend_chat_no_network_title),
fontSize = 16.sp,
color = AppColors.text,
fontWeight = FontWeight.W600
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = stringResource(R.string.friend_chat_no_network_subtitle),
fontSize = 14.sp,
color = AppColors.secondaryText,
fontWeight = FontWeight.W400
)
Spacer(modifier = Modifier.height(16.dp))
ReloadButton(
onClick = {
MyProfileViewModel.ResetModel()
MyProfileViewModel.loadProfile(pullRefresh = true)
}
)
}
}
}
}
@Composable
private fun AgentSegmentedControl(
selectedIndex: Int,
onSegmentSelected: (Int) -> Unit,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier
.height(32.dp),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically
) {
// 全部
AgentSegmentButton(
text = "全部",
isSelected = selectedIndex == 0,
onClick = { onSegmentSelected(0) },
width = 54.dp
)
Spacer(modifier = Modifier.width(8.dp))
// 公开
AgentSegmentButton(
text = "公开",
isSelected = selectedIndex == 1,
onClick = { onSegmentSelected(1) },
width = 59.dp
)
Spacer(modifier = Modifier.width(8.dp))
// 私有
AgentSegmentButton(
text = "私有",
isSelected = selectedIndex == 2,
onClick = { onSegmentSelected(2) },
width = 54.dp
)
}
}
@Composable
private fun AgentSegmentButton(
text: String,
isSelected: Boolean,
onClick: () -> Unit,
width: androidx.compose.ui.unit.Dp
) {
Box(
modifier = Modifier
.width(width)
.height(32.dp)
.background(
color = if (isSelected) {
Color(0xFF110C13) // RGB(17, 12, 19)
} else {
Color(0x147C7480) // RGB(124, 116, 128, alpha 0.08)
},
shape = RoundedCornerShape(1000.dp)
)
.clickable(onClick = onClick),
contentAlignment = Alignment.Center
) {
Text(
text = text,
fontSize = 13.sp,
fontWeight = FontWeight.Normal,
color = if (isSelected) Color(0xFFFFFFFF) else Color(0xFF000000)
)
}
}
@Composable
fun EmptyAgentsView() {
val AppColors = LocalAppTheme.current

View File

@@ -1,26 +1,38 @@
package com.aiosman.ravenow.ui.index.tabs.profile.composable
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.ravenow.AppStore
import com.aiosman.ravenow.LocalAppTheme
import com.aiosman.ravenow.LocalNavController
import com.aiosman.ravenow.R
@@ -29,23 +41,52 @@ import com.aiosman.ravenow.ui.NavigationRoute
import com.aiosman.ravenow.ui.composables.CustomAsyncImage
import com.aiosman.ravenow.ui.composables.rememberDebouncer
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
import java.text.NumberFormat
import java.util.Locale
@Composable
fun UserItem(
accountProfileEntity: AccountProfileEntity,
postCount: Long = 0
postCount: Long = 0,
isSelf: Boolean = false,
onEditClick: () -> Unit = {}
) {
val navController = LocalNavController.current
val AppColors = LocalAppTheme.current
val followerDebouncer = rememberDebouncer()
val followingDebouncer = rememberDebouncer()
// 获取 MBTI 和星座信息
val mbti = remember(accountProfileEntity.id) {
AppStore.getUserMbti(accountProfileEntity.id)
}
val zodiac = remember(accountProfileEntity.id) {
AppStore.getUserZodiac(accountProfileEntity.id)
}
// 格式化粉丝数
val numberFormat = remember { NumberFormat.getNumberInstance(Locale.getDefault()) }
val formattedFollowerCount = remember(accountProfileEntity.followerCount) {
if (accountProfileEntity.followerCount >= 10000) {
val wan = accountProfileEntity.followerCount / 10000.0
if (wan >= 100) {
"${wan.toInt()}"
} else {
String.format("%.1f万", wan)
}
} else {
numberFormat.format(accountProfileEntity.followerCount)
}
}
Column(
modifier = Modifier
.fillMaxWidth()
) {
// 顶部:头像和统计数据
Row(
verticalAlignment = Alignment.CenterVertically
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
// 头像
CustomAsyncImage(
@@ -53,39 +94,47 @@ fun UserItem(
accountProfileEntity.avatar,
modifier = Modifier
.clip(CircleShape)
.size(48.dp),
.size(96.dp),
contentDescription = "",
contentScale = ContentScale.Crop
)
Spacer(modifier = Modifier.width(32.dp))
//个人统计
// 统计数据
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.weight(1f)
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.spacedBy(0.dp),
verticalAlignment = Alignment.CenterVertically
) {
// 帖子数
Column(
modifier = Modifier
.width(80.dp)
.height(40.dp),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.weight(1f)
verticalArrangement = Arrangement.Center
) {
Text(
text = postCount.toString(),
fontWeight = FontWeight.W600,
fontSize = 16.sp,
color = AppColors.text
fontWeight = FontWeight.Medium,
fontSize = 15.sp,
color = Color(0xFF000000),
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(8.dp))
Spacer(modifier = Modifier.height(2.dp))
Text(
text = "帖子",
color = AppColors.text
fontWeight = FontWeight.Normal,
fontSize = 11.sp,
color = Color(0xFF000000),
textAlign = TextAlign.Center
)
}
// 粉丝数
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.weight(1f)
.width(80.dp)
.height(40.dp)
.noRippleClickable {
followerDebouncer {
navController.navigate(
@@ -95,26 +144,33 @@ fun UserItem(
)
)
}
}
},
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = accountProfileEntity.followerCount.toString(),
fontWeight = FontWeight.W600,
fontSize = 16.sp,
color = AppColors.text
text = formattedFollowerCount,
fontWeight = FontWeight.Medium,
fontSize = 15.sp,
color = Color(0xFF000000),
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(8.dp))
Spacer(modifier = Modifier.height(2.dp))
Text(
text = "粉丝",
color = AppColors.text
fontWeight = FontWeight.Normal,
fontSize = 11.sp,
color = Color(0xFF000000),
textAlign = TextAlign.Center
)
}
// 关注数
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.weight(1f)
.width(80.dp)
.height(40.dp)
.offset(x = 6.dp)
.noRippleClickable {
followingDebouncer {
navController.navigate(
@@ -124,49 +180,161 @@ fun UserItem(
)
)
}
}
},
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = accountProfileEntity.followingCount.toString(),
fontWeight = FontWeight.W600,
fontSize = 16.sp,
color = AppColors.text
fontWeight = FontWeight.Medium,
fontSize = 15.sp,
color = Color(0xFF000000),
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(8.dp))
Spacer(modifier = Modifier.height(2.dp))
Text(
text = "关注",
color = AppColors.text
fontWeight = FontWeight.Normal,
fontSize = 11.sp,
color = Color(0xFF000000),
textAlign = TextAlign.Center
)
}
}
}
Spacer(modifier = Modifier.height(12.dp))
// 昵称
Text(
text = accountProfileEntity.nickName,
fontWeight = FontWeight.W600,
fontSize = 16.sp,
color = AppColors.text
)
Spacer(modifier = Modifier.height(4.dp))
// 个人简介
if (accountProfileEntity.bio.isNotEmpty()){
// 中间:昵称、简介、创建者信息
Column(
modifier = Modifier
.fillMaxWidth()
) {
// 昵称
Text(
text = accountProfileEntity.bio,
fontSize = 14.sp,
color = AppColors.secondaryText,
maxLines = 1,
overflow = TextOverflow.Ellipsis
text = accountProfileEntity.nickName,
fontWeight = FontWeight.Bold,
fontSize = 22.sp,
letterSpacing = (-0.3).sp,
color = Color(0xFF000000)
)
}else{
Spacer(modifier = Modifier.height(4.dp))
// 个人简介
if (accountProfileEntity.bio.isNotEmpty()) {
Text(
text = accountProfileEntity.bio,
fontSize = 13.sp,
color = Color(0x993C3C43), // 60/255, 60/255, 67/255, alpha 0.6
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
} else {
Text(
text = "Welcome to my fantiac word i will show you something about magic",
fontSize = 13.sp,
color = Color(0x993C3C43),
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
}
// 创建者信息(如果是 AI 账户,可以显示创建者)
// 注意:当前 AccountProfileEntity 没有创建者字段,这里暂时留空
// 如果需要显示,需要从其他地方获取创建者信息
}
Spacer(modifier = Modifier.height(12.dp))
// 底部:标签按钮
Row(
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalAlignment = Alignment.CenterVertically
) {
// MBTI 标签
if (!mbti.isNullOrEmpty()) {
ProfileTag(
text = mbti,
backgroundColor = Color(0x33FF8D28), // 255/255, 141/255, 40/255, alpha 0.2
textColor = Color(0xFF000000)
)
}
// 星座标签
if (!zodiac.isNullOrEmpty()) {
ProfileTag(
text = zodiac,
backgroundColor = Color(0x33FFCC00), // 255/255, 204/255, 0/255, alpha 0.2
textColor = Color(0xFF000000)
)
}
// 编辑标签(仅自己可见)
if (isSelf) {
ProfileTag(
text = "编辑",
backgroundColor = Color(0x14947A80), // 124/255, 116/255, 128/255, alpha 0.08
textColor = Color(0xFF9284BD), // 146/255, 132/255, 189/255
leadingIcon = {
EditIcon(
color = Color(0xFF9284BD),
modifier = Modifier.size(16.dp)
)
},
onClick = onEditClick
)
}
}
}
}
@Composable
private fun ProfileTag(
text: String,
backgroundColor: Color,
textColor: Color,
leadingIcon: (@Composable () -> Unit)? = null,
onClick: (() -> Unit)? = null
) {
Box(
modifier = Modifier
.height(25.dp)
.clip(RoundedCornerShape(12.dp))
.background(backgroundColor)
.then(
if (onClick != null) {
Modifier.clickable(onClick = onClick)
} else {
Modifier
}
)
.padding(horizontal = 8.dp, vertical = 4.dp),
contentAlignment = Alignment.Center
) {
Row(
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalAlignment = Alignment.CenterVertically
) {
leadingIcon?.invoke()
Text(
text = "No bio here.",
fontSize = 14.sp,
color = AppColors.secondaryText,
maxLines = 1,
overflow = TextOverflow.Ellipsis
text = text,
fontSize = 12.sp,
color = textColor
)
}
}
}
@Composable
private fun EditIcon(
color: Color,
modifier: Modifier = Modifier
) {
Image(
painter = painterResource(id = R.mipmap.bi),
contentDescription = "编辑",
modifier = modifier,
colorFilter = ColorFilter.tint(color)
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 978 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -23,10 +23,11 @@
<string name="login_upper">ログイン</string>
<string name="lets_ride_upper">レッツ・レヴ・ナウ</string>
<string name="or_login_with">または</string>
<string name="remember_me">ログイン状態を保持する</string>
<string name="remember_me">ログインを記憶</string>
<string name="forgot_password">パスワードをお忘れですか?</string>
<string name="login_password_label">パスワード</string>
<string name="login_email_label">メールアドレス</string>
<string name="confirm_password_label">パスワードの確認</string>
<string name="text_error_email_required">メールアドレスは必須です</string>
<string name="text_error_password_required">パスワードは必須です</string>
<string name="text_hint_email">メールアドレスを入力してください</string>
@@ -91,7 +92,7 @@
<string name="reset_mail_send_failed">メールの送信に失敗しました。ネットワーク接続を確認するか、後でもう一度お試しください。</string>
<string name="seconds_ago">%1d秒前</string>
<string name="minutes_ago">%1d分前</string>
<string name="private_policy_template">同意する</string>
<string name="private_policy_template">パイパイに同意する</string>
<string name="private_policy_keyword">Rave Nowのプライバシーポリシー</string>
<string name="gallery">ギャラリー</string>
<string name="chat_upper">チャット</string>
@@ -114,9 +115,10 @@
<string name="report_title">この投稿を報告する理由は?</string>
<string name="close">閉じる</string>
<string name="blocked">ブロック済み</string>
<string name="blocked_users">ブロック済みユーザー</string>
<string name="feedback">フィードバック</string>
<string name="about_rave_now">Rave Nowについて</string>
<string name="account_and_security">アカウントセキュリティ</string>
<string name="account_and_security">アカウントセキュリティ</string>
<string name="remove_account">アカウントを削除</string>
<string name="remove_account_desc">本当にアカウントを削除しますか?この操作は元に戻せません。</string>
<string name="remove_account_password_hint">確認のためパスワードを入力してください</string>

View File

@@ -22,10 +22,11 @@
<string name="login_upper">登录</string>
<string name="lets_ride_upper">确认</string>
<string name="or_login_with">其他账号登录</string>
<string name="remember_me">记住</string>
<string name="remember_me">记住登录</string>
<string name="forgot_password">忘记密码</string>
<string name="login_password_label">密码</string>
<string name="login_email_label">邮箱</string>
<string name="confirm_password_label">确认密码</string>
<string name="text_error_email_required">邮箱是必填项</string>
<string name="text_error_password_required">密码是必填项</string>
<string name="text_hint_email">输入邮箱</string>
@@ -92,7 +93,7 @@
<string name="reset_mail_send_failed">邮件发送失败,请检查您的网络连接或稍后重试。</string>
<string name="seconds_ago">%1d秒前</string>
<string name="minutes_ago">%1d分钟前</string>
<string name="private_policy_template">同意</string>
<string name="private_policy_template">同意派派的</string>
<string name="private_policy_keyword">用户协议</string>
<string name="gallery">图片</string>
<string name="chat_upper">私信</string>
@@ -116,8 +117,9 @@
<string name="close">关闭</string>
<string name="about_rave_now">关于Rave Now</string>
<string name="blocked">已拉黑</string>
<string name="blocked_users">被屏蔽的用户</string>
<string name="feedback">反馈</string>
<string name="account_and_security">户与安全</string>
<string name="account_and_security">安全</string>
<string name="remove_account">删除账户</string>
<string name="remove_account_desc">注销账号为不可逆的操作,请确认</string>
<string name="remove_account_password_hint">输入密码以确认</string>

View File

@@ -22,10 +22,11 @@
<string name="login_upper">Log in</string>
<string name="lets_ride_upper">Let\'s Rave Now</string>
<string name="or_login_with">or</string>
<string name="remember_me">Remember me.</string>
<string name="remember_me">Remember login</string>
<string name="forgot_password">Forgot password?</string>
<string name="login_password_label">What\'s your password</string>
<string name="login_email_label">What\'s your email</string>
<string name="confirm_password_label">Confirm password</string>
<string name="text_error_email_required">Email is required</string>
<string name="text_error_password_required">Password is required</string>
<string name="text_hint_email">Enter your email</string>
@@ -90,7 +91,7 @@
<string name="reset_mail_send_failed">Failed to send email. Please check your network connection or try again later.</string>
<string name="seconds_ago">%1d seconds ago</string>
<string name="minutes_ago">%1d minutes ago</string>
<string name="private_policy_template">I agree to the</string>
<string name="private_policy_template">I agree to Paipai\'s</string>
<string name="private_policy_keyword">Rave Nows Privacy Policy</string>
<string name="gallery">Gallery</string>
<string name="chat_upper">CHAT</string>
@@ -113,9 +114,10 @@
<string name="report_title">Reason for reporting this post?</string>
<string name="close">Close</string>
<string name="blocked">Blocked</string>
<string name="blocked_users">Blocked Users</string>
<string name="feedback">Feedback</string>
<string name="about_rave_now">About Rave Now </string>
<string name="account_and_security">Account and security</string>
<string name="account_and_security">Account Security</string>
<string name="remove_account">Remove Account</string>
<string name="remove_account_desc">Are you sure you want to remove your account? This action cannot be undone.</string>
<string name="remove_account_password_hint">Please enter your password to confirm</string>