Various Fixes

This commit is contained in:
Ilya Laktyushin 2021-08-29 11:59:50 +03:00
parent e43b4b1b02
commit 98b27c9483
9 changed files with 202 additions and 57 deletions

View File

@ -1042,8 +1042,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
if let subject = strongSelf.subject, case .forwardedMessages = subject, !value && (strongSelf.presentationInterfaceState.interfaceState.selectionState?.selectedIds.count ?? 0) < 2 {
return
if let subject = strongSelf.subject, case .forwardedMessages = subject, !value {
let selectedCount = strongSelf.presentationInterfaceState.interfaceState.selectionState?.selectedIds.count ?? 0
let updatedSelectedCount = selectedCount - ids.count
if updatedSelectedCount < 1 {
return
}
}
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withToggledSelectedMessages(ids, value: value) } })
@ -5506,57 +5510,75 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var hasCaptions = false
var uniquePeerIds = Set<PeerId>()
var hasOther = false
for message in messages {
if let author = message.effectiveAuthor, !uniquePeerIds.contains(author.id) {
uniquePeerIds.insert(author.id)
}
if !message.text.isEmpty {
for media in message.media {
if media is TelegramMediaImage || media is TelegramMediaFile {
hasCaptions = true
var isDice = false
var isMusic = false
for media in message.media {
if let media = media as? TelegramMediaFile, media.isMusic {
isMusic = true
} else if media is TelegramMediaDice {
isDice = true
} else {
if !message.text.isEmpty {
if media is TelegramMediaImage || media is TelegramMediaFile {
hasCaptions = true
}
}
}
}
if !isDice && !isMusic {
hasOther = true
}
}
let canHideNames = hasOther
let hideNames = forwardOptions.hideNames
let hideCaptions = forwardOptions.hideCaptions
if case let .peer(peerId) = strongSelf.chatLocation, peerId.namespace == Namespaces.Peer.SecretChat {
} else {
items.append(.action(ContextMenuActionItem(text: uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_ShowSendersName : presentationData.strings.Conversation_ForwardOptions_ShowSendersNames, icon: { theme in
if hideNames {
return nil
} else {
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
}
}, action: { [weak self] _, f in
self?.interfaceInteraction?.updateForwardOptionsState({ current in
var updated = current
updated.hideNames = false
updated.hideCaptions = false
return updated
})
})))
items.append(.action(ContextMenuActionItem(text: uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_HideSendersName : presentationData.strings.Conversation_ForwardOptions_HideSendersNames, icon: { theme in
if hideNames {
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
} else {
return nil
}
}, action: { _, f in
self?.interfaceInteraction?.updateForwardOptionsState({ current in
var updated = current
updated.hideNames = true
return updated
})
})))
if canHideNames {
items.append(.action(ContextMenuActionItem(text: uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_ShowSendersName : presentationData.strings.Conversation_ForwardOptions_ShowSendersNames, icon: { theme in
if hideNames {
return nil
} else {
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
}
}, action: { [weak self] _, f in
self?.interfaceInteraction?.updateForwardOptionsState({ current in
var updated = current
updated.hideNames = false
updated.hideCaptions = false
return updated
})
})))
items.append(.action(ContextMenuActionItem(text: uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_HideSendersName : presentationData.strings.Conversation_ForwardOptions_HideSendersNames, icon: { theme in
if hideNames {
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
} else {
return nil
}
}, action: { _, f in
self?.interfaceInteraction?.updateForwardOptionsState({ current in
var updated = current
updated.hideNames = true
return updated
})
})))
items.append(.separator)
}
if hasCaptions {
items.append(.separator)
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_ShowCaption, icon: { theme in
if hideCaptions {
return nil
@ -5586,9 +5608,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return updated
})
})))
items.append(.separator)
}
items.append(.separator)
}
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_ChangeRecipient, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.contextMenu.primaryColor) }, action: { c, f in

View File

@ -263,9 +263,9 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
messages = messages.map { message in
var flags = message.flags
flags.remove(.Incoming)
flags.remove(.IsIncomingMask)
var attributes = message.attributes
attributes.append(OutgoingScheduleInfoMessageAttribute(scheduleTime: scheduleWhenOnlineTimestamp))
attributes = attributes.filter({ attribute in
if attribute is EditedMessageAttribute {
return false
@ -276,6 +276,12 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
if attribute is ReplyMarkupMessageAttribute {
return false
}
if attribute is ReplyThreadMessageAttribute {
return false
}
if attribute is ViewCountMessageAttribute{
return false
}
return true
})
@ -309,7 +315,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
forwardInfo = nil
}
return message.withUpdatedFlags(flags).withUpdatedText(messageText).withUpdatedMedia(messageMedia).withUpdatedTimestamp(scheduleWhenOnlineTimestamp).withUpdatedAttributes(attributes).withUpdatedAuthor(accountPeer).withUpdatedForwardInfo(forwardInfo)
return message.withUpdatedFlags(flags).withUpdatedText(messageText).withUpdatedMedia(messageMedia).withUpdatedTimestamp(Int32(context.account.network.context.globalTime())).withUpdatedAttributes(attributes).withUpdatedAuthor(accountPeer).withUpdatedForwardInfo(forwardInfo)
}
return (messages, Int32(messages.count), false)

View File

@ -1274,7 +1274,7 @@ final class ChatMediaInputNode: ChatInputNode {
strongSelf.panelFocusScrollToIndex = nil
strongSelf.panelFocusInitialPosition = nil
}
strongSelf.startCollapseTimer(timeout: decelerated ? 0.5 : 1.5)
strongSelf.startCollapseTimer(timeout: decelerated ? 0.5 : 2.0)
strongSelf.scrollingStickerPacksListPromise.set(false)
}
@ -1314,7 +1314,7 @@ final class ChatMediaInputNode: ChatInputNode {
strongSelf.panelFocusScrollToIndex = nil
strongSelf.panelFocusInitialPosition = nil
}
strongSelf.startCollapseTimer(timeout: decelerated ? 0.5 : 1.5)
strongSelf.startCollapseTimer(timeout: decelerated ? 0.5 : 2.0)
}
}
}

View File

@ -661,7 +661,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
return { item, params, mergedTop, mergedBottom, dateHeaderAtBottom in
let accessibilityData = ChatMessageAccessibilityData(item: item, isSelected: nil)
let layoutConstants = chatMessageItemLayoutConstants(layoutConstants, params: params, presentationData: item.presentationData)
let incoming = item.message.effectivelyIncoming(item.context.account.peerId)
let incoming = item.content.effectivelyIncoming(item.context.account.peerId, associatedData: item.associatedData)
var imageSize: CGSize = CGSize(width: 200.0, height: 200.0)
var isEmoji = false
if let _ = telegramDice {
@ -853,10 +853,9 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
var needsReplyBackground = false
var replyMarkup: ReplyMarkupMessageAttribute?
var ignoreForward = self.telegramDice == nil
let availableContentWidth = max(60.0, params.width - params.leftInset - params.rightInset - max(imageSize.width, 160.0) - 20.0 - layoutConstants.bubble.edgeInset * 2.0 - avatarInset - layoutConstants.bubble.contentInsets.left)
var ignoreForward = false
if let forwardInfo = item.message.forwardInfo {
if item.message.id.peerId != item.context.account.peerId {
for attribute in item.message.attributes {

View File

@ -1128,7 +1128,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
let content = item.content
let firstMessage = content.firstMessage
let incoming = item.content.effectivelyIncoming(item.context.account.peerId)
let incoming = item.content.effectivelyIncoming(item.context.account.peerId, associatedData: item.associatedData)
let messageTheme = incoming ? item.presentationData.theme.theme.chat.message.incoming : item.presentationData.theme.theme.chat.message.outgoing
var sourceReference: SourceReferenceMessageAttribute?
@ -1158,7 +1159,10 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
do {
let peerId = chatLocationPeerId
if item.message.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) {
if let subject = item.associatedData.subject, case .forwardedMessages = subject {
displayAuthorInfo = false
} else if item.message.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) {
if let forwardInfo = item.content.firstMessage.forwardInfo {
ignoreForward = true
effectiveAuthor = forwardInfo.author
@ -1683,7 +1687,13 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
}
}
let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, reactionCount: dateReactionCount)
let dateFormat: MessageTimestampStatusFormat
if let subject = item.associatedData.subject, case .forwardedMessages = subject {
dateFormat = .minimal
} else {
dateFormat = .regular
}
let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: dateFormat, reactionCount: dateReactionCount)
let statusType: ChatMessageDateAndStatusType
if message.effectivelyIncoming(item.context.account.peerId) {

View File

@ -1249,8 +1249,17 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
automaticPlayback = false
}
if let actualFetchStatus = self.actualFetchStatus, automaticPlayback || message.forwardInfo != nil {
fetchStatus = actualFetchStatus
if let actualFetchStatus = self.actualFetchStatus {
if automaticPlayback || message.forwardInfo != nil {
fetchStatus = actualFetchStatus
} else {
for attribute in message.attributes {
if let attribute = attribute as? ForwardOptionsMessageAttribute, attribute.hideNames {
fetchStatus = actualFetchStatus
break
}
}
}
}
let gifTitle = game != nil ? strings.Message_Game.uppercased() : strings.Message_Animation.uppercased()

View File

@ -15,7 +15,10 @@ public enum ChatMessageItemContent: Sequence {
case message(message: Message, read: Bool, selection: ChatHistoryMessageSelection, attributes: ChatMessageEntryAttributes)
case group(messages: [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes)])
func effectivelyIncoming(_ accountPeerId: PeerId) -> Bool {
func effectivelyIncoming(_ accountPeerId: PeerId, associatedData: ChatMessageItemAssociatedData? = nil) -> Bool {
if let subject = associatedData?.subject, case .forwardedMessages = subject {
return false
}
switch self {
case let .message(message, _, _, _):
return message.effectivelyIncoming(accountPeerId)
@ -361,9 +364,9 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible {
}
}
self.avatarHeader = avatarHeader
var headers: [ListViewItemHeader] = [self.dateHeader]
if !isScheduledMessages && content.index.timestamp == scheduleWhenOnlineTimestamp {
if case .forwardedMessages = associatedData.subject {
headers = []
}
if let avatarHeader = self.avatarHeader {

View File

@ -36,6 +36,9 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
var telegramFile: TelegramMediaFile?
private let fetchDisposable = MetaDisposable()
private var forwardInfoNode: ChatMessageForwardInfoNode?
private var forwardBackgroundNode: NavigationBackgroundNode?
private var viaBotNode: TextNode?
private let dateAndStatusNode: ChatMessageDateAndStatusNode
private var replyInfoNode: ChatMessageReplyInfoNode?
@ -50,6 +53,8 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
private var currentSwipeToReplyTranslation: CGFloat = 0.0
private var currentSwipeAction: ChatControllerInteractionSwipeAction?
private var appliedForwardInfo: (Peer?, String?)?
private var enableSynchronousImageApply: Bool = false
@ -303,15 +308,18 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
let actionButtonsLayout = ChatMessageActionButtonsNode.asyncLayout(self.actionButtonsNode)
let textLayout = TextNode.asyncLayout(self.textNode)
let makeForwardInfoLayout = ChatMessageForwardInfoNode.asyncLayout(self.forwardInfoNode)
let viaBotLayout = TextNode.asyncLayout(self.viaBotNode)
let makeReplyInfoLayout = ChatMessageReplyInfoNode.asyncLayout(self.replyInfoNode)
let currentShareButtonNode = self.shareButtonNode
let currentForwardInfo = self.appliedForwardInfo
return { item, params, mergedTop, mergedBottom, dateHeaderAtBottom in
let accessibilityData = ChatMessageAccessibilityData(item: item, isSelected: nil)
let layoutConstants = chatMessageItemLayoutConstants(layoutConstants, params: params, presentationData: item.presentationData)
let incoming = item.message.effectivelyIncoming(item.context.account.peerId)
let incoming = item.content.effectivelyIncoming(item.context.account.peerId, associatedData: item.associatedData)
var imageSize: CGSize = CGSize(width: 100.0, height: 100.0)
if let telegramFile = telegramFile {
if let dimensions = telegramFile.dimensions {
@ -501,6 +509,20 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
availableWidth -= 24.0
}
var ignoreForward = false
if let forwardInfo = item.message.forwardInfo {
if item.message.id.peerId != item.context.account.peerId {
for attribute in item.message.attributes {
if let attribute = attribute as? SourceReferenceMessageAttribute {
if attribute.messageId.peerId == forwardInfo.author?.id {
ignoreForward = true
}
break
}
}
}
}
for attribute in item.message.attributes {
if let attribute = attribute as? InlineBotMessageAttribute {
var inlineBotNameString: String?
@ -560,6 +582,41 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
}
let contentHeight = max(imageSize.height, layoutConstants.image.minDimensions.height)
var forwardSource: Peer?
var forwardAuthorSignature: String?
var forwardPsaType: String?
var forwardInfoSizeApply: (CGSize, (CGFloat) -> ChatMessageForwardInfoNode)?
var needsForwardBackground = false
if !ignoreForward, let forwardInfo = item.message.forwardInfo {
forwardPsaType = forwardInfo.psaType
if let source = forwardInfo.source {
forwardSource = source
if let authorSignature = forwardInfo.authorSignature {
forwardAuthorSignature = authorSignature
} else if let forwardInfoAuthor = forwardInfo.author, forwardInfoAuthor.id != source.id {
forwardAuthorSignature = forwardInfoAuthor.displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder)
} else {
forwardAuthorSignature = nil
}
} else {
if let currentForwardInfo = currentForwardInfo, forwardInfo.author == nil && currentForwardInfo.0 != nil {
forwardSource = nil
forwardAuthorSignature = currentForwardInfo.0?.displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder)
} else {
forwardSource = forwardInfo.author
forwardAuthorSignature = forwardInfo.authorSignature
}
}
let availableForwardWidth = max(60.0, availableWidth + 6.0)
forwardInfoSizeApply = makeForwardInfoLayout(item.presentationData, item.presentationData.strings, .standalone, forwardSource, forwardAuthorSignature, forwardPsaType, CGSize(width: availableForwardWidth, height: CGFloat.greatestFiniteMagnitude))
needsForwardBackground = true
}
var maxContentWidth = imageSize.width
var actionButtonsFinalize: ((CGFloat) -> (CGSize, (_ animated: Bool) -> ChatMessageActionButtonsNode))?
if let replyMarkup = replyMarkup {
@ -647,6 +704,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
transition = .animated(duration: duration, curve: .spring)
}
strongSelf.appliedForwardInfo = (forwardSource, forwardAuthorSignature)
strongSelf.updateAccessibilityData(accessibilityData)
transition.updateFrame(node: strongSelf.imageNode, frame: updatedImageFrame)
@ -788,6 +846,33 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
})
}
if needsForwardBackground {
if let forwardBackgroundNode = strongSelf.forwardBackgroundNode {
forwardBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate)
} else {
let forwardBackgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper))
strongSelf.forwardBackgroundNode = forwardBackgroundNode
strongSelf.contextSourceNode.contentNode.addSubnode(forwardBackgroundNode)
}
}
if let (forwardInfoSize, forwardInfoApply) = forwardInfoSizeApply {
let forwardInfoNode = forwardInfoApply(forwardInfoSize.width)
if strongSelf.forwardInfoNode == nil {
strongSelf.forwardInfoNode = forwardInfoNode
strongSelf.contextSourceNode.contentNode.addSubnode(forwardInfoNode)
}
let forwardInfoFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 12.0) : (params.width - params.rightInset - forwardInfoSize.width - layoutConstants.bubble.edgeInset - 12.0)), y: 8.0), size: forwardInfoSize)
forwardInfoNode.frame = forwardInfoFrame
if let forwardBackgroundNode = strongSelf.forwardBackgroundNode {
forwardBackgroundNode.frame = CGRect(origin: CGPoint(x: forwardInfoFrame.minX - 6.0, y: forwardInfoFrame.minY - 2.0), size: CGSize(width: forwardInfoFrame.size.width + 10.0, height: forwardInfoFrame.size.height + 4.0))
forwardBackgroundNode.update(size: forwardBackgroundNode.bounds.size, cornerRadius: 8.0, transition: .immediate)
}
} else if let forwardInfoNode = strongSelf.forwardInfoNode {
forwardInfoNode.removeFromSupernode()
strongSelf.forwardInfoNode = nil
}
if let actionButtonsSizeAndApply = actionButtonsSizeAndApply {
var animated = false
if let _ = strongSelf.actionButtonsNode {
@ -1086,7 +1171,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
return
}
let incoming = item.message.effectivelyIncoming(item.context.account.peerId)
let incoming = item.content.effectivelyIncoming(item.context.account.peerId, associatedData: item.associatedData)
var isEmoji = false
if let item = self.item, item.presentationData.largeEmoji && messageIsElligibleForLargeEmoji(item.message) {
isEmoji = true

View File

@ -90,7 +90,12 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
return (contentProperties, nil, CGFloat.greatestFiniteMagnitude, { constrainedSize, position in
let message = item.message
let incoming = item.message.effectivelyIncoming(item.context.account.peerId)
let incoming: Bool
if let subject = item.associatedData.subject, case .forwardedMessages = subject {
incoming = false
} else {
incoming = item.message.effectivelyIncoming(item.context.account.peerId)
}
var maxTextWidth = CGFloat.greatestFiniteMagnitude
for media in item.message.media {
@ -134,7 +139,13 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
}
}
let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, reactionCount: dateReactionCount)
let dateFormat: MessageTimestampStatusFormat
if let subject = item.associatedData.subject, case .forwardedMessages = subject {
dateFormat = .minimal
} else {
dateFormat = .regular
}
let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: dateFormat, reactionCount: dateReactionCount)
let statusType: ChatMessageDateAndStatusType?
var displayStatus = false