Reply-ограничения: Desktop-parity аудит и фикс .call / system accounts

This commit is contained in:
2026-03-29 18:02:01 +05:00
parent 5e89e97301
commit 469f182155
8 changed files with 254 additions and 56 deletions

View File

@@ -59,7 +59,7 @@ struct MessageCellView: View, Equatable {
}
.modifier(ConditionalSwipeToReply(
enabled: !isSavedMessages && !isSystemAccount
&& !message.attachments.contains(where: { $0.type == .avatar || $0.type == .call || $0.type == .messages }),
&& !message.attachments.contains(where: { $0.type == .avatar || $0.type == .messages }),
onReply: { actions.onReply(message) }
))
.overlay {
@@ -545,10 +545,11 @@ struct MessageCellView: View, Equatable {
private func bubbleActions(for message: ChatMessage) -> [BubbleContextAction] {
var result: [BubbleContextAction] = []
// Avatars, calls, and forwarded messages cannot be replied to or forwarded
let isAvatarOrForwarded = message.attachments.contains(where: { $0.type == .avatar || $0.type == .call || $0.type == .messages })
// Desktop parity: system accounts + ATTACHMENTS_NOT_ALLOWED_TO_REPLY = [AVATAR, MESSAGES]
let isAvatarOrForwarded = message.attachments.contains(where: { $0.type == .avatar || $0.type == .messages })
let canReplyForward = !isSavedMessages && !isSystemAccount && !isAvatarOrForwarded
if !isAvatarOrForwarded {
if canReplyForward {
result.append(BubbleContextAction(
title: "Reply",
image: UIImage(systemName: "arrowshape.turn.up.left"),
@@ -562,7 +563,7 @@ struct MessageCellView: View, Equatable {
role: []
) { actions.onCopy(message.text) })
if !isAvatarOrForwarded {
if canReplyForward {
result.append(BubbleContextAction(
title: "Forward",
image: UIImage(systemName: "arrowshape.turn.up.right"),

View File

@@ -147,6 +147,8 @@ final class NativeMessageCell: UICollectionViewCell, UIContextMenuInteractionDel
private var message: ChatMessage?
private var actions: MessageCellActions?
private var currentLayout: MessageCellLayout?
var isSavedMessages = false
var isSystemAccount = false
private var isDeliveryFailedVisible = false
private var wasSentCheckVisible = false
private var wasReadCheckVisible = false
@@ -985,9 +987,10 @@ final class NativeMessageCell: UICollectionViewCell, UIContextMenuInteractionDel
actions.onCopy(message.text)
})
}
// Avatars, calls, and forwarded messages cannot be replied to or forwarded
let isAvatarOrForwarded = message.attachments.contains(where: { $0.type == .avatar || $0.type == .call || $0.type == .messages })
if !isAvatarOrForwarded {
// Desktop parity: system accounts + ATTACHMENTS_NOT_ALLOWED_TO_REPLY = [AVATAR, MESSAGES]
let isAvatarOrForwarded = message.attachments.contains(where: { $0.type == .avatar || $0.type == .messages })
let canReplyForward = !self.isSavedMessages && !self.isSystemAccount && !isAvatarOrForwarded
if canReplyForward {
items.append(UIAction(title: "Reply", image: UIImage(systemName: "arrowshape.turn.up.left")) { _ in
actions.onReply(message)
})
@@ -1005,8 +1008,9 @@ final class NativeMessageCell: UICollectionViewCell, UIContextMenuInteractionDel
// MARK: - Swipe to Reply
@objc private func handleSwipe(_ gesture: UIPanGestureRecognizer) {
// Block swipe on avatar, call, and forwarded-message attachments
let isReplyBlocked = message?.attachments.contains(where: { $0.type == .avatar || $0.type == .call || $0.type == .messages }) ?? false
// Desktop parity: system accounts + ATTACHMENTS_NOT_ALLOWED_TO_REPLY = [AVATAR, MESSAGES]
if isSavedMessages || isSystemAccount { return }
let isReplyBlocked = message?.attachments.contains(where: { $0.type == .avatar || $0.type == .messages }) ?? false
if isReplyBlocked { return }
let translation = gesture.translation(in: contentView)

View File

@@ -254,6 +254,8 @@ final class NativeMessageListController: UIViewController {
}
}
cell.isSavedMessages = self.config.isSavedMessages
cell.isSystemAccount = self.config.isSystemAccount
cell.configure(
message: message,
timestamp: self.formatTimestamp(message.timestamp),