Группы: восстановление ключей по инвайту и Apple Emoji
- Добавлено восстановление локального ключа группы из инвайта при повторном нажатии, даже если на сервере статус уже JOINED. - В карточке приглашения сначала восстанавливается ключ, затем открывается группа. - Включено отображение Apple Emoji для названия/описания группы в GroupInfo и в заголовке группы в чате. - Обновлён превью-заголовок в GroupSetup на Apple Emoji рендер.
This commit is contained in:
@@ -284,6 +284,47 @@ class GroupRepository private constructor(context: Context) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Desktop parity fix:
|
||||
* if user is already joined on server, repeated invite click should still restore local group key.
|
||||
*/
|
||||
suspend fun ensureLocalGroupFromInvite(
|
||||
accountPublicKey: String,
|
||||
accountPrivateKey: String,
|
||||
inviteString: String
|
||||
): GroupJoinResult {
|
||||
val parsed = parseInviteString(inviteString)
|
||||
?: return GroupJoinResult(
|
||||
success = false,
|
||||
status = GroupStatus.INVALID,
|
||||
error = "Invalid invite string"
|
||||
)
|
||||
|
||||
val existingGroupKey = getGroupKey(accountPublicKey, accountPrivateKey, parsed.groupId)
|
||||
if (!existingGroupKey.isNullOrBlank()) {
|
||||
return GroupJoinResult(
|
||||
success = true,
|
||||
status = GroupStatus.JOINED,
|
||||
dialogPublicKey = toGroupDialogPublicKey(parsed.groupId),
|
||||
title = parsed.title
|
||||
)
|
||||
}
|
||||
|
||||
persistJoinedGroup(
|
||||
accountPublicKey = accountPublicKey,
|
||||
accountPrivateKey = accountPrivateKey,
|
||||
parsedInvite = parsed,
|
||||
emitSystemJoinMessage = false
|
||||
)
|
||||
|
||||
return GroupJoinResult(
|
||||
success = true,
|
||||
status = GroupStatus.JOINED,
|
||||
dialogPublicKey = toGroupDialogPublicKey(parsed.groupId),
|
||||
title = parsed.title
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun synchronizeJoinedGroup(
|
||||
accountPublicKey: String,
|
||||
accountPrivateKey: String,
|
||||
|
||||
@@ -90,6 +90,7 @@ import com.rosetta.messenger.ui.chats.components.MultiImageEditorScreen
|
||||
import com.rosetta.messenger.ui.chats.input.*
|
||||
import com.rosetta.messenger.ui.chats.models.*
|
||||
import com.rosetta.messenger.ui.chats.utils.*
|
||||
import com.rosetta.messenger.ui.components.AppleEmojiText
|
||||
import com.rosetta.messenger.ui.components.AvatarImage
|
||||
import com.rosetta.messenger.ui.components.VerifiedBadge
|
||||
import com.rosetta.messenger.ui.onboarding.PrimaryBlue
|
||||
@@ -1133,21 +1134,14 @@ fun ChatDetailScreen(
|
||||
Alignment
|
||||
.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text =
|
||||
chatTitle,
|
||||
fontSize =
|
||||
16.sp,
|
||||
fontWeight =
|
||||
FontWeight
|
||||
.SemiBold,
|
||||
color =
|
||||
Color.White,
|
||||
maxLines =
|
||||
1,
|
||||
overflow =
|
||||
TextOverflow
|
||||
.Ellipsis
|
||||
AppleEmojiText(
|
||||
text = chatTitle,
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = Color.White,
|
||||
maxLines = 1,
|
||||
overflow = android.text.TextUtils.TruncateAt.END,
|
||||
enableLinks = false
|
||||
)
|
||||
if (!isSavedMessages &&
|
||||
!isGroupChat &&
|
||||
|
||||
@@ -122,6 +122,7 @@ import com.rosetta.messenger.ui.chats.components.ImageAttachment
|
||||
import com.rosetta.messenger.ui.chats.components.ImageSourceBounds
|
||||
import com.rosetta.messenger.ui.chats.components.ImageViewerScreen
|
||||
import com.rosetta.messenger.ui.chats.components.ViewableImage
|
||||
import com.rosetta.messenger.ui.components.AppleEmojiText
|
||||
import com.rosetta.messenger.ui.components.AvatarImage
|
||||
import com.rosetta.messenger.ui.components.VerifiedBadge
|
||||
import com.rosetta.messenger.ui.icons.TelegramIcons
|
||||
@@ -854,13 +855,14 @@ fun GroupInfoScreen(
|
||||
|
||||
Spacer(modifier = Modifier.height(14.dp))
|
||||
|
||||
Text(
|
||||
AppleEmojiText(
|
||||
text = groupTitle,
|
||||
color = Color.White,
|
||||
fontSize = 24.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
overflow = android.text.TextUtils.TruncateAt.END,
|
||||
enableLinks = false
|
||||
)
|
||||
|
||||
Text(
|
||||
@@ -917,12 +919,13 @@ fun GroupInfoScreen(
|
||||
|
||||
if (groupDescription.isNotBlank()) {
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
Text(
|
||||
AppleEmojiText(
|
||||
text = groupDescription,
|
||||
color = Color.White.copy(alpha = 0.7f),
|
||||
fontSize = 12.sp,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
overflow = android.text.TextUtils.TruncateAt.END,
|
||||
enableLinks = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ import com.rosetta.messenger.network.SearchUser
|
||||
import com.rosetta.messenger.repository.AvatarRepository
|
||||
import com.rosetta.messenger.ui.components.KeyboardHeightProvider
|
||||
import com.rosetta.messenger.ui.components.OptimizedEmojiPicker
|
||||
import com.rosetta.messenger.ui.components.AppleEmojiText
|
||||
import com.rosetta.messenger.ui.components.AvatarImage
|
||||
import com.rosetta.messenger.ui.icons.TelegramIcons
|
||||
import com.rosetta.messenger.utils.AvatarFileManager
|
||||
@@ -622,13 +623,14 @@ fun GroupSetupScreen(
|
||||
Spacer(modifier = Modifier.size(12.dp))
|
||||
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
AppleEmojiText(
|
||||
text = title.trim(),
|
||||
color = primaryTextColor,
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
overflow = android.text.TextUtils.TruncateAt.END,
|
||||
enableLinks = false
|
||||
)
|
||||
Spacer(modifier = Modifier.height(2.dp))
|
||||
Text(
|
||||
|
||||
@@ -1452,7 +1452,39 @@ private fun GroupInviteInlineCard(
|
||||
if (parsedInvite == null) return
|
||||
|
||||
if (status == GroupStatus.JOINED) {
|
||||
openParsedGroup()
|
||||
if (accountPublicKey.isBlank() || accountPrivateKey.isBlank()) {
|
||||
openParsedGroup()
|
||||
return
|
||||
}
|
||||
|
||||
scope.launch {
|
||||
actionLoading = true
|
||||
val restoreResult =
|
||||
withContext(Dispatchers.IO) {
|
||||
groupRepository.ensureLocalGroupFromInvite(
|
||||
accountPublicKey = accountPublicKey,
|
||||
accountPrivateKey = accountPrivateKey,
|
||||
inviteString = normalizedInvite
|
||||
)
|
||||
}
|
||||
actionLoading = false
|
||||
|
||||
if (restoreResult.success) {
|
||||
status = GroupStatus.JOINED
|
||||
groupRepository.cacheInviteInfo(
|
||||
parsedInvite.groupId,
|
||||
GroupStatus.JOINED,
|
||||
membersCount
|
||||
)
|
||||
openParsedGroup()
|
||||
} else {
|
||||
Toast.makeText(
|
||||
context,
|
||||
restoreResult.error ?: "Failed to restore group access",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user