mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
[WIP] Polls
This commit is contained in:
parent
b64d4a23fe
commit
b1a190f87a
58 changed files with 970 additions and 470 deletions
|
|
@ -791,11 +791,11 @@ public enum ChatControllerSubject: Equatable {
|
|||
}
|
||||
|
||||
public var quote: Quote?
|
||||
public var todoTaskId: Int32?
|
||||
public var subject: EngineMessageReplyInnerSubject?
|
||||
|
||||
public init(quote: Quote? = nil, todoTaskId: Int32? = nil) {
|
||||
public init(quote: Quote? = nil, subject: EngineMessageReplyInnerSubject? = nil) {
|
||||
self.quote = quote
|
||||
self.todoTaskId = todoTaskId
|
||||
self.subject = subject
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import Foundation
|
||||
import Postbox
|
||||
import Display
|
||||
import TelegramCore
|
||||
|
||||
public enum ChatHistoryInitialSearchLocation: Equatable {
|
||||
case index(MessageIndex)
|
||||
|
|
@ -20,13 +21,13 @@ public struct MessageHistoryScrollToSubject: Equatable {
|
|||
|
||||
public var index: MessageHistoryAnchorIndex
|
||||
public var quote: Quote?
|
||||
public var todoTaskId: Int32?
|
||||
public var subject: EngineMessageReplyInnerSubject?
|
||||
public var setupReply: Bool
|
||||
|
||||
public init(index: MessageHistoryAnchorIndex, quote: Quote? = nil, todoTaskId: Int32? = nil, setupReply: Bool = false) {
|
||||
public init(index: MessageHistoryAnchorIndex, quote: Quote? = nil, subject: EngineMessageReplyInnerSubject? = nil, setupReply: Bool = false) {
|
||||
self.index = index
|
||||
self.quote = quote
|
||||
self.todoTaskId = todoTaskId
|
||||
self.subject = subject
|
||||
self.setupReply = setupReply
|
||||
}
|
||||
}
|
||||
|
|
@ -44,12 +45,12 @@ public struct MessageHistoryInitialSearchSubject: Equatable {
|
|||
|
||||
public var location: ChatHistoryInitialSearchLocation
|
||||
public var quote: Quote?
|
||||
public var todoTaskId: Int32?
|
||||
public var subject: EngineMessageReplyInnerSubject?
|
||||
|
||||
public init(location: ChatHistoryInitialSearchLocation, quote: Quote? = nil, todoTaskId: Int32? = nil) {
|
||||
public init(location: ChatHistoryInitialSearchLocation, quote: Quote? = nil, subject: EngineMessageReplyInnerSubject? = nil) {
|
||||
self.location = location
|
||||
self.quote = quote
|
||||
self.todoTaskId = todoTaskId
|
||||
self.subject = subject
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ public final class BrowserBookmarksScreen: ViewController {
|
|||
}, openConferenceCall: { _ in
|
||||
}, longTap: { _, _ in
|
||||
}, todoItemLongTap: { _, _ in
|
||||
}, pollOptionLongTap: { _, _ in
|
||||
}, openCheckoutOrReceipt: { _, _ in
|
||||
}, openSearch: {
|
||||
}, setupReply: { _ in
|
||||
|
|
|
|||
|
|
@ -481,19 +481,19 @@ public final class ChatInterfaceState: Codable, Equatable {
|
|||
public struct ReplyMessageSubject: Codable, Equatable {
|
||||
public var messageId: EngineMessage.Id
|
||||
public var quote: EngineMessageReplyQuote?
|
||||
public var todoItemId: Int32?
|
||||
public var innerSubject: EngineMessageReplyInnerSubject?
|
||||
|
||||
public init(messageId: EngineMessage.Id, quote: EngineMessageReplyQuote?, todoItemId: Int32?) {
|
||||
public init(messageId: EngineMessage.Id, quote: EngineMessageReplyQuote?, innerSubject: EngineMessageReplyInnerSubject?) {
|
||||
self.messageId = messageId
|
||||
self.quote = quote
|
||||
self.todoItemId = todoItemId
|
||||
self.innerSubject = innerSubject
|
||||
}
|
||||
|
||||
public var subjectModel: EngineMessageReplySubject {
|
||||
return EngineMessageReplySubject(
|
||||
messageId: self.messageId,
|
||||
quote: self.quote,
|
||||
todoItemId: self.todoItemId
|
||||
innerSubject: self.innerSubject
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -549,7 +549,7 @@ public final class ChatInterfaceState: Codable, Equatable {
|
|||
return ReplyMessageSubject(
|
||||
messageId: $0.messageId,
|
||||
quote: $0.quote,
|
||||
todoItemId: $0.todoItemId
|
||||
innerSubject: $0.innerSubject
|
||||
)
|
||||
})
|
||||
if let timestamp = state?.timestamp {
|
||||
|
|
@ -633,7 +633,7 @@ public final class ChatInterfaceState: Codable, Equatable {
|
|||
let replyMessageIdNamespace: Int32? = try? container.decodeIfPresent(Int32.self, forKey: "r.n")
|
||||
let replyMessageIdId: Int32? = try? container.decodeIfPresent(Int32.self, forKey: "r.i")
|
||||
if let replyMessageIdPeerId = replyMessageIdPeerId, let replyMessageIdNamespace = replyMessageIdNamespace, let replyMessageIdId = replyMessageIdId {
|
||||
self.replyMessageSubject = ReplyMessageSubject(messageId: EngineMessage.Id(peerId: EnginePeer.Id(replyMessageIdPeerId), namespace: replyMessageIdNamespace, id: replyMessageIdId), quote: nil, todoItemId: nil)
|
||||
self.replyMessageSubject = ReplyMessageSubject(messageId: EngineMessage.Id(peerId: EnginePeer.Id(replyMessageIdPeerId), namespace: replyMessageIdNamespace, id: replyMessageIdId), quote: nil, innerSubject: nil)
|
||||
} else {
|
||||
self.replyMessageSubject = nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2939,7 +2939,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||
} else if let image = media as? TelegramMediaImage {
|
||||
if let _ = largestImageRepresentation(image.representations) {
|
||||
let fitSize = contentImageSize
|
||||
contentImageSpecs.append(ContentImageSpec(message: message, media: .image(image), size: fitSize))
|
||||
contentImageSpecs.append(ContentImageSpec(message: message, media: .image(image), size: fitSize))
|
||||
}
|
||||
break inner
|
||||
} else if let file = media as? TelegramMediaFile {
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public final class ChatPanelInterfaceInteraction {
|
|||
case editPrice
|
||||
}
|
||||
|
||||
public let setupReplyMessage: (MessageId?, Int32?, @escaping (ContainedViewLayoutTransition, @escaping () -> Void) -> Void) -> Void
|
||||
public let setupReplyMessage: (MessageId?, EngineMessageReplyInnerSubject?, @escaping (ContainedViewLayoutTransition, @escaping () -> Void) -> Void) -> Void
|
||||
public let setupEditMessage: (MessageId?, @escaping (ContainedViewLayoutTransition) -> Void) -> Void
|
||||
public let beginMessageSelection: ([MessageId], @escaping (ContainedViewLayoutTransition) -> Void) -> Void
|
||||
public let cancelMessageSelection: (ContainedViewLayoutTransition) -> Void
|
||||
|
|
@ -200,9 +200,9 @@ public final class ChatPanelInterfaceInteraction {
|
|||
public let requestLayout: (ContainedViewLayoutTransition) -> Void
|
||||
public let chatController: () -> ViewController?
|
||||
public let statuses: ChatPanelInterfaceInteractionStatuses?
|
||||
|
||||
|
||||
public init(
|
||||
setupReplyMessage: @escaping (MessageId?, Int32?, @escaping (ContainedViewLayoutTransition, @escaping () -> Void) -> Void) -> Void,
|
||||
setupReplyMessage: @escaping (MessageId?, EngineMessageReplyInnerSubject?, @escaping (ContainedViewLayoutTransition, @escaping () -> Void) -> Void) -> Void,
|
||||
setupEditMessage: @escaping (MessageId?, @escaping (ContainedViewLayoutTransition) -> Void) -> Void,
|
||||
beginMessageSelection: @escaping ([MessageId], @escaping (ContainedViewLayoutTransition) -> Void) -> Void,
|
||||
cancelMessageSelection: @escaping (ContainedViewLayoutTransition) -> Void,
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ private final class BubbleSettingsControllerNode: ASDisplayNode, ASScrollViewDel
|
|||
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: [], customTags: [], 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, accountPeer: nil, isCentered: false, isPreview: true, isStandalone: false, rank: nil, rankRole: nil))
|
||||
|
||||
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: [], customTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, todoItemId: 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: [], customTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, innerSubject: nil)], 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, accountPeer: nil, isCentered: false, isPreview: true, isStandalone: false, rank: nil, rankRole: nil))
|
||||
|
||||
let waveformBase64 = "DAAOAAkACQAGAAwADwAMABAADQAPABsAGAALAA0AGAAfABoAHgATABgAGQAYABQADAAVABEAHwANAA0ACQAWABkACQAOAAwACQAfAAAAGQAVAAAAEwATAAAACAAfAAAAHAAAABwAHwAAABcAGQAAABQADgAAABQAHwAAAB8AHwAAAAwADwAAAB8AEwAAABoAFwAAAB8AFAAAAAAAHwAAAAAAHgAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAAAA="
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, ASScrollView
|
|||
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: [], customTags: [], 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, accountPeer: nil, isCentered: false, isPreview: true, isStandalone: false, rank: nil, rankRole: nil))
|
||||
|
||||
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: [], customTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, todoItemId: 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: [], customTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, innerSubject: nil)], 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, accountPeer: nil, isCentered: false, isPreview: true, isStandalone: false, rank: nil, rankRole: nil))
|
||||
|
||||
let waveformBase64 = "DAAOAAkACQAGAAwADwAMABAADQAPABsAGAALAA0AGAAfABoAHgATABgAGQAYABQADAAVABEAHwANAA0ACQAWABkACQAOAAwACQAfAAAAGQAVAAAAEwATAAAACAAfAAAAHAAAABwAHwAAABcAGQAAABQADgAAABQAHwAAAB8AHwAAAAwADwAAAB8AEwAAABoAFwAAAB8AFAAAAAAAHwAAAAAAHgAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAAAA="
|
||||
|
|
|
|||
|
|
@ -613,7 +613,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
|||
messages[message4.id] = 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: [], customTags: [], 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, todoItemId: 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: [], customTags: [], 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, innerSubject: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
messages[message5.id] = message5
|
||||
sampleMessages.append(message5)
|
||||
|
||||
|
|
@ -624,7 +624,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
|||
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: [], customTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
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: [], customTags: [], 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, todoItemId: 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: [], customTags: [], 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, innerSubject: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
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: [], customTags: [], 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: [:])
|
||||
|
|
|
|||
|
|
@ -169,7 +169,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: [], customTags: [], 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: [], customTags: [], 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, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil) : nil, text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, todoItemId: 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: [], customTags: [], 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, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil) : nil, text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, innerSubject: nil)] : [], 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, accountPeer: nil, isCentered: false, isPreview: true, isStandalone: false, rank: nil, rankRole: nil))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2034,10 +2034,10 @@ public final class ShareController: ViewController {
|
|||
var messages: [EnqueueMessage] = []
|
||||
if !text.isEmpty {
|
||||
messages.append(.message(text: url + "\n\n" + text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap {
|
||||
EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil)
|
||||
EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil)
|
||||
}, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
} else {
|
||||
messages.append(.message(text: url, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages.append(.message(text: url, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
}
|
||||
messages = transformMessages(messages, showNames: showNames, silently: silently, sendPaidMessageStars: requiresStars[peerId])
|
||||
shareSignals.append(enqueueMessages(account: currentContext.context.account, peerId: peerId, messages: messages))
|
||||
|
|
@ -2070,9 +2070,9 @@ public final class ShareController: ViewController {
|
|||
|
||||
var messages: [EnqueueMessage] = []
|
||||
if !text.isEmpty {
|
||||
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
}
|
||||
messages.append(.message(text: string, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages.append(.message(text: string, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages = transformMessages(messages, showNames: showNames, silently: silently, sendPaidMessageStars: requiresStars[peerId])
|
||||
shareSignals.append(enqueueMessages(account: currentContext.context.account, peerId: peerId, messages: messages))
|
||||
}
|
||||
|
|
@ -2104,12 +2104,12 @@ public final class ShareController: ViewController {
|
|||
|
||||
var messages: [EnqueueMessage] = []
|
||||
if !text.isEmpty {
|
||||
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
}
|
||||
let attributedText = NSMutableAttributedString(string: string, attributes: [ChatTextInputAttributes.italic: true as NSNumber])
|
||||
attributedText.append(NSAttributedString(string: "\n\n\(url)"))
|
||||
let entities = generateChatInputTextEntities(attributedText)
|
||||
messages.append(.message(text: attributedText.string, attributes: [TextEntitiesMessageAttribute(entities: entities)], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages.append(.message(text: attributedText.string, attributes: [TextEntitiesMessageAttribute(entities: entities)], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages = transformMessages(messages, showNames: showNames, silently: silently, sendPaidMessageStars: requiresStars[peerId])
|
||||
shareSignals.append(enqueueMessages(account: currentContext.context.account, peerId: peerId, messages: messages))
|
||||
}
|
||||
|
|
@ -2140,7 +2140,7 @@ public final class ShareController: ViewController {
|
|||
}
|
||||
|
||||
var messages: [EnqueueMessage] = []
|
||||
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])), threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])), threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages = transformMessages(messages, showNames: showNames, silently: silently, sendPaidMessageStars: requiresStars[peerId])
|
||||
shareSignals.append(enqueueMessages(account: currentContext.context.account, peerId: peerId, messages: messages))
|
||||
}
|
||||
|
|
@ -2224,7 +2224,7 @@ public final class ShareController: ViewController {
|
|||
|
||||
var messages: [EnqueueMessage] = []
|
||||
if !text.isEmpty && !sendTextAsCaption {
|
||||
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
}
|
||||
var attributes: [MessageAttribute] = []
|
||||
if let startAtTimestamp = mediaParameters?.startAtTimestamp, let startAtTimestampNode = strongSelf.controllerNode.startAtTimestampNode, startAtTimestampNode.value {
|
||||
|
|
@ -2233,7 +2233,7 @@ public final class ShareController: ViewController {
|
|||
if let forwardSourceMessageId {
|
||||
messages.append(.forward(source: forwardSourceMessageId, threadId: threadId, grouping: .auto, attributes: attributes, correlationId: nil))
|
||||
} else {
|
||||
messages.append(.message(text: sendTextAsCaption ? text : "", attributes: attributes, inlineStickers: [:], mediaReference: mediaReference, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages.append(.message(text: sendTextAsCaption ? text : "", attributes: attributes, inlineStickers: [:], mediaReference: mediaReference, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
}
|
||||
messages = transformMessages(messages, showNames: showNames, silently: silently, sendPaidMessageStars: requiresStars[peerId])
|
||||
shareSignals.append(enqueueMessages(account: currentContext.context.account, peerId: peerId, messages: messages))
|
||||
|
|
@ -2266,9 +2266,9 @@ public final class ShareController: ViewController {
|
|||
|
||||
var messages: [EnqueueMessage] = []
|
||||
if !text.isEmpty {
|
||||
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
}
|
||||
messages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
messages = transformMessages(messages, showNames: showNames, silently: silently, sendPaidMessageStars: requiresStars[peerId])
|
||||
shareSignals.append(enqueueMessages(account: currentContext.context.account, peerId: peerId, messages: messages))
|
||||
}
|
||||
|
|
@ -2302,7 +2302,7 @@ public final class ShareController: ViewController {
|
|||
|
||||
let correlationId = Int64.random(in: Int64.min ... Int64.max)
|
||||
correlationIds.append(correlationId)
|
||||
messagesToEnqueue.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: []))
|
||||
messagesToEnqueue.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: threadId, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: []))
|
||||
}
|
||||
for message in messages {
|
||||
for media in message.media {
|
||||
|
|
|
|||
|
|
@ -868,7 +868,7 @@ extension StoreMessage {
|
|||
var threadMessageId: MessageId?
|
||||
switch replyTo {
|
||||
case let .messageReplyHeader(messageReplyHeaderData):
|
||||
let (innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset, todoItemId) = (messageReplyHeaderData.flags, messageReplyHeaderData.replyToMsgId, messageReplyHeaderData.replyToPeerId, messageReplyHeaderData.replyFrom, messageReplyHeaderData.replyMedia, messageReplyHeaderData.replyToTopId, messageReplyHeaderData.quoteText, messageReplyHeaderData.quoteEntities, messageReplyHeaderData.quoteOffset, messageReplyHeaderData.todoItemId)
|
||||
let (innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset, todoItemId, pollOption) = (messageReplyHeaderData.flags, messageReplyHeaderData.replyToMsgId, messageReplyHeaderData.replyToPeerId, messageReplyHeaderData.replyFrom, messageReplyHeaderData.replyMedia, messageReplyHeaderData.replyToTopId, messageReplyHeaderData.quoteText, messageReplyHeaderData.quoteEntities, messageReplyHeaderData.quoteOffset, messageReplyHeaderData.todoItemId, messageReplyHeaderData.pollOption)
|
||||
let isForumTopic = (innerFlags & (1 << 3)) != 0
|
||||
|
||||
var quote: EngineMessageReplyQuote?
|
||||
|
|
@ -919,7 +919,13 @@ extension StoreMessage {
|
|||
threadId = Int64(threadIdValue.id)
|
||||
}
|
||||
}
|
||||
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: threadMessageId, quote: quote, isQuote: isQuote, todoItemId: todoItemId))
|
||||
var innerSubject: EngineMessageReplyInnerSubject?
|
||||
if let todoItemId {
|
||||
innerSubject = .todoItem(todoItemId)
|
||||
} else if let pollOption {
|
||||
innerSubject = .pollOption(pollOption.makeData())
|
||||
}
|
||||
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: threadMessageId, quote: quote, isQuote: isQuote, innerSubject: innerSubject))
|
||||
}
|
||||
if let replyHeader = replyHeader {
|
||||
attributes.append(QuotedReplyMessageAttribute(apiHeader: replyHeader, quote: quote, isQuote: isQuote))
|
||||
|
|
@ -1256,7 +1262,7 @@ extension StoreMessage {
|
|||
if chatPeerId.peerId.namespace == Namespaces.Peer.CloudChannel, let replyTo {
|
||||
switch replyTo {
|
||||
case let .messageReplyHeader(messageReplyHeaderData):
|
||||
let (innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, quoteText, quoteEntities, quoteOffset, todoItemId) = (messageReplyHeaderData.flags, messageReplyHeaderData.replyToMsgId, messageReplyHeaderData.replyToPeerId, messageReplyHeaderData.replyFrom, messageReplyHeaderData.replyMedia, messageReplyHeaderData.quoteText, messageReplyHeaderData.quoteEntities, messageReplyHeaderData.quoteOffset, messageReplyHeaderData.todoItemId)
|
||||
let (innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, quoteText, quoteEntities, quoteOffset, todoItemId, pollOption) = (messageReplyHeaderData.flags, messageReplyHeaderData.replyToMsgId, messageReplyHeaderData.replyToPeerId, messageReplyHeaderData.replyFrom, messageReplyHeaderData.replyMedia, messageReplyHeaderData.quoteText, messageReplyHeaderData.quoteEntities, messageReplyHeaderData.quoteOffset, messageReplyHeaderData.todoItemId, messageReplyHeaderData.pollOption)
|
||||
var quote: EngineMessageReplyQuote?
|
||||
let isQuote = (innerFlags & (1 << 9)) != 0
|
||||
if quoteText != nil || replyMedia != nil {
|
||||
|
|
@ -1265,7 +1271,15 @@ extension StoreMessage {
|
|||
|
||||
if let replyToMsgId = replyToMsgId {
|
||||
let replyPeerId = replyToPeerId?.peerId ?? peerId
|
||||
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: nil, quote: quote, isQuote: isQuote, todoItemId: todoItemId))
|
||||
|
||||
var innerSubject: EngineMessageReplyInnerSubject?
|
||||
if let todoItemId {
|
||||
innerSubject = .todoItem(todoItemId)
|
||||
} else if let pollOption {
|
||||
innerSubject = .pollOption(pollOption.makeData())
|
||||
}
|
||||
|
||||
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: nil, quote: quote, isQuote: isQuote, innerSubject: innerSubject))
|
||||
} else if let replyHeader = replyHeader {
|
||||
attributes.append(QuotedReplyMessageAttribute(apiHeader: replyHeader, quote: quote, isQuote: isQuote))
|
||||
}
|
||||
|
|
@ -1278,7 +1292,7 @@ extension StoreMessage {
|
|||
var threadMessageId: MessageId?
|
||||
switch replyTo {
|
||||
case let .messageReplyHeader(messageReplyHeaderData):
|
||||
let (innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset, todoItemId) = (messageReplyHeaderData.flags, messageReplyHeaderData.replyToMsgId, messageReplyHeaderData.replyToPeerId, messageReplyHeaderData.replyFrom, messageReplyHeaderData.replyMedia, messageReplyHeaderData.replyToTopId, messageReplyHeaderData.quoteText, messageReplyHeaderData.quoteEntities, messageReplyHeaderData.quoteOffset, messageReplyHeaderData.todoItemId)
|
||||
let (innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset, todoItemId, pollOption) = (messageReplyHeaderData.flags, messageReplyHeaderData.replyToMsgId, messageReplyHeaderData.replyToPeerId, messageReplyHeaderData.replyFrom, messageReplyHeaderData.replyMedia, messageReplyHeaderData.replyToTopId, messageReplyHeaderData.quoteText, messageReplyHeaderData.quoteEntities, messageReplyHeaderData.quoteOffset, messageReplyHeaderData.todoItemId, messageReplyHeaderData.pollOption)
|
||||
var quote: EngineMessageReplyQuote?
|
||||
let isQuote = (innerFlags & (1 << 9)) != 0
|
||||
if quoteText != nil || replyMedia != nil {
|
||||
|
|
@ -1304,7 +1318,13 @@ extension StoreMessage {
|
|||
default:
|
||||
break
|
||||
}
|
||||
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: threadMessageId, quote: quote, isQuote: isQuote, todoItemId: todoItemId))
|
||||
var innerSubject: EngineMessageReplyInnerSubject?
|
||||
if let todoItemId {
|
||||
innerSubject = .todoItem(todoItemId)
|
||||
} else if let pollOption {
|
||||
innerSubject = .pollOption(pollOption.makeData())
|
||||
}
|
||||
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: threadMessageId, quote: quote, isQuote: isQuote, innerSubject: innerSubject))
|
||||
} else if let replyHeader = replyHeader {
|
||||
attributes.append(QuotedReplyMessageAttribute(apiHeader: replyHeader, quote: quote, isQuote: isQuote))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ public enum EnqueueMessageGrouping {
|
|||
case auto
|
||||
}
|
||||
|
||||
public enum EngineMessageReplyInnerSubject: Codable, Equatable {
|
||||
case todoItem(Int32)
|
||||
case pollOption(Data)
|
||||
}
|
||||
|
||||
public struct EngineMessageReplyQuote: Codable, Equatable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case text = "t"
|
||||
|
|
@ -82,12 +87,12 @@ public struct EngineMessageReplyQuote: Codable, Equatable {
|
|||
public struct EngineMessageReplySubject: Codable, Equatable {
|
||||
public var messageId: EngineMessage.Id
|
||||
public var quote: EngineMessageReplyQuote?
|
||||
public var todoItemId: Int32?
|
||||
public var innerSubject: EngineMessageReplyInnerSubject?
|
||||
|
||||
public init(messageId: EngineMessage.Id, quote: EngineMessageReplyQuote?, todoItemId: Int32?) {
|
||||
public init(messageId: EngineMessage.Id, quote: EngineMessageReplyQuote?, innerSubject: EngineMessageReplyInnerSubject?) {
|
||||
self.messageId = messageId
|
||||
self.quote = quote
|
||||
self.todoItemId = todoItemId
|
||||
self.innerSubject = innerSubject
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -387,7 +392,7 @@ public func enqueueMessagesToMultiplePeers(account: Account, peerIds: [PeerId],
|
|||
for peerId in peerIds {
|
||||
var replyToMessageId: EngineMessageReplySubject?
|
||||
if let threadIds = threadIds[peerId] {
|
||||
replyToMessageId = EngineMessageReplySubject(messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadIds)), quote: nil, todoItemId: nil)
|
||||
replyToMessageId = EngineMessageReplySubject(messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadIds)), quote: nil, innerSubject: nil)
|
||||
}
|
||||
var messages = messages
|
||||
if let replyToMessageId = replyToMessageId {
|
||||
|
|
@ -433,7 +438,7 @@ public func resendMessages(account: Account, messageIds: [MessageId]) -> Signal<
|
|||
var forwardSource: MessageId?
|
||||
inner: for attribute in message.attributes {
|
||||
if let attribute = attribute as? ReplyMessageAttribute {
|
||||
replyToMessageId = EngineMessageReplySubject(messageId: attribute.messageId, quote: attribute.quote, todoItemId: attribute.todoItemId)
|
||||
replyToMessageId = EngineMessageReplySubject(messageId: attribute.messageId, quote: attribute.quote, innerSubject: attribute.innerSubject)
|
||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||
replyToStoryId = attribute.storyId
|
||||
} else if let attribute = attribute as? OutgoingMessageInfoAttribute {
|
||||
|
|
@ -528,7 +533,7 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
|
|||
mediaReference = .standalone(media: media)
|
||||
}
|
||||
}
|
||||
updatedMessages.append((transformedMedia, .message(text: sourceMessage.text, attributes: sourceMessage.attributes, inlineStickers: [:], mediaReference: mediaReference, threadId: threadId, replyToMessageId: threadId.flatMap { EngineMessageReplySubject(messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: $0)), quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])))
|
||||
updatedMessages.append((transformedMedia, .message(text: sourceMessage.text, attributes: sourceMessage.attributes, inlineStickers: [:], mediaReference: mediaReference, threadId: threadId, replyToMessageId: threadId.flatMap { EngineMessageReplySubject(messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: $0)), quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])))
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
|
|
@ -666,7 +671,7 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
|
|||
quote = EngineMessageReplyQuote(text: replyMessage.text, offset: nil, 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, isQuote: isQuote, todoItemId: replyToMessageId.todoItemId))
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyToMessageId.messageId, threadMessageId: threadMessageId, quote: quote, isQuote: isQuote, innerSubject: replyToMessageId.innerSubject))
|
||||
}
|
||||
if let replyToStoryId = replyToStoryId {
|
||||
attributes.append(ReplyStoryAttribute(storyId: replyToStoryId))
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ public func standaloneSendEnqueueMessages(
|
|||
}
|
||||
|
||||
if let replyToMessageId = message.replyToMessageId {
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyToMessageId, threadMessageId: nil, quote: nil, isQuote: false, todoItemId: nil))
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyToMessageId, threadMessageId: nil, quote: nil, isQuote: false, innerSubject: nil))
|
||||
}
|
||||
if let forwardOptions = message.forwardOptions {
|
||||
attributes.append(ForwardOptionsMessageAttribute(hideNames: forwardOptions.hideNames, hideCaptions: forwardOptions.hideCaptions))
|
||||
|
|
@ -339,6 +339,7 @@ private func sendUploadedMessageContent(
|
|||
}
|
||||
var replyToStoryId: StoryId?
|
||||
var replyTodoItemId: Int32?
|
||||
var replyPollOption: Buffer?
|
||||
var scheduleTime: Int32?
|
||||
var scheduleRepeatPeriod: Int32?
|
||||
var videoTimestamp: Int32?
|
||||
|
|
@ -352,7 +353,14 @@ private func sendUploadedMessageContent(
|
|||
for attribute in attributes {
|
||||
if let replyAttribute = attribute as? ReplyMessageAttribute {
|
||||
replyMessageId = replyAttribute.messageId.id
|
||||
replyTodoItemId = replyAttribute.todoItemId
|
||||
switch replyAttribute.innerSubject {
|
||||
case let .todoItem(todoItemId):
|
||||
replyTodoItemId = todoItemId
|
||||
case let .pollOption(pollOption):
|
||||
replyPollOption = Buffer(data: pollOption)
|
||||
default:
|
||||
break
|
||||
}
|
||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||
replyToStoryId = attribute.storyId
|
||||
} else if let outgoingInfo = attribute as? OutgoingMessageInfoAttribute {
|
||||
|
|
@ -445,7 +453,10 @@ private func sendUploadedMessageContent(
|
|||
if let _ = replyTodoItemId {
|
||||
replyFlags |= 1 << 6
|
||||
}
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyMessageId, topMsgId: topMsgId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: nil))
|
||||
if let _ = replyPollOption {
|
||||
replyFlags |= 1 << 7
|
||||
}
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyMessageId, topMsgId: topMsgId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: replyPollOption))
|
||||
} else if let replyToStoryId {
|
||||
if let inputPeer = transaction.getPeer(replyToStoryId.peerId).flatMap(apiInputPeer) {
|
||||
flags |= 1 << 0
|
||||
|
|
@ -479,7 +490,10 @@ private func sendUploadedMessageContent(
|
|||
if let _ = replyTodoItemId {
|
||||
replyFlags |= 1 << 6
|
||||
}
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyMessageId, topMsgId: topMsgId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: nil))
|
||||
if let _ = replyPollOption {
|
||||
replyFlags |= 1 << 7
|
||||
}
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyMessageId, topMsgId: topMsgId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: replyPollOption))
|
||||
} else if let replyToStoryId = replyToStoryId {
|
||||
if let inputPeer = transaction.getPeer(replyToStoryId.peerId).flatMap(apiInputPeer) {
|
||||
flags |= 1 << 0
|
||||
|
|
|
|||
|
|
@ -1694,7 +1694,7 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
|
|||
if let replyToMsgHeader {
|
||||
switch replyToMsgHeader {
|
||||
case let .inputReplyToMessage(inputReplyToMessageData):
|
||||
let (replyToMsgId, topMsgId, replyToPeerId, quoteText, quoteEntities, quoteOffset, monoforumPeerId, todoItemId) = (inputReplyToMessageData.replyToMsgId, inputReplyToMessageData.topMsgId, inputReplyToMessageData.replyToPeerId, inputReplyToMessageData.quoteText, inputReplyToMessageData.quoteEntities, inputReplyToMessageData.quoteOffset, inputReplyToMessageData.monoforumPeerId, inputReplyToMessageData.todoItemId)
|
||||
let (replyToMsgId, topMsgId, replyToPeerId, quoteText, quoteEntities, quoteOffset, monoforumPeerId, todoItemId, pollOption) = (inputReplyToMessageData.replyToMsgId, inputReplyToMessageData.topMsgId, inputReplyToMessageData.replyToPeerId, inputReplyToMessageData.quoteText, inputReplyToMessageData.quoteEntities, inputReplyToMessageData.quoteOffset, inputReplyToMessageData.monoforumPeerId, inputReplyToMessageData.todoItemId, inputReplyToMessageData.pollOption)
|
||||
let _ = topMsgId
|
||||
let _ = monoforumPeerId
|
||||
|
||||
|
|
@ -1733,10 +1733,17 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
|
|||
break
|
||||
}
|
||||
|
||||
var innerSubject: EngineMessageReplyInnerSubject?
|
||||
if let todoItemId {
|
||||
innerSubject = .todoItem(todoItemId)
|
||||
} else if let pollOption {
|
||||
innerSubject = .pollOption(pollOption.makeData())
|
||||
}
|
||||
|
||||
replySubject = EngineMessageReplySubject(
|
||||
messageId: MessageId(peerId: parsedReplyToPeerId ?? peer.peerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId),
|
||||
quote: quote,
|
||||
todoItemId: todoItemId
|
||||
innerSubject: innerSubject
|
||||
)
|
||||
case .inputReplyToStory:
|
||||
break
|
||||
|
|
|
|||
|
|
@ -197,7 +197,16 @@ private func synchronizeChatInputState(transaction: Transaction, postbox: Postbo
|
|||
}
|
||||
}
|
||||
|
||||
let replyTodoItemId = replySubject.todoItemId
|
||||
var replyTodoItemId: Int32?
|
||||
var replyPollOption: Buffer?
|
||||
switch replySubject.innerSubject {
|
||||
case let .todoItem(todoItemId):
|
||||
replyTodoItemId = todoItemId
|
||||
case let .pollOption(pollOption):
|
||||
replyPollOption = Buffer(data: pollOption)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if replyToPeer != nil {
|
||||
innerFlags |= 1 << 1
|
||||
|
|
@ -214,8 +223,11 @@ private func synchronizeChatInputState(transaction: Transaction, postbox: Postbo
|
|||
if let _ = replyTodoItemId {
|
||||
innerFlags |= 1 << 6
|
||||
}
|
||||
if let _ = replyPollOption {
|
||||
innerFlags |= 1 << 7
|
||||
}
|
||||
if !discard {
|
||||
replyTo = .inputReplyToMessage(.init(flags: innerFlags, replyToMsgId: replySubject.messageId.id, topMsgId: topMsgId, replyToPeerId: replyToPeer, quoteText: quoteText, quoteEntities: quoteEntities, quoteOffset: quoteOffset, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: nil))
|
||||
replyTo = .inputReplyToMessage(.init(flags: innerFlags, replyToMsgId: replySubject.messageId.id, topMsgId: topMsgId, replyToPeerId: replyToPeer, quoteText: quoteText, quoteEntities: quoteEntities, quoteOffset: quoteOffset, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: replyPollOption))
|
||||
}
|
||||
} else if let topMsgId {
|
||||
flags |= 1 << 0
|
||||
|
|
|
|||
|
|
@ -563,7 +563,7 @@ public final class PendingMessageManager {
|
|||
}
|
||||
var attributes = currentMessage.attributes
|
||||
if !attributes.contains(where: { $0 is ReplyMessageAttribute }) {
|
||||
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: id.peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: topicId)), threadMessageId: nil, quote: nil, isQuote: false, todoItemId: nil))
|
||||
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: id.peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: topicId)), threadMessageId: nil, quote: nil, isQuote: false, innerSubject: nil))
|
||||
}
|
||||
return .update(StoreMessage(id: id, customStableId: nil, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: topicId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
|
||||
})
|
||||
|
|
@ -1026,6 +1026,7 @@ public final class PendingMessageManager {
|
|||
var replyQuote: EngineMessageReplyQuote?
|
||||
var replyToStoryId: StoryId?
|
||||
var replyTodoItemId: Int32?
|
||||
var replyPollOption: Buffer?
|
||||
var scheduleTime: Int32?
|
||||
var scheduleRepeatPeriod: Int32?
|
||||
var videoTimestamp: Int32?
|
||||
|
|
@ -1046,7 +1047,14 @@ public final class PendingMessageManager {
|
|||
if replyAttribute.isQuote {
|
||||
replyQuote = replyAttribute.quote
|
||||
}
|
||||
replyTodoItemId = replyAttribute.todoItemId
|
||||
switch replyAttribute.innerSubject {
|
||||
case let .todoItem(todoItemId):
|
||||
replyTodoItemId = todoItemId
|
||||
case let .pollOption(pollOption):
|
||||
replyPollOption = Buffer(data: pollOption)
|
||||
default:
|
||||
break
|
||||
}
|
||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||
replyToStoryId = attribute.storyId
|
||||
} else if let _ = attribute as? ForwardSourceInfoAttribute {
|
||||
|
|
@ -1289,8 +1297,11 @@ public final class PendingMessageManager {
|
|||
if let _ = replyTodoItemId {
|
||||
replyFlags |= 1 << 6
|
||||
}
|
||||
if let _ = replyPollOption {
|
||||
replyFlags |= 1 << 7
|
||||
}
|
||||
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyMessageId, topMsgId: topMsgId, replyToPeerId: replyToPeerId, quoteText: quoteText, quoteEntities: quoteEntities, quoteOffset: quoteOffset, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: nil))
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyMessageId, topMsgId: topMsgId, replyToPeerId: replyToPeerId, quoteText: quoteText, quoteEntities: quoteEntities, quoteOffset: quoteOffset, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: replyPollOption))
|
||||
} else if let replyToStoryId {
|
||||
if let inputPeer = transaction.getPeer(replyToStoryId.peerId).flatMap(apiInputPeer) {
|
||||
flags |= 1 << 0
|
||||
|
|
@ -1532,6 +1543,7 @@ public final class PendingMessageManager {
|
|||
var replyQuote: EngineMessageReplyQuote?
|
||||
var replyToStoryId: StoryId?
|
||||
var replyTodoItemId: Int32?
|
||||
var replyPollOption: Buffer?
|
||||
var scheduleTime: Int32?
|
||||
var scheduleRepeatPeriod: Int32?
|
||||
var videoTimestamp: Int32?
|
||||
|
|
@ -1565,7 +1577,14 @@ public final class PendingMessageManager {
|
|||
if replyAttribute.isQuote {
|
||||
replyQuote = replyAttribute.quote
|
||||
}
|
||||
replyTodoItemId = replyAttribute.todoItemId
|
||||
switch replyAttribute.innerSubject {
|
||||
case let .todoItem(todoItemId):
|
||||
replyTodoItemId = todoItemId
|
||||
case let .pollOption(pollOption):
|
||||
replyPollOption = Buffer(data: pollOption)
|
||||
default:
|
||||
break
|
||||
}
|
||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||
replyToStoryId = attribute.storyId
|
||||
} else if let outgoingInfo = attribute as? OutgoingMessageInfoAttribute {
|
||||
|
|
@ -1682,7 +1701,10 @@ public final class PendingMessageManager {
|
|||
if let _ = replyTodoItemId {
|
||||
replyFlags |= 1 << 6
|
||||
}
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyMessageId, topMsgId: topMsgId, replyToPeerId: replyToPeerId, quoteText: quoteText, quoteEntities: quoteEntities, quoteOffset: quoteOffset, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: nil))
|
||||
if let _ = replyPollOption {
|
||||
replyFlags |= 1 << 7
|
||||
}
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyMessageId, topMsgId: topMsgId, replyToPeerId: replyToPeerId, quoteText: quoteText, quoteEntities: quoteEntities, quoteOffset: quoteOffset, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: replyPollOption))
|
||||
} else if let replyToStoryId = replyToStoryId {
|
||||
if let inputPeer = transaction.getPeer(replyToStoryId.peerId).flatMap(apiInputPeer) {
|
||||
flags |= 1 << 0
|
||||
|
|
@ -1780,7 +1802,10 @@ public final class PendingMessageManager {
|
|||
if let _ = replyTodoItemId {
|
||||
replyFlags |= 1 << 6
|
||||
}
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyMessageId, topMsgId: topMsgId, replyToPeerId: replyToPeerId, quoteText: quoteText, quoteEntities: quoteEntities, quoteOffset: quoteOffset, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: nil))
|
||||
if let _ = replyPollOption {
|
||||
replyFlags |= 1 << 7
|
||||
}
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyMessageId, topMsgId: topMsgId, replyToPeerId: replyToPeerId, quoteText: quoteText, quoteEntities: quoteEntities, quoteOffset: quoteOffset, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: replyPollOption))
|
||||
} else if let replyToStoryId = replyToStoryId {
|
||||
if let inputPeer = transaction.getPeer(replyToStoryId.peerId).flatMap(apiInputPeer) {
|
||||
flags |= 1 << 0
|
||||
|
|
@ -1928,7 +1953,10 @@ public final class PendingMessageManager {
|
|||
if let _ = replyTodoItemId {
|
||||
replyFlags |= 1 << 6
|
||||
}
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyMessageId, topMsgId: message.threadId.flatMap(Int32.init(clamping:)), replyToPeerId: replyToPeerId, quoteText: quoteText, quoteEntities: quoteEntities, quoteOffset: quoteOffset, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: nil))
|
||||
if let _ = replyPollOption {
|
||||
replyFlags |= 1 << 7
|
||||
}
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyMessageId, topMsgId: message.threadId.flatMap(Int32.init(clamping:)), replyToPeerId: replyToPeerId, quoteText: quoteText, quoteEntities: quoteEntities, quoteOffset: quoteOffset, monoforumPeerId: monoforumPeerId, todoItemId: replyTodoItemId, pollOption: replyPollOption))
|
||||
} else if let replyToStoryId = replyToStoryId {
|
||||
if let inputPeer = transaction.getPeer(replyToStoryId.peerId).flatMap(apiInputPeer) {
|
||||
flags |= 1 << 0
|
||||
|
|
|
|||
|
|
@ -881,7 +881,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
|
|||
}
|
||||
|
||||
if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) {
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, todoItemId: nil))
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, innerSubject: nil))
|
||||
}
|
||||
|
||||
var entitiesAttribute: TextEntitiesMessageAttribute?
|
||||
|
|
@ -1113,7 +1113,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
|
|||
}
|
||||
|
||||
if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) {
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, todoItemId: nil))
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, innerSubject: nil))
|
||||
}
|
||||
|
||||
var entitiesAttribute: TextEntitiesMessageAttribute?
|
||||
|
|
@ -1392,7 +1392,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
|
|||
}
|
||||
|
||||
if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) {
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, todoItemId: nil))
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, innerSubject: nil))
|
||||
}
|
||||
|
||||
var entitiesAttribute: TextEntitiesMessageAttribute?
|
||||
|
|
@ -1593,7 +1593,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
|
|||
}
|
||||
|
||||
if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) {
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, todoItemId: nil))
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, innerSubject: nil))
|
||||
}
|
||||
|
||||
var entitiesAttribute: TextEntitiesMessageAttribute?
|
||||
|
|
|
|||
|
|
@ -7,18 +7,18 @@ public class ReplyMessageAttribute: MessageAttribute {
|
|||
public let threadMessageId: MessageId?
|
||||
public let quote: EngineMessageReplyQuote?
|
||||
public let isQuote: Bool
|
||||
public let todoItemId: Int32?
|
||||
public let innerSubject: EngineMessageReplyInnerSubject?
|
||||
|
||||
public var associatedMessageIds: [MessageId] {
|
||||
return [self.messageId]
|
||||
}
|
||||
|
||||
public init(messageId: MessageId, threadMessageId: MessageId?, quote: EngineMessageReplyQuote?, isQuote: Bool, todoItemId: Int32?) {
|
||||
public init(messageId: MessageId, threadMessageId: MessageId?, quote: EngineMessageReplyQuote?, isQuote: Bool, innerSubject: EngineMessageReplyInnerSubject?) {
|
||||
self.messageId = messageId
|
||||
self.threadMessageId = threadMessageId
|
||||
self.quote = quote
|
||||
self.isQuote = isQuote
|
||||
self.todoItemId = todoItemId
|
||||
self.innerSubject = innerSubject
|
||||
}
|
||||
|
||||
required public init(decoder: PostboxDecoder) {
|
||||
|
|
@ -33,7 +33,13 @@ public class ReplyMessageAttribute: MessageAttribute {
|
|||
|
||||
self.quote = decoder.decodeCodable(EngineMessageReplyQuote.self, forKey: "qu")
|
||||
self.isQuote = decoder.decodeBoolForKey("iq", orElse: self.quote != nil)
|
||||
self.todoItemId = decoder.decodeOptionalInt32ForKey("tid")
|
||||
if let todoItemId = decoder.decodeOptionalInt32ForKey("tid") {
|
||||
self.innerSubject = .todoItem(todoItemId)
|
||||
} else if let pollOptionId = decoder.decodeDataForKey("pid") {
|
||||
self.innerSubject = .pollOption(pollOptionId)
|
||||
} else {
|
||||
self.innerSubject = nil
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
|
|
@ -51,10 +57,16 @@ public class ReplyMessageAttribute: MessageAttribute {
|
|||
encoder.encodeNil(forKey: "qu")
|
||||
}
|
||||
encoder.encodeBool(self.isQuote, forKey: "iq")
|
||||
if let todoItemId = self.todoItemId {
|
||||
switch self.innerSubject {
|
||||
case let .todoItem(todoItemId):
|
||||
encoder.encodeInt32(todoItemId, forKey: "tid")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "pid")
|
||||
case let .pollOption(pollOptionId):
|
||||
encoder.encodeData(pollOptionId, forKey: "pid")
|
||||
encoder.encodeNil(forKey: "tid")
|
||||
default:
|
||||
encoder.encodeNil(forKey: "tid")
|
||||
encoder.encodeNil(forKey: "pid")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public struct SynchronizeableChatInputState: Codable, Equatable {
|
|||
self.replySubject = replySubject
|
||||
} else {
|
||||
if let messageIdPeerId = try? container.decodeIfPresent(Int64.self, forKey: "m.p"), let messageIdNamespace = try? container.decodeIfPresent(Int32.self, forKey: "m.n"), let messageIdId = try? container.decodeIfPresent(Int32.self, forKey: "m.i") {
|
||||
self.replySubject = EngineMessageReplySubject(messageId: MessageId(peerId: PeerId(messageIdPeerId), namespace: messageIdNamespace, id: messageIdId), quote: nil, todoItemId: nil)
|
||||
self.replySubject = EngineMessageReplySubject(messageId: MessageId(peerId: PeerId(messageIdPeerId), namespace: messageIdNamespace, id: messageIdId), quote: nil, innerSubject: nil)
|
||||
} else {
|
||||
self.replySubject = nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ func _internal_enqueueOutgoingMessageWithChatContextResult(account: Account, to
|
|||
func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, threadId: Int64?, botId: PeerId, result: ChatContextResult, replyToMessageId: EngineMessageReplySubject?, replyToStoryId: StoryId?, hideVia: Bool, silentPosting: Bool, scheduleTime: Int32?, sendPaidMessageStars: StarsAmount?, postpone: Bool, correlationId: Int64?) -> EnqueueMessage? {
|
||||
var replyToMessageId = replyToMessageId
|
||||
if replyToMessageId == nil, let threadId = threadId {
|
||||
replyToMessageId = EngineMessageReplySubject(messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: MessageId.Id(clamping: threadId)), quote: nil, todoItemId: nil)
|
||||
replyToMessageId = EngineMessageReplySubject(messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: MessageId.Id(clamping: threadId)), quote: nil, innerSubject: nil)
|
||||
}
|
||||
|
||||
var webpageUrl: String?
|
||||
|
|
|
|||
|
|
@ -103,13 +103,13 @@ public final class ChatInputMessageAccessoryPanel: Component {
|
|||
public final class Reply: Equatable {
|
||||
public let id: EngineMessage.Id
|
||||
public let quote: EngineMessageReplyQuote?
|
||||
public let todoItemId: Int32?
|
||||
public let innerSubject: EngineMessageReplyInnerSubject?
|
||||
public let message: EngineMessage?
|
||||
|
||||
public init(id: EngineMessage.Id, quote: EngineMessageReplyQuote?, todoItemId: Int32?, message: EngineMessage?) {
|
||||
public init(id: EngineMessage.Id, quote: EngineMessageReplyQuote?, innerSubject: EngineMessageReplyInnerSubject?, message: EngineMessage?) {
|
||||
self.id = id
|
||||
self.quote = quote
|
||||
self.todoItemId = todoItemId
|
||||
self.innerSubject = innerSubject
|
||||
self.message = message
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ public final class ChatInputMessageAccessoryPanel: Component {
|
|||
if lhs.quote != rhs.quote {
|
||||
return false
|
||||
}
|
||||
if lhs.todoItemId != rhs.todoItemId {
|
||||
if lhs.innerSubject != rhs.innerSubject {
|
||||
return false
|
||||
}
|
||||
if lhs.message?.id != rhs.message?.id {
|
||||
|
|
@ -597,9 +597,13 @@ public final class ChatInputMessageAccessoryPanel: Component {
|
|||
authorName = EnginePeer(author).displayTitle(strings: environment.strings, displayOrder: environment.nameDisplayOrder)
|
||||
}
|
||||
|
||||
if let _ = reply.todoItemId {
|
||||
if case .todoItem = reply.innerSubject {
|
||||
let string = environment.strings.Chat_ReplyPanel_ReplyToTodoItem
|
||||
titleText = [.text(NSAttributedString(string: string, font: Font.medium(14.0), textColor: environment.theme.chat.inputPanel.panelControlAccentColor))]
|
||||
} else if case .pollOption = reply.innerSubject {
|
||||
//TODO:localize
|
||||
let string = "Reply to Poll Option"
|
||||
titleText = [.text(NSAttributedString(string: string, font: Font.medium(14.0), textColor: environment.theme.chat.inputPanel.panelControlAccentColor))]
|
||||
} else if let _ = reply.quote {
|
||||
let string = environment.strings.Chat_ReplyPanel_ReplyToQuoteBy(authorName).string
|
||||
titleText = [.text(NSAttributedString(string: string, font: Font.medium(14.0), textColor: environment.theme.chat.inputPanel.panelControlAccentColor))]
|
||||
|
|
@ -628,9 +632,12 @@ public final class ChatInputMessageAccessoryPanel: Component {
|
|||
if let quote = reply.quote {
|
||||
let textColor = environment.theme.chat.inputPanel.primaryTextColor
|
||||
textString = stringWithAppliedEntities(trimToLineCount(quote.text, lineCount: 1), entities: quote.entities, baseColor: textColor, linkColor: textColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: textFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, underlineLinks: false, message: message._asMessage())
|
||||
} else if let todoItemId = reply.todoItemId, let todo = message.media.first(where: { $0 is TelegramMediaTodo }) as? TelegramMediaTodo, let todoItem = todo.items.first(where: { $0.id == todoItemId }) {
|
||||
} else if case let .todoItem(todoItemId) = reply.innerSubject, let todo = message.media.first(where: { $0 is TelegramMediaTodo }) as? TelegramMediaTodo, let todoItem = todo.items.first(where: { $0.id == todoItemId }) {
|
||||
let textColor = environment.theme.chat.inputPanel.primaryTextColor
|
||||
textString = stringWithAppliedEntities(trimToLineCount(todoItem.text, lineCount: 1), entities: todoItem.entities, baseColor: textColor, linkColor: textColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: textFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, underlineLinks: false, message: message._asMessage())
|
||||
} else if case let .pollOption(pollOptionId) = reply.innerSubject, let poll = message.media.first(where: { $0 is TelegramMediaPoll }) as? TelegramMediaPoll, let pollOption = poll.options.first(where: { $0.opaqueIdentifier == pollOptionId }) {
|
||||
let textColor = environment.theme.chat.inputPanel.primaryTextColor
|
||||
textString = stringWithAppliedEntities(trimToLineCount(pollOption.text, lineCount: 1), entities: pollOption.entities, baseColor: textColor, linkColor: textColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: textFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, underlineLinks: false, message: message._asMessage())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1215,7 +1215,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||
var replyMessage: Message?
|
||||
var replyForward: QuotedReplyMessageAttribute?
|
||||
var replyQuote: (quote: EngineMessageReplyQuote, isQuote: Bool)?
|
||||
var replyTodoItemId: Int32?
|
||||
var replyInnerSubject: EngineMessageReplyInnerSubject?
|
||||
var replyStory: StoryId?
|
||||
for attribute in item.message.attributes {
|
||||
if let attribute = attribute as? InlineBotMessageAttribute {
|
||||
|
|
@ -1243,7 +1243,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||
replyMessage = item.message.associatedMessages[replyAttribute.messageId]
|
||||
}
|
||||
replyQuote = replyAttribute.quote.flatMap { ($0, replyAttribute.isQuote) }
|
||||
replyTodoItemId = replyAttribute.todoItemId
|
||||
replyInnerSubject = replyAttribute.innerSubject
|
||||
} else if let quoteReplyAttribute = attribute as? QuotedReplyMessageAttribute {
|
||||
replyForward = quoteReplyAttribute
|
||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||
|
|
@ -1283,7 +1283,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||
message: replyMessage,
|
||||
replyForward: replyForward,
|
||||
quote: replyQuote,
|
||||
todoItemId: replyTodoItemId,
|
||||
innerSubject: replyInnerSubject,
|
||||
story: replyStory,
|
||||
isSummarized: false,
|
||||
parentMessage: item.message,
|
||||
|
|
|
|||
|
|
@ -724,7 +724,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||
|
||||
private struct HighlightedState: Equatable {
|
||||
var quote: ChatInterfaceHighlightedState.Quote?
|
||||
var todoTaskId: Int32?
|
||||
var subject: EngineMessageReplyInnerSubject?
|
||||
}
|
||||
private var highlightedState: HighlightedState?
|
||||
|
||||
|
|
@ -1994,7 +1994,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||
var replyMessage: Message?
|
||||
var replyForward: QuotedReplyMessageAttribute?
|
||||
var replyQuote: (quote: EngineMessageReplyQuote, isQuote: Bool)?
|
||||
var replyTodoItemId: Int32?
|
||||
var replyInnerSubject: EngineMessageReplyInnerSubject?
|
||||
var replyStory: StoryId?
|
||||
var replyMarkup: ReplyMarkupMessageAttribute?
|
||||
var authorNameColor: UIColor?
|
||||
|
|
@ -2012,7 +2012,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||
replyMessage = firstMessage.associatedMessages[attribute.messageId]
|
||||
}
|
||||
replyQuote = attribute.quote.flatMap { ($0, attribute.isQuote) }
|
||||
replyTodoItemId = attribute.todoItemId
|
||||
replyInnerSubject = attribute.innerSubject
|
||||
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
||||
replyForward = attribute
|
||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||
|
|
@ -2823,7 +2823,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||
message: replyMessage,
|
||||
replyForward: replyForward,
|
||||
quote: replyQuote,
|
||||
todoItemId: replyTodoItemId,
|
||||
innerSubject: replyInnerSubject,
|
||||
story: replyStory,
|
||||
isSummarized: isSummarized,
|
||||
parentMessage: item.message,
|
||||
|
|
@ -5599,7 +5599,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||
if let replyInfoNode = self.replyInfoNode {
|
||||
progress = replyInfoNode.makeProgress()
|
||||
}
|
||||
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.isQuote ? attribute.quote.flatMap { quote in NavigateToMessageParams.Quote(string: quote.text, offset: quote.offset) } : nil, todoTaskId: attribute.todoItemId, progress: progress))
|
||||
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.isQuote ? attribute.quote.flatMap { quote in NavigateToMessageParams.Quote(string: quote.text, offset: quote.offset) } : nil, subject: attribute.innerSubject, progress: progress))
|
||||
}, contextMenuOnLongPress: true))
|
||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||
return .action(InternalBubbleTapAction.Action({
|
||||
|
|
@ -6423,7 +6423,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||
if let highlightedStateValue = item.controllerInteraction.highlightedState {
|
||||
for (message, _) in item.content {
|
||||
if highlightedStateValue.messageStableId == message.stableId {
|
||||
highlightedState = HighlightedState(quote: highlightedStateValue.quote, todoTaskId: highlightedStateValue.todoTaskId)
|
||||
highlightedState = HighlightedState(quote: highlightedStateValue.quote, subject: highlightedStateValue.subject)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -6520,44 +6520,57 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||
}
|
||||
}
|
||||
})
|
||||
} else if highlightedState?.todoTaskId != nil {
|
||||
} else if let replySubject = highlightedState?.subject {
|
||||
Queue.mainQueue().after(0.3, { [weak self] in
|
||||
guard let self, let _ = self.item, let backgroundHighlightNode = self.backgroundHighlightNode else {
|
||||
return
|
||||
}
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .spring)
|
||||
|
||||
if let highlightedState = self.highlightedState, let todoTaskId = highlightedState.todoTaskId {
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .spring)
|
||||
|
||||
var taskFrame: CGRect?
|
||||
for contentNode in self.contentNodes {
|
||||
if let contentNode = contentNode as? ChatMessageTodoBubbleContentNode {
|
||||
contentNode.updateTaskHighlightState(id: todoTaskId, color: highlightColor, animated: false)
|
||||
var sourceFrame = backgroundHighlightNode.view.convert(backgroundHighlightNode.bounds, to: contentNode.view)
|
||||
if item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||
sourceFrame.origin.x += 6.0
|
||||
sourceFrame.size.width -= 6.0
|
||||
} else {
|
||||
sourceFrame.size.width -= 6.0
|
||||
}
|
||||
|
||||
if let localFrame = contentNode.animateTaskItemHighlightIn(id: todoTaskId, sourceFrame: sourceFrame, transition: transition) {
|
||||
taskFrame = contentNode.view.convert(localFrame, to: backgroundHighlightNode.view.superview).insetBy(dx: -3.0, dy: 0.0)
|
||||
}
|
||||
break
|
||||
var itemFrame: CGRect?
|
||||
|
||||
switch replySubject {
|
||||
case let .todoItem(todoItemId):
|
||||
if let contentNode = self.contentNodes.first(where: { $0 is ChatMessageTodoBubbleContentNode }) as? ChatMessageTodoBubbleContentNode {
|
||||
contentNode.updateTaskHighlightState(id: todoItemId, color: highlightColor, animated: false)
|
||||
var sourceFrame = backgroundHighlightNode.view.convert(backgroundHighlightNode.bounds, to: contentNode.view)
|
||||
if item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||
sourceFrame.origin.x += 6.0
|
||||
sourceFrame.size.width -= 6.0
|
||||
} else {
|
||||
sourceFrame.size.width -= 6.0
|
||||
}
|
||||
|
||||
if let localFrame = contentNode.animateTaskItemHighlightIn(id: todoItemId, sourceFrame: sourceFrame, transition: transition) {
|
||||
itemFrame = contentNode.view.convert(localFrame, to: backgroundHighlightNode.view.superview).insetBy(dx: -3.0, dy: 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
if let taskFrame {
|
||||
self.backgroundHighlightNode = nil
|
||||
case let .pollOption(pollOption):
|
||||
if let contentNode = self.contentNodes.first(where: { $0 is ChatMessagePollBubbleContentNode }) as? ChatMessagePollBubbleContentNode {
|
||||
contentNode.updateOptionHighlightState(id: pollOption, color: highlightColor, animated: false)
|
||||
var sourceFrame = backgroundHighlightNode.view.convert(backgroundHighlightNode.bounds, to: contentNode.view)
|
||||
if item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||
sourceFrame.origin.x += 6.0
|
||||
sourceFrame.size.width -= 6.0
|
||||
} else {
|
||||
sourceFrame.size.width -= 6.0
|
||||
}
|
||||
|
||||
backgroundHighlightNode.updateLayout(size: taskFrame.size, transition: transition)
|
||||
transition.updateFrame(node: backgroundHighlightNode, frame: taskFrame)
|
||||
backgroundHighlightNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.1, delay: 0.05, removeOnCompletion: false, completion: { [weak backgroundHighlightNode] _ in
|
||||
backgroundHighlightNode?.removeFromSupernode()
|
||||
})
|
||||
if let localFrame = contentNode.animateOptionItemHighlightIn(id: pollOption, sourceFrame: sourceFrame, transition: transition) {
|
||||
itemFrame = contentNode.view.convert(localFrame, to: backgroundHighlightNode.view.superview).insetBy(dx: -3.0, dy: 0.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let itemFrame {
|
||||
self.backgroundHighlightNode = nil
|
||||
|
||||
backgroundHighlightNode.updateLayout(size: itemFrame.size, transition: transition)
|
||||
transition.updateFrame(node: backgroundHighlightNode, frame: itemFrame)
|
||||
backgroundHighlightNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.1, delay: 0.05, removeOnCompletion: false, completion: { [weak backgroundHighlightNode] _ in
|
||||
backgroundHighlightNode?.removeFromSupernode()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -7085,12 +7098,15 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||
return nil
|
||||
}
|
||||
|
||||
public func getTodoTaskRect(id: Int32) -> CGRect? {
|
||||
for contentNode in self.contentNodes {
|
||||
if let contentNode = contentNode as? ChatMessageTodoBubbleContentNode {
|
||||
if let result = contentNode.getTaskRect(id: id) {
|
||||
return contentNode.view.convert(result, to: self.view)
|
||||
}
|
||||
public func getInnerReplySubjectRect(innerSubject: EngineMessageReplyInnerSubject) -> CGRect? {
|
||||
switch innerSubject {
|
||||
case let .todoItem(todoItemId):
|
||||
if let contentNode = self.contentNodes.first(where: { $0 is ChatMessageTodoBubbleContentNode }) as? ChatMessageTodoBubbleContentNode, let result = contentNode.getTaskRect(id: todoItemId) {
|
||||
return contentNode.view.convert(result, to: self.view)
|
||||
}
|
||||
case let .pollOption(pollOption):
|
||||
if let contentNode = self.contentNodes.first(where: { $0 is ChatMessagePollBubbleContentNode }) as? ChatMessagePollBubbleContentNode, let result = contentNode.getOptionRect(id: pollOption) {
|
||||
return contentNode.view.convert(result, to: self.view)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, ASGestureReco
|
|||
var replyMessage: Message?
|
||||
var replyForward: QuotedReplyMessageAttribute?
|
||||
var replyQuote: (quote: EngineMessageReplyQuote, isQuote: Bool)?
|
||||
var replyTodoItemId: Int32?
|
||||
var replyInnerSubject: EngineMessageReplyInnerSubject?
|
||||
var replyStory: StoryId?
|
||||
for attribute in item.message.attributes {
|
||||
if let attribute = attribute as? InlineBotMessageAttribute {
|
||||
|
|
@ -508,7 +508,7 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, ASGestureReco
|
|||
replyMessage = item.message.associatedMessages[replyAttribute.messageId]
|
||||
}
|
||||
replyQuote = replyAttribute.quote.flatMap { ($0, replyAttribute.isQuote) }
|
||||
replyTodoItemId = replyAttribute.todoItemId
|
||||
replyInnerSubject = replyAttribute.innerSubject
|
||||
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
||||
replyForward = attribute
|
||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||
|
|
@ -528,7 +528,7 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, ASGestureReco
|
|||
message: replyMessage,
|
||||
replyForward: replyForward,
|
||||
quote: replyQuote,
|
||||
todoItemId: replyTodoItemId,
|
||||
innerSubject: replyInnerSubject,
|
||||
story: replyStory,
|
||||
isSummarized: false,
|
||||
parentMessage: item.message,
|
||||
|
|
|
|||
|
|
@ -352,9 +352,8 @@ public class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
|||
var replyMessage: Message?
|
||||
var replyForward: QuotedReplyMessageAttribute?
|
||||
var replyQuote: (quote: EngineMessageReplyQuote, isQuote: Bool)?
|
||||
var replyTodoItemId: Int32?
|
||||
var replyInnerSubject: EngineMessageReplyInnerSubject?
|
||||
var replyStory: StoryId?
|
||||
|
||||
for attribute in item.message.attributes {
|
||||
if let attribute = attribute as? InlineBotMessageAttribute {
|
||||
var inlineBotNameString: String?
|
||||
|
|
@ -383,7 +382,7 @@ public class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
|||
replyMessage = item.message.associatedMessages[replyAttribute.messageId]
|
||||
}
|
||||
replyQuote = replyAttribute.quote.flatMap { ($0, replyAttribute.isQuote) }
|
||||
replyTodoItemId = replyAttribute.todoItemId
|
||||
replyInnerSubject = replyAttribute.innerSubject
|
||||
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
||||
replyForward = attribute
|
||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||
|
|
@ -402,7 +401,7 @@ public class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
|||
message: replyMessage,
|
||||
replyForward: replyForward,
|
||||
quote: replyQuote,
|
||||
todoItemId: replyTodoItemId,
|
||||
innerSubject: replyInnerSubject,
|
||||
story: replyStory,
|
||||
isSummarized: false,
|
||||
parentMessage: item.message,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/EmojiTextAttachmentView",
|
||||
"//submodules/PhotoResources",
|
||||
"//submodules/LocationResources",
|
||||
"//submodules/TelegramUI/Components/ChatControllerInteraction",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -83,7 +83,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
|||
public let message: Message?
|
||||
public let replyForward: QuotedReplyMessageAttribute?
|
||||
public let quote: (quote: EngineMessageReplyQuote, isQuote: Bool)?
|
||||
public let todoItemId: Int32?
|
||||
public let innerSubject: EngineMessageReplyInnerSubject?
|
||||
public let story: StoryId?
|
||||
public let isSummarized: Bool
|
||||
public let parentMessage: Message
|
||||
|
|
@ -100,7 +100,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
|||
message: Message?,
|
||||
replyForward: QuotedReplyMessageAttribute?,
|
||||
quote: (quote: EngineMessageReplyQuote, isQuote: Bool)?,
|
||||
todoItemId: Int32?,
|
||||
innerSubject: EngineMessageReplyInnerSubject?,
|
||||
story: StoryId?,
|
||||
isSummarized: Bool,
|
||||
parentMessage: Message,
|
||||
|
|
@ -116,7 +116,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
|||
self.message = message
|
||||
self.replyForward = replyForward
|
||||
self.quote = quote
|
||||
self.todoItemId = todoItemId
|
||||
self.innerSubject = innerSubject
|
||||
self.story = story
|
||||
self.isSummarized = isSummarized
|
||||
self.parentMessage = parentMessage
|
||||
|
|
@ -446,7 +446,11 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
|||
var textLeftInset: CGFloat = 0.0
|
||||
var messageText: NSAttributedString
|
||||
var todoItemCompleted: Bool?
|
||||
if let todoItemId = arguments.todoItemId, let todo = arguments.message?.media.first(where: { $0 is TelegramMediaTodo }) as? TelegramMediaTodo, let todoItem = todo.items.first(where: { $0.id == todoItemId }) {
|
||||
|
||||
if case let .pollOption(optionId) = arguments.innerSubject, let poll = arguments.message?.media.first(where: { $0 is TelegramMediaPoll }) as? TelegramMediaPoll, let pollOption = poll.options.first(where: { $0.opaqueIdentifier == optionId }) {
|
||||
messageText = stringWithAppliedEntities(pollOption.text, entities: pollOption.entities, baseColor: textColor, linkColor: textColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: textFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, underlineLinks: false, message: nil)
|
||||
textLeftInset += 16.0
|
||||
} else if case let .todoItem(todoItemId) = arguments.innerSubject, let todo = arguments.message?.media.first(where: { $0 is TelegramMediaTodo }) as? TelegramMediaTodo, let todoItem = todo.items.first(where: { $0.id == todoItemId }) {
|
||||
messageText = stringWithAppliedEntities(todoItem.text, entities: todoItem.entities, baseColor: textColor, linkColor: textColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: textFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, underlineLinks: false, message: nil)
|
||||
textLeftInset += 16.0
|
||||
|
||||
|
|
|
|||
|
|
@ -706,7 +706,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||
var replyMessage: Message?
|
||||
var replyForward: QuotedReplyMessageAttribute?
|
||||
var replyQuote: (quote: EngineMessageReplyQuote, isQuote: Bool)?
|
||||
var replyTodoItemId: Int32?
|
||||
var replyInnerSubject: EngineMessageReplyInnerSubject?
|
||||
var replyStory: StoryId?
|
||||
for attribute in item.message.attributes {
|
||||
if let attribute = attribute as? InlineBotMessageAttribute {
|
||||
|
|
@ -735,7 +735,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||
replyMessage = item.message.associatedMessages[replyAttribute.messageId]
|
||||
}
|
||||
replyQuote = replyAttribute.quote.flatMap { ($0, replyAttribute.isQuote) }
|
||||
replyTodoItemId = replyAttribute.todoItemId
|
||||
replyInnerSubject = replyAttribute.innerSubject
|
||||
} else if let attribute = attribute as? QuotedReplyMessageAttribute {
|
||||
replyForward = attribute
|
||||
} else if let attribute = attribute as? ReplyStoryAttribute {
|
||||
|
|
@ -775,7 +775,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||
message: replyMessage,
|
||||
replyForward: replyForward,
|
||||
quote: replyQuote,
|
||||
todoItemId: replyTodoItemId,
|
||||
innerSubject: replyInnerSubject,
|
||||
story: replyStory,
|
||||
isSummarized: false,
|
||||
parentMessage: item.message,
|
||||
|
|
|
|||
|
|
@ -572,6 +572,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
|||
}
|
||||
}
|
||||
}, todoItemLongTap: { _, _ in
|
||||
}, pollOptionLongTap: { _, _ in
|
||||
}, openCheckoutOrReceipt: { _, _ in
|
||||
}, openSearch: {
|
||||
}, setupReply: { _ in
|
||||
|
|
|
|||
|
|
@ -434,7 +434,8 @@ public final class ChatSendGroupMediaMessageContextPreview: UIView, ChatSendMess
|
|||
}, chatControllerNode: {
|
||||
return nil
|
||||
}, presentGlobalOverlayController: { _, _ in }, callPeer: { _, _ in }, openConferenceCall: { _ in
|
||||
}, longTap: { _, _ in }, todoItemLongTap: { _, _ in }, openCheckoutOrReceipt: { _, _ in }, openSearch: { }, setupReply: { _ in
|
||||
}, longTap: { _, _ in }, todoItemLongTap: { _, _ in }, pollOptionLongTap: { _, _ in
|
||||
}, openCheckoutOrReceipt: { _, _ in }, openSearch: { }, setupReply: { _ in
|
||||
}, canSetupReply: { _ in
|
||||
return .none
|
||||
}, canSendMessages: {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public final class ReplyAccessoryPanelNode: AccessoryPanelNode {
|
|||
public let chatPeerId: EnginePeer.Id
|
||||
public let messageId: MessageId
|
||||
public let quote: EngineMessageReplyQuote?
|
||||
public let todoItemId: Int32?
|
||||
public let innerSubject: EngineMessageReplyInnerSubject?
|
||||
|
||||
private var previousMediaReference: AnyMediaReference?
|
||||
|
||||
|
|
@ -47,11 +47,11 @@ public final class ReplyAccessoryPanelNode: AccessoryPanelNode {
|
|||
|
||||
private var validLayout: (size: CGSize, inset: CGFloat, interfaceState: ChatPresentationInterfaceState)?
|
||||
|
||||
public init(context: AccountContext, chatPeerId: EnginePeer.Id, messageId: MessageId, quote: EngineMessageReplyQuote?, todoItemId: Int32?, theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, animationCache: AnimationCache?, animationRenderer: MultiAnimationRenderer?) {
|
||||
public init(context: AccountContext, chatPeerId: EnginePeer.Id, messageId: MessageId, quote: EngineMessageReplyQuote?, innerSubject: EngineMessageReplyInnerSubject?, theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, animationCache: AnimationCache?, animationRenderer: MultiAnimationRenderer?) {
|
||||
self.chatPeerId = chatPeerId
|
||||
self.messageId = messageId
|
||||
self.quote = quote
|
||||
self.todoItemId = todoItemId
|
||||
self.innerSubject = innerSubject
|
||||
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
|
|
@ -269,9 +269,13 @@ public final class ReplyAccessoryPanelNode: AccessoryPanelNode {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if let _ = strongSelf.todoItemId {
|
||||
if case .todoItem = strongSelf.innerSubject {
|
||||
let string = strongSelf.strings.Chat_ReplyPanel_ReplyToTodoItem
|
||||
titleText = [.text(NSAttributedString(string: string, font: Font.medium(15.0), textColor: strongSelf.theme.chat.inputPanel.panelControlAccentColor))]
|
||||
} else if case .pollOption = strongSelf.innerSubject {
|
||||
//TODO:localize
|
||||
let string = "Reply to Poll Option"
|
||||
titleText = [.text(NSAttributedString(string: string, font: Font.medium(15.0), textColor: strongSelf.theme.chat.inputPanel.panelControlAccentColor))]
|
||||
} else if let _ = strongSelf.quote {
|
||||
let string = strongSelf.strings.Chat_ReplyPanel_ReplyToQuoteBy(authorName).string
|
||||
titleText = [.text(NSAttributedString(string: string, font: Font.medium(15.0), textColor: strongSelf.theme.chat.inputPanel.panelControlAccentColor))]
|
||||
|
|
@ -303,10 +307,14 @@ public final class ReplyAccessoryPanelNode: AccessoryPanelNode {
|
|||
let quoteText = stringWithAppliedEntities(trimToLineCount(quote.text, lineCount: 1), entities: quote.entities, baseColor: textColor, linkColor: textColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: textFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, underlineLinks: false, message: message)
|
||||
|
||||
strongSelf.textNode.attributedText = quoteText
|
||||
} else if let todoItemId = strongSelf.todoItemId, let todo = message?.media.first(where: { $0 is TelegramMediaTodo }) as? TelegramMediaTodo, let todoItem = todo.items.first(where: { $0.id == todoItemId }) {
|
||||
} else if case let .todoItem(todoItemId) = strongSelf.innerSubject, let todo = message?.media.first(where: { $0 is TelegramMediaTodo }) as? TelegramMediaTodo, let todoItem = todo.items.first(where: { $0.id == todoItemId }) {
|
||||
let textColor = strongSelf.theme.chat.inputPanel.primaryTextColor
|
||||
let itemText = stringWithAppliedEntities(trimToLineCount(todoItem.text, lineCount: 1), entities: todoItem.entities, baseColor: textColor, linkColor: textColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: textFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, underlineLinks: false, message: message)
|
||||
strongSelf.textNode.attributedText = itemText
|
||||
} else if case let .pollOption(pollOptionId) = strongSelf.innerSubject, let poll = message?.media.first(where: { $0 is TelegramMediaPoll }) as? TelegramMediaPoll, let pollOption = poll.options.first(where: { $0.opaqueIdentifier == pollOptionId }) {
|
||||
let textColor = strongSelf.theme.chat.inputPanel.primaryTextColor
|
||||
let itemText = stringWithAppliedEntities(trimToLineCount(pollOption.text, lineCount: 1), entities: pollOption.entities, baseColor: textColor, linkColor: textColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: textFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, underlineLinks: false, message: message)
|
||||
strongSelf.textNode.attributedText = itemText
|
||||
}
|
||||
|
||||
strongSelf.titleNode.components = titleText
|
||||
|
|
|
|||
|
|
@ -32,12 +32,12 @@ public struct ChatInterfaceHighlightedState: Equatable {
|
|||
|
||||
public let messageStableId: UInt32
|
||||
public let quote: Quote?
|
||||
public let todoTaskId: Int32?
|
||||
public let subject: EngineMessageReplyInnerSubject?
|
||||
|
||||
public init(messageStableId: UInt32, quote: Quote?, todoTaskId: Int32?) {
|
||||
public init(messageStableId: UInt32, quote: Quote?, subject: EngineMessageReplyInnerSubject?) {
|
||||
self.messageStableId = messageStableId
|
||||
self.quote = quote
|
||||
self.todoTaskId = todoTaskId
|
||||
self.subject = subject
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,18 +96,18 @@ public struct NavigateToMessageParams {
|
|||
self.offset = offset
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public var timestamp: Double?
|
||||
public var quote: Quote?
|
||||
public var todoTaskId: Int32?
|
||||
public var subject: EngineMessageReplyInnerSubject?
|
||||
public var progress: Promise<Bool>?
|
||||
public var forceNew: Bool
|
||||
public var setupReply: Bool
|
||||
|
||||
public init(timestamp: Double?, quote: Quote?, todoTaskId: Int32? = nil, progress: Promise<Bool>? = nil, forceNew: Bool = false, setupReply: Bool = false) {
|
||||
public init(timestamp: Double?, quote: Quote?, subject: EngineMessageReplyInnerSubject? = nil, progress: Promise<Bool>? = nil, forceNew: Bool = false, setupReply: Bool = false) {
|
||||
self.timestamp = timestamp
|
||||
self.quote = quote
|
||||
self.todoTaskId = todoTaskId
|
||||
self.subject = subject
|
||||
self.progress = progress
|
||||
self.forceNew = forceNew
|
||||
self.setupReply = setupReply
|
||||
|
|
@ -217,6 +217,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
|||
public let openConferenceCall: (Message) -> Void
|
||||
public let longTap: (ChatControllerInteractionLongTapAction, LongTapParams?) -> Void
|
||||
public let todoItemLongTap: (Int32, LongTapParams?) -> Void
|
||||
public let pollOptionLongTap: (Data, LongTapParams?) -> Void
|
||||
public let openCheckoutOrReceipt: (MessageId, OpenMessageParams?) -> Void
|
||||
public let openSearch: () -> Void
|
||||
public let setupReply: (MessageId) -> Void
|
||||
|
|
@ -388,6 +389,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
|||
openConferenceCall: @escaping (Message) -> Void,
|
||||
longTap: @escaping (ChatControllerInteractionLongTapAction, LongTapParams?) -> Void,
|
||||
todoItemLongTap: @escaping (Int32, LongTapParams?) -> Void,
|
||||
pollOptionLongTap: @escaping (Data, LongTapParams?) -> Void,
|
||||
openCheckoutOrReceipt: @escaping (MessageId, OpenMessageParams?) -> Void,
|
||||
openSearch: @escaping () -> Void,
|
||||
setupReply: @escaping (MessageId) -> Void,
|
||||
|
|
@ -512,6 +514,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
|||
self.openConferenceCall = openConferenceCall
|
||||
self.longTap = longTap
|
||||
self.todoItemLongTap = todoItemLongTap
|
||||
self.pollOptionLongTap = pollOptionLongTap
|
||||
self.openCheckoutOrReceipt = openCheckoutOrReceipt
|
||||
self.openSearch = openSearch
|
||||
self.setupReply = setupReply
|
||||
|
|
|
|||
|
|
@ -875,7 +875,9 @@ final class ComposeTodoScreenComponent: Component {
|
|||
},
|
||||
assumeIsEditing: self.inputMediaNodeTargetTag === todoItem.textFieldTag,
|
||||
characterLimit: component.initialData.maxTodoItemLength,
|
||||
hasLeftInset: true,
|
||||
canReorder: isEnabled,
|
||||
canAdd: isEnabled && i != 0 && i < component.initialData.maxTodoItemsCount,
|
||||
emptyLineHandling: .notAllowed,
|
||||
returnKeyAction: { [weak self] in
|
||||
guard let self else {
|
||||
|
|
|
|||
|
|
@ -1167,6 +1167,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
break
|
||||
}
|
||||
}, todoItemLongTap: { _, _ in
|
||||
}, pollOptionLongTap: { _, _ in
|
||||
}, openCheckoutOrReceipt: { _, _ in
|
||||
}, openSearch: {
|
||||
}, setupReply: { _ in
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ extension PeerInfoScreenNode {
|
|||
strongSelf.enqueueMediaMessageDisposable.set((legacyAssetPickerEnqueueMessages(context: strongSelf.context, account: strongSelf.context.account, signals: signals!)
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] messages in
|
||||
if let strongSelf = self {
|
||||
let _ = enqueueMessages(account: strongSelf.context.account, peerId: strongSelf.peerId, messages: messages.map { $0.message.withUpdatedReplyToMessageId(.init(messageId: message.id, quote: nil, todoItemId: nil)) }).startStandalone()
|
||||
let _ = enqueueMessages(account: strongSelf.context.account, peerId: strongSelf.peerId, messages: messages.map { $0.message.withUpdatedReplyToMessageId(.init(messageId: message.id, quote: nil, innerSubject: nil)) }).startStandalone()
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -240,7 +240,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, imageIsVideoCover: false, 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: [], customTags: [], forwardInfo: nil, author: peers[authorPeerId], text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, todoItemId: 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: [], customTags: [], forwardInfo: nil, author: peers[authorPeerId], text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, innerSubject: nil)] : [], 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, accountPeer: nil, isCentered: false, isPreview: true, isStandalone: false, rank: nil, rankRole: nil))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1070,7 +1070,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, ASScrollViewDelegate
|
|||
messages[message4.id] = 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: [], customTags: [], 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, todoItemId: 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: [], customTags: [], 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, innerSubject: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
messages[message5.id] = message5
|
||||
sampleMessages.append(message5)
|
||||
|
||||
|
|
@ -1081,7 +1081,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, ASScrollViewDelegate
|
|||
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: [], customTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
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: [], customTags: [], 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, todoItemId: 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: [], customTags: [], 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, innerSubject: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
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: [], customTags: [], 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: [:])
|
||||
|
|
|
|||
|
|
@ -1524,7 +1524,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
|||
|
||||
let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3)
|
||||
messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: messageAuthor, text: self.presentationData.strings.WallpaperPreview_ChannelReplyText, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
messageAttributes = [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, todoItemId: nil)]
|
||||
messageAttributes = [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false, innerSubject: nil)]
|
||||
}
|
||||
|
||||
peers[peerId] = messageAuthor
|
||||
|
|
|
|||
|
|
@ -2563,7 +2563,7 @@ final class StoryItemSetContainerSendMessage: @unchecked(Sendable) {
|
|||
}
|
||||
|
||||
let file = TelegramMediaFile(fileId: EngineMedia.Id(namespace: Namespaces.Media.LocalFile, id: fileId), partialReference: nil, resource: ICloudFileResource(urlData: item.urlData, thumbnail: false), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(item.fileSize), attributes: attributes, alternativeRepresentations: [])
|
||||
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), threadId: nil, replyToMessageId: replyMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: replyToStoryId, localGroupingKey: groupingKey, correlationId: nil, bubbleUpEmojiOrStickersets: [])
|
||||
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), threadId: nil, replyToMessageId: replyMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: replyToStoryId, localGroupingKey: groupingKey, correlationId: nil, bubbleUpEmojiOrStickersets: [])
|
||||
messages.append(message)
|
||||
}
|
||||
if let _ = groupingKey, messages.count % 10 == 0 {
|
||||
|
|
@ -2668,7 +2668,7 @@ final class StoryItemSetContainerSendMessage: @unchecked(Sendable) {
|
|||
threadId: nil,
|
||||
botId: results.botId,
|
||||
result: result,
|
||||
replyToMessageId: replyMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) },
|
||||
replyToMessageId: replyMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) },
|
||||
replyToStoryId: storyId,
|
||||
hideVia: hideVia,
|
||||
silentPosting: silentPosting,
|
||||
|
|
@ -3056,7 +3056,7 @@ final class StoryItemSetContainerSendMessage: @unchecked(Sendable) {
|
|||
mappedMessages.append(message)
|
||||
}
|
||||
|
||||
strongSelf.sendMessages(view: view, peer: peer, messages: mappedMessages.map { $0.withUpdatedReplyToMessageId(replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }).withUpdatedReplyToStoryId(replyToStoryId) }, silentPosting: silentPosting, scheduleTime: scheduleTime)
|
||||
strongSelf.sendMessages(view: view, peer: peer, messages: mappedMessages.map { $0.withUpdatedReplyToMessageId(replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }).withUpdatedReplyToStoryId(replyToStoryId) }, silentPosting: silentPosting, scheduleTime: scheduleTime)
|
||||
|
||||
completion()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2885,7 +2885,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
|||
if let threadId {
|
||||
replyToMessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadId))
|
||||
}
|
||||
return enqueueMessages(account: account, peerId: peerId, messages: [EnqueueMessage.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: nil, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, todoItemId: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
|
||||
return enqueueMessages(account: account, peerId: peerId, messages: [EnqueueMessage.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: nil, replyToMessageId: replyToMessageId.flatMap { EngineMessageReplySubject(messageId: $0, quote: nil, innerSubject: nil) }, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
|
||||
|> map { messageIds -> MessageId? in
|
||||
if messageIds.isEmpty {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -1580,7 +1580,7 @@ extension ChatControllerImpl {
|
|||
strongSelf.window?.presentInGlobalOverlay(controller)
|
||||
}
|
||||
|
||||
let interfaceInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { [weak self] messageId, todoItemId, completion in
|
||||
let interfaceInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { [weak self] messageId, innerSubject, completion in
|
||||
guard let strongSelf = self, strongSelf.isNodeLoaded else {
|
||||
return
|
||||
}
|
||||
|
|
@ -1607,7 +1607,7 @@ extension ChatControllerImpl {
|
|||
$0.withUpdatedReplyMessageSubject(ChatInterfaceState.ReplyMessageSubject(
|
||||
messageId: message.id,
|
||||
quote: nil,
|
||||
todoItemId: todoItemId
|
||||
innerSubject: innerSubject
|
||||
))
|
||||
}).updatedReplyMessage(message).updatedSearch(nil).updatedShowCommands(false) }, completion: { t in
|
||||
completion(t, {})
|
||||
|
|
@ -1631,7 +1631,7 @@ extension ChatControllerImpl {
|
|||
let replySubject = ChatInterfaceState.ReplyMessageSubject(
|
||||
messageId: messageId,
|
||||
quote: nil,
|
||||
todoItemId: todoItemId
|
||||
innerSubject: innerSubject
|
||||
)
|
||||
|
||||
completion(.immediate, {
|
||||
|
|
@ -5160,7 +5160,7 @@ extension ChatControllerImpl {
|
|||
}
|
||||
}
|
||||
|
||||
let highlightedState = ChatInterfaceHighlightedState(messageStableId: message.stableId, quote: toSubject.quote.flatMap { quote in ChatInterfaceHighlightedState.Quote(string: quote.string, offset: quote.offset) }, todoTaskId: toSubject.todoTaskId)
|
||||
let highlightedState = ChatInterfaceHighlightedState(messageStableId: message.stableId, quote: toSubject.quote.flatMap { quote in ChatInterfaceHighlightedState.Quote(string: quote.string, offset: quote.offset) }, subject: toSubject.subject)
|
||||
controllerInteraction.highlightedState = highlightedState
|
||||
strongSelf.updateItemNodesHighlightedStates(animated: initial)
|
||||
strongSelf.contentData?.scrolledToMessageIdValue = ScrolledToMessageId(id: mappedId, allowedReplacementDirection: [])
|
||||
|
|
@ -5172,7 +5172,7 @@ extension ChatControllerImpl {
|
|||
} else {
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .info(title: nil, text: strongSelf.presentationData.strings.Chat_ToastQuoteNotFound, timeout: nil, customUndoText: nil), elevatedLayout: false, action: { _ in return true }), in: .current)
|
||||
}
|
||||
} else if let _ = toSubject.todoTaskId {
|
||||
} else if let _ = toSubject.subject {
|
||||
extendHighlight = true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -340,15 +340,15 @@ extension ChatControllerImpl {
|
|||
}
|
||||
|
||||
var quote: (string: String, offset: Int?)?
|
||||
var todoTaskId: Int32?
|
||||
var subject: EngineMessageReplyInnerSubject?
|
||||
var setupReply = false
|
||||
if case let .id(_, params) = messageLocation {
|
||||
quote = params.quote.flatMap { quote in (string: quote.string, offset: quote.offset) }
|
||||
setupReply = params.setupReply
|
||||
todoTaskId = params.todoTaskId
|
||||
subject = params.subject
|
||||
}
|
||||
|
||||
self.chatDisplayNode.historyNode.scrollToMessage(from: scrollFromIndex, to: message.index, animated: animated, quote: quote, todoTaskId: todoTaskId, scrollPosition: scrollPosition, setupReply: setupReply)
|
||||
self.chatDisplayNode.historyNode.scrollToMessage(from: scrollFromIndex, to: message.index, animated: animated, quote: quote, subject: subject, scrollPosition: scrollPosition, setupReply: setupReply)
|
||||
|
||||
if delayCompletion {
|
||||
Queue.mainQueue().after(0.25, {
|
||||
|
|
@ -512,15 +512,15 @@ extension ChatControllerImpl {
|
|||
self.loadingMessage.set(.single(statusSubject) |> delay(0.1, queue: .mainQueue()))
|
||||
|
||||
var quote: ChatControllerSubject.MessageHighlight.Quote?
|
||||
var todoTaskId: Int32?
|
||||
var subject: EngineMessageReplyInnerSubject?
|
||||
var setupReply = false
|
||||
if case let .id(_, params) = messageLocation {
|
||||
quote = params.quote.flatMap { quote in ChatControllerSubject.MessageHighlight.Quote(string: quote.string, offset: quote.offset) }
|
||||
todoTaskId = params.todoTaskId
|
||||
subject = params.subject
|
||||
setupReply = params.setupReply
|
||||
}
|
||||
|
||||
let historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: searchLocation, quote: quote.flatMap { quote in MessageHistoryInitialSearchSubject.Quote(string: quote.string, offset: quote.offset) }, todoTaskId: todoTaskId), count: 50, highlight: true, setupReply: setupReply), id: 0), context: self.context, chatLocation: self.chatLocation, subject: self.subject, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tag: nil, additionalData: [])
|
||||
let historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: searchLocation, quote: quote.flatMap { quote in MessageHistoryInitialSearchSubject.Quote(string: quote.string, offset: quote.offset) }, subject: subject), count: 50, highlight: true, setupReply: setupReply), id: 0), context: self.context, chatLocation: self.chatLocation, subject: self.subject, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tag: nil, additionalData: [])
|
||||
var signal: Signal<MessageIndex?, NoError>
|
||||
signal = historyView
|
||||
|> mapToSignal { historyView -> Signal<MessageIndex?, NoError> in
|
||||
|
|
|
|||
|
|
@ -0,0 +1,186 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import ContextUI
|
||||
import UndoUI
|
||||
import AccountContext
|
||||
import ChatMessageItemView
|
||||
import ChatMessageItemCommon
|
||||
import AvatarNode
|
||||
import ChatControllerInteraction
|
||||
import Pasteboard
|
||||
import TelegramStringFormatting
|
||||
import TelegramPresentationData
|
||||
|
||||
private enum OptionsId: Hashable {
|
||||
case item
|
||||
case message
|
||||
}
|
||||
|
||||
extension ChatControllerImpl {
|
||||
func openPollOptionContextMenu(optionId: Data, params: ChatControllerInteraction.LongTapParams) -> Void {
|
||||
guard let message = params.message, let poll = message.media.first(where: { $0 is TelegramMediaPoll }) as? TelegramMediaPoll, let pollOptionIndex = poll.options.firstIndex(where: { $0.opaqueIdentifier == optionId }), let contentNode = params.contentNode else {
|
||||
return
|
||||
}
|
||||
|
||||
let pollOption = poll.options[pollOptionIndex]
|
||||
|
||||
let _ = (contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState: self.presentationInterfaceState, context: self.context, messages: [message], controllerInteraction: self.controllerInteraction, selectAll: false, interfaceInteraction: self.interfaceInteraction, messageNode: params.messageNode as? ChatMessageItemView)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] actions in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
var items: [ContextMenuItem] = []
|
||||
// if canMark {
|
||||
// items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Chat_Todo_ContextMenu_CheckTask, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, f in
|
||||
// guard let self else {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if !self.context.isPremium {
|
||||
// f(.default)
|
||||
// let controller = UndoOverlayController(
|
||||
// presentationData: self.presentationData,
|
||||
// content: .premiumPaywall(title: nil, text: self.presentationData.strings.Chat_Todo_PremiumRequired, customUndoText: nil, timeout: nil, linkAction: nil),
|
||||
// action: { [weak self] action in
|
||||
// guard let self else {
|
||||
// return false
|
||||
// }
|
||||
// if case .info = action {
|
||||
// let controller = self.context.sharedContext.makePremiumIntroController(context: context, source: .presence, forceDark: false, dismissed: nil)
|
||||
// self.push(controller)
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
// )
|
||||
// self.present(controller, in: .current)
|
||||
// } else {
|
||||
// c?.dismiss(completion: {
|
||||
// let _ = self.context.engine.messages.requestUpdateTodoMessageItems(messageId: message.id, completedIds: [todoItemId], incompletedIds: []).start()
|
||||
// })
|
||||
// }
|
||||
// })))
|
||||
// }
|
||||
|
||||
//TODO:localize
|
||||
if canReplyInChat(self.presentationInterfaceState, accountPeerId: self.context.account.peerId) {
|
||||
items.append(.action(ContextMenuActionItem(text: "Reply to Option", icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Reply"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { [weak self] c, _ in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.interfaceInteraction?.setupReplyMessage(message.id, .pollOption(pollOption.opaqueIdentifier), { transition, completed in
|
||||
c?.dismiss(result: .custom(transition), completion: {
|
||||
completed()
|
||||
})
|
||||
})
|
||||
})))
|
||||
}
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Conversation_ContextMenuCopy, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
storeMessageTextInPasteboard(pollOption.text, entities: pollOption.entities)
|
||||
|
||||
self.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: presentationData.strings.Conversation_TextCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
|
||||
var isReplyThreadHead = false
|
||||
if case let .replyThread(replyThreadMessage) = self.presentationInterfaceState.chatLocation {
|
||||
isReplyThreadHead = message.id == replyThreadMessage.effectiveTopId
|
||||
}
|
||||
|
||||
if message.id.namespace == Namespaces.Message.Cloud, let channel = message.peers[message.id.peerId] as? TelegramChannel, !channel.isMonoForum, !isReplyThreadHead {
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Conversation_ContextMenuCopyLink, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Link"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, f in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
var threadMessageId: MessageId?
|
||||
if case let .replyThread(replyThreadMessage) = self.presentationInterfaceState.chatLocation {
|
||||
threadMessageId = replyThreadMessage.effectiveMessageId
|
||||
}
|
||||
let _ = (self.context.engine.messages.exportMessageLink(peerId: message.id.peerId, messageId: message.id, isThread: threadMessageId != nil)
|
||||
|> map { result -> String? in
|
||||
return result
|
||||
}
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] link in
|
||||
guard let self, let link else {
|
||||
return
|
||||
}
|
||||
UIPasteboard.general.string = link + "?option=\(pollOptionIndex)"
|
||||
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
var warnAboutPrivate = false
|
||||
if case .peer = self.presentationInterfaceState.chatLocation {
|
||||
if channel.addressName == nil {
|
||||
warnAboutPrivate = true
|
||||
}
|
||||
}
|
||||
Queue.mainQueue().after(0.2, {
|
||||
if warnAboutPrivate {
|
||||
self.controllerInteraction?.displayUndo(.linkCopied(title: nil, text: presentationData.strings.Conversation_PrivateMessageLinkCopiedLong))
|
||||
} else {
|
||||
self.controllerInteraction?.displayUndo(.linkCopied(title: nil, text: presentationData.strings.Conversation_LinkCopied))
|
||||
}
|
||||
})
|
||||
})
|
||||
f(.default)
|
||||
})))
|
||||
}
|
||||
|
||||
self.canReadHistory.set(false)
|
||||
|
||||
//TODO:localize
|
||||
var sources: [ContextController.Source] = []
|
||||
sources.append(
|
||||
ContextController.Source(
|
||||
id: AnyHashable(OptionsId.item),
|
||||
title: "Option",
|
||||
footer: "You're viewing actions for one option.\nYou can switch to actions for the list.",
|
||||
source: .extracted(ChatTodoItemContextExtractedContentSource(chatNode: self.chatDisplayNode, contentNode: contentNode)),
|
||||
items: .single(ContextController.Items(content: .list(items)))
|
||||
)
|
||||
)
|
||||
|
||||
let messageContentSource = ChatMessageContextExtractedContentSource(chatController: self, chatNode: self.chatDisplayNode, engine: self.context.engine, message: message, selectAll: false, snapshot: true)
|
||||
|
||||
sources.append(
|
||||
ContextController.Source(
|
||||
id: AnyHashable(OptionsId.message),
|
||||
title: self.presentationData.strings.Chat_Todo_ContextMenu_SectionList,
|
||||
source: .extracted(messageContentSource),
|
||||
items: .single(actions)
|
||||
)
|
||||
)
|
||||
|
||||
contentNode.onDismiss = { [weak messageContentSource] in
|
||||
messageContentSource?.snapshotView?.removeFromSuperview()
|
||||
}
|
||||
|
||||
let contextController = makeContextController(
|
||||
presentationData: self.presentationData,
|
||||
configuration: ContextController.Configuration(
|
||||
sources: sources,
|
||||
initialId: AnyHashable(OptionsId.item)
|
||||
)
|
||||
)
|
||||
contextController.dismissed = { [weak self] in
|
||||
self?.canReadHistory.set(true)
|
||||
}
|
||||
|
||||
self.window?.presentInGlobalOverlay(contextController)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -29,9 +29,6 @@ extension ChatControllerImpl {
|
|||
|
||||
let completion = todo.completions.first(where: { $0.id == todoItemId })
|
||||
|
||||
// let recognizer: TapLongTapOrDoubleTapGestureRecognizer? = nil// anyRecognizer as? TapLongTapOrDoubleTapGestureRecognizer
|
||||
// let gesture: ContextGesture? = nil // anyRecognizer as? ContextGesture
|
||||
|
||||
var canMark = false
|
||||
if (todo.flags.contains(.othersCanComplete) || message.author?.id == context.account.peerId) {
|
||||
canMark = true
|
||||
|
|
@ -135,7 +132,7 @@ extension ChatControllerImpl {
|
|||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.interfaceInteraction?.setupReplyMessage(message.id, todoItem.id, { transition, completed in
|
||||
self.interfaceInteraction?.setupReplyMessage(message.id, .todoItem(todoItem.id), { transition, completed in
|
||||
c?.dismiss(result: .custom(transition), completion: {
|
||||
completed()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch
|
|||
quote = EngineMessageReplyQuote(text: trimmedText.string, offset: textSelection.offset, entities: trimmedText.entities, media: nil)
|
||||
}
|
||||
|
||||
selfController.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withUpdatedReplyMessageSubject(ChatInterfaceState.ReplyMessageSubject(messageId: replySubject.messageId, quote: quote, todoItemId: nil)).withoutSelectionState() }) })
|
||||
selfController.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withUpdatedReplyMessageSubject(ChatInterfaceState.ReplyMessageSubject(messageId: replySubject.messageId, quote: quote, innerSubject: nil)).withoutSelectionState() }) })
|
||||
}
|
||||
|
||||
let items = combineLatest(queue: .mainQueue(),
|
||||
|
|
@ -381,7 +381,7 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch
|
|||
quote = EngineMessageReplyQuote(text: trimmedText.string, offset: textSelection.offset, entities: trimmedText.entities, media: nil)
|
||||
}
|
||||
|
||||
selfController.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withUpdatedReplyMessageSubject(ChatInterfaceState.ReplyMessageSubject(messageId: replySubject.messageId, quote: quote, todoItemId: nil)).withoutSelectionState() }) })
|
||||
selfController.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withUpdatedReplyMessageSubject(ChatInterfaceState.ReplyMessageSubject(messageId: replySubject.messageId, quote: quote, innerSubject: nil)).withoutSelectionState() }) })
|
||||
|
||||
f(.default)
|
||||
})))
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ func updateChatPresentationInterfaceStateImpl(
|
|||
$0.withUpdatedReplyMessageSubject(ChatInterfaceState.ReplyMessageSubject(
|
||||
messageId: keyboardButtonsMessage.id,
|
||||
quote: nil,
|
||||
todoItemId: nil
|
||||
innerSubject: nil
|
||||
)).withUpdatedMessageActionsState({ value in
|
||||
var value = value
|
||||
value.processedSetupReplyMessageId = keyboardButtonsMessage.id
|
||||
|
|
@ -73,7 +73,7 @@ func updateChatPresentationInterfaceStateImpl(
|
|||
temporaryChatPresentationInterfaceState = temporaryChatPresentationInterfaceState.updatedInterfaceState({ $0.withUpdatedReplyMessageSubject(ChatInterfaceState.ReplyMessageSubject(
|
||||
messageId: keyboardButtonsMessage.id,
|
||||
quote: nil,
|
||||
todoItemId: nil
|
||||
innerSubject: nil
|
||||
)).withUpdatedMessageActionsState({ value in
|
||||
var value = value
|
||||
value.processedSetupReplyMessageId = keyboardButtonsMessage.id
|
||||
|
|
|
|||
|
|
@ -991,19 +991,19 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
case .pinnedMessageUpdated, .gameScore, .setSameChatWallpaper, .giveawayResults, .customText, .todoCompletions, .todoAppendTasks, .suggestedPostRefund, .suggestedPostSuccess, .suggestedPostApprovalStatus:
|
||||
for attribute in message.attributes {
|
||||
if let attribute = attribute as? ReplyMessageAttribute {
|
||||
var todoTaskId: Int32?
|
||||
var subject: EngineMessageReplyInnerSubject?
|
||||
if case let .todoCompletions(completed, incompleted) = action.action {
|
||||
if let completedTaskId = completed.first {
|
||||
todoTaskId = completedTaskId
|
||||
subject = .todoItem(completedTaskId)
|
||||
} else if let incompletedTaskId = incompleted.first {
|
||||
todoTaskId = incompletedTaskId
|
||||
subject = .todoItem(incompletedTaskId)
|
||||
}
|
||||
} else if case let .todoAppendTasks(tasks) = action.action {
|
||||
if let task = tasks.first {
|
||||
todoTaskId = task.id
|
||||
subject = .todoItem(task.id)
|
||||
}
|
||||
}
|
||||
self.navigateToMessage(from: message.id, to: .id(attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.isQuote ? attribute.quote.flatMap { quote in NavigateToMessageParams.Quote(string: quote.text, offset: quote.offset) } : nil, todoTaskId: todoTaskId)))
|
||||
self.navigateToMessage(from: message.id, to: .id(attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.isQuote ? attribute.quote.flatMap { quote in NavigateToMessageParams.Quote(string: quote.text, offset: quote.offset) } : nil, subject: subject)))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -1589,7 +1589,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
if isCaptionAbove {
|
||||
parameters = ChatSendMessageActionSheetController.SendParameters(effect: nil, textIsAboveMedia: true)
|
||||
}
|
||||
self.enqueueMediaMessages(signals: signals, silentPosting: false, replyToSubject: .init(messageId: message.id, quote: nil, todoItemId: nil), parameters: parameters)
|
||||
self.enqueueMediaMessages(signals: signals, silentPosting: false, replyToSubject: .init(messageId: message.id, quote: nil, innerSubject: nil), parameters: parameters)
|
||||
}
|
||||
}, present: { [weak self] c, a in
|
||||
self?.present(c, in: .window(.root), with: a)
|
||||
|
|
@ -3163,7 +3163,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
}
|
||||
var replyToMessageId: EngineMessageReplySubject?
|
||||
if postAsReply, let messageId {
|
||||
replyToMessageId = EngineMessageReplySubject(messageId: messageId, quote: nil, todoItemId: nil)
|
||||
replyToMessageId = EngineMessageReplySubject(messageId: messageId, quote: nil, innerSubject: nil)
|
||||
}
|
||||
strongSelf.sendMessages([.message(text: command, attributes: attributes, inlineStickers: [:], mediaReference: nil, threadId: strongSelf.chatLocation.threadId, replyToMessageId: replyToMessageId, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
|
||||
}
|
||||
|
|
@ -3283,6 +3283,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
return
|
||||
}
|
||||
self.openTodoItemContextMenu(todoItemId: todoItemId, params: params)
|
||||
}, pollOptionLongTap: { [weak self] optionId, params in
|
||||
guard let self, let params else {
|
||||
return
|
||||
}
|
||||
self.openPollOptionContextMenu(optionId: optionId, params: params)
|
||||
}, openCheckoutOrReceipt: { [weak self] messageId, params in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
|
|
@ -4018,7 +4023,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
let replySubject = ChatInterfaceState.ReplyMessageSubject(
|
||||
messageId: message.id,
|
||||
quote: quoteData,
|
||||
todoItemId: nil
|
||||
innerSubject: nil
|
||||
)
|
||||
if canSendMessagesToChat(strongSelf.presentationInterfaceState) {
|
||||
let _ = strongSelf.presentVoiceMessageDiscardAlert(action: {
|
||||
|
|
@ -8323,13 +8328,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
}
|
||||
case let .replyThread(replyThreadMessage):
|
||||
if let effectiveMessageId = replyThreadMessage.effectiveMessageId {
|
||||
defaultReplyMessageSubject = EngineMessageReplySubject(messageId: effectiveMessageId, quote: nil, todoItemId: nil)
|
||||
defaultReplyMessageSubject = EngineMessageReplySubject(messageId: effectiveMessageId, quote: nil, innerSubject: nil)
|
||||
}
|
||||
case .customChatContents:
|
||||
break
|
||||
}
|
||||
if let postSuggestionState = self.presentationInterfaceState.interfaceState.postSuggestionState, let editingOriginalMessageId = postSuggestionState.editingOriginalMessageId {
|
||||
defaultReplyMessageSubject = EngineMessageReplySubject(messageId: editingOriginalMessageId, quote: nil, todoItemId: nil)
|
||||
defaultReplyMessageSubject = EngineMessageReplySubject(messageId: editingOriginalMessageId, quote: nil, innerSubject: nil)
|
||||
}
|
||||
|
||||
return messages.map { message in
|
||||
|
|
@ -9127,7 +9132,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
if case .peer(peerId.id) = strongSelf.chatLocation {
|
||||
if let subject = subject, case let .message(messageSubject, highlight, timecode, _) = subject {
|
||||
if case let .id(messageId) = messageSubject {
|
||||
strongSelf.navigateToMessage(from: sourceMessageId, to: .id(messageId, NavigateToMessageParams(timestamp: timecode, quote: nil, todoTaskId: highlight?.todoTaskId)))
|
||||
strongSelf.navigateToMessage(from: sourceMessageId, to: .id(messageId, NavigateToMessageParams(timestamp: timecode, quote: nil, subject: highlight?.subject)))
|
||||
}
|
||||
} else {
|
||||
self?.playShakeAnimation()
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ extension ChatControllerImpl {
|
|||
return state.withUpdatedReplyMessageSubject(ChatInterfaceState.ReplyMessageSubject(
|
||||
messageId: message.id,
|
||||
quote: nil,
|
||||
todoItemId: nil
|
||||
innerSubject: nil
|
||||
))
|
||||
})
|
||||
if updatedState.inputMode == .none {
|
||||
|
|
@ -195,7 +195,7 @@ extension ChatControllerImpl {
|
|||
return ChatInterfaceState.ReplyMessageSubject(
|
||||
messageId: id,
|
||||
quote: nil,
|
||||
todoItemId: nil
|
||||
innerSubject: nil
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
@ -229,7 +229,7 @@ extension ChatControllerImpl {
|
|||
if replyMessageSubject.messageId == lastMessage?.id {
|
||||
updatedReplyMessageSubject = nil
|
||||
} else if let message = strongSelf.chatDisplayNode.historyNode.messageInCurrentHistoryView(after: replyMessageSubject.messageId) {
|
||||
updatedReplyMessageSubject = ChatInterfaceState.ReplyMessageSubject(messageId: message.id, quote: nil, todoItemId: nil)
|
||||
updatedReplyMessageSubject = ChatInterfaceState.ReplyMessageSubject(messageId: message.id, quote: nil, innerSubject: nil)
|
||||
}
|
||||
|
||||
strongSelf.updateChatPresentationInterfaceState(interactive: true, { state in
|
||||
|
|
|
|||
|
|
@ -656,7 +656,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
|||
mappedQuote = EngineMessageReplyQuote(text: quote, offset: nil, entities: [], media: nil)
|
||||
}
|
||||
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyMessage.id, threadMessageId: nil, quote: mappedQuote, isQuote: mappedQuote != nil, todoItemId: nil))
|
||||
attributes.append(ReplyMessageAttribute(messageId: replyMessage.id, threadMessageId: nil, quote: mappedQuote, isQuote: mappedQuote != nil, innerSubject: nil))
|
||||
}
|
||||
|
||||
let message = Message(
|
||||
|
|
|
|||
|
|
@ -1014,7 +1014,7 @@ public final class ChatHistoryListNodeImpl: ListViewImpl, ChatHistoryNode, ChatH
|
|||
initialSearchLocation = .index(MessageIndex.absoluteUpperBound())
|
||||
}
|
||||
}
|
||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: initialSearchLocation, quote: (highlight?.quote).flatMap { quote in MessageHistoryInitialSearchSubject.Quote(string: quote.string, offset: quote.offset) }, todoTaskId: highlight?.todoTaskId), count: historyMessageCount, highlight: highlight != nil, setupReply: setupReply), id: 0)
|
||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: initialSearchLocation, quote: (highlight?.quote).flatMap { quote in MessageHistoryInitialSearchSubject.Quote(string: quote.string, offset: quote.offset) }, subject: highlight?.subject), count: historyMessageCount, highlight: highlight != nil, setupReply: setupReply), id: 0)
|
||||
} else if let subject = subject, case let .pinnedMessages(maybeMessageId) = subject, let messageId = maybeMessageId {
|
||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(messageId)), count: historyMessageCount, highlight: true, setupReply: false), id: 0)
|
||||
} else {
|
||||
|
|
@ -1923,7 +1923,7 @@ public final class ChatHistoryListNodeImpl: ListViewImpl, ChatHistoryNode, ChatH
|
|||
initialSearchLocation = .index(.absoluteUpperBound())
|
||||
}
|
||||
}
|
||||
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: initialSearchLocation, quote: (highlight?.quote).flatMap { quote in MessageHistoryInitialSearchSubject.Quote(string: quote.string, offset: quote.offset) }, todoTaskId: highlight?.todoTaskId), count: historyMessageCount, highlight: highlight != nil, setupReply: setupReply), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0)
|
||||
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: initialSearchLocation, quote: (highlight?.quote).flatMap { quote in MessageHistoryInitialSearchSubject.Quote(string: quote.string, offset: quote.offset) }, subject: highlight?.subject), count: historyMessageCount, highlight: highlight != nil, setupReply: setupReply), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0)
|
||||
} else if let subject = subject, case let .pinnedMessages(maybeMessageId) = subject, let messageId = maybeMessageId {
|
||||
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(messageId)), count: historyMessageCount, highlight: true, setupReply: false), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0)
|
||||
} else if var chatHistoryLocation = strongSelf.chatHistoryLocationValue {
|
||||
|
|
@ -3489,8 +3489,8 @@ public final class ChatHistoryListNodeImpl: ListViewImpl, ChatHistoryNode, ChatH
|
|||
}
|
||||
}
|
||||
|
||||
public func scrollToMessage(from fromIndex: MessageIndex, to toIndex: MessageIndex, animated: Bool, highlight: Bool = true, quote: (string: String, offset: Int?)? = nil, todoTaskId: Int32? = nil, scrollPosition: ListViewScrollPosition = .center(.bottom), setupReply: Bool = false) {
|
||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .message(toIndex), quote: quote.flatMap { quote in MessageHistoryScrollToSubject.Quote(string: quote.string, offset: quote.offset) }, todoTaskId: todoTaskId, setupReply: setupReply), anchorIndex: .message(toIndex), sourceIndex: .message(fromIndex), scrollPosition: scrollPosition, animated: animated, highlight: highlight, setupReply: setupReply), id: self.takeNextHistoryLocationId())
|
||||
public func scrollToMessage(from fromIndex: MessageIndex, to toIndex: MessageIndex, animated: Bool, highlight: Bool = true, quote: (string: String, offset: Int?)? = nil, subject: EngineMessageReplyInnerSubject? = nil, scrollPosition: ListViewScrollPosition = .center(.bottom), setupReply: Bool = false) {
|
||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(subject: MessageHistoryScrollToSubject(index: .message(toIndex), quote: quote.flatMap { quote in MessageHistoryScrollToSubject.Quote(string: quote.string, offset: quote.offset) }, subject: subject, setupReply: setupReply), anchorIndex: .message(toIndex), sourceIndex: .message(fromIndex), scrollPosition: scrollPosition, animated: animated, highlight: highlight, setupReply: setupReply), id: self.takeNextHistoryLocationId())
|
||||
}
|
||||
|
||||
public func anchorMessageInCurrentHistoryView() -> Message? {
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ func chatHistoryViewForLocation(
|
|||
|
||||
preloaded = true
|
||||
|
||||
return .HistoryView(view: view, type: reportUpdateType, scrollPosition: .index(subject: MessageHistoryScrollToSubject(index: anchorIndex, quote: searchLocationSubject.quote.flatMap { quote in MessageHistoryScrollToSubject.Quote(string: quote.string, offset: quote.offset) }, todoTaskId: searchLocationSubject.todoTaskId, setupReply: setupReply), position: .center(.bottom), directionHint: .Down, animated: false, highlight: highlight, displayLink: false, setupReply: setupReply), flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData), id: location.id)
|
||||
return .HistoryView(view: view, type: reportUpdateType, scrollPosition: .index(subject: MessageHistoryScrollToSubject(index: anchorIndex, quote: searchLocationSubject.quote.flatMap { quote in MessageHistoryScrollToSubject.Quote(string: quote.string, offset: quote.offset) }, subject: searchLocationSubject.subject, setupReply: setupReply), position: .center(.bottom), directionHint: .Down, animated: false, highlight: highlight, displayLink: false, setupReply: setupReply), flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData), id: location.id)
|
||||
}
|
||||
}
|
||||
case let .Navigation(index, anchorIndex, count, _):
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ func textInputAccessoryPanel(
|
|||
contents: .reply(ChatInputMessageAccessoryPanel.Contents.Reply(
|
||||
id: replyMessageSubject.messageId,
|
||||
quote: replyMessageSubject.quote,
|
||||
todoItemId: replyMessageSubject.todoItemId,
|
||||
innerSubject: replyMessageSubject.innerSubject,
|
||||
message: nil
|
||||
)),
|
||||
chatPeerId: chatPeerId,
|
||||
|
|
@ -322,7 +322,7 @@ func accessoryPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceS
|
|||
}
|
||||
|
||||
if let chatPeerId {
|
||||
let panelNode = ReplyAccessoryPanelNode(context: context, chatPeerId: chatPeerId, messageId: replyMessageSubject.messageId, quote: replyMessageSubject.quote, todoItemId: replyMessageSubject.todoItemId, theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings, nameDisplayOrder: chatPresentationInterfaceState.nameDisplayOrder, dateTimeFormat: chatPresentationInterfaceState.dateTimeFormat, animationCache: chatControllerInteraction?.presentationContext.animationCache, animationRenderer: chatControllerInteraction?.presentationContext.animationRenderer)
|
||||
let panelNode = ReplyAccessoryPanelNode(context: context, chatPeerId: chatPeerId, messageId: replyMessageSubject.messageId, quote: replyMessageSubject.quote, innerSubject: replyMessageSubject.innerSubject, theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings, nameDisplayOrder: chatPresentationInterfaceState.nameDisplayOrder, dateTimeFormat: chatPresentationInterfaceState.dateTimeFormat, animationCache: chatControllerInteraction?.presentationContext.animationCache, animationRenderer: chatControllerInteraction?.presentationContext.animationRenderer)
|
||||
panelNode.interfaceInteraction = interfaceInteraction
|
||||
return panelNode
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu
|
|||
}, openConferenceCall: { _ in
|
||||
}, longTap: { _, _ in
|
||||
}, todoItemLongTap: { _, _ in
|
||||
}, pollOptionLongTap: { _, _ in
|
||||
}, openCheckoutOrReceipt: { _, _ in
|
||||
}, openSearch: {
|
||||
}, setupReply: { _ in
|
||||
|
|
|
|||
|
|
@ -230,10 +230,10 @@ func preparedChatHistoryViewTransition(from fromView: ChatHistoryView?, to toVie
|
|||
}
|
||||
return 0.0
|
||||
}))
|
||||
} else if let todoTaskId = scrollSubject.todoTaskId {
|
||||
} else if let subject = scrollSubject.subject {
|
||||
position = .center(.custom({ itemNode in
|
||||
if let itemNode = itemNode as? ChatMessageBubbleItemNode {
|
||||
if let taskRect = itemNode.getTodoTaskRect(id: todoTaskId) {
|
||||
if let taskRect = itemNode.getInnerReplySubjectRect(innerSubject: subject) {
|
||||
return taskRect.midY
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2416,6 +2416,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||
},
|
||||
todoItemLongTap: { _, _ in
|
||||
},
|
||||
pollOptionLongTap: { _, _ in
|
||||
},
|
||||
openCheckoutOrReceipt: { _, _ in
|
||||
},
|
||||
openSearch: {
|
||||
|
|
|
|||
|
|
@ -1143,7 +1143,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
|
|||
return .result(.replyThreadMessage(replyThreadMessage: result, messageId: messageId))
|
||||
})
|
||||
} else {
|
||||
return .single(.result(.peer(foundPeer._asPeer(), .chat(textInputState: nil, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil, todoTaskId: taskId), timecode: timecode, setupReply: false), peekData: nil))))
|
||||
return .single(.result(.peer(foundPeer._asPeer(), .chat(textInputState: nil, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil, subject: taskId.flatMap { .todoItem($0) }), timecode: timecode, setupReply: false), peekData: nil))))
|
||||
}
|
||||
} else {
|
||||
return .single(.result(.inaccessiblePeer))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue