diff --git a/submodules/AccountContext/Sources/ChatController.swift b/submodules/AccountContext/Sources/ChatController.swift index 764839370a..dec3611c54 100644 --- a/submodules/AccountContext/Sources/ChatController.swift +++ b/submodules/AccountContext/Sources/ChatController.swift @@ -27,10 +27,10 @@ public final class ChatMessageItemAssociatedData: Equatable { public let currentlyPlayingMessageId: EngineMessage.Index? public let isCopyProtectionEnabled: Bool public let availableReactions: AvailableReactions? - public let defaultReaction: String? + public let defaultReaction: MessageReaction.Reaction? public let isPremium: Bool - public init(automaticDownloadPeerType: MediaAutoDownloadPeerType, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, isRecentActions: Bool = false, subject: ChatControllerSubject? = nil, contactsPeerIds: Set = Set(), channelDiscussionGroup: ChannelDiscussionGroupStatus = .unknown, animatedEmojiStickers: [String: [StickerPackItem]] = [:], additionalAnimatedEmojiStickers: [String: [Int: StickerPackItem]] = [:], forcedResourceStatus: FileMediaResourceStatus? = nil, currentlyPlayingMessageId: EngineMessage.Index? = nil, isCopyProtectionEnabled: Bool = false, availableReactions: AvailableReactions?, defaultReaction: String?, isPremium: Bool) { + public init(automaticDownloadPeerType: MediaAutoDownloadPeerType, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, isRecentActions: Bool = false, subject: ChatControllerSubject? = nil, contactsPeerIds: Set = Set(), channelDiscussionGroup: ChannelDiscussionGroupStatus = .unknown, animatedEmojiStickers: [String: [StickerPackItem]] = [:], additionalAnimatedEmojiStickers: [String: [Int: StickerPackItem]] = [:], forcedResourceStatus: FileMediaResourceStatus? = nil, currentlyPlayingMessageId: EngineMessage.Index? = nil, isCopyProtectionEnabled: Bool = false, availableReactions: AvailableReactions?, defaultReaction: MessageReaction.Reaction?, isPremium: Bool) { self.automaticDownloadPeerType = automaticDownloadPeerType self.automaticDownloadNetworkType = automaticDownloadNetworkType self.isRecentActions = isRecentActions @@ -590,5 +590,5 @@ public enum FileMediaResourceMediaStatus: Equatable { } public protocol ChatMessageItemNodeProtocol: ListViewItemNode { - func targetReactionView(value: String) -> UIView? + func targetReactionView(value: MessageReaction.Reaction) -> UIView? } diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index 0b7fa1e30f..1287d19cc7 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -1127,7 +1127,12 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { if let attribute = messages.first?._asMessage().reactionsAttribute { loop: for recentPeer in attribute.recentPeers { if recentPeer.isUnseen { - messageText = item.presentationData.strings.ChatList_UserReacted(recentPeer.value).string + switch recentPeer.value { + case let .builtin(value): + messageText = item.presentationData.strings.ChatList_UserReacted(value).string + case .custom: + break + } break loop } } diff --git a/submodules/Components/ReactionButtonListComponent/Sources/ReactionButtonListComponent.swift b/submodules/Components/ReactionButtonListComponent/Sources/ReactionButtonListComponent.swift index 3550d08997..da45c7ac1f 100644 --- a/submodules/Components/ReactionButtonListComponent/Sources/ReactionButtonListComponent.swift +++ b/submodules/Components/ReactionButtonListComponent/Sources/ReactionButtonListComponent.swift @@ -35,16 +35,16 @@ public final class ReactionIconView: PortalSourceView { private final class ReactionImageCache { static let shared = ReactionImageCache() - private var images: [String: UIImage] = [:] + private var images: [MessageReaction.Reaction: UIImage] = [:] init() { } - func get(reaction: String) -> UIImage? { + func get(reaction: MessageReaction.Reaction) -> UIImage? { return self.images[reaction] } - func put(reaction: String, image: UIImage) { + func put(reaction: MessageReaction.Reaction, image: UIImage) { self.images[reaction] = image } } @@ -716,11 +716,11 @@ public final class ReactionButtonAsyncNode: ContextControllerSourceView { public final class ReactionButtonComponent: Equatable { public struct Reaction: Equatable { - public var value: String + public var value: MessageReaction.Reaction public var centerAnimation: TelegramMediaFile? public var legacyIcon: TelegramMediaFile? - public init(value: String, centerAnimation: TelegramMediaFile?, legacyIcon: TelegramMediaFile?) { + public init(value: MessageReaction.Reaction, centerAnimation: TelegramMediaFile?, legacyIcon: TelegramMediaFile?) { self.value = value self.centerAnimation = centerAnimation self.legacyIcon = legacyIcon @@ -771,7 +771,7 @@ public final class ReactionButtonComponent: Equatable { public let avatarPeers: [EnginePeer] public let count: Int public let isSelected: Bool - public let action: (String) -> Void + public let action: (MessageReaction.Reaction) -> Void public init( context: AccountContext, @@ -780,7 +780,7 @@ public final class ReactionButtonComponent: Equatable { avatarPeers: [EnginePeer], count: Int, isSelected: Bool, - action: @escaping (String) -> Void + action: @escaping (MessageReaction.Reaction) -> Void ) { self.context = context self.colors = colors @@ -888,7 +888,7 @@ public final class ReactionButtonsAsyncLayoutContainer { public struct ApplyResult { public struct Item { - public var value: String + public var value: MessageReaction.Reaction public var node: ReactionNodePool.Item public var size: CGSize } @@ -897,7 +897,7 @@ public final class ReactionButtonsAsyncLayoutContainer { public var removedNodes: [ReactionNodePool.Item] } - public private(set) var buttons: [String: ReactionNodePool.Item] = [:] + public private(set) var buttons: [MessageReaction.Reaction: ReactionNodePool.Item] = [:] public init() { } @@ -910,15 +910,15 @@ public final class ReactionButtonsAsyncLayoutContainer { public func update( context: AccountContext, - action: @escaping (String) -> Void, + action: @escaping (MessageReaction.Reaction) -> Void, reactions: [ReactionButtonsAsyncLayoutContainer.Reaction], colors: ReactionButtonComponent.Colors, constrainedWidth: CGFloat ) -> Result { var items: [Result.Item] = [] - var applyItems: [(key: String, size: CGSize, apply: (_ animation: ListViewItemUpdateAnimation) -> ReactionNodePool.Item)] = [] + var applyItems: [(key: MessageReaction.Reaction, size: CGSize, apply: (_ animation: ListViewItemUpdateAnimation) -> ReactionNodePool.Item)] = [] - var validIds = Set() + var validIds = Set() for reaction in reactions.sorted(by: { lhs, rhs in var lhsCount = lhs.count if lhs.isSelected { @@ -931,7 +931,7 @@ public final class ReactionButtonsAsyncLayoutContainer { if lhsCount != rhsCount { return lhsCount > rhsCount } - return lhs.reaction.value < rhs.reaction.value + return false }) { validIds.insert(reaction.reaction.value) @@ -962,7 +962,7 @@ public final class ReactionButtonsAsyncLayoutContainer { applyItems.append((reaction.reaction.value, size, apply)) } - var removeIds: [String] = [] + var removeIds: [MessageReaction.Reaction] = [] for (id, _) in self.buttons { if !validIds.contains(id) { removeIds.append(id) diff --git a/submodules/Components/ReactionImageComponent/Sources/ReactionImageComponent.swift b/submodules/Components/ReactionImageComponent/Sources/ReactionImageComponent.swift index ee53100d74..91fdea753c 100644 --- a/submodules/Components/ReactionImageComponent/Sources/ReactionImageComponent.swift +++ b/submodules/Components/ReactionImageComponent/Sources/ReactionImageComponent.swift @@ -65,7 +65,7 @@ public final class ReactionImageNode: ASDisplayNode { private let iconNode: ASImageNode - public init(context: AccountContext, availableReactions: AvailableReactions?, reaction: String, displayPixelSize: CGSize) { + public init(context: AccountContext, availableReactions: AvailableReactions?, reaction: MessageReaction.Reaction, displayPixelSize: CGSize) { self.iconNode = ASImageNode() var file: TelegramMediaFile? diff --git a/submodules/Components/ReactionListContextMenuContent/Sources/ReactionListContextMenuContent.swift b/submodules/Components/ReactionListContextMenuContent/Sources/ReactionListContextMenuContent.swift index 0a1127c202..d66b8916e1 100644 --- a/submodules/Components/ReactionListContextMenuContent/Sources/ReactionListContextMenuContent.swift +++ b/submodules/Components/ReactionListContextMenuContent/Sources/ReactionListContextMenuContent.swift @@ -106,7 +106,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent private final class ReactionTabListNode: ASDisplayNode { private final class ItemNode: ASDisplayNode { let context: AccountContext - let reaction: String? + let reaction: MessageReaction.Reaction? let count: Int let titleLabelNode: ImmediateTextNode @@ -115,9 +115,9 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent private var theme: PresentationTheme? - var action: ((String?) -> Void)? + var action: ((MessageReaction.Reaction?) -> Void)? - init(context: AccountContext, availableReactions: AvailableReactions?, reaction: String?, count: Int) { + init(context: AccountContext, availableReactions: AvailableReactions?, reaction: MessageReaction.Reaction?, count: Int) { self.context = context self.reaction = reaction self.count = count @@ -195,13 +195,13 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent private let itemNodes: [ItemNode] struct ScrollToTabReaction { - var value: String? + var value: MessageReaction.Reaction? } var scrollToTabReaction: ScrollToTabReaction? - var action: ((String?) -> Void)? + var action: ((MessageReaction.Reaction?) -> Void)? - init(context: AccountContext, availableReactions: AvailableReactions?, reactions: [(String?, Int)], message: EngineMessage) { + init(context: AccountContext, availableReactions: AvailableReactions?, reactions: [(MessageReaction.Reaction?, Int)], message: EngineMessage) { self.scrollNode = ASScrollNode() self.scrollNode.canCancelAllTouchesInViews = true self.scrollNode.view.delaysContentTouches = false @@ -236,7 +236,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent } } - func update(size: CGSize, presentationData: PresentationData, selectedReaction: String?, transition: ContainedViewLayoutTransition) { + func update(size: CGSize, presentationData: PresentationData, selectedReaction: MessageReaction.Reaction?, transition: ContainedViewLayoutTransition) { let sideInset: CGFloat = 11.0 let spacing: CGFloat = 0.0 let verticalInset: CGFloat = 7.0 @@ -352,7 +352,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent let avatarSize: CGFloat = 28.0 let sideInset: CGFloat = 16.0 - let reaction: String? = item.reaction + let reaction: MessageReaction.Reaction? = item.reaction if let reaction = reaction { if self.reactionIconNode == nil { let reactionIconNode = ReactionImageNode(context: self.context, availableReactions: self.availableReactions, reaction: reaction, displayPixelSize: CGSize(width: 30.0 * UIScreenScale, height: 30.0 * UIScreenScale)) @@ -366,7 +366,18 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent if self.item != item { self.item = item - self.accessibilityLabel = "\(item.peer.debugDisplayTitle) \(item.reaction ?? "")" + let reactionStringValue: String + if let reaction = item.reaction { + switch reaction { + case let .builtin(value): + reactionStringValue = value + case .custom: + reactionStringValue = "" + } + } else { + reactionStringValue = "" + } + self.accessibilityLabel = "\(item.peer.debugDisplayTitle) \(reactionStringValue)" } let premiumConfiguration = PremiumConfiguration.with(appConfiguration: self.context.currentAppConfiguration.with { $0 }) @@ -488,7 +499,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent private let context: AccountContext private let availableReactions: AvailableReactions? - let reaction: String? + let reaction: MessageReaction.Reaction? private let requestUpdate: (ReactionsTabNode, ContainedViewLayoutTransition) -> Void private let requestUpdateApparentHeight: (ReactionsTabNode, ContainedViewLayoutTransition) -> Void private let openPeer: (PeerId) -> Void @@ -516,7 +527,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent context: AccountContext, availableReactions: AvailableReactions?, message: EngineMessage, - reaction: String?, + reaction: MessageReaction.Reaction?, readStats: MessageReadStats?, requestUpdate: @escaping (ReactionsTabNode, ContainedViewLayoutTransition) -> Void, requestUpdateApparentHeight: @escaping (ReactionsTabNode, ContainedViewLayoutTransition) -> Void, @@ -754,7 +765,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent private let availableReactions: AvailableReactions? private let message: EngineMessage private let readStats: MessageReadStats? - private let reactions: [(String?, Int)] + private let reactions: [(MessageReaction.Reaction?, Int)] private let requestUpdate: (ContainedViewLayoutTransition) -> Void private let requestUpdateApparentHeight: (ContainedViewLayoutTransition) -> Void @@ -781,7 +792,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent context: AccountContext, availableReactions: AvailableReactions?, message: EngineMessage, - reaction: String?, + reaction: MessageReaction.Reaction?, readStats: MessageReadStats?, requestUpdate: @escaping (ContainedViewLayoutTransition) -> Void, requestUpdateApparentHeight: @escaping (ContainedViewLayoutTransition) -> Void, @@ -808,7 +819,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent } } - var reactions: [(String?, Int)] = [] + var reactions: [(MessageReaction.Reaction?, Int)] = [] var totalCount: Int = 0 if let reactionsAttribute = message._asMessage().reactionsAttribute { for listReaction in reactionsAttribute.reactions { @@ -967,7 +978,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent } if let tabListNode = self.tabListNode { let tabListFrame = CGRect(origin: CGPoint(x: 0.0, y: topContentHeight), size: CGSize(width: constrainedSize.width, height: 44.0)) - let selectedReaction: String? = self.reactions[self.currentTabIndex].0 + let selectedReaction: MessageReaction.Reaction? = self.reactions[self.currentTabIndex].0 tabListNode.update(size: tabListFrame.size, presentationData: self.presentationData, selectedReaction: selectedReaction, transition: transition) transition.updateFrame(node: tabListNode, frame: tabListFrame) topContentHeight += tabListFrame.height @@ -1124,7 +1135,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent let context: AccountContext let availableReactions: AvailableReactions? let message: EngineMessage - let reaction: String? + let reaction: MessageReaction.Reaction? let readStats: MessageReadStats? let back: (() -> Void)? let openPeer: (PeerId) -> Void @@ -1133,7 +1144,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent context: AccountContext, availableReactions: AvailableReactions?, message: EngineMessage, - reaction: String?, + reaction: MessageReaction.Reaction?, readStats: MessageReadStats?, back: (() -> Void)?, openPeer: @escaping (PeerId) -> Void diff --git a/submodules/ContextUI/Sources/ContextController.swift b/submodules/ContextUI/Sources/ContextController.swift index 579a9befd4..13d21e0ed8 100644 --- a/submodules/ContextUI/Sources/ContextController.swift +++ b/submodules/ContextUI/Sources/ContextController.swift @@ -1432,7 +1432,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi } } - func animateOutToReaction(value: String, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: @escaping () -> Void) { + func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: @escaping () -> Void) { if let presentationNode = self.presentationNode { presentationNode.animateOutToReaction(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, completion: completion) return @@ -2643,7 +2643,7 @@ public final class ContextController: ViewController, StandalonePresentableContr self.dismissed?() } - public func dismissWithReaction(value: String, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: (() -> Void)?) { + public func dismissWithReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: (() -> Void)?) { if !self.wasDismissed { self.wasDismissed = true self.controllerNode.animateOutToReaction(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, completion: { [weak self] in diff --git a/submodules/ContextUI/Sources/ContextControllerExtractedPresentationNode.swift b/submodules/ContextUI/Sources/ContextControllerExtractedPresentationNode.swift index ca4a75a0d0..59bdc6c691 100644 --- a/submodules/ContextUI/Sources/ContextControllerExtractedPresentationNode.swift +++ b/submodules/ContextUI/Sources/ContextControllerExtractedPresentationNode.swift @@ -990,7 +990,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo } } - func animateOutToReaction(value: String, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: @escaping () -> Void) { + func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: @escaping () -> Void) { guard let reactionContextNode = self.reactionContextNode else { self.requestAnimateOut(.default, completion) return diff --git a/submodules/ContextUI/Sources/ContextControllerPresentationNode.swift b/submodules/ContextUI/Sources/ContextControllerPresentationNode.swift index 2d79af8384..d9a4a625c6 100644 --- a/submodules/ContextUI/Sources/ContextControllerPresentationNode.swift +++ b/submodules/ContextUI/Sources/ContextControllerPresentationNode.swift @@ -25,7 +25,7 @@ protocol ContextControllerPresentationNode: ASDisplayNode { stateTransition: ContextControllerPresentationNodeStateTransition? ) - func animateOutToReaction(value: String, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: @escaping () -> Void) + func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: @escaping () -> Void) func cancelReactionAnimation() func highlightGestureMoved(location: CGPoint, hover: Bool) diff --git a/submodules/PeerInfoUI/Sources/ItemListReactionItem.swift b/submodules/PeerInfoUI/Sources/ItemListReactionItem.swift index 75d8a7f12a..2ade5e10e9 100644 --- a/submodules/PeerInfoUI/Sources/ItemListReactionItem.swift +++ b/submodules/PeerInfoUI/Sources/ItemListReactionItem.swift @@ -14,7 +14,7 @@ public class ItemListReactionItem: ListViewItem, ItemListItem { let context: AccountContext let presentationData: ItemListPresentationData let availableReactions: AvailableReactions? - let reaction: String + let reaction: MessageReaction.Reaction let title: String let value: Bool let enabled: Bool @@ -27,7 +27,7 @@ public class ItemListReactionItem: ListViewItem, ItemListItem { context: AccountContext, presentationData: ItemListPresentationData, availableReactions: AvailableReactions?, - reaction: String, + reaction: MessageReaction.Reaction, title: String, value: Bool, enabled: Bool = true, diff --git a/submodules/PeerInfoUI/Sources/PeerAllowedReactionListController.swift b/submodules/PeerInfoUI/Sources/PeerAllowedReactionListController.swift index c759ea7895..6776bd02b4 100644 --- a/submodules/PeerInfoUI/Sources/PeerAllowedReactionListController.swift +++ b/submodules/PeerInfoUI/Sources/PeerAllowedReactionListController.swift @@ -15,12 +15,12 @@ import PresentationDataUtils private final class PeerAllowedReactionListControllerArguments { let context: AccountContext let toggleAll: () -> Void - let toggleItem: (String) -> Void + let toggleItem: (MessageReaction.Reaction) -> Void init( context: AccountContext, toggleAll: @escaping () -> Void, - toggleItem: @escaping (String) -> Void + toggleItem: @escaping (MessageReaction.Reaction) -> Void ) { self.context = context self.toggleAll = toggleAll @@ -38,14 +38,14 @@ private enum PeerAllowedReactionListControllerEntry: ItemListNodeEntry { case allowAll case allowAllInfo case itemsHeader - case item(String) + case item(MessageReaction.Reaction) } case allowAll(text: String, isEnabled: Bool) case allowAllInfo(String) case itemsHeader(String) - case item(index: Int, value: String, availableReactions: AvailableReactions?, reaction: String, text: String, isEnabled: Bool) + case item(index: Int, value: MessageReaction.Reaction, availableReactions: AvailableReactions?, reaction: MessageReaction.Reaction, text: String, isEnabled: Bool) var section: ItemListSectionId { switch self { @@ -145,7 +145,7 @@ private enum PeerAllowedReactionListControllerEntry: ItemListNodeEntry { } private struct PeerAllowedReactionListControllerState: Equatable { - var updatedAllowedReactions: Set? = nil + var updatedAllowedReactions: Set? = nil } private func peerAllowedReactionListControllerEntries( diff --git a/submodules/Postbox/Sources/Coding.swift b/submodules/Postbox/Sources/Coding.swift index 00544eb6b2..aac8208b6a 100644 --- a/submodules/Postbox/Sources/Coding.swift +++ b/submodules/Postbox/Sources/Coding.swift @@ -661,6 +661,26 @@ public final class PostboxEncoder { let (data, valueType) = innerEncoder.makeData(addHeader: true, isDictionary: false) self.encodeInnerObjectData(data, valueType: valueType, forKey: key) } + + public func encodeArray(_ value: [T], forKey key: String) { + self.encodeKey(key) + var t: Int8 = ValueType.ObjectArray.rawValue + self.buffer.write(&t, offset: 0, length: 1) + var length: Int32 = Int32(value.count) + self.buffer.write(&length, offset: 0, length: 4) + + for object in value { + let typeHash: Int32 = murMurHashString32("\(type(of: object))") + let innerEncoder = _AdaptedPostboxEncoder(typeHash: typeHash) + try! object.encode(to: innerEncoder) + + let (data, _) = innerEncoder.makeData(addHeader: true, isDictionary: false) + + var length: Int32 = Int32(data.count) + self.buffer.write(&length, offset: 0, length: 4) + self.buffer.write(data) + } + } func encodeInnerObjectData(_ value: Data, valueType: ValueType, forKey key: String) { self.encodeKey(key) @@ -1814,4 +1834,44 @@ public final class PostboxDecoder { return nil } } + + public func decodeArray(_ type: [T].Type, forKey key: String) -> [T]? { + if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectArray) { + var length: Int32 = 0 + memcpy(&length, self.buffer.memory + self.offset, 4) + self.offset += 4 + + var array: [T] = [] + array.reserveCapacity(Int(length)) + + var i: Int32 = 0 + while i < length { + var typeHash: Int32 = 0 + memcpy(&typeHash, self.buffer.memory + self.offset, 4) + self.offset += 4 + + var objectLength: Int32 = 0 + memcpy(&objectLength, self.buffer.memory + self.offset, 4) + + let innerBuffer = ReadBuffer(memory: self.buffer.memory + (self.offset + 4), length: Int(objectLength), freeWhenDone: false) + let innerData = innerBuffer.makeData() + self.offset += 4 + Int(length) + + do { + let result = try AdaptedPostboxDecoder().decode(T.self, from: innerData) + array.append(result) + } catch let error { + postboxLog("Decoding error: \(error)") + //assertionFailure("Decoding error: \(error)") + return nil + } + + i += 1 + } + + return array + } else { + return nil + } + } } diff --git a/submodules/Postbox/Sources/PreferencesEntry.swift b/submodules/Postbox/Sources/PreferencesEntry.swift index 125a6ed5ae..09ad00e905 100644 --- a/submodules/Postbox/Sources/PreferencesEntry.swift +++ b/submodules/Postbox/Sources/PreferencesEntry.swift @@ -68,7 +68,7 @@ public final class PreferencesEntry: Equatable { public func get(_ type: T.Type) -> T? { let decoder = PostboxDecoder(buffer: MemoryBuffer(data: self.data)) let result = decoder.decode(T.self, forKey: "_") - assert(result != nil) + //assert(result != nil) return result } diff --git a/submodules/PremiumUI/Sources/PremiumDemoScreen.swift b/submodules/PremiumUI/Sources/PremiumDemoScreen.swift index e84f034deb..3725b2ad2c 100644 --- a/submodules/PremiumUI/Sources/PremiumDemoScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumDemoScreen.swift @@ -569,7 +569,7 @@ private final class DemoSheetContent: CombinedComponent { stickerOverrideMessages ) |> map { reactions, items, data, reactionOverrideMessages, stickerOverrideMessages -> ([AvailableReactions.Reaction], [TelegramMediaFile], Bool?, PremiumPromoConfiguration?) in - var reactionOverrides: [String: TelegramMediaFile] = [:] + var reactionOverrides: [MessageReaction.Reaction: TelegramMediaFile] = [:] for item in accountSpecificReactionOverrides { if let maybeMessage = reactionOverrideMessages[item.messageId], let message = maybeMessage { for media in message.media { @@ -580,7 +580,7 @@ private final class DemoSheetContent: CombinedComponent { } } - var stickerOverrides: [String: TelegramMediaFile] = [:] + var stickerOverrides: [MessageReaction.Reaction: TelegramMediaFile] = [:] for item in accountSpecificStickerOverrides { if let maybeMessage = stickerOverrideMessages[item.messageId], let message = maybeMessage { for media in message.media { @@ -623,7 +623,7 @@ private final class DemoSheetContent: CombinedComponent { for attribute in file.attributes { switch attribute { case let .Sticker(displayText, _, _): - if let replacementFile = stickerOverrides[displayText], let dimensions = replacementFile.dimensions { + if let replacementFile = stickerOverrides[.builtin(displayText)], let dimensions = replacementFile.dimensions { let _ = dimensions return TelegramMediaFile( fileId: file.fileId, diff --git a/submodules/PremiumUI/Sources/ReactionsCarouselComponent.swift b/submodules/PremiumUI/Sources/ReactionsCarouselComponent.swift index 8a8c172e7a..740e05f6f8 100644 --- a/submodules/PremiumUI/Sources/ReactionsCarouselComponent.swift +++ b/submodules/PremiumUI/Sources/ReactionsCarouselComponent.swift @@ -121,17 +121,17 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate { self.context = context self.theme = theme - var reactionMap: [String: AvailableReactions.Reaction] = [:] + var reactionMap: [MessageReaction.Reaction: AvailableReactions.Reaction] = [:] for reaction in reactions { reactionMap[reaction.value] = reaction } - var addedReactions = Set() + var addedReactions = Set() var sortedReactions: [AvailableReactions.Reaction] = [] for emoji in order { - if let reaction = reactionMap[emoji] { + if let reaction = reactionMap[.builtin(emoji)] { sortedReactions.append(reaction) - addedReactions.insert(emoji) + addedReactions.insert(.builtin(emoji)) } } diff --git a/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift b/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift index bafc9be91e..4b25931b24 100644 --- a/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift +++ b/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift @@ -18,9 +18,9 @@ import ComponentDisplayAdapters public final class ReactionItem { public struct Reaction: Equatable { - public var rawValue: String + public var rawValue: MessageReaction.Reaction - public init(rawValue: String) { + public init(rawValue: MessageReaction.Reaction) { self.rawValue = rawValue } } @@ -728,7 +728,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate { itemNode.layer.animateScale(from: 1.0, to: (targetSnapshotView.bounds.width * 1.0) / itemNode.bounds.width, duration: duration, removeOnCompletion: false) } - public func willAnimateOutToReaction(value: String) { + public func willAnimateOutToReaction(value: MessageReaction.Reaction) { for (_, itemNode) in self.visibleItemNodes { if let itemNode = itemNode as? ReactionNode, itemNode.item.reaction.rawValue == value { itemNode.isExtracted = true @@ -736,7 +736,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate { } } - public func animateOutToReaction(value: String, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: @escaping () -> Void) { + public func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: @escaping () -> Void) { var foundItemNode: ReactionNode? for (_, itemNode) in self.visibleItemNodes { if let itemNode = itemNode as? ReactionNode, itemNode.item.reaction.rawValue == value { diff --git a/submodules/SettingsUI/Sources/Reactions/QuickReactionSetupController.swift b/submodules/SettingsUI/Sources/Reactions/QuickReactionSetupController.swift index 7958de0f31..d461d01f24 100644 --- a/submodules/SettingsUI/Sources/Reactions/QuickReactionSetupController.swift +++ b/submodules/SettingsUI/Sources/Reactions/QuickReactionSetupController.swift @@ -15,12 +15,12 @@ import WebPBinding private final class QuickReactionSetupControllerArguments { let context: AccountContext - let selectItem: (String) -> Void + let selectItem: (MessageReaction.Reaction) -> Void let toggleReaction: () -> Void init( context: AccountContext, - selectItem: @escaping (String) -> Void, + selectItem: @escaping (MessageReaction.Reaction) -> Void, toggleReaction: @escaping () -> Void ) { self.context = context @@ -40,14 +40,14 @@ private enum QuickReactionSetupControllerEntry: ItemListNodeEntry { case demoMessage case demoDescription case itemsHeader - case item(String) + case item(MessageReaction.Reaction) } case demoHeader(String) - case demoMessage(wallpaper: TelegramWallpaper, fontSize: PresentationFontSize, bubbleCorners: PresentationChatBubbleCorners, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, availableReactions: AvailableReactions?, reaction: String?) + case demoMessage(wallpaper: TelegramWallpaper, fontSize: PresentationFontSize, bubbleCorners: PresentationChatBubbleCorners, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, availableReactions: AvailableReactions?, reaction: MessageReaction.Reaction?) case demoDescription(String) case itemsHeader(String) - case item(index: Int, value: String, image: UIImage?, imageIsAnimation: Bool, text: String, isSelected: Bool) + case item(index: Int, value: MessageReaction.Reaction, image: UIImage?, imageIsAnimation: Bool, text: String, isSelected: Bool) var section: ItemListSectionId { switch self { @@ -184,7 +184,7 @@ private struct QuickReactionSetupControllerState: Equatable { private func quickReactionSetupControllerEntries( presentationData: PresentationData, availableReactions: AvailableReactions?, - images: [String: (image: UIImage, isAnimation: Bool)], + images: [MessageReaction.Reaction: (image: UIImage, isAnimation: Bool)], reactionSettings: ReactionSettings, state: QuickReactionSetupControllerState, isPremium: Bool @@ -275,9 +275,9 @@ public func quickReactionSetupController( return reactionSettings } - let images: Signal<[String: (image: UIImage, isAnimation: Bool)], NoError> = context.engine.stickers.availableReactions() - |> mapToSignal { availableReactions -> Signal<[String: (image: UIImage, isAnimation: Bool)], NoError> in - var signals: [Signal<(String, (image: UIImage, isAnimation: Bool)?), NoError>] = [] + let images: Signal<[MessageReaction.Reaction: (image: UIImage, isAnimation: Bool)], NoError> = context.engine.stickers.availableReactions() + |> mapToSignal { availableReactions -> Signal<[MessageReaction.Reaction: (image: UIImage, isAnimation: Bool)], NoError> in + var signals: [Signal<(MessageReaction.Reaction, (image: UIImage, isAnimation: Bool)?), NoError>] = [] if let availableReactions = availableReactions { for availableReaction in availableReactions.reactions { @@ -285,8 +285,8 @@ public func quickReactionSetupController( continue } if let centerAnimation = availableReaction.centerAnimation { - let signal: Signal<(String, (image: UIImage, isAnimation: Bool)?), NoError> = reactionStaticImage(context: context, animation: centerAnimation, pixelSize: CGSize(width: 72.0 * 2.0, height: 72.0 * 2.0)) - |> map { data -> (String, (image: UIImage, isAnimation: Bool)?) in + let signal: Signal<(MessageReaction.Reaction, (image: UIImage, isAnimation: Bool)?), NoError> = reactionStaticImage(context: context, animation: centerAnimation, pixelSize: CGSize(width: 72.0 * 2.0, height: 72.0 * 2.0)) + |> map { data -> (MessageReaction.Reaction, (image: UIImage, isAnimation: Bool)?) in guard data.isComplete else { return (availableReaction.value, nil) } @@ -300,8 +300,8 @@ public func quickReactionSetupController( } signals.append(signal) } else { - let signal: Signal<(String, (image: UIImage, isAnimation: Bool)?), NoError> = context.account.postbox.mediaBox.resourceData(availableReaction.staticIcon.resource) - |> map { data -> (String, (image: UIImage, isAnimation: Bool)?) in + let signal: Signal<(MessageReaction.Reaction, (image: UIImage, isAnimation: Bool)?), NoError> = context.account.postbox.mediaBox.resourceData(availableReaction.staticIcon.resource) + |> map { data -> (MessageReaction.Reaction, (image: UIImage, isAnimation: Bool)?) in guard data.complete else { return (availableReaction.value, nil) } @@ -320,8 +320,8 @@ public func quickReactionSetupController( } return combineLatest(queue: .mainQueue(), signals) - |> map { values -> [String: (image: UIImage, isAnimation: Bool)] in - var dict: [String: (image: UIImage, isAnimation: Bool)] = [:] + |> map { values -> [MessageReaction.Reaction: (image: UIImage, isAnimation: Bool)] in + var dict: [MessageReaction.Reaction: (image: UIImage, isAnimation: Bool)] = [:] for (key, image) in values { if let image = image { dict[key] = image diff --git a/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift b/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift index 05b05784e1..031f213a58 100644 --- a/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift @@ -24,10 +24,10 @@ class ReactionChatPreviewItem: ListViewItem, ItemListItem { let dateTimeFormat: PresentationDateTimeFormat let nameDisplayOrder: PresentationPersonNameOrder let availableReactions: AvailableReactions? - let reaction: String? + let reaction: MessageReaction.Reaction? let toggleReaction: () -> Void - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, fontSize: PresentationFontSize, chatBubbleCorners: PresentationChatBubbleCorners, wallpaper: TelegramWallpaper, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, availableReactions: AvailableReactions?, reaction: String?, toggleReaction: @escaping () -> Void) { + init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, fontSize: PresentationFontSize, chatBubbleCorners: PresentationChatBubbleCorners, wallpaper: TelegramWallpaper, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, availableReactions: AvailableReactions?, reaction: MessageReaction.Reaction?, toggleReaction: @escaping () -> Void) { self.context = context self.theme = theme self.strings = strings diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index 0b60cbaac5..fa06a4f9f7 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -166,7 +166,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[476978193] = { return Api.ChatPhoto.parse_chatPhoto($0) } dict[935395612] = { return Api.ChatPhoto.parse_chatPhotoEmpty($0) } dict[-1973130814] = { return Api.CodeSettings.parse_codeSettings($0) } - dict[856375399] = { return Api.Config.parse_config($0) } + dict[589653676] = { return Api.Config.parse_config($0) } dict[341499403] = { return Api.Contact.parse_contact($0) } dict[383348795] = { return Api.ContactStatus.parse_contactStatus($0) } dict[2104790276] = { return Api.DataJSON.parse_dataJSON($0) } @@ -477,7 +477,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-1618676578] = { return Api.MessageMedia.parse_messageMediaUnsupported($0) } dict[784356159] = { return Api.MessageMedia.parse_messageMediaVenue($0) } dict[-1557277184] = { return Api.MessageMedia.parse_messageMediaWebPage($0) } - dict[1370914559] = { return Api.MessagePeerReaction.parse_messagePeerReaction($0) } + dict[-1319698788] = { return Api.MessagePeerReaction.parse_messagePeerReaction($0) } dict[182649427] = { return Api.MessageRange.parse_messageRange($0) } dict[1328256121] = { return Api.MessageReactions.parse_messageReactions($0) } dict[-2083123262] = { return Api.MessageReplies.parse_messageReplies($0) } @@ -609,7 +609,10 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[1103656293] = { return Api.PrivacyRule.parse_privacyValueDisallowChatParticipants($0) } dict[-125240806] = { return Api.PrivacyRule.parse_privacyValueDisallowContacts($0) } dict[-463335103] = { return Api.PrivacyRule.parse_privacyValueDisallowUsers($0) } - dict[1873957073] = { return Api.ReactionCount.parse_reactionCount($0) } + dict[-1992950669] = { return Api.Reaction.parse_reactionCustomEmoji($0) } + dict[455247544] = { return Api.Reaction.parse_reactionEmoji($0) } + dict[2046153753] = { return Api.Reaction.parse_reactionEmpty($0) } + dict[609529328] = { return Api.ReactionCount.parse_reactionCount($0) } dict[-1551583367] = { return Api.ReceivedNotifyMessage.parse_receivedNotifyMessage($0) } dict[-1294306862] = { return Api.RecentMeUrl.parse_recentMeUrlChat($0) } dict[-347535331] = { return Api.RecentMeUrl.parse_recentMeUrlChatInvite($0) } @@ -1489,6 +1492,8 @@ public extension Api { _1.serialize(buffer, boxed) case let _1 as Api.PrivacyRule: _1.serialize(buffer, boxed) + case let _1 as Api.Reaction: + _1.serialize(buffer, boxed) case let _1 as Api.ReactionCount: _1.serialize(buffer, boxed) case let _1 as Api.ReceivedNotifyMessage: diff --git a/submodules/TelegramApi/Sources/Api13.swift b/submodules/TelegramApi/Sources/Api13.swift index af91a1bec8..fbbd71a592 100644 --- a/submodules/TelegramApi/Sources/Api13.swift +++ b/submodules/TelegramApi/Sources/Api13.swift @@ -1,16 +1,16 @@ public extension Api { enum MessagePeerReaction: TypeConstructorDescription { - case messagePeerReaction(flags: Int32, peerId: Api.Peer, reaction: String) + case messagePeerReaction(flags: Int32, peerId: Api.Peer, reaction: Api.Reaction) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { case .messagePeerReaction(let flags, let peerId, let reaction): if boxed { - buffer.appendInt32(1370914559) + buffer.appendInt32(-1319698788) } serializeInt32(flags, buffer: buffer, boxed: false) peerId.serialize(buffer, true) - serializeString(reaction, buffer: buffer, boxed: false) + reaction.serialize(buffer, true) break } } @@ -29,8 +29,10 @@ public extension Api { if let signature = reader.readInt32() { _2 = Api.parse(reader, signature: signature) as? Api.Peer } - var _3: String? - _3 = parseString(reader) + var _3: Api.Reaction? + if let signature = reader.readInt32() { + _3 = Api.parse(reader, signature: signature) as? Api.Reaction + } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = _3 != nil diff --git a/submodules/TelegramApi/Sources/Api17.swift b/submodules/TelegramApi/Sources/Api17.swift index 6fbc72af8f..f21b0d678e 100644 --- a/submodules/TelegramApi/Sources/Api17.swift +++ b/submodules/TelegramApi/Sources/Api17.swift @@ -1,15 +1,83 @@ +public extension Api { + enum Reaction: TypeConstructorDescription { + case reactionCustomEmoji(documentId: Int64) + case reactionEmoji(emoticon: String) + case reactionEmpty + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .reactionCustomEmoji(let documentId): + if boxed { + buffer.appendInt32(-1992950669) + } + serializeInt64(documentId, buffer: buffer, boxed: false) + break + case .reactionEmoji(let emoticon): + if boxed { + buffer.appendInt32(455247544) + } + serializeString(emoticon, buffer: buffer, boxed: false) + break + case .reactionEmpty: + if boxed { + buffer.appendInt32(2046153753) + } + + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .reactionCustomEmoji(let documentId): + return ("reactionCustomEmoji", [("documentId", String(describing: documentId))]) + case .reactionEmoji(let emoticon): + return ("reactionEmoji", [("emoticon", String(describing: emoticon))]) + case .reactionEmpty: + return ("reactionEmpty", []) + } + } + + public static func parse_reactionCustomEmoji(_ reader: BufferReader) -> Reaction? { + var _1: Int64? + _1 = reader.readInt64() + let _c1 = _1 != nil + if _c1 { + return Api.Reaction.reactionCustomEmoji(documentId: _1!) + } + else { + return nil + } + } + public static func parse_reactionEmoji(_ reader: BufferReader) -> Reaction? { + var _1: String? + _1 = parseString(reader) + let _c1 = _1 != nil + if _c1 { + return Api.Reaction.reactionEmoji(emoticon: _1!) + } + else { + return nil + } + } + public static func parse_reactionEmpty(_ reader: BufferReader) -> Reaction? { + return Api.Reaction.reactionEmpty + } + + } +} public extension Api { enum ReactionCount: TypeConstructorDescription { - case reactionCount(flags: Int32, reaction: String, count: Int32) + case reactionCount(flags: Int32, reaction: Api.Reaction, count: Int32) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { case .reactionCount(let flags, let reaction, let count): if boxed { - buffer.appendInt32(1873957073) + buffer.appendInt32(609529328) } serializeInt32(flags, buffer: buffer, boxed: false) - serializeString(reaction, buffer: buffer, boxed: false) + reaction.serialize(buffer, true) serializeInt32(count, buffer: buffer, boxed: false) break } @@ -25,8 +93,10 @@ public extension Api { public static func parse_reactionCount(_ reader: BufferReader) -> ReactionCount? { var _1: Int32? _1 = reader.readInt32() - var _2: String? - _2 = parseString(reader) + var _2: Api.Reaction? + if let signature = reader.readInt32() { + _2 = Api.parse(reader, signature: signature) as? Api.Reaction + } var _3: Int32? _3 = reader.readInt32() let _c1 = _1 != nil diff --git a/submodules/TelegramApi/Sources/Api29.swift b/submodules/TelegramApi/Sources/Api29.swift index 8754083e4c..a46513a518 100644 --- a/submodules/TelegramApi/Sources/Api29.swift +++ b/submodules/TelegramApi/Sources/Api29.swift @@ -4416,13 +4416,13 @@ public extension Api.functions.messages { } } public extension Api.functions.messages { - static func getMessageReactionsList(flags: Int32, peer: Api.InputPeer, id: Int32, reaction: String?, offset: String?, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func getMessageReactionsList(flags: Int32, peer: Api.InputPeer, id: Int32, reaction: Api.Reaction?, offset: String?, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(-521245833) + buffer.appendInt32(1176190792) serializeInt32(flags, buffer: buffer, boxed: false) peer.serialize(buffer, true) serializeInt32(id, buffer: buffer, boxed: false) - if Int(flags) & Int(1 << 0) != 0 {serializeString(reaction!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 0) != 0 {reaction!.serialize(buffer, true)} if Int(flags) & Int(1 << 1) != 0 {serializeString(offset!, buffer: buffer, boxed: false)} serializeInt32(limit, buffer: buffer, boxed: false) return (FunctionDescription(name: "messages.getMessageReactionsList", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("id", String(describing: id)), ("reaction", String(describing: reaction)), ("offset", String(describing: offset)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.MessageReactionsList? in @@ -5726,13 +5726,13 @@ public extension Api.functions.messages { } } public extension Api.functions.messages { - static func sendReaction(flags: Int32, peer: Api.InputPeer, msgId: Int32, reaction: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func sendReaction(flags: Int32, peer: Api.InputPeer, msgId: Int32, reaction: Api.Reaction?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(627641572) + buffer.appendInt32(1526634933) serializeInt32(flags, buffer: buffer, boxed: false) peer.serialize(buffer, true) serializeInt32(msgId, buffer: buffer, boxed: false) - if Int(flags) & Int(1 << 0) != 0 {serializeString(reaction!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 0) != 0 {reaction!.serialize(buffer, true)} return (FunctionDescription(name: "messages.sendReaction", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("msgId", String(describing: msgId)), ("reaction", String(describing: reaction))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in let reader = BufferReader(buffer) var result: Api.Updates? @@ -5930,10 +5930,10 @@ public extension Api.functions.messages { } } public extension Api.functions.messages { - static func setDefaultReaction(reaction: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func setDefaultReaction(reaction: Api.Reaction) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(-647969580) - serializeString(reaction, buffer: buffer, boxed: false) + buffer.appendInt32(1330094102) + reaction.serialize(buffer, true) return (FunctionDescription(name: "messages.setDefaultReaction", parameters: [("reaction", String(describing: reaction))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in let reader = BufferReader(buffer) var result: Api.Bool? diff --git a/submodules/TelegramApi/Sources/Api4.swift b/submodules/TelegramApi/Sources/Api4.swift index 666e1b148f..36e39fc393 100644 --- a/submodules/TelegramApi/Sources/Api4.swift +++ b/submodules/TelegramApi/Sources/Api4.swift @@ -366,13 +366,13 @@ public extension Api { } public extension Api { enum Config: TypeConstructorDescription { - case config(flags: Int32, date: Int32, expires: Int32, testMode: Api.Bool, thisDc: Int32, dcOptions: [Api.DcOption], dcTxtDomainName: String, chatSizeMax: Int32, megagroupSizeMax: Int32, forwardedCountMax: Int32, onlineUpdatePeriodMs: Int32, offlineBlurTimeoutMs: Int32, offlineIdleTimeoutMs: Int32, onlineCloudTimeoutMs: Int32, notifyCloudDelayMs: Int32, notifyDefaultDelayMs: Int32, pushChatPeriodMs: Int32, pushChatLimit: Int32, savedGifsLimit: Int32, editTimeLimit: Int32, revokeTimeLimit: Int32, revokePmTimeLimit: Int32, ratingEDecay: Int32, stickersRecentLimit: Int32, stickersFavedLimit: Int32, channelsReadMediaPeriod: Int32, tmpSessions: Int32?, pinnedDialogsCountMax: Int32, pinnedInfolderCountMax: Int32, callReceiveTimeoutMs: Int32, callRingTimeoutMs: Int32, callConnectTimeoutMs: Int32, callPacketTimeoutMs: Int32, meUrlPrefix: String, autoupdateUrlPrefix: String?, gifSearchUsername: String?, venueSearchUsername: String?, imgSearchUsername: String?, staticMapsProvider: String?, captionLengthMax: Int32, messageLengthMax: Int32, webfileDcId: Int32, suggestedLangCode: String?, langPackVersion: Int32?, baseLangPackVersion: Int32?) + case config(flags: Int32, date: Int32, expires: Int32, testMode: Api.Bool, thisDc: Int32, dcOptions: [Api.DcOption], dcTxtDomainName: String, chatSizeMax: Int32, megagroupSizeMax: Int32, forwardedCountMax: Int32, onlineUpdatePeriodMs: Int32, offlineBlurTimeoutMs: Int32, offlineIdleTimeoutMs: Int32, onlineCloudTimeoutMs: Int32, notifyCloudDelayMs: Int32, notifyDefaultDelayMs: Int32, pushChatPeriodMs: Int32, pushChatLimit: Int32, savedGifsLimit: Int32, editTimeLimit: Int32, revokeTimeLimit: Int32, revokePmTimeLimit: Int32, ratingEDecay: Int32, stickersRecentLimit: Int32, stickersFavedLimit: Int32, channelsReadMediaPeriod: Int32, tmpSessions: Int32?, pinnedDialogsCountMax: Int32, pinnedInfolderCountMax: Int32, callReceiveTimeoutMs: Int32, callRingTimeoutMs: Int32, callConnectTimeoutMs: Int32, callPacketTimeoutMs: Int32, meUrlPrefix: String, autoupdateUrlPrefix: String?, gifSearchUsername: String?, venueSearchUsername: String?, imgSearchUsername: String?, staticMapsProvider: String?, captionLengthMax: Int32, messageLengthMax: Int32, webfileDcId: Int32, suggestedLangCode: String?, langPackVersion: Int32?, baseLangPackVersion: Int32?, reactionsDefault: Api.Reaction?) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .config(let flags, let date, let expires, let testMode, let thisDc, let dcOptions, let dcTxtDomainName, let chatSizeMax, let megagroupSizeMax, let forwardedCountMax, let onlineUpdatePeriodMs, let offlineBlurTimeoutMs, let offlineIdleTimeoutMs, let onlineCloudTimeoutMs, let notifyCloudDelayMs, let notifyDefaultDelayMs, let pushChatPeriodMs, let pushChatLimit, let savedGifsLimit, let editTimeLimit, let revokeTimeLimit, let revokePmTimeLimit, let ratingEDecay, let stickersRecentLimit, let stickersFavedLimit, let channelsReadMediaPeriod, let tmpSessions, let pinnedDialogsCountMax, let pinnedInfolderCountMax, let callReceiveTimeoutMs, let callRingTimeoutMs, let callConnectTimeoutMs, let callPacketTimeoutMs, let meUrlPrefix, let autoupdateUrlPrefix, let gifSearchUsername, let venueSearchUsername, let imgSearchUsername, let staticMapsProvider, let captionLengthMax, let messageLengthMax, let webfileDcId, let suggestedLangCode, let langPackVersion, let baseLangPackVersion): + case .config(let flags, let date, let expires, let testMode, let thisDc, let dcOptions, let dcTxtDomainName, let chatSizeMax, let megagroupSizeMax, let forwardedCountMax, let onlineUpdatePeriodMs, let offlineBlurTimeoutMs, let offlineIdleTimeoutMs, let onlineCloudTimeoutMs, let notifyCloudDelayMs, let notifyDefaultDelayMs, let pushChatPeriodMs, let pushChatLimit, let savedGifsLimit, let editTimeLimit, let revokeTimeLimit, let revokePmTimeLimit, let ratingEDecay, let stickersRecentLimit, let stickersFavedLimit, let channelsReadMediaPeriod, let tmpSessions, let pinnedDialogsCountMax, let pinnedInfolderCountMax, let callReceiveTimeoutMs, let callRingTimeoutMs, let callConnectTimeoutMs, let callPacketTimeoutMs, let meUrlPrefix, let autoupdateUrlPrefix, let gifSearchUsername, let venueSearchUsername, let imgSearchUsername, let staticMapsProvider, let captionLengthMax, let messageLengthMax, let webfileDcId, let suggestedLangCode, let langPackVersion, let baseLangPackVersion, let reactionsDefault): if boxed { - buffer.appendInt32(856375399) + buffer.appendInt32(589653676) } serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(date, buffer: buffer, boxed: false) @@ -423,14 +423,15 @@ public extension Api { if Int(flags) & Int(1 << 2) != 0 {serializeString(suggestedLangCode!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 2) != 0 {serializeInt32(langPackVersion!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 2) != 0 {serializeInt32(baseLangPackVersion!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 15) != 0 {reactionsDefault!.serialize(buffer, true)} break } } public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .config(let flags, let date, let expires, let testMode, let thisDc, let dcOptions, let dcTxtDomainName, let chatSizeMax, let megagroupSizeMax, let forwardedCountMax, let onlineUpdatePeriodMs, let offlineBlurTimeoutMs, let offlineIdleTimeoutMs, let onlineCloudTimeoutMs, let notifyCloudDelayMs, let notifyDefaultDelayMs, let pushChatPeriodMs, let pushChatLimit, let savedGifsLimit, let editTimeLimit, let revokeTimeLimit, let revokePmTimeLimit, let ratingEDecay, let stickersRecentLimit, let stickersFavedLimit, let channelsReadMediaPeriod, let tmpSessions, let pinnedDialogsCountMax, let pinnedInfolderCountMax, let callReceiveTimeoutMs, let callRingTimeoutMs, let callConnectTimeoutMs, let callPacketTimeoutMs, let meUrlPrefix, let autoupdateUrlPrefix, let gifSearchUsername, let venueSearchUsername, let imgSearchUsername, let staticMapsProvider, let captionLengthMax, let messageLengthMax, let webfileDcId, let suggestedLangCode, let langPackVersion, let baseLangPackVersion): - return ("config", [("flags", String(describing: flags)), ("date", String(describing: date)), ("expires", String(describing: expires)), ("testMode", String(describing: testMode)), ("thisDc", String(describing: thisDc)), ("dcOptions", String(describing: dcOptions)), ("dcTxtDomainName", String(describing: dcTxtDomainName)), ("chatSizeMax", String(describing: chatSizeMax)), ("megagroupSizeMax", String(describing: megagroupSizeMax)), ("forwardedCountMax", String(describing: forwardedCountMax)), ("onlineUpdatePeriodMs", String(describing: onlineUpdatePeriodMs)), ("offlineBlurTimeoutMs", String(describing: offlineBlurTimeoutMs)), ("offlineIdleTimeoutMs", String(describing: offlineIdleTimeoutMs)), ("onlineCloudTimeoutMs", String(describing: onlineCloudTimeoutMs)), ("notifyCloudDelayMs", String(describing: notifyCloudDelayMs)), ("notifyDefaultDelayMs", String(describing: notifyDefaultDelayMs)), ("pushChatPeriodMs", String(describing: pushChatPeriodMs)), ("pushChatLimit", String(describing: pushChatLimit)), ("savedGifsLimit", String(describing: savedGifsLimit)), ("editTimeLimit", String(describing: editTimeLimit)), ("revokeTimeLimit", String(describing: revokeTimeLimit)), ("revokePmTimeLimit", String(describing: revokePmTimeLimit)), ("ratingEDecay", String(describing: ratingEDecay)), ("stickersRecentLimit", String(describing: stickersRecentLimit)), ("stickersFavedLimit", String(describing: stickersFavedLimit)), ("channelsReadMediaPeriod", String(describing: channelsReadMediaPeriod)), ("tmpSessions", String(describing: tmpSessions)), ("pinnedDialogsCountMax", String(describing: pinnedDialogsCountMax)), ("pinnedInfolderCountMax", String(describing: pinnedInfolderCountMax)), ("callReceiveTimeoutMs", String(describing: callReceiveTimeoutMs)), ("callRingTimeoutMs", String(describing: callRingTimeoutMs)), ("callConnectTimeoutMs", String(describing: callConnectTimeoutMs)), ("callPacketTimeoutMs", String(describing: callPacketTimeoutMs)), ("meUrlPrefix", String(describing: meUrlPrefix)), ("autoupdateUrlPrefix", String(describing: autoupdateUrlPrefix)), ("gifSearchUsername", String(describing: gifSearchUsername)), ("venueSearchUsername", String(describing: venueSearchUsername)), ("imgSearchUsername", String(describing: imgSearchUsername)), ("staticMapsProvider", String(describing: staticMapsProvider)), ("captionLengthMax", String(describing: captionLengthMax)), ("messageLengthMax", String(describing: messageLengthMax)), ("webfileDcId", String(describing: webfileDcId)), ("suggestedLangCode", String(describing: suggestedLangCode)), ("langPackVersion", String(describing: langPackVersion)), ("baseLangPackVersion", String(describing: baseLangPackVersion))]) + case .config(let flags, let date, let expires, let testMode, let thisDc, let dcOptions, let dcTxtDomainName, let chatSizeMax, let megagroupSizeMax, let forwardedCountMax, let onlineUpdatePeriodMs, let offlineBlurTimeoutMs, let offlineIdleTimeoutMs, let onlineCloudTimeoutMs, let notifyCloudDelayMs, let notifyDefaultDelayMs, let pushChatPeriodMs, let pushChatLimit, let savedGifsLimit, let editTimeLimit, let revokeTimeLimit, let revokePmTimeLimit, let ratingEDecay, let stickersRecentLimit, let stickersFavedLimit, let channelsReadMediaPeriod, let tmpSessions, let pinnedDialogsCountMax, let pinnedInfolderCountMax, let callReceiveTimeoutMs, let callRingTimeoutMs, let callConnectTimeoutMs, let callPacketTimeoutMs, let meUrlPrefix, let autoupdateUrlPrefix, let gifSearchUsername, let venueSearchUsername, let imgSearchUsername, let staticMapsProvider, let captionLengthMax, let messageLengthMax, let webfileDcId, let suggestedLangCode, let langPackVersion, let baseLangPackVersion, let reactionsDefault): + return ("config", [("flags", String(describing: flags)), ("date", String(describing: date)), ("expires", String(describing: expires)), ("testMode", String(describing: testMode)), ("thisDc", String(describing: thisDc)), ("dcOptions", String(describing: dcOptions)), ("dcTxtDomainName", String(describing: dcTxtDomainName)), ("chatSizeMax", String(describing: chatSizeMax)), ("megagroupSizeMax", String(describing: megagroupSizeMax)), ("forwardedCountMax", String(describing: forwardedCountMax)), ("onlineUpdatePeriodMs", String(describing: onlineUpdatePeriodMs)), ("offlineBlurTimeoutMs", String(describing: offlineBlurTimeoutMs)), ("offlineIdleTimeoutMs", String(describing: offlineIdleTimeoutMs)), ("onlineCloudTimeoutMs", String(describing: onlineCloudTimeoutMs)), ("notifyCloudDelayMs", String(describing: notifyCloudDelayMs)), ("notifyDefaultDelayMs", String(describing: notifyDefaultDelayMs)), ("pushChatPeriodMs", String(describing: pushChatPeriodMs)), ("pushChatLimit", String(describing: pushChatLimit)), ("savedGifsLimit", String(describing: savedGifsLimit)), ("editTimeLimit", String(describing: editTimeLimit)), ("revokeTimeLimit", String(describing: revokeTimeLimit)), ("revokePmTimeLimit", String(describing: revokePmTimeLimit)), ("ratingEDecay", String(describing: ratingEDecay)), ("stickersRecentLimit", String(describing: stickersRecentLimit)), ("stickersFavedLimit", String(describing: stickersFavedLimit)), ("channelsReadMediaPeriod", String(describing: channelsReadMediaPeriod)), ("tmpSessions", String(describing: tmpSessions)), ("pinnedDialogsCountMax", String(describing: pinnedDialogsCountMax)), ("pinnedInfolderCountMax", String(describing: pinnedInfolderCountMax)), ("callReceiveTimeoutMs", String(describing: callReceiveTimeoutMs)), ("callRingTimeoutMs", String(describing: callRingTimeoutMs)), ("callConnectTimeoutMs", String(describing: callConnectTimeoutMs)), ("callPacketTimeoutMs", String(describing: callPacketTimeoutMs)), ("meUrlPrefix", String(describing: meUrlPrefix)), ("autoupdateUrlPrefix", String(describing: autoupdateUrlPrefix)), ("gifSearchUsername", String(describing: gifSearchUsername)), ("venueSearchUsername", String(describing: venueSearchUsername)), ("imgSearchUsername", String(describing: imgSearchUsername)), ("staticMapsProvider", String(describing: staticMapsProvider)), ("captionLengthMax", String(describing: captionLengthMax)), ("messageLengthMax", String(describing: messageLengthMax)), ("webfileDcId", String(describing: webfileDcId)), ("suggestedLangCode", String(describing: suggestedLangCode)), ("langPackVersion", String(describing: langPackVersion)), ("baseLangPackVersion", String(describing: baseLangPackVersion)), ("reactionsDefault", String(describing: reactionsDefault))]) } } @@ -529,6 +530,10 @@ public extension Api { if Int(_1!) & Int(1 << 2) != 0 {_44 = reader.readInt32() } var _45: Int32? if Int(_1!) & Int(1 << 2) != 0 {_45 = reader.readInt32() } + var _46: Api.Reaction? + if Int(_1!) & Int(1 << 15) != 0 {if let signature = reader.readInt32() { + _46 = Api.parse(reader, signature: signature) as? Api.Reaction + } } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = _3 != nil @@ -574,8 +579,9 @@ public extension Api { let _c43 = (Int(_1!) & Int(1 << 2) == 0) || _43 != nil let _c44 = (Int(_1!) & Int(1 << 2) == 0) || _44 != nil let _c45 = (Int(_1!) & Int(1 << 2) == 0) || _45 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 && _c31 && _c32 && _c33 && _c34 && _c35 && _c36 && _c37 && _c38 && _c39 && _c40 && _c41 && _c42 && _c43 && _c44 && _c45 { - return Api.Config.config(flags: _1!, date: _2!, expires: _3!, testMode: _4!, thisDc: _5!, dcOptions: _6!, dcTxtDomainName: _7!, chatSizeMax: _8!, megagroupSizeMax: _9!, forwardedCountMax: _10!, onlineUpdatePeriodMs: _11!, offlineBlurTimeoutMs: _12!, offlineIdleTimeoutMs: _13!, onlineCloudTimeoutMs: _14!, notifyCloudDelayMs: _15!, notifyDefaultDelayMs: _16!, pushChatPeriodMs: _17!, pushChatLimit: _18!, savedGifsLimit: _19!, editTimeLimit: _20!, revokeTimeLimit: _21!, revokePmTimeLimit: _22!, ratingEDecay: _23!, stickersRecentLimit: _24!, stickersFavedLimit: _25!, channelsReadMediaPeriod: _26!, tmpSessions: _27, pinnedDialogsCountMax: _28!, pinnedInfolderCountMax: _29!, callReceiveTimeoutMs: _30!, callRingTimeoutMs: _31!, callConnectTimeoutMs: _32!, callPacketTimeoutMs: _33!, meUrlPrefix: _34!, autoupdateUrlPrefix: _35, gifSearchUsername: _36, venueSearchUsername: _37, imgSearchUsername: _38, staticMapsProvider: _39, captionLengthMax: _40!, messageLengthMax: _41!, webfileDcId: _42!, suggestedLangCode: _43, langPackVersion: _44, baseLangPackVersion: _45) + let _c46 = (Int(_1!) & Int(1 << 15) == 0) || _46 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 && _c31 && _c32 && _c33 && _c34 && _c35 && _c36 && _c37 && _c38 && _c39 && _c40 && _c41 && _c42 && _c43 && _c44 && _c45 && _c46 { + return Api.Config.config(flags: _1!, date: _2!, expires: _3!, testMode: _4!, thisDc: _5!, dcOptions: _6!, dcTxtDomainName: _7!, chatSizeMax: _8!, megagroupSizeMax: _9!, forwardedCountMax: _10!, onlineUpdatePeriodMs: _11!, offlineBlurTimeoutMs: _12!, offlineIdleTimeoutMs: _13!, onlineCloudTimeoutMs: _14!, notifyCloudDelayMs: _15!, notifyDefaultDelayMs: _16!, pushChatPeriodMs: _17!, pushChatLimit: _18!, savedGifsLimit: _19!, editTimeLimit: _20!, revokeTimeLimit: _21!, revokePmTimeLimit: _22!, ratingEDecay: _23!, stickersRecentLimit: _24!, stickersFavedLimit: _25!, channelsReadMediaPeriod: _26!, tmpSessions: _27, pinnedDialogsCountMax: _28!, pinnedInfolderCountMax: _29!, callReceiveTimeoutMs: _30!, callRingTimeoutMs: _31!, callConnectTimeoutMs: _32!, callPacketTimeoutMs: _33!, meUrlPrefix: _34!, autoupdateUrlPrefix: _35, gifSearchUsername: _36, venueSearchUsername: _37, imgSearchUsername: _38, staticMapsProvider: _39, captionLengthMax: _40!, messageLengthMax: _41!, webfileDcId: _42!, suggestedLangCode: _43, langPackVersion: _44, baseLangPackVersion: _45, reactionsDefault: _46) } else { return nil diff --git a/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift b/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift index c9f848db87..5f07721f99 100644 --- a/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift +++ b/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift @@ -636,7 +636,7 @@ struct AccountFinalState { struct AccountReplayedFinalState { let state: AccountFinalState let addedIncomingMessageIds: [MessageId] - let addedReactionEvents: [(reactionAuthor: Peer, reaction: String, message: Message, timestamp: Int32)] + let addedReactionEvents: [(reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)] let wasScheduledMessageIds: [MessageId] let addedSecretMessageIds: [MessageId] let deletedMessageIds: [DeletedMessageId] @@ -655,7 +655,7 @@ struct AccountReplayedFinalState { struct AccountFinalStateEvents { let addedIncomingMessageIds: [MessageId] - let addedReactionEvents: [(reactionAuthor: Peer, reaction: String, message: Message, timestamp: Int32)] + let addedReactionEvents: [(reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)] let wasScheduledMessageIds:[MessageId] let deletedMessageIds: [DeletedMessageId] let updatedTypingActivities: [PeerActivitySpace: [PeerId: PeerInputActivity?]] @@ -680,7 +680,7 @@ struct AccountFinalStateEvents { return self.addedIncomingMessageIds.isEmpty && self.addedReactionEvents.isEmpty && self.wasScheduledMessageIds.isEmpty && self.deletedMessageIds.isEmpty && self.updatedTypingActivities.isEmpty && self.updatedWebpages.isEmpty && self.updatedCalls.isEmpty && self.addedCallSignalingData.isEmpty && self.updatedGroupCallParticipants.isEmpty && self.updatedPeersNearby?.isEmpty ?? true && self.isContactUpdates.isEmpty && self.displayAlerts.isEmpty && self.dismissBotWebViews.isEmpty && self.delayNotificatonsUntil == nil && self.updatedMaxMessageId == nil && self.updatedQts == nil && self.externallyUpdatedPeerId.isEmpty && !authorizationListUpdated && self.updatedIncomingThreadReadStates.isEmpty && self.updatedOutgoingThreadReadStates.isEmpty && !self.updateConfig } - init(addedIncomingMessageIds: [MessageId] = [], addedReactionEvents: [(reactionAuthor: Peer, reaction: String, message: Message, timestamp: Int32)] = [], wasScheduledMessageIds: [MessageId] = [], deletedMessageIds: [DeletedMessageId] = [], updatedTypingActivities: [PeerActivitySpace: [PeerId: PeerInputActivity?]] = [:], updatedWebpages: [MediaId: TelegramMediaWebpage] = [:], updatedCalls: [Api.PhoneCall] = [], addedCallSignalingData: [(Int64, Data)] = [], updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] = [], updatedPeersNearby: [PeerNearby]? = nil, isContactUpdates: [(PeerId, Bool)] = [], displayAlerts: [(text: String, isDropAuth: Bool)] = [], dismissBotWebViews: [Int64] = [], delayNotificatonsUntil: Int32? = nil, updatedMaxMessageId: Int32? = nil, updatedQts: Int32? = nil, externallyUpdatedPeerId: Set = Set(), authorizationListUpdated: Bool = false, updatedIncomingThreadReadStates: [MessageId: MessageId.Id] = [:], updatedOutgoingThreadReadStates: [MessageId: MessageId.Id] = [:], updateConfig: Bool = false) { + init(addedIncomingMessageIds: [MessageId] = [], addedReactionEvents: [(reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)] = [], wasScheduledMessageIds: [MessageId] = [], deletedMessageIds: [DeletedMessageId] = [], updatedTypingActivities: [PeerActivitySpace: [PeerId: PeerInputActivity?]] = [:], updatedWebpages: [MediaId: TelegramMediaWebpage] = [:], updatedCalls: [Api.PhoneCall] = [], addedCallSignalingData: [(Int64, Data)] = [], updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] = [], updatedPeersNearby: [PeerNearby]? = nil, isContactUpdates: [(PeerId, Bool)] = [], displayAlerts: [(text: String, isDropAuth: Bool)] = [], dismissBotWebViews: [Int64] = [], delayNotificatonsUntil: Int32? = nil, updatedMaxMessageId: Int32? = nil, updatedQts: Int32? = nil, externallyUpdatedPeerId: Set = Set(), authorizationListUpdated: Bool = false, updatedIncomingThreadReadStates: [MessageId: MessageId.Id] = [:], updatedOutgoingThreadReadStates: [MessageId: MessageId.Id] = [:], updateConfig: Bool = false) { self.addedIncomingMessageIds = addedIncomingMessageIds self.addedReactionEvents = addedReactionEvents self.wasScheduledMessageIds = wasScheduledMessageIds diff --git a/submodules/TelegramCore/Sources/ApiUtils/ReactionsMessageAttribute.swift b/submodules/TelegramCore/Sources/ApiUtils/ReactionsMessageAttribute.swift index 32c3f32a9e..88eb9cfddb 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/ReactionsMessageAttribute.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/ReactionsMessageAttribute.swift @@ -8,20 +8,28 @@ extension ReactionsMessageAttribute { case let .messageReactions(flags, results, recentReactions): let min = (flags & (1 << 0)) != 0 let canViewList = (flags & (1 << 2)) != 0 - var reactions = results.map { result -> MessageReaction in + var reactions = results.compactMap { result -> MessageReaction? in switch result { case let .reactionCount(flags, reaction, count): - return MessageReaction(value: reaction, count: count, isSelected: (flags & (1 << 0)) != 0) + if let reaction = MessageReaction.Reaction(apiReaction: reaction) { + return MessageReaction(value: reaction, count: count, isSelected: (flags & (1 << 0)) != 0) + } else { + return nil + } } } let parsedRecentReactions: [ReactionsMessageAttribute.RecentPeer] if let recentReactions = recentReactions { - parsedRecentReactions = recentReactions.map { recentReaction -> ReactionsMessageAttribute.RecentPeer in + parsedRecentReactions = recentReactions.compactMap { recentReaction -> ReactionsMessageAttribute.RecentPeer? in switch recentReaction { case let .messagePeerReaction(flags, peerId, reaction): let isLarge = (flags & (1 << 0)) != 0 let isUnseen = (flags & (1 << 1)) != 0 - return ReactionsMessageAttribute.RecentPeer(value: reaction, isLarge: isLarge, isUnseen: isUnseen, peerId: peerId.peerId) + if let reaction = MessageReaction.Reaction(apiReaction: reaction) { + return ReactionsMessageAttribute.RecentPeer(value: reaction, isLarge: isLarge, isUnseen: isUnseen, peerId: peerId.peerId) + } else { + return nil + } } } } else { @@ -29,7 +37,7 @@ extension ReactionsMessageAttribute { } if min { - var currentSelectedReaction: String? + var currentSelectedReaction: MessageReaction.Reaction? for reaction in self.reactions { if reaction.isSelected { currentSelectedReaction = reaction.value @@ -49,12 +57,12 @@ extension ReactionsMessageAttribute { } } -public func mergedMessageReactionsAndPeers(message: Message) -> (reactions: [MessageReaction], peers: [(String, EnginePeer)]) { +public func mergedMessageReactionsAndPeers(message: Message) -> (reactions: [MessageReaction], peers: [(MessageReaction.Reaction, EnginePeer)]) { guard let attribute = mergedMessageReactions(attributes: message.attributes) else { return ([], []) } - var recentPeers = attribute.recentPeers.compactMap { recentPeer -> (String, EnginePeer)? in + var recentPeers = attribute.recentPeers.compactMap { recentPeer -> (MessageReaction.Reaction, EnginePeer)? in if let peer = message.peers[recentPeer.peerId] { return (recentPeer.value, EnginePeer(peer)) } else { @@ -137,12 +145,16 @@ extension ReactionsMessageAttribute { let canViewList = (flags & (1 << 2)) != 0 let parsedRecentReactions: [ReactionsMessageAttribute.RecentPeer] if let recentReactions = recentReactions { - parsedRecentReactions = recentReactions.map { recentReaction -> ReactionsMessageAttribute.RecentPeer in + parsedRecentReactions = recentReactions.compactMap { recentReaction -> ReactionsMessageAttribute.RecentPeer? in switch recentReaction { case let .messagePeerReaction(flags, peerId, reaction): let isLarge = (flags & (1 << 0)) != 0 let isUnseen = (flags & (1 << 1)) != 0 - return ReactionsMessageAttribute.RecentPeer(value: reaction, isLarge: isLarge, isUnseen: isUnseen, peerId: peerId.peerId) + if let reaction = MessageReaction.Reaction(apiReaction: reaction) { + return ReactionsMessageAttribute.RecentPeer(value: reaction, isLarge: isLarge, isUnseen: isUnseen, peerId: peerId.peerId) + } else { + return nil + } } } } else { @@ -151,10 +163,14 @@ extension ReactionsMessageAttribute { self.init( canViewList: canViewList, - reactions: results.map { result in + reactions: results.compactMap { result -> MessageReaction? in switch result { case let .reactionCount(flags, reaction, count): - return MessageReaction(value: reaction, count: count, isSelected: (flags & (1 << 0)) != 0) + if let reaction = MessageReaction.Reaction(apiReaction: reaction) { + return MessageReaction(value: reaction, count: count, isSelected: (flags & (1 << 0)) != 0) + } else { + return nil + } } }, recentPeers: parsedRecentReactions diff --git a/submodules/TelegramCore/Sources/Settings/ReactionSettings.swift b/submodules/TelegramCore/Sources/Settings/ReactionSettings.swift index b395e3f43e..25ad5a86ad 100644 --- a/submodules/TelegramCore/Sources/Settings/ReactionSettings.swift +++ b/submodules/TelegramCore/Sources/Settings/ReactionSettings.swift @@ -2,11 +2,11 @@ import Postbox import SwiftSignalKit public struct ReactionSettings: Equatable, Codable { - public static var `default` = ReactionSettings(quickReaction: "👍") + public static var `default` = ReactionSettings(quickReaction: .builtin("👍")) - public var quickReaction: String + public var quickReaction: MessageReaction.Reaction - public init(quickReaction: String) { + public init(quickReaction: MessageReaction.Reaction) { self.quickReaction = quickReaction } } diff --git a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift index 23775a3d16..c7a54d91f0 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift @@ -4,8 +4,7 @@ import SwiftSignalKit import TelegramApi import MtProtoKit -private func reactionGeneratedEvent(_ previousReactions: ReactionsMessageAttribute?, _ updatedReactions: ReactionsMessageAttribute?, message: Message, transaction: Transaction) -> (reactionAuthor: Peer, reaction: String, message: Message, timestamp: Int32)? { - +private func reactionGeneratedEvent(_ previousReactions: ReactionsMessageAttribute?, _ updatedReactions: ReactionsMessageAttribute?, message: Message, transaction: Transaction) -> (reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)? { if let updatedReactions = updatedReactions, !message.flags.contains(.Incoming), message.id.peerId.namespace == Namespaces.Peer.CloudUser { let prev = previousReactions?.reactions ?? [] @@ -2533,7 +2532,7 @@ func replayFinalState( } var wasScheduledMessageIds:[MessageId] = [] var addedIncomingMessageIds: [MessageId] = [] - var addedReactionEvents: [(reactionAuthor: Peer, reaction: String, message: Message, timestamp: Int32)] = [] + var addedReactionEvents: [(reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)] = [] if !wasOperationScheduledMessageIds.isEmpty { let existingIds = transaction.filterStoredMessageIds(Set(wasOperationScheduledMessageIds)) @@ -2773,7 +2772,7 @@ func replayFinalState( invalidateGroupStats.insert(Namespaces.PeerGroup.archive) } case let .EditMessage(id, message): - var generatedEvent: (reactionAuthor: Peer, reaction: String, message: Message, timestamp: Int32)? + var generatedEvent: (reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)? transaction.updateMessage(id, update: { previousMessage in var updatedFlags = message.flags var updatedLocalTags = message.localTags diff --git a/submodules/TelegramCore/Sources/State/AccountStateManager.swift b/submodules/TelegramCore/Sources/State/AccountStateManager.swift index a607d2b285..fdfc06ff5f 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManager.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManager.swift @@ -105,8 +105,8 @@ public final class AccountStateManager { return self.notificationMessagesPipe.signal() } - private let reactionNotificationsPipe = ValuePipe<[(reactionAuthor: Peer, reaction: String, message: Message, timestamp: Int32)]>() - public var reactionNotifications: Signal<[(reactionAuthor: Peer, reaction: String, message: Message, timestamp: Int32)], NoError> { + private let reactionNotificationsPipe = ValuePipe<[(reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)]>() + public var reactionNotifications: Signal<[(reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)], NoError> { return self.reactionNotificationsPipe.signal() } @@ -753,7 +753,7 @@ public final class AccountStateManager { let timestamp = Int32(Date().timeIntervalSince1970) let minReactionTimestamp = timestamp - 20 - let reactionEvents = events.addedReactionEvents.compactMap { event -> (reactionAuthor: Peer, reaction: String, message: Message, timestamp: Int32)? in + let reactionEvents = events.addedReactionEvents.compactMap { event -> (reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)? in if event.timestamp >= minReactionTimestamp { return (event.reactionAuthor, event.reaction, event.message, event.timestamp) } else { @@ -761,7 +761,6 @@ public final class AccountStateManager { } } self.reactionNotificationsPipe.putNext(reactionEvents) - if !events.displayAlerts.isEmpty { self.displayAlertsPipe.putNext(events.displayAlerts) diff --git a/submodules/TelegramCore/Sources/State/AvailableReactions.swift b/submodules/TelegramCore/Sources/State/AvailableReactions.swift index 724dc5c18f..7f88ae2e7f 100644 --- a/submodules/TelegramCore/Sources/State/AvailableReactions.swift +++ b/submodules/TelegramCore/Sources/State/AvailableReactions.swift @@ -21,7 +21,7 @@ public final class AvailableReactions: Equatable, Codable { public let isEnabled: Bool public let isPremium: Bool - public let value: String + public let value: MessageReaction.Reaction public let title: String public let staticIcon: TelegramMediaFile public let appearAnimation: TelegramMediaFile @@ -34,7 +34,7 @@ public final class AvailableReactions: Equatable, Codable { public init( isEnabled: Bool, isPremium: Bool, - value: String, + value: MessageReaction.Reaction, title: String, staticIcon: TelegramMediaFile, appearAnimation: TelegramMediaFile, @@ -100,7 +100,7 @@ public final class AvailableReactions: Equatable, Codable { self.isEnabled = try container.decode(Bool.self, forKey: .isEnabled) self.isPremium = try container.decodeIfPresent(Bool.self, forKey: .isPremium) ?? false - self.value = try container.decode(String.self, forKey: .value) + self.value = .builtin(try container.decode(String.self, forKey: .value)) self.title = try container.decode(String.self, forKey: .title) let staticIconData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .staticIcon) @@ -137,7 +137,12 @@ public final class AvailableReactions: Equatable, Codable { try container.encode(self.isEnabled, forKey: .isEnabled) try container.encode(self.isPremium, forKey: .isPremium) - try container.encode(self.value, forKey: .value) + switch self.value { + case let .builtin(value): + try container.encode(value, forKey: .value) + case .custom: + break + } try container.encode(self.title, forKey: .title) try container.encode(PostboxEncoder().encodeObjectToRawData(self.staticIcon), forKey: .staticIcon) @@ -221,7 +226,7 @@ private extension AvailableReactions.Reaction { self.init( isEnabled: isEnabled, isPremium: isPremium, - value: reaction, + value: .builtin(reaction), title: title, staticIcon: staticIconFile, appearAnimation: appearAnimationFile, diff --git a/submodules/TelegramCore/Sources/State/ManagedAppConfigurationUpdates.swift b/submodules/TelegramCore/Sources/State/ManagedAppConfigurationUpdates.swift index 927d243675..adcc08bf2d 100644 --- a/submodules/TelegramCore/Sources/State/ManagedAppConfigurationUpdates.swift +++ b/submodules/TelegramCore/Sources/State/ManagedAppConfigurationUpdates.swift @@ -4,7 +4,6 @@ import SwiftSignalKit import TelegramApi import MtProtoKit - func updateAppConfigurationOnce(postbox: Postbox, network: Network) -> Signal { return network.request(Api.functions.help.getAppConfig()) |> map(Optional.init) @@ -17,14 +16,6 @@ func updateAppConfigurationOnce(postbox: Postbox, network: Network) -> Signal Void in if let data = JSON(apiJson: result) { - if let value = data["reactions_default"] as? String { - updateReactionSettings(transaction: transaction, { settings in - var settings = settings - settings.quickReaction = value - return settings - }) - } - updateAppConfiguration(transaction: transaction, { configuration -> AppConfiguration in var configuration = configuration configuration.data = data diff --git a/submodules/TelegramCore/Sources/State/ManagedConfigurationUpdates.swift b/submodules/TelegramCore/Sources/State/ManagedConfigurationUpdates.swift index 1010cab2d0..71bcf86c43 100644 --- a/submodules/TelegramCore/Sources/State/ManagedConfigurationUpdates.swift +++ b/submodules/TelegramCore/Sources/State/ManagedConfigurationUpdates.swift @@ -12,7 +12,7 @@ func managedConfigurationUpdates(accountManager: AccountManager mapToSignal { result -> Signal in return postbox.transaction { transaction -> Signal in switch result { - case let .config(flags, _, _, _, _, dcOptions, _, chatSizeMax, megagroupSizeMax, forwardedCountMax, _, _, _, _, _, _, _, _, savedGifsLimit, editTimeLimit, revokeTimeLimit, revokePmTimeLimit, _, stickersRecentLimit, stickersFavedLimit, _, _, pinnedDialogsCountMax, pinnedInfolderCountMax, _, _, _, _, _, autoupdateUrlPrefix, gifSearchUsername, venueSearchUsername, imgSearchUsername, _, captionLengthMax, _, webfileDcId, suggestedLangCode, langPackVersion, baseLangPackVersion): + case let .config(flags, _, _, _, _, dcOptions, _, chatSizeMax, megagroupSizeMax, forwardedCountMax, _, _, _, _, _, _, _, _, savedGifsLimit, editTimeLimit, revokeTimeLimit, revokePmTimeLimit, _, stickersRecentLimit, stickersFavedLimit, _, _, pinnedDialogsCountMax, pinnedInfolderCountMax, _, _, _, _, _, autoupdateUrlPrefix, gifSearchUsername, venueSearchUsername, imgSearchUsername, _, captionLengthMax, _, webfileDcId, suggestedLangCode, langPackVersion, baseLangPackVersion, defaultReaction): var addressList: [Int: [MTDatacenterAddress]] = [:] for option in dcOptions { switch option { @@ -63,6 +63,14 @@ func managedConfigurationUpdates(accountManager: AccountManager Signal in let (primary, secondary) = getLocalization(transaction) var invalidateLocalization = false diff --git a/submodules/TelegramCore/Sources/State/MessageReactions.swift b/submodules/TelegramCore/Sources/State/MessageReactions.swift index 76c19ce087..61a8a1c638 100644 --- a/submodules/TelegramCore/Sources/State/MessageReactions.swift +++ b/submodules/TelegramCore/Sources/State/MessageReactions.swift @@ -4,7 +4,7 @@ import SwiftSignalKit import TelegramApi import MtProtoKit -public func updateMessageReactionsInteractively(account: Account, messageId: MessageId, reaction: String?, isLarge: Bool) -> Signal { +public func updateMessageReactionsInteractively(account: Account, messageId: MessageId, reaction: MessageReaction.Reaction?, isLarge: Bool) -> Signal { return account.postbox.transaction { transaction -> Void in transaction.setPendingMessageAction(type: .updateReaction, id: messageId, action: UpdateMessageReactionsAction()) transaction.updateMessage(messageId, update: { currentMessage in @@ -31,14 +31,14 @@ private enum RequestUpdateMessageReactionError { } private func requestUpdateMessageReaction(postbox: Postbox, network: Network, stateManager: AccountStateManager, messageId: MessageId) -> Signal { - return postbox.transaction { transaction -> (Peer, String?, Bool)? in + return postbox.transaction { transaction -> (Peer, MessageReaction.Reaction?, Bool)? in guard let peer = transaction.getPeer(messageId.peerId) else { return nil } guard let message = transaction.getMessage(messageId) else { return nil } - var value: String? + var value: MessageReaction.Reaction? var isLarge: Bool = false for attribute in message.attributes { if let attribute = attribute as? PendingReactionsMessageAttribute { @@ -69,7 +69,7 @@ private func requestUpdateMessageReaction(postbox: Postbox, network: Network, st } } - let signal: Signal = network.request(Api.functions.messages.sendReaction(flags: flags, peer: inputPeer, msgId: messageId.id, reaction: value)) + let signal: Signal = network.request(Api.functions.messages.sendReaction(flags: flags, peer: inputPeer, msgId: messageId.id, reaction: value?.apiReaction)) |> mapError { _ -> RequestUpdateMessageReactionError in return .generic } @@ -241,7 +241,7 @@ private func synchronizeMessageReactions(transaction: Transaction, postbox: Post } public extension EngineMessageReactionListContext.State { - init(message: EngineMessage, reaction: String?) { + init(message: EngineMessage, reaction: MessageReaction.Reaction?) { var totalCount = 0 var hasOutgoingReaction = false var items: [EngineMessageReactionListContext.Item] = [] @@ -277,11 +277,11 @@ public extension EngineMessageReactionListContext.State { public final class EngineMessageReactionListContext { public final class Item: Equatable { public let peer: EnginePeer - public let reaction: String? + public let reaction: MessageReaction.Reaction? public init( peer: EnginePeer, - reaction: String? + reaction: MessageReaction.Reaction? ) { self.peer = peer self.reaction = reaction @@ -330,7 +330,7 @@ public final class EngineMessageReactionListContext { let account: Account let message: EngineMessage - let reaction: String? + let reaction: MessageReaction.Reaction? let disposable = MetaDisposable() @@ -339,7 +339,7 @@ public final class EngineMessageReactionListContext { var isLoadingMore: Bool = false - init(queue: Queue, account: Account, message: EngineMessage, reaction: String?) { + init(queue: Queue, account: Account, message: EngineMessage, reaction: MessageReaction.Reaction?) { self.queue = queue self.account = account self.message = message @@ -389,7 +389,7 @@ public final class EngineMessageReactionListContext { if currentOffset != nil { flags |= 1 << 1 } - return account.network.request(Api.functions.messages.getMessageReactionsList(flags: flags, peer: inputPeer, id: message.id.id, reaction: reaction, offset: currentOffset, limit: Int32(limit))) + return account.network.request(Api.functions.messages.getMessageReactionsList(flags: flags, peer: inputPeer, id: message.id.id, reaction: reaction?.apiReaction, offset: currentOffset, limit: Int32(limit))) |> map(Optional.init) |> `catch` { _ -> Signal in return .single(nil) @@ -423,7 +423,7 @@ public final class EngineMessageReactionListContext { for reaction in reactions { switch reaction { case let .messagePeerReaction(_, peer, reaction): - if let peer = transaction.getPeer(peer.peerId) { + if let peer = transaction.getPeer(peer.peerId), let reaction = MessageReaction.Reaction(apiReaction: reaction) { items.append(EngineMessageReactionListContext.Item(peer: EnginePeer(peer), reaction: reaction)) } } @@ -487,7 +487,7 @@ public final class EngineMessageReactionListContext { } } - init(account: Account, message: EngineMessage, reaction: String?) { + init(account: Account, message: EngineMessage, reaction: MessageReaction.Reaction?) { let queue = Queue() self.queue = queue self.impl = QueueLocalObject(queue: queue, generate: { @@ -506,7 +506,7 @@ public enum UpdatePeerAllowedReactionsError { case generic } -func _internal_updatePeerAllowedReactions(account: Account, peerId: PeerId, allowedReactions: [String]) -> Signal { +func _internal_updatePeerAllowedReactions(account: Account, peerId: PeerId, allowedReactions: [MessageReaction.Reaction]) -> Signal { return account.postbox.transaction { transaction -> Api.InputPeer? in return transaction.getPeer(peerId).flatMap(apiInputPeer) } @@ -515,7 +515,14 @@ func _internal_updatePeerAllowedReactions(account: Account, peerId: PeerId, allo guard let inputPeer = inputPeer else { return .fail(.generic) } - return account.network.request(Api.functions.messages.setChatAvailableReactions(peer: inputPeer, availableReactions: allowedReactions)) + return account.network.request(Api.functions.messages.setChatAvailableReactions(peer: inputPeer, availableReactions: allowedReactions.compactMap { item -> String? in + switch item { + case let .builtin(value): + return value + case .custom: + return nil + } + })) |> mapError { _ -> UpdatePeerAllowedReactionsError in return .generic } @@ -539,8 +546,8 @@ func _internal_updatePeerAllowedReactions(account: Account, peerId: PeerId, allo } } -func _internal_updateDefaultReaction(account: Account, reaction: String) -> Signal { - return account.network.request(Api.functions.messages.setDefaultReaction(reaction: reaction)) +func _internal_updateDefaultReaction(account: Account, reaction: MessageReaction.Reaction) -> Signal { + return account.network.request(Api.functions.messages.setDefaultReaction(reaction: reaction.apiReaction)) |> `catch` { _ -> Signal in return .single(.boolFalse) } diff --git a/submodules/TelegramCore/Sources/State/Serialization.swift b/submodules/TelegramCore/Sources/State/Serialization.swift index 9179723fed..8575ec3884 100644 --- a/submodules/TelegramCore/Sources/State/Serialization.swift +++ b/submodules/TelegramCore/Sources/State/Serialization.swift @@ -246,7 +246,7 @@ public class Serialization: NSObject, MTSerialization { return { response -> MTDatacenterAddressListData? in if let config = parser.parse(Buffer(data: response)) { switch config { - case let .config(_, _, _, _, _, dcOptions, _, _, _, _, _, _,_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _): + case let .config(_, _, _, _, _, dcOptions, _, _, _, _, _, _,_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _): var addressDict: [NSNumber: [Any]] = [:] for option in dcOptions { switch option { diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedChannelData.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedChannelData.swift index 14eec4aff8..3d97acf9b4 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedChannelData.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedChannelData.swift @@ -238,7 +238,7 @@ public final class CachedChannelData: CachedPeerData { public let themeEmoticon: String? public let inviteRequestsPending: Int32? public let sendAsPeerId: PeerId? - public let allowedReactions: [String]? + public let allowedReactions: [MessageReaction.Reaction]? public let peerIds: Set public let messageIds: Set @@ -307,7 +307,7 @@ public final class CachedChannelData: CachedPeerData { themeEmoticon: String?, inviteRequestsPending: Int32?, sendAsPeerId: PeerId?, - allowedReactions: [String]? + allowedReactions: [MessageReaction.Reaction]? ) { self.isNotAccessible = isNotAccessible self.flags = flags @@ -471,7 +471,7 @@ public final class CachedChannelData: CachedPeerData { return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: sendAsPeerId, allowedReactions: self.allowedReactions) } - public func withUpdatedAllowedReactions(_ allowedReactions: [String]?) -> CachedChannelData { + public func withUpdatedAllowedReactions(_ allowedReactions: [MessageReaction.Reaction]?) -> CachedChannelData { return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, allowedReactions: allowedReactions) } @@ -562,7 +562,13 @@ public final class CachedChannelData: CachedPeerData { self.sendAsPeerId = decoder.decodeOptionalInt64ForKey("sendAsPeerId").flatMap(PeerId.init) - self.allowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") + if let allowedReactions = decoder.decodeArray([MessageReaction.Reaction].self, forKey: "allowedReactionList") { + self.allowedReactions = allowedReactions + } else if let allowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") { + self.allowedReactions = allowedReactions.map(MessageReaction.Reaction.builtin) + } else { + self.allowedReactions = nil + } if case let .known(linkedDiscussionPeerIdValue) = self.linkedDiscussionPeerId { if let linkedDiscussionPeerIdValue = linkedDiscussionPeerIdValue { @@ -702,7 +708,6 @@ public final class CachedChannelData: CachedPeerData { encoder.encodeNil(forKey: "irp") } - if let sendAsPeerId = self.sendAsPeerId { encoder.encodeInt64(sendAsPeerId.toInt64(), forKey: "sendAsPeerId") } else { @@ -710,9 +715,9 @@ public final class CachedChannelData: CachedPeerData { } if let allowedReactions = self.allowedReactions { - encoder.encodeStringArray(allowedReactions, forKey: "allowedReactions") + encoder.encodeArray(allowedReactions, forKey: "allowedReactionList") } else { - encoder.encodeNil(forKey: "allowedReactions") + encoder.encodeNil(forKey: "allowedReactionList") } } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedGroupData.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedGroupData.swift index 5f556539a6..64f2479c90 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedGroupData.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedGroupData.swift @@ -55,7 +55,7 @@ public final class CachedGroupData: CachedPeerData { public let callJoinPeerId: PeerId? public let themeEmoticon: String? public let inviteRequestsPending: Int32? - public let allowedReactions: [String]? + public let allowedReactions: [MessageReaction.Reaction]? public let peerIds: Set public let messageIds: Set @@ -98,7 +98,7 @@ public final class CachedGroupData: CachedPeerData { callJoinPeerId: PeerId?, themeEmoticon: String?, inviteRequestsPending: Int32?, - allowedReactions: [String]? + allowedReactions: [MessageReaction.Reaction]? ) { self.participants = participants self.exportedInvitation = exportedInvitation @@ -180,7 +180,13 @@ public final class CachedGroupData: CachedPeerData { self.inviteRequestsPending = decoder.decodeOptionalInt32ForKey("irp") - self.allowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") + if let allowedReactions = decoder.decodeArray([MessageReaction.Reaction].self, forKey: "allowedReactionList") { + self.allowedReactions = allowedReactions + } else if let allowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") { + self.allowedReactions = allowedReactions.map(MessageReaction.Reaction.builtin) + } else { + self.allowedReactions = nil + } var messageIds = Set() if let pinnedMessageId = self.pinnedMessageId { @@ -273,9 +279,9 @@ public final class CachedGroupData: CachedPeerData { } if let allowedReactions = self.allowedReactions { - encoder.encodeStringArray(allowedReactions, forKey: "allowedReactions") + encoder.encodeArray(allowedReactions, forKey: "allowedReactionList") } else { - encoder.encodeNil(forKey: "allowedReactions") + encoder.encodeNil(forKey: "allowedReactionList") } } @@ -359,7 +365,7 @@ public final class CachedGroupData: CachedPeerData { return CachedGroupData(participants: self.participants, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, about: self.about, flags: self.flags, hasScheduledMessages: self.hasScheduledMessages, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, callJoinPeerId: self.callJoinPeerId, themeEmoticon: self.themeEmoticon, inviteRequestsPending: inviteRequestsPending, allowedReactions: self.allowedReactions) } - public func withUpdatedAllowedReactions(_ allowedReactions: [String]?) -> CachedGroupData { + public func withUpdatedAllowedReactions(_ allowedReactions: [MessageReaction.Reaction]?) -> CachedGroupData { return CachedGroupData(participants: self.participants, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, about: self.about, flags: self.flags, hasScheduledMessages: self.hasScheduledMessages, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, callJoinPeerId: self.callJoinPeerId, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, allowedReactions: allowedReactions) } } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_ReactionsMessageAttribute.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_ReactionsMessageAttribute.swift index 237ed3e02a..0c0e306188 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_ReactionsMessageAttribute.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_ReactionsMessageAttribute.swift @@ -1,37 +1,95 @@ import Postbox +import TelegramApi public struct MessageReaction: Equatable, PostboxCoding { - public var value: String + public enum Reaction: Hashable, Codable { + case builtin(String) + case custom(Int64) + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: StringCodingKey.self) + + if let value = try container.decodeIfPresent(String.self, forKey: "v") { + self = .builtin(value) + } else { + self = .custom(try container.decode(Int64.self, forKey: "cfid")) + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: StringCodingKey.self) + + switch self { + case let .builtin(value): + try container.encode(value, forKey: "v") + case let .custom(fileId): + try container.encode(fileId, forKey: "cfid") + } + } + } + + public var value: Reaction public var count: Int32 public var isSelected: Bool - public init(value: String, count: Int32, isSelected: Bool) { + public init(value: Reaction, count: Int32, isSelected: Bool) { self.value = value self.count = count self.isSelected = isSelected } public init(decoder: PostboxDecoder) { - self.value = decoder.decodeStringForKey("v", orElse: "") + if let value = decoder.decodeOptionalStringForKey("v") { + self.value = .builtin(value) + } else { + self.value = .custom(decoder.decodeInt64ForKey("cfid", orElse: 0)) + } self.count = decoder.decodeInt32ForKey("c", orElse: 0) self.isSelected = decoder.decodeInt32ForKey("s", orElse: 0) != 0 } public func encode(_ encoder: PostboxEncoder) { - encoder.encodeString(self.value, forKey: "v") + switch self.value { + case let .builtin(value): + encoder.encodeString(value, forKey: "v") + case let .custom(fileId): + encoder.encodeInt64(fileId, forKey: "cfid") + } encoder.encodeInt32(self.count, forKey: "c") encoder.encodeInt32(self.isSelected ? 1 : 0, forKey: "s") } } +extension MessageReaction.Reaction { + init?(apiReaction: Api.Reaction) { + switch apiReaction { + case .reactionEmpty: + return nil + case let .reactionEmoji(emoticon): + self = .builtin(emoticon) + case let .reactionCustomEmoji(documentId): + self = .custom(documentId) + } + } + + var apiReaction: Api.Reaction { + switch self { + case let .builtin(value): + return .reactionEmoji(emoticon: value) + case let .custom(fileId): + return .reactionCustomEmoji(documentId: fileId) + } + } +} + public final class ReactionsMessageAttribute: Equatable, MessageAttribute { public struct RecentPeer: Equatable, PostboxCoding { - public var value: String + public var value: MessageReaction.Reaction public var isLarge: Bool public var isUnseen: Bool public var peerId: PeerId - public init(value: String, isLarge: Bool, isUnseen: Bool, peerId: PeerId) { + public init(value: MessageReaction.Reaction, isLarge: Bool, isUnseen: Bool, peerId: PeerId) { self.value = value self.isLarge = isLarge self.isUnseen = isUnseen @@ -39,14 +97,23 @@ public final class ReactionsMessageAttribute: Equatable, MessageAttribute { } public init(decoder: PostboxDecoder) { - self.value = decoder.decodeStringForKey("v", orElse: "") + if let value = decoder.decodeOptionalStringForKey("v") { + self.value = .builtin(value) + } else { + self.value = .custom(decoder.decodeInt64ForKey("cfid", orElse: 0)) + } self.isLarge = decoder.decodeInt32ForKey("l", orElse: 0) != 0 self.isUnseen = decoder.decodeInt32ForKey("u", orElse: 0) != 0 self.peerId = PeerId(decoder.decodeInt64ForKey("p", orElse: 0)) } public func encode(_ encoder: PostboxEncoder) { - encoder.encodeString(self.value, forKey: "v") + switch self.value { + case let .builtin(value): + encoder.encodeString(value, forKey: "v") + case let .custom(fileId): + encoder.encodeInt64(fileId, forKey: "cfid") + } encoder.encodeInt32(self.isLarge ? 1 : 0, forKey: "l") encoder.encodeInt32(self.isUnseen ? 1 : 0, forKey: "u") encoder.encodeInt64(self.peerId.toInt64(), forKey: "p") @@ -116,7 +183,7 @@ public final class ReactionsMessageAttribute: Equatable, MessageAttribute { public final class PendingReactionsMessageAttribute: MessageAttribute { public let accountPeerId: PeerId? - public let value: String? + public let value: MessageReaction.Reaction? public let isLarge: Bool public var associatedPeerIds: [PeerId] { @@ -127,7 +194,7 @@ public final class PendingReactionsMessageAttribute: MessageAttribute { } } - public init(accountPeerId: PeerId?, value: String?, isLarge: Bool) { + public init(accountPeerId: PeerId?, value: MessageReaction.Reaction?, isLarge: Bool) { self.accountPeerId = accountPeerId self.value = value self.isLarge = isLarge @@ -135,7 +202,13 @@ public final class PendingReactionsMessageAttribute: MessageAttribute { required public init(decoder: PostboxDecoder) { self.accountPeerId = decoder.decodeOptionalInt64ForKey("ap").flatMap(PeerId.init) - self.value = decoder.decodeOptionalStringForKey("v") + if let value = decoder.decodeOptionalStringForKey("v") { + self.value = .builtin(value) + } else if let fileId = decoder.decodeOptionalInt64ForKey("cfid") { + self.value = .custom(fileId) + } else { + self.value = nil + } self.isLarge = decoder.decodeInt32ForKey("l", orElse: 0) != 0 } @@ -146,7 +219,12 @@ public final class PendingReactionsMessageAttribute: MessageAttribute { encoder.encodeNil(forKey: "ap") } if let value = self.value { - encoder.encodeString(value, forKey: "v") + switch value { + case let .builtin(value): + encoder.encodeString(value, forKey: "v") + case let .custom(fileId): + encoder.encodeInt64(fileId, forKey: "cfid") + } } else { encoder.encodeNil(forKey: "v") } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift index 6d54f2a338..21ed971f09 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift @@ -452,7 +452,7 @@ public extension TelegramEngine.EngineData.Item { } public struct AllowedReactions: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem { - public typealias Result = [String]? + public typealias Result = [MessageReaction.Reaction]? fileprivate var id: EnginePeer.Id public var mapKey: EnginePeer.Id { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Localization/Localizations.swift b/submodules/TelegramCore/Sources/TelegramEngine/Localization/Localizations.swift index b4db9bdc32..b4e59c4e66 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Localization/Localizations.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Localization/Localizations.swift @@ -9,7 +9,7 @@ func _internal_currentlySuggestedLocalization(network: Network, extractKeys: [St |> retryRequest |> mapToSignal { result -> Signal in switch result { - case let .config(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, suggestedLangCode, _, _): + case let .config(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, suggestedLangCode, _, _, _): if let suggestedLangCode = suggestedLangCode { return _internal_suggestedLocalizationInfo(network: network, languageCode: suggestedLangCode, extractKeys: extractKeys) |> map(Optional.init) } else { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift index 8dd88f94a7..f1fd558bfa 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift @@ -344,7 +344,7 @@ public extension TelegramEngine { } } - public func messageReactionList(message: EngineMessage, reaction: String?) -> EngineMessageReactionListContext { + public func messageReactionList(message: EngineMessage, reaction: MessageReaction.Reaction?) -> EngineMessageReactionListContext { return EngineMessageReactionListContext(account: self.account, message: message, reaction: reaction) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift index 6eeb70e3c7..05d601451a 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift @@ -694,7 +694,7 @@ public extension TelegramEngine { return _internal_updatePeerSendAsPeer(account: self.account, peerId: peerId, sendAs: sendAs) } - public func updatePeerAllowedReactions(peerId: PeerId, allowedReactions: [String]) -> Signal { + public func updatePeerAllowedReactions(peerId: PeerId, allowedReactions: [MessageReaction.Reaction]) -> Signal { return _internal_updatePeerAllowedReactions(account: account, peerId: peerId, allowedReactions: allowedReactions) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift index 31c2abda50..2e123e9ec3 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift @@ -389,7 +389,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee .withUpdatedCallJoinPeerId(groupCallDefaultJoinAs?.peerId) .withUpdatedThemeEmoticon(chatFullThemeEmoticon) .withUpdatedInviteRequestsPending(chatFullRequestsPending) - .withUpdatedAllowedReactions(allowedReactions ?? []) + .withUpdatedAllowedReactions(allowedReactions.flatMap({ $0.map(MessageReaction.Reaction.builtin) }) ?? []) }) case .channelFull: break @@ -627,7 +627,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee .withUpdatedThemeEmoticon(themeEmoticon) .withUpdatedInviteRequestsPending(requestsPending) .withUpdatedSendAsPeerId(sendAsPeerId) - .withUpdatedAllowedReactions(allowedReactions ?? []) + .withUpdatedAllowedReactions(allowedReactions.flatMap({ $0.map(MessageReaction.Reaction.builtin) }) ?? []) }) if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Stickers/TelegramEngineStickers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Stickers/TelegramEngineStickers.swift index 4159f4464a..2dab75738d 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Stickers/TelegramEngineStickers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Stickers/TelegramEngineStickers.swift @@ -105,7 +105,7 @@ public extension TelegramEngine { return _internal_cachedAvailableReactions(postbox: self.account.postbox) } - public func updateQuickReaction(reaction: String) -> Signal { + public func updateQuickReaction(reaction: MessageReaction.Reaction) -> Signal { let _ = updateReactionSettingsInteractively(postbox: self.account.postbox, { settings in var settings = settings settings.quickReaction = reaction diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index d9ec368967..3a5fe4f4dc 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -1290,7 +1290,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } - var updatedReaction: String? = reaction.rawValue + var updatedReaction: MessageReaction.Reaction? = reaction.rawValue var isFirst = true for attribute in topMessage.attributes { if let attribute = attribute as? ReactionsMessageAttribute { @@ -1434,7 +1434,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } - var updatedReaction: String? + var updatedReaction: MessageReaction.Reaction? switch reaction { case .default: updatedReaction = item.associatedData.defaultReaction @@ -1442,7 +1442,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G updatedReaction = value } - var removedReaction: String? + var removedReaction: MessageReaction.Reaction? var messageAlreadyHasThisReaction = false for attribute in message.attributes { @@ -6531,7 +6531,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard item.message.id == messageId else { return } - var maybeUpdatedReaction: (String, Bool, EnginePeer?)? + var maybeUpdatedReaction: (MessageReaction.Reaction, Bool, EnginePeer?)? if let attribute = item.message.reactionsAttribute { for recentPeer in attribute.recentPeers { if recentPeer.isUnseen { @@ -16701,7 +16701,7 @@ func canAddMessageReactions(message: Message) -> Bool { } enum AllowedReactions { - case set(Set) + case set(Set) case all } diff --git a/submodules/TelegramUI/Sources/ChatControllerInteraction.swift b/submodules/TelegramUI/Sources/ChatControllerInteraction.swift index 8c383a695e..b84ff770ef 100644 --- a/submodules/TelegramUI/Sources/ChatControllerInteraction.swift +++ b/submodules/TelegramUI/Sources/ChatControllerInteraction.swift @@ -49,7 +49,7 @@ public enum ChatControllerInteractionSwipeAction { public enum ChatControllerInteractionReaction { case `default` - case reaction(String) + case reaction(MessageReaction.Reaction) } struct UnreadMessageRangeKey: Hashable { @@ -63,7 +63,7 @@ public final class ChatControllerInteraction { let openPeerMention: (String) -> Void let openMessageContextMenu: (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void let updateMessageReaction: (Message, ChatControllerInteractionReaction) -> Void - let openMessageReactionContextMenu: (Message, ContextExtractedContentContainingView, ContextGesture?, String) -> Void + let openMessageReactionContextMenu: (Message, ContextExtractedContentContainingView, ContextGesture?, MessageReaction.Reaction) -> Void let activateMessagePinch: (PinchSourceContainerNode) -> Void let openMessageContextActions: (Message, ASDisplayNode, CGRect, ContextGesture?) -> Void let navigateToMessage: (MessageId, MessageId) -> Void @@ -167,7 +167,7 @@ public final class ChatControllerInteraction { openPeer: @escaping (PeerId?, ChatControllerInteractionNavigateToPeer, MessageReference?, Peer?) -> Void, openPeerMention: @escaping (String) -> Void, openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void, - openMessageReactionContextMenu: @escaping (Message, ContextExtractedContentContainingView, ContextGesture?, String) -> Void, + openMessageReactionContextMenu: @escaping (Message, ContextExtractedContentContainingView, ContextGesture?, MessageReaction.Reaction) -> Void, updateMessageReaction: @escaping (Message, ChatControllerInteractionReaction) -> Void, activateMessagePinch: @escaping (PinchSourceContainerNode) -> Void, openMessageContextActions: @escaping (Message, ASDisplayNode, CGRect, ContextGesture?) -> Void, diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index d40c4a6934..2b7c84e43b 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -314,7 +314,7 @@ private final class ChatHistoryTransactionOpaqueState { } } -private func extractAssociatedData(chatLocation: ChatLocation, view: MessageHistoryView, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, animatedEmojiStickers: [String: [StickerPackItem]], additionalAnimatedEmojiStickers: [String: [Int: StickerPackItem]], subject: ChatControllerSubject?, currentlyPlayingMessageId: MessageIndex?, isCopyProtectionEnabled: Bool, availableReactions: AvailableReactions?, defaultReaction: String?, isPremium: Bool) -> ChatMessageItemAssociatedData { +private func extractAssociatedData(chatLocation: ChatLocation, view: MessageHistoryView, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, animatedEmojiStickers: [String: [StickerPackItem]], additionalAnimatedEmojiStickers: [String: [Int: StickerPackItem]], subject: ChatControllerSubject?, currentlyPlayingMessageId: MessageIndex?, isCopyProtectionEnabled: Bool, availableReactions: AvailableReactions?, defaultReaction: MessageReaction.Reaction?, isPremium: Bool) -> ChatMessageItemAssociatedData { var automaticMediaDownloadPeerType: MediaAutoDownloadPeerType = .channel var contactsPeerIds: Set = Set() var channelDiscussionGroup: ChatMessageItemAssociatedData.ChannelDiscussionGroupStatus = .unknown @@ -983,7 +983,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { let availableReactions = context.engine.stickers.availableReactions() let defaultReaction = context.account.postbox.preferencesView(keys: [PreferencesKeys.reactionSettings]) - |> map { preferencesView -> String? in + |> map { preferencesView -> MessageReaction.Reaction? in let reactionSettings: ReactionSettings if let entry = preferencesView.values[PreferencesKeys.reactionSettings], let value = entry.get(ReactionSettings.self) { reactionSettings = value @@ -2338,9 +2338,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { let completion: (Bool, ListViewDisplayedItemRange) -> Void = { [weak self] wasTransformed, visibleRange in if let strongSelf = self { - var newIncomingReactions: [MessageId: (value: String, isLarge: Bool)] = [:] + var newIncomingReactions: [MessageId: (value: MessageReaction.Reaction, isLarge: Bool)] = [:] if case .peer = strongSelf.chatLocation, let previousHistoryView = strongSelf.historyView { - var updatedIncomingReactions: [MessageId: (value: String, isLarge: Bool)] = [:] + var updatedIncomingReactions: [MessageId: (value: MessageReaction.Reaction, isLarge: Bool)] = [:] for entry in transition.historyView.filteredEntries { switch entry { case let .MessageEntry(message, _, _, _, _, _): @@ -2375,7 +2375,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { switch entry { case let .MessageEntry(message, _, _, _, _, _): if let updatedReaction = updatedIncomingReactions[message.id] { - var previousReaction: String? + var previousReaction: MessageReaction.Reaction? if let reactions = message.reactionsAttribute { for recentPeer in reactions.recentPeers { if recentPeer.isUnseen { @@ -2390,7 +2390,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { case let .MessageGroupEntry(_, messages, _): for message in messages { if let updatedReaction = updatedIncomingReactions[message.0.id] { - var previousReaction: String? + var previousReaction: MessageReaction.Reaction? if let reactions = message.0.reactionsAttribute { for recentPeer in reactions.recentPeers { if recentPeer.isUnseen { @@ -2693,7 +2693,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { return } - var selectedReaction: (String, EnginePeer?, Bool)? + var selectedReaction: (MessageReaction.Reaction, EnginePeer?, Bool)? let recentPeers = forceMapping[item.content.firstMessage.id] ?? reactionsAttribute.recentPeers for recentPeer in recentPeers { if recentPeer.isUnseen { diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index 49e08d6c23..f6f8f30111 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -794,7 +794,11 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState continue } - subActions.append(.action(ContextMenuActionItem(text: reaction.value, icon: { _ in + guard case let .builtin(emojiValue) = reaction.value else { + continue + } + + subActions.append(.action(ContextMenuActionItem(text: emojiValue, icon: { _ in return nil }, action: { _, f in let _ = updateExperimentalUISettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in @@ -874,9 +878,9 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState currentItems = [] } - currentItems.removeAll(where: { $0.key == stickerName }) + currentItems.removeAll(where: { $0.key == MessageReaction.Reaction.builtin(stickerName) }) currentItems.append(ExperimentalUISettings.AccountReactionOverrides.Item( - key: stickerName, + key: .builtin(stickerName), messageId: message.id, mediaId: file.fileId )) diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index 5ad275307d..f710cacb55 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -2591,7 +2591,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { item.controllerInteraction.openMessageContextMenu(item.message, false, self, self.imageNode.frame, nil, nil) } - override func targetReactionView(value: String) -> UIView? { + override func targetReactionView(value: MessageReaction.Reaction) -> UIView? { if let result = self.reactionButtonsNode?.reactionTargetView(value: value) { return result } diff --git a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift index a2ff3fdca7..87fa1c9184 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift @@ -1164,7 +1164,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode { } } - func reactionTargetView(value: String) -> UIView? { + func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { if !self.statusNode.isHidden { if let result = self.statusNode.reactionView(value: value) { return result diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift index f7d557f2e8..8386d29697 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift @@ -217,7 +217,7 @@ class ChatMessageBubbleContentNode: ASDisplayNode { func unreadMessageRangeUpdated() { } - func reactionTargetView(value: String) -> UIView? { + func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { return nil } diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index edf7f2c29e..654afe9e8d 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -3974,7 +3974,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode item.controllerInteraction.openMessageContextMenu(item.message, true, self, subFrame, nil, nil) } - override func targetReactionView(value: String) -> UIView? { + override func targetReactionView(value: MessageReaction.Reaction) -> UIView? { if let result = self.reactionButtonsNode?.reactionTargetView(value: value) { return result } diff --git a/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift index 9a875ecb03..31491aabfb 100644 --- a/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift @@ -399,7 +399,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode { } } - override func reactionTargetView(value: String) -> UIView? { + override func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { if !self.dateAndStatusNode.isHidden { return self.dateAndStatusNode.reactionView(value: value) } diff --git a/submodules/TelegramUI/Sources/ChatMessageDateAndStatusNode.swift b/submodules/TelegramUI/Sources/ChatMessageDateAndStatusNode.swift index c5110500c3..d9f84e54ee 100644 --- a/submodules/TelegramUI/Sources/ChatMessageDateAndStatusNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageDateAndStatusNode.swift @@ -51,7 +51,7 @@ private final class StatusReactionNode: ASDisplayNode { private let iconImageDisposable = MetaDisposable() private var theme: PresentationTheme? - private var value: String? + private var value: MessageReaction.Reaction? private var isSelected: Bool? override init() { @@ -66,7 +66,7 @@ private final class StatusReactionNode: ASDisplayNode { self.iconImageDisposable.dispose() } - func update(context: AccountContext, type: ChatMessageDateAndStatusType, value: String, file: TelegramMediaFile?, isSelected: Bool, count: Int, theme: PresentationTheme, wallpaper: TelegramWallpaper, animated: Bool) { + func update(context: AccountContext, type: ChatMessageDateAndStatusType, value: MessageReaction.Reaction, file: TelegramMediaFile?, isSelected: Bool, count: Int, theme: PresentationTheme, wallpaper: TelegramWallpaper, animated: Bool) { if self.value != value { self.value = value @@ -147,7 +147,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { var constrainedSize: CGSize var availableReactions: AvailableReactions? var reactions: [MessageReaction] - var reactionPeers: [(String, EnginePeer)] + var reactionPeers: [(MessageReaction.Reaction, EnginePeer)] var replyCount: Int var isPinned: Bool var hasAutoremove: Bool @@ -164,7 +164,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { constrainedSize: CGSize, availableReactions: AvailableReactions?, reactions: [MessageReaction], - reactionPeers: [(String, EnginePeer)], + reactionPeers: [(MessageReaction.Reaction, EnginePeer)], replyCount: Int, isPinned: Bool, hasAutoremove: Bool, @@ -196,7 +196,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { private var clockMinNode: ASImageNode? private let dateNode: TextNode private var impressionIcon: ASImageNode? - private var reactionNodes: [String: StatusReactionNode] = [:] + private var reactionNodes: [MessageReaction.Reaction: StatusReactionNode] = [:] private let reactionButtonsContainer = ReactionButtonsAsyncLayoutContainer() private var reactionCountNode: TextNode? private var reactionButtonNode: HighlightTrackingButtonNode? @@ -225,8 +225,8 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { } } } - var reactionSelected: ((String) -> Void)? - var openReactionPreview: ((ContextGesture?, ContextExtractedContentContainingView, String) -> Void)? + var reactionSelected: ((MessageReaction.Reaction) -> Void)? + var openReactionPreview: ((ContextGesture?, ContextExtractedContentContainingView, MessageReaction.Reaction) -> Void)? override init() { self.dateNode = TextNode() @@ -1013,7 +1013,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { var reactionOffset: CGFloat = leftOffset + leftInset - reactionInset + backgroundInsets.left if arguments.layoutInput.displayInlineReactions { - var validReactions = Set() + var validReactions = Set() for reaction in arguments.reactions.sorted(by: { lhs, rhs in if lhs.isSelected != rhs.isSelected { if lhs.isSelected { @@ -1022,7 +1022,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { return false } } else { - return lhs.value < rhs.value + return lhs.count > rhs.count } }) { let node: StatusReactionNode @@ -1066,7 +1066,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { reactionOffset += reactionTrailingSpacing } - var removeIds: [String] = [] + var removeIds: [MessageReaction.Reaction] = [] for (id, node) in strongSelf.reactionNodes { if !validReactions.contains(id) { removeIds.append(id) @@ -1189,7 +1189,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { } } - func reactionView(value: String) -> UIView? { + func reactionView(value: MessageReaction.Reaction) -> UIView? { for (id, node) in self.reactionNodes { if id == value { return node.iconView diff --git a/submodules/TelegramUI/Sources/ChatMessageFileBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageFileBubbleContentNode.swift index 433cc7bc5e..e898b902a9 100644 --- a/submodules/TelegramUI/Sources/ChatMessageFileBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageFileBubbleContentNode.swift @@ -227,7 +227,7 @@ class ChatMessageFileBubbleContentNode: ChatMessageBubbleContentNode { return super.hitTest(point, with: event) } - override func reactionTargetView(value: String) -> UIView? { + override func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { if !self.interactiveFileNode.dateAndStatusNode.isHidden { return self.interactiveFileNode.dateAndStatusNode.reactionView(value: value) } diff --git a/submodules/TelegramUI/Sources/ChatMessageGameBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageGameBubbleContentNode.swift index 35f51b625f..b2b6000425 100644 --- a/submodules/TelegramUI/Sources/ChatMessageGameBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageGameBubbleContentNode.swift @@ -140,7 +140,7 @@ final class ChatMessageGameBubbleContentNode: ChatMessageBubbleContentNode { return self.contentNode.transitionNode(media: media) } - override func reactionTargetView(value: String) -> UIView? { + override func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { if !self.contentNode.statusNode.isHidden { return self.contentNode.statusNode.reactionView(value: value) } diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index 6766f2010a..e6751b0b0e 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -1333,7 +1333,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD } } - override func targetReactionView(value: String) -> UIView? { + override func targetReactionView(value: MessageReaction.Reaction) -> UIView? { if let result = self.reactionButtonsNode?.reactionTargetView(value: value) { return result } diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift index e5b7c7cb8d..d0b87b6282 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift @@ -69,7 +69,7 @@ struct ChatMessageDateAndStatus { var edited: Bool var viewCount: Int? var dateReactions: [MessageReaction] - var dateReactionPeers: [(String, EnginePeer)] + var dateReactionPeers: [(MessageReaction.Reaction, EnginePeer)] var dateReplies: Int var isPinned: Bool var dateText: String diff --git a/submodules/TelegramUI/Sources/ChatMessageInvoiceBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageInvoiceBubbleContentNode.swift index 2dd754cc31..3c960f0dac 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInvoiceBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInvoiceBubbleContentNode.swift @@ -136,7 +136,7 @@ final class ChatMessageInvoiceBubbleContentNode: ChatMessageBubbleContentNode { return self.contentNode.transitionNode(media: media) } - override func reactionTargetView(value: String) -> UIView? { + override func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { if !self.contentNode.statusNode.isHidden { return self.contentNode.statusNode.reactionView(value: value) } diff --git a/submodules/TelegramUI/Sources/ChatMessageItemView.swift b/submodules/TelegramUI/Sources/ChatMessageItemView.swift index 881e1cdecb..7f48d56237 100644 --- a/submodules/TelegramUI/Sources/ChatMessageItemView.swift +++ b/submodules/TelegramUI/Sources/ChatMessageItemView.swift @@ -682,7 +682,7 @@ public class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol var accessibilityData: ChatMessageAccessibilityData? var safeInsets = UIEdgeInsets() - var awaitingAppliedReaction: (String?, () -> Void)? + var awaitingAppliedReaction: (MessageReaction.Reaction?, () -> Void)? public required convenience init() { self.init(layerBacked: false) @@ -868,7 +868,7 @@ public class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol func openMessageContextMenu() { } - public func targetReactionView(value: String) -> UIView? { + public func targetReactionView(value: MessageReaction.Reaction) -> UIView? { return nil } diff --git a/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift index 022a4122f6..2bde308c51 100644 --- a/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift @@ -502,7 +502,7 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode { } } - override func reactionTargetView(value: String) -> UIView? { + override func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { if !self.dateAndStatusNode.isHidden { return self.dateAndStatusNode.reactionView(value: value) } diff --git a/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift index 3eb9af0c06..8ea5a05f53 100644 --- a/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift @@ -392,7 +392,7 @@ class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { return false } - override func reactionTargetView(value: String) -> UIView? { + override func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { if !self.interactiveImageNode.dateAndStatusNode.isHidden { return self.interactiveImageNode.dateAndStatusNode.reactionView(value: value) } diff --git a/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift index 1346e494d3..f1b0920182 100644 --- a/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift @@ -1754,7 +1754,7 @@ class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode { } } - override func reactionTargetView(value: String) -> UIView? { + override func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { if !self.statusNode.isHidden { return self.statusNode.reactionView(value: value) } diff --git a/submodules/TelegramUI/Sources/ChatMessageReactionsFooterContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageReactionsFooterContentNode.swift index 8db5c338b3..78eca7ae28 100644 --- a/submodules/TelegramUI/Sources/ChatMessageReactionsFooterContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageReactionsFooterContentNode.swift @@ -60,10 +60,10 @@ final class MessageReactionButtonsNode: ASDisplayNode { private var bubbleBackgroundNode: WallpaperBubbleBackgroundNode? private let container: ReactionButtonsAsyncLayoutContainer private var backgroundMaskView: UIView? - private var backgroundMaskButtons: [String: UIView] = [:] + private var backgroundMaskButtons: [MessageReaction.Reaction: UIView] = [:] - var reactionSelected: ((String) -> Void)? - var openReactionPreview: ((ContextGesture?, ContextExtractedContentContainingView, String) -> Void)? + var reactionSelected: ((MessageReaction.Reaction) -> Void)? + var openReactionPreview: ((ContextGesture?, ContextExtractedContentContainingView, MessageReaction.Reaction) -> Void)? override init() { self.container = ReactionButtonsAsyncLayoutContainer() @@ -268,7 +268,7 @@ final class MessageReactionButtonsNode: ASDisplayNode { let reactionButtons = reactionButtonsResult.apply(animation) - var validIds = Set() + var validIds = Set() for item in reactionButtons.items { validIds.insert(item.value) @@ -352,7 +352,7 @@ final class MessageReactionButtonsNode: ASDisplayNode { } } - var removeMaskIds: [String] = [] + var removeMaskIds: [MessageReaction.Reaction] = [] for (id, view) in strongSelf.backgroundMaskButtons { if !validIds.contains(id) { removeMaskIds.append(id) @@ -415,7 +415,7 @@ final class MessageReactionButtonsNode: ASDisplayNode { } } - func reactionTargetView(value: String) -> UIView? { + func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { for (key, button) in self.container.buttons { if key == value { return button.view.iconView @@ -569,7 +569,7 @@ final class ChatMessageReactionsFooterContentNode: ChatMessageBubbleContentNode return nil } - override func reactionTargetView(value: String) -> UIView? { + override func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { return self.buttonsNode.reactionTargetView(value: value) } } @@ -608,8 +608,8 @@ final class ChatMessageReactionButtonsNode: ASDisplayNode { private let buttonsNode: MessageReactionButtonsNode - var reactionSelected: ((String) -> Void)? - var openReactionPreview: ((ContextGesture?, ContextExtractedContentContainingView, String) -> Void)? + var reactionSelected: ((MessageReaction.Reaction) -> Void)? + var openReactionPreview: ((ContextGesture?, ContextExtractedContentContainingView, MessageReaction.Reaction) -> Void)? override init() { self.buttonsNode = MessageReactionButtonsNode() @@ -669,7 +669,7 @@ final class ChatMessageReactionButtonsNode: ASDisplayNode { animation.animator.updateFrame(layer: self.buttonsNode.layer, frame: self.buttonsNode.layer.frame.offsetBy(dx: 0.0, dy: -self.buttonsNode.layer.bounds.height / 2.0), completion: nil) } - func reactionTargetView(value: String) -> UIView? { + func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { return self.buttonsNode.reactionTargetView(value: value) } diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index 7ab3d9312d..17934e5570 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -1613,7 +1613,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { item.controllerInteraction.openMessageContextMenu(item.message, false, self, self.imageNode.frame, nil, nil) } - override func targetReactionView(value: String) -> UIView? { + override func targetReactionView(value: MessageReaction.Reaction) -> UIView? { if let result = self.reactionButtonsNode?.reactionTargetView(value: value) { return result } diff --git a/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift index 2df9ca3c88..25cadc1342 100644 --- a/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift @@ -773,7 +773,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } } - override func reactionTargetView(value: String) -> UIView? { + override func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { if !self.statusNode.isHidden { return self.statusNode.reactionView(value: value) } diff --git a/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift index 3a38fa9ecb..4f527c518d 100644 --- a/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift @@ -559,7 +559,7 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode { self.contentNode.updateTouchesAtPoint(point.flatMap { $0.offsetBy(dx: -contentNodeFrame.minX, dy: -contentNodeFrame.minY) }) } - override func reactionTargetView(value: String) -> UIView? { + override func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { return self.contentNode.reactionTargetView(value: value) } } diff --git a/submodules/TelegramUIPreferences/Sources/ExperimentalUISettings.swift b/submodules/TelegramUIPreferences/Sources/ExperimentalUISettings.swift index 012d60cf95..5db9e36288 100644 --- a/submodules/TelegramUIPreferences/Sources/ExperimentalUISettings.swift +++ b/submodules/TelegramUIPreferences/Sources/ExperimentalUISettings.swift @@ -6,11 +6,11 @@ import SwiftSignalKit public struct ExperimentalUISettings: Codable, Equatable { public struct AccountReactionOverrides: Equatable, Codable { public struct Item: Equatable, Codable { - public var key: String + public var key: MessageReaction.Reaction public var messageId: MessageId public var mediaId: MediaId - public init(key: String, messageId: MessageId, mediaId: MediaId) { + public init(key: MessageReaction.Reaction, messageId: MessageId, mediaId: MediaId) { self.key = key self.messageId = messageId self.mediaId = mediaId @@ -142,8 +142,8 @@ public struct ExperimentalUISettings: Codable, Equatable { self.inlineStickers = (try container.decodeIfPresent(Int32.self, forKey: "inlineStickers") ?? 0) != 0 self.localTranscription = (try container.decodeIfPresent(Int32.self, forKey: "localTranscription") ?? 0) != 0 self.enableReactionOverrides = try container.decodeIfPresent(Bool.self, forKey: "enableReactionOverrides") ?? false - self.accountReactionEffectOverrides = (try container.decodeIfPresent([AccountReactionOverrides].self, forKey: "accountReactionEffectOverrides")) ?? [] - self.accountStickerEffectOverrides = (try container.decodeIfPresent([AccountReactionOverrides].self, forKey: "accountStickerEffectOverrides")) ?? [] + self.accountReactionEffectOverrides = (try? container.decodeIfPresent([AccountReactionOverrides].self, forKey: "accountReactionEffectOverrides")) ?? [] + self.accountStickerEffectOverrides = (try? container.decodeIfPresent([AccountReactionOverrides].self, forKey: "accountStickerEffectOverrides")) ?? [] } public func encode(to encoder: Encoder) throws {