Various improvements

This commit is contained in:
Ilya Laktyushin
2025-02-22 19:17:36 +04:00
parent eecb2ef5c0
commit 8d7f9bf372
122 changed files with 3454 additions and 1121 deletions

View File

@@ -121,13 +121,18 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
let hideAllAdditionalInfo = item.presentationData.isPreview
var hasSeparateCommentsButton = false
var addedPriceInfo = false
outer: for (message, itemAttributes) in item.content {
for attribute in message.attributes {
if let attribute = attribute as? RestrictedContentMessageAttribute, attribute.platformText(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) != nil {
result.append((message, ChatMessageRestrictedBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
needReactions = false
break outer
} else if let _ = attribute as? PaidStarsMessageAttribute, !addedPriceInfo {
result.append((message, ChatMessageActionBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
addedPriceInfo = true
}
}
@@ -1521,11 +1526,11 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
if let sourceAuthorInfo, let originalAuthorId = sourceAuthorInfo.originalAuthor, let peer = item.message.peers[originalAuthorId] {
effectiveAuthor = peer
} else if let sourceAuthorInfo, let originalAuthorName = sourceAuthorInfo.originalAuthorName {
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(originalAuthorName.persistentHashValue % 32))), accessHash: nil, firstName: originalAuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil, sendPaidMessageStars: nil)
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(originalAuthorName.persistentHashValue % 32))), accessHash: nil, firstName: originalAuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)
} else {
ignoreForward = true
if effectiveAuthor == nil, let authorSignature = forwardInfo.authorSignature {
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil, sendPaidMessageStars: nil)
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)
}
}
}
@@ -1542,7 +1547,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
displayAuthorInfo = !mergedTop.merged && incoming
} else if let forwardInfo = item.content.firstMessage.forwardInfo, forwardInfo.flags.contains(.isImported), let authorSignature = forwardInfo.authorSignature {
ignoreForward = true
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil, sendPaidMessageStars: nil)
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)
displayAuthorInfo = !mergedTop.merged && incoming
} else if let _ = item.content.firstMessage.adAttribute, let author = item.content.firstMessage.author {
ignoreForward = true
@@ -1791,7 +1796,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
var addedContentNodes: [(Message, Bool, ChatMessageBubbleContentNode, Int?)]?
for contentNodeItemValue in contentNodeMessagesAndClasses {
let contentNodeItem = contentNodeItemValue as (message: Message, type: AnyClass, attributes: ChatMessageEntryAttributes, bubbleAttributes: BubbleItemAttributes)
var found = false
for currentNodeItemValue in currentContentClassesPropertiesAndLayouts {
let currentNodeItem = currentNodeItemValue as (message: Message, type: AnyClass, supportsMosaic: Bool, index: Int?, currentLayout: (ChatMessageBubbleContentItem, ChatMessageItemLayoutConstants, ChatMessageBubblePreparePosition, Bool?, CGSize, CGFloat) -> (ChatMessageBubbleContentProperties, CGSize?, CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))))
@@ -1803,7 +1808,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
}
}
if !found {
let contentNode = (contentNodeItem.type as! ChatMessageBubbleContentNode.Type).init()
let contentNode = (contentNodeItem.type as! ChatMessageBubbleContentNode.Type).init()
contentNode.index = contentNodeItem.bubbleAttributes.index
contentPropertiesAndPrepareLayouts.append((contentNodeItem.message, contentNode.supportsMosaic, contentNodeItem.attributes, contentNodeItem.bubbleAttributes, contentNode.asyncLayoutContent()))
if addedContentNodes == nil {
@@ -2028,7 +2033,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
prepareContentPosition = .linear(top: topPosition, bottom: refinedBottomPosition)
}
let contentItem = ChatMessageBubbleContentItem(context: item.context, controllerInteraction: item.controllerInteraction, message: message, topMessage: item.content.firstMessage, read: read, chatLocation: item.chatLocation, presentationData: item.presentationData, associatedData: item.associatedData, attributes: attributes, isItemPinned: isItemPinned, isItemEdited: isItemEdited)
let contentItem = ChatMessageBubbleContentItem(context: item.context, controllerInteraction: item.controllerInteraction, message: message, topMessage: item.content.firstMessage, content: item.content, read: read, chatLocation: item.chatLocation, presentationData: item.presentationData, associatedData: item.associatedData, attributes: attributes, isItemPinned: isItemPinned, isItemEdited: isItemEdited)
var itemSelection: Bool?
switch content {
@@ -2066,22 +2071,24 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
contentPropertiesAndLayouts.append((unboundSize, properties, prepareContentPosition, bubbleAttributes, nodeLayout, needSeparateContainers && !bubbleAttributes.isAttachment ? message.stableId : nil, itemSelection))
switch properties.hidesBackground {
case .never:
backgroundHiding = .never
case .emptyWallpaper:
if backgroundHiding == nil {
backgroundHiding = properties.hidesBackground
}
case .always:
backgroundHiding = .always
}
if !properties.isDetached {
switch properties.hidesBackground {
case .never:
backgroundHiding = .never
case .emptyWallpaper:
if backgroundHiding == nil {
backgroundHiding = properties.hidesBackground
}
case .always:
backgroundHiding = .always
}
switch properties.forceAlignment {
switch properties.forceAlignment {
case .none:
break
case .center:
alignment = .center
}
}
index += 1
@@ -2933,15 +2940,20 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
if let mosaicRange = mosaicRange, mosaicRange.contains(i), let (framesAndPositions, size) = calculatedGroupFramesAndSize {
let mosaicIndex = i - mosaicRange.lowerBound
if mosaicIndex == 0 && i == 0 {
if mosaicIndex == 0 && (i == 0 || (i == 1 && detachedContentNodesHeight > 0)) {
if !headerSize.height.isZero {
contentNodesHeight += 7.0
totalContentNodesHeight += 7.0
}
}
var contentNodeOriginY = contentNodesHeight
if detachedContentNodesHeight > 0 {
contentNodeOriginY -= detachedContentNodesHeight - 4.0
}
let (_, apply) = finalize(maxContentWidth)
let contentNodeFrame = framesAndPositions[mosaicIndex].0.offsetBy(dx: 0.0, dy: contentNodesHeight)
let contentNodeFrame = framesAndPositions[mosaicIndex].0.offsetBy(dx: 0.0, dy: contentNodeOriginY)
contentNodeFramesPropertiesAndApply.append((contentNodeFrame, properties, true, apply))
if i == mosaicRange.upperBound - 1 {
@@ -2950,7 +2962,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
contentNodesHeight += size.height
totalContentNodesHeight += size.height
mosaicStatusOrigin = contentNodeFrame.bottomRight
}
} else {
@@ -2984,9 +2996,17 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
currentItemSelection = itemSelection
}
let contentNodeOriginY = contentNodesHeight - detachedContentNodesHeight
var contentNodeOriginY = contentNodesHeight
if detachedContentNodesHeight > 0 {
contentNodeOriginY -= detachedContentNodesHeight - 4.0
}
let (size, apply) = finalize(maxContentWidth)
let containerFrame = CGRect(origin: CGPoint(x: 0.0, y: contentNodeOriginY), size: size)
var containerFrame = CGRect(origin: CGPoint(x: 0.0, y: contentNodeOriginY), size: size)
if size.height == 33.0 && detachedContentNodesHeight > 0.0 {
//TODO:unmock
containerFrame = containerFrame.offsetBy(dx: 0.0, dy: 2.0)
}
contentNodeFramesPropertiesAndApply.append((containerFrame, properties, contentGroupId == nil, apply))
if contentProperties.neighborType == .media && unlockButtonPosition == nil {
@@ -2998,7 +3018,8 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
totalContentNodesHeight += size.height
if properties.isDetached {
detachedContentNodesHeight += size.height
detachedContentNodesHeight += size.height + 4.0
totalContentNodesHeight += 4.0
}
}
}
@@ -3160,7 +3181,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
nameNodeSizeApply: nameNodeSizeApply,
viaWidth: viaWidth,
contentOrigin: contentOrigin,
nameNodeOriginY: nameNodeOriginY,
nameNodeOriginY: nameNodeOriginY + detachedContentNodesHeight,
authorNameColor: authorNameColor,
layoutConstants: layoutConstants,
currentCredibilityIcon: currentCredibilityIcon,
@@ -3168,11 +3189,11 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
boostNodeSizeApply: boostNodeSizeApply,
contentUpperRightCorner: contentUpperRightCorner,
threadInfoSizeApply: threadInfoSizeApply,
threadInfoOriginY: threadInfoOriginY,
threadInfoOriginY: threadInfoOriginY + detachedContentNodesHeight,
forwardInfoSizeApply: forwardInfoSizeApply,
forwardInfoOriginY: forwardInfoOriginY,
forwardInfoOriginY: forwardInfoOriginY + detachedContentNodesHeight,
replyInfoSizeApply: replyInfoSizeApply,
replyInfoOriginY: replyInfoOriginY,
replyInfoOriginY: replyInfoOriginY + detachedContentNodesHeight,
removedContentNodeIndices: removedContentNodeIndices,
updatedContentNodeOrder: updatedContentNodeOrder,
addedContentNodes: addedContentNodes,
@@ -4049,32 +4070,33 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
}
if let addedContentNodes = addedContentNodes {
for (contentNodeMessage, isAttachment, contentNode, _ ) in addedContentNodes {
for (contentNodeMessage, isAttachment, contentNode, _) in addedContentNodes {
let index = updatedContentNodes.count
updatedContentNodes.append(contentNode)
let contextSourceNode: ContextExtractedContentContainingNode
let containerSupernode: ASDisplayNode
if isAttachment {
contextSourceNode = strongSelf.mainContextSourceNode
containerSupernode = strongSelf.clippingNode
if index < contentNodeFramesPropertiesAndApply.count && contentNodeFramesPropertiesAndApply[index].1.isDetached {
strongSelf.addSubnode(contentNode)
} else {
contextSourceNode = strongSelf.contentContainers.first(where: { $0.contentMessageStableId == contentNodeMessage.stableId })?.sourceNode ?? strongSelf.mainContextSourceNode
containerSupernode = strongSelf.contentContainers.first(where: { $0.contentMessageStableId == contentNodeMessage.stableId })?.sourceNode.contentNode ?? strongSelf.clippingNode
let contextSourceNode: ContextExtractedContentContainingNode
let containerSupernode: ASDisplayNode
if isAttachment {
contextSourceNode = strongSelf.mainContextSourceNode
containerSupernode = strongSelf.clippingNode
} else {
contextSourceNode = strongSelf.contentContainers.first(where: { $0.contentMessageStableId == contentNodeMessage.stableId })?.sourceNode ?? strongSelf.mainContextSourceNode
containerSupernode = strongSelf.contentContainers.first(where: { $0.contentMessageStableId == contentNodeMessage.stableId })?.sourceNode.contentNode ?? strongSelf.clippingNode
}
containerSupernode.addSubnode(contentNode)
contentNode.updateIsTextSelectionActive = { [weak contextSourceNode] value in
contextSourceNode?.updateDistractionFreeMode?(value)
}
contentNode.updateIsExtractedToContextPreview(contextSourceNode.isExtractedToContextPreview)
}
#if DEBUG && false
contentNode.layer.borderColor = UIColor(white: 0.0, alpha: 0.2).cgColor
contentNode.layer.borderWidth = 1.0
#endif
containerSupernode.addSubnode(contentNode)
contentNode.itemNode = strongSelf
contentNode.bubbleBackgroundNode = strongSelf.backgroundNode
contentNode.bubbleBackdropNode = strongSelf.backgroundWallpaperNode
contentNode.updateIsTextSelectionActive = { [weak contextSourceNode] value in
contextSourceNode?.updateDistractionFreeMode?(value)
}
contentNode.requestInlineUpdate = { [weak strongSelf] in
guard let strongSelf else {
return
@@ -4082,7 +4104,6 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
strongSelf.internalUpdateLayout()
}
contentNode.updateIsExtractedToContextPreview(contextSourceNode.isExtractedToContextPreview)
}
}