Merge pull request #87 from Kevinlinpr/nagisa

修复bug、暗色模式适配
This commit is contained in:
2025-11-20 23:06:53 +08:00
committed by GitHub
7 changed files with 315 additions and 253 deletions

View File

@@ -16,9 +16,11 @@ import androidx.compose.runtime.rememberCoroutineScope
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.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.aiosman.ravenow.AppState
import com.aiosman.ravenow.LocalAppTheme
import com.aiosman.ravenow.LocalNavController
import com.aiosman.ravenow.R
@@ -68,6 +70,19 @@ fun ChangePasswordScreen() {
var confirmPasswordError by remember { mutableStateOf<String?>(null) }
var passwordError by remember { mutableStateOf<String?>(null) }
val AppColors = LocalAppTheme.current
// 暗色模式下的 hint 文本颜色
val isDarkMode = AppState.darkMode
val hintColor = if (isDarkMode) {
Color(0xFFFFFFFF).copy(alpha = 0.7f)
} else {
null // 使用默认颜色
}
val labelColor = if (isDarkMode) {
Color(0xFFFFFFFF).copy(alpha = 0.7f)
} else {
null // 使用默认颜色
}
fun validate(): Boolean {
// 使用通用密码校验器校验当前密码
val currentPasswordValidation = PasswordValidator.validateCurrentPassword(currentPassword, context)
@@ -112,7 +127,9 @@ fun ChangePasswordScreen() {
password = true,
label = stringResource(R.string.current_password),
hint = stringResource(R.string.current_password_tip5),
error = oldPasswordError
error = oldPasswordError,
customHintColor = hintColor,
customLabelColor = labelColor
)
Spacer(modifier = Modifier.height(4.dp))
TextInputField(
@@ -121,7 +138,9 @@ fun ChangePasswordScreen() {
password = true,
label = stringResource(R.string.new_password),
hint = stringResource(R.string.new_password),
error = passwordError
error = passwordError,
customHintColor = hintColor,
customLabelColor = labelColor
)
Spacer(modifier = Modifier.height(4.dp))
TextInputField(
@@ -130,7 +149,9 @@ fun ChangePasswordScreen() {
password = true,
label = stringResource(R.string.confirm_new_password_tip1),
hint = stringResource(R.string.new_password_tip1),
error = confirmPasswordError
error = confirmPasswordError,
customHintColor = hintColor,
customLabelColor = labelColor
)
Spacer(modifier = Modifier.height(50.dp))
ActionButton(

View File

@@ -17,6 +17,7 @@ import androidx.compose.runtime.rememberCoroutineScope
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.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
@@ -50,6 +51,14 @@ fun RemoveAccountScreen() {
val scope = rememberCoroutineScope()
val context = LocalContext.current
// 暗色模式下的 hint 文本颜色
val isDarkMode = AppState.darkMode
val hintColor = if (isDarkMode) {
Color(0xFFFFFFFF).copy(alpha = 0.7f)
} else {
null // 使用默认颜色
}
fun removeAccount(password: String) {
// 使用通用密码校验器
val passwordValidation = PasswordValidator.validateCurrentPassword(password, context)
@@ -132,7 +141,8 @@ fun RemoveAccountScreen() {
},
password = true,
hint = stringResource(R.string.remove_account_password_hint),
error = passwordError
error = passwordError,
customHintColor = hintColor
)
Spacer(modifier = Modifier.weight(1f))

View File

@@ -10,6 +10,7 @@ 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.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
@@ -89,26 +90,26 @@ fun AgentChatListScreen() {
.pullRefresh(state)
) {
if (AgentChatListViewModel.agentChatList.isEmpty() && !AgentChatListViewModel.isLoading) {
// 空状态
Column(
Box(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
.padding(horizontal = 16.dp),
contentAlignment = Alignment.Center
) {
// 空状态
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.offset(y = (-40).dp)
) {
val isNetworkAvailable = NetworkUtils.isNetworkAvailable(context)
if (isNetworkAvailable) {
Spacer(modifier = Modifier.height(39.dp))
Image(
painter = painterResource(id = R.mipmap.invalid_name_3),
contentDescription = "null data",
modifier = Modifier
.width(181.dp)
.height(153.dp)
modifier = Modifier.size(120.dp)
)
Spacer(modifier = Modifier.height(9.dp))
Spacer(modifier = Modifier.height(12.dp))
Text(
text = stringResource(R.string.no_one_knocked_yet),
color = AppColors.text,
@@ -119,14 +120,11 @@ fun AgentChatListScreen() {
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
}
else {
Spacer(modifier = Modifier.height(39.dp))
} else {
Image(
painter = painterResource(id = R.mipmap.invalid_name_10),
contentDescription = "network error",
modifier = Modifier
.size(181.dp)
modifier = Modifier.size(120.dp)
)
Spacer(modifier = Modifier.height(24.dp))
Text(
@@ -157,6 +155,7 @@ fun AgentChatListScreen() {
)
}
}
}
} else {
LazyColumn(
modifier = Modifier.fillMaxSize()

View File

@@ -217,24 +217,25 @@ fun AllChatListScreen() {
.pullRefresh(state)
) {
if (allConversations.isEmpty() && !isLoading) {
Column(
Box(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
.padding(horizontal = 16.dp),
contentAlignment = Alignment.Center
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.offset(y = (-40).dp)
) {
val isNetworkAvailable = NetworkUtils.isNetworkAvailable(context)
if (isNetworkAvailable) {
Spacer(modifier = Modifier.height(39.dp))
Image(
painter = painterResource(id = R.mipmap.invalid_name_3),
contentDescription = "null data",
modifier = Modifier
.width(181.dp)
.height(153.dp)
modifier = Modifier.size(120.dp)
)
Spacer(modifier = Modifier.height(9.dp))
Spacer(modifier = Modifier.height(12.dp))
Text(
text = stringResource(R.string.no_one_knocked_yet),
color = AppColors.text,
@@ -246,12 +247,10 @@ fun AllChatListScreen() {
overflow = TextOverflow.Ellipsis
)
} else {
Spacer(modifier = Modifier.height(39.dp))
Image(
painter = painterResource(id = R.mipmap.invalid_name_10),
contentDescription = "network error",
modifier = Modifier
.size(181.dp)
modifier = Modifier.size(120.dp)
)
Spacer(modifier = Modifier.height(24.dp))
Text(
@@ -286,6 +285,7 @@ fun AllChatListScreen() {
)
}
}
}
} else {
LazyColumn(
modifier = Modifier.fillMaxSize()

View File

@@ -72,25 +72,25 @@ fun FriendChatListScreen() {
.pullRefresh(state)
) {
if (FriendChatListViewModel.friendChatList.isEmpty() && !FriendChatListViewModel.isLoading) {
Column(
Box(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
.padding(horizontal = 16.dp),
contentAlignment = Alignment.Center
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
//verticalArrangement = Arrangement.Center
modifier = Modifier.offset(y = (-40).dp)
) {
val isNetworkAvailable = NetworkUtils.isNetworkAvailable(context)
if (isNetworkAvailable) {
Spacer(modifier = Modifier.height(39.dp))
Image(
painter = painterResource(id = R.mipmap.invalid_name_3),
contentDescription = "null data",
modifier = Modifier
.width(181.dp)
.height(153.dp)
modifier = Modifier.size(120.dp)
)
Spacer(modifier = Modifier.height(9.dp))
Spacer(modifier = Modifier.height(12.dp))
Text(
text = stringResource(R.string.no_one_knocked_yet),
color = AppColors.text,
@@ -102,12 +102,10 @@ fun FriendChatListScreen() {
overflow = TextOverflow.Ellipsis
)
} else {
Spacer(modifier = Modifier.height(39.dp))
Image(
painter = painterResource(id = R.mipmap.invalid_name_10),
contentDescription = "network error",
modifier = Modifier
.size(181.dp)
modifier = Modifier.size(120.dp)
)
Spacer(modifier = Modifier.height(24.dp))
Text(
@@ -138,6 +136,7 @@ fun FriendChatListScreen() {
)
}
}
}
} else {
LazyColumn(
modifier = Modifier.fillMaxSize()

View File

@@ -67,24 +67,25 @@ fun GroupChatListScreen() {
.pullRefresh(state)
) {
if (GroupChatListViewModel.groupChatList.isEmpty() && !GroupChatListViewModel.isLoading) {
Column(
Box(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
.padding(horizontal = 16.dp),
contentAlignment = Alignment.Center
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.offset(y = (-40).dp)
) {
val isNetworkAvailable = NetworkUtils.isNetworkAvailable(context)
if (isNetworkAvailable) {
Spacer(modifier = Modifier.height(39.dp))
Image(
painter = painterResource(id = R.mipmap.invalid_name_3),
contentDescription = "null data",
modifier = Modifier
.width(181.dp)
.height(153.dp)
modifier = Modifier.size(120.dp)
)
Spacer(modifier = Modifier.height(9.dp))
Spacer(modifier = Modifier.height(12.dp))
Text(
text = stringResource(R.string.no_one_knocked_yet),
color = AppColors.text,
@@ -96,12 +97,10 @@ fun GroupChatListScreen() {
overflow = TextOverflow.Ellipsis
)
} else {
Spacer(modifier = Modifier.height(39.dp))
Image(
painter = painterResource(id = R.mipmap.invalid_name_10),
contentDescription = "network error",
modifier = Modifier
.size(181.dp)
modifier = Modifier.size(120.dp)
)
Spacer(modifier = Modifier.height(24.dp))
Text(
@@ -132,6 +131,7 @@ fun GroupChatListScreen() {
)
}
}
}
} else {
LazyColumn(
modifier = Modifier.fillMaxSize()

View File

@@ -19,6 +19,8 @@ import com.aiosman.ravenow.entity.MomentEntity
import com.aiosman.ravenow.entity.MomentPagingSource
import com.aiosman.ravenow.entity.MomentRemoteDataSource
import com.aiosman.ravenow.entity.MomentServiceImpl
import com.aiosman.ravenow.event.MomentFavouriteChangeEvent
import com.aiosman.ravenow.event.MomentLikeChangeEvent
import com.aiosman.ravenow.entity.AgentEntity
import com.aiosman.ravenow.entity.AgentRemoteDataSource
import com.aiosman.ravenow.entity.AgentSearchPagingSource
@@ -31,6 +33,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
object SearchViewModel : ViewModel() {
var searchText by mutableStateOf("")
@@ -204,7 +207,14 @@ object SearchViewModel : ViewModel() {
suspend fun likeMoment(id: Int) {
try {
momentService.likeMoment(id)
updateMomentLike(id, true)
val likeCount = updateMomentLike(id, true)
EventBus.getDefault().post(
MomentLikeChangeEvent(
postId = id,
likeCount = likeCount,
isLike = true
)
)
} catch (e: Exception) {
e.printStackTrace()
}
@@ -213,7 +223,14 @@ object SearchViewModel : ViewModel() {
suspend fun dislikeMoment(id: Int) {
try {
momentService.dislikeMoment(id)
updateMomentLike(id, false)
val likeCount = updateMomentLike(id, false)
EventBus.getDefault().post(
MomentLikeChangeEvent(
postId = id,
likeCount = likeCount,
isLike = false
)
)
} catch (e: Exception) {
e.printStackTrace()
}
@@ -223,6 +240,12 @@ object SearchViewModel : ViewModel() {
try {
momentService.favoriteMoment(id)
updateMomentFavorite(id, true)
EventBus.getDefault().post(
MomentFavouriteChangeEvent(
postId = id,
isFavourite = true
)
)
} catch (e: Exception) {
e.printStackTrace()
}
@@ -232,6 +255,12 @@ object SearchViewModel : ViewModel() {
try {
momentService.unfavoriteMoment(id)
updateMomentFavorite(id, false)
EventBus.getDefault().post(
MomentFavouriteChangeEvent(
postId = id,
isFavourite = false
)
)
} catch (e: Exception) {
e.printStackTrace()
}
@@ -241,19 +270,23 @@ object SearchViewModel : ViewModel() {
updateMomentCommentCount(id, 1)
}
private fun updateMomentLike(id: Int, isLike: Boolean) {
private fun updateMomentLike(id: Int, isLike: Boolean): Int? {
var latestLikeCount: Int? = null
val currentPagingData = _momentsFlow.value
val updatedPagingData = currentPagingData.map { momentItem ->
if (momentItem.id == id) {
val nextCount = (momentItem.likeCount + if (isLike) 1 else -1).coerceAtLeast(0)
latestLikeCount = nextCount
momentItem.copy(
liked = isLike,
likeCount = momentItem.likeCount + if (isLike) 1 else -1
likeCount = nextCount
)
} else {
momentItem
}
}
_momentsFlow.value = updatedPagingData
return latestLikeCount
}
private fun updateMomentFavorite(id: Int, isFavorite: Boolean) {
@@ -262,7 +295,7 @@ object SearchViewModel : ViewModel() {
if (momentItem.id == id) {
momentItem.copy(
isFavorite = isFavorite,
favoriteCount = momentItem.favoriteCount + if (isFavorite) 1 else -1
favoriteCount = (momentItem.favoriteCount + if (isFavorite) 1 else -1).coerceAtLeast(0)
)
} else {
momentItem