Исправил переход по своему тэгу в группах и убрал лишнюю подсветку

- Клик по своему упоминанию теперь сразу открывает My Profile без экрана OtherProfile и kebab-меню\n- Нормализовал сравнение аккаунта по publicKey/username (trim + ignoreCase)\n- Убрал жёлтую подсветку сообщений с упоминанием в группах\n- Подровнял положение бейджа верификации рядом с именем
This commit is contained in:
2026-03-06 20:03:50 +05:00
parent 6a269f93db
commit 429025537f
4 changed files with 61 additions and 40 deletions

View File

@@ -2322,6 +2322,10 @@ fun ChatDetailScreen(
username.trim().trimStart('@').lowercase(Locale.ROOT)
if (normalizedUsername.isBlank()) return@MessageBubble
scope.launch {
val normalizedCurrentUsername =
currentUserUsername.trim().trimStart('@').lowercase(Locale.ROOT)
val normalizedOpponentUsername =
user.username.trim().trimStart('@').lowercase(Locale.ROOT)
val targetPublicKey =
mentionCandidates
.firstOrNull {
@@ -2331,22 +2335,34 @@ fun ChatDetailScreen(
)
}
?.publicKey
?.trim()
?.takeIf { it.isNotBlank() }
?: run {
val normalizedCurrent =
currentUserUsername.trim().trimStart('@').lowercase(Locale.ROOT)
if (normalizedCurrent == normalizedUsername && currentUserPublicKey.isNotBlank()) {
currentUserPublicKey
?: run {
if (normalizedCurrentUsername == normalizedUsername && currentUserPublicKey.isNotBlank()) {
currentUserPublicKey.trim()
} else {
val normalizedOpponent =
user.username.trim().trimStart('@').lowercase(Locale.ROOT)
if (normalizedOpponent == normalizedUsername && user.publicKey.isNotBlank()) user.publicKey
if (normalizedOpponentUsername == normalizedUsername && user.publicKey.isNotBlank()) user.publicKey.trim()
else ""
}
}
if (targetPublicKey.isBlank()) return@launch
if (targetPublicKey.equals(currentUserPublicKey.trim(), ignoreCase = true)) {
showContextMenu = false
contextMenuMessage = null
onUserProfileClick(
SearchUser(
title = currentUserName.ifBlank { "You" },
username = currentUserUsername.trim().trimStart('@'),
publicKey = currentUserPublicKey.trim(),
verified = 0,
online = 0
)
)
return@launch
}
val resolvedUser = viewModel.resolveUserForProfile(targetPublicKey)
if (resolvedUser != null) {
showContextMenu = false

View File

@@ -90,22 +90,6 @@ import kotlinx.coroutines.withContext
* organization
*/
private fun containsUserMention(text: String, username: String): Boolean {
val normalizedUsername = username.trim().trimStart('@')
if (normalizedUsername.isBlank()) return false
val mentionRegex =
Regex(
pattern = """(^|\s)@${Regex.escape(normalizedUsername)}(?=\b)""",
options = setOf(RegexOption.IGNORE_CASE)
)
return mentionRegex.containsMatchIn(text)
}
private fun containsAllMention(text: String): Boolean {
val mentionRegex = Regex("""(^|\s)@all(?=\b)""", setOf(RegexOption.IGNORE_CASE))
return mentionRegex.containsMatchIn(text)
}
/**
* Telegram-style layout для текста сообщения с временем. Если текст + время помещаются в одну
* строку - располагает их рядом. Если текст длинный и переносится - время встаёт в правый нижний
@@ -361,21 +345,10 @@ fun MessageBubble(
)
// Colors
val isMentionedIncoming =
remember(message.text, message.isOutgoing, isGroupChat, currentUserUsername) {
!message.isOutgoing &&
isGroupChat &&
message.text.isNotBlank() &&
(containsAllMention(message.text) ||
containsUserMention(message.text, currentUserUsername))
}
val bubbleColor =
remember(message.isOutgoing, isDarkTheme, isMentionedIncoming) {
remember(message.isOutgoing, isDarkTheme) {
if (message.isOutgoing) {
PrimaryBlue
} else if (isMentionedIncoming) {
if (isDarkTheme) Color(0xFF3A3422) else Color(0xFFFFF3CD)
} else {
if (isDarkTheme) Color(0xFF212121) else Color(0xFFF5F5F5)
}

View File

@@ -9,6 +9,7 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@@ -35,6 +36,11 @@ fun VerifiedBadge(
if (verified <= 0) return
var showDialog by remember { mutableStateOf(false) }
val inlineOffsetY: Dp = when {
size <= 16 -> (-0.5).dp
size <= 20 -> (-1).dp
else -> 0.dp
}
// Цвет верификации: в тёмной теме — как индикаторы прочтения (PrimaryBlue), в светлой — #ACD2F9
val badgeColor =
@@ -58,6 +64,7 @@ fun VerifiedBadge(
contentDescription = "Verified",
tint = badgeColor,
modifier = modifier
.offset(y = inlineOffsetY)
.size(size.dp)
.clickable { showDialog = true }
)