mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-30 07:00:49 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
262d836e8a
@ -61,21 +61,16 @@ public enum InteractiveTransitionGestureRecognizerEdgeWidth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class InteractiveTransitionGestureRecognizer: UIPanGestureRecognizer {
|
public class InteractiveTransitionGestureRecognizer: UIPanGestureRecognizer {
|
||||||
private let staticEdgeWidth: InteractiveTransitionGestureRecognizerEdgeWidth
|
private let edgeWidth: InteractiveTransitionGestureRecognizerEdgeWidth
|
||||||
private let allowedDirections: (CGPoint) -> InteractiveTransitionGestureRecognizerDirections
|
private let allowedDirections: (CGPoint) -> InteractiveTransitionGestureRecognizerDirections
|
||||||
public var dynamicEdgeWidth: ((CGPoint) -> InteractiveTransitionGestureRecognizerEdgeWidth)?
|
|
||||||
|
|
||||||
private var currentEdgeWidth: InteractiveTransitionGestureRecognizerEdgeWidth
|
|
||||||
|
|
||||||
private var ignoreOffset: CGPoint = CGPoint()
|
|
||||||
private var validatedGesture = false
|
private var validatedGesture = false
|
||||||
private var firstLocation: CGPoint = CGPoint()
|
private var firstLocation: CGPoint = CGPoint()
|
||||||
private var currentAllowedDirections: InteractiveTransitionGestureRecognizerDirections = []
|
private var currentAllowedDirections: InteractiveTransitionGestureRecognizerDirections = []
|
||||||
|
|
||||||
public init(target: Any?, action: Selector?, allowedDirections: @escaping (CGPoint) -> InteractiveTransitionGestureRecognizerDirections, edgeWidth: InteractiveTransitionGestureRecognizerEdgeWidth = .constant(16.0)) {
|
public init(target: Any?, action: Selector?, allowedDirections: @escaping (CGPoint) -> InteractiveTransitionGestureRecognizerDirections, edgeWidth: InteractiveTransitionGestureRecognizerEdgeWidth = .constant(16.0)) {
|
||||||
self.allowedDirections = allowedDirections
|
self.allowedDirections = allowedDirections
|
||||||
self.staticEdgeWidth = edgeWidth
|
self.edgeWidth = edgeWidth
|
||||||
self.currentEdgeWidth = edgeWidth
|
|
||||||
|
|
||||||
super.init(target: target, action: action)
|
super.init(target: target, action: action)
|
||||||
|
|
||||||
@ -86,7 +81,6 @@ public class InteractiveTransitionGestureRecognizer: UIPanGestureRecognizer {
|
|||||||
override public func reset() {
|
override public func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
|
|
||||||
self.ignoreOffset = CGPoint()
|
|
||||||
self.validatedGesture = false
|
self.validatedGesture = false
|
||||||
self.currentAllowedDirections = []
|
self.currentAllowedDirections = []
|
||||||
}
|
}
|
||||||
@ -105,10 +99,6 @@ public class InteractiveTransitionGestureRecognizer: UIPanGestureRecognizer {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if let dynamicEdgeWidth = self.dynamicEdgeWidth {
|
|
||||||
self.currentEdgeWidth = dynamicEdgeWidth(point)
|
|
||||||
}
|
|
||||||
|
|
||||||
super.touchesBegan(touches, with: event)
|
super.touchesBegan(touches, with: event)
|
||||||
|
|
||||||
self.firstLocation = point
|
self.firstLocation = point
|
||||||
@ -138,11 +128,6 @@ public class InteractiveTransitionGestureRecognizer: UIPanGestureRecognizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func translation(in view: UIView?) -> CGPoint {
|
|
||||||
let result = super.translation(in: view)
|
|
||||||
return result//.offsetBy(dx: self.ignoreOffset.x, dy: self.ignoreOffset.y)
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
|
override public func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
|
||||||
let location = touches.first!.location(in: self.view)
|
let location = touches.first!.location(in: self.view)
|
||||||
let translation = CGPoint(x: location.x - self.firstLocation.x, y: location.y - self.firstLocation.y)
|
let translation = CGPoint(x: location.x - self.firstLocation.x, y: location.y - self.firstLocation.y)
|
||||||
@ -161,63 +146,41 @@ public class InteractiveTransitionGestureRecognizer: UIPanGestureRecognizer {
|
|||||||
if absTranslationX > 2.0 && absTranslationX > absTranslationY * 2.0 {
|
if absTranslationX > 2.0 && absTranslationX > absTranslationY * 2.0 {
|
||||||
self.state = .failed
|
self.state = .failed
|
||||||
} else if absTranslationY > 2.0 && absTranslationX * 2.0 < absTranslationY {
|
} else if absTranslationY > 2.0 && absTranslationX * 2.0 < absTranslationY {
|
||||||
self.ignoreOffset = CGPoint(x: -translation.x, y: -translation.y)
|
|
||||||
self.validatedGesture = true
|
self.validatedGesture = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let defaultEdgeWidth: CGFloat
|
let edgeWidth: CGFloat
|
||||||
switch self.staticEdgeWidth {
|
switch self.edgeWidth {
|
||||||
case let .constant(value):
|
case let .constant(value):
|
||||||
defaultEdgeWidth = value
|
edgeWidth = value
|
||||||
case let .widthMultiplier(factor, minValue, maxValue):
|
case let .widthMultiplier(factor, minValue, maxValue):
|
||||||
defaultEdgeWidth = max(minValue, min(size.width * factor, maxValue))
|
edgeWidth = max(minValue, min(size.width * factor, maxValue))
|
||||||
}
|
|
||||||
|
|
||||||
let extendedEdgeWidth: CGFloat
|
|
||||||
switch self.currentEdgeWidth {
|
|
||||||
case let .constant(value):
|
|
||||||
extendedEdgeWidth = value
|
|
||||||
case let .widthMultiplier(factor, minValue, maxValue):
|
|
||||||
extendedEdgeWidth = max(minValue, min(size.width * factor, maxValue))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.validatedGesture {
|
if !self.validatedGesture {
|
||||||
if self.firstLocation.x < extendedEdgeWidth && !self.currentAllowedDirections.contains(.rightEdge) {
|
if self.firstLocation.x < edgeWidth && !self.currentAllowedDirections.contains(.rightEdge) {
|
||||||
self.state = .failed
|
self.state = .failed
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if self.firstLocation.x > size.width - extendedEdgeWidth && !self.currentAllowedDirections.contains(.leftEdge) {
|
if self.firstLocation.x > size.width - edgeWidth && !self.currentAllowedDirections.contains(.leftEdge) {
|
||||||
self.state = .failed
|
self.state = .failed
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.currentAllowedDirections.contains(.rightEdge) && self.firstLocation.x < extendedEdgeWidth {
|
if self.currentAllowedDirections.contains(.rightEdge) && self.firstLocation.x < edgeWidth {
|
||||||
if absTranslationY > 2.0 && absTranslationY > absTranslationX * 2.0 {
|
self.validatedGesture = true
|
||||||
self.state = .failed
|
} else if self.currentAllowedDirections.contains(.leftEdge) && self.firstLocation.x > size.width - edgeWidth {
|
||||||
} else if absTranslationX > 2.0 && absTranslationY * 2.0 < absTranslationX {
|
self.validatedGesture = true
|
||||||
self.ignoreOffset = CGPoint(x: -translation.x, y: -translation.y)
|
} else if !self.currentAllowedDirections.contains(.leftCenter) && translation.x < 0.0 {
|
||||||
self.validatedGesture = true
|
self.state = .failed
|
||||||
fireBegan = true
|
} else if !self.currentAllowedDirections.contains(.rightCenter) && translation.x > 0.0 {
|
||||||
}
|
self.state = .failed
|
||||||
} else {
|
} else if absTranslationY > 2.0 && absTranslationY > absTranslationX * 2.0 {
|
||||||
if self.currentAllowedDirections.contains(.rightEdge) && self.firstLocation.x < defaultEdgeWidth {
|
self.state = .failed
|
||||||
self.ignoreOffset = CGPoint(x: -translation.x, y: -translation.y)
|
} else if absTranslationX > 2.0 && absTranslationY * 2.0 < absTranslationX {
|
||||||
self.validatedGesture = true
|
self.validatedGesture = true
|
||||||
} else if self.currentAllowedDirections.contains(.leftEdge) && self.firstLocation.x > size.width - defaultEdgeWidth {
|
fireBegan = true
|
||||||
self.ignoreOffset = CGPoint(x: -translation.x, y: -translation.y)
|
|
||||||
self.validatedGesture = true
|
|
||||||
} else if !self.currentAllowedDirections.contains(.leftCenter) && translation.x < 0.0 {
|
|
||||||
self.state = .failed
|
|
||||||
} else if !self.currentAllowedDirections.contains(.rightCenter) && translation.x > 0.0 {
|
|
||||||
self.state = .failed
|
|
||||||
} else if absTranslationY > 2.0 && absTranslationY > absTranslationX * 2.0 {
|
|
||||||
self.state = .failed
|
|
||||||
} else if absTranslationX > 2.0 && absTranslationY * 2.0 < absTranslationX {
|
|
||||||
self.ignoreOffset = CGPoint(x: -translation.x, y: -translation.y)
|
|
||||||
self.validatedGesture = true
|
|
||||||
fireBegan = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,12 +142,12 @@ public final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelega
|
|||||||
}
|
}
|
||||||
return .right
|
return .right
|
||||||
})
|
})
|
||||||
panRecognizer.dynamicEdgeWidth = { [weak self] _ in
|
/*panRecognizer.dynamicEdgeWidth = { [weak self] _ in
|
||||||
guard let self, let controller = self.controllers.last, let value = controller.interactiveNavivationGestureEdgeWidth else {
|
guard let self, let controller = self.controllers.last, let value = controller.interactiveNavivationGestureEdgeWidth else {
|
||||||
return .constant(16.0)
|
return .constant(16.0)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}*/
|
||||||
if #available(iOS 13.4, *) {
|
if #available(iOS 13.4, *) {
|
||||||
panRecognizer.allowedScrollTypesMask = .continuous
|
panRecognizer.allowedScrollTypesMask = .continuous
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ private final class BubbleSettingsControllerNode: ASDisplayNode, UIScrollViewDel
|
|||||||
let message1 = Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66003, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message1 = Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66003, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message1], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false))
|
items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message1], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false))
|
||||||
|
|
||||||
let message2 = Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66002, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message2 = Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66002, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message2], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false))
|
items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message2], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false))
|
||||||
|
|
||||||
let waveformBase64 = "DAAOAAkACQAGAAwADwAMABAADQAPABsAGAALAA0AGAAfABoAHgATABgAGQAYABQADAAVABEAHwANAA0ACQAWABkACQAOAAwACQAfAAAAGQAVAAAAEwATAAAACAAfAAAAHAAAABwAHwAAABcAGQAAABQADgAAABQAHwAAAB8AHwAAAAwADwAAAB8AEwAAABoAFwAAAB8AFAAAAAAAHwAAAAAAHgAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAAAA="
|
let waveformBase64 = "DAAOAAkACQAGAAwADwAMABAADQAPABsAGAALAA0AGAAfABoAHgATABgAGQAYABQADAAVABEAHwANAA0ACQAWABkACQAOAAwACQAfAAAAGQAVAAAAEwATAAAACAAfAAAAHAAAABwAHwAAABcAGQAAABQADgAAABQAHwAAAB8AHwAAAAwADwAAAB8AEwAAABoAFwAAAB8AFAAAAAAAHwAAAAAAHgAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAAAA="
|
||||||
|
@ -436,7 +436,7 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView
|
|||||||
let message1 = Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66003, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message1 = Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66003, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message1], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false))
|
items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message1], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false))
|
||||||
|
|
||||||
let message2 = Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66002, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message2 = Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66002, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message2], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false))
|
items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message2], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false))
|
||||||
|
|
||||||
let waveformBase64 = "DAAOAAkACQAGAAwADwAMABAADQAPABsAGAALAA0AGAAfABoAHgATABgAGQAYABQADAAVABEAHwANAA0ACQAWABkACQAOAAwACQAfAAAAGQAVAAAAEwATAAAACAAfAAAAHAAAABwAHwAAABcAGQAAABQADgAAABQAHwAAAB8AHwAAAAwADwAAAB8AEwAAABoAFwAAAB8AFAAAAAAAHwAAAAAAHgAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAAAA="
|
let waveformBase64 = "DAAOAAkACQAGAAwADwAMABAADQAPABsAGAALAA0AGAAfABoAHgATABgAGQAYABQADAAVABEAHwANAA0ACQAWABkACQAOAAwACQAfAAAAGQAVAAAAEwATAAAACAAfAAAAHAAAABwAHwAAABcAGQAAABQADgAAABQAHwAAAB8AHwAAAAwADwAAAB8AEwAAABoAFwAAAB8AFAAAAAAAHwAAAAAAHgAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAAAA="
|
||||||
|
@ -1048,7 +1048,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
|||||||
messages[message4.id] = message4
|
messages[message4.id] = message4
|
||||||
sampleMessages.append(message4)
|
sampleMessages.append(message4)
|
||||||
|
|
||||||
let message5 = Message(stableId: 5, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 5), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66004, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [ReplyMessageAttribute(messageId: message4.id, threadMessageId: nil, quote: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message5 = Message(stableId: 5, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 5), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66004, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [ReplyMessageAttribute(messageId: message4.id, threadMessageId: nil, quote: nil, isQuote: false)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
messages[message5.id] = message5
|
messages[message5.id] = message5
|
||||||
sampleMessages.append(message5)
|
sampleMessages.append(message5)
|
||||||
|
|
||||||
@ -1059,7 +1059,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
|||||||
let message6 = Message(stableId: 6, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 6), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66005, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message6 = Message(stableId: 6, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 6), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66005, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
sampleMessages.append(message6)
|
sampleMessages.append(message6)
|
||||||
|
|
||||||
let message7 = Message(stableId: 7, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 7), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66006, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: message5.id, threadMessageId: nil, quote: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message7 = Message(stableId: 7, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 7), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66006, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: message5.id, threadMessageId: nil, quote: nil, isQuote: false)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
sampleMessages.append(message7)
|
sampleMessages.append(message7)
|
||||||
|
|
||||||
let message8 = Message(stableId: 8, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 8), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66007, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message8 = Message(stableId: 8, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 8), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66007, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
|
@ -599,7 +599,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
messages[message4.id] = message4
|
messages[message4.id] = message4
|
||||||
sampleMessages.append(message4)
|
sampleMessages.append(message4)
|
||||||
|
|
||||||
let message5 = Message(stableId: 5, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 5), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66004, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [ReplyMessageAttribute(messageId: message4.id, threadMessageId: nil, quote: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message5 = Message(stableId: 5, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 5), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66004, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [ReplyMessageAttribute(messageId: message4.id, threadMessageId: nil, quote: nil, isQuote: false)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
messages[message5.id] = message5
|
messages[message5.id] = message5
|
||||||
sampleMessages.append(message5)
|
sampleMessages.append(message5)
|
||||||
|
|
||||||
@ -610,7 +610,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
let message6 = Message(stableId: 6, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 6), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66005, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message6 = Message(stableId: 6, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 6), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66005, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
sampleMessages.append(message6)
|
sampleMessages.append(message6)
|
||||||
|
|
||||||
let message7 = Message(stableId: 7, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 7), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66006, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: message5.id, threadMessageId: nil, quote: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message7 = Message(stableId: 7, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 7), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66006, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: message5.id, threadMessageId: nil, quote: nil, isQuote: false)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
sampleMessages.append(message7)
|
sampleMessages.append(message7)
|
||||||
|
|
||||||
let message8 = Message(stableId: 8, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 8), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66007, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message8 = Message(stableId: 8, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 8), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66007, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
|
@ -159,7 +159,7 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode {
|
|||||||
messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
}
|
}
|
||||||
|
|
||||||
let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: messageItem.outgoing ? otherPeerId : peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: messageItem.outgoing ? [] : [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: messageItem.outgoing ? TelegramUser(id: otherPeerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil) : nil, text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil)] : [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: messageItem.outgoing ? otherPeerId : peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: messageItem.outgoing ? [] : [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: messageItem.outgoing ? TelegramUser(id: otherPeerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil) : nil, text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false)] : [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
items.append(item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [message], theme: item.componentTheme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode, availableReactions: nil, isCentered: false))
|
items.append(item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [message], theme: item.componentTheme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode, availableReactions: nil, isCentered: false))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,6 +590,8 @@ extension StoreMessage {
|
|||||||
let isForumTopic = (innerFlags & (1 << 3)) != 0
|
let isForumTopic = (innerFlags & (1 << 3)) != 0
|
||||||
|
|
||||||
var quote: EngineMessageReplyQuote?
|
var quote: EngineMessageReplyQuote?
|
||||||
|
let isQuote = (innerFlags & (1 << 9)) != 0
|
||||||
|
|
||||||
if quoteText != nil || replyMedia != nil {
|
if quoteText != nil || replyMedia != nil {
|
||||||
quote = EngineMessageReplyQuote(text: quoteText ?? "", entities: messageTextEntitiesFromApiEntities(quoteEntities ?? []), media: textMediaAndExpirationTimerFromApiMedia(replyMedia, peerId).media)
|
quote = EngineMessageReplyQuote(text: quoteText ?? "", entities: messageTextEntitiesFromApiEntities(quoteEntities ?? []), media: textMediaAndExpirationTimerFromApiMedia(replyMedia, peerId).media)
|
||||||
}
|
}
|
||||||
@ -601,9 +603,7 @@ extension StoreMessage {
|
|||||||
if isForumTopic {
|
if isForumTopic {
|
||||||
let threadIdValue = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: replyToTopId)
|
let threadIdValue = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: replyToTopId)
|
||||||
threadMessageId = threadIdValue
|
threadMessageId = threadIdValue
|
||||||
if replyPeerId == peerId {
|
threadId = makeMessageThreadId(threadIdValue)
|
||||||
threadId = makeMessageThreadId(threadIdValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let threadIdValue = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: replyToTopId)
|
let threadIdValue = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: replyToTopId)
|
||||||
@ -623,10 +623,10 @@ extension StoreMessage {
|
|||||||
threadId = makeMessageThreadId(threadIdValue)
|
threadId = makeMessageThreadId(threadIdValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: threadMessageId, quote: quote))
|
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: threadMessageId, quote: quote, isQuote: isQuote))
|
||||||
}
|
}
|
||||||
if let replyHeader = replyHeader {
|
if let replyHeader = replyHeader {
|
||||||
attributes.append(QuotedReplyMessageAttribute(apiHeader: replyHeader, quote: quote))
|
attributes.append(QuotedReplyMessageAttribute(apiHeader: replyHeader, quote: quote, isQuote: isQuote))
|
||||||
}
|
}
|
||||||
case let .messageReplyStoryHeader(userId, storyId):
|
case let .messageReplyStoryHeader(userId, storyId):
|
||||||
attributes.append(ReplyStoryAttribute(storyId: StoryId(peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), id: storyId)))
|
attributes.append(ReplyStoryAttribute(storyId: StoryId(peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), id: storyId)))
|
||||||
@ -867,8 +867,9 @@ extension StoreMessage {
|
|||||||
if let replyTo = replyTo {
|
if let replyTo = replyTo {
|
||||||
var threadMessageId: MessageId?
|
var threadMessageId: MessageId?
|
||||||
switch replyTo {
|
switch replyTo {
|
||||||
case let .messageReplyHeader(_, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities):
|
case let .messageReplyHeader(innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities):
|
||||||
var quote: EngineMessageReplyQuote?
|
var quote: EngineMessageReplyQuote?
|
||||||
|
let isQuote = (innerFlags & (1 << 9)) != 0
|
||||||
if quoteText != nil || replyMedia != nil {
|
if quoteText != nil || replyMedia != nil {
|
||||||
quote = EngineMessageReplyQuote(text: quoteText ?? "", entities: messageTextEntitiesFromApiEntities(quoteEntities ?? []), media: textMediaAndExpirationTimerFromApiMedia(replyMedia, peerId).media)
|
quote = EngineMessageReplyQuote(text: quoteText ?? "", entities: messageTextEntitiesFromApiEntities(quoteEntities ?? []), media: textMediaAndExpirationTimerFromApiMedia(replyMedia, peerId).media)
|
||||||
}
|
}
|
||||||
@ -892,9 +893,9 @@ extension StoreMessage {
|
|||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: threadMessageId, quote: quote))
|
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: threadMessageId, quote: quote, isQuote: isQuote))
|
||||||
} else if let replyHeader = replyHeader {
|
} else if let replyHeader = replyHeader {
|
||||||
attributes.append(QuotedReplyMessageAttribute(apiHeader: replyHeader, quote: quote))
|
attributes.append(QuotedReplyMessageAttribute(apiHeader: replyHeader, quote: quote, isQuote: isQuote))
|
||||||
}
|
}
|
||||||
case let .messageReplyStoryHeader(userId, storyId):
|
case let .messageReplyStoryHeader(userId, storyId):
|
||||||
attributes.append(ReplyStoryAttribute(storyId: StoryId(peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), id: storyId)))
|
attributes.append(ReplyStoryAttribute(storyId: StoryId(peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), id: storyId)))
|
||||||
|
@ -563,6 +563,7 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
|
|||||||
if let replyToMessageId = replyToMessageId {
|
if let replyToMessageId = replyToMessageId {
|
||||||
var threadMessageId: MessageId?
|
var threadMessageId: MessageId?
|
||||||
var quote = replyToMessageId.quote
|
var quote = replyToMessageId.quote
|
||||||
|
let isQuote = quote != nil
|
||||||
if let replyMessage = transaction.getMessage(replyToMessageId.messageId) {
|
if let replyMessage = transaction.getMessage(replyToMessageId.messageId) {
|
||||||
threadMessageId = replyMessage.effectiveReplyThreadMessageId
|
threadMessageId = replyMessage.effectiveReplyThreadMessageId
|
||||||
if quote == nil, replyToMessageId.messageId.peerId != peerId {
|
if quote == nil, replyToMessageId.messageId.peerId != peerId {
|
||||||
@ -579,7 +580,7 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
|
|||||||
quote = EngineMessageReplyQuote(text: replyMessage.text, entities: messageTextEntitiesInRange(entities: replyMessage.textEntitiesAttribute?.entities ?? [], range: NSRange(location: 0, length: nsText.length), onlyQuoteable: true), media: replyMedia)
|
quote = EngineMessageReplyQuote(text: replyMessage.text, entities: messageTextEntitiesInRange(entities: replyMessage.textEntitiesAttribute?.entities ?? [], range: NSRange(location: 0, length: nsText.length), onlyQuoteable: true), media: replyMedia)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
attributes.append(ReplyMessageAttribute(messageId: replyToMessageId.messageId, threadMessageId: threadMessageId, quote: quote))
|
attributes.append(ReplyMessageAttribute(messageId: replyToMessageId.messageId, threadMessageId: threadMessageId, quote: quote, isQuote: isQuote))
|
||||||
}
|
}
|
||||||
if let replyToStoryId = replyToStoryId {
|
if let replyToStoryId = replyToStoryId {
|
||||||
attributes.append(ReplyStoryAttribute(storyId: replyToStoryId))
|
attributes.append(ReplyStoryAttribute(storyId: replyToStoryId))
|
||||||
|
@ -164,7 +164,7 @@ public func standaloneSendEnqueueMessages(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let replyToMessageId = message.replyToMessageId {
|
if let replyToMessageId = message.replyToMessageId {
|
||||||
attributes.append(ReplyMessageAttribute(messageId: replyToMessageId, threadMessageId: nil, quote: nil))
|
attributes.append(ReplyMessageAttribute(messageId: replyToMessageId, threadMessageId: nil, quote: nil, isQuote: false))
|
||||||
}
|
}
|
||||||
if let forwardOptions = message.forwardOptions {
|
if let forwardOptions = message.forwardOptions {
|
||||||
attributes.append(ForwardOptionsMessageAttribute(hideNames: forwardOptions.hideNames, hideCaptions: forwardOptions.hideCaptions))
|
attributes.append(ForwardOptionsMessageAttribute(hideNames: forwardOptions.hideNames, hideCaptions: forwardOptions.hideCaptions))
|
||||||
|
@ -793,7 +793,9 @@ public final class PendingMessageManager {
|
|||||||
if peerId != replyAttribute.messageId.peerId {
|
if peerId != replyAttribute.messageId.peerId {
|
||||||
replyPeerId = replyAttribute.messageId.peerId
|
replyPeerId = replyAttribute.messageId.peerId
|
||||||
}
|
}
|
||||||
replyQuote = replyAttribute.quote
|
if replyAttribute.isQuote {
|
||||||
|
replyQuote = replyAttribute.quote
|
||||||
|
}
|
||||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||||
replyToStoryId = attribute.storyId
|
replyToStoryId = attribute.storyId
|
||||||
} else if let _ = attribute as? ForwardSourceInfoAttribute {
|
} else if let _ = attribute as? ForwardSourceInfoAttribute {
|
||||||
@ -1160,7 +1162,9 @@ public final class PendingMessageManager {
|
|||||||
if peer.id != replyAttribute.messageId.peerId {
|
if peer.id != replyAttribute.messageId.peerId {
|
||||||
replyPeerId = replyAttribute.messageId.peerId
|
replyPeerId = replyAttribute.messageId.peerId
|
||||||
}
|
}
|
||||||
replyQuote = replyAttribute.quote
|
if replyAttribute.isQuote {
|
||||||
|
replyQuote = replyAttribute.quote
|
||||||
|
}
|
||||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||||
replyToStoryId = attribute.storyId
|
replyToStoryId = attribute.storyId
|
||||||
} else if let outgoingInfo = attribute as? OutgoingMessageInfoAttribute {
|
} else if let outgoingInfo = attribute as? OutgoingMessageInfoAttribute {
|
||||||
|
@ -881,7 +881,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) {
|
if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) {
|
||||||
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil))
|
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false))
|
||||||
}
|
}
|
||||||
|
|
||||||
var entitiesAttribute: TextEntitiesMessageAttribute?
|
var entitiesAttribute: TextEntitiesMessageAttribute?
|
||||||
@ -1113,7 +1113,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) {
|
if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) {
|
||||||
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil))
|
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false))
|
||||||
}
|
}
|
||||||
|
|
||||||
var entitiesAttribute: TextEntitiesMessageAttribute?
|
var entitiesAttribute: TextEntitiesMessageAttribute?
|
||||||
@ -1392,7 +1392,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) {
|
if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) {
|
||||||
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil))
|
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false))
|
||||||
}
|
}
|
||||||
|
|
||||||
var entitiesAttribute: TextEntitiesMessageAttribute?
|
var entitiesAttribute: TextEntitiesMessageAttribute?
|
||||||
@ -1593,7 +1593,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) {
|
if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) {
|
||||||
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil))
|
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false))
|
||||||
}
|
}
|
||||||
|
|
||||||
var entitiesAttribute: TextEntitiesMessageAttribute?
|
var entitiesAttribute: TextEntitiesMessageAttribute?
|
||||||
|
@ -6,15 +6,17 @@ public class ReplyMessageAttribute: MessageAttribute {
|
|||||||
public let messageId: MessageId
|
public let messageId: MessageId
|
||||||
public let threadMessageId: MessageId?
|
public let threadMessageId: MessageId?
|
||||||
public let quote: EngineMessageReplyQuote?
|
public let quote: EngineMessageReplyQuote?
|
||||||
|
public let isQuote: Bool
|
||||||
|
|
||||||
public var associatedMessageIds: [MessageId] {
|
public var associatedMessageIds: [MessageId] {
|
||||||
return [self.messageId]
|
return [self.messageId]
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(messageId: MessageId, threadMessageId: MessageId?, quote: EngineMessageReplyQuote?) {
|
public init(messageId: MessageId, threadMessageId: MessageId?, quote: EngineMessageReplyQuote?, isQuote: Bool) {
|
||||||
self.messageId = messageId
|
self.messageId = messageId
|
||||||
self.threadMessageId = threadMessageId
|
self.threadMessageId = threadMessageId
|
||||||
self.quote = quote
|
self.quote = quote
|
||||||
|
self.isQuote = isQuote
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(decoder: PostboxDecoder) {
|
required public init(decoder: PostboxDecoder) {
|
||||||
@ -28,6 +30,7 @@ public class ReplyMessageAttribute: MessageAttribute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.quote = decoder.decodeCodable(EngineMessageReplyQuote.self, forKey: "qu")
|
self.quote = decoder.decodeCodable(EngineMessageReplyQuote.self, forKey: "qu")
|
||||||
|
self.isQuote = decoder.decodeBoolForKey("iq", orElse: self.quote != nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
@ -44,6 +47,7 @@ public class ReplyMessageAttribute: MessageAttribute {
|
|||||||
} else {
|
} else {
|
||||||
encoder.encodeNil(forKey: "qu")
|
encoder.encodeNil(forKey: "qu")
|
||||||
}
|
}
|
||||||
|
encoder.encodeBool(self.isQuote, forKey: "iq")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +55,7 @@ public class QuotedReplyMessageAttribute: MessageAttribute {
|
|||||||
public let peerId: PeerId?
|
public let peerId: PeerId?
|
||||||
public let authorName: String?
|
public let authorName: String?
|
||||||
public let quote: EngineMessageReplyQuote?
|
public let quote: EngineMessageReplyQuote?
|
||||||
|
public let isQuote: Bool
|
||||||
|
|
||||||
public var associatedMessageIds: [MessageId] {
|
public var associatedMessageIds: [MessageId] {
|
||||||
return []
|
return []
|
||||||
@ -64,16 +69,18 @@ public class QuotedReplyMessageAttribute: MessageAttribute {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(peerId: PeerId?, authorName: String?, quote: EngineMessageReplyQuote?) {
|
public init(peerId: PeerId?, authorName: String?, quote: EngineMessageReplyQuote?, isQuote: Bool) {
|
||||||
self.peerId = peerId
|
self.peerId = peerId
|
||||||
self.authorName = authorName
|
self.authorName = authorName
|
||||||
self.quote = quote
|
self.quote = quote
|
||||||
|
self.isQuote = isQuote
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(decoder: PostboxDecoder) {
|
required public init(decoder: PostboxDecoder) {
|
||||||
self.peerId = decoder.decodeOptionalInt64ForKey("p").flatMap(PeerId.init)
|
self.peerId = decoder.decodeOptionalInt64ForKey("p").flatMap(PeerId.init)
|
||||||
self.authorName = decoder.decodeOptionalStringForKey("a")
|
self.authorName = decoder.decodeOptionalStringForKey("a")
|
||||||
self.quote = decoder.decodeCodable(EngineMessageReplyQuote.self, forKey: "qu")
|
self.quote = decoder.decodeCodable(EngineMessageReplyQuote.self, forKey: "qu")
|
||||||
|
self.isQuote = decoder.decodeBoolForKey("iq", orElse: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
@ -94,14 +101,16 @@ public class QuotedReplyMessageAttribute: MessageAttribute {
|
|||||||
} else {
|
} else {
|
||||||
encoder.encodeNil(forKey: "qu")
|
encoder.encodeNil(forKey: "qu")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
encoder.encodeBool(self.isQuote, forKey: "iq")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension QuotedReplyMessageAttribute {
|
extension QuotedReplyMessageAttribute {
|
||||||
convenience init(apiHeader: Api.MessageFwdHeader, quote: EngineMessageReplyQuote?) {
|
convenience init(apiHeader: Api.MessageFwdHeader, quote: EngineMessageReplyQuote?, isQuote: Bool) {
|
||||||
switch apiHeader {
|
switch apiHeader {
|
||||||
case let .messageFwdHeader(_, fromId, fromName, _, _, _, _, _, _):
|
case let .messageFwdHeader(_, fromId, fromName, _, _, _, _, _, _):
|
||||||
self.init(peerId: fromId?.peerId, authorName: fromName, quote: quote)
|
self.init(peerId: fromId?.peerId, authorName: fromName, quote: quote, isQuote: isQuote)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
@property (nonatomic, copy) bool (^ _Nullable shouldRespondToAction)(SEL _Nullable);
|
@property (nonatomic, copy) bool (^ _Nullable shouldRespondToAction)(SEL _Nullable);
|
||||||
@property (nonatomic, copy) bool (^ _Nullable shouldReturn)();
|
@property (nonatomic, copy) bool (^ _Nullable shouldReturn)();
|
||||||
@property (nonatomic, copy) void (^ _Nullable backspaceWhileEmpty)();
|
@property (nonatomic, copy) void (^ _Nullable backspaceWhileEmpty)();
|
||||||
|
@property (nonatomic, copy) void (^ _Nullable dropAutocorrectioniOS16)();
|
||||||
|
|
||||||
- (instancetype _Nonnull)initWithFrame:(CGRect)frame textContainer:(NSTextContainer * _Nullable)textContainer disableTiling:(bool)disableTiling;
|
- (instancetype _Nonnull)initWithFrame:(CGRect)frame textContainer:(NSTextContainer * _Nullable)textContainer disableTiling:(bool)disableTiling;
|
||||||
|
|
||||||
|
@ -12,6 +12,12 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface ChatInputTextViewImpl () <UIGestureRecognizerDelegate> {
|
||||||
|
UIGestureRecognizer *_tapRecognizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation ChatInputTextViewImpl
|
@implementation ChatInputTextViewImpl
|
||||||
|
|
||||||
- (instancetype _Nonnull)initWithFrame:(CGRect)frame textContainer:(NSTextContainer * _Nullable)textContainer disableTiling:(bool)disableTiling {
|
- (instancetype _Nonnull)initWithFrame:(CGRect)frame textContainer:(NSTextContainer * _Nullable)textContainer disableTiling:(bool)disableTiling {
|
||||||
@ -26,10 +32,40 @@
|
|||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (@available(iOS 17.0, *)) {
|
||||||
|
} else {
|
||||||
|
_tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(workaroundTapGesture:)];
|
||||||
|
_tapRecognizer.cancelsTouchesInView = false;
|
||||||
|
_tapRecognizer.delaysTouchesBegan = false;
|
||||||
|
_tapRecognizer.delaysTouchesEnded = false;
|
||||||
|
_tapRecognizer.delegate = self;
|
||||||
|
[self addGestureRecognizer:_tapRecognizer];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)workaroundTapGesture:(UITapGestureRecognizer *)recognizer {
|
||||||
|
if (recognizer.state == UIGestureRecognizerStateEnded) {
|
||||||
|
static Class promptClass = nil;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
promptClass = NSClassFromString([[NSString alloc] initWithFormat:@"%@AutocorrectInlinePrompt", @"UI"]);
|
||||||
|
});
|
||||||
|
UIView *result = [self hitTest:[recognizer locationInView:self] withEvent:nil];
|
||||||
|
if (result != nil && [result class] == promptClass) {
|
||||||
|
if (_dropAutocorrectioniOS16) {
|
||||||
|
_dropAutocorrectioniOS16();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
|
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
|
||||||
{
|
{
|
||||||
if (_shouldRespondToAction) {
|
if (_shouldRespondToAction) {
|
||||||
|
@ -32,7 +32,6 @@ open class ChatInputTextNode: ASDisplayNode, UITextViewDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var selectionChangedForEditedText: Bool = false
|
private var selectionChangedForEditedText: Bool = false
|
||||||
private var isPreservingSelection: Bool = false
|
|
||||||
|
|
||||||
public var textView: ChatInputTextView {
|
public var textView: ChatInputTextView {
|
||||||
return self.view as! ChatInputTextView
|
return self.view as! ChatInputTextView
|
||||||
@ -81,20 +80,7 @@ open class ChatInputTextNode: ASDisplayNode, UITextViewDelegate {
|
|||||||
get {
|
get {
|
||||||
return self.textView.attributedText
|
return self.textView.attributedText
|
||||||
} set(value) {
|
} set(value) {
|
||||||
if self.textView.attributedText != value {
|
self.textView.attributedText = value
|
||||||
let selectedRange = self.textView.selectedRange;
|
|
||||||
let preserveSelectedRange = selectedRange.location != self.textView.textStorage.length
|
|
||||||
|
|
||||||
self.textView.attributedText = value ?? NSAttributedString()
|
|
||||||
|
|
||||||
if preserveSelectedRange {
|
|
||||||
self.isPreservingSelection = true
|
|
||||||
self.textView.selectedRange = selectedRange
|
|
||||||
self.isPreservingSelection = false
|
|
||||||
}
|
|
||||||
|
|
||||||
self.textView.updateTextContainerInset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +150,7 @@ open class ChatInputTextNode: ASDisplayNode, UITextViewDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc public func textViewDidChangeSelection(_ textView: UITextView) {
|
@objc public func textViewDidChangeSelection(_ textView: UITextView) {
|
||||||
if self.isPreservingSelection {
|
if self.textView.isPreservingSelection {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +173,9 @@ open class ChatInputTextNode: ASDisplayNode, UITextViewDelegate {
|
|||||||
guard let delegate = self.delegate else {
|
guard let delegate = self.delegate else {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if self.textView.isPreservingText {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return delegate.chatInputTextNode(shouldChangeTextIn: range, replacementText: text)
|
return delegate.chatInputTextNode(shouldChangeTextIn: range, replacementText: text)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,6 +295,30 @@ public final class ChatInputTextView: ChatInputTextViewImpl, NSLayoutManagerDele
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override public var attributedText: NSAttributedString? {
|
||||||
|
get {
|
||||||
|
return super.attributedText
|
||||||
|
} set(value) {
|
||||||
|
if self.attributedText != value {
|
||||||
|
let selectedRange = self.selectedRange
|
||||||
|
let preserveSelectedRange = selectedRange.location != self.textStorage.length
|
||||||
|
|
||||||
|
super.attributedText = value ?? NSAttributedString()
|
||||||
|
|
||||||
|
if preserveSelectedRange {
|
||||||
|
self.isPreservingSelection = true
|
||||||
|
self.selectedRange = selectedRange
|
||||||
|
self.isPreservingSelection = false
|
||||||
|
}
|
||||||
|
|
||||||
|
self.updateTextContainerInset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate var isPreservingSelection: Bool = false
|
||||||
|
fileprivate var isPreservingText: Bool = false
|
||||||
|
|
||||||
public weak var customDelegate: ChatInputTextNodeDelegate?
|
public weak var customDelegate: ChatInputTextNodeDelegate?
|
||||||
|
|
||||||
public var theme: Theme? {
|
public var theme: Theme? {
|
||||||
@ -391,6 +404,27 @@ public final class ChatInputTextView: ChatInputTextViewImpl, NSLayoutManagerDele
|
|||||||
self.customTextStorage.delegate = self
|
self.customTextStorage.delegate = self
|
||||||
self.measurementTextStorage.delegate = self
|
self.measurementTextStorage.delegate = self
|
||||||
|
|
||||||
|
self.dropAutocorrectioniOS16 = { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.isPreservingSelection = true
|
||||||
|
self.isPreservingText = true
|
||||||
|
|
||||||
|
let rangeCopy = self.selectedRange
|
||||||
|
var fakeRange = rangeCopy
|
||||||
|
if fakeRange.location != 0 {
|
||||||
|
fakeRange.location -= 1
|
||||||
|
}
|
||||||
|
self.unmarkText()
|
||||||
|
self.selectedRange = fakeRange
|
||||||
|
self.selectedRange = rangeCopy
|
||||||
|
|
||||||
|
self.isPreservingSelection = false
|
||||||
|
self.isPreservingText = false
|
||||||
|
}
|
||||||
|
|
||||||
self.shouldCopy = { [weak self] in
|
self.shouldCopy = { [weak self] in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return true
|
return true
|
||||||
@ -542,7 +576,7 @@ public final class ChatInputTextView: ChatInputTextViewImpl, NSLayoutManagerDele
|
|||||||
|
|
||||||
if self.measurementTextStorage != self.attributedText || self.measurementTextContainer.size != measureSize || self.measurementTextContainer.rightInset != rightInset {
|
if self.measurementTextStorage != self.attributedText || self.measurementTextContainer.size != measureSize || self.measurementTextContainer.rightInset != rightInset {
|
||||||
self.measurementTextContainer.rightInset = rightInset
|
self.measurementTextContainer.rightInset = rightInset
|
||||||
self.measurementTextStorage.setAttributedString(self.attributedText)
|
self.measurementTextStorage.setAttributedString(self.attributedText ?? NSAttributedString())
|
||||||
self.measurementTextContainer.size = measureSize
|
self.measurementTextContainer.size = measureSize
|
||||||
self.measurementLayoutManager.invalidateLayout(forCharacterRange: NSRange(location: 0, length: self.measurementTextStorage.length), actualCharacterRange: nil)
|
self.measurementLayoutManager.invalidateLayout(forCharacterRange: NSRange(location: 0, length: self.measurementTextStorage.length), actualCharacterRange: nil)
|
||||||
self.measurementLayoutManager.ensureLayout(for: self.measurementTextContainer)
|
self.measurementLayoutManager.ensureLayout(for: self.measurementTextContainer)
|
||||||
@ -772,6 +806,7 @@ private final class QuoteBackgroundView: UIView {
|
|||||||
|
|
||||||
self.backgroundView.update(
|
self.backgroundView.update(
|
||||||
size: size,
|
size: size,
|
||||||
|
isTransparent: false,
|
||||||
primaryColor: theme.foreground,
|
primaryColor: theme.foreground,
|
||||||
secondaryColor: theme.lineStyle != .solid ? .clear : nil,
|
secondaryColor: theme.lineStyle != .solid ? .clear : nil,
|
||||||
thirdColor: theme.lineStyle == .tripleDashed ? .clear : nil,
|
thirdColor: theme.lineStyle == .tripleDashed ? .clear : nil,
|
||||||
|
@ -114,8 +114,8 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
private var threadInfoNode: ChatMessageThreadInfoNode?
|
private var threadInfoNode: ChatMessageThreadInfoNode?
|
||||||
private var replyInfoNode: ChatMessageReplyInfoNode?
|
private var replyInfoNode: ChatMessageReplyInfoNode?
|
||||||
private var replyBackgroundContent: WallpaperBubbleBackgroundNode?
|
private var replyBackgroundContent: WallpaperBubbleBackgroundNode?
|
||||||
private var replyBackgroundNode: NavigationBackgroundNode?
|
|
||||||
private var forwardInfoNode: ChatMessageForwardInfoNode?
|
private var forwardInfoNode: ChatMessageForwardInfoNode?
|
||||||
|
private var forwardBackgroundContent: WallpaperBubbleBackgroundNode?
|
||||||
|
|
||||||
private var actionButtonsNode: ChatMessageActionButtonsNode?
|
private var actionButtonsNode: ChatMessageActionButtonsNode?
|
||||||
private var reactionButtonsNode: ChatMessageReactionButtonsNode?
|
private var reactionButtonsNode: ChatMessageReactionButtonsNode?
|
||||||
@ -305,7 +305,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
if let item = self.item {
|
if let item = self.item {
|
||||||
let _ = item
|
let _ = item
|
||||||
replyRecognizer.allowBothDirections = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply
|
replyRecognizer.allowBothDirections = false//!item.context.sharedContext.immediateExperimentalUISettings.unidirectionalSwipeToReply
|
||||||
self.view.disablesInteractiveTransitionGestureRecognizer = true
|
self.view.disablesInteractiveTransitionGestureRecognizer = false
|
||||||
}
|
}
|
||||||
replyRecognizer.shouldBegin = { [weak self] in
|
replyRecognizer.shouldBegin = { [weak self] in
|
||||||
if let strongSelf = self, let item = strongSelf.item {
|
if let strongSelf = self, let item = strongSelf.item {
|
||||||
@ -1058,7 +1058,6 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
var viaBotApply: (TextNodeLayout, () -> TextNode)?
|
var viaBotApply: (TextNodeLayout, () -> TextNode)?
|
||||||
var threadInfoApply: (CGSize, (Bool) -> ChatMessageThreadInfoNode)?
|
var threadInfoApply: (CGSize, (Bool) -> ChatMessageThreadInfoNode)?
|
||||||
var replyInfoApply: (CGSize, (CGSize, Bool, ListViewItemUpdateAnimation) -> ChatMessageReplyInfoNode)?
|
var replyInfoApply: (CGSize, (CGSize, Bool, ListViewItemUpdateAnimation) -> ChatMessageReplyInfoNode)?
|
||||||
var needsReplyBackground = false
|
|
||||||
var replyMarkup: ReplyMarkupMessageAttribute?
|
var replyMarkup: ReplyMarkupMessageAttribute?
|
||||||
|
|
||||||
var availableContentWidth = min(200.0, 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 availableContentWidth = min(200.0, 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))
|
||||||
@ -1080,7 +1079,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
|
|
||||||
var replyMessage: Message?
|
var replyMessage: Message?
|
||||||
var replyForward: QuotedReplyMessageAttribute?
|
var replyForward: QuotedReplyMessageAttribute?
|
||||||
var replyQuote: EngineMessageReplyQuote?
|
var replyQuote: (quote: EngineMessageReplyQuote, isQuote: Bool)?
|
||||||
var replyStory: StoryId?
|
var replyStory: StoryId?
|
||||||
for attribute in item.message.attributes {
|
for attribute in item.message.attributes {
|
||||||
if let attribute = attribute as? InlineBotMessageAttribute {
|
if let attribute = attribute as? InlineBotMessageAttribute {
|
||||||
@ -1107,7 +1106,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
} else {
|
} else {
|
||||||
replyMessage = item.message.associatedMessages[replyAttribute.messageId]
|
replyMessage = item.message.associatedMessages[replyAttribute.messageId]
|
||||||
}
|
}
|
||||||
replyQuote = replyAttribute.quote
|
replyQuote = replyAttribute.quote.flatMap { ($0, replyAttribute.isQuote) }
|
||||||
} else if let quoteReplyAttribute = attribute as? QuotedReplyMessageAttribute {
|
} else if let quoteReplyAttribute = attribute as? QuotedReplyMessageAttribute {
|
||||||
replyForward = quoteReplyAttribute
|
replyForward = quoteReplyAttribute
|
||||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||||
@ -1216,10 +1215,16 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
forwardInfoSizeApply = makeForwardInfoLayout(item.context, item.presentationData, item.presentationData.strings, .standalone, forwardSource, forwardAuthorSignature, forwardPsaType, nil, CGSize(width: availableWidth, height: CGFloat.greatestFiniteMagnitude))
|
forwardInfoSizeApply = makeForwardInfoLayout(item.context, item.presentationData, item.presentationData.strings, .standalone, forwardSource, forwardAuthorSignature, forwardPsaType, nil, CGSize(width: availableWidth, height: CGFloat.greatestFiniteMagnitude))
|
||||||
}
|
}
|
||||||
|
|
||||||
if replyInfoApply != nil || viaBotApply != nil || forwardInfoSizeApply != nil {
|
var needsReplyBackground = false
|
||||||
|
if replyInfoApply != nil {
|
||||||
needsReplyBackground = true
|
needsReplyBackground = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var needsForwardBackground = false
|
||||||
|
if viaBotApply != nil || forwardInfoSizeApply != nil {
|
||||||
|
needsForwardBackground = true
|
||||||
|
}
|
||||||
|
|
||||||
var maxContentWidth = imageSize.width
|
var maxContentWidth = imageSize.width
|
||||||
var actionButtonsFinalize: ((CGFloat) -> (CGSize, (_ animation: ListViewItemUpdateAnimation) -> ChatMessageActionButtonsNode))?
|
var actionButtonsFinalize: ((CGFloat) -> (CGSize, (_ animation: ListViewItemUpdateAnimation) -> ChatMessageActionButtonsNode))?
|
||||||
if let replyMarkup = replyMarkup {
|
if let replyMarkup = replyMarkup {
|
||||||
@ -1272,6 +1277,53 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
layoutSize.height += 4.0 + reactionButtonsSizeAndApply.0.height
|
layoutSize.height += 4.0 + reactionButtonsSizeAndApply.0.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var headersOffset: CGFloat = 0.0
|
||||||
|
if let (threadInfoSize, _) = threadInfoApply {
|
||||||
|
headersOffset += threadInfoSize.height + 10.0
|
||||||
|
}
|
||||||
|
|
||||||
|
var viaBotFrame: CGRect?
|
||||||
|
if let (viaBotLayout, _) = viaBotApply {
|
||||||
|
viaBotFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 15.0) : (params.width - params.rightInset - viaBotLayout.size.width - layoutConstants.bubble.edgeInset - 14.0)), y: headersOffset + 8.0), size: viaBotLayout.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
var replyInfoFrame: CGRect?
|
||||||
|
if let (replyInfoSize, _) = replyInfoApply {
|
||||||
|
var viaBotSize = CGSize()
|
||||||
|
if let viaBotFrame = viaBotFrame {
|
||||||
|
viaBotSize = viaBotFrame.size
|
||||||
|
}
|
||||||
|
let replyInfoFrameValue = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 10.0) : (params.width - params.rightInset - max(replyInfoSize.width, viaBotSize.width) - layoutConstants.bubble.edgeInset - 10.0)), y: headersOffset + 8.0 + viaBotSize.height), size: replyInfoSize)
|
||||||
|
replyInfoFrame = replyInfoFrameValue
|
||||||
|
if let viaBotFrameValue = viaBotFrame {
|
||||||
|
if replyInfoFrameValue.minX < replyInfoFrameValue.minX {
|
||||||
|
viaBotFrame = viaBotFrameValue.offsetBy(dx: replyInfoFrameValue.minX - viaBotFrameValue.minX, dy: 0.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var replyBackgroundFrame: CGRect?
|
||||||
|
if let replyInfoFrame = replyInfoFrame {
|
||||||
|
var viaBotSize = CGSize()
|
||||||
|
if let viaBotFrame = viaBotFrame {
|
||||||
|
viaBotSize = viaBotFrame.size
|
||||||
|
}
|
||||||
|
|
||||||
|
replyBackgroundFrame = CGRect(origin: CGPoint(x: replyInfoFrame.minX - 4.0, y: headersOffset + replyInfoFrame.minY - viaBotSize.height - 2.0), size: CGSize(width: max(replyInfoFrame.size.width, viaBotSize.width) + 8.0, height: replyInfoFrame.size.height + viaBotSize.height + 5.0))
|
||||||
|
}
|
||||||
|
let _ = replyBackgroundFrame
|
||||||
|
|
||||||
|
/*if let replyBackgroundFrameValue = replyBackgroundFrame {
|
||||||
|
if replyBackgroundFrameValue.insetBy(dx: -2.0, dy: -2.0).intersects(baseShareButtonFrame) {
|
||||||
|
let offset: CGFloat = 25.0
|
||||||
|
|
||||||
|
layoutSize.height += offset
|
||||||
|
updatedImageFrame.origin.y += offset
|
||||||
|
dateAndStatusFrame.origin.y += offset
|
||||||
|
baseShareButtonFrame.origin.y += offset
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
func finishLayout(_ animation: ListViewItemUpdateAnimation, _ apply: ListViewItemApply, _ synchronousLoads: Bool) {
|
func finishLayout(_ animation: ListViewItemUpdateAnimation, _ apply: ListViewItemApply, _ synchronousLoads: Bool) {
|
||||||
if let strongSelf = weakSelf.value {
|
if let strongSelf = weakSelf.value {
|
||||||
strongSelf.appliedForwardInfo = (forwardSource, forwardAuthorSignature)
|
strongSelf.appliedForwardInfo = (forwardSource, forwardAuthorSignature)
|
||||||
@ -1391,34 +1443,31 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
dateAndStatusApply(animation)
|
dateAndStatusApply(animation)
|
||||||
|
|
||||||
if needsReplyBackground {
|
if needsReplyBackground {
|
||||||
if let replyBackgroundNode = strongSelf.replyBackgroundNode {
|
if strongSelf.replyBackgroundContent == nil, let backgroundContent = item.controllerInteraction.presentationContext.backgroundNode?.makeBubbleBackground(for: .free) {
|
||||||
replyBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate)
|
backgroundContent.clipsToBounds = true
|
||||||
} else {
|
strongSelf.replyBackgroundContent = backgroundContent
|
||||||
let replyBackgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper))
|
strongSelf.contextSourceNode.contentNode.insertSubnode(backgroundContent, at: 0)
|
||||||
strongSelf.replyBackgroundNode = replyBackgroundNode
|
|
||||||
strongSelf.contextSourceNode.contentNode.addSubnode(replyBackgroundNode)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if item.controllerInteraction.presentationContext.backgroundNode?.hasExtraBubbleBackground() == true {
|
|
||||||
if strongSelf.replyBackgroundContent == nil, let backgroundContent = item.controllerInteraction.presentationContext.backgroundNode?.makeBubbleBackground(for: .free) {
|
|
||||||
backgroundContent.clipsToBounds = true
|
|
||||||
strongSelf.replyBackgroundContent = backgroundContent
|
|
||||||
strongSelf.insertSubnode(backgroundContent, at: 0)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
strongSelf.replyBackgroundContent?.removeFromSupernode()
|
|
||||||
strongSelf.replyBackgroundContent = nil
|
|
||||||
}
|
|
||||||
} else if let replyBackgroundNode = strongSelf.replyBackgroundNode {
|
|
||||||
strongSelf.replyBackgroundNode = nil
|
|
||||||
replyBackgroundNode.removeFromSupernode()
|
|
||||||
|
|
||||||
if let replyBackgroundContent = strongSelf.replyBackgroundContent {
|
if let replyBackgroundContent = strongSelf.replyBackgroundContent {
|
||||||
replyBackgroundContent.removeFromSupernode()
|
replyBackgroundContent.removeFromSupernode()
|
||||||
strongSelf.replyBackgroundContent = nil
|
strongSelf.replyBackgroundContent = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if needsForwardBackground {
|
||||||
|
if strongSelf.forwardBackgroundContent == nil, let backgroundContent = item.controllerInteraction.presentationContext.backgroundNode?.makeBubbleBackground(for: .free) {
|
||||||
|
backgroundContent.clipsToBounds = true
|
||||||
|
strongSelf.forwardBackgroundContent = backgroundContent
|
||||||
|
strongSelf.contextSourceNode.contentNode.insertSubnode(backgroundContent, at: 0)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let forwardBackgroundContent = strongSelf.forwardBackgroundContent {
|
||||||
|
forwardBackgroundContent.removeFromSupernode()
|
||||||
|
strongSelf.forwardBackgroundContent = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var headersOffset: CGFloat = 0.0
|
var headersOffset: CGFloat = 0.0
|
||||||
if let (threadInfoSize, threadInfoApply) = threadInfoApply {
|
if let (threadInfoSize, threadInfoApply) = threadInfoApply {
|
||||||
let threadInfoNode = threadInfoApply(synchronousLoads)
|
let threadInfoNode = threadInfoApply(synchronousLoads)
|
||||||
@ -1446,16 +1495,24 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
messageInfoSize = CGSize(width: max(messageInfoSize.width, replyInfoSize.width), height: 0.0)
|
messageInfoSize = CGSize(width: max(messageInfoSize.width, replyInfoSize.width), height: 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var forwardAreaFrame: CGRect?
|
||||||
if let (viaBotLayout, viaBotApply) = viaBotApply, forwardInfoSizeApply == nil {
|
if let (viaBotLayout, viaBotApply) = viaBotApply, forwardInfoSizeApply == nil {
|
||||||
let viaBotNode = viaBotApply()
|
let viaBotNode = viaBotApply()
|
||||||
if strongSelf.viaBotNode == nil {
|
if strongSelf.viaBotNode == nil {
|
||||||
strongSelf.viaBotNode = viaBotNode
|
strongSelf.viaBotNode = viaBotNode
|
||||||
strongSelf.contextSourceNode.contentNode.addSubnode(viaBotNode)
|
strongSelf.contextSourceNode.contentNode.addSubnode(viaBotNode)
|
||||||
}
|
}
|
||||||
let viaBotFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 11.0) : (params.width - params.rightInset - messageInfoSize.width - layoutConstants.bubble.edgeInset - 9.0)), y: headersOffset + 8.0), size: viaBotLayout.size)
|
let viaBotFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 11.0 + 5.0) : (params.width - params.rightInset - messageInfoSize.width - layoutConstants.bubble.edgeInset - 9.0 - 5.0)), y: headersOffset + 8.0), size: viaBotLayout.size)
|
||||||
|
|
||||||
viaBotNode.frame = viaBotFrame
|
viaBotNode.frame = viaBotFrame
|
||||||
|
|
||||||
messageInfoSize = CGSize(width: messageInfoSize.width, height: viaBotLayout.size.height)
|
messageInfoSize = CGSize(width: messageInfoSize.width, height: viaBotLayout.size.height)
|
||||||
|
|
||||||
|
if let forwardAreaFrameValue = forwardAreaFrame {
|
||||||
|
forwardAreaFrame = forwardAreaFrameValue.union(viaBotFrame)
|
||||||
|
} else {
|
||||||
|
forwardAreaFrame = viaBotFrame
|
||||||
|
}
|
||||||
} else if let viaBotNode = strongSelf.viaBotNode {
|
} else if let viaBotNode = strongSelf.viaBotNode {
|
||||||
viaBotNode.removeFromSupernode()
|
viaBotNode.removeFromSupernode()
|
||||||
strongSelf.viaBotNode = nil
|
strongSelf.viaBotNode = nil
|
||||||
@ -1471,10 +1528,16 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
forwardInfoNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
forwardInfoNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let forwardInfoFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 12.0) : (params.width - params.rightInset - messageInfoSize.width - layoutConstants.bubble.edgeInset - 8.0)), y: headersOffset + 8.0 + messageInfoSize.height), size: forwardInfoSize)
|
let forwardInfoFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 12.0 + 5.0) : (params.width - params.rightInset - messageInfoSize.width - layoutConstants.bubble.edgeInset - 8.0 - 5.0)), y: headersOffset + 8.0 + messageInfoSize.height), size: forwardInfoSize)
|
||||||
forwardInfoNode.frame = forwardInfoFrame
|
forwardInfoNode.frame = forwardInfoFrame
|
||||||
|
|
||||||
messageInfoSize = CGSize(width: messageInfoSize.width, height: messageInfoSize.height + forwardInfoSize.height - 1.0)
|
messageInfoSize = CGSize(width: messageInfoSize.width, height: messageInfoSize.height + forwardInfoSize.height + 8.0)
|
||||||
|
|
||||||
|
if let forwardAreaFrameValue = forwardAreaFrame {
|
||||||
|
forwardAreaFrame = forwardAreaFrameValue.union(forwardInfoFrame)
|
||||||
|
} else {
|
||||||
|
forwardAreaFrame = forwardInfoFrame
|
||||||
|
}
|
||||||
} else if let forwardInfoNode = strongSelf.forwardInfoNode {
|
} else if let forwardInfoNode = strongSelf.forwardInfoNode {
|
||||||
if animation.isAnimated {
|
if animation.isAnimated {
|
||||||
if let forwardInfoNode = strongSelf.forwardInfoNode {
|
if let forwardInfoNode = strongSelf.forwardInfoNode {
|
||||||
@ -1489,9 +1552,18 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var forwardBackgroundFrame: CGRect?
|
||||||
|
if let forwardAreaFrame {
|
||||||
|
forwardBackgroundFrame = forwardAreaFrame.insetBy(dx: -6.0, dy: -3.0)
|
||||||
|
}
|
||||||
|
|
||||||
var replyBackgroundFrame: CGRect?
|
var replyBackgroundFrame: CGRect?
|
||||||
if let (replyInfoSize, replyInfoApply) = replyInfoApply {
|
if let (replyInfoSize, replyInfoApply) = replyInfoApply {
|
||||||
let replyInfoFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 11.0) : (params.width - params.rightInset - messageInfoSize.width - layoutConstants.bubble.edgeInset - 9.0)), y: headersOffset + 8.0 + messageInfoSize.height), size: replyInfoSize)
|
if headersOffset != 0.0 {
|
||||||
|
headersOffset += 6.0
|
||||||
|
}
|
||||||
|
|
||||||
|
let replyInfoFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 11.0) : (params.width - params.rightInset - replyInfoSize.width - layoutConstants.bubble.edgeInset - 9.0)), y: headersOffset + 8.0 + messageInfoSize.height), size: replyInfoSize)
|
||||||
replyBackgroundFrame = replyInfoFrame
|
replyBackgroundFrame = replyInfoFrame
|
||||||
|
|
||||||
let replyInfoNode = replyInfoApply(replyInfoFrame.size, synchronousLoads, animation)
|
let replyInfoNode = replyInfoApply(replyInfoFrame.size, synchronousLoads, animation)
|
||||||
@ -1507,24 +1579,25 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
strongSelf.replyInfoNode = nil
|
strongSelf.replyInfoNode = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if let replyBackgroundNode = strongSelf.replyBackgroundNode, let replyBackgroundFrame {
|
if let backgroundContent = strongSelf.replyBackgroundContent, let replyBackgroundFrame {
|
||||||
replyBackgroundNode.frame = replyBackgroundFrame
|
backgroundContent.cornerRadius = 4.0
|
||||||
|
backgroundContent.frame = replyBackgroundFrame
|
||||||
let cornerRadius = 4.0
|
if let (rect, containerSize) = strongSelf.absoluteRect {
|
||||||
replyBackgroundNode.update(size: replyBackgroundNode.bounds.size, cornerRadius: cornerRadius, transition: .immediate)
|
var backgroundFrame = backgroundContent.frame
|
||||||
|
backgroundFrame.origin.x += rect.minX
|
||||||
if let backgroundContent = strongSelf.replyBackgroundContent {
|
backgroundFrame.origin.y += rect.minY
|
||||||
replyBackgroundNode.isHidden = true
|
backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
|
||||||
backgroundContent.cornerRadius = cornerRadius
|
}
|
||||||
backgroundContent.frame = replyBackgroundNode.frame
|
}
|
||||||
if let (rect, containerSize) = strongSelf.absoluteRect {
|
|
||||||
var backgroundFrame = backgroundContent.frame
|
if let backgroundContent = strongSelf.forwardBackgroundContent, let forwardBackgroundFrame {
|
||||||
backgroundFrame.origin.x += rect.minX
|
backgroundContent.cornerRadius = 4.0
|
||||||
backgroundFrame.origin.y += rect.minY
|
backgroundContent.frame = forwardBackgroundFrame
|
||||||
backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
|
if let (rect, containerSize) = strongSelf.absoluteRect {
|
||||||
}
|
var backgroundFrame = backgroundContent.frame
|
||||||
} else {
|
backgroundFrame.origin.x += rect.minX
|
||||||
replyBackgroundNode.isHidden = false
|
backgroundFrame.origin.y += rect.minY
|
||||||
|
backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1533,7 +1606,8 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
strongSelf.replyInfoNode?.alpha = panelsAlpha
|
strongSelf.replyInfoNode?.alpha = panelsAlpha
|
||||||
strongSelf.viaBotNode?.alpha = panelsAlpha
|
strongSelf.viaBotNode?.alpha = panelsAlpha
|
||||||
strongSelf.forwardInfoNode?.alpha = panelsAlpha
|
strongSelf.forwardInfoNode?.alpha = panelsAlpha
|
||||||
strongSelf.replyBackgroundNode?.alpha = panelsAlpha
|
strongSelf.replyBackgroundContent?.alpha = panelsAlpha
|
||||||
|
strongSelf.forwardBackgroundContent?.alpha = panelsAlpha
|
||||||
|
|
||||||
if isFailed {
|
if isFailed {
|
||||||
let deliveryFailedNode: ChatMessageDeliveryFailedNode
|
let deliveryFailedNode: ChatMessageDeliveryFailedNode
|
||||||
@ -1969,7 +2043,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
for attribute in item.message.attributes {
|
for attribute in item.message.attributes {
|
||||||
if let attribute = attribute as? ReplyMessageAttribute {
|
if let attribute = attribute as? ReplyMessageAttribute {
|
||||||
return .optionalAction({
|
return .optionalAction({
|
||||||
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.quote?.text))
|
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.isQuote ? attribute.quote?.text : nil))
|
||||||
})
|
})
|
||||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||||
return .optionalAction({
|
return .optionalAction({
|
||||||
@ -2445,8 +2519,11 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
if let forwardInfoNode = self.forwardInfoNode {
|
if let forwardInfoNode = self.forwardInfoNode {
|
||||||
transition.updateAlpha(node: forwardInfoNode, alpha: panelsAlpha)
|
transition.updateAlpha(node: forwardInfoNode, alpha: panelsAlpha)
|
||||||
}
|
}
|
||||||
if let replyBackgroundNode = self.replyBackgroundNode {
|
if let replyBackgroundContent = self.replyBackgroundContent {
|
||||||
transition.updateAlpha(node: replyBackgroundNode, alpha: panelsAlpha)
|
transition.updateAlpha(node: replyBackgroundContent, alpha: panelsAlpha)
|
||||||
|
}
|
||||||
|
if let forwardBackgroundContent = self.forwardBackgroundContent {
|
||||||
|
transition.updateAlpha(node: forwardBackgroundContent, alpha: panelsAlpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let selectionState = item.controllerInteraction.selectionState {
|
if let selectionState = item.controllerInteraction.selectionState {
|
||||||
@ -2814,9 +2891,13 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
relativeTargetRect: sourceReplyPanel.relativeTargetRect
|
relativeTargetRect: sourceReplyPanel.relativeTargetRect
|
||||||
)
|
)
|
||||||
let offset = replyInfoNode.animateFromInputPanel(sourceReplyPanel: mappedPanel, localRect: localRect, transition: transition)
|
let offset = replyInfoNode.animateFromInputPanel(sourceReplyPanel: mappedPanel, localRect: localRect, transition: transition)
|
||||||
if let replyBackgroundNode = self.replyBackgroundNode {
|
if let replyBackgroundContent = self.replyBackgroundContent {
|
||||||
transition.animatePositionAdditive(layer: replyBackgroundNode.layer, offset: offset)
|
transition.animatePositionAdditive(layer: replyBackgroundContent.layer, offset: offset)
|
||||||
replyBackgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
|
replyBackgroundContent.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
|
||||||
|
}
|
||||||
|
if let forwardBackgroundContent = self.forwardBackgroundContent {
|
||||||
|
transition.animatePositionAdditive(layer: forwardBackgroundContent.layer, offset: offset)
|
||||||
|
forwardBackgroundContent.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -869,13 +869,13 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
if let current = self.backgroundView {
|
if let current = self.backgroundView {
|
||||||
backgroundView = current
|
backgroundView = current
|
||||||
animation.animator.updateFrame(layer: backgroundView.layer, frame: backgroundFrame, completion: nil)
|
animation.animator.updateFrame(layer: backgroundView.layer, frame: backgroundFrame, completion: nil)
|
||||||
backgroundView.update(size: backgroundFrame.size, primaryColor: mainColor, secondaryColor: secondaryColor, thirdColor: tertiaryColor, pattern: nil, animation: animation)
|
backgroundView.update(size: backgroundFrame.size, isTransparent: false, primaryColor: mainColor, secondaryColor: secondaryColor, thirdColor: tertiaryColor, pattern: nil, animation: animation)
|
||||||
} else {
|
} else {
|
||||||
backgroundView = MessageInlineBlockBackgroundView()
|
backgroundView = MessageInlineBlockBackgroundView()
|
||||||
self.backgroundView = backgroundView
|
self.backgroundView = backgroundView
|
||||||
backgroundView.frame = backgroundFrame
|
backgroundView.frame = backgroundFrame
|
||||||
self.transformContainer.view.insertSubview(backgroundView, at: 0)
|
self.transformContainer.view.insertSubview(backgroundView, at: 0)
|
||||||
backgroundView.update(size: backgroundFrame.size, primaryColor: mainColor, secondaryColor: secondaryColor, thirdColor: tertiaryColor, pattern: nil, animation: .None)
|
backgroundView.update(size: backgroundFrame.size, isTransparent: false, primaryColor: mainColor, secondaryColor: secondaryColor, thirdColor: tertiaryColor, pattern: nil, animation: .None)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let backgroundView = self.backgroundView {
|
if let backgroundView = self.backgroundView {
|
||||||
|
@ -1615,7 +1615,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
var inlineBotNameString: String?
|
var inlineBotNameString: String?
|
||||||
var replyMessage: Message?
|
var replyMessage: Message?
|
||||||
var replyForward: QuotedReplyMessageAttribute?
|
var replyForward: QuotedReplyMessageAttribute?
|
||||||
var replyQuote: EngineMessageReplyQuote?
|
var replyQuote: (quote: EngineMessageReplyQuote, isQuote: Bool)?
|
||||||
var replyStory: StoryId?
|
var replyStory: StoryId?
|
||||||
var replyMarkup: ReplyMarkupMessageAttribute?
|
var replyMarkup: ReplyMarkupMessageAttribute?
|
||||||
var authorNameColor: UIColor?
|
var authorNameColor: UIColor?
|
||||||
@ -1632,7 +1632,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
} else {
|
} else {
|
||||||
replyMessage = firstMessage.associatedMessages[attribute.messageId]
|
replyMessage = firstMessage.associatedMessages[attribute.messageId]
|
||||||
}
|
}
|
||||||
replyQuote = attribute.quote
|
replyQuote = attribute.quote.flatMap { ($0, attribute.isQuote) }
|
||||||
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
||||||
replyForward = attribute
|
replyForward = attribute
|
||||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||||
@ -4047,7 +4047,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
if let replyInfoNode = self.replyInfoNode {
|
if let replyInfoNode = self.replyInfoNode {
|
||||||
progress = replyInfoNode.makeProgress()
|
progress = replyInfoNode.makeProgress()
|
||||||
}
|
}
|
||||||
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.quote?.text, progress: progress))
|
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.isQuote ? attribute.quote?.text : nil, progress: progress))
|
||||||
}, contextMenuOnLongPress: true))
|
}, contextMenuOnLongPress: true))
|
||||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||||
return .action(InternalBubbleTapAction.Action({
|
return .action(InternalBubbleTapAction.Action({
|
||||||
|
@ -456,7 +456,7 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureReco
|
|||||||
|
|
||||||
var replyMessage: Message?
|
var replyMessage: Message?
|
||||||
var replyForward: QuotedReplyMessageAttribute?
|
var replyForward: QuotedReplyMessageAttribute?
|
||||||
var replyQuote: EngineMessageReplyQuote?
|
var replyQuote: (quote: EngineMessageReplyQuote, isQuote: Bool)?
|
||||||
var replyStory: StoryId?
|
var replyStory: StoryId?
|
||||||
for attribute in item.message.attributes {
|
for attribute in item.message.attributes {
|
||||||
if let attribute = attribute as? InlineBotMessageAttribute {
|
if let attribute = attribute as? InlineBotMessageAttribute {
|
||||||
@ -499,7 +499,7 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureReco
|
|||||||
} else {
|
} else {
|
||||||
replyMessage = item.message.associatedMessages[replyAttribute.messageId]
|
replyMessage = item.message.associatedMessages[replyAttribute.messageId]
|
||||||
}
|
}
|
||||||
replyQuote = replyAttribute.quote
|
replyQuote = replyAttribute.quote.flatMap { ($0, replyAttribute.isQuote) }
|
||||||
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
||||||
replyForward = attribute
|
replyForward = attribute
|
||||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||||
@ -963,7 +963,7 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureReco
|
|||||||
for attribute in item.message.attributes {
|
for attribute in item.message.attributes {
|
||||||
if let attribute = attribute as? ReplyMessageAttribute {
|
if let attribute = attribute as? ReplyMessageAttribute {
|
||||||
return .optionalAction({
|
return .optionalAction({
|
||||||
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.quote?.text))
|
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.isQuote ? attribute.quote?.text : nil))
|
||||||
})
|
})
|
||||||
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
||||||
return .action(InternalBubbleTapAction.Action {
|
return .action(InternalBubbleTapAction.Action {
|
||||||
|
@ -331,7 +331,7 @@ public class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
|||||||
if !ignoreHeaders {
|
if !ignoreHeaders {
|
||||||
var replyMessage: Message?
|
var replyMessage: Message?
|
||||||
var replyForward: QuotedReplyMessageAttribute?
|
var replyForward: QuotedReplyMessageAttribute?
|
||||||
var replyQuote: EngineMessageReplyQuote?
|
var replyQuote: (quote: EngineMessageReplyQuote, isQuote: Bool)?
|
||||||
var replyStory: StoryId?
|
var replyStory: StoryId?
|
||||||
|
|
||||||
for attribute in item.message.attributes {
|
for attribute in item.message.attributes {
|
||||||
@ -361,7 +361,7 @@ public class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
|||||||
} else {
|
} else {
|
||||||
replyMessage = item.message.associatedMessages[replyAttribute.messageId]
|
replyMessage = item.message.associatedMessages[replyAttribute.messageId]
|
||||||
}
|
}
|
||||||
replyQuote = replyAttribute.quote
|
replyQuote = replyAttribute.quote.flatMap { ($0, replyAttribute.isQuote) }
|
||||||
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
||||||
replyForward = attribute
|
replyForward = attribute
|
||||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||||
@ -1291,7 +1291,7 @@ public class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
|||||||
if let item = self.item {
|
if let item = self.item {
|
||||||
for attribute in item.message.attributes {
|
for attribute in item.message.attributes {
|
||||||
if let attribute = attribute as? ReplyMessageAttribute {
|
if let attribute = attribute as? ReplyMessageAttribute {
|
||||||
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.quote?.text))
|
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.isQuote ? attribute.quote?.text : nil))
|
||||||
return
|
return
|
||||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||||
item.controllerInteraction.navigateToStory(item.message, attribute.storyId)
|
item.controllerInteraction.navigateToStory(item.message, attribute.storyId)
|
||||||
|
@ -80,7 +80,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
|||||||
public let type: ChatMessageReplyInfoType
|
public let type: ChatMessageReplyInfoType
|
||||||
public let message: Message?
|
public let message: Message?
|
||||||
public let replyForward: QuotedReplyMessageAttribute?
|
public let replyForward: QuotedReplyMessageAttribute?
|
||||||
public let quote: EngineMessageReplyQuote?
|
public let quote: (quote: EngineMessageReplyQuote, isQuote: Bool)?
|
||||||
public let story: StoryId?
|
public let story: StoryId?
|
||||||
public let parentMessage: Message
|
public let parentMessage: Message
|
||||||
public let constrainedSize: CGSize
|
public let constrainedSize: CGSize
|
||||||
@ -95,7 +95,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
|||||||
type: ChatMessageReplyInfoType,
|
type: ChatMessageReplyInfoType,
|
||||||
message: Message?,
|
message: Message?,
|
||||||
replyForward: QuotedReplyMessageAttribute?,
|
replyForward: QuotedReplyMessageAttribute?,
|
||||||
quote: EngineMessageReplyQuote?,
|
quote: (quote: EngineMessageReplyQuote, isQuote: Bool)?,
|
||||||
story: StoryId?,
|
story: StoryId?,
|
||||||
parentMessage: Message,
|
parentMessage: Message,
|
||||||
constrainedSize: CGSize,
|
constrainedSize: CGSize,
|
||||||
@ -410,7 +410,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
|||||||
var text: String
|
var text: String
|
||||||
var messageEntities: [MessageTextEntity]
|
var messageEntities: [MessageTextEntity]
|
||||||
|
|
||||||
if let quote = arguments.quote, !quote.text.isEmpty {
|
if let quote = arguments.quote?.quote, !quote.text.isEmpty {
|
||||||
text = quote.text
|
text = quote.text
|
||||||
messageEntities = quote.entities
|
messageEntities = quote.entities
|
||||||
} else {
|
} else {
|
||||||
@ -547,7 +547,15 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
|||||||
var adjustedConstrainedTextSize = contrainedTextSize
|
var adjustedConstrainedTextSize = contrainedTextSize
|
||||||
var textCutout: TextNodeCutout?
|
var textCutout: TextNodeCutout?
|
||||||
var textCutoutWidth: CGFloat = 0.0
|
var textCutoutWidth: CGFloat = 0.0
|
||||||
if arguments.quote != nil || arguments.replyForward?.quote != nil {
|
|
||||||
|
var isQuote = false
|
||||||
|
if let quote = arguments.quote, quote.isQuote {
|
||||||
|
isQuote = true
|
||||||
|
} else if let replyForward = arguments.replyForward, replyForward.quote != nil, replyForward.isQuote {
|
||||||
|
isQuote = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if isQuote {
|
||||||
additionalTitleWidth += 10.0
|
additionalTitleWidth += 10.0
|
||||||
maxTitleNumberOfLines = 2
|
maxTitleNumberOfLines = 2
|
||||||
maxTextNumberOfLines = 5
|
maxTextNumberOfLines = 5
|
||||||
@ -761,8 +769,13 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
|||||||
)] as? TelegramMediaFile
|
)] as? TelegramMediaFile
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
var isTransparent: Bool = false
|
||||||
|
if case .standalone = arguments.type {
|
||||||
|
isTransparent = true
|
||||||
|
}
|
||||||
node.backgroundView.update(
|
node.backgroundView.update(
|
||||||
size: backgroundFrame.size,
|
size: backgroundFrame.size,
|
||||||
|
isTransparent: isTransparent,
|
||||||
primaryColor: mainColor,
|
primaryColor: mainColor,
|
||||||
secondaryColor: secondaryColor,
|
secondaryColor: secondaryColor,
|
||||||
thirdColor: tertiaryColor,
|
thirdColor: tertiaryColor,
|
||||||
@ -770,7 +783,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
|||||||
animation: animation
|
animation: animation
|
||||||
)
|
)
|
||||||
|
|
||||||
if arguments.quote != nil || arguments.replyForward?.quote != nil {
|
if isQuote {
|
||||||
let quoteIconView: UIImageView
|
let quoteIconView: UIImageView
|
||||||
if let current = node.quoteIconView {
|
if let current = node.quoteIconView {
|
||||||
quoteIconView = current
|
quoteIconView = current
|
||||||
|
@ -56,8 +56,8 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
private var threadInfoNode: ChatMessageThreadInfoNode?
|
private var threadInfoNode: ChatMessageThreadInfoNode?
|
||||||
private var replyInfoNode: ChatMessageReplyInfoNode?
|
private var replyInfoNode: ChatMessageReplyInfoNode?
|
||||||
private var replyBackgroundContent: WallpaperBubbleBackgroundNode?
|
private var replyBackgroundContent: WallpaperBubbleBackgroundNode?
|
||||||
private var replyBackgroundNode: NavigationBackgroundNode?
|
|
||||||
private var forwardInfoNode: ChatMessageForwardInfoNode?
|
private var forwardInfoNode: ChatMessageForwardInfoNode?
|
||||||
|
private var forwardBackgroundContent: WallpaperBubbleBackgroundNode?
|
||||||
|
|
||||||
private var actionButtonsNode: ChatMessageActionButtonsNode?
|
private var actionButtonsNode: ChatMessageActionButtonsNode?
|
||||||
private var reactionButtonsNode: ChatMessageReactionButtonsNode?
|
private var reactionButtonsNode: ChatMessageReactionButtonsNode?
|
||||||
@ -350,6 +350,14 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
|
|
||||||
replyBackgroundContent.update(rect: rect, within: containerSize, transition: .immediate)
|
replyBackgroundContent.update(rect: rect, within: containerSize, transition: .immediate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let forwardBackgroundContent = self.forwardBackgroundContent {
|
||||||
|
var forwardBackgroundContentFrame = forwardBackgroundContent.frame
|
||||||
|
forwardBackgroundContentFrame.origin.x += rect.minX
|
||||||
|
forwardBackgroundContentFrame.origin.y += rect.minY
|
||||||
|
|
||||||
|
forwardBackgroundContent.update(rect: rect, within: containerSize, transition: .immediate)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,7 +659,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
|
|
||||||
var replyMessage: Message?
|
var replyMessage: Message?
|
||||||
var replyForward: QuotedReplyMessageAttribute?
|
var replyForward: QuotedReplyMessageAttribute?
|
||||||
var replyQuote: EngineMessageReplyQuote?
|
var replyQuote: (quote: EngineMessageReplyQuote, isQuote: Bool)?
|
||||||
var replyStory: StoryId?
|
var replyStory: StoryId?
|
||||||
for attribute in item.message.attributes {
|
for attribute in item.message.attributes {
|
||||||
if let attribute = attribute as? InlineBotMessageAttribute {
|
if let attribute = attribute as? InlineBotMessageAttribute {
|
||||||
@ -679,7 +687,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
} else {
|
} else {
|
||||||
replyMessage = item.message.associatedMessages[replyAttribute.messageId]
|
replyMessage = item.message.associatedMessages[replyAttribute.messageId]
|
||||||
}
|
}
|
||||||
replyQuote = replyAttribute.quote
|
replyQuote = replyAttribute.quote.flatMap { ($0, replyAttribute.isQuote) }
|
||||||
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
||||||
replyForward = attribute
|
replyForward = attribute
|
||||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||||
@ -784,10 +792,15 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var needsReplyBackground = false
|
var needsReplyBackground = false
|
||||||
if replyInfoApply != nil || viaBotApply != nil || forwardInfoSizeApply != nil {
|
if replyInfoApply != nil {
|
||||||
needsReplyBackground = true
|
needsReplyBackground = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var needsForwardBackground = false
|
||||||
|
if viaBotApply != nil || forwardInfoSizeApply != nil {
|
||||||
|
needsForwardBackground = true
|
||||||
|
}
|
||||||
|
|
||||||
var maxContentWidth = imageSize.width
|
var maxContentWidth = imageSize.width
|
||||||
var actionButtonsFinalize: ((CGFloat) -> (CGSize, (_ animation: ListViewItemUpdateAnimation) -> ChatMessageActionButtonsNode))?
|
var actionButtonsFinalize: ((CGFloat) -> (CGSize, (_ animation: ListViewItemUpdateAnimation) -> ChatMessageActionButtonsNode))?
|
||||||
if let replyMarkup = replyMarkup {
|
if let replyMarkup = replyMarkup {
|
||||||
@ -971,34 +984,31 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if needsReplyBackground {
|
if needsReplyBackground {
|
||||||
if let replyBackgroundNode = strongSelf.replyBackgroundNode {
|
if strongSelf.replyBackgroundContent == nil, let backgroundContent = item.controllerInteraction.presentationContext.backgroundNode?.makeBubbleBackground(for: .free) {
|
||||||
replyBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate)
|
backgroundContent.clipsToBounds = true
|
||||||
} else {
|
strongSelf.replyBackgroundContent = backgroundContent
|
||||||
let replyBackgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper))
|
strongSelf.contextSourceNode.contentNode.insertSubnode(backgroundContent, at: 0)
|
||||||
strongSelf.replyBackgroundNode = replyBackgroundNode
|
|
||||||
strongSelf.contextSourceNode.contentNode.addSubnode(replyBackgroundNode)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if item.controllerInteraction.presentationContext.backgroundNode?.hasExtraBubbleBackground() == true {
|
|
||||||
if strongSelf.replyBackgroundContent == nil, let backgroundContent = item.controllerInteraction.presentationContext.backgroundNode?.makeBubbleBackground(for: .free) {
|
|
||||||
backgroundContent.clipsToBounds = true
|
|
||||||
strongSelf.replyBackgroundContent = backgroundContent
|
|
||||||
strongSelf.insertSubnode(backgroundContent, at: 0)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
strongSelf.replyBackgroundContent?.removeFromSupernode()
|
|
||||||
strongSelf.replyBackgroundContent = nil
|
|
||||||
}
|
|
||||||
} else if let replyBackgroundNode = strongSelf.replyBackgroundNode {
|
|
||||||
replyBackgroundNode.removeFromSupernode()
|
|
||||||
strongSelf.replyBackgroundNode = nil
|
|
||||||
|
|
||||||
if let replyBackgroundContent = strongSelf.replyBackgroundContent {
|
if let replyBackgroundContent = strongSelf.replyBackgroundContent {
|
||||||
replyBackgroundContent.removeFromSupernode()
|
replyBackgroundContent.removeFromSupernode()
|
||||||
strongSelf.replyBackgroundContent = nil
|
strongSelf.replyBackgroundContent = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if needsForwardBackground {
|
||||||
|
if strongSelf.forwardBackgroundContent == nil, let backgroundContent = item.controllerInteraction.presentationContext.backgroundNode?.makeBubbleBackground(for: .free) {
|
||||||
|
backgroundContent.clipsToBounds = true
|
||||||
|
strongSelf.forwardBackgroundContent = backgroundContent
|
||||||
|
strongSelf.contextSourceNode.contentNode.insertSubnode(backgroundContent, at: 0)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let forwardBackgroundContent = strongSelf.forwardBackgroundContent {
|
||||||
|
forwardBackgroundContent.removeFromSupernode()
|
||||||
|
strongSelf.forwardBackgroundContent = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var headersOffset: CGFloat = 0.0
|
var headersOffset: CGFloat = 0.0
|
||||||
if let (threadInfoSize, threadInfoApply) = threadInfoApply {
|
if let (threadInfoSize, threadInfoApply) = threadInfoApply {
|
||||||
let threadInfoNode = threadInfoApply(synchronousLoads)
|
let threadInfoNode = threadInfoApply(synchronousLoads)
|
||||||
@ -1026,16 +1036,24 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
messageInfoSize = CGSize(width: max(messageInfoSize.width, replyInfoSize.width), height: 0.0)
|
messageInfoSize = CGSize(width: max(messageInfoSize.width, replyInfoSize.width), height: 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var forwardAreaFrame: CGRect?
|
||||||
if let (viaBotLayout, viaBotApply) = viaBotApply, forwardInfoSizeApply == nil {
|
if let (viaBotLayout, viaBotApply) = viaBotApply, forwardInfoSizeApply == nil {
|
||||||
let viaBotNode = viaBotApply()
|
let viaBotNode = viaBotApply()
|
||||||
if strongSelf.viaBotNode == nil {
|
if strongSelf.viaBotNode == nil {
|
||||||
strongSelf.viaBotNode = viaBotNode
|
strongSelf.viaBotNode = viaBotNode
|
||||||
strongSelf.contextSourceNode.contentNode.addSubnode(viaBotNode)
|
strongSelf.contextSourceNode.contentNode.addSubnode(viaBotNode)
|
||||||
}
|
}
|
||||||
let viaBotFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 11.0) : (params.width - params.rightInset - messageInfoSize.width - layoutConstants.bubble.edgeInset - 9.0)), y: headersOffset + 8.0), size: viaBotLayout.size)
|
let viaBotFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 11.0 + 5.0) : (params.width - params.rightInset - messageInfoSize.width - layoutConstants.bubble.edgeInset - 9.0 - 5.0)), y: headersOffset + 8.0), size: viaBotLayout.size)
|
||||||
|
|
||||||
viaBotNode.frame = viaBotFrame
|
viaBotNode.frame = viaBotFrame
|
||||||
|
|
||||||
messageInfoSize = CGSize(width: messageInfoSize.width, height: viaBotLayout.size.height)
|
messageInfoSize = CGSize(width: messageInfoSize.width, height: viaBotLayout.size.height)
|
||||||
|
|
||||||
|
if let forwardAreaFrameValue = forwardAreaFrame {
|
||||||
|
forwardAreaFrame = forwardAreaFrameValue.union(viaBotFrame)
|
||||||
|
} else {
|
||||||
|
forwardAreaFrame = viaBotFrame
|
||||||
|
}
|
||||||
} else if let viaBotNode = strongSelf.viaBotNode {
|
} else if let viaBotNode = strongSelf.viaBotNode {
|
||||||
viaBotNode.removeFromSupernode()
|
viaBotNode.removeFromSupernode()
|
||||||
strongSelf.viaBotNode = nil
|
strongSelf.viaBotNode = nil
|
||||||
@ -1051,10 +1069,16 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
forwardInfoNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
forwardInfoNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let forwardInfoFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 12.0) : (params.width - params.rightInset - messageInfoSize.width - layoutConstants.bubble.edgeInset - 8.0)), y: headersOffset + 8.0 + messageInfoSize.height), size: forwardInfoSize)
|
let forwardInfoFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 12.0 + 5.0) : (params.width - params.rightInset - messageInfoSize.width - layoutConstants.bubble.edgeInset - 8.0 - 5.0)), y: headersOffset + 8.0 + messageInfoSize.height), size: forwardInfoSize)
|
||||||
forwardInfoNode.frame = forwardInfoFrame
|
forwardInfoNode.frame = forwardInfoFrame
|
||||||
|
|
||||||
messageInfoSize = CGSize(width: messageInfoSize.width, height: messageInfoSize.height + forwardInfoSize.height - 1.0)
|
messageInfoSize = CGSize(width: messageInfoSize.width, height: messageInfoSize.height + forwardInfoSize.height + 8.0)
|
||||||
|
|
||||||
|
if let forwardAreaFrameValue = forwardAreaFrame {
|
||||||
|
forwardAreaFrame = forwardAreaFrameValue.union(forwardInfoFrame)
|
||||||
|
} else {
|
||||||
|
forwardAreaFrame = forwardInfoFrame
|
||||||
|
}
|
||||||
} else if let forwardInfoNode = strongSelf.forwardInfoNode {
|
} else if let forwardInfoNode = strongSelf.forwardInfoNode {
|
||||||
if animation.isAnimated {
|
if animation.isAnimated {
|
||||||
if let forwardInfoNode = strongSelf.forwardInfoNode {
|
if let forwardInfoNode = strongSelf.forwardInfoNode {
|
||||||
@ -1069,9 +1093,18 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var forwardBackgroundFrame: CGRect?
|
||||||
|
if let forwardAreaFrame {
|
||||||
|
forwardBackgroundFrame = forwardAreaFrame.insetBy(dx: -6.0, dy: -3.0)
|
||||||
|
}
|
||||||
|
|
||||||
var replyBackgroundFrame: CGRect?
|
var replyBackgroundFrame: CGRect?
|
||||||
if let (replyInfoSize, replyInfoApply) = replyInfoApply {
|
if let (replyInfoSize, replyInfoApply) = replyInfoApply {
|
||||||
let replyInfoFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 11.0) : (params.width - params.rightInset - messageInfoSize.width - layoutConstants.bubble.edgeInset - 9.0)), y: headersOffset + 8.0 + messageInfoSize.height), size: replyInfoSize)
|
if headersOffset != 0.0 {
|
||||||
|
headersOffset += 6.0
|
||||||
|
}
|
||||||
|
|
||||||
|
let replyInfoFrame = CGRect(origin: CGPoint(x: (!incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + 11.0) : (params.width - params.rightInset - replyInfoSize.width - layoutConstants.bubble.edgeInset - 9.0)), y: headersOffset + 8.0 + messageInfoSize.height), size: replyInfoSize)
|
||||||
replyBackgroundFrame = replyInfoFrame
|
replyBackgroundFrame = replyInfoFrame
|
||||||
|
|
||||||
let replyInfoNode = replyInfoApply(replyInfoFrame.size, synchronousLoads, animation)
|
let replyInfoNode = replyInfoApply(replyInfoFrame.size, synchronousLoads, animation)
|
||||||
@ -1087,24 +1120,25 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
strongSelf.replyInfoNode = nil
|
strongSelf.replyInfoNode = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if let replyBackgroundNode = strongSelf.replyBackgroundNode, let replyBackgroundFrame {
|
if let backgroundContent = strongSelf.replyBackgroundContent, let replyBackgroundFrame {
|
||||||
replyBackgroundNode.frame = replyBackgroundFrame
|
backgroundContent.cornerRadius = 4.0
|
||||||
|
backgroundContent.frame = replyBackgroundFrame
|
||||||
let cornerRadius = 4.0
|
if let (rect, containerSize) = strongSelf.absoluteRect {
|
||||||
replyBackgroundNode.update(size: replyBackgroundNode.bounds.size, cornerRadius: cornerRadius, transition: .immediate)
|
var backgroundFrame = backgroundContent.frame
|
||||||
|
backgroundFrame.origin.x += rect.minX
|
||||||
if let backgroundContent = strongSelf.replyBackgroundContent {
|
backgroundFrame.origin.y += rect.minY
|
||||||
replyBackgroundNode.isHidden = true
|
backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
|
||||||
backgroundContent.cornerRadius = cornerRadius
|
}
|
||||||
backgroundContent.frame = replyBackgroundNode.frame
|
}
|
||||||
if let (rect, containerSize) = strongSelf.absoluteRect {
|
|
||||||
var backgroundFrame = backgroundContent.frame
|
if let backgroundContent = strongSelf.forwardBackgroundContent, let forwardBackgroundFrame {
|
||||||
backgroundFrame.origin.x += rect.minX
|
backgroundContent.cornerRadius = 4.0
|
||||||
backgroundFrame.origin.y += rect.minY
|
backgroundContent.frame = forwardBackgroundFrame
|
||||||
backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
|
if let (rect, containerSize) = strongSelf.absoluteRect {
|
||||||
}
|
var backgroundFrame = backgroundContent.frame
|
||||||
} else {
|
backgroundFrame.origin.x += rect.minX
|
||||||
replyBackgroundNode.isHidden = false
|
backgroundFrame.origin.y += rect.minY
|
||||||
|
backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1113,7 +1147,8 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
strongSelf.replyInfoNode?.alpha = panelsAlpha
|
strongSelf.replyInfoNode?.alpha = panelsAlpha
|
||||||
strongSelf.viaBotNode?.alpha = panelsAlpha
|
strongSelf.viaBotNode?.alpha = panelsAlpha
|
||||||
strongSelf.forwardInfoNode?.alpha = panelsAlpha
|
strongSelf.forwardInfoNode?.alpha = panelsAlpha
|
||||||
strongSelf.replyBackgroundNode?.alpha = panelsAlpha
|
strongSelf.replyBackgroundContent?.alpha = panelsAlpha
|
||||||
|
strongSelf.forwardBackgroundContent?.alpha = panelsAlpha
|
||||||
|
|
||||||
if isFailed {
|
if isFailed {
|
||||||
let deliveryFailedNode: ChatMessageDeliveryFailedNode
|
let deliveryFailedNode: ChatMessageDeliveryFailedNode
|
||||||
@ -1336,7 +1371,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
for attribute in item.message.attributes {
|
for attribute in item.message.attributes {
|
||||||
if let attribute = attribute as? ReplyMessageAttribute {
|
if let attribute = attribute as? ReplyMessageAttribute {
|
||||||
return .optionalAction({
|
return .optionalAction({
|
||||||
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.quote?.text))
|
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.isQuote ? attribute.quote?.text : nil))
|
||||||
})
|
})
|
||||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||||
return .optionalAction({
|
return .optionalAction({
|
||||||
@ -1591,8 +1626,11 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
if let forwardInfoNode = self.forwardInfoNode {
|
if let forwardInfoNode = self.forwardInfoNode {
|
||||||
transition.updateAlpha(node: forwardInfoNode, alpha: panelsAlpha)
|
transition.updateAlpha(node: forwardInfoNode, alpha: panelsAlpha)
|
||||||
}
|
}
|
||||||
if let replyBackgroundNode = self.replyBackgroundNode {
|
if let replyBackgroundContent = self.replyBackgroundContent {
|
||||||
transition.updateAlpha(node: replyBackgroundNode, alpha: panelsAlpha)
|
transition.updateAlpha(node: replyBackgroundContent, alpha: panelsAlpha)
|
||||||
|
}
|
||||||
|
if let forwardBackgroundContent = self.forwardBackgroundContent {
|
||||||
|
transition.updateAlpha(node: forwardBackgroundContent, alpha: panelsAlpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let selectionState = item.controllerInteraction.selectionState {
|
if let selectionState = item.controllerInteraction.selectionState {
|
||||||
@ -1635,10 +1673,10 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
let alpha: CGFloat = 0.0
|
let alpha: CGFloat = 0.0
|
||||||
let previousAlpha = replyInfoNode.alpha
|
let previousAlpha = replyInfoNode.alpha
|
||||||
replyInfoNode.alpha = alpha
|
replyInfoNode.alpha = alpha
|
||||||
self.replyBackgroundNode?.alpha = alpha
|
self.replyBackgroundContent?.alpha = alpha
|
||||||
if animated {
|
if animated {
|
||||||
replyInfoNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.3)
|
replyInfoNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.3)
|
||||||
self.replyBackgroundNode?.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.3)
|
self.replyBackgroundContent?.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1664,10 +1702,10 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
let alpha: CGFloat = 1.0
|
let alpha: CGFloat = 1.0
|
||||||
let previousAlpha = replyInfoNode.alpha
|
let previousAlpha = replyInfoNode.alpha
|
||||||
replyInfoNode.alpha = alpha
|
replyInfoNode.alpha = alpha
|
||||||
self.replyBackgroundNode?.alpha = alpha
|
self.replyBackgroundContent?.alpha = alpha
|
||||||
if animated {
|
if animated {
|
||||||
replyInfoNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.3)
|
replyInfoNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.3)
|
||||||
self.replyBackgroundNode?.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.3)
|
self.replyBackgroundContent?.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1957,9 +1995,13 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
)
|
)
|
||||||
|
|
||||||
let offset = replyInfoNode.animateFromInputPanel(sourceReplyPanel: mappedPanel, localRect: localRect, transition: transition)
|
let offset = replyInfoNode.animateFromInputPanel(sourceReplyPanel: mappedPanel, localRect: localRect, transition: transition)
|
||||||
if let replyBackgroundNode = self.replyBackgroundNode {
|
if let replyBackgroundContent = self.replyBackgroundContent {
|
||||||
transition.animatePositionAdditive(layer: replyBackgroundNode.layer, offset: offset)
|
transition.animatePositionAdditive(layer: replyBackgroundContent.layer, offset: offset)
|
||||||
replyBackgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
|
replyBackgroundContent.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
|
||||||
|
}
|
||||||
|
if let forwardBackgroundContent = self.forwardBackgroundContent {
|
||||||
|
transition.animatePositionAdditive(layer: forwardBackgroundContent.layer, offset: offset)
|
||||||
|
forwardBackgroundContent.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ private func addRoundedRectPath(context: CGContext, rect: CGRect, radius: CGFloa
|
|||||||
context.restoreGState()
|
context.restoreGState()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func generateBackgroundTemplateImage(addStripe: Bool) -> UIImage {
|
private func generateBackgroundTemplateImage(addStripe: Bool, isTransparent: Bool) -> UIImage {
|
||||||
return generateImage(CGSize(width: radius * 2.0 + 4.0, height: radius * 2.0 + 8.0), rotatedContext: { size, context in
|
return generateImage(CGSize(width: radius * 2.0 + 4.0, height: radius * 2.0 + 8.0), rotatedContext: { size, context in
|
||||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||||
|
|
||||||
@ -36,7 +36,9 @@ private func generateBackgroundTemplateImage(addStripe: Bool) -> UIImage {
|
|||||||
context.clip()
|
context.clip()
|
||||||
|
|
||||||
context.setFillColor(UIColor.white.withMultipliedAlpha(0.1).cgColor)
|
context.setFillColor(UIColor.white.withMultipliedAlpha(0.1).cgColor)
|
||||||
context.fill(CGRect(origin: CGPoint(), size: size))
|
if !isTransparent {
|
||||||
|
context.fill(CGRect(origin: CGPoint(), size: size))
|
||||||
|
}
|
||||||
|
|
||||||
if addStripe {
|
if addStripe {
|
||||||
context.setFillColor(UIColor.white.withMultipliedAlpha(0.2).cgColor)
|
context.setFillColor(UIColor.white.withMultipliedAlpha(0.2).cgColor)
|
||||||
@ -69,11 +71,19 @@ private func generateProgressTemplateImage() -> UIImage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private let backgroundSolidTemplateImage: UIImage = {
|
private let backgroundSolidTemplateImage: UIImage = {
|
||||||
return generateBackgroundTemplateImage(addStripe: true)
|
return generateBackgroundTemplateImage(addStripe: true, isTransparent: false)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private let backgroundDashTemplateImage: UIImage = {
|
private let backgroundDashTemplateImage: UIImage = {
|
||||||
return generateBackgroundTemplateImage(addStripe: false)
|
return generateBackgroundTemplateImage(addStripe: false, isTransparent: false)
|
||||||
|
}()
|
||||||
|
|
||||||
|
private let transparentBackgroundSolidTemplateImage: UIImage = {
|
||||||
|
return generateBackgroundTemplateImage(addStripe: true, isTransparent: true)
|
||||||
|
}()
|
||||||
|
|
||||||
|
private let transparentBackgroundDashTemplateImage: UIImage = {
|
||||||
|
return generateBackgroundTemplateImage(addStripe: false, isTransparent: true)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private func generateDashBackgroundTemplateImage() -> UIImage {
|
private func generateDashBackgroundTemplateImage() -> UIImage {
|
||||||
@ -436,6 +446,7 @@ public final class MessageInlineBlockBackgroundView: UIView {
|
|||||||
|
|
||||||
private struct Params: Equatable {
|
private struct Params: Equatable {
|
||||||
var size: CGSize
|
var size: CGSize
|
||||||
|
var isTransparent: Bool
|
||||||
var primaryColor: UIColor
|
var primaryColor: UIColor
|
||||||
var secondaryColor: UIColor?
|
var secondaryColor: UIColor?
|
||||||
var thirdColor: UIColor?
|
var thirdColor: UIColor?
|
||||||
@ -444,6 +455,7 @@ public final class MessageInlineBlockBackgroundView: UIView {
|
|||||||
|
|
||||||
init(
|
init(
|
||||||
size: CGSize,
|
size: CGSize,
|
||||||
|
isTransparent: Bool,
|
||||||
primaryColor: UIColor,
|
primaryColor: UIColor,
|
||||||
secondaryColor: UIColor?,
|
secondaryColor: UIColor?,
|
||||||
thirdColor: UIColor?,
|
thirdColor: UIColor?,
|
||||||
@ -451,6 +463,7 @@ public final class MessageInlineBlockBackgroundView: UIView {
|
|||||||
displayProgress: Bool
|
displayProgress: Bool
|
||||||
) {
|
) {
|
||||||
self.size = size
|
self.size = size
|
||||||
|
self.isTransparent = isTransparent
|
||||||
self.primaryColor = primaryColor
|
self.primaryColor = primaryColor
|
||||||
self.secondaryColor = secondaryColor
|
self.secondaryColor = secondaryColor
|
||||||
self.thirdColor = thirdColor
|
self.thirdColor = thirdColor
|
||||||
@ -467,6 +480,7 @@ public final class MessageInlineBlockBackgroundView: UIView {
|
|||||||
if let params = self.params {
|
if let params = self.params {
|
||||||
self.update(
|
self.update(
|
||||||
size: params.size,
|
size: params.size,
|
||||||
|
isTransparent: params.isTransparent,
|
||||||
primaryColor: params.primaryColor,
|
primaryColor: params.primaryColor,
|
||||||
secondaryColor: params.secondaryColor,
|
secondaryColor: params.secondaryColor,
|
||||||
thirdColor: params.thirdColor,
|
thirdColor: params.thirdColor,
|
||||||
@ -577,6 +591,7 @@ public final class MessageInlineBlockBackgroundView: UIView {
|
|||||||
|
|
||||||
public func update(
|
public func update(
|
||||||
size: CGSize,
|
size: CGSize,
|
||||||
|
isTransparent: Bool,
|
||||||
primaryColor: UIColor,
|
primaryColor: UIColor,
|
||||||
secondaryColor: UIColor?,
|
secondaryColor: UIColor?,
|
||||||
thirdColor: UIColor?,
|
thirdColor: UIColor?,
|
||||||
@ -585,6 +600,7 @@ public final class MessageInlineBlockBackgroundView: UIView {
|
|||||||
) {
|
) {
|
||||||
let params = Params(
|
let params = Params(
|
||||||
size: size,
|
size: size,
|
||||||
|
isTransparent: isTransparent,
|
||||||
primaryColor: primaryColor,
|
primaryColor: primaryColor,
|
||||||
secondaryColor: secondaryColor,
|
secondaryColor: secondaryColor,
|
||||||
thirdColor: thirdColor,
|
thirdColor: thirdColor,
|
||||||
@ -602,10 +618,18 @@ public final class MessageInlineBlockBackgroundView: UIView {
|
|||||||
patternContentLayer.layerTintColor = primaryColor.cgColor
|
patternContentLayer.layerTintColor = primaryColor.cgColor
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.secondaryColor != nil {
|
if params.isTransparent {
|
||||||
self.backgroundView.image = backgroundDashTemplateImage
|
if params.secondaryColor != nil {
|
||||||
|
self.backgroundView.image = transparentBackgroundDashTemplateImage
|
||||||
|
} else {
|
||||||
|
self.backgroundView.image = transparentBackgroundSolidTemplateImage
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.backgroundView.image = backgroundSolidTemplateImage
|
if params.secondaryColor != nil {
|
||||||
|
self.backgroundView.image = backgroundDashTemplateImage
|
||||||
|
} else {
|
||||||
|
self.backgroundView.image = backgroundSolidTemplateImage
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.backgroundView.tintColor = params.primaryColor
|
self.backgroundView.tintColor = params.primaryColor
|
||||||
}
|
}
|
||||||
@ -711,7 +735,7 @@ public final class MessageInlineBlockBackgroundView: UIView {
|
|||||||
|
|
||||||
let itemSize = CGSize(width: placement.size / 3.0, height: placement.size / 3.0)
|
let itemSize = CGSize(width: placement.size / 3.0, height: placement.size / 3.0)
|
||||||
patternContentLayer.frame = CGRect(origin: CGPoint(x: size.width - placement.position.x / 3.0 - itemSize.width * 0.5, y: placement.position.y / 3.0 - itemSize.height * 0.5), size: itemSize)
|
patternContentLayer.frame = CGRect(origin: CGPoint(x: size.width - placement.position.x / 3.0 - itemSize.width * 0.5, y: placement.position.y / 3.0 - itemSize.height * 0.5), size: itemSize)
|
||||||
var alphaFraction = abs(placement.position.x) / 500.0
|
var alphaFraction = abs(placement.position.x) / min(500.0, size.width)
|
||||||
alphaFraction = min(1.0, max(0.0, alphaFraction))
|
alphaFraction = min(1.0, max(0.0, alphaFraction))
|
||||||
patternContentLayer.opacity = 0.3 * Float(1.0 - alphaFraction)
|
patternContentLayer.opacity = 0.3 * Float(1.0 - alphaFraction)
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ final class PeerNameColorChatPreviewItemNode: ListViewItemNode {
|
|||||||
media.append(TelegramMediaWebpage(webpageId: MediaId(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent(url: "", displayUrl: "", hash: 0, type: nil, websiteName: site, title: title, text: text, embedUrl: nil, embedType: nil, embedSize: nil, duration: nil, author: nil, isMediaLargeByDefault: nil, image: nil, file: nil, story: nil, attributes: [], instantPage: nil))))
|
media.append(TelegramMediaWebpage(webpageId: MediaId(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent(url: "", displayUrl: "", hash: 0, type: nil, websiteName: site, title: title, text: text, embedUrl: nil, embedType: nil, embedSize: nil, duration: nil, author: nil, isMediaLargeByDefault: nil, image: nil, file: nil, story: nil, attributes: [], instantPage: nil))))
|
||||||
}
|
}
|
||||||
|
|
||||||
let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: messageItem.outgoing ? [] : [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[authorPeerId], text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil)] : [], media: media, peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: messageItem.outgoing ? [] : [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[authorPeerId], text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false)] : [], media: media, peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
items.append(item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [message], theme: item.componentTheme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode, availableReactions: nil, isCentered: false))
|
items.append(item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [message], theme: item.componentTheme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode, availableReactions: nil, isCentered: false))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,7 +774,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
case .pinnedMessageUpdated:
|
case .pinnedMessageUpdated:
|
||||||
for attribute in message.attributes {
|
for attribute in message.attributes {
|
||||||
if let attribute = attribute as? ReplyMessageAttribute {
|
if let attribute = attribute as? ReplyMessageAttribute {
|
||||||
strongSelf.navigateToMessage(from: message.id, to: .id(attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.quote?.text)))
|
strongSelf.navigateToMessage(from: message.id, to: .id(attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.isQuote ? attribute.quote?.text : nil)))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -783,7 +783,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
case .gameScore:
|
case .gameScore:
|
||||||
for attribute in message.attributes {
|
for attribute in message.attributes {
|
||||||
if let attribute = attribute as? ReplyMessageAttribute {
|
if let attribute = attribute as? ReplyMessageAttribute {
|
||||||
strongSelf.navigateToMessage(from: message.id, to: .id(attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.quote?.text)))
|
strongSelf.navigateToMessage(from: message.id, to: .id(attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.isQuote ? attribute.quote?.text : nil)))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -17034,7 +17034,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let navigationController = strongSelf.effectiveNavigationController {
|
if let navigationController = strongSelf.effectiveNavigationController {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), subject: messageLocation.messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil) }))
|
var quote: String?
|
||||||
|
if case let .id(_, params) = messageLocation {
|
||||||
|
quote = params.quote
|
||||||
|
}
|
||||||
|
|
||||||
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), subject: messageLocation.messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: quote), timecode: nil) }))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
completion?()
|
completion?()
|
||||||
|
@ -566,7 +566,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
mappedQuote = EngineMessageReplyQuote(text: quote, entities: [], media: nil)
|
mappedQuote = EngineMessageReplyQuote(text: quote, entities: [], media: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes.append(ReplyMessageAttribute(messageId: replyMessage.id, threadMessageId: nil, quote: mappedQuote))
|
attributes.append(ReplyMessageAttribute(messageId: replyMessage.id, threadMessageId: nil, quote: mappedQuote, isQuote: mappedQuote != nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
let message = Message(
|
let message = Message(
|
||||||
|
@ -2849,8 +2849,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
|
|||||||
|
|
||||||
var hasTracking = false
|
var hasTracking = false
|
||||||
var hasTrackingView = false
|
var hasTrackingView = false
|
||||||
if textInputNode.selectedRange.length == 0 && textInputNode.selectedRange.location > 0 {
|
if textInputNode.selectedRange.length == 0, textInputNode.selectedRange.location > 0, let attributedText = textInputNode.textView.attributedText {
|
||||||
let selectedSubstring = textInputNode.textView.attributedText.attributedSubstring(from: NSRange(location: 0, length: textInputNode.selectedRange.location))
|
let selectedSubstring = attributedText.attributedSubstring(from: NSRange(location: 0, length: textInputNode.selectedRange.location))
|
||||||
if let lastCharacter = selectedSubstring.string.last, String(lastCharacter).isSingleEmoji {
|
if let lastCharacter = selectedSubstring.string.last, String(lastCharacter).isSingleEmoji {
|
||||||
let queryLength = (String(lastCharacter) as NSString).length
|
let queryLength = (String(lastCharacter) as NSString).length
|
||||||
if selectedSubstring.attribute(ChatTextInputAttributes.customEmoji, at: selectedSubstring.length - queryLength, effectiveRange: nil) == nil {
|
if selectedSubstring.attribute(ChatTextInputAttributes.customEmoji, at: selectedSubstring.length - queryLength, effectiveRange: nil) == nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user