diff --git a/Telegram/NotificationService/Sources/NotificationService.swift b/Telegram/NotificationService/Sources/NotificationService.swift index 8c92b1ef94..deb4e1a3e9 100644 --- a/Telegram/NotificationService/Sources/NotificationService.swift +++ b/Telegram/NotificationService/Sources/NotificationService.swift @@ -1712,7 +1712,11 @@ private final class NotificationServiceHandler { var content = initialContent if let interactionAuthorId = interactionAuthorId { - if inAppNotificationSettings.displayNameOnLockscreen, let peer = transaction.getPeer(interactionAuthorId) { + if inAppNotificationSettings.displayNameOnLockscreen, var peer = transaction.getPeer(interactionAuthorId) { + if let channel = peer as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = transaction.getPeer(linkedMonoforumId) { + peer = mainChannel + } + var foundLocalId: String? transaction.enumerateDeviceContactImportInfoItems({ _, value in if let value = value as? TelegramDeviceContactImportedData { @@ -2026,7 +2030,11 @@ private final class NotificationServiceHandler { var content = initialContent if let interactionAuthorId = interactionAuthorId { - if inAppNotificationSettings.displayNameOnLockscreen, let peer = transaction.getPeer(interactionAuthorId) { + if inAppNotificationSettings.displayNameOnLockscreen, var peer = transaction.getPeer(interactionAuthorId) { + if let channel = peer as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = transaction.getPeer(linkedMonoforumId) { + peer = mainChannel + } + var foundLocalId: String? transaction.enumerateDeviceContactImportInfoItems({ _, value in if let value = value as? TelegramDeviceContactImportedData { diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 12c0d44b7e..f60d7511e2 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -14013,9 +14013,17 @@ Sorry for the inconvenience."; "Notification.PaidMessagePriceChanged.Stars_1" = "%@ Star"; "Notification.PaidMessagePriceChanged.Stars_any" = "%@ Stars"; "Notification.PaidMessagePriceChanged" = "%1$@ changed price to %2$@ per message"; -"Notification.PaidMessagePriceChangedAndEnabledChannelMessage" = "%1$@ changed price to %2$@ per message, and enabled messaging this channel"; "Notification.PaidMessagePriceChangedYou" = "You changed price to %1$@ per message"; -"Notification.PaidMessagePriceChangedAndEnabledChannelMessageYou" = "You changed price to %1$@ per message, and enabled messaging this channel"; + +"Notification.ChannelMessagePriceChanged_1" = "{name} set the private message price to %d star"; +"Notification.ChannelMessagePriceChanged_any" = "{name} set the private message price to %d stars"; +"Notification.ChannelMessagePriceZeroChanged" = "%@ now accepts private messages"; + +"Notification.ChannelMessagePriceChangedAndEnabledChannelMessage_1" = "{name} now accepts private messages for %d star"; +"Notification.ChannelMessagePriceChangedAndEnabledChannelMessage_any" = "{name} now accepts private messages for %d stars"; +"Notification.ChannelMessagePriceZeroChangedAndEnabledChannelMessage" = "%@ now accepts private messages"; + +"Notification.ChannelMessageDisabled" = "%@ no longer accepts private messages"; "Premium.MaxExpiringStoriesTextNumberFormat_1" = "**%d** story"; "Premium.MaxExpiringStoriesTextNumberFormat_any" = "**%d** stories"; @@ -14368,3 +14376,25 @@ Sorry for the inconvenience."; "PeerInfo.OptionTopics.Enabled" = "Enabled"; "PeerInfo.OptionTopics.Disabled" = "Disabled"; + +"ChannelMessages.Title" = "Allow Channel Messages"; +"ChannelMessages.Info" = "Allow users to send messages to your channel, with the option to charge a fee for each message."; +"ChannelMessages.SwitchTitle" = "Allow Channel Messages"; +"ChannelMessages.PriceSectionTitle" = "PRICE FOR EACH MESSAGE"; +"ChannelMessages.PriceSectionFooter" = "You will receive 85% of the selected fee for each incoming message."; + +"ChatList.MonoforumLabel" = "MESSAGES"; +"ChatList.MonoforumEmptyText" = "No messages here yet..."; + +"Chat.InlineTopicMenu.Reorder" = "Reorder"; +"Chat.InlineTopicMenu.Edit" = "Edit"; +"Chat.InlineTopicMenu.AllTab" = "All"; +"Chat.ChannelMessagesHint" = "Send a message to the channel's admin"; +"Chat.ChannelMessagesHintBadge" = "NEW"; + +"PeerInfo.AllowChannelMessages" = "Allow Channel Messages"; +"PeerInfo.AllowChannelMessages.On" = "On"; +"PeerInfo.AllowChannelMessages.Off" = "Off"; +"PeerInfo.ChannelMessages" = "Channel Messages"; + +"Chat.EmptyStateMonoforum.Text" = "Send a direct message to the administrator of **%@**."; diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 6ba78eb0f2..b4c716e0f0 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -1118,6 +1118,7 @@ public protocol SharedAccountContext: AnyObject { func makeCollectibleItemInfoScreen(context: AccountContext, initialData: CollectibleItemInfoScreenInitialData) -> ViewController func makeCollectibleItemInfoScreenInitialData(context: AccountContext, peerId: EnginePeer.Id, subject: CollectibleItemInfoScreenSubject) -> Signal func makeBotSettingsScreen(context: AccountContext, peerId: EnginePeer.Id?) -> ViewController + func makeEditForumTopicScreen(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64, threadInfo: EngineMessageHistoryThread.Info, isHidden: Bool) -> ViewController func navigateToChatController(_ params: NavigateToChatControllerParams) func navigateToForumChannel(context: AccountContext, peerId: EnginePeer.Id, navigationController: NavigationController) diff --git a/submodules/AccountContext/Sources/PeerSelectionController.swift b/submodules/AccountContext/Sources/PeerSelectionController.swift index aef3c6d9ff..c08d6edcdb 100644 --- a/submodules/AccountContext/Sources/PeerSelectionController.swift +++ b/submodules/AccountContext/Sources/PeerSelectionController.swift @@ -50,7 +50,7 @@ public final class PeerSelectionControllerParams { public let updatedPresentationData: (initial: PresentationData, signal: Signal)? public let filter: ChatListNodePeersFilter public let requestPeerType: [ReplyMarkupButtonRequestPeerType]? - public let forumPeerId: EnginePeer.Id? + public let forumPeerId: (id: EnginePeer.Id, isMonoforum: Bool)? public let hasFilters: Bool public let hasChatListSelector: Bool public let hasContactSelector: Bool @@ -72,7 +72,7 @@ public final class PeerSelectionControllerParams { updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, filter: ChatListNodePeersFilter = [.onlyWriteable], requestPeerType: [ReplyMarkupButtonRequestPeerType]? = nil, - forumPeerId: EnginePeer.Id? = nil, + forumPeerId: (id: EnginePeer.Id, isMonoforum: Bool)? = nil, hasFilters: Bool = false, hasChatListSelector: Bool = true, hasContactSelector: Bool = true, diff --git a/submodules/AttachmentUI/Sources/AttachmentPanel.swift b/submodules/AttachmentUI/Sources/AttachmentPanel.swift index 6f53f3e534..c030d277eb 100644 --- a/submodules/AttachmentUI/Sources/AttachmentPanel.swift +++ b/submodules/AttachmentUI/Sources/AttachmentPanel.swift @@ -1191,7 +1191,8 @@ final class AttachmentPanel: ASDisplayNode, ASScrollViewDelegate { canMakePaidContent: canMakePaidContent, currentPrice: currentPrice, hasTimers: hasTimers, - sendPaidMessageStars: strongSelf.presentationInterfaceState.sendPaidMessageStars + sendPaidMessageStars: strongSelf.presentationInterfaceState.sendPaidMessageStars, + isMonoforum: strongSelf.presentationInterfaceState.renderedPeer?.peer?.isMonoForum ?? false )), hasEntityKeyboard: hasEntityKeyboard, gesture: gesture, @@ -1297,7 +1298,11 @@ final class AttachmentPanel: ASDisplayNode, ASScrollViewDelegate { if let data = view.cachedData as? CachedUserData { return data.sendPaidMessageStars } else if let channel = peerViewMainPeer(view) as? TelegramChannel { - return channel.sendPaidMessageStars + if channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = view.peers[linkedMonoforumId] as? TelegramChannel, mainChannel.hasPermission(.sendSomething) { + return nil + } else { + return channel.sendPaidMessageStars + } } else { return nil } diff --git a/submodules/AvatarNode/Sources/AvatarNode.swift b/submodules/AvatarNode/Sources/AvatarNode.swift index c72505e5a1..31113827f4 100644 --- a/submodules/AvatarNode/Sources/AvatarNode.swift +++ b/submodules/AvatarNode/Sources/AvatarNode.swift @@ -35,6 +35,7 @@ public enum AvatarNodeClipStyle { case none case round case roundedRect + case bubble } private class AvatarNodeParameters: NSObject { @@ -272,6 +273,30 @@ public final class AvatarEditOverlayNode: ASDisplayNode { } public final class AvatarNode: ASDisplayNode { + public static func avatarBubbleMask(size: CGSize) -> UIImage! { + return generateImage(size, rotatedContext: { size, context in + context.clear(CGRect(origin: CGPoint(), size: size)) + context.setFillColor(UIColor.white.cgColor) + AvatarNode.addAvatarBubblePath(context: context, rect: CGRect(origin: CGPoint(), size: size)) + context.fillPath() + }) + } + + public static func addAvatarBubblePath(context: CGContext, rect: CGRect) { + if let path = try? convertSvgPath("M60,30.274903 C60,46.843446 46.568544,60.274904 30,60.274904 C13.431458,60.274904 0,46.843446 0,30.274903 C0,23.634797 2.158635,17.499547 5.810547,12.529785 L6.036133,12.226074 C6.921364,10.896042 7.367402,8.104698 5.548828,5.316895 C3.606939,2.340088 1.186019,0.979668 2.399414,0.470215 C3.148032,0.156204 7.572027,0.000065 10.764648,1.790527 C12.148517,2.56662 13.2296,3.342422 14.09224,4.039734 C14.42622,4.309704 14.892063,4.349773 15.265962,4.138523 C19.618079,1.679604 24.644722,0.274902 30,0.274902 C46.568544,0.274902 60,13.70636 60,30.274903 Z ") { + let sx = rect.width / 60.0 + let sy = rect.height / 60.0 + var transform = CGAffineTransform( + a: sx, b: 0.0, + c: 0.0, d: -sy, + tx: rect.minX, + ty: rect.minY + rect.height + ) + let transformedPath = path.copy(using: &transform)! + context.addPath(transformedPath) + } + } + public static let gradientColors: [[UIColor]] = [ [UIColor(rgb: 0xff516a), UIColor(rgb: 0xff885e)], [UIColor(rgb: 0xffa85c), UIColor(rgb: 0xffcd6a)], @@ -335,6 +360,7 @@ public final class AvatarNode: ASDisplayNode { private var theme: PresentationTheme? private var overrideImage: AvatarNodeImageOverride? public let imageNode: ImageNode + private var imageNodeMask: UIImageView? public var editOverlayNode: AvatarEditOverlayNode? private let imageReadyDisposable = MetaDisposable() @@ -399,7 +425,7 @@ public final class AvatarNode: ASDisplayNode { self.displaysAsynchronously = true self.disableClearContentsOnHide = true - self.imageNode.isLayerBacked = true + self.imageNode.isUserInteractionEnabled = false self.addSubnode(self.imageNode) self.imageNode.contentUpdated = { [weak self] image in @@ -434,6 +460,9 @@ public final class AvatarNode: ASDisplayNode { public func updateSize(size: CGSize) { self.imageNode.frame = CGRect(origin: CGPoint(), size: size) self.editOverlayNode?.frame = self.imageNode.frame + if let imageNodeMask = self.imageNodeMask { + imageNodeMask.frame = CGRect(origin: CGPoint(), size: size) + } if !self.displaySuspended { self.setNeedsDisplay() self.editOverlayNode?.setNeedsDisplay() @@ -678,6 +707,7 @@ public final class AvatarNode: ASDisplayNode { if self.params == params { return } + let previousSize = self.params?.displayDimensions self.params = params switch clipStyle { @@ -690,6 +720,29 @@ public final class AvatarNode: ASDisplayNode { case .roundedRect: self.imageNode.clipsToBounds = true self.imageNode.cornerRadius = displayDimensions.height * 0.25 + case .bubble: + break + } + + if case .bubble = clipStyle { + var updateMask = false + let imageNodeMask: UIImageView + if let current = self.imageNodeMask { + imageNodeMask = current + updateMask = previousSize != params.displayDimensions + } else { + imageNodeMask = UIImageView() + self.imageNodeMask = imageNodeMask + self.imageNode.view.mask = imageNodeMask + imageNodeMask.frame = self.imageNode.frame + updateMask = true + } + if updateMask { + imageNodeMask.image = AvatarNode.avatarBubbleMask(size: params.displayDimensions) + } + } else if self.imageNodeMask != nil { + self.imageNodeMask = nil + self.imageNode.view.mask = nil } if let imageCache = genericContext.imageCache as? DirectMediaImageCache, let peer, let smallProfileImage = peer.smallProfileImage, let peerReference = PeerReference(peer._asPeer()) { @@ -902,6 +955,10 @@ public final class AvatarNode: ASDisplayNode { context.beginPath() context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: bounds.size.width, height: bounds.size.height), cornerRadius: floor(bounds.size.width * 0.25)).cgPath) context.clip() + } else if case .bubble = parameters.clipStyle { + context.beginPath() + AvatarNode.addAvatarBubblePath(context: context, rect: CGRect(x: 0.0, y: 0.0, width: bounds.size.width, height: bounds.size.height)) + context.clip() } } else { colors = grayscaleColors @@ -1472,3 +1529,4 @@ public final class AvatarNode: ASDisplayNode { } } } + diff --git a/submodules/AvatarNode/Sources/PeerAvatar.swift b/submodules/AvatarNode/Sources/PeerAvatar.swift index d6ac7578ed..e4c3bf1fc4 100644 --- a/submodules/AvatarNode/Sources/PeerAvatar.swift +++ b/submodules/AvatarNode/Sources/PeerAvatar.swift @@ -214,6 +214,16 @@ public func peerAvatarImage(postbox: Postbox, network: Network, peerReference: P case .roundedRect: context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: displayDimensions.width, height: displayDimensions.height).insetBy(dx: inset, dy: inset), cornerRadius: floor(displayDimensions.width * 0.25)).cgPath) context.clip() + case .bubble: + let rect = CGRect(origin: CGPoint(), size: displayDimensions).insetBy(dx: inset, dy: inset) + context.translateBy(x: rect.midX, y: rect.midY) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -rect.midX, y: -rect.midY) + AvatarNode.addAvatarBubblePath(context: context, rect: rect) + context.translateBy(x: rect.midX, y: rect.midY) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -rect.midX, y: -rect.midY) + context.clip() } var shouldBlur = false @@ -265,6 +275,8 @@ public func peerAvatarImage(postbox: Postbox, network: Network, peerReference: P } case .roundedRect: break + case .bubble: + break } } else { if let emptyColor = emptyColor { @@ -279,6 +291,16 @@ public func peerAvatarImage(postbox: Postbox, network: Network, peerReference: P context.beginPath() context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: displayDimensions.width, height: displayDimensions.height).insetBy(dx: inset, dy: inset), cornerRadius: floor(displayDimensions.width * 0.25)).cgPath) context.fillPath() + case .bubble: + let rect = CGRect(origin: CGPoint(), size: displayDimensions).insetBy(dx: inset, dy: inset) + context.translateBy(x: rect.midX, y: rect.midY) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -rect.midX, y: -rect.midY) + AvatarNode.addAvatarBubblePath(context: context, rect: rect) + context.translateBy(x: rect.midX, y: rect.midY) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -rect.midX, y: -rect.midY) + context.clip() } } } @@ -295,6 +317,16 @@ public func peerAvatarImage(postbox: Postbox, network: Network, peerReference: P context.beginPath() context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: displayDimensions.width, height: displayDimensions.height).insetBy(dx: inset, dy: inset), cornerRadius: floor(displayDimensions.width * 0.25)).cgPath) context.fillPath() + case .bubble: + let rect = CGRect(origin: CGPoint(), size: displayDimensions).insetBy(dx: inset, dy: inset) + context.translateBy(x: rect.midX, y: rect.midY) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -rect.midX, y: -rect.midY) + AvatarNode.addAvatarBubblePath(context: context, rect: rect) + context.translateBy(x: rect.midX, y: rect.midY) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -rect.midX, y: -rect.midY) + context.clip() } } @@ -332,6 +364,16 @@ public func peerAvatarImage(postbox: Postbox, network: Network, peerReference: P context.beginPath() context.addPath(UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: displayDimensions.width, height: displayDimensions.height).insetBy(dx: inset, dy: inset), cornerRadius: floor(displayDimensions.width * 0.25)).cgPath) context.fillPath() + case .bubble: + let rect = CGRect(origin: CGPoint(), size: displayDimensions).insetBy(dx: inset, dy: inset) + context.translateBy(x: rect.midX, y: rect.midY) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -rect.midX, y: -rect.midY) + AvatarNode.addAvatarBubblePath(context: context, rect: rect) + context.translateBy(x: rect.midX, y: rect.midY) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -rect.midX, y: -rect.midY) + context.clip() } } }) diff --git a/submodules/ChatListUI/Sources/ChatContextMenus.swift b/submodules/ChatListUI/Sources/ChatContextMenus.swift index 2dfab03f46..e909cc633c 100644 --- a/submodules/ChatListUI/Sources/ChatContextMenus.swift +++ b/submodules/ChatListUI/Sources/ChatContextMenus.swift @@ -581,7 +581,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch } } -func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId: Int64, isPinned: Bool?, isClosed: Bool?, chatListController: ChatListControllerImpl?, joined: Bool, canSelect: Bool) -> Signal<[ContextMenuItem], NoError> { +public func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId: Int64, isPinned: Bool?, isClosed: Bool?, chatListController: ViewController?, joined: Bool, canSelect: Bool, customEdit: ((ContextController) -> Void)? = nil, customPinUnpin: ((ContextController) -> Void)? = nil, reorder: (() -> Void)? = nil) -> Signal<[ContextMenuItem], NoError> { let presentationData = context.sharedContext.currentPresentationData.with({ $0 }) let strings = presentationData.strings @@ -603,8 +603,17 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId: if let isClosed = isClosed, isClosed && threadId != 1 { } else { - if let isPinned = isPinned, channel.hasPermission(.manageTopics) { - items.append(.action(ContextMenuActionItem(text: isPinned ? presentationData.strings.ChatList_Context_Unpin : presentationData.strings.ChatList_Context_Pin, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isPinned ? "Chat/Context Menu/Unpin": "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { _, f in + if let isPinned, channel.hasPermission(.manageTopics) { + items.append(.action(ContextMenuActionItem(text: isPinned ? presentationData.strings.ChatList_Context_Unpin : presentationData.strings.ChatList_Context_Pin, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isPinned ? "Chat/Context Menu/Unpin": "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { c, f in + if let customPinUnpin { + if let c = c as? ContextController { + customPinUnpin(c) + } else { + f(.default) + } + return + } + f(.default) let _ = (context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: threadId) @@ -621,6 +630,14 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId: } }) }))) + + if isPinned, let reorder { + items.append(.action(ContextMenuActionItem(text: presentationData.strings.Chat_InlineTopicMenu_Reorder, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ReorderItems"), color: theme.contextMenu.primaryColor) }, action: { c, _ in + c?.dismiss(completion: { + }) + reorder() + }))) + } } } @@ -636,6 +653,26 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId: }))) } + var canOpenClose = false + if channel.flags.contains(.isCreator) { + canOpenClose = true + } else if channel.hasPermission(.manageTopics) { + canOpenClose = true + } else if threadData.isOwnedByMe { + canOpenClose = true + } + + if threadId != 1, canOpenClose, let customEdit { + items.append(.action(ContextMenuActionItem(text: presentationData.strings.Chat_InlineTopicMenu_Edit, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Edit"), color: theme.contextMenu.primaryColor) }, action: { c, f in + if let c = c as? ContextController { + customEdit(c) + } else { + f(.default) + } + return + }))) + } + var isMuted = false switch threadData.notificationSettings.muteState { case .muted: @@ -863,14 +900,6 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId: }))) if threadId != 1 { - var canOpenClose = false - if channel.flags.contains(.isCreator) { - canOpenClose = true - } else if channel.hasPermission(.manageTopics) { - canOpenClose = true - } else if threadData.isOwnedByMe { - canOpenClose = true - } if canOpenClose { items.append(.action(ContextMenuActionItem(text: threadData.isClosed ? presentationData.strings.ChatList_Context_ReopenTopic : presentationData.strings.ChatList_Context_CloseTopic, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: threadData.isClosed ? "Chat/Context Menu/Play": "Chat/Context Menu/Pause"), color: theme.contextMenu.primaryColor) }, action: { _, f in f(.default) @@ -882,14 +911,36 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId: items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_Delete, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak chatListController] _, f in f(.default) - chatListController?.deletePeerThread(peerId: peerId, threadId: threadId) + if let chatListController = chatListController as? ChatListControllerImpl { + chatListController.deletePeerThread(peerId: peerId, threadId: threadId) + } else if let chatListController { + let actionSheet = ActionSheetController(presentationData: presentationData) + var items: [ActionSheetItem] = [] + + items.append(ActionSheetTextItem(title: presentationData.strings.ChatList_DeleteTopicConfirmationText, parseMarkdown: true)) + items.append(ActionSheetButtonItem(title: presentationData.strings.ChatList_DeleteTopicConfirmationAction, color: .destructive, action: { [weak actionSheet] in + actionSheet?.dismissAnimated() + let _ = context.engine.peers.removeForumChannelThread(id: peerId, threadId: threadId).startStandalone(completed: { + }) + })) + + actionSheet.setItemGroups([ + ActionSheetItemGroup(items: items), + ActionSheetItemGroup(items: [ + ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in + actionSheet?.dismissAnimated() + }) + ]) + ]) + chatListController.present(actionSheet, in: .window(.root)) + } }))) } } - if canSelect { + if canSelect, let chatListController = chatListController as? ChatListControllerImpl { items.append(.separator) - items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_Select, textColor: .primary, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in + items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_Select, textColor: .primary, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { [weak chatListController] _, f in f(.default) chatListController?.selectPeerThread(peerId: peerId, threadId: threadId) }))) diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 269bc6efcb..3367102c6b 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -5290,7 +5290,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController func deletePeerChat(peerId: PeerId, joined: Bool) { let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.RenderedPeer(id: peerId)) |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in - guard let strongSelf = self, let peer = peer, let chatPeer = peer.peers[peer.peerId], let mainPeer = peer.chatMainPeer else { + guard let strongSelf = self, let peer = peer, let chatPeer = peer.peers[peer.peerId], let mainPeer = peer.chatOrMonoforumMainPeer else { return } strongSelf.view.window?.endEditing(true) diff --git a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift index 64daba37ad..fd486ba5c7 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift @@ -145,6 +145,9 @@ private enum ChatListRecentEntry: Comparable, Identifiable { if case .secretChat = maybeChatPeer, let associatedPeerId = maybeChatPeer._asPeer().associatedPeerId, let associatedPeer = peer.peer.peers[associatedPeerId] { primaryPeer = EnginePeer(associatedPeer) chatPeer = maybeChatPeer + } else if case .channel = maybeChatPeer, let mainChannel = peer.peer.chatOrMonoforumMainPeer { + primaryPeer = EnginePeer(mainChannel) + chatPeer = maybeChatPeer } else { primaryPeer = maybeChatPeer chatPeer = maybeChatPeer @@ -2987,6 +2990,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode { var associatedPeer: EnginePeer? if case let .secretChat(secretChat) = peer, let associatedPeerId = secretChat.associatedPeerId { associatedPeer = renderedPeer.peers[associatedPeerId] + } else if case let .channel(channel) = peer, channel.isMonoForum { + associatedPeer = renderedPeer.chatOrMonoforumMainPeer } entries.append(.recentlySearchedPeer(peer, associatedPeer, foundLocalPeers.unread[peer.id], index, presentationData.theme, presentationData.strings, presentationData.nameSortOrder, presentationData.nameDisplayOrder, nil, false)) @@ -2998,8 +3003,13 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode { if lowercasedQuery.count > 1 { for peer in recentPeers { + let renderedPeer = peer if let peer = peer.peer.chatMainPeer, !existingPeerIds.contains(peer.id) { let peer = EnginePeer(peer) + var associatedPeer: EnginePeer? + if case let .channel(channel) = peer, channel.isMonoForum { + associatedPeer = renderedPeer.peer.chatOrMonoforumMainPeer.flatMap(EnginePeer.init) + } var matches = false if case let .user(user) = peer { @@ -3014,7 +3024,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode { if matches { existingPeerIds.insert(peer.id) - entries.append(.localPeer(peer, nil, nil, index, presentationData.theme, presentationData.strings, presentationData.nameSortOrder, presentationData.nameDisplayOrder, localExpandType, nil, false, false)) + entries.append(.localPeer(peer, associatedPeer, nil, index, presentationData.theme, presentationData.strings, presentationData.nameSortOrder, presentationData.nameDisplayOrder, localExpandType, nil, false, false)) } } } @@ -3035,6 +3045,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode { var associatedPeer: EnginePeer? if case let .secretChat(secretChat) = peer, let associatedPeerId = secretChat.associatedPeerId { associatedPeer = renderedPeer.peers[associatedPeerId] + } else if case let .channel(channel) = peer, channel.isMonoForum { + associatedPeer = renderedPeer.chatOrMonoforumMainPeer } entries.append(.localPeer(peer, associatedPeer, foundLocalPeers.unread[peer.id], index, presentationData.theme, presentationData.strings, presentationData.nameSortOrder, presentationData.nameDisplayOrder, localExpandType, nil, false, false)) @@ -3078,6 +3090,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode { if !existingPeerIds.contains(peer.peer.id), filteredPeer(EnginePeer(peer.peer), EnginePeer(accountPeer)) { existingPeerIds.insert(peer.peer.id) + entries.append(.globalPeer(peer, nil, index, presentationData.theme, presentationData.strings, presentationData.nameSortOrder, presentationData.nameDisplayOrder, globalExpandType, nil, false, finalQuery)) index += 1 numberOfGlobalPeers += 1 diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index 4f5a1f5393..cad55bfac3 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -1318,6 +1318,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { private var inlineNavigationMarkLayer: SimpleLayer? public let titleNode: TextNode + private var titleBadge: (backgroundView: UIImageView, textNode: TextNode)? public let authorNode: AuthorNode private var compoundHighlightingNode: LinkHighlightingNode? private var textArrowNode: ASImageNode? @@ -1835,10 +1836,19 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { self.avatarNode.font = avatarPlaceholderFont(size: avatarFontSize) } } - if peer.smallProfileImage != nil && overrideImage == nil { - self.avatarNode.setPeerV2(context: item.context, theme: item.presentationData.theme, peer: peer, overrideImage: overrideImage, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, clipStyle: isForumAvatar ? .roundedRect : .round, synchronousLoad: synchronousLoads, displayDimensions: CGSize(width: avatarDiameter, height: avatarDiameter)) + let avatarClipStyle: AvatarNodeClipStyle + if peerIsMonoforum { + avatarClipStyle = .bubble + } else if isForumAvatar { + avatarClipStyle = .roundedRect } else { - self.avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: peer, overrideImage: overrideImage, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, clipStyle: isForumAvatar ? .roundedRect : .round, synchronousLoad: synchronousLoads, displayDimensions: CGSize(width: 60.0, height: 60.0)) + avatarClipStyle = .round + } + + if peer.smallProfileImage != nil && overrideImage == nil { + self.avatarNode.setPeerV2(context: item.context, theme: item.presentationData.theme, peer: peer, overrideImage: overrideImage, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, clipStyle: avatarClipStyle, synchronousLoad: synchronousLoads, displayDimensions: CGSize(width: avatarDiameter, height: avatarDiameter)) + } else { + self.avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: peer, overrideImage: overrideImage, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, clipStyle: avatarClipStyle, synchronousLoad: synchronousLoads, displayDimensions: CGSize(width: 60.0, height: 60.0)) } if peer.isPremium && peer.id != item.context.account.peerId { @@ -2028,6 +2038,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { let textLayout = TextNodeWithEntities.asyncLayout(self.textNode) let makeTrailingTextBadgeLayout = TextNode.asyncLayout(self.trailingTextBadgeNode) let titleLayout = TextNode.asyncLayout(self.titleNode) + let titleBadgeLayout = TextNode.asyncLayout(self.titleBadge?.textNode) let authorLayout = self.authorNode.asyncLayout() let makeMeasureLayout = TextNode.asyncLayout(self.measureNode) let inputActivitiesLayout = self.inputActivitiesNode.asyncLayout() @@ -2226,6 +2237,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { var textLeftCutout: CGFloat = 0.0 var dateAttributedString: NSAttributedString? var titleAttributedString: NSAttributedString? + var titleBadgeText: String? var badgeContent = ChatListBadgeContent.none var mentionBadgeContent = ChatListBadgeContent.none var statusState = ChatListStatusNodeState.none @@ -3001,12 +3013,10 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { } else { textColor = theme.titleColor } - //TODO:localize if case let .channel(channel) = itemPeer.peer, channel.flags.contains(.isMonoforum) { - titleAttributedString = NSAttributedString(string: "\(displayTitle) Messages", font: titleFont, textColor: textColor) - } else { - titleAttributedString = NSAttributedString(string: displayTitle, font: titleFont, textColor: textColor) + titleBadgeText = item.presentationData.strings.ChatList_MonoforumLabel } + titleAttributedString = NSAttributedString(string: displayTitle, font: titleFont, textColor: textColor) } case .group: titleAttributedString = NSAttributedString(string: item.presentationData.strings.ChatList_ArchivedChatsTitle, font: titleFont, textColor: theme.titleColor) @@ -3224,7 +3234,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { default: break } - } else if case let .chat(itemPeer) = contentPeer, let peer = itemPeer.chatMainPeer { + } else if case let .chat(itemPeer) = contentPeer, let peer = itemPeer.chatOrMonoforumMainPeer { if peer.isSubscription { isSubscription = true } @@ -3369,7 +3379,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { } else if case let .peer(peer) = item.content, case let .channel(channel) = peer.peer.peer, channel.flags.contains(.isMonoforum) { if forumThread != nil || !topForumTopicItems.isEmpty { if let forumThread { - isFirstForumThreadSelectable = forumThread.isUnread + isFirstForumThreadSelectable = false forumThreads.append((id: forumThread.id, threadPeer: forumThread.threadPeer, title: NSAttributedString(string: forumThread.threadPeer?.compactDisplayTitle ?? " ", font: textFont, textColor: forumThread.isUnread || isSearching ? theme.authorNameColor : theme.messageTextColor), iconId: nil, iconColor: nil)) } for topicItem in topForumTopicItems { @@ -3463,11 +3473,19 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { titleAttributedString = NSAttributedString(string: " ", font: titleFont, textColor: theme.titleColor) } - let titleRectWidth = rawContentWidth - dateLayout.size.width - 10.0 - statusWidth - titleIconsWidth + var titleRectWidth = rawContentWidth - dateLayout.size.width - 10.0 - statusWidth - titleIconsWidth var titleCutout: TextNodeCutout? if !titleLeftCutout.isZero { titleCutout = TextNodeCutout(topLeft: CGSize(width: titleLeftCutout, height: 10.0), topRight: nil, bottomRight: nil) } + + var titleBadgeLayoutAndApply: (TextNodeLayout, () -> TextNode)? + if let titleBadgeText { + let titleBadgeLayoutAndApplyValue = titleBadgeLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: titleBadgeText, font: Font.semibold(11.0), textColor: theme.titleColor.withMultipliedAlpha(0.4)), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: titleRectWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + titleBadgeLayoutAndApply = titleBadgeLayoutAndApplyValue + titleRectWidth = max(10.0, titleRectWidth - titleBadgeLayoutAndApplyValue.0.size.width - 8.0) + } + let (titleLayout, titleApply) = titleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: maxTitleLines, truncationType: .end, constrainedSize: CGSize(width: titleRectWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: titleCutout, insets: UIEdgeInsets())) var inputActivitiesSize: CGSize? @@ -4244,6 +4262,36 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { let contentDelta = CGPoint(x: contentRect.origin.x - (strongSelf.titleNode.frame.minX - titleOffset), y: contentRect.origin.y - (strongSelf.titleNode.frame.minY - UIScreenPixel)) let titleFrame = CGRect(origin: CGPoint(x: contentRect.origin.x + titleOffset, y: contentRect.origin.y + UIScreenPixel), size: titleLayout.size) strongSelf.titleNode.frame = titleFrame + + if let (titleBadgeLayout, titleBadgeApply) = titleBadgeLayoutAndApply { + let titleBadgeNode = titleBadgeApply() + let backgroundView: UIImageView + if let current = strongSelf.titleBadge { + backgroundView = current.backgroundView + } else { + backgroundView = UIImageView(image: generateStretchableFilledCircleImage(radius: 4.0, color: .white)?.withRenderingMode(.alwaysTemplate)) + strongSelf.titleBadge = (backgroundView, titleBadgeNode) + + strongSelf.mainContentContainerNode.view.addSubview(backgroundView) + strongSelf.mainContentContainerNode.addSubnode(titleBadgeNode) + } + let titleBadgeFrame = CGRect(origin: CGPoint(x: titleFrame.maxX + titleIconsWidth + 10.0, y: titleFrame.minY + floor((titleFrame.height - titleBadgeLayout.size.height) * 0.5)), size: titleBadgeLayout.size) + titleBadgeNode.frame = titleBadgeFrame + + var titleBadgeBackgroundFrame = titleBadgeFrame.insetBy(dx: -4.0, dy: -2.0) + titleBadgeBackgroundFrame.size.height -= 1.0 + backgroundView.frame = titleBadgeBackgroundFrame + if item.presentationData.theme.overallDarkAppearance { + backgroundView.tintColor = theme.titleColor.withMultipliedAlpha(0.1) + } else { + backgroundView.tintColor = theme.titleColor.withMultipliedAlpha(0.05) + } + } else if let titleBadge = strongSelf.titleBadge { + strongSelf.titleBadge = nil + titleBadge.backgroundView.removeFromSuperview() + titleBadge.textNode.removeFromSupernode() + } + let authorNodeFrame = CGRect(origin: CGPoint(x: contentRect.origin.x - 1.0, y: contentRect.minY + titleLayout.size.height), size: authorLayout) strongSelf.authorNode.frame = authorNodeFrame let textNodeFrame = CGRect(origin: CGPoint(x: contentRect.origin.x - 1.0, y: contentRect.minY + titleLayout.size.height - 1.0 + UIScreenPixel + (authorLayout.height.isZero ? 0.0 : (authorLayout.height - 3.0))), size: textLayout.size) diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index c2c7180505..026dfa2641 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -468,7 +468,7 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL interaction: nodeInteraction ), directionHint: entry.directionHint) case let .peers(filter, isSelecting, _, filters, displayAutoremoveTimeout, displayPresence): - let itemPeer = peer.chatMainPeer + let itemPeer = peer.chatOrMonoforumMainPeer var chatPeer: EnginePeer? if let peer = peer.peers[peer.peerId] { chatPeer = peer @@ -643,7 +643,7 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL animationRenderer: nodeInteraction.animationRenderer ), directionHint: entry.directionHint) case .peerType: - let itemPeer = peer.chatMainPeer + let itemPeer = peer.chatOrMonoforumMainPeer var chatPeer: EnginePeer? if let peer = peer.peers[peer.peerId] { chatPeer = peer @@ -867,7 +867,7 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL interaction: nodeInteraction ), directionHint: entry.directionHint) case let .peers(filter, isSelecting, _, filters, displayAutoremoveTimeout, displayPresence): - let itemPeer = peer.chatMainPeer + let itemPeer = peer.chatOrMonoforumMainPeer var chatPeer: EnginePeer? if let peer = peer.peers[peer.peerId] { chatPeer = peer @@ -993,7 +993,7 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL animationRenderer: nodeInteraction.animationRenderer ), directionHint: entry.directionHint) case .peerType: - let itemPeer = peer.chatMainPeer + let itemPeer = peer.chatOrMonoforumMainPeer var chatPeer: EnginePeer? if let peer = peer.peers[peer.peerId] { chatPeer = peer diff --git a/submodules/ChatPresentationInterfaceState/Sources/ChatPresentationInterfaceState.swift b/submodules/ChatPresentationInterfaceState/Sources/ChatPresentationInterfaceState.swift index 43af0609e1..1ebea824b3 100644 --- a/submodules/ChatPresentationInterfaceState/Sources/ChatPresentationInterfaceState.swift +++ b/submodules/ChatPresentationInterfaceState/Sources/ChatPresentationInterfaceState.swift @@ -441,11 +441,6 @@ public final class ChatPresentationInterfaceState: Equatable { } } - public enum TopicListDisplayMode { - case top - case side - } - public final class ReportReasonData: Equatable { public let title: String public let option: Data @@ -474,6 +469,14 @@ public final class ChatPresentationInterfaceState: Equatable { } } + public struct PersistentPeerData: Codable, Equatable { + public var topicListPanelLocation: Bool + + public init(topicListPanelLocation: Bool) { + self.topicListPanelLocation = topicListPanelLocation + } + } + public let interfaceState: ChatInterfaceState public let chatLocation: ChatLocation public let renderedPeer: RenderedPeer? @@ -563,7 +566,7 @@ public final class ChatPresentationInterfaceState: Equatable { public let starGiftsAvailable: Bool public let alwaysShowGiftButton: Bool public let disallowedGifts: TelegramDisallowedGifts? - public let topicListDisplayMode: TopicListDisplayMode? + public let persistentData: PersistentPeerData public init(chatWallpaper: TelegramWallpaper, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, limitsConfiguration: LimitsConfiguration, fontSize: PresentationFontSize, bubbleCorners: PresentationChatBubbleCorners, accountPeerId: PeerId, mode: ChatControllerPresentationMode, chatLocation: ChatLocation, subject: ChatControllerSubject?, peerNearbyData: ChatPeerNearbyData?, greetingData: ChatGreetingData?, pendingUnpinnedAllMessages: Bool, activeGroupCallInfo: ChatActiveGroupCallInfo?, hasActiveGroupCall: Bool, importState: ChatPresentationImportState?, threadData: ThreadData?, isGeneralThreadClosed: Bool?, replyMessage: Message?, accountPeerColor: AccountPeerColor?, businessIntro: TelegramBusinessIntro?) { self.interfaceState = ChatInterfaceState() @@ -655,10 +658,12 @@ public final class ChatPresentationInterfaceState: Equatable { self.starGiftsAvailable = false self.alwaysShowGiftButton = false self.disallowedGifts = nil - self.topicListDisplayMode = nil + self.persistentData = PersistentPeerData( + topicListPanelLocation: false + ) } - public init(interfaceState: ChatInterfaceState, chatLocation: ChatLocation, renderedPeer: RenderedPeer?, isNotAccessible: Bool, explicitelyCanPinMessages: Bool, contactStatus: ChatContactStatus?, hasBots: Bool, isArchived: Bool, inputTextPanelState: ChatTextInputPanelState, editMessageState: ChatEditInterfaceMessageState?, inputQueryResults: [ChatPresentationInputQueryKind: ChatPresentationInputQueryResult], inputMode: ChatInputMode, titlePanelContexts: [ChatTitlePanelContext], keyboardButtonsMessage: Message?, pinnedMessageId: MessageId?, pinnedMessage: ChatPinnedMessage?, peerIsBlocked: Bool, peerIsMuted: Bool, peerDiscussionId: PeerId?, peerGeoLocation: PeerGeoLocation?, callsAvailable: Bool, callsPrivate: Bool, slowmodeState: ChatSlowmodeState?, chatHistoryState: ChatHistoryNodeHistoryState?, botStartPayload: String?, urlPreview: UrlPreview?, editingUrlPreview: UrlPreview?, search: ChatSearchData?, searchQuerySuggestionResult: ChatPresentationInputQueryResult?, historyFilter: HistoryFilter?, displayHistoryFilterAsList: Bool, presentationReady: Bool, chatWallpaper: TelegramWallpaper, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, limitsConfiguration: LimitsConfiguration, fontSize: PresentationFontSize, bubbleCorners: PresentationChatBubbleCorners, accountPeerId: PeerId, mode: ChatControllerPresentationMode, hasScheduledMessages: Bool, autoremoveTimeout: Int32?, subject: ChatControllerSubject?, peerNearbyData: ChatPeerNearbyData?, greetingData: ChatGreetingData?, pendingUnpinnedAllMessages: Bool, activeGroupCallInfo: ChatActiveGroupCallInfo?, hasActiveGroupCall: Bool, importState: ChatPresentationImportState?, reportReason: ReportReasonData?, showCommands: Bool, hasBotCommands: Bool, showSendAsPeers: Bool, sendAsPeers: [SendAsPeer]?, botMenuButton: BotMenuButton, showWebView: Bool, currentSendAsPeerId: PeerId?, copyProtectionEnabled: Bool, hasAtLeast3Messages: Bool, hasPlentyOfMessages: Bool, isPremium: Bool, premiumGiftOptions: [CachedPremiumGiftOption], suggestPremiumGift: Bool, forceInputCommandsHidden: Bool, voiceMessagesAvailable: Bool, customEmojiAvailable: Bool, threadData: ThreadData?, forumTopicData: ThreadData?, isGeneralThreadClosed: Bool?, translationState: ChatPresentationTranslationState?, replyMessage: Message?, accountPeerColor: AccountPeerColor?, savedMessagesTopicPeer: EnginePeer?, hasSearchTags: Bool, isPremiumRequiredForMessaging: Bool, sendPaidMessageStars: StarsAmount?, acknowledgedPaidMessage: Bool, hasSavedChats: Bool, appliedBoosts: Int32?, boostsToUnrestrict: Int32?, businessIntro: TelegramBusinessIntro?, hasBirthdayToday: Bool, adMessage: Message?, peerVerification: PeerVerification?, starGiftsAvailable: Bool, alwaysShowGiftButton: Bool, disallowedGifts: TelegramDisallowedGifts?, topicListDisplayMode: TopicListDisplayMode?) { + public init(interfaceState: ChatInterfaceState, chatLocation: ChatLocation, renderedPeer: RenderedPeer?, isNotAccessible: Bool, explicitelyCanPinMessages: Bool, contactStatus: ChatContactStatus?, hasBots: Bool, isArchived: Bool, inputTextPanelState: ChatTextInputPanelState, editMessageState: ChatEditInterfaceMessageState?, inputQueryResults: [ChatPresentationInputQueryKind: ChatPresentationInputQueryResult], inputMode: ChatInputMode, titlePanelContexts: [ChatTitlePanelContext], keyboardButtonsMessage: Message?, pinnedMessageId: MessageId?, pinnedMessage: ChatPinnedMessage?, peerIsBlocked: Bool, peerIsMuted: Bool, peerDiscussionId: PeerId?, peerGeoLocation: PeerGeoLocation?, callsAvailable: Bool, callsPrivate: Bool, slowmodeState: ChatSlowmodeState?, chatHistoryState: ChatHistoryNodeHistoryState?, botStartPayload: String?, urlPreview: UrlPreview?, editingUrlPreview: UrlPreview?, search: ChatSearchData?, searchQuerySuggestionResult: ChatPresentationInputQueryResult?, historyFilter: HistoryFilter?, displayHistoryFilterAsList: Bool, presentationReady: Bool, chatWallpaper: TelegramWallpaper, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, limitsConfiguration: LimitsConfiguration, fontSize: PresentationFontSize, bubbleCorners: PresentationChatBubbleCorners, accountPeerId: PeerId, mode: ChatControllerPresentationMode, hasScheduledMessages: Bool, autoremoveTimeout: Int32?, subject: ChatControllerSubject?, peerNearbyData: ChatPeerNearbyData?, greetingData: ChatGreetingData?, pendingUnpinnedAllMessages: Bool, activeGroupCallInfo: ChatActiveGroupCallInfo?, hasActiveGroupCall: Bool, importState: ChatPresentationImportState?, reportReason: ReportReasonData?, showCommands: Bool, hasBotCommands: Bool, showSendAsPeers: Bool, sendAsPeers: [SendAsPeer]?, botMenuButton: BotMenuButton, showWebView: Bool, currentSendAsPeerId: PeerId?, copyProtectionEnabled: Bool, hasAtLeast3Messages: Bool, hasPlentyOfMessages: Bool, isPremium: Bool, premiumGiftOptions: [CachedPremiumGiftOption], suggestPremiumGift: Bool, forceInputCommandsHidden: Bool, voiceMessagesAvailable: Bool, customEmojiAvailable: Bool, threadData: ThreadData?, forumTopicData: ThreadData?, isGeneralThreadClosed: Bool?, translationState: ChatPresentationTranslationState?, replyMessage: Message?, accountPeerColor: AccountPeerColor?, savedMessagesTopicPeer: EnginePeer?, hasSearchTags: Bool, isPremiumRequiredForMessaging: Bool, sendPaidMessageStars: StarsAmount?, acknowledgedPaidMessage: Bool, hasSavedChats: Bool, appliedBoosts: Int32?, boostsToUnrestrict: Int32?, businessIntro: TelegramBusinessIntro?, hasBirthdayToday: Bool, adMessage: Message?, peerVerification: PeerVerification?, starGiftsAvailable: Bool, alwaysShowGiftButton: Bool, disallowedGifts: TelegramDisallowedGifts?, persistentData: PersistentPeerData) { self.interfaceState = interfaceState self.chatLocation = chatLocation self.renderedPeer = renderedPeer @@ -748,7 +753,7 @@ public final class ChatPresentationInterfaceState: Equatable { self.starGiftsAvailable = starGiftsAvailable self.alwaysShowGiftButton = alwaysShowGiftButton self.disallowedGifts = disallowedGifts - self.topicListDisplayMode = topicListDisplayMode + self.persistentData = persistentData } public static func ==(lhs: ChatPresentationInterfaceState, rhs: ChatPresentationInterfaceState) -> Bool { @@ -1028,42 +1033,42 @@ public final class ChatPresentationInterfaceState: Equatable { if lhs.disallowedGifts != rhs.disallowedGifts { return false } - if lhs.topicListDisplayMode != rhs.topicListDisplayMode { + if lhs.persistentData != rhs.persistentData { return false } return true } public func updatedInterfaceState(_ f: (ChatInterfaceState) -> ChatInterfaceState) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: f(self.interfaceState), chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: f(self.interfaceState), chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedChatLocation(_ chatLocation: ChatLocation) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedPeer(_ f: (RenderedPeer?) -> RenderedPeer?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: f(self.renderedPeer), isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: f(self.renderedPeer), isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedIsNotAccessible(_ isNotAccessible: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedExplicitelyCanPinMessages(_ explicitelyCanPinMessages: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedContactStatus(_ contactStatus: ChatContactStatus?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedHasBots(_ hasBots: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedIsArchived(_ isArchived: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedInputQueryResult(queryKind: ChatPresentationInputQueryKind, _ f: (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?) -> ChatPresentationInterfaceState { @@ -1080,307 +1085,307 @@ public final class ChatPresentationInterfaceState: Equatable { inputQueryResults.removeValue(forKey: queryKind) } - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedInputTextPanelState(_ f: (ChatTextInputPanelState) -> ChatTextInputPanelState) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: f(self.inputTextPanelState), editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: f(self.inputTextPanelState), editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedEditMessageState(_ editMessageState: ChatEditInterfaceMessageState?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedInputMode(_ f: (ChatInputMode) -> ChatInputMode) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: f(self.inputMode), titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: f(self.inputMode), titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedTitlePanelContext(_ f: ([ChatTitlePanelContext]) -> [ChatTitlePanelContext]) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: f(self.titlePanelContexts), keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: f(self.titlePanelContexts), keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedKeyboardButtonsMessage(_ message: Message?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: message, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: message, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedPinnedMessage(_ pinnedMessage: ChatPinnedMessage?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedPeerIsBlocked(_ peerIsBlocked: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedPeerIsMuted(_ peerIsMuted: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedPeerDiscussionId(_ peerDiscussionId: PeerId?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedPeerGeoLocation(_ peerGeoLocation: PeerGeoLocation?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedCallsAvailable(_ callsAvailable: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedCallsPrivate(_ callsPrivate: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedSlowmodeState(_ slowmodeState: ChatSlowmodeState?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedBotStartPayload(_ botStartPayload: String?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedChatHistoryState(_ chatHistoryState: ChatHistoryNodeHistoryState?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedUrlPreview(_ urlPreview: UrlPreview?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedEditingUrlPreview(_ editingUrlPreview: UrlPreview?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedSearch(_ search: ChatSearchData?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedSearchQuerySuggestionResult(_ f: (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: f(self.searchQuerySuggestionResult), historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: f(self.searchQuerySuggestionResult), historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedHistoryFilter(_ historyFilter: HistoryFilter?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedDisplayHistoryFilterAsList(_ displayHistoryFilterAsList: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedMode(_ mode: ChatControllerPresentationMode) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedPresentationReady(_ presentationReady: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedTheme(_ theme: PresentationTheme) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedStrings(_ strings: PresentationStrings) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedDateTimeFormat(_ dateTimeFormat: PresentationDateTimeFormat) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedChatWallpaper(_ chatWallpaper: TelegramWallpaper) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedBubbleCorners(_ bubbleCorners: PresentationChatBubbleCorners) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedSubject(_ subject: ChatControllerSubject?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedAutoremoveTimeout(_ autoremoveTimeout: Int32?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedPendingUnpinnedAllMessages(_ pendingUnpinnedAllMessages: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedActiveGroupCallInfo(_ activeGroupCallInfo: ChatActiveGroupCallInfo?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedHasActiveGroupCall(_ hasActiveGroupCall: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedImportState(_ importState: ChatPresentationImportState?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedReportReason(_ reportReason: ReportReasonData?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedShowCommands(_ showCommands: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedHasBotCommands(_ hasBotCommands: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedShowSendAsPeers(_ showSendAsPeers: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedSendAsPeers(_ sendAsPeers: [SendAsPeer]?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedCurrentSendAsPeerId(_ currentSendAsPeerId: PeerId?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedBotMenuButton(_ botMenuButton: BotMenuButton) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedShowWebView(_ showWebView: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedCopyProtectionEnabled(_ copyProtectionEnabled: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedHasAtLeast3Messages(_ hasAtLeast3Messages: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedHasPlentyOfMessages(_ hasPlentyOfMessages: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedIsPremium(_ isPremium: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedPremiumGiftOptions(_ premiumGiftOptions: [CachedPremiumGiftOption]) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedSuggestPremiumGift(_ suggestPremiumGift: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedForceInputCommandsHidden(_ forceInputCommandsHidden: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedVoiceMessagesAvailable(_ voiceMessagesAvailable: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedCustomEmojiAvailable(_ customEmojiAvailable: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedThreadData(_ threadData: ThreadData?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedForumTopicData(_ forumTopicData: ThreadData?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedIsGeneralThreadClosed(_ isGeneralThreadClosed: Bool?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedTranslationState(_ translationState: ChatPresentationTranslationState?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedReplyMessage(_ replyMessage: Message?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedAccountPeerColor(_ accountPeerColor: AccountPeerColor?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedSavedMessagesTopicPeer(_ savedMessagesTopicPeer: EnginePeer?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedHasSearchTags(_ hasSearchTags: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedIsPremiumRequiredForMessaging(_ isPremiumRequiredForMessaging: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedSendPaidMessageStars(_ sendPaidMessageStars: StarsAmount?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedAcknowledgedPaidMessage(_ acknowledgedPaidMessage: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedHasSavedChats(_ hasSavedChats: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedAppliedBoosts(_ appliedBoosts: Int32?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedBoostsToUnrestrict(_ boostsToUnrestrict: Int32?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedBusinessIntro(_ businessIntro: TelegramBusinessIntro?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedHasBirthdayToday(_ hasBirthdayToday: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedAdMessage(_ adMessage: Message?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedPeerVerification(_ peerVerification: PeerVerification?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedStarGiftsAvailable(_ starGiftsAvailable: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedAlwaysShowGiftButton(_ alwaysShowGiftButton: Bool) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: self.persistentData) } public func updatedDisallowedGifts(_ disallowedGifts: TelegramDisallowedGifts?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: disallowedGifts, topicListDisplayMode: self.topicListDisplayMode) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: disallowedGifts, persistentData: self.persistentData) } - public func updatedTopicListDisplayMode(_ topicListDisplayMode: TopicListDisplayMode?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: topicListDisplayMode) + public func updatedPersistentData(_ persistentData: PersistentPeerData) -> ChatPresentationInterfaceState { + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, persistentData: persistentData) } } diff --git a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetController.swift b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetController.swift index c75dc8abf3..30a4447d7a 100644 --- a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetController.swift +++ b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetController.swift @@ -24,6 +24,7 @@ public enum SendMessageActionSheetControllerParams { public let currentPrice: Int64? public let hasTimers: Bool public let sendPaidMessageStars: StarsAmount? + public let isMonoforum: Bool public init( isScheduledMessages: Bool, @@ -36,7 +37,8 @@ public enum SendMessageActionSheetControllerParams { canMakePaidContent: Bool, currentPrice: Int64?, hasTimers: Bool, - sendPaidMessageStars: StarsAmount? + sendPaidMessageStars: StarsAmount?, + isMonoforum: Bool ) { self.isScheduledMessages = isScheduledMessages self.mediaPreview = mediaPreview @@ -49,6 +51,7 @@ public enum SendMessageActionSheetControllerParams { self.currentPrice = currentPrice self.hasTimers = hasTimers self.sendPaidMessageStars = sendPaidMessageStars + self.isMonoforum = isMonoforum } } diff --git a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageContextScreen.swift b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageContextScreen.swift index e5140c9846..dee2ad2dfa 100644 --- a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageContextScreen.swift +++ b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageContextScreen.swift @@ -463,6 +463,9 @@ final class ChatSendMessageContextScreenComponent: Component { if let _ = sendMessage.sendPaidMessageStars { canSchedule = false } + if sendMessage.isMonoforum { + canSchedule = false + } canMakePaidContent = sendMessage.canMakePaidContent currentPrice = sendMessage.currentPrice case .editMessage: diff --git a/submodules/ComponentFlow/Source/Base/Transition.swift b/submodules/ComponentFlow/Source/Base/Transition.swift index 5dde9d68e0..d196265547 100644 --- a/submodules/ComponentFlow/Source/Base/Transition.swift +++ b/submodules/ComponentFlow/Source/Base/Transition.swift @@ -16,8 +16,8 @@ public extension UIView { } } -private extension CALayer { - func animate(from: Any, to: Any, keyPath: String, duration: Double, delay: Double, curve: ComponentTransition.Animation.Curve, removeOnCompletion: Bool, additive: Bool, completion: ((Bool) -> Void)? = nil) { +public extension CALayer { + func animate(from: Any, to: Any, keyPath: String, duration: Double, delay: Double, curve: ComponentTransition.Animation.Curve, removeOnCompletion: Bool, additive: Bool, completion: ((Bool) -> Void)? = nil, key: String? = nil) { let timingFunction: String let mediaTimingFunction: CAMediaTimingFunction? switch curve { @@ -39,7 +39,8 @@ private extension CALayer { mediaTimingFunction: mediaTimingFunction, removeOnCompletion: removeOnCompletion, additive: additive, - completion: completion + completion: completion, + key: key ) } } diff --git a/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift b/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift index ddc2f0a963..8cb08592bf 100644 --- a/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift +++ b/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift @@ -1211,7 +1211,7 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode { strongSelf.contextSourceNode.contentRect = extractedRect switch item.peer { - case let .peer(peer, _): + case let .peer(peer, chatPeer): if let peer = peer { var overrideImage: AvatarNodeImageOverride? if peer.id == item.context.account.peerId, case let .generalSearch(isSavedMessages) = item.peerMode, case .treatSelfAsSaved = item.aliasHandling { @@ -1233,8 +1233,16 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode { if case .app(true) = item.peerMode { clipStyle = .roundedRect displayDimensions = CGSize(width: displayDimensions.width, height: displayDimensions.width * 1.2) - } else if case let .channel(channel) = peer, channel.isForumOrMonoForum { - clipStyle = .roundedRect + } else if case let .channel(channel) = peer { + if case let .channel(chatPeer) = chatPeer, chatPeer.isMonoForum { + clipStyle = .bubble + } else { + if channel.isForum { + clipStyle = .roundedRect + } else { + clipStyle = .round + } + } } else { clipStyle = .round } diff --git a/submodules/DeleteChatPeerActionSheetItem/Sources/DeleteChatPeerActionSheetItem.swift b/submodules/DeleteChatPeerActionSheetItem/Sources/DeleteChatPeerActionSheetItem.swift index 9ae8bce77c..e1d5e197cc 100644 --- a/submodules/DeleteChatPeerActionSheetItem/Sources/DeleteChatPeerActionSheetItem.swift +++ b/submodules/DeleteChatPeerActionSheetItem/Sources/DeleteChatPeerActionSheetItem.swift @@ -80,18 +80,23 @@ private final class DeleteChatPeerActionSheetItemNode: ActionSheetItemNode { self.addSubnode(self.avatarNode) self.addSubnode(self.accessibilityArea) + var clipStyle: AvatarNodeClipStyle = .round + if case let .channel(channel) = chatPeer, channel.isMonoForum { + clipStyle = .bubble + } + if chatPeer.id == context.account.peerId { - self.avatarNode.setPeer(context: context, theme: (context.sharedContext.currentPresentationData.with { $0 }).theme, peer: peer, overrideImage: .savedMessagesIcon) + self.avatarNode.setPeer(context: context, theme: (context.sharedContext.currentPresentationData.with { $0 }).theme, peer: peer, overrideImage: .savedMessagesIcon, clipStyle: clipStyle) } else if chatPeer.id.isReplies { - self.avatarNode.setPeer(context: context, theme: (context.sharedContext.currentPresentationData.with { $0 }).theme, peer: peer, overrideImage: .repliesIcon) + self.avatarNode.setPeer(context: context, theme: (context.sharedContext.currentPresentationData.with { $0 }).theme, peer: peer, overrideImage: .repliesIcon, clipStyle: clipStyle) } else if chatPeer.id.isAnonymousSavedMessages { - self.avatarNode.setPeer(context: context, theme: (context.sharedContext.currentPresentationData.with { $0 }).theme, peer: peer, overrideImage: .anonymousSavedMessagesIcon(isColored: true)) + self.avatarNode.setPeer(context: context, theme: (context.sharedContext.currentPresentationData.with { $0 }).theme, peer: peer, overrideImage: .anonymousSavedMessagesIcon(isColored: true), clipStyle: clipStyle) } else { var overrideImage: AvatarNodeImageOverride? if chatPeer.isDeleted { overrideImage = .deletedIcon } - self.avatarNode.setPeer(context: context, theme: (context.sharedContext.currentPresentationData.with { $0 }).theme, peer: peer, overrideImage: overrideImage) + self.avatarNode.setPeer(context: context, theme: (context.sharedContext.currentPresentationData.with { $0 }).theme, peer: peer, overrideImage: overrideImage, clipStyle: clipStyle) } var attributedText: NSAttributedString? @@ -109,11 +114,11 @@ private final class DeleteChatPeerActionSheetItemNode: ActionSheetItemNode { var text: PresentationStrings.FormattedString? switch action { case .delete: - if chatPeer.id == context.account.peerId { + if peer.id == context.account.peerId { text = PresentationStrings.FormattedString(string: strings.ChatList_DeleteSavedMessagesConfirmation, ranges: []) - } else if case let .legacyGroup(chatPeer) = chatPeer { + } else if case let .legacyGroup(chatPeer) = peer { text = strings.ChatList_LeaveGroupConfirmation(chatPeer.title) - } else if case let .channel(chatPeer) = chatPeer { + } else if case let .channel(chatPeer) = peer { text = strings.ChatList_LeaveGroupConfirmation(chatPeer.title) } else if case .secretChat = chatPeer { text = strings.ChatList_DeleteSecretChatConfirmation(peer.displayTitle(strings: strings, displayOrder: nameOrder)) diff --git a/submodules/Display/Source/ListView.swift b/submodules/Display/Source/ListView.swift index 9443d324d1..99044f64e6 100644 --- a/submodules/Display/Source/ListView.swift +++ b/submodules/Display/Source/ListView.swift @@ -263,6 +263,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel public final var didScrollWithOffset: ((CGFloat, ContainedViewLayoutTransition, ListViewItemNode?, Bool) -> Void)? public final var addContentOffset: ((CGFloat, ListViewItemNode?) -> Void)? public final var shouldStopScrolling: ((CGFloat) -> Bool)? + public final var onContentsUpdated: ((ContainedViewLayoutTransition) -> Void)? public final var updateScrollingIndicator: ((ScrollingIndicatorState?, ContainedViewLayoutTransition) -> Void)? @@ -389,6 +390,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel private var reorderScrollUpdateTimestamp: Double? private var reorderLastTimestamp: Double? public var reorderedItemHasShadow = true + public var reorderingRequiresLongPress = false private let waitingForNodesDisposable = MetaDisposable() @@ -518,7 +520,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel let itemNodeFrame = itemNode.frame let itemNodeBounds = itemNode.bounds if itemNode.isReorderable(at: point.offsetBy(dx: -itemNodeFrame.minX + itemNodeBounds.minX, dy: -itemNodeFrame.minY + itemNodeBounds.minY)) { - let requiresLongPress = !strongSelf.reorderedItemHasShadow + let requiresLongPress = strongSelf.reorderingRequiresLongPress return (true, requiresLongPress, itemNode) } break @@ -1101,6 +1103,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel self.updateVisibleContentOffset() self.updateVisibleItemRange() self.updateItemNodesVisibilities(onlyPositive: false) + self.onContentsUpdated?(.immediate) //CATransaction.commit() } @@ -3509,6 +3512,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel } self.updateItemHeaders(leftInset: listInsets.left, rightInset: listInsets.right, synchronousLoad: synchronousLoads, transition: headerNodesTransition, animateInsertion: animated || !requestItemInsertionAnimationsIndices.isEmpty, animateFullTransition: animateFullTransition) + self.onContentsUpdated?(headerNodesTransition.0) if let offset = offset, !offset.isZero { //self.didScrollWithOffset?(-offset, headerNodesTransition.0, nil) @@ -3733,6 +3737,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel } else { self.updateItemHeaders(leftInset: listInsets.left, rightInset: listInsets.right, synchronousLoad: synchronousLoads, transition: headerNodesTransition, animateInsertion: animated || !requestItemInsertionAnimationsIndices.isEmpty, animateFullTransition: animateFullTransition) self.updateItemNodesVisibilities(onlyPositive: deferredUpdateVisible) + self.onContentsUpdated?(headerNodesTransition.0) applyHeaderNodesFullTransition() diff --git a/submodules/Display/Source/ListViewAnimation.swift b/submodules/Display/Source/ListViewAnimation.swift index 44f51677a3..137c0fd16f 100644 --- a/submodules/Display/Source/ListViewAnimation.swift +++ b/submodules/Display/Source/ListViewAnimation.swift @@ -129,7 +129,7 @@ public func listViewAnimationCurveFromAnimationOptions(animationOptions: UIView. public final class ListViewAnimation { let from: Interpolatable - let to: Interpolatable + public let to: Interpolatable let duration: Double let startTime: Double let invertOffsetDirection: Bool diff --git a/submodules/Postbox/Sources/ChatListIndexTable.swift b/submodules/Postbox/Sources/ChatListIndexTable.swift index e672c4ced4..63c4179381 100644 --- a/submodules/Postbox/Sources/ChatListIndexTable.swift +++ b/submodules/Postbox/Sources/ChatListIndexTable.swift @@ -185,7 +185,31 @@ final class ChatListIndexTable: Table { var updatedPeerTags: [PeerId: (previous: PeerSummaryCounterTags, updated: PeerSummaryCounterTags)] = [:] var updatedIsThreadBasedUnreadCountCalculation: [PeerId: Bool] = [:] + var upatedPeerMap: [PeerId: (Peer?, Peer)] = [:] + for (previous, updated) in updatedPeers { + var needsAssociatedPeers = false + if let previous, previous.0.associatedPeerId != nil { + needsAssociatedPeers = true + } else if updated.0.associatedPeerId != nil { + needsAssociatedPeers = true + } + + if needsAssociatedPeers && upatedPeerMap.isEmpty { + for (previous, updated) in updatedPeers { + upatedPeerMap[updated.0.id] = (previous?.0, updated.0) + } + } + + var previousAssociatedPeer: Peer? + var updatedAssociatedPeer: Peer? + if let previous, let previousAssociatedPeerId = previous.0.associatedPeerId { + previousAssociatedPeer = upatedPeerMap[previousAssociatedPeerId]?.0 ?? postbox.peerTable.get(previousAssociatedPeerId) + } + if let updatedAssociatedPeerId = updated.0.associatedPeerId { + updatedAssociatedPeer = upatedPeerMap[updatedAssociatedPeerId]?.1 ?? postbox.peerTable.get(updatedAssociatedPeerId) + } + let previousTags: PeerSummaryCounterTags if let (previous, previousIsContact) = previous { previousTags = postbox.seedConfiguration.peerSummaryCounterTags(previous, previousIsContact) @@ -198,13 +222,13 @@ final class ChatListIndexTable: Table { } if let previous = previous { - var isThreadBasedUnreadCalculation = postbox.seedConfiguration.peerSummaryIsThreadBased(updated.0).value + var isThreadBasedUnreadCalculation = postbox.seedConfiguration.peerSummaryIsThreadBased(updated.0, updatedAssociatedPeer).value if let cachedData = updatedCachedPeerData[updated.0.id]?.1, postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedData) { isThreadBasedUnreadCalculation = false } var wasThreadBasedUnreadCalculation = false - if postbox.seedConfiguration.peerSummaryIsThreadBased(previous.0).value { + if postbox.seedConfiguration.peerSummaryIsThreadBased(previous.0, previousAssociatedPeer).value { if let cachedData = postbox.cachedPeerDataTable.get(previous.0.id), postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedData) { } else { wasThreadBasedUnreadCalculation = true @@ -223,14 +247,15 @@ final class ChatListIndexTable: Table { guard let peer = postbox.peerTable.get(peerId) else { continue } + let associatedPeer = peer.associatedPeerId.flatMap(postbox.peerTable.get) - var isThreadBasedUnreadCalculation = postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value + var isThreadBasedUnreadCalculation = postbox.seedConfiguration.peerSummaryIsThreadBased(peer, associatedPeer).value if postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedDataUpdate.1) { isThreadBasedUnreadCalculation = false } var wasThreadBasedUnreadCalculation = false - if postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value { + if postbox.seedConfiguration.peerSummaryIsThreadBased(peer, associatedPeer).value { if let previousCachedData = cachedDataUpdate.0, postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(previousCachedData) { } else { wasThreadBasedUnreadCalculation = true @@ -439,7 +464,7 @@ final class ChatListIndexTable: Table { displayAsRegularChat = true } - if let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value, !displayAsRegularChat { + if let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value, !displayAsRegularChat { let previousCount: Int32 if let previousSummary = alteredInitialPeerThreadsSummaries[peerId] { previousCount = previousSummary.effectiveUnreadCount @@ -458,7 +483,7 @@ final class ChatListIndexTable: Table { } let currentReadState: CombinedPeerReadState? - if let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value, !displayAsRegularChat { + if let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value, !displayAsRegularChat { let count = postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0 currentReadState = CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 1, maxKnownId: 0, count: count, markedUnread: false))]) } else { @@ -691,7 +716,7 @@ final class ChatListIndexTable: Table { } let combinedState: CombinedPeerReadState? - if postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value { + if postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value { let count: Int32 = postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0 combinedState = CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 1, maxKnownId: 0, count: count, markedUnread: false))]) } else { @@ -788,7 +813,7 @@ final class ChatListIndexTable: Table { } let combinedState: CombinedPeerReadState? - if postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value { + if postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value { let count: Int32 = postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0 combinedState = CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 1, maxKnownId: 0, count: count, markedUnread: false))]) } else { diff --git a/submodules/Postbox/Sources/ChatListView.swift b/submodules/Postbox/Sources/ChatListView.swift index c25f25fa95..2a3d47aca1 100644 --- a/submodules/Postbox/Sources/ChatListView.swift +++ b/submodules/Postbox/Sources/ChatListView.swift @@ -714,7 +714,7 @@ final class MutableChatListView { let renderedPeer = RenderedPeer(peerId: peer.id, peers: peers, associatedMedia: renderAssociatedMediaForPeers(postbox: postbox, peers: peers)) let isUnread: Bool - if postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value { + if postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value { let hasUnmutedUnread = postbox.peerThreadsSummaryTable.get(peerId: peer.id)?.hasUnmutedUnread ?? false isUnread = hasUnmutedUnread } else { @@ -846,7 +846,7 @@ final class MutableChatListView { displayAsRegularChat = postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedData) } - if let peer = groupEntries[i].renderedPeers[j].peer.peer, postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value, !displayAsRegularChat { + if let peer = groupEntries[i].renderedPeers[j].peer.peer, postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value, !displayAsRegularChat { isUnread = postbox.peerThreadsSummaryTable.get(peerId: peer.id)?.hasUnmutedUnread ?? false } else { isUnread = postbox.readStateTable.getCombinedState(groupEntries[i].renderedPeers[j].peer.peerId)?.isUnread ?? false @@ -942,7 +942,7 @@ final class MutableChatListView { var isThreadBased = false var threadsArePeers = false if let peer = renderedPeer.peer { - let value = postbox.seedConfiguration.peerSummaryIsThreadBased(peer) + let value = postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)) isThreadBased = value.value threadsArePeers = value.threadsArePeers } diff --git a/submodules/Postbox/Sources/ChatListViewState.swift b/submodules/Postbox/Sources/ChatListViewState.swift index 29dc942b51..dd1b39962a 100644 --- a/submodules/Postbox/Sources/ChatListViewState.swift +++ b/submodules/Postbox/Sources/ChatListViewState.swift @@ -65,7 +65,7 @@ private func mappedChatListFilterPredicate(postbox: PostboxImpl, currentTransact if let cachedPeerData = postbox.cachedPeerDataTable.get(peer.id), postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedPeerData) { displayAsRegularChat = true } - let isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value + let isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value if !isThreadBased { displayAsRegularChat = true } @@ -439,7 +439,7 @@ private final class ChatListViewSpaceState { if let cachedPeerData = postbox.cachedPeerDataTable.get(peer.id), postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedPeerData) { displayAsRegularChat = true } - let isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value + let isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value if !isThreadBased { displayAsRegularChat = true } @@ -577,7 +577,7 @@ private final class ChatListViewSpaceState { if let cachedPeerData = postbox.cachedPeerDataTable.get(entryPeer.id), postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedPeerData) { displayAsRegularChat = true } - let isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(entryPeer).value + let isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(entryPeer, entryPeer.associatedPeerId.flatMap(postbox.peerTable.get)).value if !isThreadBased { displayAsRegularChat = true } @@ -630,7 +630,7 @@ private final class ChatListViewSpaceState { if let cachedPeerData = postbox.cachedPeerDataTable.get(mainPeer.id), postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedPeerData) { displayAsRegularChat = true } - let isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(mainPeer).value + let isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(mainPeer, mainPeer.associatedPeerId.flatMap(postbox.peerTable.get)).value if !isThreadBased { displayAsRegularChat = true } @@ -816,7 +816,7 @@ private final class ChatListViewSpaceState { if let cachedPeerData = postbox.cachedPeerDataTable.get(entryPeer.id), postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedPeerData) { displayAsRegularChat = true } - let isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(entryPeer).value + let isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(entryPeer, entryPeer.associatedPeerId.flatMap(postbox.peerTable.get)).value if !isThreadBased { displayAsRegularChat = true } @@ -878,7 +878,7 @@ private final class ChatListViewSpaceState { if let cachedPeerData = postbox.cachedPeerDataTable.get(mainPeer.id), postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedPeerData) { displayAsRegularChat = true } - let isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(mainPeer).value + let isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(mainPeer, mainPeer.associatedPeerId.flatMap(postbox.peerTable.get)).value if !isThreadBased { displayAsRegularChat = true } @@ -978,7 +978,7 @@ private final class ChatListViewSpaceState { } let isThreadBased: Bool if let peer = postbox.peerTable.get(entryData.index.messageIndex.id.peerId) { - isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value + isThreadBased = postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value } else { isThreadBased = false } @@ -1620,7 +1620,7 @@ struct ChatListViewState { var isThreadBased = false var threadsArePeers = false if let peer = postbox.peerTable.get(index.messageIndex.id.peerId) { - let value = postbox.seedConfiguration.peerSummaryIsThreadBased(peer) + let value = postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)) isThreadBased = value.value threadsArePeers = value.threadsArePeers } diff --git a/submodules/Postbox/Sources/MessageHistoryView.swift b/submodules/Postbox/Sources/MessageHistoryView.swift index 61d5a7cfd2..94b0a438a5 100644 --- a/submodules/Postbox/Sources/MessageHistoryView.swift +++ b/submodules/Postbox/Sources/MessageHistoryView.swift @@ -679,13 +679,16 @@ final class MutableMessageHistoryView: MutablePostboxView { hasChanges = true } case let .UpdateReadState(peerId, combinedReadState): - hasChanges = true - if let transientReadStates = self.transientReadStates { - switch transientReadStates { - case let .peer(states): - var updatedStates = states - updatedStates[peerId] = combinedReadState - self.transientReadStates = .peer(updatedStates) + if case let .single(_, threadId) = self.peerIds, threadId != nil { + } else { + hasChanges = true + if let transientReadStates = self.transientReadStates { + switch transientReadStates { + case let .peer(states): + var updatedStates = states + updatedStates[peerId] = combinedReadState + self.transientReadStates = .peer(updatedStates) + } } } case let .UpdateTimestamp(index, timestamp): @@ -698,8 +701,15 @@ final class MutableMessageHistoryView: MutablePostboxView { var currentThreadId: Int64? switch self.peerIds { - case let .single(_, threadIdValue): + case let .single(peerId, threadIdValue): currentThreadId = threadIdValue + + if let threadIdValue, transaction.updatedPeerThreadInfos.contains(MessageHistoryThreadsTable.ItemId(peerId: peerId, threadId: threadIdValue)) { + if let threadData = postbox.messageHistoryThreadIndexTable.get(peerId: peerId, threadId: threadIdValue) { + hasChanges = true + self.transientReadStates = .peer([peerId: CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: threadData.summary.maxOutgoingReadId, maxKnownId: 0, count: 0, markedUnread: false))])]) + } + } case .associated: break case .external: diff --git a/submodules/Postbox/Sources/MessageThreadIndexTable.swift b/submodules/Postbox/Sources/MessageThreadIndexTable.swift index 9e3c2aec2d..fa39627fa6 100644 --- a/submodules/Postbox/Sources/MessageThreadIndexTable.swift +++ b/submodules/Postbox/Sources/MessageThreadIndexTable.swift @@ -5,17 +5,20 @@ public struct StoredMessageHistoryThreadInfo: Equatable, PostboxCoding { public var totalUnreadCount: Int32 public var isMarkedUnread: Bool public var mutedUntil: Int32? + public var maxOutgoingReadId: Int32 - public init(totalUnreadCount: Int32, isMarkedUnread: Bool, mutedUntil: Int32?) { + public init(totalUnreadCount: Int32, isMarkedUnread: Bool, mutedUntil: Int32?, maxOutgoingReadId: Int32) { self.totalUnreadCount = totalUnreadCount self.isMarkedUnread = isMarkedUnread self.mutedUntil = mutedUntil + self.maxOutgoingReadId = maxOutgoingReadId } public init(decoder: PostboxDecoder) { self.totalUnreadCount = decoder.decodeInt32ForKey("u", orElse: 0) self.mutedUntil = decoder.decodeOptionalInt32ForKey("m") self.isMarkedUnread = decoder.decodeBoolForKey("mu", orElse: false) + self.maxOutgoingReadId = decoder.decodeInt32ForKey("or", orElse: 0) } public func encode(_ encoder: PostboxEncoder) { @@ -26,6 +29,7 @@ public struct StoredMessageHistoryThreadInfo: Equatable, PostboxCoding { } else { encoder.encodeNil(forKey: "m") } + encoder.encodeInt32(self.maxOutgoingReadId, forKey: "or") } } @@ -112,7 +116,7 @@ class MessageHistoryThreadIndexTable: Table { return ValueBoxTable(id: id, keyType: .binary, compactValuesOnCreation: true) } - private struct UpdatedEntry { + struct UpdatedEntry { var value: StoredMessageHistoryThreadInfo? } @@ -127,7 +131,7 @@ class MessageHistoryThreadIndexTable: Table { private let sharedKey = ValueBoxKey(length: 8 + 4 + 8 + 4 + 4) - private var updatedInfoItems: [MessageHistoryThreadsTable.ItemId: UpdatedEntry] = [:] + private(set) var updatedInfoItems: [MessageHistoryThreadsTable.ItemId: UpdatedEntry] = [:] init(valueBox: ValueBox, table: ValueBoxTable, reverseIndexTable: MessageHistoryThreadReverseIndexTable, seedConfiguration: SeedConfiguration, useCaches: Bool) { self.reverseIndexTable = reverseIndexTable diff --git a/submodules/Postbox/Sources/Postbox.swift b/submodules/Postbox/Sources/Postbox.swift index cf1cca5917..c887e02cd2 100644 --- a/submodules/Postbox/Sources/Postbox.swift +++ b/submodules/Postbox/Sources/Postbox.swift @@ -2456,6 +2456,7 @@ final class PostboxImpl { let transactionParticipationInTotalUnreadCountUpdates = self.peerNotificationSettingsTable.transactionParticipationInTotalUnreadCountUpdates(postbox: self, transaction: currentTransaction) let updatedMessageThreadPeerIds = self.messageHistoryThreadIndexTable.replay(threadsTable: self.messageHistoryThreadsTable, namespaces: self.seedConfiguration.chatMessagesNamespaces, updatedIds: self.messageHistoryThreadsTable.updatedIds) + let updatedPeerThreadInfos = Set(self.messageHistoryThreadIndexTable.updatedInfoItems.keys) let alteredInitialPeerThreadsSummaries = self.peerThreadsSummaryTable.update(peerIds: updatedMessageThreadPeerIds.union(self.currentUpdatedPeerThreadCombinedStates), indexTable: self.messageHistoryThreadIndexTable, combinedStateTable: self.peerThreadCombinedStateTable, tagsSummaryTable: self.messageHistoryTagsSummaryTable) self.chatListIndexTable.commitWithTransaction( @@ -2479,7 +2480,62 @@ final class PostboxImpl { let updatedPeerTimeoutAttributes = self.peerTimeoutPropertiesTable.hasUpdates - let transaction = PostboxTransaction(currentUpdatedState: self.currentUpdatedState, currentPeerHoleOperations: self.currentPeerHoleOperations, currentOperationsByPeerId: self.currentOperationsByPeerId, chatListOperations: self.currentChatListOperations, currentUpdatedChatListInclusions: self.currentUpdatedChatListInclusions, currentUpdatedPeers: self.currentUpdatedPeers, currentUpdatedPeerNotificationSettings: self.currentUpdatedPeerNotificationSettings, currentUpdatedPeerNotificationBehaviorTimestamps: self.currentUpdatedPeerNotificationBehaviorTimestamps, currentUpdatedCachedPeerData: self.currentUpdatedCachedPeerData, currentUpdatedPeerPresences: currentUpdatedPeerPresences, currentUpdatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates, currentUpdatedTotalUnreadStates: self.currentUpdatedTotalUnreadStates, currentUpdatedTotalUnreadSummaries: self.currentUpdatedGroupTotalUnreadSummaries, alteredInitialPeerCombinedReadStates: alteredInitialPeerCombinedReadStates, currentPeerMergedOperationLogOperations: self.currentPeerMergedOperationLogOperations, currentTimestampBasedMessageAttributesOperations: self.currentTimestampBasedMessageAttributesOperations, unsentMessageOperations: self.currentUnsentOperations, updatedSynchronizePeerReadStateOperations: self.currentUpdatedSynchronizeReadStateOperations, currentUpdatedGroupSummarySynchronizeOperations: self.currentUpdatedGroupSummarySynchronizeOperations, currentPreferencesOperations: self.currentPreferencesOperations, currentOrderedItemListOperations: self.currentOrderedItemListOperations, currentItemCollectionItemsOperations: self.currentItemCollectionItemsOperations, currentItemCollectionInfosOperations: self.currentItemCollectionInfosOperations, currentUpdatedPeerChatStates: self.currentUpdatedPeerChatStates, currentGlobalTagsOperations: self.currentGlobalTagsOperations, currentLocalTagsOperations: self.currentLocalTagsOperations, updatedMedia: self.currentUpdatedMedia, replaceRemoteContactCount: self.currentReplaceRemoteContactCount, replaceContactPeerIds: self.currentReplacedContactPeerIds, currentPendingMessageActionsOperations: self.currentPendingMessageActionsOperations, currentUpdatedMessageActionsSummaries: self.currentUpdatedMessageActionsSummaries, currentUpdatedMessageTagSummaries: self.currentUpdatedMessageTagSummaries, currentInvalidateMessageTagSummaries: self.currentInvalidateMessageTagSummaries, currentUpdatedPendingPeerNotificationSettings: self.currentUpdatedPendingPeerNotificationSettings, replacedAdditionalChatListItems: self.currentReplacedAdditionalChatListItems, updatedNoticeEntryKeys: self.currentUpdatedNoticeEntryKeys, updatedCacheEntryKeys: self.currentUpdatedCacheEntryKeys, currentUpdatedMasterClientId: currentUpdatedMasterClientId, updatedFailedMessagePeerIds: self.messageHistoryFailedTable.updatedPeerIds, updatedFailedMessageIds: self.messageHistoryFailedTable.updatedMessageIds, updatedGlobalNotificationSettings: self.currentNeedsReindexUnreadCounters, updatedPeerTimeoutAttributes: updatedPeerTimeoutAttributes, updatedMessageThreadPeerIds: updatedMessageThreadPeerIds, updatedPeerThreadCombinedStates: self.currentUpdatedPeerThreadCombinedStates, updatedPeerThreadsSummaries: Set(alteredInitialPeerThreadsSummaries.keys), updatedPinnedThreads: self.currentUpdatedPinnedThreads, updatedHiddenPeerIds: self.currentUpdatedHiddenPeerIds, storyGeneralStatesEvents: self.currentStoryGeneralStatesEvents, storyPeerStatesEvents: self.currentStoryPeerStatesEvents, storySubscriptionsEvents: self.currentStorySubscriptionsEvents, storyItemsEvents: self.currentStoryItemsEvents, currentStoryTopItemEvents: self.currentStoryTopItemEvents, storyEvents: self.currentStoryEvents) + let transaction = PostboxTransaction( + currentUpdatedState: self.currentUpdatedState, + currentPeerHoleOperations: self.currentPeerHoleOperations, + currentOperationsByPeerId: self.currentOperationsByPeerId, + chatListOperations: self.currentChatListOperations, + currentUpdatedChatListInclusions: self.currentUpdatedChatListInclusions, + currentUpdatedPeers: self.currentUpdatedPeers, + currentUpdatedPeerNotificationSettings: self.currentUpdatedPeerNotificationSettings, + currentUpdatedPeerNotificationBehaviorTimestamps: self.currentUpdatedPeerNotificationBehaviorTimestamps, + currentUpdatedCachedPeerData: self.currentUpdatedCachedPeerData, + currentUpdatedPeerPresences: currentUpdatedPeerPresences, + currentUpdatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates, + currentUpdatedTotalUnreadStates: self.currentUpdatedTotalUnreadStates, + currentUpdatedTotalUnreadSummaries: self.currentUpdatedGroupTotalUnreadSummaries, + alteredInitialPeerCombinedReadStates: alteredInitialPeerCombinedReadStates, + currentPeerMergedOperationLogOperations: self.currentPeerMergedOperationLogOperations, + currentTimestampBasedMessageAttributesOperations: self.currentTimestampBasedMessageAttributesOperations, + unsentMessageOperations: self.currentUnsentOperations, + updatedSynchronizePeerReadStateOperations: self.currentUpdatedSynchronizeReadStateOperations, + currentUpdatedGroupSummarySynchronizeOperations: self.currentUpdatedGroupSummarySynchronizeOperations, + currentPreferencesOperations: self.currentPreferencesOperations, + currentOrderedItemListOperations: self.currentOrderedItemListOperations, + currentItemCollectionItemsOperations: self.currentItemCollectionItemsOperations, + currentItemCollectionInfosOperations: self.currentItemCollectionInfosOperations, + currentUpdatedPeerChatStates: self.currentUpdatedPeerChatStates, + currentGlobalTagsOperations: self.currentGlobalTagsOperations, + currentLocalTagsOperations: self.currentLocalTagsOperations, + updatedMedia: self.currentUpdatedMedia, + replaceRemoteContactCount: self.currentReplaceRemoteContactCount, + replaceContactPeerIds: self.currentReplacedContactPeerIds, + currentPendingMessageActionsOperations: self.currentPendingMessageActionsOperations, + currentUpdatedMessageActionsSummaries: self.currentUpdatedMessageActionsSummaries, + currentUpdatedMessageTagSummaries: self.currentUpdatedMessageTagSummaries, + currentInvalidateMessageTagSummaries: self.currentInvalidateMessageTagSummaries, + currentUpdatedPendingPeerNotificationSettings: self.currentUpdatedPendingPeerNotificationSettings, + replacedAdditionalChatListItems: self.currentReplacedAdditionalChatListItems, + updatedNoticeEntryKeys: self.currentUpdatedNoticeEntryKeys, + updatedCacheEntryKeys: self.currentUpdatedCacheEntryKeys, + currentUpdatedMasterClientId: currentUpdatedMasterClientId, + updatedFailedMessagePeerIds: self.messageHistoryFailedTable.updatedPeerIds, + updatedFailedMessageIds: self.messageHistoryFailedTable.updatedMessageIds, + updatedGlobalNotificationSettings: self.currentNeedsReindexUnreadCounters, + updatedPeerTimeoutAttributes: updatedPeerTimeoutAttributes, + updatedMessageThreadPeerIds: updatedMessageThreadPeerIds, + updatedPeerThreadCombinedStates: self.currentUpdatedPeerThreadCombinedStates, + updatedPeerThreadsSummaries: Set(alteredInitialPeerThreadsSummaries.keys), + updatedPeerThreadInfos: updatedPeerThreadInfos, + updatedPinnedThreads: self.currentUpdatedPinnedThreads, + updatedHiddenPeerIds: self.currentUpdatedHiddenPeerIds, + storyGeneralStatesEvents: self.currentStoryGeneralStatesEvents, + storyPeerStatesEvents: self.currentStoryPeerStatesEvents, + storySubscriptionsEvents: self.currentStorySubscriptionsEvents, + storyItemsEvents: self.currentStoryItemsEvents, + currentStoryTopItemEvents: self.currentStoryTopItemEvents, + storyEvents: self.currentStoryEvents + ) var updatedTransactionState: Int64? var updatedMasterClientId: Int64? if !transaction.isEmpty { @@ -3334,8 +3390,14 @@ final class PostboxImpl { var transientReadStates: MessageHistoryViewReadState? switch peerIds { case let .single(peerId, threadId): - if threadId == nil, let readState = self.readStateTable.getCombinedState(peerId) { - transientReadStates = .peer([peerId: readState]) + if let threadId { + if let threadData = self.messageHistoryThreadIndexTable.get(peerId: peerId, threadId: threadId) { + transientReadStates = .peer([peerId: CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: threadData.summary.maxOutgoingReadId, maxKnownId: 0, count: 0, markedUnread: false))])]) + } + } else { + if let readState = self.readStateTable.getCombinedState(peerId) { + transientReadStates = .peer([peerId: readState]) + } } case let .associated(peerId, _): if let readState = self.readStateTable.getCombinedState(peerId) { diff --git a/submodules/Postbox/Sources/PostboxTransaction.swift b/submodules/Postbox/Sources/PostboxTransaction.swift index 5729f31e3f..0098e5b59c 100644 --- a/submodules/Postbox/Sources/PostboxTransaction.swift +++ b/submodules/Postbox/Sources/PostboxTransaction.swift @@ -47,6 +47,7 @@ final class PostboxTransaction { let updatedMessageThreadPeerIds: Set let updatedPeerThreadCombinedStates: Set let updatedPeerThreadsSummaries: Set + let updatedPeerThreadInfos: Set let updatedPinnedThreads: Set let updatedHiddenPeerIds: Bool let storyGeneralStatesEvents: [StoryGeneralStatesTable.Event] @@ -195,6 +196,9 @@ final class PostboxTransaction { if !self.updatedPeerThreadsSummaries.isEmpty { return false } + if !self.updatedPeerThreadInfos.isEmpty { + return false + } if !self.updatedPinnedThreads.isEmpty { return false } @@ -269,6 +273,7 @@ final class PostboxTransaction { updatedMessageThreadPeerIds: Set, updatedPeerThreadCombinedStates: Set, updatedPeerThreadsSummaries: Set, + updatedPeerThreadInfos: Set, updatedPinnedThreads: Set, updatedHiddenPeerIds: Bool, storyGeneralStatesEvents: [StoryGeneralStatesTable.Event], @@ -323,6 +328,7 @@ final class PostboxTransaction { self.updatedMessageThreadPeerIds = updatedMessageThreadPeerIds self.updatedPeerThreadCombinedStates = updatedPeerThreadCombinedStates self.updatedPeerThreadsSummaries = updatedPeerThreadsSummaries + self.updatedPeerThreadInfos = updatedPeerThreadInfos self.updatedPinnedThreads = updatedPinnedThreads self.updatedHiddenPeerIds = updatedHiddenPeerIds self.storyGeneralStatesEvents = storyGeneralStatesEvents diff --git a/submodules/Postbox/Sources/SeedConfiguration.swift b/submodules/Postbox/Sources/SeedConfiguration.swift index 260ee2b2c2..859186b969 100644 --- a/submodules/Postbox/Sources/SeedConfiguration.swift +++ b/submodules/Postbox/Sources/SeedConfiguration.swift @@ -66,7 +66,7 @@ public final class SeedConfiguration { public let existingGlobalMessageTags: GlobalMessageTags public let peerNamespacesRequiringMessageTextIndex: [PeerId.Namespace] public let peerSummaryCounterTags: (Peer, Bool) -> PeerSummaryCounterTags - public let peerSummaryIsThreadBased: (Peer) -> (value: Bool, threadsArePeers: Bool) + public let peerSummaryIsThreadBased: (Peer, Peer?) -> (value: Bool, threadsArePeers: Bool) public let additionalChatListIndexNamespace: MessageId.Namespace? public let messageNamespacesRequiringGroupStatsValidation: Set public let defaultMessageNamespaceReadStates: [MessageId.Namespace: PeerReadState] @@ -97,7 +97,7 @@ public final class SeedConfiguration { existingGlobalMessageTags: GlobalMessageTags, peerNamespacesRequiringMessageTextIndex: [PeerId.Namespace], peerSummaryCounterTags: @escaping (Peer, Bool) -> PeerSummaryCounterTags, - peerSummaryIsThreadBased: @escaping (Peer) -> (value: Bool, threadsArePeers: Bool), + peerSummaryIsThreadBased: @escaping (Peer, Peer?) -> (value: Bool, threadsArePeers: Bool), additionalChatListIndexNamespace: MessageId.Namespace?, messageNamespacesRequiringGroupStatsValidation: Set, defaultMessageNamespaceReadStates: [MessageId.Namespace: PeerReadState], diff --git a/submodules/Postbox/Sources/UnreadMessageCountsView.swift b/submodules/Postbox/Sources/UnreadMessageCountsView.swift index 988f23b9b4..32c134ad71 100644 --- a/submodules/Postbox/Sources/UnreadMessageCountsView.swift +++ b/submodules/Postbox/Sources/UnreadMessageCountsView.swift @@ -64,7 +64,7 @@ final class MutableUnreadMessageCountsView: MutablePostboxView { case let .totalInGroup(groupId): return .totalInGroup(groupId, postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: groupId)) case let .peer(peerId, handleThreads): - if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value { + if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value { var count: Int32 = 0 if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) { count = summary.totalUnreadCount @@ -113,7 +113,7 @@ final class MutableUnreadMessageCountsView: MutablePostboxView { } } case let .peer(peerId, handleThreads, _): - if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value { + if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value { if transaction.updatedPeerThreadsSummaries.contains(peerId) { var count: Int32 = 0 if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) { @@ -143,7 +143,7 @@ final class MutableUnreadMessageCountsView: MutablePostboxView { case let .totalInGroup(groupId): return .totalInGroup(groupId, postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: groupId)) case let .peer(peerId, handleThreads): - if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value { + if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value { var count: Int32 = 0 if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) { count = summary.totalUnreadCount @@ -240,7 +240,7 @@ final class MutableCombinedReadStateView: MutablePostboxView { var updated = false if transaction.alteredInitialPeerCombinedReadStates[self.peerId] != nil || transaction.updatedPeerThreadCombinedStates.contains(self.peerId) { - if self.handleThreads, let peer = postbox.peerTable.get(self.peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value { + if self.handleThreads, let peer = postbox.peerTable.get(self.peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value { var count: Int32 = 0 if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) { count = summary.totalUnreadCount @@ -260,14 +260,14 @@ final class MutableCombinedReadStateView: MutablePostboxView { func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { let state: CombinedPeerReadState? - if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value { + if self.handleThreads, let peer = postbox.peerTable.get(self.peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)).value { var count: Int32 = 0 - if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) { + if let summary = postbox.peerThreadsSummaryTable.get(peerId: self.peerId) { count = summary.totalUnreadCount } state = CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 1, maxOutgoingReadId: 1, maxKnownId: 1, count: count, markedUnread: false))]) } else { - state = postbox.readStateTable.getCombinedState(peerId) + state = postbox.readStateTable.getCombinedState(self.peerId) } if state != self.state { diff --git a/submodules/SelectablePeerNode/Sources/SelectablePeerNode.swift b/submodules/SelectablePeerNode/Sources/SelectablePeerNode.swift index d28906ef1a..f4ba6fd9fc 100644 --- a/submodules/SelectablePeerNode/Sources/SelectablePeerNode.swift +++ b/submodules/SelectablePeerNode/Sources/SelectablePeerNode.swift @@ -212,7 +212,7 @@ public final class SelectablePeerNode: ASDisplayNode { public func setup(accountPeerId: EnginePeer.Id, postbox: Postbox, network: Network, energyUsageSettings: EnergyUsageSettings, contentSettings: ContentSettings, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, resolveInlineStickers: @escaping ([Int64]) -> Signal<[Int64: TelegramMediaFile], NoError>, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer, requiresPremiumForMessaging: Bool, requiresStars: Int64? = nil, customTitle: String? = nil, iconId: Int64? = nil, iconColor: Int32? = nil, online: Bool = false, numberOfLines: Int = 2, synchronousLoad: Bool) { let isFirstTime = self.peer == nil self.peer = peer - guard let mainPeer = peer.chatMainPeer else { + guard let mainPeer = peer.chatOrMonoforumMainPeer else { return } @@ -226,8 +226,10 @@ public final class SelectablePeerNode: ASDisplayNode { } var isForum = false - if let peer = peer.chatMainPeer, case let .channel(channel) = peer, channel.isForumOrMonoForum { - isForum = true + var isMonoforum = false + if let peer = peer.chatMainPeer, case let .channel(channel) = peer { + isForum = channel.isForum + isMonoforum = channel.isMonoForum } let text: String @@ -246,7 +248,15 @@ public final class SelectablePeerNode: ASDisplayNode { } self.textNode.maximumNumberOfLines = numberOfLines self.textNode.attributedText = NSAttributedString(string: customTitle ?? text, font: textFont, textColor: self.currentSelected ? self.theme.selectedTextColor : defaultColor, paragraphAlignment: .center) - self.avatarNode.setPeer(accountPeerId: accountPeerId, postbox: postbox, network: network, contentSettings: contentSettings, theme: theme, peer: mainPeer, overrideImage: overrideImage, emptyColor: self.theme.avatarPlaceholderColor, clipStyle: isForum ? .roundedRect : .round, synchronousLoad: synchronousLoad) + let clipStyle: AvatarNodeClipStyle + if isMonoforum { + clipStyle = .bubble + } else if isForum { + clipStyle = .roundedRect + } else { + clipStyle = .round + } + self.avatarNode.setPeer(accountPeerId: accountPeerId, postbox: postbox, network: network, contentSettings: contentSettings, theme: theme, peer: mainPeer, overrideImage: overrideImage, emptyColor: self.theme.avatarPlaceholderColor, clipStyle: clipStyle, synchronousLoad: synchronousLoad) if let requiresStars { let avatarBadgeOutline: UIImageView diff --git a/submodules/ShareController/Sources/ShareControllerNode.swift b/submodules/ShareController/Sources/ShareControllerNode.swift index 2addbd6134..ac5ac7f677 100644 --- a/submodules/ShareController/Sources/ShareControllerNode.swift +++ b/submodules/ShareController/Sources/ShareControllerNode.swift @@ -760,9 +760,14 @@ final class ShareControllerNode: ViewControllerTracingNode, ASScrollViewDelegate return } + var isMonoforum = false + if case let .channel(channel) = mainPeer { + isMonoforum = channel.isMonoForum + } + var didPresent = false var presentImpl: (() -> Void)? - let threads = threadList(accountPeerId: context.accountPeerId, postbox: context.stateManager.postbox, peerId: mainPeer.id) + let threads = threadList(accountPeerId: context.accountPeerId, postbox: context.stateManager.postbox, peerId: mainPeer.id, isMonoforum: isMonoforum) |> deliverOnMainQueue |> beforeNext { _ in if !didPresent { @@ -1933,78 +1938,162 @@ private final class ShareContextReferenceContentSource: ContextReferenceContentS } } -private func threadList(accountPeerId: EnginePeer.Id, postbox: Postbox, peerId: EnginePeer.Id) -> Signal { - let viewKey: PostboxViewKey = .messageHistoryThreadIndex( - id: peerId, - summaryComponents: ChatListEntrySummaryComponents( - components: [:] - ) - ) - - return postbox.combinedView(keys: [viewKey]) - |> mapToSignal { view -> Signal in - return postbox.transaction { transaction -> CombinedView in - if let peer = transaction.getPeer(accountPeerId) { - transaction.updatePeersInternal([peer]) { current, _ in - return current ?? peer +private func threadList(accountPeerId: EnginePeer.Id, postbox: Postbox, peerId: EnginePeer.Id, isMonoforum: Bool) -> Signal { + if isMonoforum { + let viewKey: PostboxViewKey = .savedMessagesIndex(peerId: peerId) + let interfaceStateKey: PostboxViewKey = .chatInterfaceState(peerId: peerId) + + return postbox.combinedView(keys: [viewKey, interfaceStateKey]) + |> map { views -> EngineChatList in + guard let view = views.views[viewKey] as? MessageHistorySavedMessagesIndexView else { + preconditionFailure() + } + + var draft: EngineChatList.Draft? + if let interfaceStateView = views.views[interfaceStateKey] as? ChatInterfaceStateView { + if let embeddedState = interfaceStateView.value, let _ = embeddedState.overrideChatTimestamp { + if let opaqueState = _internal_decodeStoredChatInterfaceState(state: embeddedState) { + if let text = opaqueState.synchronizeableInputState?.text { + draft = EngineChatList.Draft(text: text, entities: opaqueState.synchronizeableInputState?.entities ?? []) + } + } } } - return view - } - } - |> map { views -> EngineChatList in - guard let view = views.views[viewKey] as? MessageHistoryThreadIndexView else { - preconditionFailure() - } - - var items: [EngineChatList.Item] = [] - for item in view.items { - guard let peer = view.peer else { - continue - } - guard let data = item.info.get(MessageHistoryThreadData.self) else { - continue + + var items: [EngineChatList.Item] = [] + for item in view.items { + guard let sourcePeer = item.peer else { + continue + } + + let sourceId = PeerId(item.id) + + var messages: [EngineMessage] = [] + if let topMessage = item.topMessage { + messages.append(EngineMessage(topMessage)) + } + + let mappedMessageIndex = MessageIndex(id: MessageId(peerId: sourceId, namespace: item.index.id.namespace, id: item.index.id.id), timestamp: item.index.timestamp) + + let readCounters = EnginePeerReadCounters(state: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: Int32(item.unreadCount), markedUnread: item.markedUnread))]), isMuted: false) + + var itemDraft: EngineChatList.Draft? + if let embeddedState = item.embeddedInterfaceState, let _ = embeddedState.overrideChatTimestamp { + if let opaqueState = _internal_decodeStoredChatInterfaceState(state: embeddedState) { + if let text = opaqueState.synchronizeableInputState?.text { + itemDraft = EngineChatList.Draft(text: text, entities: opaqueState.synchronizeableInputState?.entities ?? []) + } + } + } + + items.append(EngineChatList.Item( + id: .chatList(sourceId), + index: .chatList(ChatListIndex(pinningIndex: item.pinnedIndex.flatMap(UInt16.init), messageIndex: mappedMessageIndex)), + messages: messages, + readCounters: readCounters, + isMuted: false, + draft: sourceId == accountPeerId ? draft : itemDraft, + threadData: nil, + renderedPeer: EngineRenderedPeer(peer: EnginePeer(sourcePeer)), + presence: nil, + hasUnseenMentions: false, + hasUnseenReactions: false, + forumTopicData: nil, + topForumTopicItems: [], + hasFailed: false, + isContact: false, + autoremoveTimeout: nil, + storyStats: nil, + displayAsTopicList: false, + isPremiumRequiredToMessage: false, + mediaDraftContentType: nil + )) } - let pinnedIndex: EngineChatList.Item.PinnedIndex - if let index = item.pinnedIndex { - pinnedIndex = .index(index) - } else { - pinnedIndex = .none - } + let list = EngineChatList( + items: items.reversed(), + groupItems: [], + additionalItems: [], + hasEarlier: false, + hasLater: false, + isLoading: view.isLoading + ) - items.append(EngineChatList.Item( - id: .forum(item.id), - index: .forum(pinnedIndex: pinnedIndex, timestamp: item.index.timestamp, threadId: item.id, namespace: item.index.id.namespace, id: item.index.id.id), - messages: item.topMessage.flatMap { [EngineMessage($0)] } ?? [], - readCounters: nil, - isMuted: false, - draft: nil, - threadData: data, - renderedPeer: EngineRenderedPeer(peer: EnginePeer(peer)), - presence: nil, - hasUnseenMentions: false, - hasUnseenReactions: false, - forumTopicData: nil, - topForumTopicItems: [], - hasFailed: false, - isContact: false, - autoremoveTimeout: nil, - storyStats: nil, - displayAsTopicList: false, - isPremiumRequiredToMessage: false, - mediaDraftContentType: nil - )) + return list } - - let list = EngineChatList( - items: items, - groupItems: [], - additionalItems: [], - hasEarlier: false, - hasLater: false, - isLoading: view.isLoading + } else { + let viewKey: PostboxViewKey = .messageHistoryThreadIndex( + id: peerId, + summaryComponents: ChatListEntrySummaryComponents( + components: [:] + ) ) - return list + + return postbox.combinedView(keys: [viewKey]) + |> mapToSignal { view -> Signal in + return postbox.transaction { transaction -> CombinedView in + if let peer = transaction.getPeer(accountPeerId) { + transaction.updatePeersInternal([peer]) { current, _ in + return current ?? peer + } + } + return view + } + } + |> map { views -> EngineChatList in + guard let view = views.views[viewKey] as? MessageHistoryThreadIndexView else { + preconditionFailure() + } + + var items: [EngineChatList.Item] = [] + for item in view.items { + guard let peer = view.peer else { + continue + } + guard let data = item.info.get(MessageHistoryThreadData.self) else { + continue + } + + let pinnedIndex: EngineChatList.Item.PinnedIndex + if let index = item.pinnedIndex { + pinnedIndex = .index(index) + } else { + pinnedIndex = .none + } + + items.append(EngineChatList.Item( + id: .forum(item.id), + index: .forum(pinnedIndex: pinnedIndex, timestamp: item.index.timestamp, threadId: item.id, namespace: item.index.id.namespace, id: item.index.id.id), + messages: item.topMessage.flatMap { [EngineMessage($0)] } ?? [], + readCounters: nil, + isMuted: false, + draft: nil, + threadData: data, + renderedPeer: EngineRenderedPeer(peer: EnginePeer(peer)), + presence: nil, + hasUnseenMentions: false, + hasUnseenReactions: false, + forumTopicData: nil, + topForumTopicItems: [], + hasFailed: false, + isContact: false, + autoremoveTimeout: nil, + storyStats: nil, + displayAsTopicList: false, + isPremiumRequiredToMessage: false, + mediaDraftContentType: nil + )) + } + + let list = EngineChatList( + items: items, + groupItems: [], + additionalItems: [], + hasEarlier: false, + hasLater: false, + isLoading: view.isLoading + ) + return list + } } } diff --git a/submodules/ShareController/Sources/ShareControllerPeerGridItem.swift b/submodules/ShareController/Sources/ShareControllerPeerGridItem.swift index 6a116d5a5b..f9ee2a4670 100644 --- a/submodules/ShareController/Sources/ShareControllerPeerGridItem.swift +++ b/submodules/ShareController/Sources/ShareControllerPeerGridItem.swift @@ -16,14 +16,14 @@ final class ShareControllerInteraction { var selectedPeerIds = Set() var selectedPeers: [EngineRenderedPeer] = [] - var selectedTopics: [EnginePeer.Id: (Int64, MessageHistoryThreadData)] = [:] + var selectedTopics: [EnginePeer.Id: (Int64, MessageHistoryThreadData?)] = [:] let togglePeer: (EngineRenderedPeer, Bool) -> Void - let selectTopic: (EngineRenderedPeer, Int64, MessageHistoryThreadData) -> Void + let selectTopic: (EngineRenderedPeer, Int64, MessageHistoryThreadData?) -> Void let shareStory: (() -> Void)? let disabledPeerSelected: (EngineRenderedPeer) -> Void - init(togglePeer: @escaping (EngineRenderedPeer, Bool) -> Void, selectTopic: @escaping (EngineRenderedPeer, Int64, MessageHistoryThreadData) -> Void, shareStory: (() -> Void)?, disabledPeerSelected: @escaping (EngineRenderedPeer) -> Void) { + init(togglePeer: @escaping (EngineRenderedPeer, Bool) -> Void, selectTopic: @escaping (EngineRenderedPeer, Int64, MessageHistoryThreadData?) -> Void, shareStory: (() -> Void)?, disabledPeerSelected: @escaping (EngineRenderedPeer) -> Void) { self.togglePeer = togglePeer self.selectTopic = selectTopic self.shareStory = shareStory diff --git a/submodules/ShareController/Sources/ShareTopicGridItem.swift b/submodules/ShareController/Sources/ShareTopicGridItem.swift index de756596ae..015d0b7648 100644 --- a/submodules/ShareController/Sources/ShareTopicGridItem.swift +++ b/submodules/ShareController/Sources/ShareTopicGridItem.swift @@ -12,22 +12,25 @@ import AccountContext import ShimmerEffect import ComponentFlow import EmojiStatusComponent +import AvatarNode final class ShareTopicGridItem: GridItem { let environment: ShareControllerEnvironment let context: ShareControllerAccountContext let theme: PresentationTheme let strings: PresentationStrings + let basePeer: EnginePeer let peer: EngineRenderedPeer? let id: Int64 - let threadInfo: MessageHistoryThreadData + let threadInfo: MessageHistoryThreadData? let controllerInteraction: ShareControllerInteraction let section: GridSection? - init(environment: ShareControllerEnvironment, context: ShareControllerAccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, id: Int64, threadInfo: MessageHistoryThreadData, controllerInteraction: ShareControllerInteraction) { + init(environment: ShareControllerEnvironment, context: ShareControllerAccountContext, theme: PresentationTheme, strings: PresentationStrings, basePeer: EnginePeer, peer: EngineRenderedPeer?, id: Int64, threadInfo: MessageHistoryThreadData?, controllerInteraction: ShareControllerInteraction) { self.environment = environment self.context = context + self.basePeer = basePeer self.theme = theme self.strings = strings self.peer = peer @@ -52,6 +55,7 @@ final class ShareTopicGridItemNode: GridItemNode { private let iconView: ComponentView private let textNode: ImmediateTextNode + private var avatarNode: AvatarNode? private var placeholderNode: ShimmerEffectNode? private var absoluteLocation: (CGRect, CGSize)? @@ -80,7 +84,11 @@ final class ShareTopicGridItemNode: GridItemNode { @objc private func tapped() { if let item = self.currentItem, let peer = item.peer { - item.controllerInteraction.selectTopic(peer, item.id, item.threadInfo) + if let threadInfo = item.threadInfo { + item.controllerInteraction.selectTopic(peer, item.id, threadInfo) + } else { + item.controllerInteraction.selectTopic(EngineRenderedPeer(peer: item.basePeer), item.id, nil) + } } } @@ -100,40 +108,59 @@ final class ShareTopicGridItemNode: GridItemNode { } self.currentItem = item - self.textNode.attributedText = NSAttributedString(string: item.threadInfo.info.title, font: Font.regular(11.0), textColor: item.theme.actionSheet.primaryTextColor) + if let threadInfo = item.threadInfo { + self.textNode.attributedText = NSAttributedString(string: threadInfo.info.title, font: Font.regular(11.0), textColor: item.theme.actionSheet.primaryTextColor) + + let iconContent: EmojiStatusComponent.Content + if let fileId = threadInfo.info.icon { + iconContent = .animation(content: .customEmoji(fileId: fileId), size: CGSize(width: 96.0, height: 96.0), placeholderColor: item.theme.actionSheet.disabledActionTextColor, themeColor: item.theme.actionSheet.primaryTextColor, loopMode: .count(0)) + } else { + iconContent = .topic(title: String(threadInfo.info.title.prefix(1)), color: threadInfo.info.iconColor, size: CGSize(width: 64.0, height: 64.0)) + } + + let iconSize = self.iconView.update( + transition: .easeInOut(duration: 0.2), + component: AnyComponent(EmojiStatusComponent( + postbox: item.context.stateManager.postbox, + energyUsageSettings: item.environment.energyUsageSettings, + resolveInlineStickers: item.context.resolveInlineStickers, + animationCache: item.context.animationCache, + animationRenderer: item.context.animationRenderer, + content: iconContent, + isVisibleForAnimations: true, + action: nil + )), + environment: {}, + containerSize: CGSize(width: 54.0, height: 54.0) + ) + + if let iconComponentView = self.iconView.view { + if iconComponentView.superview == nil { + self.view.addSubview(iconComponentView) + } + iconComponentView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - iconSize.width) / 2.0), y: 7.0), size: iconSize) + } + } else if let peer = item.peer, let mainPeer = peer.chatMainPeer { + self.textNode.attributedText = NSAttributedString(string: mainPeer.compactDisplayTitle, font: Font.regular(11.0), textColor: item.theme.actionSheet.primaryTextColor) + + let avatarNode: AvatarNode + if let current = self.avatarNode { + avatarNode = current + } else { + avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 12.0)) + self.avatarNode = avatarNode + self.addSubnode(avatarNode) + } + let iconSize = CGSize(width: 54.0, height: 54.0) + avatarNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - iconSize.width) / 2.0), y: 7.0), size: iconSize) + avatarNode.updateSize(size: iconSize) + + avatarNode.setPeer(accountPeerId: item.context.accountPeerId, postbox: item.context.stateManager.postbox, network: item.context.stateManager.network, contentSettings: ContentSettings.default, theme: item.theme, peer: mainPeer, overrideImage: nil, emptyColor: item.theme.list.mediaPlaceholderColor, clipStyle: .round, synchronousLoad: false) + } + let textSize = self.textNode.updateLayout(size) let textFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) / 2.0), y: 4.0 + 60.0 + 4.0), size: textSize) self.textNode.frame = textFrame - - let iconContent: EmojiStatusComponent.Content - if let fileId = item.threadInfo.info.icon { - iconContent = .animation(content: .customEmoji(fileId: fileId), size: CGSize(width: 96.0, height: 96.0), placeholderColor: item.theme.actionSheet.disabledActionTextColor, themeColor: item.theme.actionSheet.primaryTextColor, loopMode: .count(0)) - } else { - iconContent = .topic(title: String(item.threadInfo.info.title.prefix(1)), color: item.threadInfo.info.iconColor, size: CGSize(width: 64.0, height: 64.0)) - } - - let iconSize = self.iconView.update( - transition: .easeInOut(duration: 0.2), - component: AnyComponent(EmojiStatusComponent( - postbox: item.context.stateManager.postbox, - energyUsageSettings: item.environment.energyUsageSettings, - resolveInlineStickers: item.context.resolveInlineStickers, - animationCache: item.context.animationCache, - animationRenderer: item.context.animationRenderer, - content: iconContent, - isVisibleForAnimations: true, - action: nil - )), - environment: {}, - containerSize: CGSize(width: 54.0, height: 54.0) - ) - - if let iconComponentView = self.iconView.view { - if iconComponentView.superview == nil { - self.view.addSubview(iconComponentView) - } - iconComponentView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - iconSize.width) / 2.0), y: 7.0), size: iconSize) - } } override func layout() { diff --git a/submodules/ShareController/Sources/ShareTopicsContainerNode.swift b/submodules/ShareController/Sources/ShareTopicsContainerNode.swift index 5462d91491..18d5b6e4a2 100644 --- a/submodules/ShareController/Sources/ShareTopicsContainerNode.swift +++ b/submodules/ShareController/Sources/ShareTopicsContainerNode.swift @@ -18,9 +18,10 @@ private let subtitleFont = Font.regular(12.0) private struct ShareTopicEntry: Comparable, Identifiable { let index: Int32 + let basePeer: EnginePeer let peer: EngineRenderedPeer let id: Int64 - let threadData: MessageHistoryThreadData + let threadData: MessageHistoryThreadData? let theme: PresentationTheme let strings: PresentationStrings @@ -32,6 +33,9 @@ private struct ShareTopicEntry: Comparable, Identifiable { if lhs.index != rhs.index { return false } + if lhs.basePeer != rhs.basePeer { + return false + } if lhs.peer != rhs.peer { return false } @@ -53,7 +57,7 @@ private struct ShareTopicEntry: Comparable, Identifiable { } func item(environment: ShareControllerEnvironment, context: ShareControllerAccountContext, interfaceInteraction: ShareControllerInteraction) -> GridItem { - return ShareTopicGridItem(environment: environment, context: context, theme: self.theme, strings: self.strings, peer: self.peer, id: self.id, threadInfo: self.threadData, controllerInteraction: interfaceInteraction) + return ShareTopicGridItem(environment: environment, context: context, theme: self.theme, strings: self.strings, basePeer: self.basePeer, peer: self.peer, id: self.id, threadInfo: self.threadData, controllerInteraction: interfaceInteraction) } } @@ -205,7 +209,10 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode { for topic in topics { if case let .forum(_, _, threadId, _, _) = topic.index, let threadData = topic.threadData { - entries.append(ShareTopicEntry(index: index, peer: EngineRenderedPeer(peer: peer), id: threadId, threadData: threadData, theme: theme, strings: strings)) + entries.append(ShareTopicEntry(index: index, basePeer: peer, peer: EngineRenderedPeer(peer: peer), id: threadId, threadData: threadData, theme: theme, strings: strings)) + index += 1 + } else if case .chatList = topic.index { + entries.append(ShareTopicEntry(index: index, basePeer: peer, peer: topic.renderedPeer, id: topic.renderedPeer.peerId.toInt64(), threadData: nil, theme: theme, strings: strings)) index += 1 } } diff --git a/submodules/TelegramApi/Sources/Api38.swift b/submodules/TelegramApi/Sources/Api38.swift index f244a6ac73..acc66397d7 100644 --- a/submodules/TelegramApi/Sources/Api38.swift +++ b/submodules/TelegramApi/Sources/Api38.swift @@ -8923,13 +8923,14 @@ public extension Api.functions.messages { } } public extension Api.functions.messages { - static func unpinAllMessages(flags: Int32, peer: Api.InputPeer, topMsgId: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func unpinAllMessages(flags: Int32, peer: Api.InputPeer, topMsgId: Int32?, savedPeerId: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(-299714136) + buffer.appendInt32(103667527) serializeInt32(flags, buffer: buffer, boxed: false) peer.serialize(buffer, true) if Int(flags) & Int(1 << 0) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)} - return (FunctionDescription(name: "messages.unpinAllMessages", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("topMsgId", String(describing: topMsgId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.AffectedHistory? in + if Int(flags) & Int(1 << 1) != 0 {savedPeerId!.serialize(buffer, true)} + return (FunctionDescription(name: "messages.unpinAllMessages", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("topMsgId", String(describing: topMsgId)), ("savedPeerId", String(describing: savedPeerId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.AffectedHistory? in let reader = BufferReader(buffer) var result: Api.messages.AffectedHistory? if let signature = reader.readInt32() { diff --git a/submodules/TelegramCore/Sources/ForumChannels.swift b/submodules/TelegramCore/Sources/ForumChannels.swift index a114815f47..2343e2d27a 100644 --- a/submodules/TelegramCore/Sources/ForumChannels.swift +++ b/submodules/TelegramCore/Sources/ForumChannels.swift @@ -161,7 +161,8 @@ extension StoredMessageHistoryThreadInfo { self.init(data: entry, summary: Summary( totalUnreadCount: data.incomingUnreadCount, isMarkedUnread: data.isMarkedUnread, - mutedUntil: mutedUntil + mutedUntil: mutedUntil, + maxOutgoingReadId: data.maxOutgoingReadId )) } } diff --git a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift index 7f99ebc3e2..a24348e934 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift @@ -4262,7 +4262,7 @@ func replayFinalState( } else { updatedIncomingThreadReadStates[peerAndThreadId] = readMaxId } - if let channel = transaction.getPeer(peerAndThreadId.peerId) as? TelegramChannel, case .group = channel.info, channel.flags.contains(.isForum) { + if let channel = transaction.getPeer(peerAndThreadId.peerId) as? TelegramChannel, case .group = channel.info, (channel.flags.contains(.isForum) || channel.flags.contains(.isMonoforum)) { let threadId = peerAndThreadId.threadId if var data = transaction.getMessageHistoryThreadInfo(peerId: peerAndThreadId.peerId, threadId: threadId)?.data.get(MessageHistoryThreadData.self) { if readMaxId > data.maxIncomingReadId { @@ -4315,7 +4315,7 @@ func replayFinalState( } else { updatedOutgoingThreadReadStates[peerAndThreadId] = readMaxId } - if let channel = transaction.getPeer(peerAndThreadId.peerId) as? TelegramChannel, case .group = channel.info, channel.flags.contains(.isForum) { + if let channel = transaction.getPeer(peerAndThreadId.peerId) as? TelegramChannel, case .group = channel.info, (channel.flags.contains(.isForum) || channel.flags.contains(.isMonoforum)) { if var data = transaction.getMessageHistoryThreadInfo(peerId: peerAndThreadId.peerId, threadId: peerAndThreadId.threadId)?.data.get(MessageHistoryThreadData.self) { if readMaxId >= data.maxOutgoingReadId { data.maxOutgoingReadId = readMaxId diff --git a/submodules/TelegramCore/Sources/State/AccountStateManager.swift b/submodules/TelegramCore/Sources/State/AccountStateManager.swift index c81ec2048a..a4ec6abec5 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManager.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManager.swift @@ -2345,7 +2345,8 @@ public func messagesForNotification(transaction: Transaction, id: MessageId, alw var notificationSettingsStack: [TelegramPeerNotificationSettings] = [] - if let threadId = message.threadId, let threadData = transaction.getMessageHistoryThreadInfo(peerId: message.id.peerId, threadId: threadId)?.data.get(MessageHistoryThreadData.self) { + if let peer = peer as? TelegramChannel, peer.isMonoForum { + } else if let threadId = message.threadId, let threadData = transaction.getMessageHistoryThreadInfo(peerId: message.id.peerId, threadId: threadId)?.data.get(MessageHistoryThreadData.self) { notificationSettingsStack.append(threadData.notificationSettings) } diff --git a/submodules/TelegramCore/Sources/State/PendingMessageManager.swift b/submodules/TelegramCore/Sources/State/PendingMessageManager.swift index 6521525367..27240c6ccd 100644 --- a/submodules/TelegramCore/Sources/State/PendingMessageManager.swift +++ b/submodules/TelegramCore/Sources/State/PendingMessageManager.swift @@ -949,7 +949,9 @@ public final class PendingMessageManager { var monoforumPeerId: Api.InputPeer? if let threadId = messages[0].0.threadId { if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum) { - monoforumPeerId = transaction.getPeer(PeerId(threadId)).flatMap(apiInputPeer) + if let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = transaction.getPeer(linkedMonoforumId) as? TelegramChannel, mainChannel.hasPermission(.sendSomething) { + monoforumPeerId = transaction.getPeer(PeerId(threadId)).flatMap(apiInputPeer) + } } else { flags |= Int32(1 << 9) topMsgId = Int32(clamping: threadId) @@ -1043,7 +1045,9 @@ public final class PendingMessageManager { var monoforumPeerId: Api.InputPeer? if let threadId = messages[0].0.threadId { if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum) { - monoforumPeerId = transaction.getPeer(PeerId(threadId)).flatMap(apiInputPeer) + if let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = transaction.getPeer(linkedMonoforumId) as? TelegramChannel, mainChannel.hasPermission(.sendSomething) { + monoforumPeerId = transaction.getPeer(PeerId(threadId)).flatMap(apiInputPeer) + } } else { flags |= Int32(1 << 9) topMsgId = Int32(clamping: threadId) @@ -1352,7 +1356,9 @@ public final class PendingMessageManager { var monoforumPeerId: Api.InputPeer? if let threadId = message.threadId { if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum) { - monoforumPeerId = transaction.getPeer(PeerId(threadId)).flatMap(apiInputPeer) + if let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = transaction.getPeer(linkedMonoforumId) as? TelegramChannel, mainChannel.hasPermission(.sendSomething) { + monoforumPeerId = transaction.getPeer(PeerId(threadId)).flatMap(apiInputPeer) + } } else { topMsgId = Int32(clamping: threadId) } @@ -1615,7 +1621,9 @@ public final class PendingMessageManager { var monoforumPeerId: Api.InputPeer? if let threadId = message.threadId { if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum) { - monoforumPeerId = transaction.getPeer(PeerId(threadId)).flatMap(apiInputPeer) + if let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = transaction.getPeer(linkedMonoforumId) as? TelegramChannel, mainChannel.hasPermission(.sendSomething) { + monoforumPeerId = transaction.getPeer(PeerId(threadId)).flatMap(apiInputPeer) + } } else { flags |= Int32(1 << 9) topMsgId = Int32(clamping: threadId) diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift index f4e68f4760..b35e834e07 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift @@ -313,6 +313,7 @@ private enum PreferencesKeyValues: Int32 { case botStorageState = 42 case secureBotStorageState = 43 case serverSuggestionInfo = 44 + case persistentChatInterfaceData = 45 } public func applicationSpecificPreferencesKey(_ value: Int32) -> ValueBoxKey { @@ -562,6 +563,13 @@ public struct PreferencesKeys { key.setInt32(0, value: PreferencesKeyValues.serverSuggestionInfo.rawValue) return key } + + public static func persistentChatInterfaceData(peerId: PeerId) -> ValueBoxKey { + let key = ValueBoxKey(length: 4 + 8) + key.setInt32(0, value: PreferencesKeyValues.persistentChatInterfaceData.rawValue) + key.setInt64(4, value: peerId.toInt64()) + return key + } } private enum SharedDataKeyValues: Int32 { diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_StandaloneAccountTransaction.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_StandaloneAccountTransaction.swift index 5bc38f77ae..6879891c8d 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_StandaloneAccountTransaction.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_StandaloneAccountTransaction.swift @@ -73,7 +73,7 @@ public let telegramPostboxSeedConfiguration: SeedConfiguration = { return .nonContact } }, - peerSummaryIsThreadBased: { peer in + peerSummaryIsThreadBased: { peer, associatedPeer in if let channel = peer as? TelegramChannel { if channel.flags.contains(.isForum) { if channel.flags.contains(.displayForumAsTabs) { @@ -82,7 +82,11 @@ public let telegramPostboxSeedConfiguration: SeedConfiguration = { return (true, false) } } else if channel.flags.contains(.isMonoforum) { - return (true, true) + if let associatedPeer = associatedPeer as? TelegramChannel, associatedPeer.hasPermission(.sendSomething) { + return (true, true) + } else { + return (false, false) + } } else { return (false, false) } @@ -194,7 +198,7 @@ public let telegramPostboxSeedConfiguration: SeedConfiguration = { }, automaticThreadIndexInfo: { peerId, _ in if peerId.namespace == Namespaces.Peer.CloudUser { - return StoredMessageHistoryThreadInfo(data: CodableEntry(data: Data()), summary: StoredMessageHistoryThreadInfo.Summary(totalUnreadCount: 0, isMarkedUnread: false, mutedUntil: nil)) + return StoredMessageHistoryThreadInfo(data: CodableEntry(data: Data()), summary: StoredMessageHistoryThreadInfo.Summary(totalUnreadCount: 0, isMarkedUnread: false, mutedUntil: nil, maxOutgoingReadId: 0)) } else { return nil } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramSecretChat.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramSecretChat.swift index d1958c38ee..054b229e73 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramSecretChat.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramSecretChat.swift @@ -22,6 +22,7 @@ public final class TelegramSecretChat: Peer, Equatable { } public let notificationSettingsPeerId: PeerId? + public let associatedPeerOverridesIdentity: Bool = true public var timeoutAttribute: UInt32? { return nil } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift index 3999c200e2..2321c6c6dd 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift @@ -204,6 +204,11 @@ public extension TelegramEngine.EngineData.Item { return nil } peers[mainPeer.id] = EnginePeer(mainPeer) + } else if let channel = peer as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId { + guard let mainChannel = view.peers[linkedMonoforumId] else { + return nil + } + peers[mainChannel.id] = EnginePeer(mainChannel) } return EngineRenderedPeer(peerId: self.id, peers: peers, associatedMedia: view.media) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/ApplyMaxReadIndexInteractively.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ApplyMaxReadIndexInteractively.swift index 0610057116..2b42cf7357 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/ApplyMaxReadIndexInteractively.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ApplyMaxReadIndexInteractively.swift @@ -12,6 +12,30 @@ func _internal_applyMaxReadIndexInteractively(postbox: Postbox, stateManager: Ac func _internal_applyMaxReadIndexInteractively(transaction: Transaction, stateManager: AccountStateManager, index: MessageIndex) { let messageIds = transaction.applyInteractiveReadMaxIndex(index) + + if let channel = transaction.getPeer(index.id.peerId) as? TelegramChannel, channel.isForumOrMonoForum { + if let combinedPeerReadState = transaction.getCombinedPeerReadState(channel.id), combinedPeerReadState.count == 0 { + for item in transaction.getMessageHistoryThreadIndex(peerId: channel.id, limit: 100) { + guard var data = transaction.getMessageHistoryThreadInfo(peerId: index.id.peerId, threadId: item.threadId)?.data.get(MessageHistoryThreadData.self) else { + continue + } + guard let messageIndex = transaction.getMessageHistoryThreadTopMessage(peerId: index.id.peerId, threadId: item.threadId, namespaces: Set([Namespaces.Message.Cloud])) else { + continue + } + if data.incomingUnreadCount != 0 { + data.incomingUnreadCount = 0 + data.isMarkedUnread = false + data.maxIncomingReadId = max(messageIndex.id.id, data.maxIncomingReadId) + data.maxKnownMessageId = max(data.maxKnownMessageId, messageIndex.id.id) + + if let entry = StoredMessageHistoryThreadInfo(data) { + transaction.setMessageHistoryThreadInfo(peerId: index.id.peerId, threadId: item.threadId, info: entry) + } + } + } + } + } + if index.id.peerId.namespace == Namespaces.Peer.SecretChat { let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) for id in messageIds { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/UpdatePinnedMessage.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/UpdatePinnedMessage.swift index 09ec98fd65..5874962f80 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/UpdatePinnedMessage.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/UpdatePinnedMessage.swift @@ -110,12 +110,18 @@ func _internal_requestUpdatePinnedMessage(account: Account, peerId: PeerId, upda } func _internal_requestUnpinAllMessages(account: Account, peerId: PeerId, threadId: Int64?) -> Signal { - return account.postbox.transaction { transaction -> (Peer?, CachedPeerData?) in - return (transaction.getPeer(peerId), transaction.getPeerCachedData(peerId: peerId)) + return account.postbox.transaction { transaction -> (Peer?, Peer?, CachedPeerData?) in + let peer = transaction.getPeer(peerId) + var subPeer: Peer? + if let channel = peer as? TelegramChannel, channel.isMonoForum, let threadId { + subPeer = transaction.getPeer(PeerId(threadId)) + } + + return (peer, subPeer, transaction.getPeerCachedData(peerId: peerId)) } |> mapError { _ -> UpdatePinnedMessageError in } - |> mapToSignal { peer, cachedPeerData -> Signal in + |> mapToSignal { peer, subPeer, cachedPeerData -> Signal in guard let peer = peer, let inputPeer = apiInputPeer(peer) else { return .fail(.generic) } @@ -148,10 +154,20 @@ func _internal_requestUnpinAllMessages(account: Account, peerId: PeerId, threadI } var flags: Int32 = 0 - if threadId != nil { - flags |= (1 << 0) + var topMsgId: Int32? + var savedPeerId: Api.InputPeer? + if let threadId { + if let channel = peer as? TelegramChannel, channel.isMonoForum { + if let inputSubPeer = subPeer.flatMap(apiInputPeer) { + flags |= (1 << 1) + savedPeerId = inputSubPeer + } + } else { + flags |= (1 << 0) + topMsgId = Int32(clamping: threadId) + } } - let request: Signal = account.network.request(Api.functions.messages.unpinAllMessages(flags: flags, peer: inputPeer, topMsgId: threadId.flatMap(Int32.init(clamping:)))) + let request: Signal = account.network.request(Api.functions.messages.unpinAllMessages(flags: flags, peer: inputPeer, topMsgId: topMsgId, savedPeerId: savedPeerId)) |> mapError { error -> InternalError in return .error(error.errorDescription) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift index 4719a84401..d05aa6dd5b 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift @@ -1143,6 +1143,18 @@ public extension TelegramEngine { |> ignoreValues } + public func getPerstistentChatInterfaceState(peerId: EnginePeer.Id) -> Signal { + return self.account.postbox.transaction({ transaction -> CodableEntry? in + return (transaction.getPreferencesEntry(key: PreferencesKeys.persistentChatInterfaceData(peerId: peerId))?.data).flatMap(CodableEntry.init(data:)) + }) + } + + public func setPerstistentChatInterfaceState(peerId: EnginePeer.Id, state: CodableEntry?) { + let _ = self.account.postbox.transaction({ transaction -> Void in + transaction.setPreferencesEntry(key: PreferencesKeys.persistentChatInterfaceData(peerId: peerId), value: (state?.data).flatMap(PreferencesEntry.init(data:))) + }).startStandalone() + } + public func sendAsAvailablePeers(peerId: PeerId) -> Signal<[SendAsPeer], NoError> { return _internal_cachedPeerSendAsAvailablePeers(account: self.account, peerId: peerId) } diff --git a/submodules/TelegramCore/Sources/Utils/PeerUtils.swift b/submodules/TelegramCore/Sources/Utils/PeerUtils.swift index 04de12d0f6..eb40aaa6a8 100644 --- a/submodules/TelegramCore/Sources/Utils/PeerUtils.swift +++ b/submodules/TelegramCore/Sources/Utils/PeerUtils.swift @@ -279,6 +279,14 @@ public extension Peer { } } + var displayForumAsTabs: Bool { + if let channel = self as? TelegramChannel, isForum { + return channel.flags.contains(.displayForumAsTabs) + } else { + return false + } + } + var isForumOrMonoForum: Bool { if let channel = self as? TelegramChannel { return channel.flags.contains(.isForum) || channel.flags.contains(.isMonoforum) @@ -460,7 +468,7 @@ public func peerViewMonoforumMainPeer(_ view: PeerView) -> Peer? { if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum), let linkedMonoforumId = channel.linkedMonoforumId { return view.peers[linkedMonoforumId] } else { - return peer + return nil } } else { return nil diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesSettings.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesSettings.swift index aa4b951618..c94fa8ed06 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesSettings.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesSettings.swift @@ -85,6 +85,7 @@ public struct PresentationResourcesSettings { public static let balance = renderIcon(name: "Settings/Menu/Balance", scaleFactor: 0.97, backgroundColors: [UIColor(rgb: 0x34c759)]) public static let affiliateProgram = renderIcon(name: "Settings/Menu/AffiliateProgram") public static let earnStars = renderIcon(name: "Settings/Menu/EarnStars") + public static let channelMessages = renderIcon(name: "Chat/Info/ChannelMessages", backgroundColors: [UIColor(rgb: 0xFF9500)]) public static let premium = generateImage(CGSize(width: 29.0, height: 29.0), contextGenerator: { size, context in let bounds = CGRect(origin: CGPoint(), size: size) diff --git a/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift b/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift index e9a4798453..17874db695 100644 --- a/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift +++ b/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift @@ -140,8 +140,7 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, } else { if forChatList { if isMonoforum { - //TODO:Localize - attributedString = NSAttributedString(string: "No messages here yet...", font: titleFont, textColor: primaryTextColor) + attributedString = NSAttributedString(string: strings.ChatList_MonoforumEmptyText, font: titleFont, textColor: primaryTextColor) } else { attributedString = NSAttributedString(string: strings.Notification_CreatedGroup, font: titleFont, textColor: primaryTextColor) } @@ -1262,21 +1261,28 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, let starsString = strings.Notification_PaidMessagePriceChanged_Stars(Int32(stars)) if message.author?.id == accountPeerId { let resultString: PresentationStrings.FormattedString - if broadcastMessagesAllowed { - resultString = strings.Notification_PaidMessagePriceChangedAndEnabledChannelMessageYou(starsString) - } else { - resultString = strings.Notification_PaidMessagePriceChangedYou(starsString) - } + resultString = strings.Notification_PaidMessagePriceChangedYou(starsString) attributedString = addAttributesToStringWithRanges(resultString._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes]) } else { let peerName = message.author?.compactDisplayTitle ?? "" var attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: [(0, message.author?.id)]) attributes[1] = boldAttributes let resultString: PresentationStrings.FormattedString + if broadcastMessagesAllowed { - resultString = strings.Notification_PaidMessagePriceChangedAndEnabledChannelMessage(peerName, starsString) + if stars == 0 { + resultString = strings.Notification_ChannelMessagePriceZeroChanged(peerName) + } else { + var rawString = strings.Notification_ChannelMessagePriceChanged(Int32(stars)) + rawString = rawString.replacingOccurrences(of: "{name}", with: peerName) + resultString = PresentationStrings.FormattedString(string: rawString, ranges: []) + } } else { - resultString = strings.Notification_PaidMessagePriceChanged(peerName, starsString) + if let channel = message.peers[message.id.peerId] as? TelegramChannel, case .broadcast = channel.info { + resultString = strings.Notification_ChannelMessageDisabled(peerName) + } else { + resultString = strings.Notification_PaidMessagePriceChanged(peerName, starsString) + } } attributedString = addAttributesToStringWithRanges(resultString._tuple, body: bodyAttributes, argumentAttributes: attributes) } diff --git a/submodules/TelegramUI/BUILD b/submodules/TelegramUI/BUILD index 2dbaa6367f..922a08f279 100644 --- a/submodules/TelegramUI/BUILD +++ b/submodules/TelegramUI/BUILD @@ -479,6 +479,8 @@ swift_library( "//submodules/TelegramUI/Components/PeerInfo/PostSuggestionsSettingsScreen", "//submodules/TelegramUI/Components/ForumSettingsScreen", "//submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel", + "//submodules/TelegramUI/Components/GifVideoLayer", + "//submodules/TelegramUI/Components/BatchVideoRendering", ] + select({ "@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets, "//build-system:ios_sim_arm64": [], diff --git a/submodules/TelegramUI/Components/AsyncListComponent/BUILD b/submodules/TelegramUI/Components/AsyncListComponent/BUILD new file mode 100644 index 0000000000..51c0d2258b --- /dev/null +++ b/submodules/TelegramUI/Components/AsyncListComponent/BUILD @@ -0,0 +1,23 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "AsyncListComponent", + module_name = "AsyncListComponent", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/AsyncDisplayKit", + "//submodules/Display", + "//submodules/ComponentFlow", + "//submodules/SSignalKit/SwiftSignalKit", + "//submodules/MergeLists", + "//submodules/Components/ComponentDisplayAdapters", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/TelegramUI/Components/AsyncListComponent/Sources/AsyncListComponent.swift b/submodules/TelegramUI/Components/AsyncListComponent/Sources/AsyncListComponent.swift new file mode 100644 index 0000000000..bafe1552f6 --- /dev/null +++ b/submodules/TelegramUI/Components/AsyncListComponent/Sources/AsyncListComponent.swift @@ -0,0 +1,638 @@ +import Foundation +import UIKit +import Display +import AsyncDisplayKit +import ComponentFlow +import SwiftSignalKit +import MergeLists +import ComponentDisplayAdapters + +public final class AsyncListComponent: Component { + public protocol ItemView: UIView { + func isReorderable(at point: CGPoint) -> Bool + } + + public final class OverlayContainerView: UIView { + public override init(frame: CGRect) { + super.init(frame: frame) + + self.layer.anchorPoint = CGPoint() + } + + required public init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public func updatePosition(position: CGPoint, transition: ComponentTransition) { + let previousPosition: CGPoint + var forceUpdate = false + if self.layer.animation(forKey: "positionUpdate") != nil, let presentation = self.layer.presentation() { + forceUpdate = true + previousPosition = presentation.position + + if !transition.animation.isImmediate { + self.layer.removeAnimation(forKey: "positionUpdate") + } + } else { + previousPosition = self.layer.position + } + + if previousPosition != position || forceUpdate { + self.center = position + if case let .curve(duration, curve) = transition.animation { + self.layer.animate( + from: NSValue(cgPoint: CGPoint(x: previousPosition.x - position.x, y: previousPosition.y - position.y)), + to: NSValue(cgPoint: CGPoint()), + keyPath: "position", + duration: duration, + delay: 0.0, + curve: curve, + removeOnCompletion: true, + additive: true, + completion: nil, + key: "positionUpdate" + ) + } + } + } + } + + final class ResetScrollingRequest: Equatable { + let requestId: Int + let id: AnyHashable + + init(requestId: Int, id: AnyHashable) { + self.requestId = requestId + self.id = id + } + + static func ==(lhs: ResetScrollingRequest, rhs: ResetScrollingRequest) -> Bool { + if lhs === rhs { + return true + } + if lhs.requestId != rhs.requestId { + return false + } + if lhs.id != rhs.id { + return false + } + return true + } + } + + public final class ExternalState { + public struct Value: Equatable { + var resetScrollingRequest: ResetScrollingRequest? + + public static func ==(lhs: Value, rhs: Value) -> Bool { + if lhs.resetScrollingRequest != rhs.resetScrollingRequest { + return false + } + return true + } + } + + public private(set) var value: Value = Value() + private var nextId: Int = 0 + + public init() { + + } + + public func resetScrolling(id: AnyHashable) { + let requestId = self.nextId + self.nextId += 1 + self.value.resetScrollingRequest = ResetScrollingRequest(requestId: requestId, id: id) + } + } + + public enum Direction { + case vertical + case horizontal + } + + public final class VisibleItem { + public let item: AnyComponentWithIdentity + public let frame: CGRect + + init(item: AnyComponentWithIdentity, frame: CGRect) { + self.item = item + self.frame = frame + } + } + + public final class VisibleItems: Sequence, IteratorProtocol { + private let view: AsyncListComponent.View + private var index: Int = 0 + private let indices: [(Int, CGRect)] + + init(view: AsyncListComponent.View, direction: Direction) { + self.view = view + var indices: [(Int, CGRect)] = [] + view.listNode.forEachItemNode { itemNode in + if let itemNode = itemNode as? ListItemNodeImpl, let index = itemNode.index { + var itemFrame = itemNode.frame + itemFrame.origin.y -= itemNode.transitionOffset + if let animation = itemNode.animationForKey("height") { + if let height = animation.to as? CGFloat { + itemFrame.size.height = height + } + } + + if case .horizontal = direction { + itemFrame = CGRect(origin: CGPoint(x: itemFrame.minY, y: itemFrame.minX), size: CGSize(width: itemFrame.height, height: itemFrame.width)) + } + + indices.append((index, itemFrame)) + } + } + indices.sort(by: { $0.0 < $1.0 }) + self.indices = indices + } + + public func next() -> VisibleItem? { + if self.index >= self.indices.count { + return nil + } + let index = self.index + self.index += 1 + + if let component = self.view.component { + let (itemIndex, itemFrame) = self.indices[index] + return VisibleItem(item: component.items[itemIndex], frame: itemFrame) + } + + return nil + } + } + + public let externalState: ExternalState + public let externalStateValue: ExternalState.Value + public let items: [AnyComponentWithIdentity] + public let itemSetId: AnyHashable // Changing itemSetId supresses update animations + public let direction: Direction + public let insets: UIEdgeInsets + public let reorderItems: ((Int, Int) -> Bool)? + public let onVisibleItemsUpdated: ((VisibleItems, ComponentTransition) -> Void)? + + public init( + externalState: ExternalState, + items: [AnyComponentWithIdentity], + itemSetId: AnyHashable, + direction: Direction, + insets: UIEdgeInsets, + reorderItems: ((Int, Int) -> Bool)? = nil, + onVisibleItemsUpdated: ((VisibleItems, ComponentTransition) -> Void)? = nil + ) { + self.externalState = externalState + self.externalStateValue = externalState.value + self.items = items + self.itemSetId = itemSetId + self.direction = direction + self.insets = insets + self.reorderItems = reorderItems + self.onVisibleItemsUpdated = onVisibleItemsUpdated + } + + public static func ==(lhs: AsyncListComponent, rhs: AsyncListComponent) -> Bool { + if lhs.externalState !== rhs.externalState { + return false + } + if lhs.items != rhs.items { + return false + } + if lhs.itemSetId != rhs.itemSetId { + return false + } + if lhs.direction != rhs.direction { + return false + } + if lhs.insets != rhs.insets { + return false + } + if (lhs.reorderItems == nil) != (rhs.reorderItems == nil) { + return false + } + return true + } + + private struct ItemEntry: Comparable, Identifiable { + let contents: AnyComponentWithIdentity + let index: Int + + var id: AnyHashable { + return self.contents.id + } + + var stableId: AnyHashable { + return self.id + } + + static func ==(lhs: ItemEntry, rhs: ItemEntry) -> Bool { + if lhs.contents != rhs.contents { + return false + } + if lhs.index != rhs.index { + return false + } + return true + } + + static func <(lhs: ItemEntry, rhs: ItemEntry) -> Bool { + return lhs.index < rhs.index + } + + func item(parentView: AsyncListComponent.View?, direction: Direction) -> ListViewItem { + return ListItemImpl(parentView: parentView, contents: self.contents, direction: direction) + } + } + + private final class ListItemImpl: ListViewItem { + weak var parentView: AsyncListComponent.View? + let contents: AnyComponentWithIdentity + let direction: Direction + + let selectable: Bool = false + + init(parentView: AsyncListComponent.View?, contents: AnyComponentWithIdentity, direction: Direction) { + self.parentView = parentView + self.contents = contents + self.direction = direction + } + + func nodeConfiguredForParams( + async: @escaping (@escaping () -> Void) -> Void, + params: ListViewItemLayoutParams, + synchronousLoads: Bool, + previousItem: ListViewItem?, + nextItem: ListViewItem?, + completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void + ) { + async { + let impl: () -> Void = { + let node = ListItemNodeImpl() + let (nodeLayout, apply) = node.asyncLayout()(self, params) + node.insets = nodeLayout.insets + node.contentSize = nodeLayout.contentSize + + Queue.mainQueue().async { + completion(node, { + return (nil, { _ in + apply(false) + }) + }) + } + } + + if Thread.isMainThread { + impl() + } else { + assert(false) + Queue.mainQueue().async { + impl() + } + } + } + } + + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { + Queue.mainQueue().async { + assert(node() is ListItemNodeImpl) + if let nodeValue = node() as? ListItemNodeImpl { + let layout = nodeValue.asyncLayout() + async { + let impl: () -> Void = { + let (nodeLayout, apply) = layout(self, params) + Queue.mainQueue().async { + completion(nodeLayout, { _ in + apply(animation.isAnimated) + }) + } + } + + if Thread.isMainThread { + impl() + } else { + assert(false) + Queue.mainQueue().async { + impl() + } + } + } + } + } + } + } + + private final class ListItemNodeImpl: ListViewItemNode { + private let contentContainer: UIView + private let contentsView = ComponentView() + private(set) var item: ListItemImpl? + + init() { + self.contentContainer = UIView() + + super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + + self.view.addSubview(self.contentContainer) + + self.scrollPositioningInsets = UIEdgeInsets(top: -24.0, left: 0.0, bottom: -24.0, right: 0.0) + } + + deinit { + } + + override func isReorderable(at point: CGPoint) -> Bool { + if let itemView = self.contentsView.view as? ItemView { + return itemView.isReorderable(at: self.view.convert(point, to: itemView)) + } + return false + } + + override func snapshotForReordering() -> UIView? { + return self.view.snapshotView(afterScreenUpdates: false) + } + + func asyncLayout() -> (ListItemImpl, ListViewItemLayoutParams) -> (ListViewItemNodeLayout, (Bool) -> Void) { + return { item, params in + let containerSize: CGSize + switch item.direction { + case .vertical: + containerSize = CGSize(width: params.width, height: 100000.0) + case .horizontal: + containerSize = CGSize(width: 100000.0, height: params.width) + } + + let contentsSize = self.contentsView.update( + transition: .immediate, + component: item.contents.component, + environment: {}, + containerSize: containerSize + ) + + let mappedContentsSize: CGSize + switch item.direction { + case .vertical: + mappedContentsSize = CGSize(width: params.width, height: contentsSize.height) + case .horizontal: + mappedContentsSize = CGSize(width: params.width, height: contentsSize.width) + } + + let itemLayout = ListViewItemNodeLayout(contentSize: mappedContentsSize, insets: UIEdgeInsets()) + return (itemLayout, { animated in + self.item = item + + switch item.direction { + case .vertical: + self.contentContainer.layer.sublayerTransform = CATransform3DIdentity + case .horizontal: + self.contentContainer.layer.sublayerTransform = CATransform3DMakeRotation(CGFloat.pi / 2.0, 0.0, 0.0, 1.0) + } + self.contentContainer.frame = CGRect(origin: CGPoint(), size: mappedContentsSize) + + let contentsFrame = CGRect(origin: CGPoint(), size: contentsSize) + + if let contentsComponentView = self.contentsView.view { + if contentsComponentView.superview == nil { + self.contentContainer.addSubview(contentsComponentView) + } + contentsComponentView.center = CGPoint(x: mappedContentsSize.width * 0.5, y: mappedContentsSize.height * 0.5) + contentsComponentView.bounds = CGRect(origin: CGPoint(), size: contentsFrame.size) + } + }) + } + } + + override func animateInsertion(_ currentTimestamp: Double, duration: Double, options: ListViewItemAnimationOptions) { + super.animateInsertion(currentTimestamp, duration: duration, options: options) + + self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) + } + + override func animateRemoved(_ currentTimestamp: Double, duration: Double) { + super.animateRemoved(currentTimestamp, duration: duration) + + self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false) + } + + override func animateAdded(_ currentTimestamp: Double, duration: Double) { + super.animateAdded(currentTimestamp, duration: duration) + + self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) + } + } + + public final class View: UIView { + let listNode: ListView + + private var externalStateValue: ExternalState.Value? + private var isUpdating: Bool = false + private(set) var component: AsyncListComponent? + + private var currentEntries: [ItemEntry] = [] + + private var ignoreUpdateVisibleItems: Bool = false + + public override init(frame: CGRect) { + self.listNode = ListView() + self.listNode.useMainQueueTransactions = true + self.listNode.scroller.delaysContentTouches = false + self.listNode.reorderedItemHasShadow = false + + super.init(frame: frame) + + self.addSubview(self.listNode.view) + + self.listNode.onContentsUpdated = { [weak self] transition in + guard let self else { + return + } + self.updateVisibleItems(transition: ComponentTransition(transition)) + } + } + + required public init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + return super.hitTest(point, with: event) + } + + public func stopScrolling() { + self.listNode.stopScrolling() + } + + private func updateVisibleItems(transition: ComponentTransition) { + if self.ignoreUpdateVisibleItems { + return + } + guard let component = self.component else { + return + } + if let onVisibleItemsUpdated = component.onVisibleItemsUpdated { + onVisibleItemsUpdated(VisibleItems(view: self, direction: component.direction), transition) + } + } + + func update(component: AsyncListComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + let previousComponent = self.component + self.component = component + + let listSize: CGSize + let listInsets: UIEdgeInsets + switch component.direction { + case .vertical: + self.listNode.transform = CATransform3DIdentity + listSize = CGSize(width: availableSize.width, height: availableSize.height) + listInsets = component.insets + case .horizontal: + self.listNode.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0) + listSize = CGSize(width: availableSize.height, height: availableSize.width) + listInsets = UIEdgeInsets(top: component.insets.left, left: component.insets.top, bottom: component.insets.right, right: component.insets.bottom) + } + + var updateSizeAndInsets = ListViewUpdateSizeAndInsets( + size: listSize, + insets: listInsets, + duration: 0.0, + curve: .Default(duration: nil) + ) + + var animateTransition = false + var transactionOptions: ListViewDeleteAndInsertOptions = [] + + if !transition.animation.isImmediate, let previousComponent { + if previousComponent.itemSetId == component.itemSetId { + transactionOptions.insert(.AnimateInsertion) + } + animateTransition = true + + switch transition.animation { + case .none: + break + case let .curve(duration, curve): + updateSizeAndInsets.duration = duration + switch curve { + case .linear, .easeInOut: + updateSizeAndInsets.curve = .Default(duration: duration) + case .spring: + updateSizeAndInsets.curve = .Spring(duration: duration) + case let .custom(a, b, c, d): + updateSizeAndInsets.curve = .Custom(duration: duration, a, b, c, d) + } + } + } + + var entries: [ItemEntry] = [] + for item in component.items { + entries.append(ItemEntry( + contents: item, + index: entries.count + )) + } + + var scrollToItem: ListViewScrollToItem? + if let resetScrollingRequest = component.externalStateValue.resetScrollingRequest, previousComponent?.externalStateValue.resetScrollingRequest != component.externalStateValue.resetScrollingRequest { + if let index = entries.firstIndex(where: { $0.id == resetScrollingRequest.id }) { + var directionHint: ListViewScrollToItemDirectionHint = .Down + var didSelectDirection = false + self.listNode.forEachItemNode { itemNode in + if didSelectDirection { + return + } + if let itemNode = itemNode as? ListItemNodeImpl, let itemIndex = itemNode.index { + if itemIndex <= index { + directionHint = .Up + } else { + directionHint = .Down + } + didSelectDirection = true + } + } + + scrollToItem = ListViewScrollToItem( + index: index, + position: .visible, + animated: animateTransition, + curve: updateSizeAndInsets.curve, + directionHint: directionHint + ) + } + } + + self.ignoreUpdateVisibleItems = true + + let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: self.currentEntries, rightList: entries) + self.currentEntries = entries + let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } + let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(parentView: self, direction: component.direction), directionHint: .Down) } + let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(parentView: self, direction: component.direction), directionHint: nil) } + + transactionOptions.insert(.Synchronous) + + self.listNode.transaction( + deleteIndices: [], + insertIndicesAndItems: [], + updateIndicesAndItems: [], + options: transactionOptions, + scrollToItem: nil, + updateSizeAndInsets: updateSizeAndInsets, + stationaryItemRange: nil, + updateOpaqueState: nil, + completion: { _ in } + ) + + self.listNode.transaction( + deleteIndices: deletions, + insertIndicesAndItems: insertions, + updateIndicesAndItems: updates, + options: transactionOptions, + scrollToItem: scrollToItem, + updateSizeAndInsets: nil, + stationaryItemRange: nil, + updateOpaqueState: nil, + completion: { _ in } + ) + + let mappedListFrame: CGRect + switch component.direction { + case .vertical: + mappedListFrame = CGRect(origin: CGPoint(x: availableSize.width * 0.5, y: availableSize.height * 0.5), size: listSize) + case .horizontal: + mappedListFrame = CGRect(origin: CGPoint(x: availableSize.width * 0.5, y: availableSize.height * 0.5), size: listSize) + } + self.listNode.position = mappedListFrame.origin + self.listNode.bounds = CGRect(origin: CGPoint(), size: mappedListFrame.size) + + self.listNode.reorderItem = { [weak self] fromIndex, toIndex, _ in + guard let self, let component = self.component else { + return .single(false) + } + guard let reorderItems = component.reorderItems else { + return .single(false) + } + + if reorderItems(fromIndex, toIndex) { + return .single(true) + } else { + return .single(false) + } + } + + self.ignoreUpdateVisibleItems = false + + self.updateVisibleItems(transition: transition) + + return availableSize + } + } + + public func makeView() -> View { + return View(frame: CGRect()) + } + + public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition) + } +} diff --git a/submodules/TelegramUI/Components/Chat/ChatChannelSubscriberInputPanelNode/Sources/ChatChannelSubscriberInputPanelNode.swift b/submodules/TelegramUI/Components/Chat/ChatChannelSubscriberInputPanelNode/Sources/ChatChannelSubscriberInputPanelNode.swift index 7a82d4ddde..885f479a43 100644 --- a/submodules/TelegramUI/Components/Chat/ChatChannelSubscriberInputPanelNode/Sources/ChatChannelSubscriberInputPanelNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatChannelSubscriberInputPanelNode/Sources/ChatChannelSubscriberInputPanelNode.swift @@ -381,14 +381,13 @@ public final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let _ = presentationData - //TODO:localize - let text: String = "Tap here to suggest a message" + let text: String = presentationData.strings.Chat_ChannelMessagesHint let tooltipController = TooltipScreen( account: context.account, sharedContext: context.sharedContext, text: .plain(text: text), - textBadge: "NEW", + textBadge: presentationData.strings.Chat_ChannelMessagesHintBadge.isEmpty ? nil : presentationData.strings.Chat_ChannelMessagesHintBadge, balancedTextLayout: false, style: .wide, arrowStyle: .small, diff --git a/submodules/TelegramUI/Components/Chat/ChatContextResultPeekContent/BUILD b/submodules/TelegramUI/Components/Chat/ChatContextResultPeekContent/BUILD index 436d275171..7dc886d4b5 100644 --- a/submodules/TelegramUI/Components/Chat/ChatContextResultPeekContent/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatContextResultPeekContent/BUILD @@ -19,7 +19,8 @@ swift_library( "//submodules/AppBundle", "//submodules/ContextUI", "//submodules/SoftwareVideo", - "//submodules/TelegramUI/Components/MultiplexedVideoNode", + "//submodules/TelegramUI/Components/BatchVideoRendering", + "//submodules/TelegramUI/Components/GifVideoLayer", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/Chat/ChatContextResultPeekContent/Sources/ChatContextResultPeekContent.swift b/submodules/TelegramUI/Components/Chat/ChatContextResultPeekContent/Sources/ChatContextResultPeekContent.swift index 5e55312bd9..0b75b02a83 100644 --- a/submodules/TelegramUI/Components/Chat/ChatContextResultPeekContent/Sources/ChatContextResultPeekContent.swift +++ b/submodules/TelegramUI/Components/Chat/ChatContextResultPeekContent/Sources/ChatContextResultPeekContent.swift @@ -10,17 +10,21 @@ import PhotoResources import AppBundle import ContextUI import SoftwareVideo -import MultiplexedVideoNode +import BatchVideoRendering +import GifVideoLayer +import AccountContext public final class ChatContextResultPeekContent: PeekControllerContent { - public let account: Account + public let context: AccountContext public let contextResult: ChatContextResult public let menu: [ContextMenuItem] + public let batchVideoContext: BatchVideoRenderingContext - public init(account: Account, contextResult: ChatContextResult, menu: [ContextMenuItem]) { - self.account = account + public init(context: AccountContext, contextResult: ChatContextResult, menu: [ContextMenuItem], batchVideoContext: BatchVideoRenderingContext) { + self.context = context self.contextResult = contextResult self.menu = menu + self.batchVideoContext = batchVideoContext } public func presentation() -> PeekControllerContentPresentation { @@ -36,7 +40,7 @@ public final class ChatContextResultPeekContent: PeekControllerContent { } public func node() -> PeekControllerContentNode & ASDisplayNode { - return ChatContextResultPeekNode(account: self.account, contextResult: self.contextResult) + return ChatContextResultPeekNode(context: self.context, contextResult: self.contextResult, batchVideoContext: self.batchVideoContext) } public func topAccessoryNode() -> ASDisplayNode? { @@ -62,62 +66,29 @@ public final class ChatContextResultPeekContent: PeekControllerContent { } private final class ChatContextResultPeekNode: ASDisplayNode, PeekControllerContentNode { - private let account: Account + private let context: AccountContext private let contextResult: ChatContextResult + private let batchVideoContext: BatchVideoRenderingContext private let imageNodeBackground: ASDisplayNode private let imageNode: TransformImageNode - private var videoLayer: (SoftwareVideoThumbnailNode, SoftwareVideoLayerFrameManager, SampleBufferLayer)? + private var videoLayer: GifVideoLayer? private var currentImageResource: TelegramMediaResource? private var currentVideoFile: TelegramMediaFile? - private let timebase: CMTimebase - - private var displayLink: CADisplayLink? private var ticking: Bool = false { didSet { if self.ticking != oldValue { - if self.ticking { - class DisplayLinkProxy: NSObject { - weak var target: ChatContextResultPeekNode? - init(target: ChatContextResultPeekNode) { - self.target = target - } - - @objc func displayLinkEvent() { - self.target?.displayLinkEvent() - } - } - - let displayLink = CADisplayLink(target: DisplayLinkProxy(target: self), selector: #selector(DisplayLinkProxy.displayLinkEvent)) - self.displayLink = displayLink - displayLink.add(to: RunLoop.main, forMode: .common) - if #available(iOS 10.0, *) { - displayLink.preferredFramesPerSecond = 25 - } else { - displayLink.frameInterval = 2 - } - displayLink.isPaused = false - CMTimebaseSetRate(self.timebase, rate: 1.0) - } else if let displayLink = self.displayLink { - self.displayLink = nil - displayLink.isPaused = true - displayLink.invalidate() - CMTimebaseSetRate(self.timebase, rate: 0.0) - } + self.videoLayer?.shouldBeAnimating = self.ticking } } } - private func displayLinkEvent() { - let timestamp = CMTimebaseGetTime(self.timebase).seconds - self.videoLayer?.1.tick(timestamp: timestamp) - } - - init(account: Account, contextResult: ChatContextResult) { - self.account = account + init(context: AccountContext, contextResult: ChatContextResult, batchVideoContext: BatchVideoRenderingContext) { + self.context = context self.contextResult = contextResult + self.batchVideoContext = batchVideoContext self.imageNodeBackground = ASDisplayNode() self.imageNodeBackground.isLayerBacked = true @@ -128,11 +99,6 @@ private final class ChatContextResultPeekNode: ASDisplayNode, PeekControllerCont self.imageNode.isLayerBacked = !smartInvertColorsEnabled() self.imageNode.displaysAsynchronously = false - var timebase: CMTimebase? - CMTimebaseCreateWithSourceClock(allocator: nil, sourceClock: CMClockGetHostTimeClock(), timebaseOut: &timebase) - CMTimebaseSetRate(timebase!, rate: 0.0) - self.timebase = timebase! - super.init() self.addSubnode(self.imageNodeBackground) @@ -142,10 +108,6 @@ private final class ChatContextResultPeekNode: ASDisplayNode, PeekControllerCont } deinit { - if let displayLink = self.displayLink { - displayLink.isPaused = true - displayLink.invalidate() - } } func ready() -> Signal { @@ -236,7 +198,7 @@ private final class ChatContextResultPeekNode: ASDisplayNode, PeekControllerCont if let imageResource = imageResource { let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: Int32(fittedImageDimensions.width * 2.0), height: Int32(fittedImageDimensions.height * 2.0)), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false) let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) - updateImageSignal = chatMessagePhoto(postbox: self.account.postbox, userLocation: .other, photoReference: .standalone(media: tmpImage)) + updateImageSignal = chatMessagePhoto(postbox: self.context.account.postbox, userLocation: .other, photoReference: .standalone(media: tmpImage)) } else { updateImageSignal = .complete() } @@ -256,33 +218,26 @@ private final class ChatContextResultPeekNode: ASDisplayNode, PeekControllerCont } if updatedVideoFile { - if let (thumbnailLayer, _, layer) = self.videoLayer { + if let videoLayer = self.videoLayer { self.videoLayer = nil - thumbnailLayer.removeFromSupernode() - layer.layer.removeFromSuperlayer() + videoLayer.removeFromSuperlayer() } - if let videoFileReference = videoFileReference { - let thumbnailLayer = SoftwareVideoThumbnailNode(account: self.account, fileReference: videoFileReference, synchronousLoad: false) - self.addSubnode(thumbnailLayer) - let layerHolder = takeSampleBufferLayer() - layerHolder.layer.videoGravity = AVLayerVideoGravity.resizeAspectFill - self.layer.addSublayer(layerHolder.layer) - let manager = SoftwareVideoLayerFrameManager(account: self.account, userLocation: .other, userContentType: .other, fileReference: videoFileReference, layerHolder: layerHolder) - self.videoLayer = (thumbnailLayer, manager, layerHolder) - thumbnailLayer.ready = { [weak self, weak thumbnailLayer, weak manager] in - if let strongSelf = self, let thumbnailLayer = thumbnailLayer, let manager = manager { - if strongSelf.videoLayer?.0 === thumbnailLayer && strongSelf.videoLayer?.1 === manager { - manager.start() - } - } - } + if let videoFileReference { + let videoLayer = GifVideoLayer( + context: self.context, + batchVideoContext: self.batchVideoContext, + userLocation: .other, + file: videoFileReference, + synchronousLoad: false + ) + self.videoLayer = videoLayer + self.layer.addSublayer(videoLayer) } } - if let (thumbnailLayer, _, layer) = self.videoLayer { - thumbnailLayer.frame = CGRect(origin: CGPoint(), size: croppedImageDimensions) - layer.layer.frame = CGRect(origin: CGPoint(), size: CGSize(width: croppedImageDimensions.width, height: croppedImageDimensions.height)) + if let videoLayer = self.videoLayer { + videoLayer.frame = CGRect(origin: CGPoint(), size: CGSize(width: croppedImageDimensions.width, height: croppedImageDimensions.height)) } if !self.ticking { diff --git a/submodules/TelegramUI/Components/Chat/ChatEmptyNode/Sources/ChatEmptyNode.swift b/submodules/TelegramUI/Components/Chat/ChatEmptyNode/Sources/ChatEmptyNode.swift index 535c0b7a65..82f9898882 100644 --- a/submodules/TelegramUI/Components/Chat/ChatEmptyNode/Sources/ChatEmptyNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatEmptyNode/Sources/ChatEmptyNode.swift @@ -372,7 +372,7 @@ public final class ChatEmptyNodeNearbyChatContent: ASDisplayNode, ChatEmptyNodeS let distance = interfaceState.peerNearbyData?.distance ?? 0 if let renderedPeer = interfaceState.renderedPeer { - if let chatPeer = renderedPeer.peers[renderedPeer.peerId] { + if let chatPeer = renderedPeer.chatOrMonoforumMainPeer { displayName = EnginePeer(chatPeer).compactDisplayTitle } } @@ -1205,7 +1205,7 @@ public final class ChatEmptyNodePremiumRequiredChatContent: ASDisplayNode, ChatE private let interaction: ChatPanelInterfaceInteraction? private let iconBackground: SimpleLayer - private let icon = ComponentView() + private var icon = ComponentView() private let text = ComponentView() private let buttonTitle = ComponentView() private let button: HighlightTrackingButton @@ -1279,14 +1279,14 @@ public final class ChatEmptyNodePremiumRequiredChatContent: ASDisplayNode, ChatE let textButtonSpacing: CGFloat = 12.0 let peerTitle: String - if let peer = interfaceState.renderedPeer?.chatMainPeer { + if let peer = interfaceState.renderedPeer?.chatOrMonoforumMainPeer { peerTitle = EnginePeer(peer).compactDisplayTitle } else { peerTitle = " " } let text: NSAttributedString - let actionText: String + var actionText: String? let attributes = MarkdownAttributes( body: MarkdownAttributeSet(font: Font.regular(15.0), textColor: serviceColor.primaryText), bold: MarkdownAttributeSet(font: Font.semibold(15.0), textColor: serviceColor.primaryText), @@ -1313,14 +1313,19 @@ public final class ChatEmptyNodePremiumRequiredChatContent: ASDisplayNode, ChatE text = attributedString actionText = interfaceState.strings.Chat_EmptyStatePaidMessaging_Action } else { - let rawText: String - if self.isPremiumDisabled { - rawText = interfaceState.strings.Chat_EmptyStateMessagingRestrictedToPremiumDisabled_Text(peerTitle).string + if let channel = interfaceState.renderedPeer?.peer as? TelegramChannel, channel.isMonoForum { + let rawText = interfaceState.strings.Chat_EmptyStateMonoforum_Text(peerTitle).string + text = parseMarkdownIntoAttributedString(rawText, attributes: attributes) } else { - rawText = interfaceState.strings.Chat_EmptyStateMessagingRestrictedToPremium_Text(peerTitle).string + let rawText: String + if self.isPremiumDisabled { + rawText = interfaceState.strings.Chat_EmptyStateMessagingRestrictedToPremiumDisabled_Text(peerTitle).string + } else { + rawText = interfaceState.strings.Chat_EmptyStateMessagingRestrictedToPremium_Text(peerTitle).string + } + text = parseMarkdownIntoAttributedString(rawText, attributes: attributes) + actionText = interfaceState.strings.Chat_EmptyStateMessagingRestrictedToPremium_Action } - text = parseMarkdownIntoAttributedString(rawText, attributes: attributes) - actionText = interfaceState.strings.Chat_EmptyStateMessagingRestrictedToPremium_Action } let textSize = self.text.update( transition: .immediate, @@ -1333,21 +1338,30 @@ public final class ChatEmptyNodePremiumRequiredChatContent: ASDisplayNode, ChatE containerSize: CGSize(width: maxWidth - sideInset * 2.0, height: 500.0) ) - let buttonTitleSize = self.buttonTitle.update( - transition: .immediate, - component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: actionText, font: Font.semibold(15.0), textColor: serviceColor.primaryText)) - )), - environment: {}, - containerSize: CGSize(width: 200.0, height: 100.0) - ) - let buttonSize = CGSize(width: buttonTitleSize.width + 20.0 * 2.0, height: buttonTitleSize.height + 9.0 * 2.0) + var buttonTitleSize: CGSize? + if let actionText { + buttonTitleSize = self.buttonTitle.update( + transition: .immediate, + component: AnyComponent(MultilineTextComponent( + text: .plain(NSAttributedString(string: actionText, font: Font.semibold(15.0), textColor: serviceColor.primaryText)) + )), + environment: {}, + containerSize: CGSize(width: 200.0, height: 100.0) + ) + } else { + self.buttonTitle.view?.removeFromSuperview() + } + + var buttonSize: CGSize? + if let buttonTitleSize { + buttonSize = CGSize(width: buttonTitleSize.width + 20.0 * 2.0, height: buttonTitleSize.height + 9.0 * 2.0) + } var contentsWidth: CGFloat = 0.0 contentsWidth = max(contentsWidth, iconBackgroundSize + sideInset * 2.0) contentsWidth = max(contentsWidth, textSize.width + sideInset * 2.0) - if !self.isPremiumDisabled { + if !self.isPremiumDisabled, let buttonSize { contentsWidth = max(contentsWidth, buttonSize.width + sideInset * 2.0) } @@ -1363,14 +1377,31 @@ public final class ChatEmptyNodePremiumRequiredChatContent: ASDisplayNode, ChatE let iconComponent: AnyComponent do { - iconComponent = AnyComponent( - LottieComponent( - content: LottieComponent.AppBundleContent(name: "PremiumRequired"), - color: serviceColor.primaryText, - size: CGSize(width: 120.0, height: 120.0), - loop: true + if let channel = interfaceState.renderedPeer?.peer as? TelegramChannel, channel.isMonoForum { + if let view = self.icon.view, !(view is BundleIconComponent.View) { + view.removeFromSuperview() + self.icon = ComponentView() + } + + iconComponent = AnyComponent(BundleIconComponent( + name: "Chat/Empty Chat/ChannelMessages", + tintColor: serviceColor.primaryText + )) + } else { + if let view = self.icon.view, !(view is LottieComponent.View) { + view.removeFromSuperview() + self.icon = ComponentView() + } + + iconComponent = AnyComponent( + LottieComponent( + content: LottieComponent.AppBundleContent(name: "PremiumRequired"), + color: serviceColor.primaryText, + size: CGSize(width: 120.0, height: 120.0), + loop: true + ) ) - ) + } } let iconSize = self.icon.update( transition: .immediate, @@ -1397,9 +1428,7 @@ public final class ChatEmptyNodePremiumRequiredChatContent: ASDisplayNode, ChatE } contentsHeight += textSize.height - if self.isPremiumDisabled { - contentsHeight += bottomInset - } else { + if !self.isPremiumDisabled, let buttonTitleSize, let buttonSize { contentsHeight += textButtonSpacing let buttonFrame = CGRect(origin: CGPoint(x: floor((contentsWidth - buttonSize.width) * 0.5), y: contentsHeight), size: buttonSize) @@ -1416,6 +1445,8 @@ public final class ChatEmptyNodePremiumRequiredChatContent: ASDisplayNode, ChatE self.buttonStarsNode.frame = CGRect(origin: CGPoint(), size: buttonSize) contentsHeight += buttonSize.height contentsHeight += bottomInset + } else { + contentsHeight += bottomInset } @@ -1432,7 +1463,7 @@ private enum ChatEmptyNodeContentType: Equatable { case greeting case topic case premiumRequired - case starsRequired(Int64) + case starsRequired(Int64?) } private final class EmptyAttachedDescriptionNode: HighlightTrackingButtonNode { @@ -1835,8 +1866,8 @@ public final class ChatEmptyNode: ASDisplayNode { } } } - } else if let channel = peer as? TelegramChannel, channel.isMonoForum, let sendPaidMessageStars = interfaceState.sendPaidMessageStars { - contentType = .starsRequired(sendPaidMessageStars.value) + } else if let channel = peer as? TelegramChannel, channel.isMonoForum { + contentType = .starsRequired(interfaceState.sendPaidMessageStars?.value) } else { contentType = .regular } @@ -1927,7 +1958,7 @@ public final class ChatEmptyNode: ASDisplayNode { transition.updateFrame(node: self.backgroundNode, frame: contentFrame) self.backgroundNode.update(size: self.backgroundNode.bounds.size, cornerRadius: min(20.0, self.backgroundNode.bounds.height / 2.0), transition: transition) - if displayAttachedDescription, let peer = interfaceState.renderedPeer?.chatMainPeer { + if displayAttachedDescription, let peer = interfaceState.renderedPeer?.chatOrMonoforumMainPeer { let isPremium = interfaceState.isPremium let attachedDescriptionNode: EmptyAttachedDescriptionNode if let current = self.attachedDescriptionNode { diff --git a/submodules/TelegramUI/Components/Chat/ChatLoadingNode/Sources/ChatLoadingNode.swift b/submodules/TelegramUI/Components/Chat/ChatLoadingNode/Sources/ChatLoadingNode.swift index 79537cbef6..9ca1f0c736 100644 --- a/submodules/TelegramUI/Components/Chat/ChatLoadingNode/Sources/ChatLoadingNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatLoadingNode/Sources/ChatLoadingNode.swift @@ -215,7 +215,10 @@ public final class ChatLoadingPlaceholderNode: ASDisplayNode { self.borderNode.view.mask = self.borderMaskNode.view if self.context.sharedContext.energyUsageSettings.fullTranslucency { - Queue.mainQueue().after(0.3) { + Queue.mainQueue().after(0.3) { [weak self] in + guard let self else { + return + } if !self.didAnimateOut { self.backgroundNode?.updateIsLooping(true) } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift index 635239cca1..6fbd76a16d 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift @@ -619,8 +619,6 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI private let shadowNode: ChatMessageShadowNode private var clippingNode: ChatMessageBubbleClippingNode - private var suggestedPostInfoNode: ChatMessageSuggestedPostInfoNode? - override public var extractedBackgroundNode: ASDisplayNode? { return self.shadowNode } @@ -1427,8 +1425,6 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI let weakSelf = Weak(self) - let makeSuggestedPostInfoNodeLayout: ChatMessageSuggestedPostInfoNode.AsyncLayout = ChatMessageSuggestedPostInfoNode.asyncLayout(self.suggestedPostInfoNode) - return { item, params, mergedTop, mergedBottom, dateHeaderAtBottom in let layoutConstants = chatMessageItemLayoutConstants(layoutConstants, params: params, presentationData: item.presentationData) return ChatMessageBubbleItemNode.beginLayout( @@ -1451,7 +1447,6 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI unlockButtonLayout: unlockButtonLayout, mediaInfoLayout: mediaInfoLayout, mosaicStatusLayout: mosaicStatusLayout, - makeSuggestedPostInfoNodeLayout: makeSuggestedPostInfoNodeLayout, layoutConstants: layoutConstants, currentItem: currentItem, currentForwardInfo: currentForwardInfo, @@ -1480,7 +1475,6 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI unlockButtonLayout: (ChatMessageUnlockMediaNode.Arguments) -> (CGSize, (Bool) -> ChatMessageUnlockMediaNode), mediaInfoLayout: (ChatMessageStarsMediaInfoNode.Arguments) -> (CGSize, (Bool) -> ChatMessageStarsMediaInfoNode), mosaicStatusLayout: (ChatMessageDateAndStatusNode.Arguments) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation) -> ChatMessageDateAndStatusNode)), - makeSuggestedPostInfoNodeLayout: ChatMessageSuggestedPostInfoNode.AsyncLayout, layoutConstants: ChatMessageItemLayoutConstants, currentItem: ChatMessageItem?, currentForwardInfo: (Peer?, String?)?, @@ -1597,7 +1591,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } } if isMonoForum { - if case .replyThread = item.chatLocation { + if case let .replyThread(replyThreadMessage) = item.chatLocation, firstMessage.effectivelyIncoming(item.context.account.peerId), item.effectiveAuthorId == PeerId(replyThreadMessage.threadId) { displayAuthorInfo = false } } @@ -1713,10 +1707,6 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } } else if item.message.id.peerId.isRepliesOrVerificationCodes { needsShareButton = false - } else if let channel = item.content.firstMessage.peers[item.content.firstMessage.id.peerId] as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = item.content.firstMessage.peers[linkedMonoforumId] as? TelegramChannel, mainChannel.hasPermission(.sendSomething), case .peer = item.chatLocation { - if incoming { - needsShareButton = true - } } else if incoming { if let _ = sourceReference { needsShareButton = true @@ -3000,7 +2990,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI var totalContentNodesHeight: CGFloat = 0.0 var currentContainerGroupOverlap: CGFloat = 0.0 var detachedContentNodesHeight: CGFloat = 0.0 - var additionalTopHeight: CGFloat = 0.0 + let additionalTopHeight: CGFloat = 0.0 var mosaicStatusOrigin: CGPoint? var unlockButtonPosition: CGPoint? @@ -3176,13 +3166,6 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } reactionButtonsSizeAndApply = reactionButtonsFinalize(maxContentWidth) } - - var suggestedPostInfoNodeLayout: (CGSize, () -> ChatMessageSuggestedPostInfoNode)? - suggestedPostInfoNodeLayout = nil - - if let suggestedPostInfoNodeLayout { - additionalTopHeight += 4.0 + suggestedPostInfoNodeLayout.0.height + 8.0 - } let minimalContentSize: CGSize if hideBackground { @@ -3320,7 +3303,6 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI avatarOffset: avatarOffset, hidesHeaders: hidesHeaders, disablesComments: disablesComments, - suggestedPostInfoNodeLayout: suggestedPostInfoNodeLayout, alignment: alignment, isSidePanelOpen: isSidePanelOpen ) @@ -3384,7 +3366,6 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI avatarOffset: CGFloat?, hidesHeaders: Bool, disablesComments: Bool, - suggestedPostInfoNodeLayout: (CGSize, () -> ChatMessageSuggestedPostInfoNode)?, alignment: ChatMessageBubbleContentAlignment, isSidePanelOpen: Bool ) -> Void { @@ -3468,22 +3449,6 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI strongSelf.backgroundNode.backgroundFrame = backgroundFrame - if let (suggestedPostInfoSize, suggestedPostInfoApply) = suggestedPostInfoNodeLayout { - let suggestedPostInfoNode = suggestedPostInfoApply() - if suggestedPostInfoNode !== strongSelf.suggestedPostInfoNode { - strongSelf.suggestedPostInfoNode?.removeFromSupernode() - strongSelf.suggestedPostInfoNode = suggestedPostInfoNode - strongSelf.mainContextSourceNode.contentNode.addSubnode(suggestedPostInfoNode) - - let suggestedPostInfoFrame = CGRect(origin: CGPoint(x: floor((params.width - suggestedPostInfoSize.width) * 0.5), y: 4.0), size: suggestedPostInfoSize) - suggestedPostInfoNode.frame = suggestedPostInfoFrame - //animation.animator.updateFrame(layer: suggestedPostInfoNode.layer, frame: suggestedPostInfoFrame, completion: nil) - } - } else if let suggestedPostInfoNode = strongSelf.suggestedPostInfoNode { - strongSelf.suggestedPostInfoNode = nil - suggestedPostInfoNode.removeFromSupernode() - } - if let avatarOffset { strongSelf.updateAttachedAvatarNodeOffset(offset: avatarOffset, transition: .animated(duration: 0.3, curve: .spring)) } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageSuggestedPostInfoNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageSuggestedPostInfoNode.swift deleted file mode 100644 index 210e0770b6..0000000000 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageSuggestedPostInfoNode.swift +++ /dev/null @@ -1,169 +0,0 @@ -import Foundation -import UIKit -import AsyncDisplayKit -import Display -import SwiftSignalKit -import Postbox -import TelegramCore -import TelegramPresentationData -import TelegramUIPreferences -import TextFormat -import AccountContext -import WallpaperBackgroundNode -import ChatMessageItem -import TelegramStringFormatting - -public final class ChatMessageSuggestedPostInfoNode: ASDisplayNode { - private var titleNode: TextNode? - private var priceLabelNode: TextNode? - private var priceValueNode: TextNode? - private var timeLabelNode: TextNode? - private var timeValueNode: TextNode? - - private var backgroundNode: WallpaperBubbleBackgroundNode? - - override public init() { - super.init() - } - - public typealias AsyncLayout = (ChatMessageItem, CGFloat) -> (CGSize, () -> ChatMessageSuggestedPostInfoNode) - - public static func asyncLayout(_ node: ChatMessageSuggestedPostInfoNode?) -> (ChatMessageItem, CGFloat) -> (CGSize, () -> ChatMessageSuggestedPostInfoNode) { - let makeTitleLayout = TextNode.asyncLayout(node?.titleNode) - let makePriceLabelLayout = TextNode.asyncLayout(node?.priceLabelNode) - let makePriceValueLayout = TextNode.asyncLayout(node?.priceValueNode) - let makeTimeLabelLayout = TextNode.asyncLayout(node?.timeLabelNode) - let makeTimeValueLayout = TextNode.asyncLayout(node?.timeValueNode) - - return { item, maxWidth in - let insets = UIEdgeInsets( - top: 12.0, - left: 12.0, - bottom: 12.0, - right: 12.0 - ) - - let titleSpacing: CGFloat = 8.0 - let labelSpacing: CGFloat = 8.0 - let valuesVerticalSpacing: CGFloat = 2.0 - - var amount: Int64 = 0 - var timestamp: Int32? - - if "".isEmpty { - amount = 0 - timestamp = nil - } - - /*for attribute in item.message.attributes { - if let attribute = attribute as? OutgoingSuggestedPostMessageAttribute { - amount = attribute.price.value - timestamp = attribute.timestamp - } - }*/ - - //TODO:localize - let amountString: String - if amount == 0 { - amountString = "Free" - } else if amount == 1 { - amountString = "1 Star" - } else { - amountString = "\(amount) Stars" - } - - var timestampString: String - if let timestamp { - timestampString = humanReadableStringForTimestamp(strings: item.presentationData.strings, dateTimeFormat: PresentationDateTimeFormat(), timestamp: timestamp, alwaysShowTime: true).string - if timestampString.count > 1 { - timestampString = String(timestampString[timestampString.startIndex]).capitalized + timestampString[timestampString.index(after: timestampString.startIndex)...] - } - } else { - timestampString = "Anytime" - } - - let serviceColor = serviceMessageColorComponents(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper) - - //TODO:localize - let titleLayout = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "You suggest to post\nthis message.", font: Font.regular(13.0), textColor: serviceColor.primaryText), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxWidth - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets())) - - let priceLabelLayout = makePriceLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "Price", font: Font.regular(13.0), textColor: serviceColor.primaryText.withMultipliedAlpha(0.5)), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxWidth - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let timeLabelLayout = makeTimeLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "Time", font: Font.regular(13.0), textColor: serviceColor.primaryText.withMultipliedAlpha(0.5)), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxWidth - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - - let priceValueLayout = makePriceValueLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: amountString, font: Font.semibold(13.0), textColor: serviceColor.primaryText), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxWidth - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let timeValueLayout = makeTimeValueLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: timestampString, font: Font.semibold(13.0), textColor: serviceColor.primaryText), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxWidth - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - - var maxContentWidth: CGFloat = 0.0 - var contentHeight: CGFloat = 0.0 - - maxContentWidth = max(maxContentWidth, titleLayout.0.size.width) - - contentHeight += titleLayout.0.size.height - contentHeight += titleSpacing - - maxContentWidth = max(maxContentWidth, priceLabelLayout.0.size.width + labelSpacing + priceValueLayout.0.size.width) - contentHeight += priceLabelLayout.0.size.height + valuesVerticalSpacing - - maxContentWidth = max(maxContentWidth, timeLabelLayout.0.size.width + labelSpacing + timeValueLayout.0.size.width) - contentHeight += timeLabelLayout.0.size.height - - let size = CGSize(width: insets.left + insets.right + maxContentWidth, height: insets.top + insets.bottom + contentHeight) - - return (size, { - let node = node ?? ChatMessageSuggestedPostInfoNode() - - if node.backgroundNode == nil { - if let backgroundNode = item.controllerInteraction.presentationContext.backgroundNode?.makeBubbleBackground(for: .free) { - node.backgroundNode = backgroundNode - backgroundNode.layer.masksToBounds = true - backgroundNode.layer.cornerRadius = 15.0 - node.insertSubnode(backgroundNode, at: 0) - } - } - - if let backgroundNode = node.backgroundNode { - backgroundNode.frame = CGRect(origin: CGPoint(), size: size) - } - - let titleNode = titleLayout.1() - if node.titleNode !== titleNode { - node.titleNode = titleNode - node.addSubnode(titleNode) - } - let priceLabelNode = priceLabelLayout.1() - if node.priceLabelNode !== priceLabelNode { - node.priceLabelNode = priceLabelNode - node.addSubnode(priceLabelNode) - } - let priceValueNode = priceValueLayout.1() - if node.priceValueNode !== priceValueNode { - node.priceValueNode = priceValueNode - node.addSubnode(priceValueNode) - } - let timeLabelNode = timeLabelLayout.1() - if node.timeLabelNode !== timeLabelNode { - node.timeLabelNode = timeLabelNode - node.addSubnode(timeLabelNode) - } - let timeValueNode = timeValueLayout.1() - if node.timeValueNode !== timeValueNode { - node.timeValueNode = timeValueNode - node.addSubnode(timeValueNode) - } - - let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleLayout.0.size.width) * 0.5), y: insets.top), size: titleLayout.0.size) - titleNode.frame = titleFrame - - let priceLabelFrame = CGRect(origin: CGPoint(x: insets.left, y: titleFrame.maxY + titleSpacing), size: priceLabelLayout.0.size) - priceLabelNode.frame = priceLabelFrame - priceValueNode.frame = CGRect(origin: CGPoint(x: priceLabelFrame.maxX + labelSpacing, y: priceLabelFrame.minY), size: priceValueLayout.0.size) - - let timeLabelFrame = CGRect(origin: CGPoint(x: insets.left, y: priceLabelFrame.maxY + valuesVerticalSpacing), size: timeLabelLayout.0.size) - timeLabelNode.frame = timeLabelFrame - timeValueNode.frame = CGRect(origin: CGPoint(x: timeLabelFrame.maxX + labelSpacing, y: timeLabelFrame.minY), size: timeValueLayout.0.size) - - return node - }) - } - } -} diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift index bf7e26de8b..e586681e6b 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift @@ -19,6 +19,7 @@ import ChatMessageItem import AvatarNode import ComponentFlow import EmojiStatusComponent +import AppBundle private let timezoneOffset: Int32 = { let nowTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) @@ -276,7 +277,7 @@ private final class ChatMessageDateContentNode: ASDisplayNode { let graphics = PresentationResourcesChat.principalGraphics(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, bubbleCorners: presentationData.chatBubbleCorners) - let fullTranslucency: Bool = controllerInteraction?.enableFullTranslucency ?? true + let fullTranslucency: Bool = true self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: fullTranslucency && dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) self.stickBackgroundNode.image = graphics.dateFloatingBackground @@ -305,7 +306,7 @@ private final class ChatMessageDateContentNode: ASDisplayNode { let graphics = PresentationResourcesChat.principalGraphics(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, bubbleCorners: presentationData.chatBubbleCorners) - let fullTranslucency: Bool = self.controllerInteraction?.enableFullTranslucency ?? true + let fullTranslucency: Bool = true self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: fullTranslucency && dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) self.stickBackgroundNode.image = graphics.dateFloatingBackground @@ -328,7 +329,7 @@ private final class ChatMessageDateContentNode: ASDisplayNode { } func update(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) { - let chatDateSize: CGFloat = 20.0 + let chatDateSize: CGFloat = 22.0 let chatDateInset: CGFloat = 6.0 let labelSize = self.labelNode.bounds.size @@ -366,6 +367,8 @@ private final class ChatMessageDateContentNode: ASDisplayNode { } private final class ChatMessagePeerContentNode: ASDisplayNode { + private static let arrowImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/HeaderArrow"), color: .white)!.withRenderingMode(.alwaysTemplate) + private let context: AccountContext private var presentationData: ChatPresentationData private let controllerInteraction: ChatControllerInteraction? @@ -373,6 +376,7 @@ private final class ChatMessagePeerContentNode: ASDisplayNode { private var avatarNode: AvatarNode? private var icon: ComponentView? + private var arrowIcon: UIImageView? public let labelNode: TextNode public let backgroundNode: NavigationBackgroundNode @@ -417,7 +421,7 @@ private final class ChatMessagePeerContentNode: ASDisplayNode { let graphics = PresentationResourcesChat.principalGraphics(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, bubbleCorners: presentationData.chatBubbleCorners) - let fullTranslucency: Bool = controllerInteraction?.enableFullTranslucency ?? true + let fullTranslucency: Bool = true self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: fullTranslucency && dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) self.stickBackgroundNode.image = graphics.dateFloatingBackground @@ -482,6 +486,10 @@ private final class ChatMessagePeerContentNode: ASDisplayNode { let (size, apply) = labelLayout(TextNodeLayoutArguments(attributedString: attributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 320.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) let _ = apply() self.labelNode.frame = CGRect(origin: CGPoint(), size: size.size) + + let arrowIcon = UIImageView(image: ChatMessagePeerContentNode.arrowImage) + self.arrowIcon = arrowIcon + self.view.addSubview(arrowIcon) } func updatePresentationData(_ presentationData: ChatPresentationData, context: AccountContext) { @@ -490,7 +498,7 @@ private final class ChatMessagePeerContentNode: ASDisplayNode { let graphics = PresentationResourcesChat.principalGraphics(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, bubbleCorners: presentationData.chatBubbleCorners) - let fullTranslucency: Bool = self.controllerInteraction?.enableFullTranslucency ?? true + let fullTranslucency: Bool = true self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: fullTranslucency && dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) self.stickBackgroundNode.image = graphics.dateFloatingBackground @@ -513,8 +521,10 @@ private final class ChatMessagePeerContentNode: ASDisplayNode { } func update(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) { - let chatDateSize: CGFloat = 20.0 + let chatDateSize: CGFloat = 22.0 let chatDateInset: CGFloat = 6.0 + let arrowInset: CGFloat = 5.0 + let arrowSpacing: CGFloat = arrowInset + 6.0 let avatarDiameter: CGFloat = 16.0 let avatarInset: CGFloat @@ -527,7 +537,7 @@ private final class ChatMessagePeerContentNode: ASDisplayNode { let avatarSpacing: CGFloat = 4.0 let labelSize = self.labelNode.bounds.size - let backgroundSize = CGSize(width: avatarInset + avatarDiameter + avatarSpacing + labelSize.width + chatDateInset, height: chatDateSize) + let backgroundSize = CGSize(width: avatarInset + avatarDiameter + avatarSpacing + labelSize.width + chatDateInset + arrowSpacing, height: chatDateSize) let backgroundFrame = CGRect(origin: CGPoint(x: leftInset + floorToScreenPixels((size.width - leftInset - rightInset - backgroundSize.width) / 2.0), y: (size.height - chatDateSize) / 2.0), size: backgroundSize) @@ -548,6 +558,13 @@ private final class ChatMessagePeerContentNode: ASDisplayNode { transition.updatePosition(node: self.labelNode, position: labelFrame.center) self.labelNode.bounds = CGRect(origin: CGPoint(), size: labelFrame.size) + + if let arrowIcon = self.arrowIcon, let image = arrowIcon.image { + arrowIcon.tintColor = bubbleVariableColor(variableColor: presentationData.theme.theme.chat.serviceMessage.dateTextColor, wallpaper: presentationData.theme.wallpaper).withMultipliedAlpha(0.7) + let arrowSize = image.size + let arrowFrame = CGRect(origin: CGPoint(x: backgroundFrame.maxX - arrowInset - arrowSize.width, y: backgroundFrame.minY + floorToScreenPixels((backgroundFrame.height - arrowSize.height) * 0.5)), size: arrowSize) + transition.updateFrame(view: arrowIcon, frame: arrowFrame) + } if let backgroundContent = self.backgroundContent { backgroundContent.allowsGroupOpacity = true diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageItemImpl.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageItemImpl.swift index 83ac51b1f9..770fb2a577 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageItemImpl.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageItemImpl.swift @@ -399,7 +399,10 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible var hasAvatar = false if !hasActionMedia { if !isBroadcastChannel { - hasAvatar = true + if let channel = message.peers[message.id.peerId] as? TelegramChannel, channel.isMonoForum, chatLocation.threadId != nil { + } else { + hasAvatar = true + } } else if let channel = message.peers[message.id.peerId] as? TelegramChannel, case let .broadcast(info) = channel.info { if info.flags.contains(.messagesShouldHaveProfiles) { hasAvatar = true diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageNotificationItem/Sources/ChatMessageNotificationItem.swift b/submodules/TelegramUI/Components/Chat/ChatMessageNotificationItem/Sources/ChatMessageNotificationItem.swift index 386b50a569..5f65b540b3 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageNotificationItem/Sources/ChatMessageNotificationItem.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageNotificationItem/Sources/ChatMessageNotificationItem.swift @@ -139,8 +139,7 @@ final class ChatMessageNotificationItemNode: NotificationItemNode { } if case let .channel(channel) = peer, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = firstMessage.peers[linkedMonoforumId] { - //TODO:localize - title = authorString + "@" + EnginePeer(mainChannel).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder) + " Messages" + title = authorString + "@" + EnginePeer(mainChannel).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder) } else { if let threadData = item.threadData { title = "\(authorString) → \(threadData.info.title)" diff --git a/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/BUILD b/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/BUILD index 0a13c0f284..faaa994060 100644 --- a/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/BUILD @@ -24,6 +24,13 @@ swift_library( "//submodules/TelegramUI/Components/EmojiStatusComponent", "//submodules/Components/BundleIconComponent", "//submodules/AvatarNode", + "//submodules/ChatListUI", + "//submodules/ContextUI", + "//submodules/TelegramUI/Components/AsyncListComponent", + "//submodules/TelegramUI/Components/TextBadgeComponent", + "//submodules/TelegramUI/Components/MaskedContainerComponent", + "//submodules/AppBundle", + "//submodules/PresentationDataUtils", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift b/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift index b5b43da910..a686733ac9 100644 --- a/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift +++ b/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift @@ -14,6 +14,13 @@ import BlurredBackgroundComponent import EmojiStatusComponent import BundleIconComponent import AvatarNode +import ChatListUI +import ContextUI +import AsyncListComponent +import TextBadgeComponent +import MaskedContainerComponent +import AppBundle +import PresentationDataUtils public final class ChatSidePanelEnvironment: Equatable { public let insets: UIEdgeInsets @@ -33,12 +40,19 @@ public final class ChatSidePanelEnvironment: Equatable { public final class ChatSideTopicsPanel: Component { public typealias EnvironmentType = ChatSidePanelEnvironment + public enum Location { + case side + case top + } + let context: AccountContext let theme: PresentationTheme let strings: PresentationStrings + let location: Location let peerId: EnginePeer.Id let isMonoforum: Bool let topicId: Int64? + let controller: () -> ViewController? let togglePanel: () -> Void let updateTopicId: (Int64?, Bool) -> Void @@ -46,18 +60,22 @@ public final class ChatSideTopicsPanel: Component { context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, + location: Location, peerId: EnginePeer.Id, isMonoforum: Bool, topicId: Int64?, + controller: @escaping () -> ViewController?, togglePanel: @escaping () -> Void, updateTopicId: @escaping (Int64?, Bool) -> Void ) { self.context = context self.theme = theme self.strings = strings + self.location = location self.peerId = peerId self.isMonoforum = isMonoforum self.topicId = topicId + self.controller = controller self.togglePanel = togglePanel self.updateTopicId = updateTopicId } @@ -72,6 +90,9 @@ public final class ChatSideTopicsPanel: Component { if lhs.strings !== rhs.strings { return false } + if lhs.location != rhs.location { + return false + } if lhs.peerId != rhs.peerId { return false } @@ -108,223 +129,873 @@ public final class ChatSideTopicsPanel: Component { } } - private final class ItemView: UIView { - private let context: AccountContext - private let action: () -> Void + private protocol ItemComponent: AnyObject { + var item: Item { get } + } + + private final class VerticalItemComponent: Component, ItemComponent { + let context: AccountContext + let item: Item + let isSelected: Bool + let isReordering: Bool + let theme: PresentationTheme + let action: (() -> Void)? + let contextGesture: ((ContextGesture, ContextExtractedContentContainingNode) -> Void)? - private let extractedContainerNode: ContextExtractedContentContainingNode - private let containerNode: ContextControllerSourceNode - - private let containerButton: HighlightTrackingButton - - private var icon: ComponentView? - private var avatarNode: AvatarNode? - private let title = ComponentView() - - init(context: AccountContext, action: @escaping (() -> Void), contextGesture: @escaping (ContextGesture, ContextExtractedContentContainingNode) -> Void) { + init(context: AccountContext, item: Item, isSelected: Bool, isReordering: Bool, theme: PresentationTheme, strings: PresentationStrings, action: (() -> Void)?, contextGesture: ((ContextGesture, ContextExtractedContentContainingNode) -> Void)?) { self.context = context + self.item = item + self.isSelected = isSelected + self.isReordering = isReordering + self.theme = theme self.action = action + self.contextGesture = contextGesture + } + + static func ==(lhs: VerticalItemComponent, rhs: VerticalItemComponent) -> Bool { + if lhs === rhs { + return true + } + if lhs.context !== rhs.context { + return false + } + if lhs.item != rhs.item { + return false + } + if lhs.isSelected != rhs.isSelected { + return false + } + if lhs.isReordering != rhs.isReordering { + return false + } + if lhs.theme !== rhs.theme { + return false + } + if (lhs.action == nil) != (rhs.action == nil) { + return false + } + if (lhs.contextGesture == nil) != (rhs.contextGesture == nil) { + return false + } + return true + } + + final class View: UIView, AsyncListComponent.ItemView { + private let extractedContainerNode: ContextExtractedContentContainingNode + private let containerNode: ContextControllerSourceNode - self.extractedContainerNode = ContextExtractedContentContainingNode() - self.containerNode = ContextControllerSourceNode() + private let containerButton: UIView + private var extractedBackgroundView: UIImageView? - self.containerButton = HighlightTrackingButton() + private var tapRecognizer: UITapGestureRecognizer? - super.init(frame: CGRect()) + private let iconContainer: MaskedContainerView + private var icon: ComponentView? + private var avatarNode: AvatarNode? + private let title = ComponentView() + private var badge: ComponentView? - self.extractedContainerNode.contentNode.view.addSubview(self.containerButton) + private var component: VerticalItemComponent? - self.containerNode.addSubnode(self.extractedContainerNode) - self.containerNode.targetNodeForActivationProgress = self.extractedContainerNode.contentNode - self.addSubview(self.containerNode.view) - - self.containerButton.addTarget(self, action: #selector(self.pressed), for: .touchUpInside) - self.containerButton.highligthedChanged = { [weak self] highlighted in - if let self, self.bounds.width > 0.0 { - let topScale: CGFloat = (self.bounds.width - 1.0) / self.bounds.width - let maxScale: CGFloat = (self.bounds.width + 1.0) / self.bounds.width + override init(frame: CGRect) { + self.extractedContainerNode = ContextExtractedContentContainingNode() + self.containerNode = ContextControllerSourceNode() + + self.iconContainer = MaskedContainerView() + self.iconContainer.isUserInteractionEnabled = false + + self.containerButton = UIView() + + super.init(frame: frame) + + self.extractedContainerNode.contentNode.view.addSubview(self.containerButton) + + self.containerNode.addSubnode(self.extractedContainerNode) + self.containerNode.targetNodeForActivationProgress = self.extractedContainerNode.contentNode + self.addSubview(self.containerNode.view) + + self.containerButton.addSubview(self.iconContainer) + + let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))) + self.tapRecognizer = tapRecognizer + self.containerButton.addGestureRecognizer(tapRecognizer) + tapRecognizer.isEnabled = false + + self.containerNode.activated = { [weak self] gesture, _ in + guard let self, let component = self.component else { + return + } + component.contextGesture?(gesture, self.extractedContainerNode) + } + + self.extractedContainerNode.willUpdateIsExtractedToContextPreview = { [weak self] isExtracted, transition in + guard let self, let component = self.component else { + return + } - if highlighted { - self.layer.removeAnimation(forKey: "opacity") - self.layer.removeAnimation(forKey: "sublayerTransform") - let transition: ContainedViewLayoutTransition = .animated(duration: 0.2, curve: .easeInOut) - transition.updateTransformScale(layer: self.layer, scale: topScale) - } else { - let transition: ContainedViewLayoutTransition = .immediate - transition.updateTransformScale(layer: self.layer, scale: 1.0) - - self.layer.animateScale(from: topScale, to: maxScale, duration: 0.13, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in - guard let self else { - return - } - - self.layer.animateScale(from: maxScale, to: 1.0, duration: 0.1, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue) + if isExtracted { + let extractedBackgroundView: UIImageView + if let current = self.extractedBackgroundView { + extractedBackgroundView = current + } else { + extractedBackgroundView = UIImageView(image: generateStretchableFilledCircleImage(diameter: 28.0, color: component.theme.contextMenu.backgroundColor)) + self.extractedBackgroundView = extractedBackgroundView + self.extractedContainerNode.contentNode.view.insertSubview(extractedBackgroundView, at: 0) + extractedBackgroundView.frame = self.extractedContainerNode.contentNode.bounds.insetBy(dx: 2.0, dy: 0.0) + extractedBackgroundView.alpha = 0.0 + } + transition.updateAlpha(layer: extractedBackgroundView.layer, alpha: 1.0) + } else if let extractedBackgroundView = self.extractedBackgroundView { + self.extractedBackgroundView = nil + let alphaTransition: ContainedViewLayoutTransition + if transition.isAnimated { + alphaTransition = .animated(duration: 0.18, curve: .easeInOut) + } else { + alphaTransition = .immediate + } + alphaTransition.updateAlpha(layer: extractedBackgroundView.layer, alpha: 0.0, completion: { [weak extractedBackgroundView] _ in + extractedBackgroundView?.removeFromSuperview() }) } } + + self.containerNode.isGestureEnabled = false } - self.containerNode.isGestureEnabled = false - } - - required init?(coder: NSCoder) { - preconditionFailure() - } - - @objc private func pressed() { - self.action() - } - - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - var mappedPoint = point - if self.bounds.insetBy(dx: -8.0, dy: -4.0).contains(point) { - mappedPoint = self.bounds.center + required init?(coder: NSCoder) { + preconditionFailure() } - return super.hitTest(mappedPoint, with: event) - } - - func update(context: AccountContext, item: Item, isSelected: Bool, theme: PresentationTheme, width: CGFloat, transition: ComponentTransition) -> CGSize { - let spacing: CGFloat = 3.0 - let iconSize = CGSize(width: 30.0, height: 30.0) - var avatarIconContent: EmojiStatusComponent.Content? - if case let .forum(topicId) = item.item.id { - if topicId != 1, let threadData = item.item.threadData { - if let fileId = threadData.info.icon, fileId != 0 { - avatarIconContent = .animation(content: .customEmoji(fileId: fileId), size: iconSize, placeholderColor: theme.list.mediaPlaceholderColor, themeColor: theme.list.itemAccentColor, loopMode: .count(0)) - } else { - avatarIconContent = .topic(title: String(threadData.info.title.prefix(1)), color: threadData.info.iconColor, size: iconSize) + @objc private func tapGesture(_ recognizer: UITapGestureRecognizer) { + if case .ended = recognizer.state { + if let iconView = self.icon?.view as? EmojiStatusComponent.View { + iconView.playOnce() } - } else { - avatarIconContent = .image(image: PresentationResourcesChatList.generalTopicIcon(theme), tintColor: theme.rootController.navigationBar.secondaryTextColor) + self.component?.action?() } } - if let avatarIconContent { - let avatarIconComponent = EmojiStatusComponent( - context: context, - animationCache: context.animationCache, - animationRenderer: context.animationRenderer, - content: avatarIconContent, - isVisibleForAnimations: false, - action: nil - ) - let icon: ComponentView - if let current = self.icon { - icon = current - } else { - icon = ComponentView() - self.icon = icon + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + var mappedPoint = point + if self.bounds.insetBy(dx: -8.0, dy: -4.0).contains(point) { + mappedPoint = self.bounds.center } - let _ = icon.update( - transition: .immediate, - component: AnyComponent(avatarIconComponent), - environment: {}, - containerSize: iconSize - ) - } else if let icon = self.icon { - self.icon = nil - icon.view?.removeFromSuperview() + return super.hitTest(mappedPoint, with: event) } - let titleText: String - if case let .forum(topicId) = item.item.id { - let _ = topicId - if let threadData = item.item.threadData { - titleText = threadData.info.title - } else { - //TODO:localize - titleText = "General" + func isReorderable(at point: CGPoint) -> Bool { + guard let component = self.component else { + return false } - } else { - titleText = item.item.renderedPeer.chatMainPeer?.compactDisplayTitle ?? " " + return component.isReordering } - if let avatarIconContent, let icon = self.icon { - let avatarIconComponent = EmojiStatusComponent( - context: context, - animationCache: context.animationCache, - animationRenderer: context.animationRenderer, - content: avatarIconContent, - isVisibleForAnimations: false, - action: nil - ) - let _ = icon.update( - transition: .immediate, - component: AnyComponent(avatarIconComponent), - environment: {}, - containerSize: iconSize - ) - } - - let titleSize = self.title.update( - transition: .immediate, - component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: titleText, font: Font.regular(10.0), textColor: isSelected ? theme.rootController.navigationBar.accentTextColor : theme.rootController.navigationBar.secondaryTextColor)), - horizontalAlignment: .center, - maximumNumberOfLines: 2 - )), - environment: {}, - containerSize: CGSize(width: width - 6.0 * 2.0, height: 100.0) - ) - - let contentSize: CGFloat = iconSize.height + spacing + titleSize.height - let size = CGSize(width: width, height: contentSize) - - let iconFrame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) * 0.5), y: 0.0), size: iconSize) - let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) * 0.5), y: iconFrame.maxY + spacing), size: titleSize) - - if let icon = self.icon { - if let avatarNode = self.avatarNode { - self.avatarNode = nil - avatarNode.view.removeFromSuperview() + private func updateIsShaking(animated: Bool) { + guard let component = self.component else { + return } - if let iconView = icon.view { - if iconView.superview == nil { - iconView.isUserInteractionEnabled = false - self.containerButton.addSubview(iconView) + if component.isReordering { + if self.layer.animation(forKey: "shaking_position") == nil { + let degreesToRadians: (_ x: CGFloat) -> CGFloat = { x in + return .pi * x / 180.0 + } + + let duration: Double = 0.4 + let displacement: CGFloat = 1.0 + let degreesRotation: CGFloat = 2.0 + + let negativeDisplacement = -1.0 * displacement + let position = CAKeyframeAnimation.init(keyPath: "position") + position.beginTime = 0.8 + position.duration = duration + position.values = [ + NSValue(cgPoint: CGPoint(x: negativeDisplacement, y: negativeDisplacement)), + NSValue(cgPoint: CGPoint(x: 0, y: 0)), + NSValue(cgPoint: CGPoint(x: negativeDisplacement, y: 0)), + NSValue(cgPoint: CGPoint(x: 0, y: negativeDisplacement)), + NSValue(cgPoint: CGPoint(x: negativeDisplacement, y: negativeDisplacement)) + ] + position.calculationMode = .linear + position.isRemovedOnCompletion = false + position.repeatCount = Float.greatestFiniteMagnitude + position.beginTime = CFTimeInterval(Float(arc4random()).truncatingRemainder(dividingBy: Float(25)) / Float(100)) + position.isAdditive = true + + let transform = CAKeyframeAnimation.init(keyPath: "transform") + transform.beginTime = 2.6 + transform.duration = 0.3 + transform.valueFunction = CAValueFunction(name: CAValueFunctionName.rotateZ) + transform.values = [ + degreesToRadians(-1.0 * degreesRotation), + degreesToRadians(degreesRotation), + degreesToRadians(-1.0 * degreesRotation) + ] + transform.calculationMode = .linear + transform.isRemovedOnCompletion = false + transform.repeatCount = Float.greatestFiniteMagnitude + transform.isAdditive = true + transform.beginTime = CFTimeInterval(Float(arc4random()).truncatingRemainder(dividingBy: Float(25)) / Float(100)) + + self.layer.add(position, forKey: "shaking_position") + self.layer.add(transform, forKey: "shaking_rotation") } - iconView.frame = iconFrame + } else if self.layer.animation(forKey: "shaking_position") != nil { + if let presentationLayer = self.layer.presentation() { + let transition: ComponentTransition = .easeInOut(duration: 0.1) + if presentationLayer.position != self.layer.position { + transition.animatePosition(layer: self.layer, from: CGPoint(x: presentationLayer.position.x - self.layer.position.x, y: presentationLayer.position.y - self.layer.position.y), to: CGPoint(), additive: true) + } + if !CATransform3DIsIdentity(presentationLayer.transform) { + transition.setTransform(layer: self.layer, transform: CATransform3DIdentity) + } + } + + self.layer.removeAnimation(forKey: "shaking_position") + self.layer.removeAnimation(forKey: "shaking_rotation") } - } else { - let avatarNode: AvatarNode - if let current = self.avatarNode { - avatarNode = current - } else { - avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 11.0)) - avatarNode.isUserInteractionEnabled = false - self.avatarNode = avatarNode - self.containerButton.addSubview(avatarNode.view) - } - avatarNode.frame = iconFrame - avatarNode.updateSize(size: iconFrame.size) + } + + func update(component: VerticalItemComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + self.component = component - if let peer = item.item.renderedPeer.chatMainPeer { - if peer.smallProfileImage != nil { - avatarNode.setPeerV2(context: context, theme: theme, peer: peer, overrideImage: nil, emptyColor: .gray, clipStyle: .round, synchronousLoad: false, displayDimensions: iconFrame.size) + self.tapRecognizer?.isEnabled = component.action != nil + + self.containerNode.isGestureEnabled = component.contextGesture != nil + self.containerNode.activated = { [weak self] gesture, _ in + guard let self, let component = self.component else { + return + } + component.contextGesture?(gesture, self.extractedContainerNode) + } + + let topInset: CGFloat = 8.0 + let bottomInset: CGFloat = 8.0 + let spacing: CGFloat = 3.0 + let iconSize = CGSize(width: 30.0, height: 30.0) + + var avatarIconContent: EmojiStatusComponent.Content? + if case let .forum(topicId) = component.item.item.id { + if topicId != 1, let threadData = component.item.item.threadData { + if let fileId = threadData.info.icon, fileId != 0 { + avatarIconContent = .animation(content: .customEmoji(fileId: fileId), size: iconSize, placeholderColor: component.theme.list.mediaPlaceholderColor, themeColor: component.theme.list.itemAccentColor, loopMode: .count(0)) + } else { + avatarIconContent = .topic(title: String(threadData.info.title.prefix(1)), color: threadData.info.iconColor, size: iconSize) + } } else { - avatarNode.setPeer(context: context, theme: theme, peer: peer, overrideImage: nil, emptyColor: .gray, clipStyle: .round, synchronousLoad: false, displayDimensions: iconFrame.size) + avatarIconContent = .image(image: PresentationResourcesChatList.generalTopicIcon(component.theme), tintColor: component.theme.rootController.navigationBar.secondaryTextColor) } } - } - - if let titleView = self.title.view { - if titleView.superview == nil { - titleView.isUserInteractionEnabled = false - self.containerButton.addSubview(titleView) + + if let avatarIconContent { + let avatarIconComponent = EmojiStatusComponent( + context: component.context, + animationCache: component.context.animationCache, + animationRenderer: component.context.animationRenderer, + content: avatarIconContent, + isVisibleForAnimations: true, + action: nil + ) + let icon: ComponentView + if let current = self.icon { + icon = current + } else { + icon = ComponentView() + self.icon = icon + } + let _ = icon.update( + transition: .immediate, + component: AnyComponent(avatarIconComponent), + environment: {}, + containerSize: iconSize + ) + } else if let icon = self.icon { + self.icon = nil + icon.view?.removeFromSuperview() } - titleView.frame = titleFrame + + let titleText: String + if case let .forum(topicId) = component.item.item.id { + let _ = topicId + if let threadData = component.item.item.threadData { + titleText = threadData.info.title + } else { + titleText = " " + } + } else { + titleText = component.item.item.renderedPeer.chatMainPeer?.compactDisplayTitle ?? " " + } + + if let avatarIconContent, let icon = self.icon { + let avatarIconComponent = EmojiStatusComponent( + context: component.context, + animationCache: component.context.animationCache, + animationRenderer: component.context.animationRenderer, + content: avatarIconContent, + isVisibleForAnimations: true, + action: nil + ) + let _ = icon.update( + transition: .immediate, + component: AnyComponent(avatarIconComponent), + environment: {}, + containerSize: iconSize + ) + } + + let titleSize = self.title.update( + transition: .immediate, + component: AnyComponent(MultilineTextComponent( + text: .plain(NSAttributedString(string: titleText, font: Font.regular(10.0), textColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.rootController.navigationBar.secondaryTextColor)), + horizontalAlignment: .center, + maximumNumberOfLines: 2 + )), + environment: {}, + containerSize: CGSize(width: availableSize.width - 6.0 * 2.0, height: 100.0) + ) + + let contentSize: CGFloat = topInset + bottomInset + iconSize.height + spacing + titleSize.height + let size = CGSize(width: availableSize.width, height: contentSize) + + let iconFrame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) * 0.5), y: topInset), size: iconSize) + let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) * 0.5), y: iconFrame.maxY + spacing), size: titleSize) + + self.iconContainer.frame = iconFrame + + if let icon = self.icon { + if let avatarNode = self.avatarNode { + self.avatarNode = nil + avatarNode.view.removeFromSuperview() + } + + if let iconView = icon.view { + if iconView.superview == nil { + iconView.isUserInteractionEnabled = false + self.iconContainer.contentView.addSubview(iconView) + } + iconView.frame = CGRect(origin: CGPoint(), size: iconFrame.size) + } + } else { + let avatarNode: AvatarNode + if let current = self.avatarNode { + avatarNode = current + } else { + avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 11.0)) + avatarNode.isUserInteractionEnabled = false + self.avatarNode = avatarNode + self.iconContainer.contentView.addSubview(avatarNode.view) + } + avatarNode.frame = CGRect(origin: CGPoint(), size: iconFrame.size) + avatarNode.updateSize(size: iconFrame.size) + + if let peer = component.item.item.renderedPeer.chatMainPeer { + if peer.smallProfileImage != nil { + avatarNode.setPeerV2(context: component.context, theme: component.theme, peer: peer, overrideImage: nil, emptyColor: .gray, clipStyle: .round, synchronousLoad: false, displayDimensions: iconFrame.size) + } else { + avatarNode.setPeer(context: component.context, theme: component.theme, peer: peer, overrideImage: nil, emptyColor: .gray, clipStyle: .round, synchronousLoad: false, displayDimensions: iconFrame.size) + } + } + } + + var iconMaskItems: [MaskedContainerView.Item] = [] + if let readCounters = component.item.item.readCounters, readCounters.count > 0 { + let badge: ComponentView + var badgeTransition = transition + if let current = self.badge { + badge = current + } else { + badgeTransition = .immediate + badge = ComponentView() + self.badge = badge + } + + let badgeSize = badge.update( + transition: badgeTransition, + component: AnyComponent(TextBadgeComponent( + text: countString(Int64(readCounters.count)), + font: Font.medium(12.0), + background: component.item.item.isMuted ? component.theme.chatList.unreadBadgeInactiveBackgroundColor : component.theme.chatList.unreadBadgeActiveBackgroundColor, + foreground: component.item.item.isMuted ? component.theme.chatList.unreadBadgeInactiveTextColor : component.theme.chatList.unreadBadgeActiveTextColor, + insets: UIEdgeInsets(top: 1.0, left: 5.0, bottom: 2.0, right: 5.0) + )), + environment: {}, + containerSize: CGSize(width: 100.0, height: 100.0) + ) + let badgeFrame = CGRect(origin: CGPoint(x: iconFrame.maxX + 10.0 - badgeSize.width, y: iconFrame.minY - 6.0), size: badgeSize) + if let badgeView = badge.view { + if badgeView.superview == nil { + self.containerButton.addSubview(badgeView) + } + badgeView.frame = badgeFrame + } + let badgeMaskFrame = badgeFrame.offsetBy(dx: -iconFrame.minX, dy: -iconFrame.minY).insetBy(dx: -1.33, dy: -1.33) + iconMaskItems.append(MaskedContainerView.Item( + frame: badgeMaskFrame, + shape: .roundedRect(cornerRadius: badgeMaskFrame.height * 0.5) + )) + } else if let badge = self.badge { + self.badge = nil + badge.view?.removeFromSuperview() + } + self.iconContainer.update(size: iconFrame.size, items: iconMaskItems, isInverted: true) + self.iconContainer.frame = iconFrame + + if let titleView = self.title.view { + if titleView.superview == nil { + titleView.isUserInteractionEnabled = false + self.containerButton.addSubview(titleView) + } + titleView.frame = titleFrame + } + + transition.setFrame(view: self.containerButton, frame: CGRect(origin: CGPoint(), size: size)) + + self.extractedContainerNode.frame = CGRect(origin: CGPoint(), size: size) + self.extractedContainerNode.contentNode.frame = CGRect(origin: CGPoint(), size: size) + self.extractedContainerNode.contentRect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height)) + self.containerNode.frame = CGRect(origin: CGPoint(), size: size) + + self.updateIsShaking(animated: !transition.animation.isImmediate) + + return size + } + } + + func makeView() -> View { + return View(frame: CGRect()) + } + + func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition) + } + } + + private final class HorizontalItemComponent: Component, ItemComponent { + let context: AccountContext + let item: Item + let isSelected: Bool + let isReordering: Bool + let theme: PresentationTheme + let action: (() -> Void)? + let contextGesture: ((ContextGesture, ContextExtractedContentContainingNode) -> Void)? + + init(context: AccountContext, item: Item, isSelected: Bool, isReordering: Bool, theme: PresentationTheme, strings: PresentationStrings, action: (() -> Void)?, contextGesture: ((ContextGesture, ContextExtractedContentContainingNode) -> Void)?) { + self.context = context + self.item = item + self.isSelected = isSelected + self.isReordering = isReordering + self.theme = theme + self.action = action + self.contextGesture = contextGesture + } + + static func ==(lhs: HorizontalItemComponent, rhs: HorizontalItemComponent) -> Bool { + if lhs === rhs { + return true + } + if lhs.context !== rhs.context { + return false + } + if lhs.item != rhs.item { + return false + } + if lhs.isSelected != rhs.isSelected { + return false + } + if lhs.isReordering != rhs.isReordering { + return false + } + if lhs.theme !== rhs.theme { + return false + } + if (lhs.action == nil) != (rhs.action == nil) { + return false + } + if (lhs.contextGesture == nil) != (rhs.contextGesture == nil) { + return false + } + return true + } + + final class View: UIView, AsyncListComponent.ItemView { + private let extractedContainerNode: ContextExtractedContentContainingNode + private let containerNode: ContextControllerSourceNode + + private let containerButton: UIView + private var extractedBackgroundView: UIImageView? + + private var tapRecognizer: UITapGestureRecognizer? + + private var icon: ComponentView? + private var avatarNode: AvatarNode? + private let title = ComponentView() + private var badge: ComponentView? + + private var component: HorizontalItemComponent? + + override init(frame: CGRect) { + self.extractedContainerNode = ContextExtractedContentContainingNode() + self.containerNode = ContextControllerSourceNode() + + self.containerButton = UIView() + + super.init(frame: frame) + + self.extractedContainerNode.contentNode.view.addSubview(self.containerButton) + + self.containerNode.addSubnode(self.extractedContainerNode) + self.containerNode.targetNodeForActivationProgress = self.extractedContainerNode.contentNode + self.addSubview(self.containerNode.view) + + let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))) + self.tapRecognizer = tapRecognizer + self.containerButton.addGestureRecognizer(tapRecognizer) + tapRecognizer.isEnabled = false + + self.containerNode.activated = { [weak self] gesture, _ in + guard let self, let component = self.component else { + return + } + component.contextGesture?(gesture, self.extractedContainerNode) + } + + self.extractedContainerNode.willUpdateIsExtractedToContextPreview = { [weak self] isExtracted, transition in + guard let self, let component = self.component else { + return + } + + if isExtracted { + let extractedBackgroundView: UIImageView + if let current = self.extractedBackgroundView { + extractedBackgroundView = current + } else { + extractedBackgroundView = UIImageView(image: generateStretchableFilledCircleImage(diameter: 28.0, color: component.theme.contextMenu.backgroundColor)) + self.extractedBackgroundView = extractedBackgroundView + self.extractedContainerNode.contentNode.view.insertSubview(extractedBackgroundView, at: 0) + extractedBackgroundView.frame = self.extractedContainerNode.contentNode.bounds.insetBy(dx: 2.0, dy: 0.0) + extractedBackgroundView.alpha = 0.0 + } + transition.updateAlpha(layer: extractedBackgroundView.layer, alpha: 1.0) + } else if let extractedBackgroundView = self.extractedBackgroundView { + self.extractedBackgroundView = nil + let alphaTransition: ContainedViewLayoutTransition + if transition.isAnimated { + alphaTransition = .animated(duration: 0.18, curve: .easeInOut) + } else { + alphaTransition = .immediate + } + alphaTransition.updateAlpha(layer: extractedBackgroundView.layer, alpha: 0.0, completion: { [weak extractedBackgroundView] _ in + extractedBackgroundView?.removeFromSuperview() + }) + } + } + + self.containerNode.isGestureEnabled = false } - transition.setFrame(view: self.containerButton, frame: CGRect(origin: CGPoint(), size: size)) + required init?(coder: NSCoder) { + preconditionFailure() + } - self.extractedContainerNode.frame = CGRect(origin: CGPoint(), size: size) - self.extractedContainerNode.contentNode.frame = CGRect(origin: CGPoint(), size: size) - self.extractedContainerNode.contentRect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height)) - self.containerNode.frame = CGRect(origin: CGPoint(), size: size) + @objc private func tapGesture(_ recognizer: UITapGestureRecognizer) { + if case .ended = recognizer.state { + if let iconView = self.icon?.view as? EmojiStatusComponent.View { + iconView.playOnce() + } + self.component?.action?() + } + } - return size + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + var mappedPoint = point + if self.bounds.insetBy(dx: -8.0, dy: -4.0).contains(point) { + mappedPoint = self.bounds.center + } + return super.hitTest(mappedPoint, with: event) + } + + func isReorderable(at point: CGPoint) -> Bool { + guard let component = self.component else { + return false + } + return component.isReordering + } + + private func updateIsShaking(animated: Bool) { + guard let component = self.component else { + return + } + + if component.isReordering { + if self.layer.animation(forKey: "shaking_position") == nil { + let degreesToRadians: (_ x: CGFloat) -> CGFloat = { x in + return .pi * x / 180.0 + } + + let duration: Double = 0.4 + let displacement: CGFloat = 1.0 + let degreesRotation: CGFloat = 2.0 + + let negativeDisplacement = -1.0 * displacement + let position = CAKeyframeAnimation.init(keyPath: "position") + position.beginTime = 0.8 + position.duration = duration + position.values = [ + NSValue(cgPoint: CGPoint(x: negativeDisplacement, y: negativeDisplacement)), + NSValue(cgPoint: CGPoint(x: 0, y: 0)), + NSValue(cgPoint: CGPoint(x: negativeDisplacement, y: 0)), + NSValue(cgPoint: CGPoint(x: 0, y: negativeDisplacement)), + NSValue(cgPoint: CGPoint(x: negativeDisplacement, y: negativeDisplacement)) + ] + position.calculationMode = .linear + position.isRemovedOnCompletion = false + position.repeatCount = Float.greatestFiniteMagnitude + position.beginTime = CFTimeInterval(Float(arc4random()).truncatingRemainder(dividingBy: Float(25)) / Float(100)) + position.isAdditive = true + + let transform = CAKeyframeAnimation.init(keyPath: "transform") + transform.beginTime = 2.6 + transform.duration = 0.3 + transform.valueFunction = CAValueFunction(name: CAValueFunctionName.rotateZ) + transform.values = [ + degreesToRadians(-1.0 * degreesRotation), + degreesToRadians(degreesRotation), + degreesToRadians(-1.0 * degreesRotation) + ] + transform.calculationMode = .linear + transform.isRemovedOnCompletion = false + transform.repeatCount = Float.greatestFiniteMagnitude + transform.isAdditive = true + transform.beginTime = CFTimeInterval(Float(arc4random()).truncatingRemainder(dividingBy: Float(25)) / Float(100)) + + self.layer.add(position, forKey: "shaking_position") + self.layer.add(transform, forKey: "shaking_rotation") + } + } else if self.layer.animation(forKey: "shaking_position") != nil { + if let presentationLayer = self.layer.presentation() { + let transition: ComponentTransition = .easeInOut(duration: 0.1) + if presentationLayer.position != self.layer.position { + transition.animatePosition(layer: self.layer, from: CGPoint(x: presentationLayer.position.x - self.layer.position.x, y: presentationLayer.position.y - self.layer.position.y), to: CGPoint(), additive: true) + } + if !CATransform3DIsIdentity(presentationLayer.transform) { + transition.setTransform(layer: self.layer, transform: CATransform3DIdentity) + } + } + + self.layer.removeAnimation(forKey: "shaking_position") + self.layer.removeAnimation(forKey: "shaking_rotation") + } + } + + func update(component: HorizontalItemComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + self.component = component + + self.tapRecognizer?.isEnabled = component.action != nil + + self.containerNode.isGestureEnabled = component.contextGesture != nil + self.containerNode.activated = { [weak self] gesture, _ in + guard let self, let component = self.component else { + return + } + component.contextGesture?(gesture, self.extractedContainerNode) + } + + let leftInset: CGFloat = 12.0 + let rightInset: CGFloat = 12.0 + let spacing: CGFloat = 4.0 + let badgeSpacing: CGFloat = 4.0 + let iconSize = CGSize(width: 18.0, height: 18.0) + + var avatarIconContent: EmojiStatusComponent.Content? + if case let .forum(topicId) = component.item.item.id { + if topicId != 1, let threadData = component.item.item.threadData { + if let fileId = threadData.info.icon, fileId != 0 { + avatarIconContent = .animation(content: .customEmoji(fileId: fileId), size: iconSize, placeholderColor: component.theme.list.mediaPlaceholderColor, themeColor: component.theme.list.itemAccentColor, loopMode: .count(0)) + } else { + avatarIconContent = .topic(title: String(threadData.info.title.prefix(1)), color: threadData.info.iconColor, size: iconSize) + } + } else { + avatarIconContent = .image(image: PresentationResourcesChatList.generalTopicIcon(component.theme), tintColor: component.theme.rootController.navigationBar.secondaryTextColor) + } + } + + if let avatarIconContent { + let avatarIconComponent = EmojiStatusComponent( + context: component.context, + animationCache: component.context.animationCache, + animationRenderer: component.context.animationRenderer, + content: avatarIconContent, + isVisibleForAnimations: false, + action: nil + ) + let icon: ComponentView + if let current = self.icon { + icon = current + } else { + icon = ComponentView() + self.icon = icon + } + let _ = icon.update( + transition: .immediate, + component: AnyComponent(avatarIconComponent), + environment: {}, + containerSize: iconSize + ) + } else if let icon = self.icon { + self.icon = nil + icon.view?.removeFromSuperview() + } + + let titleText: String + if case let .forum(topicId) = component.item.item.id { + let _ = topicId + if let threadData = component.item.item.threadData { + titleText = threadData.info.title + } else { + titleText = " " + } + } else { + titleText = component.item.item.renderedPeer.chatMainPeer?.compactDisplayTitle ?? " " + } + + if let avatarIconContent, let icon = self.icon { + let avatarIconComponent = EmojiStatusComponent( + context: component.context, + animationCache: component.context.animationCache, + animationRenderer: component.context.animationRenderer, + content: avatarIconContent, + isVisibleForAnimations: false, + action: nil + ) + let _ = icon.update( + transition: .immediate, + component: AnyComponent(avatarIconComponent), + environment: {}, + containerSize: iconSize + ) + } + + let titleSize = self.title.update( + transition: .immediate, + component: AnyComponent(MultilineTextComponent( + text: .plain(NSAttributedString(string: titleText, font: Font.medium(14.0), textColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.rootController.navigationBar.secondaryTextColor)), + horizontalAlignment: .center, + maximumNumberOfLines: 2 + )), + environment: {}, + containerSize: CGSize(width: availableSize.width - 6.0 * 2.0, height: 100.0) + ) + + var badgeSize: CGSize? + if let readCounters = component.item.item.readCounters, readCounters.count > 0 { + let badge: ComponentView + var badgeTransition = transition + if let current = self.badge { + badge = current + } else { + badgeTransition = .immediate + badge = ComponentView() + self.badge = badge + } + + badgeSize = badge.update( + transition: badgeTransition, + component: AnyComponent(TextBadgeComponent( + text: countString(Int64(readCounters.count)), + font: Font.medium(12.0), + background: component.item.item.isMuted ? component.theme.chatList.unreadBadgeInactiveBackgroundColor : component.theme.chatList.unreadBadgeActiveBackgroundColor, + foreground: component.item.item.isMuted ? component.theme.chatList.unreadBadgeInactiveTextColor : component.theme.chatList.unreadBadgeActiveTextColor, + insets: UIEdgeInsets(top: 1.0, left: 5.0, bottom: 2.0, right: 5.0) + )), + environment: {}, + containerSize: CGSize(width: 100.0, height: 100.0) + ) + } else if let badge = self.badge { + self.badge = nil + badge.view?.removeFromSuperview() + } + + var contentSize: CGFloat = leftInset + rightInset + iconSize.width + spacing + titleSize.width + if let badgeSize { + contentSize += badgeSize.width + badgeSpacing + } + let size = CGSize(width: contentSize, height: availableSize.height) + + let iconFrame = CGRect(origin: CGPoint(x: leftInset, y: floor((size.height - iconSize.height) * 0.5)), size: iconSize) + let titleFrame = CGRect(origin: CGPoint(x: iconFrame.maxX + spacing, y: floor((size.height - titleSize.height) * 0.5)), size: titleSize) + + if let icon = self.icon { + if let avatarNode = self.avatarNode { + self.avatarNode = nil + avatarNode.view.removeFromSuperview() + } + + if let iconView = icon.view { + if iconView.superview == nil { + iconView.isUserInteractionEnabled = false + self.containerButton.addSubview(iconView) + } + iconView.frame = iconFrame + } + } else { + let avatarNode: AvatarNode + if let current = self.avatarNode { + avatarNode = current + } else { + avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 11.0)) + avatarNode.isUserInteractionEnabled = false + self.avatarNode = avatarNode + self.containerButton.addSubview(avatarNode.view) + } + avatarNode.frame = iconFrame + avatarNode.updateSize(size: iconFrame.size) + + if let peer = component.item.item.renderedPeer.chatMainPeer { + if peer.smallProfileImage != nil { + avatarNode.setPeerV2(context: component.context, theme: component.theme, peer: peer, overrideImage: nil, emptyColor: .gray, clipStyle: .round, synchronousLoad: false, displayDimensions: iconFrame.size) + } else { + avatarNode.setPeer(context: component.context, theme: component.theme, peer: peer, overrideImage: nil, emptyColor: .gray, clipStyle: .round, synchronousLoad: false, displayDimensions: iconFrame.size) + } + } + } + + if let titleView = self.title.view { + if titleView.superview == nil { + titleView.isUserInteractionEnabled = false + self.containerButton.addSubview(titleView) + } + titleView.frame = titleFrame + } + + if let badge = self.badge, let badgeSize { + let badgeFrame = CGRect(origin: CGPoint(x: titleFrame.maxX + badgeSpacing, y: floor((size.height - badgeSize.height) * 0.5)), size: badgeSize) + if let badgeView = badge.view { + if badgeView.superview == nil { + self.containerButton.addSubview(badgeView) + } + badgeView.frame = badgeFrame + } + } + + transition.setFrame(view: self.containerButton, frame: CGRect(origin: CGPoint(), size: size)) + + self.extractedContainerNode.frame = CGRect(origin: CGPoint(), size: size) + self.extractedContainerNode.contentNode.frame = CGRect(origin: CGPoint(), size: size) + self.extractedContainerNode.contentRect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height)) + self.containerNode.frame = CGRect(origin: CGPoint(), size: size) + + self.updateIsShaking(animated: !transition.animation.isImmediate) + + return size + } + } + + func makeView() -> View { + return View(frame: CGRect()) + } + + func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition) } } @@ -337,7 +1008,9 @@ public final class ChatSideTopicsPanel: Component { private let containerButton: HighlightTrackingButton - private let icon = ComponentView() + private var icon = ComponentView() + + private var isReordering: Bool = false init(context: AccountContext, action: @escaping (() -> Void)) { self.context = context @@ -394,20 +1067,31 @@ public final class ChatSideTopicsPanel: Component { } override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - var mappedPoint = point - if self.bounds.insetBy(dx: -8.0, dy: -4.0).contains(point) { - mappedPoint = self.bounds.center - } - return super.hitTest(mappedPoint, with: event) + return super.hitTest(point, with: event) } - func update(context: AccountContext, theme: PresentationTheme, width: CGFloat, transition: ComponentTransition) -> CGSize { + func update(context: AccountContext, theme: PresentationTheme, width: CGFloat, location: Location, isReordering: Bool, transition: ComponentTransition) -> CGSize { + let alphaTransition: ComponentTransition = transition.animation.isImmediate ? .immediate : .easeInOut(duration: 0.2) + + var animateIconIn = false + if self.isReordering != isReordering { + self.isReordering = isReordering + if let iconView = self.icon.view { + self.icon = ComponentView() + transition.setScale(view: iconView, scale: 0.001) + alphaTransition.setAlpha(view: iconView, alpha: 0.0, completion: { [weak iconView] _ in + iconView?.removeFromSuperview() + }) + animateIconIn = true + } + } + let iconSize = self.icon.update( transition: .immediate, component: AnyComponent(BundleIconComponent( - name: "Chat/Title Panels/SidebarIcon", - tintColor: theme.rootController.navigationBar.accentTextColor, - maxSize: nil, + name: isReordering ? "Media Editor/Done" : "Chat/Title Panels/SidebarIcon", + tintColor: location == .side ? theme.rootController.navigationBar.accentTextColor : theme.rootController.navigationBar.secondaryTextColor, + maxSize: CGSize(width: 24.0, height: 24.0), scaleFactor: 1.0 )), environment: {}, @@ -415,7 +1099,7 @@ public final class ChatSideTopicsPanel: Component { ) let topInset: CGFloat = 10.0 - let bottomInset: CGFloat = 12.0 + let bottomInset: CGFloat = 2.0 let contentSize: CGFloat = topInset + iconSize.height + bottomInset let size = CGSize(width: width, height: contentSize) @@ -428,6 +1112,10 @@ public final class ChatSideTopicsPanel: Component { self.containerButton.addSubview(iconView) } iconView.frame = iconFrame + if animateIconIn { + alphaTransition.animateAlpha(view: iconView, from: 0.0, to: 1.0) + transition.animateScale(view: iconView, from: 0.001, to: 1.0) + } } transition.setFrame(view: self.containerButton, frame: CGRect(origin: CGPoint(), size: size)) @@ -441,206 +1129,328 @@ public final class ChatSideTopicsPanel: Component { } } - private final class AllItemView: UIView { - private let context: AccountContext - private let action: () -> Void + private protocol AllItemComponent: AnyObject { + } + + private final class VerticalAllItemComponent: Component, AllItemComponent { + let isSelected: Bool + let theme: PresentationTheme + let strings: PresentationStrings + let action: (() -> Void)? - private let extractedContainerNode: ContextExtractedContentContainingNode - private let containerNode: ContextControllerSourceNode - - private let containerButton: HighlightTrackingButton - - private let icon = ComponentView() - private let title = ComponentView() - - init(context: AccountContext, action: @escaping (() -> Void)) { - self.context = context + init(isSelected: Bool, theme: PresentationTheme, strings: PresentationStrings, action: (() -> Void)?) { + self.isSelected = isSelected + self.theme = theme + self.strings = strings self.action = action - - self.extractedContainerNode = ContextExtractedContentContainingNode() - self.containerNode = ContextControllerSourceNode() - - self.containerButton = HighlightTrackingButton() - - super.init(frame: CGRect()) - - self.extractedContainerNode.contentNode.view.addSubview(self.containerButton) - - self.containerNode.addSubnode(self.extractedContainerNode) - self.containerNode.targetNodeForActivationProgress = self.extractedContainerNode.contentNode - self.addSubview(self.containerNode.view) - - self.containerButton.addTarget(self, action: #selector(self.pressed), for: .touchUpInside) - self.containerButton.highligthedChanged = { [weak self] highlighted in - if let self, self.bounds.width > 0.0 { - let topScale: CGFloat = (self.bounds.width - 1.0) / self.bounds.width - let maxScale: CGFloat = (self.bounds.width + 1.0) / self.bounds.width - - if highlighted { - self.layer.removeAnimation(forKey: "opacity") - self.layer.removeAnimation(forKey: "sublayerTransform") - let transition: ContainedViewLayoutTransition = .animated(duration: 0.2, curve: .easeInOut) - transition.updateTransformScale(layer: self.layer, scale: topScale) - } else { - let transition: ContainedViewLayoutTransition = .immediate - transition.updateTransformScale(layer: self.layer, scale: 1.0) - - self.layer.animateScale(from: topScale, to: maxScale, duration: 0.13, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in - guard let self else { - return - } - - self.layer.animateScale(from: maxScale, to: 1.0, duration: 0.1, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue) - }) - } - } + } + + static func ==(lhs: VerticalAllItemComponent, rhs: VerticalAllItemComponent) -> Bool { + if lhs === rhs { + return true } - - self.containerNode.isGestureEnabled = false - } - - required init?(coder: NSCoder) { - preconditionFailure() - } - - @objc private func pressed() { - self.action() - } - - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - var mappedPoint = point - if self.bounds.insetBy(dx: -8.0, dy: -4.0).contains(point) { - mappedPoint = self.bounds.center + if lhs.isSelected != rhs.isSelected { + return false } - return super.hitTest(mappedPoint, with: event) - } - - func update(context: AccountContext, isSelected: Bool, theme: PresentationTheme, width: CGFloat, transition: ComponentTransition) -> CGSize { - let spacing: CGFloat = 3.0 - - let iconSize = self.icon.update( - transition: .immediate, - component: AnyComponent(BundleIconComponent( - name: "Chat List/Tabs/IconChats", - tintColor: isSelected ? theme.rootController.navigationBar.accentTextColor : theme.rootController.navigationBar.secondaryTextColor - )), - environment: {}, - containerSize: CGSize(width: 100.0, height: 100.0) - ) - - //TODO:localize - let titleText: String = "All" - let titleSize = self.title.update( - transition: .immediate, - component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: titleText, font: Font.regular(10.0), textColor: isSelected ? theme.rootController.navigationBar.accentTextColor : theme.rootController.navigationBar.secondaryTextColor)), - maximumNumberOfLines: 2 - )), - environment: {}, - containerSize: CGSize(width: width - 4.0 * 2.0, height: 100.0) - ) - - let contentSize: CGFloat = iconSize.height + spacing + titleSize.height - let size = CGSize(width: width, height: contentSize) - - let iconFrame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) * 0.5), y: 0.0), size: iconSize) - let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) * 0.5), y: iconFrame.maxY + spacing), size: titleSize) - - if let iconView = self.icon.view { - if iconView.superview == nil { - iconView.isUserInteractionEnabled = false - self.containerButton.addSubview(iconView) - } - iconView.frame = iconFrame + if lhs.theme !== rhs.theme { + return false } - - if let titleView = self.title.view { - if titleView.superview == nil { - titleView.isUserInteractionEnabled = false - self.containerButton.addSubview(titleView) - } - titleView.frame = titleFrame + if lhs.strings !== rhs.strings { + return false + } + if (lhs.action == nil) != (rhs.action == nil) { + return false } - - transition.setFrame(view: self.containerButton, frame: CGRect(origin: CGPoint(), size: size)) - - self.extractedContainerNode.frame = CGRect(origin: CGPoint(), size: size) - self.extractedContainerNode.contentNode.frame = CGRect(origin: CGPoint(), size: size) - self.extractedContainerNode.contentRect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height)) - self.containerNode.frame = CGRect(origin: CGPoint(), size: size) - - return size - } - } - - private final class ScrollView: UIScrollView { - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - return super.hitTest(point, with: event) - } - - override func touchesShouldCancel(in view: UIView) -> Bool { return true } + + final class View: UIView { + private let containerButton: UIView + + private let icon = ComponentView() + private let title = ComponentView() + + private var tapRecognizer: UITapGestureRecognizer? + + private var component: VerticalAllItemComponent? + + override init(frame: CGRect) { + self.containerButton = UIView() + + super.init(frame: frame) + + self.addSubview(self.containerButton) + let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))) + self.tapRecognizer = tapRecognizer + self.containerButton.addGestureRecognizer(tapRecognizer) + tapRecognizer.isEnabled = false + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc private func tapGesture(_ recognizer: UITapGestureRecognizer) { + if case .ended = recognizer.state { + self.component?.action?() + } + } + + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + var mappedPoint = point + if self.bounds.insetBy(dx: -8.0, dy: -4.0).contains(point) { + mappedPoint = self.bounds.center + } + return super.hitTest(mappedPoint, with: event) + } + + func update(component: VerticalAllItemComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + self.component = component + + self.tapRecognizer?.isEnabled = component.action != nil + + let topInset: CGFloat = 6.0 + let bottomInset: CGFloat = 8.0 + + let spacing: CGFloat = 1.0 + + let iconSize = self.icon.update( + transition: .immediate, + component: AnyComponent(BundleIconComponent( + name: "Chat List/Tabs/IconChats", + tintColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.rootController.navigationBar.secondaryTextColor + )), + environment: {}, + containerSize: CGSize(width: 100.0, height: 100.0) + ) + + let titleText: String = component.strings.Chat_InlineTopicMenu_AllTab + let titleSize = self.title.update( + transition: .immediate, + component: AnyComponent(MultilineTextComponent( + text: .plain(NSAttributedString(string: titleText, font: Font.regular(10.0), textColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.rootController.navigationBar.secondaryTextColor)), + maximumNumberOfLines: 2 + )), + environment: {}, + containerSize: CGSize(width: availableSize.width - 4.0 * 2.0, height: 100.0) + ) + + let contentSize: CGFloat = topInset + bottomInset + iconSize.height + spacing + titleSize.height + let size = CGSize(width: availableSize.width, height: contentSize) + + let iconFrame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) * 0.5), y: topInset), size: iconSize) + let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) * 0.5), y: iconFrame.maxY + spacing), size: titleSize) + + if let iconView = self.icon.view { + if iconView.superview == nil { + iconView.isUserInteractionEnabled = false + self.containerButton.addSubview(iconView) + } + iconView.frame = iconFrame + } + + if let titleView = self.title.view { + if titleView.superview == nil { + titleView.isUserInteractionEnabled = false + self.containerButton.addSubview(titleView) + } + titleView.frame = titleFrame + } + + transition.setFrame(view: self.containerButton, frame: CGRect(origin: CGPoint(), size: size)) + + return size + } + } + + func makeView() -> View { + return View(frame: CGRect()) + } + + func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition) + } } - private enum ScrollId: Equatable { + private final class HorizontalAllItemComponent: Component, AllItemComponent { + let isSelected: Bool + let theme: PresentationTheme + let strings: PresentationStrings + let action: (() -> Void)? + + init(isSelected: Bool, theme: PresentationTheme, strings: PresentationStrings, action: (() -> Void)?) { + self.isSelected = isSelected + self.theme = theme + self.strings = strings + self.action = action + } + + static func ==(lhs: HorizontalAllItemComponent, rhs: HorizontalAllItemComponent) -> Bool { + if lhs === rhs { + return true + } + if lhs.isSelected != rhs.isSelected { + return false + } + if lhs.theme !== rhs.theme { + return false + } + if lhs.strings !== rhs.strings { + return false + } + if (lhs.action == nil) != (rhs.action == nil) { + return false + } + return true + } + + final class View: UIView { + private let containerButton: UIView + + private let title = ComponentView() + + private var tapRecognizer: UITapGestureRecognizer? + + private var component: HorizontalAllItemComponent? + + override init(frame: CGRect) { + self.containerButton = UIView() + + super.init(frame: frame) + + self.addSubview(self.containerButton) + let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))) + self.tapRecognizer = tapRecognizer + self.containerButton.addGestureRecognizer(tapRecognizer) + tapRecognizer.isEnabled = false + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc private func tapGesture(_ recognizer: UITapGestureRecognizer) { + if case .ended = recognizer.state { + self.component?.action?() + } + } + + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + var mappedPoint = point + if self.bounds.insetBy(dx: -8.0, dy: -4.0).contains(point) { + mappedPoint = self.bounds.center + } + return super.hitTest(mappedPoint, with: event) + } + + func update(component: HorizontalAllItemComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + self.component = component + + self.tapRecognizer?.isEnabled = component.action != nil + + let leftInset: CGFloat = 6.0 + let rightInset: CGFloat = 12.0 + + let titleText: String = component.strings.Chat_InlineTopicMenu_AllTab + let titleSize = self.title.update( + transition: .immediate, + component: AnyComponent(MultilineTextComponent( + text: .plain(NSAttributedString(string: titleText, font: Font.medium(14.0), textColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.rootController.navigationBar.secondaryTextColor)), + maximumNumberOfLines: 2 + )), + environment: {}, + containerSize: CGSize(width: 200.0, height: 200.0) + ) + + let contentSize: CGFloat = leftInset + rightInset + titleSize.height + let size = CGSize(width: contentSize, height: availableSize.height) + + let titleFrame = CGRect(origin: CGPoint(x: leftInset, y: floor((size.height - titleSize.height) * 0.5)), size: titleSize) + + if let titleView = self.title.view { + if titleView.superview == nil { + titleView.isUserInteractionEnabled = false + self.containerButton.addSubview(titleView) + } + titleView.frame = titleFrame + } + + transition.setFrame(view: self.containerButton, frame: CGRect(origin: CGPoint(), size: size)) + + return size + } + } + + func makeView() -> View { + return View(frame: CGRect()) + } + + func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition) + } + } + + private enum ScrollId: Hashable { case all case topic(Int64) } public final class View: UIView { - private let scrollView: ScrollView + private let list = ComponentView() + private let listState = AsyncListComponent.ExternalState() private let scrollContainerView: UIView private let scrollViewMask: UIImageView - private let background = ComponentView() - private let separatorLayer: SimpleLayer + private var background: ComponentView? + private var separatorLayer: SimpleLayer? + + private let selectedLineContainer: AsyncListComponent.OverlayContainerView private let selectedLineView: UIImageView + private let pinnedBackgroundContainer: AsyncListComponent.OverlayContainerView + private let pinnedBackgroundView: UIImageView + private let pinnedIconView: UIImageView - private var items: [Item] = [] - private var itemViews: [Item.Id: ItemView] = [:] - private var allItemView: AllItemView? private var tabItemView: TabItemView? + private var rawItems: [Item] = [] + private var reorderingItems: [Item]? + private var resetReorderingOnNextUpdate: Bool = false + private var itemsContentVersion: Int = 0 + + private var isTogglingPinnedItem: Bool = false + private weak var dismissContextControllerOnNextUpdate: ContextController? + private var component: ChatSideTopicsPanel? private weak var state: EmptyComponentState? private var isUpdating: Bool = false private var appliedScrollToId: ScrollId? + private var isReordering: Bool = false private var itemsDisposable: Disposable? override public init(frame: CGRect) { self.selectedLineView = UIImageView() - self.scrollView = ScrollView(frame: CGRect()) + self.selectedLineView.isHidden = true + self.selectedLineContainer = AsyncListComponent.OverlayContainerView() + self.selectedLineContainer.addSubview(self.selectedLineView) + + self.pinnedIconView = UIImageView() + self.pinnedBackgroundView = UIImageView() + self.pinnedBackgroundContainer = AsyncListComponent.OverlayContainerView() + self.pinnedBackgroundContainer.addSubview(self.pinnedIconView) + self.pinnedBackgroundContainer.addSubview(self.pinnedBackgroundView) + self.pinnedBackgroundContainer.isHidden = true self.scrollContainerView = UIView() - self.scrollViewMask = UIImageView(image: generateGradientImage(size: CGSize(width: 8.0, height: 8.0), colors: [ - UIColor(white: 1.0, alpha: 0.0), - UIColor(white: 1.0, alpha: 1.0) - ], locations: [0.0, 1.0], direction: .vertical)?.stretchableImage(withLeftCapWidth: 0, topCapHeight: 8)) + self.scrollViewMask = UIImageView() self.scrollContainerView.mask = self.scrollViewMask - self.separatorLayer = SimpleLayer() - super.init(frame: frame) - self.scrollView.delaysContentTouches = false - self.scrollView.canCancelContentTouches = true - self.scrollView.clipsToBounds = true - self.scrollView.contentInsetAdjustmentBehavior = .never - if #available(iOS 13.0, *) { - self.scrollView.automaticallyAdjustsScrollIndicatorInsets = false - } - self.scrollView.showsVerticalScrollIndicator = false - self.scrollView.showsHorizontalScrollIndicator = false - self.scrollView.alwaysBounceHorizontal = false - self.scrollView.alwaysBounceVertical = false - self.scrollView.scrollsToTop = false - self.addSubview(self.scrollContainerView) - self.scrollContainerView.addSubview(self.scrollView) - self.scrollView.addSubview(self.selectedLineView) + self.scrollContainerView.addSubview(self.pinnedBackgroundContainer) + self.scrollContainerView.addSubview(self.selectedLineContainer) } required public init?(coder: NSCoder) { @@ -652,14 +1462,22 @@ public final class ChatSideTopicsPanel: Component { } public func updateGlobalOffset(globalOffset: CGFloat, transition: ComponentTransition) { + guard let component = self.component else { + return + } if let tabItemView = self.tabItemView { - transition.setTransform(view: tabItemView, transform: CATransform3DMakeTranslation(-globalOffset, 0.0, 0.0)) + switch component.location { + case .side: + transition.setTransform(view: tabItemView, transform: CATransform3DMakeTranslation(-globalOffset, 0.0, 0.0)) + case .top: + transition.setTransform(view: tabItemView, transform: CATransform3DMakeTranslation(0.0, -globalOffset, 0.0)) + } } } public func topicIndex(threadId: Int64?) -> Int? { if let threadId { - if let value = self.items.firstIndex(where: { item in + if let value = self.rawItems.firstIndex(where: { item in if item.id == .chatList(PeerId(threadId)) { return true } else if item.id == .forum(threadId) { @@ -677,6 +1495,139 @@ public final class ChatSideTopicsPanel: Component { } } + private func updateListOverlays(visibleItems: AsyncListComponent.VisibleItems, transition: ComponentTransition) { + guard let component = self.component, let listView = self.list.view else { + return + } + + var selectedItemFrame: CGRect? + var beforePinnedItemsPosition: CGFloat? + var afterPinnedItemsPosition: CGFloat? + var seenPinnedItems = false + for item in visibleItems { + if let _ = item.item.component.wrapped as? AllItemComponent { + if component.topicId == nil { + switch component.location { + case .side: + selectedItemFrame = item.frame + case .top: + selectedItemFrame = CGRect(origin: CGPoint(x: item.frame.minX + 5.0, y: item.frame.minY), size: CGSize(width: item.frame.width - 4.0 - 11.0, height: item.frame.height)) + } + } + if !seenPinnedItems { + switch component.location { + case .side: + beforePinnedItemsPosition = item.frame.maxY + case .top: + beforePinnedItemsPosition = item.frame.maxX + } + } + } else if let itemComponent = item.item.component.wrapped as? ItemComponent { + let topicId: Int64 + switch itemComponent.item.item.id { + case let .chatList(peerId): + topicId = peerId.toInt64() + case let .forum(topicIdValue): + topicId = topicIdValue + } + if topicId == component.topicId { + selectedItemFrame = item.frame + } + + var isPinned = false + if case let .forum(pinnedIndex, _, _, _, _) = itemComponent.item.item.index { + if case .index = pinnedIndex { + isPinned = true + } + } + if isPinned { + seenPinnedItems = true + } else { + if !seenPinnedItems { + switch component.location { + case .side: + beforePinnedItemsPosition = item.frame.maxY + case .top: + beforePinnedItemsPosition = item.frame.maxX + } + } else { + if afterPinnedItemsPosition == nil { + switch component.location { + case .side: + afterPinnedItemsPosition = item.frame.minY + case .top: + afterPinnedItemsPosition = item.frame.minX + } + } + } + } + } + } + + if seenPinnedItems { + if beforePinnedItemsPosition == nil { + beforePinnedItemsPosition = -500.0 + } + if afterPinnedItemsPosition == nil { + switch component.location { + case .side: + afterPinnedItemsPosition = listView.bounds.height + 500.0 + case .top: + afterPinnedItemsPosition = listView.bounds.width + 500.0 + } + } + } + + if let selectedItemFrame { + var lineTransition = transition + if self.selectedLineView.isHidden { + self.selectedLineView.isHidden = false + lineTransition = .immediate + } + let selectedLineFrame: CGRect + switch component.location { + case .side: + selectedLineFrame = CGRect(origin: CGPoint(x: 0.0, y: selectedItemFrame.minY), size: CGSize(width: 4.0, height: selectedItemFrame.height)) + case .top: + selectedLineFrame = CGRect(origin: CGPoint(x: selectedItemFrame.minX, y: listView.frame.maxY - 3.0), size: CGSize(width: selectedItemFrame.width, height: 3.0)) + } + + self.selectedLineContainer.updatePosition(position: selectedLineFrame.origin, transition: lineTransition) + lineTransition.setFrame(view: self.selectedLineView, frame: CGRect(origin: CGPoint(), size: selectedLineFrame.size)) + } else { + self.selectedLineView.isHidden = true + } + + if let beforePinnedItemsPosition, let afterPinnedItemsPosition, afterPinnedItemsPosition > beforePinnedItemsPosition { + var pinnedItemsTransition = transition + if self.pinnedBackgroundContainer.isHidden { + self.pinnedBackgroundContainer.isHidden = false + pinnedItemsTransition = .immediate + } + let pinnedItemsBackgroundFrame: CGRect + switch component.location { + case .side: + pinnedItemsBackgroundFrame = CGRect(origin: CGPoint(x: 5.0, y: beforePinnedItemsPosition), size: CGSize(width: listView.bounds.width - 5.0 - 4.0, height: afterPinnedItemsPosition - beforePinnedItemsPosition)) + case .top: + pinnedItemsBackgroundFrame = CGRect(origin: CGPoint(x: beforePinnedItemsPosition, y: 4.0), size: CGSize(width: afterPinnedItemsPosition - beforePinnedItemsPosition, height: listView.bounds.height - 5.0 - 4.0)) + } + self.pinnedBackgroundContainer.updatePosition(position: pinnedItemsBackgroundFrame.origin, transition: pinnedItemsTransition) + pinnedItemsTransition.setFrame(view: self.pinnedBackgroundView, frame: CGRect(origin: CGPoint(), size: pinnedItemsBackgroundFrame.size)) + + let pinnedIconFrame = CGRect(origin: CGPoint(x: 2.0, y: 2.0), size: CGSize(width: 12.0, height: 12.0)) + pinnedItemsTransition.setFrame(view: self.pinnedIconView, frame: pinnedIconFrame) + } else { + self.pinnedBackgroundContainer.isHidden = true + } + } + + private func updateIsReordering(isReordering: Bool) { + self.isReordering = isReordering + if !self.isUpdating { + self.state?.updated(transition: .spring(duration: 0.4)) + } + } + func update(component: ChatSideTopicsPanel, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { self.isUpdating = true defer { @@ -685,6 +1636,12 @@ public final class ChatSideTopicsPanel: Component { self.state = state + if self.resetReorderingOnNextUpdate { + self.resetReorderingOnNextUpdate = false + self.reorderingItems = nil + self.isReordering = false + } + if self.component == nil { let threadListSignal: Signal = component.context.sharedContext.subscribeChatListData(context: component.context, location: component.isMonoforum ? .savedMessagesChats(peerId: component.peerId) : .forum(peerId: component.peerId)) @@ -693,59 +1650,121 @@ public final class ChatSideTopicsPanel: Component { guard let self else { return } - self.items.removeAll() + let wasEmpty = self.rawItems.isEmpty + + self.rawItems.removeAll() for item in chatList.items.reversed() { - self.items.append(Item(item: item)) + self.rawItems.append(Item(item: item)) + } + + if self.reorderingItems != nil { + self.reorderingItems = self.rawItems } if !self.isUpdating { - self.state?.updated(transition: .immediate) + self.state?.updated(transition: (wasEmpty || self.isTogglingPinnedItem) ? .immediate : .spring(duration: 0.4)) } }) + + switch component.location { + case .side: + self.scrollViewMask.image = generateGradientImage(size: CGSize(width: 8.0, height: 8.0), colors: [ + UIColor(white: 1.0, alpha: 0.0), + UIColor(white: 1.0, alpha: 1.0) + ], locations: [0.0, 1.0], direction: .vertical)?.stretchableImage(withLeftCapWidth: 0, topCapHeight: 8) + case .top: + self.scrollViewMask.image = generateGradientImage(size: CGSize(width: 8.0, height: 8.0), colors: [ + UIColor(white: 1.0, alpha: 0.0), + UIColor(white: 1.0, alpha: 1.0) + ], locations: [0.0, 1.0], direction: .horizontal)?.stretchableImage(withLeftCapWidth: 8, topCapHeight: 0) + } } let themeUpdated = self.component?.theme !== component.theme self.component = component - let _ = self.background.update( - transition: transition, - component: AnyComponent(BlurredBackgroundComponent( - color: component.theme.rootController.navigationBar.blurredBackgroundColor - )), - environment: {}, - containerSize: availableSize - ) - self.separatorLayer.backgroundColor = component.theme.rootController.navigationBar.separatorColor.cgColor - - if let backgroundView = self.background.view { - if backgroundView.superview == nil { - self.insertSubview(backgroundView, at: 0) + if case .side = component.location { + let background: ComponentView + if let current = self.background { + background = current + } else { + background = ComponentView() + self.background = background } - transition.setFrame(view: backgroundView, frame: CGRect(origin: CGPoint(), size: availableSize)) + let _ = background.update( + transition: transition, + component: AnyComponent(BlurredBackgroundComponent( + color: component.theme.rootController.navigationBar.blurredBackgroundColor + )), + environment: {}, + containerSize: availableSize + ) + + if let backgroundView = background.view { + if backgroundView.superview == nil { + self.insertSubview(backgroundView, at: 0) + } + transition.setFrame(view: backgroundView, frame: CGRect(origin: CGPoint(), size: availableSize)) + } + + let separatorLayer: SimpleLayer + if let current = self.separatorLayer { + separatorLayer = current + } else { + separatorLayer = SimpleLayer() + self.separatorLayer = separatorLayer + self.layer.addSublayer(separatorLayer) + } + if themeUpdated { + separatorLayer.backgroundColor = component.theme.rootController.navigationBar.separatorColor.cgColor + } + + transition.setFrame(layer: separatorLayer, frame: CGRect(origin: CGPoint(x: availableSize.width, y: 0.0), size: CGSize(width: UIScreenPixel, height: availableSize.height))) } - if self.separatorLayer.superlayer == nil { - self.layer.addSublayer(self.separatorLayer) - } - transition.setFrame(layer: self.separatorLayer, frame: CGRect(origin: CGPoint(x: availableSize.width, y: 0.0), size: CGSize(width: UIScreenPixel, height: availableSize.height))) if themeUpdated { - self.selectedLineView.image = generateImage(CGSize(width: 4.0, height: 7.0), rotatedContext: { size, context in - context.clear(CGRect(origin: CGPoint(), size: size)) - context.setFillColor(component.theme.rootController.navigationBar.accentTextColor.cgColor) - context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - size.height, y: 0.0), size: CGSize(width: size.height, height: size.height))) - })?.stretchableImage(withLeftCapWidth: 1, topCapHeight: 4) + switch component.location { + case .side: + self.selectedLineView.image = generateImage(CGSize(width: 4.0, height: 7.0), rotatedContext: { size, context in + context.clear(CGRect(origin: CGPoint(), size: size)) + context.setFillColor(component.theme.rootController.navigationBar.accentTextColor.cgColor) + context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - size.height, y: 0.0), size: CGSize(width: size.height, height: size.height))) + })?.stretchableImage(withLeftCapWidth: 1, topCapHeight: 4) + case .top: + self.selectedLineView.image = generateImage(CGSize(width: 4.0, height: 3.0), rotatedContext: { size, context in + context.clear(CGRect(origin: CGPoint(), size: size)) + context.setFillColor(component.theme.rootController.navigationBar.accentTextColor.cgColor) + context.addPath(UIBezierPath(roundedRect: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: size.height * 2.0)), cornerRadius: 2.0).cgPath) + context.fillPath() + })?.stretchableImage(withLeftCapWidth: 2, topCapHeight: 1) + } + + if self.pinnedIconView.image == nil { + self.pinnedIconView.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/Pinned"), color: .white)?.withRenderingMode(.alwaysTemplate) + } + self.pinnedIconView.tintColor = component.theme.chatList.unreadBadgeInactiveBackgroundColor + + if self.pinnedBackgroundView.image == nil { + self.pinnedBackgroundView.image = generateStretchableFilledCircleImage(diameter: 10.0, color: .white)?.withRenderingMode(.alwaysTemplate) + } + var pinnedBackgroundColor = component.theme.rootController.navigationSearchBar.inputFillColor + if pinnedBackgroundColor.distance(to: component.theme.list.blocksBackgroundColor) < 100 { + pinnedBackgroundColor = pinnedBackgroundColor.withMultipliedBrightnessBy(0.8) + } + self.pinnedBackgroundView.tintColor = pinnedBackgroundColor } - let hadItemViews = !self.itemViews.isEmpty - let environment = environment[EnvironmentType.self].value let containerInsets = environment.insets - let panelWidth: CGFloat = availableSize.width - containerInsets.left - let itemSpacing: CGFloat = 24.0 - - var topContainerInset: CGFloat = containerInsets.top + var directionContainerInset: CGFloat + switch component.location { + case .side: + directionContainerInset = containerInsets.top + case .top: + directionContainerInset = containerInsets.left + } do { var itemTransition = transition @@ -760,69 +1779,51 @@ public final class ChatSideTopicsPanel: Component { guard let self, let component = self.component else { return } - component.togglePanel() + if self.isReordering { + if let reorderingItems = self.reorderingItems { + var threadIds: [Int64] = [] + for item in reorderingItems { + if case let .forum(pinnedIndex, _, threadId, _, _) = item.item.index, case .index = pinnedIndex { + threadIds.append(threadId) + } + } + + var currentThreadIds: [Int64] = [] + for item in self.rawItems { + if case let .forum(pinnedIndex, _, threadId, _, _) = item.item.index, case .index = pinnedIndex { + currentThreadIds.append(threadId) + } + } + + if threadIds != currentThreadIds { + let _ = component.context.engine.peers.setForumChannelPinnedTopics(id: component.peerId, threadIds: threadIds).startStandalone() + self.resetReorderingOnNextUpdate = true + } else { + self.reorderingItems = nil + self.isReordering = false + self.state?.updated(transition: .spring(duration: 0.4)) + } + } else { + self.isReordering = false + self.state?.updated(transition: .spring(duration: 0.4)) + } + } else { + component.togglePanel() + } }) self.tabItemView = itemView self.addSubview(itemView) } - - let itemSize = itemView.update(context: component.context, theme: component.theme, width: panelWidth, transition: .immediate) - let itemFrame = CGRect(origin: CGPoint(x: 0.0, y: topContainerInset), size: itemSize) - itemTransition.setPosition(layer: itemView.layer, position: itemFrame.center) - itemTransition.setBounds(layer: itemView.layer, bounds: CGRect(origin: CGPoint(), size: itemFrame.size)) - - if animateIn && !transition.animation.isImmediate { - itemView.layer.animateAlpha(from: 0.0, to: itemView.alpha, duration: 0.15) - transition.containedViewLayoutTransition.animateTransformScale(view: itemView, from: 0.001) - } - - topContainerInset += itemSize.height - topContainerInset -= 24.0 - } - - var contentSize = CGSize(width: panelWidth, height: 0.0) - contentSize.height += 36.0 - - var validIds: [Item.Id] = [] - var isFirst = true - var selectedItemFrame: CGRect? - - do { - if isFirst { - isFirst = false - } else { - contentSize.height += itemSpacing - } - - var itemTransition = transition - var animateIn = false - let itemView: AllItemView - if let current = self.allItemView { - itemView = current - } else { - itemTransition = .immediate - animateIn = true - itemView = AllItemView(context: component.context, action: { [weak self] in - guard let self, let component = self.component else { - return - } - - component.updateTopicId(nil, false) - }) - self.allItemView = itemView - self.scrollView.addSubview(itemView) - } - - var isSelected = false - if component.topicId == nil { - isSelected = true - } - let itemSize = itemView.update(context: component.context, isSelected: isSelected, theme: component.theme, width: panelWidth, transition: .immediate) - let itemFrame = CGRect(origin: CGPoint(x: containerInsets.left, y: contentSize.height), size: itemSize) - - if isSelected { - selectedItemFrame = itemFrame + let itemSize = itemView.update(context: component.context, theme: component.theme, width: 72.0, location: component.location, isReordering: self.isReordering, transition: itemTransition) + let itemFrame: CGRect + switch component.location { + case .side: + itemFrame = CGRect(origin: CGPoint(x: 0.0, y: directionContainerInset), size: itemSize) + directionContainerInset += itemSize.height + case .top: + itemFrame = CGRect(origin: CGPoint(x: directionContainerInset, y: 0.0), size: itemSize) + directionContainerInset += itemSize.width - 14.0 } itemTransition.setPosition(layer: itemView.layer, position: itemFrame.center) @@ -832,122 +1833,24 @@ public final class ChatSideTopicsPanel: Component { itemView.layer.animateAlpha(from: 0.0, to: itemView.alpha, duration: 0.15) transition.containedViewLayoutTransition.animateTransformScale(view: itemView, from: 0.001) } - - contentSize.height += itemSize.height } - for item in self.items { - if isFirst { - isFirst = false - } else { - contentSize.height += itemSpacing - } - let itemId = item.id - validIds.append(itemId) - - var itemTransition = transition - var animateIn = false - let itemView: ItemView - if let current = self.itemViews[itemId] { - itemView = current - } else { - itemTransition = .immediate - animateIn = true - let chatListItem = item.item - itemView = ItemView(context: component.context, action: { [weak self] in - guard let self, let component = self.component else { - return - } - - let topicId: Int64 - if case let .forum(topicIdValue) = chatListItem.id { - topicId = topicIdValue - } else { - topicId = chatListItem.renderedPeer.peerId.toInt64() - } - - var direction = true - if let lhsIndex = self.topicIndex(threadId: component.topicId), let rhsIndex = self.topicIndex(threadId: topicId) { - direction = lhsIndex < rhsIndex - } - - component.updateTopicId(topicId, direction) - }, contextGesture: { gesture, sourceNode in - }) - self.itemViews[itemId] = itemView - self.scrollView.addSubview(itemView) - } - - var isSelected = false - if case let .forum(topicId) = item.item.id { - isSelected = component.topicId == topicId - } else { - isSelected = component.topicId == item.item.renderedPeer.peerId.toInt64() - } - let itemSize = itemView.update(context: component.context, item: item, isSelected: isSelected, theme: component.theme, width: panelWidth, transition: .immediate) - let itemFrame = CGRect(origin: CGPoint(x: containerInsets.left, y: contentSize.height), size: itemSize) - - if isSelected { - selectedItemFrame = itemFrame - } - - itemTransition.setPosition(layer: itemView.layer, position: itemFrame.center) - itemTransition.setBounds(layer: itemView.layer, bounds: CGRect(origin: CGPoint(), size: itemFrame.size)) - - if animateIn && !transition.animation.isImmediate { - itemView.layer.animateAlpha(from: 0.0, to: itemView.alpha, duration: 0.15) - transition.containedViewLayoutTransition.animateTransformScale(view: itemView, from: 0.001) - } - - contentSize.height += itemSize.height + let scrollSize: CGSize + let scrollFrame: CGRect + let listContentInsets: UIEdgeInsets + switch component.location { + case .side: + scrollSize = CGSize(width: availableSize.width, height: availableSize.height - directionContainerInset) + scrollFrame = CGRect(origin: CGPoint(x: 0.0, y: directionContainerInset), size: scrollSize) + listContentInsets = UIEdgeInsets(top: 8.0, left: 0.0, bottom: 8.0, right: 0.0) + case .top: + scrollSize = CGSize(width: availableSize.width - directionContainerInset, height: availableSize.height) + scrollFrame = CGRect(origin: CGPoint(x: directionContainerInset, y: 0.0), size: scrollSize) + listContentInsets = UIEdgeInsets(top: 0.0, left: 8.0, bottom: 0.0, right: 8.0) } - contentSize.height += 12.0 - - var removedIds: [Item.Id] = [] - for (id, itemView) in self.itemViews { - if !validIds.contains(id) { - removedIds.append(id) - - if !transition.animation.isImmediate { - itemView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.18, removeOnCompletion: false, completion: { [weak itemView] _ in - itemView?.removeFromSuperview() - }) - transition.setScale(layer: itemView.layer, scale: 0.001) - } else { - itemView.removeFromSuperview() - } - } - } - for id in removedIds { - self.itemViews.removeValue(forKey: id) - } - - if let selectedItemFrame { - let lineFrame = CGRect(origin: CGPoint(x: containerInsets.left, y: selectedItemFrame.minY), size: CGSize(width: 4.0, height: selectedItemFrame.height + 4.0)) - if self.selectedLineView.isHidden { - self.selectedLineView.isHidden = false - self.selectedLineView.frame = lineFrame - } else { - transition.setFrame(view: self.selectedLineView, frame: lineFrame) - } - } else { - self.selectedLineView.isHidden = true - } - - contentSize.height += containerInsets.bottom - - let scrollSize = CGSize(width: availableSize.width, height: availableSize.height - topContainerInset) - - self.scrollContainerView.frame = CGRect(origin: CGPoint(x: 0.0, y: topContainerInset), size: scrollSize) - self.scrollViewMask.frame = CGRect(origin: CGPoint(x: 0.0, y: topContainerInset), size: scrollSize) - - if self.scrollView.bounds.size != scrollSize { - self.scrollView.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: scrollSize) - } - if self.scrollView.contentSize != contentSize { - self.scrollView.contentSize = contentSize - } + self.scrollContainerView.frame = scrollFrame + self.scrollViewMask.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: scrollSize) let scrollToId: ScrollId if let threadId = component.topicId { @@ -956,17 +1859,378 @@ public final class ChatSideTopicsPanel: Component { scrollToId = .all } if self.appliedScrollToId != scrollToId { - if case let .topic(threadId) = scrollToId { - if let itemView = self.itemViews[.forum(threadId)] { - self.appliedScrollToId = scrollToId - self.scrollView.scrollRectToVisible(itemView.frame.insetBy(dx: -46.0, dy: 0.0), animated: hadItemViews) + self.appliedScrollToId = scrollToId + self.listState.resetScrolling(id: AnyHashable(scrollToId)) + } + + var listItems: [AnyComponentWithIdentity] = [] + switch component.location { + case .side: + listItems.append(AnyComponentWithIdentity( + id: ScrollId.all, + component: AnyComponent(VerticalAllItemComponent( + isSelected: component.topicId == nil, + theme: component.theme, + strings: component.strings, + action: { [weak self] in + guard let self, let component = self.component else { + return + } + component.updateTopicId(nil, false) + } + ))) + ) + case .top: + listItems.append(AnyComponentWithIdentity( + id: ScrollId.all, + component: AnyComponent(HorizontalAllItemComponent( + isSelected: component.topicId == nil, + theme: component.theme, + strings: component.strings, + action: { [weak self] in + guard let self, let component = self.component else { + return + } + component.updateTopicId(nil, false) + } + ))) + ) + } + for item in self.reorderingItems ?? self.rawItems { + let scrollId: ScrollId + let topicId: Int64 + var isItemReordering = false + switch item.item.id { + case let .chatList(peerId): + topicId = peerId.toInt64() + case let .forum(topicIdValue): + topicId = topicIdValue + if self.isReordering { + if case let .forum(pinnedIndex, _, _, _, _) = item.item.index, case .index = pinnedIndex { + isItemReordering = true + } } - } else if case .all = scrollToId { - self.appliedScrollToId = scrollToId - self.scrollView.scrollRectToVisible(CGRect(origin: CGPoint(), size: CGSize(width: 1.0, height: 1.0)), animated: hadItemViews) - } else { - self.appliedScrollToId = scrollToId } + scrollId = .topic(topicId) + + let itemAction: (() -> Void)? = self.isReordering ? nil : { [weak self] in + guard let self, let component = self.component else { + return + } + + let direction: Bool + if let lhsIndex = self.topicIndex(threadId: component.topicId), let rhsIndex = self.topicIndex(threadId: topicId) { + direction = lhsIndex < rhsIndex + } else { + direction = false + } + component.updateTopicId(topicId, direction) + } + var itemContextGesture: ((ContextGesture, ContextExtractedContentContainingNode) -> Void)? + if !self.isReordering && component.isMonoforum { + itemContextGesture = { [weak self] gesture, sourceNode in + guard let self, let component = self.component else { + return + } + guard let controller = component.controller() else { + return + } + + let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }) + + if let listView = self.list.view as? AsyncListComponent.View { + listView.stopScrolling() + } + + let topicId: Int64 + switch item.item.id { + case let .chatList(peerId): + topicId = peerId.toInt64() + case let .forum(topicIdValue): + topicId = topicIdValue + } + + var items: [ContextMenuItem] = [] + + items.append(.action(ContextMenuActionItem(text: presentationData.strings.ChatList_Context_Delete, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak self] c, _ in + guard let self else { + return + } + + c?.dismiss(completion: { [weak self] in + guard let self, let component = self.component, let controller = component.controller() else { + return + } + + let actionSheet = ActionSheetController(presentationData: presentationData) + var items: [ActionSheetItem] = [] + + items.append(ActionSheetTextItem(title: presentationData.strings.ChatList_DeleteTopicConfirmationText, parseMarkdown: true)) + items.append(ActionSheetButtonItem(title: presentationData.strings.ChatList_DeleteTopicConfirmationAction, color: .destructive, action: { [weak self, weak actionSheet] in + actionSheet?.dismissAnimated() + guard let self, let component = self.component else { + return + } + + if component.topicId == topicId { + component.updateTopicId(nil, false) + } + + let _ = component.context.engine.peers.removeForumChannelThread(id: component.peerId, threadId: topicId).startStandalone(completed: { + }) + })) + + actionSheet.setItemGroups([ + ActionSheetItemGroup(items: items), + ActionSheetItemGroup(items: [ + ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in + actionSheet?.dismissAnimated() + }) + ]) + ]) + controller.present(actionSheet, in: .window(.root)) + }) + }))) + + let contextController = ContextController( + presentationData: presentationData, + source: .extracted(ItemExtractedContentSource( + sourceNode: sourceNode, + containerView: self, + keepInPlace: false + )), + items: .single(ContextController.Items(content: .list(items))), + recognizer: nil, + gesture: gesture + ) + controller.presentInGlobalOverlay(contextController) + } + } else if !self.isReordering { + itemContextGesture = { [weak self] gesture, sourceNode in + guard let self, let component = self.component else { + return + } + guard let controller = component.controller() else { + return + } + + let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }) + + if let listView = self.list.view as? AsyncListComponent.View { + listView.stopScrolling() + } + + let topicId: Int64 + switch item.item.id { + case let .chatList(peerId): + topicId = peerId.toInt64() + case let .forum(topicIdValue): + topicId = topicIdValue + } + + var isPinned = false + if case let .forum(pinnedIndex, _, _, _, _) = item.item.index { + if case .index = pinnedIndex { + isPinned = true + } + } + let isClosed = item.item.threadData?.isClosed + let threadData = item.item.threadData + + let _ = (chatForumTopicMenuItems( + context: component.context, + peerId: component.peerId, + threadId: topicId, + isPinned: isPinned, + isClosed: isClosed, + chatListController: controller, + joined: true, + canSelect: false, + customEdit: { [weak self] contextController in + contextController.dismiss(completion: { + guard let self, let component = self.component, let threadData else { + return + } + let editController = component.context.sharedContext.makeEditForumTopicScreen( + context: component.context, + peerId: component.peerId, + threadId: topicId, + threadInfo: threadData.info, + isHidden: threadData.isHidden + ) + component.controller()?.push(editController) + }) + }, + customPinUnpin: { [weak self] contextController in + guard let self, let component = self.component else { + contextController.dismiss(completion: {}) + return + } + + self.isTogglingPinnedItem = true + self.dismissContextControllerOnNextUpdate = contextController + + let _ = (component.context.engine.peers.toggleForumChannelTopicPinned(id: component.peerId, threadId: topicId) + |> deliverOnMainQueue).startStandalone(error: { [weak self, weak contextController] error in + guard let self, let component = self.component else { + contextController?.dismiss(completion: {}) + return + } + + switch error { + case let .limitReached(count): + contextController?.dismiss(completion: {}) + if let controller = component.controller() { + let presentationData = component.context.sharedContext.currentPresentationData.with { $0 } + let text = presentationData.strings.ChatList_MaxThreadPinsFinalText(Int32(count)) + controller.present(textAlertController(context: component.context, title: presentationData.strings.Premium_LimitReached, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})], parseMarkdown: true), in: .window(.root)) + } + default: + break + } + }) + }, + reorder: { [weak self] in + guard let self else { + return + } + self.updateIsReordering(isReordering: true) + } + ) + |> take(1) + |> deliverOnMainQueue).startStandalone(next: { [weak self, weak sourceNode, weak gesture] items in + guard let self, let component = self.component else { + return + } + guard let controller = component.controller() else { + return + } + guard let sourceNode else { + return + } + + let contextController = ContextController( + presentationData: presentationData, + source: .extracted(ItemExtractedContentSource( + sourceNode: sourceNode, + containerView: self, + keepInPlace: false + )), + items: .single(ContextController.Items(content: .list(items))), + recognizer: nil, + gesture: gesture + ) + controller.presentInGlobalOverlay(contextController) + }) + } + } + + switch component.location { + case .side: + listItems.append(AnyComponentWithIdentity( + id: scrollId, + component: AnyComponent(VerticalItemComponent( + context: component.context, + item: item, + isSelected: component.topicId == topicId, + isReordering: isItemReordering, + theme: component.theme, + strings: component.strings, + action: itemAction, + contextGesture: itemContextGesture + ))) + ) + case .top: + listItems.append(AnyComponentWithIdentity( + id: scrollId, + component: AnyComponent(HorizontalItemComponent( + context: component.context, + item: item, + isSelected: component.topicId == topicId, + isReordering: isItemReordering, + theme: component.theme, + strings: component.strings, + action: itemAction, + contextGesture: itemContextGesture + ))) + ) + } + } + + let _ = self.list.update( + transition: transition, + component: AnyComponent(AsyncListComponent( + externalState: self.listState, + items: listItems, + itemSetId: AnyHashable(self.itemsContentVersion), + direction: component.location == .side ? .vertical : .horizontal, + insets: listContentInsets, + reorderItems: { [weak self] fromIndex, toIndex in + guard let self else { + return false + } + if !self.isReordering { + return false + } + + if self.reorderingItems == nil { + self.reorderingItems = self.rawItems + } + if var reorderingItems = self.reorderingItems { + var maxToIndex = -1 + for item in reorderingItems { + if case let .forum(pinnedIndex, _, _, _, _) = item.item.index, case .index = pinnedIndex { + maxToIndex += 1 + } else { + break + } + } + + let fromItemIndex = fromIndex - 1 + // Account for synthesized "all" item: [all, item_0, item_1, ...] + let toItemIndex = max(0, min(maxToIndex, toIndex - 1)) + if fromItemIndex == toItemIndex { + return false + } + + let reorderingItem = reorderingItems[fromItemIndex] + if toItemIndex < fromItemIndex { + reorderingItems.remove(at: fromItemIndex) + reorderingItems.insert(reorderingItem, at: toItemIndex) + } else { + reorderingItems.insert(reorderingItem, at: toItemIndex + 1) + reorderingItems.remove(at: fromItemIndex) + } + + self.reorderingItems = reorderingItems + self.state?.updated(transition: .spring(duration: 0.4)) + } + + return true + }, + onVisibleItemsUpdated: { [weak self] visibleItems, transition in + guard let self else { + return + } + self.updateListOverlays(visibleItems: visibleItems, transition: transition) + } + )), + environment: {}, + containerSize: scrollSize + ) + if let listView = self.list.view { + if listView.superview == nil { + self.scrollContainerView.addSubview(listView) + } + transition.setFrame(view: listView, frame: CGRect(origin: CGPoint(), size: scrollSize)) + } + + if self.isTogglingPinnedItem { + self.isTogglingPinnedItem = false + } + if let dismissContextControllerOnNextUpdate = self.dismissContextControllerOnNextUpdate { + self.dismissContextControllerOnNextUpdate = nil + dismissContextControllerOnNextUpdate.dismiss(completion: {}) } return availableSize @@ -981,3 +2245,35 @@ public final class ChatSideTopicsPanel: Component { return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition) } } + +private final class ItemExtractedContentSource: ContextExtractedContentSource { + let keepInPlace: Bool + let ignoreContentTouches: Bool = true + let blurBackground: Bool = true + let adjustContentForSideInset: Bool = true + + private let sourceNode: ContextExtractedContentContainingNode + private weak var containerView: UIView? + + init(sourceNode: ContextExtractedContentContainingNode, containerView: UIView, keepInPlace: Bool) { + self.sourceNode = sourceNode + self.containerView = containerView + self.keepInPlace = keepInPlace + } + + func takeView() -> ContextControllerTakeViewInfo? { + var contentArea: CGRect? + if let containerView = self.containerView { + contentArea = containerView.convert(containerView.bounds, to: nil) + } + + return ContextControllerTakeViewInfo( + containingItem: .node(self.sourceNode), + contentAreaInScreenSpace: contentArea ?? UIScreen.main.bounds + ) + } + + func putBack() -> ContextControllerPutBackViewInfo? { + return ContextControllerPutBackViewInfo(contentAreaInScreenSpace: UIScreen.main.bounds) + } +} diff --git a/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift b/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift index 437de99742..6e7a0cfd7d 100644 --- a/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift +++ b/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift @@ -268,6 +268,10 @@ public final class EmojiStatusComponent: Component { } } + public func playOnce() { + self.animationLayer?.playOnce() + } + func update(component: EmojiStatusComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { let availableSize = component.size ?? availableSize diff --git a/submodules/TelegramUI/Components/EmojiTextAttachmentView/Sources/EmojiTextAttachmentView.swift b/submodules/TelegramUI/Components/EmojiTextAttachmentView/Sources/EmojiTextAttachmentView.swift index 1e3eb5ce9f..5d0490c400 100644 --- a/submodules/TelegramUI/Components/EmojiTextAttachmentView/Sources/EmojiTextAttachmentView.swift +++ b/submodules/TelegramUI/Components/EmojiTextAttachmentView/Sources/EmojiTextAttachmentView.swift @@ -371,6 +371,7 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget { } } + private var overrideLoopCount: Int? private var currentLoopCount: Int = 0 public var isUnique: Bool = false @@ -612,8 +613,10 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget { var shouldBePlaying = self.isInHierarchyValue && self.isVisibleForAnimations - if shouldBePlaying, let loopCount = arguments.loopCount, self.currentLoopCount >= loopCount { - shouldBePlaying = false + if shouldBePlaying { + if let loopCount = self.overrideLoopCount ?? arguments.loopCount, self.currentLoopCount >= loopCount { + shouldBePlaying = false + } } if self.shouldBeAnimating != shouldBePlaying { @@ -621,6 +624,7 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget { if !shouldBePlaying { self.currentLoopCount = 0 + self.overrideLoopCount = nil } } } @@ -795,6 +799,12 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget { } } + public func playOnce() { + self.currentLoopCount = 0 + self.overrideLoopCount = 1 + self.updatePlayback() + } + public func reloadAnimation() { self.updateFile(attemptSynchronousLoad: false) } @@ -880,6 +890,7 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget { if didLoop { self.currentLoopCount += 1 + self.overrideLoopCount = nil if let loopCount = arguments.loopCount, self.currentLoopCount >= loopCount { self.updatePlayback() } diff --git a/submodules/TelegramUI/Components/MaskedContainerComponent/BUILD b/submodules/TelegramUI/Components/MaskedContainerComponent/BUILD new file mode 100644 index 0000000000..4f2e41640c --- /dev/null +++ b/submodules/TelegramUI/Components/MaskedContainerComponent/BUILD @@ -0,0 +1,19 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "MaskedContainerComponent", + module_name = "MaskedContainerComponent", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/Display", + "//submodules/ComponentFlow", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/TelegramUI/Components/MaskedContainerComponent/Sources/MaskedContainerComponent.swift b/submodules/TelegramUI/Components/MaskedContainerComponent/Sources/MaskedContainerComponent.swift new file mode 100644 index 0000000000..c83fff8f83 --- /dev/null +++ b/submodules/TelegramUI/Components/MaskedContainerComponent/Sources/MaskedContainerComponent.swift @@ -0,0 +1,94 @@ +import Foundation +import UIKit +import Display +import ComponentFlow + +public final class MaskedContainerView: UIView { + public struct Item: Equatable { + public enum Shape: Equatable { + case ellipse + case roundedRect(cornerRadius: CGFloat) + } + + public var frame: CGRect + public var shape: Shape + + public init(frame: CGRect, shape: Shape) { + self.frame = frame + self.shape = shape + } + } + + private struct Params: Equatable { + let size: CGSize + let items: [Item] + let isInverted: Bool + + init(size: CGSize, items: [Item], isInverted: Bool) { + self.size = size + self.items = items + self.isInverted = isInverted + } + } + + public let contentView: UIView + public let contentMaskView: UIImageView + + private var params: Params? + + override public init(frame: CGRect) { + self.contentView = UIView() + self.contentMaskView = UIImageView() + + super.init(frame: frame) + + self.addSubview(self.contentView) + } + + required public init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public func update(size: CGSize, items: [Item], isInverted: Bool) { + let params = Params(size: size, items: items, isInverted: isInverted) + if self.params == params { + return + } + self.params = params + self.contentView.frame = CGRect(origin: CGPoint(), size: size) + self.contentMaskView.frame = CGRect(origin: CGPoint(), size: size) + + if items.isEmpty { + self.contentMaskView.image = nil + self.contentView.mask = nil + } else { + let renderer = UIGraphicsImageRenderer(bounds: CGRect(origin: CGPoint(), size: size)) + let image = renderer.image { context in + UIGraphicsPushContext(context.cgContext) + + if isInverted { + context.cgContext.setFillColor(UIColor.black.cgColor) + context.cgContext.fill(CGRect(origin: CGPoint(), size: size)) + + context.cgContext.setFillColor(UIColor.clear.cgColor) + context.cgContext.setBlendMode(.copy) + } + + for item in items { + switch item.shape { + case .ellipse: + context.cgContext.fillEllipse(in: item.frame) + case let .roundedRect(cornerRadius): + context.cgContext.addPath(UIBezierPath(roundedRect: item.frame, cornerRadius: cornerRadius).cgPath) + context.cgContext.fillPath() + } + } + + UIGraphicsPopContext() + } + self.contentMaskView.image = image + + self.contentView.mask = self.contentMaskView + } + } +} diff --git a/submodules/TelegramUI/Components/NotificationExceptionsScreen/Sources/NotificationExceptionsScreen.swift b/submodules/TelegramUI/Components/NotificationExceptionsScreen/Sources/NotificationExceptionsScreen.swift index a75a51de5f..8b20e10e96 100644 --- a/submodules/TelegramUI/Components/NotificationExceptionsScreen/Sources/NotificationExceptionsScreen.swift +++ b/submodules/TelegramUI/Components/NotificationExceptionsScreen/Sources/NotificationExceptionsScreen.swift @@ -526,7 +526,7 @@ public func threadNotificationExceptionsScreen(context: AccountContext, peerId: }, addException: { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let filter: ChatListNodePeersFilter = [.excludeRecent, .doNotSearchMessages, .removeSearchHeader] - let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: filter, forumPeerId: peerId, hasContactSelector: false, title: presentationData.strings.Notifications_AddExceptionTitle)) + let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: filter, forumPeerId: (peerId, false), hasContactSelector: false, title: presentationData.strings.Notifications_AddExceptionTitle)) controller.peerSelected = { [weak controller] _, threadId in guard let threadId = threadId else { return diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index 4ea27126a0..606d5edcdc 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -1033,7 +1033,7 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p } } if !isPremiumDisabled || context.isPremium { - items[.payment]!.append(PeerInfoScreenDisclosureItem(id: 103, label: .text(""), additionalBadgeLabel: presentationData.strings.Settings_New, text: presentationData.strings.Settings_Business, icon: PresentationResourcesSettings.business, action: { + items[.payment]!.append(PeerInfoScreenDisclosureItem(id: 103, label: .text(""), additionalBadgeLabel: nil, text: presentationData.strings.Settings_Business, icon: PresentationResourcesSettings.business, action: { interaction.openSettings(.businessSetup) })) } @@ -2219,8 +2219,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt interaction.editingOpenDiscussionGroupSetup() })) - //TODO:localize - items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPostSuggestionsSettings, label: .text(channel.linkedMonoforumId == nil ? "Off" : "On"), additionalBadgeLabel: presentationData.strings.Settings_New, text: "Message Channel", icon: UIImage(bundleImageName: "Chat/Info/PostSuggestionsIcon"), action: { + items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPostSuggestionsSettings, label: .text(channel.linkedMonoforumId == nil ? presentationData.strings.PeerInfo_AllowChannelMessages_Off : presentationData.strings.PeerInfo_AllowChannelMessages_On), additionalBadgeLabel: presentationData.strings.Settings_New, text: presentationData.strings.PeerInfo_AllowChannelMessages, icon: PresentationResourcesSettings.channelMessages, action: { interaction.editingOpenPostSuggestionsSetup() })) } @@ -2247,10 +2246,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt } else { label = "" } - var additionalBadgeLabel: String? = nil - if case .broadcast = channel.info { - additionalBadgeLabel = presentationData.strings.Settings_New - } + let additionalBadgeLabel: String? = nil items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemReactions, label: .text(label), additionalBadgeLabel: additionalBadgeLabel, text: presentationData.strings.PeerInfo_Reactions, icon: UIImage(bundleImageName: "Settings/Menu/Reactions"), action: { interaction.editingOpenReactionsSetup() })) @@ -2357,8 +2353,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt })) if channel.linkedMonoforumId != nil { - //TODO:localize - items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemChannelMessages, label: .none, text: "Channel Messages", icon: UIImage(bundleImageName: "Chat/Info/RecentActionsIcon"), action: { + items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemChannelMessages, label: .none, text: presentationData.strings.PeerInfo_ChannelMessages, icon: PresentationResourcesSettings.channelMessages, action: { interaction.openChannelMessages() })) } @@ -2375,7 +2370,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt } if canJoinRefProgram { - items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAffiliatePrograms, label: .text(""), additionalBadgeLabel: presentationData.strings.Settings_New, text: presentationData.strings.PeerInfo_ItemAffiliatePrograms_Title, icon: PresentationResourcesSettings.affiliateProgram, action: { + items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAffiliatePrograms, label: .text(""), additionalBadgeLabel: nil, text: presentationData.strings.PeerInfo_ItemAffiliatePrograms_Title, icon: PresentationResourcesSettings.affiliateProgram, action: { interaction.editingOpenAffiliateProgram() })) } @@ -2531,7 +2526,8 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt if let approximateBoostLevel = channel.approximateBoostLevel, approximateBoostLevel < 1 { boostIcon = generateDisclosureActionBoostLevelBadgeImage(text: presentationData.strings.Channel_Info_BoostLevelPlusBadge("1").string) } else { - let labelText = NSAttributedString(string: presentationData.strings.Settings_New, font: Font.medium(11.0), textColor: presentationData.theme.list.itemCheckColors.foregroundColor) + boostIcon = nil + /*let labelText = NSAttributedString(string: presentationData.strings.Settings_New, font: Font.medium(11.0), textColor: presentationData.theme.list.itemCheckColors.foregroundColor) let labelBounds = labelText.boundingRect(with: CGSize(width: 100.0, height: 100.0), options: [.usesLineFragmentOrigin], context: nil) let labelSize = CGSize(width: ceil(labelBounds.width), height: ceil(labelBounds.height)) let badgeSize = CGSize(width: labelSize.width + 8.0, height: labelSize.height + 2.0 + 1.0) @@ -2547,7 +2543,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt UIGraphicsPushContext(context) labelText.draw(at: CGPoint(x: 4.0, y: 1.0 + UIScreenPixel)) UIGraphicsPopContext() - }) + })*/ } items[.peerDataSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAppearance, label: .image(colorImage, colorImage.size), additionalBadgeIcon: boostIcon, text: presentationData.strings.Channel_Info_AppearanceItem, icon: UIImage(bundleImageName: "Chat/Info/NameColorIcon"), action: { interaction.editingOpenNameColorSetup() diff --git a/submodules/TelegramUI/Components/PeerInfo/PostSuggestionsSettingsScreen/Sources/PostSuggestionsSettingsScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PostSuggestionsSettingsScreen/Sources/PostSuggestionsSettingsScreen.swift index 7e783c1a31..fd64e787d7 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PostSuggestionsSettingsScreen/Sources/PostSuggestionsSettingsScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PostSuggestionsSettingsScreen/Sources/PostSuggestionsSettingsScreen.swift @@ -124,7 +124,7 @@ final class PostSuggestionsSettingsScreenComponent: Component { } if component.initialPrice != currentAmount { - let _ = component.context.engine.peers.updateChannelPaidMessagesStars(peerId: peer.id, stars: currentAmount, broadcastMessagesAllowed: true).startStandalone() + let _ = component.context.engine.peers.updateChannelPaidMessagesStars(peerId: peer.id, stars: currentAmount, broadcastMessagesAllowed: currentAmount != nil).startStandalone() } return true @@ -200,11 +200,10 @@ final class PostSuggestionsSettingsScreenComponent: Component { let presentationData = component.context.sharedContext.currentPresentationData.with { $0 } - //TODO:localize let navigationTitleSize = self.navigationTitle.update( transition: transition, component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: "Post Suggestion", font: Font.semibold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)), + text: .plain(NSAttributedString(string: environment.strings.ChannelMessages_Title, font: Font.semibold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)), horizontalAlignment: .center )), environment: {}, @@ -231,7 +230,7 @@ final class PostSuggestionsSettingsScreenComponent: Component { let iconSize = self.icon.update( transition: .immediate, component: AnyComponent(LottieComponent( - content: LottieComponent.AppBundleContent(name: "LampEmoji"), + content: LottieComponent.AppBundleContent(name: "ChannelMessages"), loop: false )), environment: {}, @@ -249,8 +248,7 @@ final class PostSuggestionsSettingsScreenComponent: Component { contentHeight += 129.0 - //TODO:localize - let subtitleString = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString("Allow users to suggest posts for your channel.", attributes: MarkdownAttributes( + let subtitleString = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.ChannelMessages_Info, attributes: MarkdownAttributes( body: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.freeTextColor), bold: MarkdownAttributeSet(font: Font.semibold(15.0), textColor: environment.theme.list.freeTextColor), link: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.itemAccentColor), @@ -301,7 +299,7 @@ final class PostSuggestionsSettingsScreenComponent: Component { title: AnyComponent(VStack([ AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent( text: .plain(NSAttributedString( - string: "Allow Post Suggestions", + string: environment.strings.ChannelMessages_SwitchTitle, font: Font.regular(presentationData.listsFontSize.baseDisplaySize), textColor: environment.theme.list.itemPrimaryTextColor )), @@ -385,26 +383,6 @@ final class PostSuggestionsSettingsScreenComponent: Component { ), params: ListViewItemLayoutParams(width: availableSize.width - sideInset * 2.0, leftInset: 0.0, rightInset: 0.0, availableHeight: 10000.0, isStandalone: true) )))) - /*contentSectionItems.append(AnyComponentWithIdentity(id: 0, component: AnyComponent(ListItemSliderSelectorComponent( - theme: environment.theme, - content: .discrete(ListItemSliderSelectorComponent.Discrete( - values: sliderValueList.map { item in - return item - }, - markPositions: false, - selectedIndex: max(0, min(sliderValueList.count - 1, self.starCount - 1)), - title: sliderTitle, - secondaryTitle: sliderSecondaryTitle, - selectedIndexUpdated: { [weak self] index in - guard let self else { - return - } - let index = max(0, min(sliderValueList.count, index)) - self.starCount = index - self.state?.updated(transition: .immediate) - } - )) - ))))*/ let contentSectionSize = self.contentSection.update( transition: transition, @@ -412,7 +390,7 @@ final class PostSuggestionsSettingsScreenComponent: Component { theme: environment.theme, header: AnyComponent(MultilineTextComponent( text: .plain(NSAttributedString( - string: "PRICE FOR EACH SUGGESTION", + string: environment.strings.ChannelMessages_PriceSectionTitle, font: Font.regular(13.0), textColor: environment.theme.list.freeTextColor )), @@ -420,7 +398,7 @@ final class PostSuggestionsSettingsScreenComponent: Component { )), footer: AnyComponent(MultilineTextComponent( text: .plain(NSAttributedString( - string: "Charge users for the ability to suggest one post for your channel. You're not required to publish any suggestions by charging this. You'll receive 85% of the selected fee for each incoming suggestion.", + string: environment.strings.ChannelMessages_PriceSectionFooter, font: Font.regular(13.0), textColor: environment.theme.list.freeTextColor )), @@ -509,7 +487,7 @@ public final class PostSuggestionsSettingsScreen: ViewControllerComponentContain if case let .channel(channel) = peer, case let .broadcast(info) = channel.info, info.flags.contains(.hasMonoforum), let linkedMonoforumId = channel.linkedMonoforumId { initialPrice = await context.engine.data.get( TelegramEngine.EngineData.Item.Peer.SendMessageToChannelPrice(id: linkedMonoforumId) - ).get() ?? StarsAmount(value: 20, nanos: 0) + ).get() ?? StarsAmount(value: 0, nanos: 0) } else { initialPrice = await context.engine.data.get( TelegramEngine.EngineData.Item.Peer.SendMessageToChannelPrice(id: peerId) diff --git a/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionController.swift b/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionController.swift index 7634568075..ba9f768fad 100644 --- a/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionController.swift +++ b/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionController.swift @@ -22,7 +22,7 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon public var peerSelected: ((EnginePeer, Int64?) -> Void)? public var multiplePeersSelected: (([EnginePeer], [EnginePeer.Id: EnginePeer], NSAttributedString, AttachmentTextInputPanelSendMode, ChatInterfaceForwardOptionsState?, ChatSendMessageActionSheetController.SendParameters?) -> Void)? private let filter: ChatListNodePeersFilter - private let forumPeerId: EnginePeer.Id? + private let forumPeerId: (id: EnginePeer.Id, isMonoforum: Bool)? private let selectForumThreads: Bool private let attemptSelection: ((EnginePeer, Int64?, ChatListDisabledPeerReason) -> Void)? @@ -277,28 +277,45 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon self.peerSelectionNode.requestOpenPeer = { [weak self] peer, threadId in if let strongSelf = self, let peerSelected = strongSelf.peerSelected { if case let .channel(peer) = peer, peer.isForumOrMonoForum, threadId == nil, strongSelf.selectForumThreads { - let controller = PeerSelectionControllerImpl( - PeerSelectionControllerParams( - context: strongSelf.context, - updatedPresentationData: nil, - filter: strongSelf.filter, - forumPeerId: peer.id, - hasFilters: false, - hasChatListSelector: false, - hasContactSelector: false, - hasGlobalSearch: false, - title: EnginePeer(peer).compactDisplayTitle, - attemptSelection: strongSelf.attemptSelection, - createNewGroup: nil, - pretendPresentedInModal: false, - multipleSelection: false, - forwardedMessageIds: [], - hasTypeHeaders: false, - selectForumThreads: false + let mainPeer: Signal + if peer.isMonoForum, let linkedMonoforumId = peer.linkedMonoforumId { + mainPeer = strongSelf.context.engine.data.get( + TelegramEngine.EngineData.Item.Peer.Peer(id: linkedMonoforumId) ) - ) - controller.peerSelected = strongSelf.peerSelected - strongSelf.push(controller) + } else { + mainPeer = .single(nil) + } + + let _ = (mainPeer |> deliverOnMainQueue).startStandalone(next: { [weak strongSelf] mainPeer in + guard let strongSelf else { + return + } + + let displayPeer = mainPeer ?? EnginePeer(peer) + + let controller = PeerSelectionControllerImpl( + PeerSelectionControllerParams( + context: strongSelf.context, + updatedPresentationData: nil, + filter: strongSelf.filter, + forumPeerId: (peer.id, peer.isMonoForum), + hasFilters: false, + hasChatListSelector: false, + hasContactSelector: false, + hasGlobalSearch: false, + title: displayPeer.compactDisplayTitle, + attemptSelection: strongSelf.attemptSelection, + createNewGroup: nil, + pretendPresentedInModal: false, + multipleSelection: false, + forwardedMessageIds: [], + hasTypeHeaders: false, + selectForumThreads: false + ) + ) + controller.peerSelected = strongSelf.peerSelected + strongSelf.push(controller) + }) } else { peerSelected(peer, threadId) } @@ -322,7 +339,7 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon context: strongSelf.context, updatedPresentationData: nil, filter: strongSelf.filter, - forumPeerId: peer.id, + forumPeerId: (peer.id, peer.isMonoForum), hasFilters: false, hasChatListSelector: false, hasContactSelector: false, diff --git a/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift b/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift index 4c035c1011..087b0199bf 100644 --- a/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift +++ b/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift @@ -33,7 +33,7 @@ final class PeerSelectionControllerNode: ASDisplayNode { private let presentInGlobalOverlay: (ViewController, Any?) -> Void private let dismiss: () -> Void private let filter: ChatListNodePeersFilter - private let forumPeerId: EnginePeer.Id? + private let forumPeerId: (id: EnginePeer.Id, isMonoforum: Bool)? private let hasGlobalSearch: Bool private let forwardedMessageIds: [EngineMessage.Id] private let hasTypeHeaders: Bool @@ -109,7 +109,7 @@ final class PeerSelectionControllerNode: ASDisplayNode { return (self.presentationData, self.presentationDataPromise.get()) } - init(context: AccountContext, controller: PeerSelectionControllerImpl, presentationData: PresentationData, filter: ChatListNodePeersFilter, forumPeerId: EnginePeer.Id?, hasFilters: Bool, hasChatListSelector: Bool, hasContactSelector: Bool, hasGlobalSearch: Bool, forwardedMessageIds: [EngineMessage.Id], hasTypeHeaders: Bool, requestPeerType: [ReplyMarkupButtonRequestPeerType]?, hasCreation: Bool, createNewGroup: (() -> Void)?, present: @escaping (ViewController, Any?) -> Void, presentInGlobalOverlay: @escaping (ViewController, Any?) -> Void, dismiss: @escaping () -> Void) { + init(context: AccountContext, controller: PeerSelectionControllerImpl, presentationData: PresentationData, filter: ChatListNodePeersFilter, forumPeerId: (id: EnginePeer.Id, isMonoforum: Bool)?, hasFilters: Bool, hasChatListSelector: Bool, hasContactSelector: Bool, hasGlobalSearch: Bool, forwardedMessageIds: [EngineMessage.Id], hasTypeHeaders: Bool, requestPeerType: [ReplyMarkupButtonRequestPeerType]?, hasCreation: Bool, createNewGroup: (() -> Void)?, present: @escaping (ViewController, Any?) -> Void, presentInGlobalOverlay: @escaping (ViewController, Any?) -> Void, dismiss: @escaping () -> Void) { self.context = context self.controller = controller self.present = present @@ -193,8 +193,12 @@ final class PeerSelectionControllerNode: ASDisplayNode { } let chatListLocation: ChatListControllerLocation - if let forumPeerId = self.forumPeerId { - chatListLocation = .forum(peerId: forumPeerId) + if let (forumPeerId, isMonoforum) = self.forumPeerId { + if isMonoforum { + chatListLocation = .savedMessagesChats(peerId: forumPeerId) + } else { + chatListLocation = .forum(peerId: forumPeerId) + } } else { chatListLocation = .chatList(groupId: .root) } @@ -248,12 +252,46 @@ final class PeerSelectionControllerNode: ASDisplayNode { } self.chatListNode?.peerSelected = { [weak self] peer, threadId, _, _, _ in - self?.chatListNode?.clearHighlightAnimated(true) - self?.requestOpenPeer?(peer, threadId) + guard let self else { + return + } + + if let (peerId, isMonoforum) = self.forumPeerId, isMonoforum { + let _ = (self.context.engine.data.get( + TelegramEngine.EngineData.Item.Peer.Peer(id: peerId) + ) + |> deliverOnMainQueue).startStandalone(next: { [weak self] mainPeer in + guard let self, let mainPeer else { + return + } + self.chatListNode?.clearHighlightAnimated(true) + self.requestOpenPeer?(mainPeer, peer.id.toInt64()) + }) + } else { + self.chatListNode?.clearHighlightAnimated(true) + self.requestOpenPeer?(peer, threadId) + } } self.mainContainerNode?.peerSelected = { [weak self] peer, threadId, _, _, _ in - self?.chatListNode?.clearHighlightAnimated(true) - self?.requestOpenPeer?(peer, threadId) + guard let self else { + return + } + + if let (peerId, isMonoforum) = self.forumPeerId, isMonoforum { + let _ = (self.context.engine.data.get( + TelegramEngine.EngineData.Item.Peer.Peer(id: peerId) + ) + |> deliverOnMainQueue).startStandalone(next: { [weak self] mainPeer in + guard let self, let mainPeer else { + return + } + self.chatListNode?.clearHighlightAnimated(true) + self.requestOpenPeer?(mainPeer, peer.id.toInt64()) + }) + } else { + self.chatListNode?.clearHighlightAnimated(true) + self.requestOpenPeer?(peer, threadId) + } } self.chatListNode?.disabledPeerSelected = { [weak self] peer, threadId, reason in @@ -718,7 +756,8 @@ final class PeerSelectionControllerNode: ASDisplayNode { canMakePaidContent: false, currentPrice: nil, hasTimers: false, - sendPaidMessageStars: nil + sendPaidMessageStars: nil, + isMonoforum: false )), hasEntityKeyboard: hasEntityKeyboard, gesture: gesture, @@ -1212,8 +1251,12 @@ final class PeerSelectionControllerNode: ASDisplayNode { self.mainContainerNode?.accessibilityElementsHidden = true let chatListLocation: ChatListControllerLocation - if let forumPeerId = self.forumPeerId { - chatListLocation = .forum(peerId: forumPeerId) + if let (forumPeerId, isMonoforum) = self.forumPeerId { + if isMonoforum { + chatListLocation = .savedMessagesChats(peerId: forumPeerId) + } else { + chatListLocation = .forum(peerId: forumPeerId) + } } else { chatListLocation = .chatList(groupId: EngineChatList.Group(.root)) } diff --git a/submodules/TelegramUI/Components/Settings/ThemeCarouselItem/Sources/ThemeCarouselItem.swift b/submodules/TelegramUI/Components/Settings/ThemeCarouselItem/Sources/ThemeCarouselItem.swift index b5340ad252..a34c56bc77 100644 --- a/submodules/TelegramUI/Components/Settings/ThemeCarouselItem/Sources/ThemeCarouselItem.swift +++ b/submodules/TelegramUI/Components/Settings/ThemeCarouselItem/Sources/ThemeCarouselItem.swift @@ -198,7 +198,7 @@ private func generateBorderImage(theme: PresentationTheme, bordered: Bool, selec } -private final class ThemeCarouselThemeItemIconNode : ListViewItemNode { +private final class ThemeCarouselThemeItemIconNode: ListViewItemNode { private let containerNode: ASDisplayNode private let emojiContainerNode: ASDisplayNode private let imageNode: TransformImageNode diff --git a/submodules/TelegramUI/Components/TextBadgeComponent/BUILD b/submodules/TelegramUI/Components/TextBadgeComponent/BUILD new file mode 100644 index 0000000000..1ddb36aac1 --- /dev/null +++ b/submodules/TelegramUI/Components/TextBadgeComponent/BUILD @@ -0,0 +1,19 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "TextBadgeComponent", + module_name = "TextBadgeComponent", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/Display", + "//submodules/ComponentFlow", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/TelegramUI/Components/TextBadgeComponent/Sources/TextBadgeComponent.swift b/submodules/TelegramUI/Components/TextBadgeComponent/Sources/TextBadgeComponent.swift new file mode 100644 index 0000000000..03476f4996 --- /dev/null +++ b/submodules/TelegramUI/Components/TextBadgeComponent/Sources/TextBadgeComponent.swift @@ -0,0 +1,171 @@ +import Foundation +import UIKit +import Display +import ComponentFlow + +public final class TextBadgeComponent: Component { + public let text: String + public let font: UIFont + public let background: UIColor + public let foreground: UIColor + public let insets: UIEdgeInsets + + public init( + text: String, + font: UIFont, + background: UIColor, + foreground: UIColor, + insets: UIEdgeInsets + ) { + self.text = text + self.font = font + self.background = background + self.foreground = foreground + self.insets = insets + } + + public static func ==(lhs: TextBadgeComponent, rhs: TextBadgeComponent) -> Bool { + if lhs.text != rhs.text { + return false + } + if lhs.font != rhs.font { + return false + } + if lhs.background != rhs.background { + return false + } + if lhs.foreground != rhs.foreground { + return false + } + if lhs.insets != rhs.insets { + return false + } + return true + } + + private struct TextLayout { + var size: CGSize + var opticalBounds: CGRect + + init(size: CGSize, opticalBounds: CGRect) { + self.size = size + self.opticalBounds = opticalBounds + } + } + + public final class View: UIView { + private let backgroundView: UIImageView + private let textContentsView: UIImageView + + private var textLayout: TextLayout? + + private var component: TextBadgeComponent? + + override public init(frame: CGRect) { + self.backgroundView = UIImageView() + + self.textContentsView = UIImageView() + self.textContentsView.layer.anchorPoint = CGPoint() + + super.init(frame: frame) + + self.addSubview(self.backgroundView) + self.addSubview(self.textContentsView) + } + + required public init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func update(component: TextBadgeComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + let previousComponent = self.component + self.component = component + + if component.text != previousComponent?.text || component.font != previousComponent?.font { + let attributedText = NSAttributedString(string: component.text, attributes: [ + NSAttributedString.Key.font: component.font, + NSAttributedString.Key.foregroundColor: UIColor.white + ]) + + var boundingRect = attributedText.boundingRect(with: availableSize, options: .usesLineFragmentOrigin, context: nil) + boundingRect.size.width = ceil(boundingRect.size.width) + boundingRect.size.height = ceil(boundingRect.size.height) + + if let context = DrawingContext(size: boundingRect.size, scale: 0.0, opaque: false, clear: true) { + context.withContext { c in + UIGraphicsPushContext(c) + defer { + UIGraphicsPopContext() + } + + attributedText.draw(at: CGPoint()) + } + var minFilledLineY = Int(context.scaledSize.height) - 1 + var maxFilledLineY = 0 + var minFilledLineX = Int(context.scaledSize.width) - 1 + var maxFilledLineX = 0 + for y in 0 ..< Int(context.scaledSize.height) { + let linePtr = context.bytes.advanced(by: max(0, y) * context.bytesPerRow).assumingMemoryBound(to: UInt32.self) + + for x in 0 ..< Int(context.scaledSize.width) { + let pixelPtr = linePtr.advanced(by: x) + if pixelPtr.pointee != 0 { + minFilledLineY = min(y, minFilledLineY) + maxFilledLineY = max(y, maxFilledLineY) + minFilledLineX = min(x, minFilledLineX) + maxFilledLineX = max(x, maxFilledLineX) + } + } + } + + var opticalBounds = CGRect() + if minFilledLineX <= maxFilledLineX && minFilledLineY <= maxFilledLineY { + opticalBounds.origin.x = CGFloat(minFilledLineX) / context.scale + opticalBounds.origin.y = CGFloat(minFilledLineY) / context.scale + opticalBounds.size.width = CGFloat(maxFilledLineX - minFilledLineX) / context.scale + opticalBounds.size.height = CGFloat(maxFilledLineY - minFilledLineY) / context.scale + } + + self.textContentsView.image = context.generateImage()?.withRenderingMode(.alwaysTemplate) + self.textLayout = TextLayout(size: boundingRect.size, opticalBounds: opticalBounds) + } else { + self.textLayout = TextLayout(size: boundingRect.size, opticalBounds: CGRect(origin: CGPoint(), size: boundingRect.size)) + } + } + + let textSize = self.textLayout?.size ?? CGSize(width: 1.0, height: 1.0) + + var size = CGSize(width: textSize.width + component.insets.left + component.insets.right, height: textSize.height + component.insets.top + component.insets.bottom) + size.width = max(size.width, size.height) + + let backgroundFrame = CGRect(origin: CGPoint(), size: size) + transition.setFrame(view: self.backgroundView, frame: backgroundFrame) + + let textFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) * 0.5), y: component.insets.top + UIScreenPixel), size: textSize) + /*if let textLayout = self.textLayout { + textFrame.origin.x = textLayout.opticalBounds.minX + floorToScreenPixels((backgroundFrame.width - textLayout.opticalBounds.width) * 0.5) + textFrame.origin.y = textLayout.opticalBounds.minY + floorToScreenPixels((backgroundFrame.height - textLayout.opticalBounds.height) * 0.5) + }*/ + + transition.setPosition(view: self.textContentsView, position: textFrame.origin) + self.textContentsView.bounds = CGRect(origin: CGPoint(), size: textFrame.size) + + if size.height != self.backgroundView.image?.size.height { + self.backgroundView.image = generateStretchableFilledCircleImage(diameter: size.height, color: .white)?.withRenderingMode(.alwaysTemplate) + } + + self.backgroundView.tintColor = component.background + self.textContentsView.tintColor = component.foreground + + return size + } + } + + public func makeView() -> View { + return View(frame: CGRect()) + } + + public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition) + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Empty Chat/ChannelMessages.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Empty Chat/ChannelMessages.imageset/Contents.json new file mode 100644 index 0000000000..b581188887 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Empty Chat/ChannelMessages.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "channelmessages (1).pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/Gift.imageset/gift_24.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Empty Chat/ChannelMessages.imageset/channelmessages (1).pdf similarity index 59% rename from submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/Gift.imageset/gift_24.pdf rename to submodules/TelegramUI/Images.xcassets/Chat/Empty Chat/ChannelMessages.imageset/channelmessages (1).pdf index 19e0e9d869..9de626dba3 100644 Binary files a/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/Gift.imageset/gift_24.pdf and b/submodules/TelegramUI/Images.xcassets/Chat/Empty Chat/ChannelMessages.imageset/channelmessages (1).pdf differ diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Info/PostSuggestionsIcon.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Info/ChannelMessages.imageset/Contents.json similarity index 75% rename from submodules/TelegramUI/Images.xcassets/Chat/Info/PostSuggestionsIcon.imageset/Contents.json rename to submodules/TelegramUI/Images.xcassets/Chat/Info/ChannelMessages.imageset/Contents.json index a88c7d45f3..97986c3294 100644 --- a/submodules/TelegramUI/Images.xcassets/Chat/Info/PostSuggestionsIcon.imageset/Contents.json +++ b/submodules/TelegramUI/Images.xcassets/Chat/Info/ChannelMessages.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "ic_discussion.pdf", + "filename" : "bubbles_30 (1).pdf", "idiom" : "universal" } ], diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Info/ChannelMessages.imageset/bubbles_30 (1).pdf b/submodules/TelegramUI/Images.xcassets/Chat/Info/ChannelMessages.imageset/bubbles_30 (1).pdf new file mode 100644 index 0000000000..8461becec8 Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chat/Info/ChannelMessages.imageset/bubbles_30 (1).pdf differ diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Info/PostSuggestionsIcon.imageset/ic_discussion.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Info/PostSuggestionsIcon.imageset/ic_discussion.pdf deleted file mode 100644 index ab7bf2f754..0000000000 Binary files a/submodules/TelegramUI/Images.xcassets/Chat/Info/PostSuggestionsIcon.imageset/ic_discussion.pdf and /dev/null differ diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/Gift.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/Gift.imageset/Contents.json index 977e80dac2..6bc0991ed8 100644 --- a/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/Gift.imageset/Contents.json +++ b/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/Gift.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "gift_24.pdf", + "filename" : "giftchannel_30.pdf", "idiom" : "universal" } ], diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/Gift.imageset/giftchannel_30.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/Gift.imageset/giftchannel_30.pdf new file mode 100644 index 0000000000..cda0618a24 Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/Gift.imageset/giftchannel_30.pdf differ diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/SuggestPost.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/SuggestPost.imageset/Contents.json index b4dafac96c..a14cd6ab89 100644 --- a/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/SuggestPost.imageset/Contents.json +++ b/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/SuggestPost.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "postsuggestionsbutton.pdf", + "filename" : "messagechannel_30.pdf", "idiom" : "universal" } ], diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/SuggestPost.imageset/postsuggestionsbutton.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/SuggestPost.imageset/messagechannel_30.pdf similarity index 59% rename from submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/SuggestPost.imageset/postsuggestionsbutton.pdf rename to submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/SuggestPost.imageset/messagechannel_30.pdf index 6adbed6a54..11747df3d2 100644 Binary files a/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/SuggestPost.imageset/postsuggestionsbutton.pdf and b/submodules/TelegramUI/Images.xcassets/Chat/Input/Accessory Panels/SuggestPost.imageset/messagechannel_30.pdf differ diff --git a/submodules/TelegramUI/Resources/Animations/ChannelMessages.tgs b/submodules/TelegramUI/Resources/Animations/ChannelMessages.tgs new file mode 100644 index 0000000000..3a0806e1ae Binary files /dev/null and b/submodules/TelegramUI/Resources/Animations/ChannelMessages.tgs differ diff --git a/submodules/TelegramUI/Resources/Animations/LampEmoji.tgs b/submodules/TelegramUI/Resources/Animations/LampEmoji.tgs deleted file mode 100644 index e3c35414ad..0000000000 Binary files a/submodules/TelegramUI/Resources/Animations/LampEmoji.tgs and /dev/null differ diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift index 8d12f0c738..3e64d87570 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift @@ -487,6 +487,11 @@ extension ChatControllerImpl { let initialInterfaceState = contentData.initialInterfaceState contentData.initialInterfaceState = nil + if !self.didInitializePersistentPeerInterfaceData, let initialPersistentPeerData = contentData.initialPersistentPeerData { + self.didInitializePersistentPeerInterfaceData = true + presentationInterfaceState = presentationInterfaceState.updatedPersistentData(initialPersistentPeerData) + } + presentationInterfaceState = presentationInterfaceState.updatedInterfaceState { interfaceState in var interfaceState = interfaceState if let initialInterfaceState { @@ -566,8 +571,6 @@ extension ChatControllerImpl { let initTimestamp = self.initTimestamp #endif - //TODO:release ready must include chat node - self.ready.set(combineLatest(queue: .mainQueue(), [ self.contentDataReady.get(), self.wallpaperReady.get(), @@ -1538,7 +1541,14 @@ extension ChatControllerImpl { completion(t, {}) }) strongSelf.updateItemNodesSearchTextHighlightStates() - strongSelf.chatDisplayNode.ensureInputViewFocused() + if !strongSelf.chatDisplayNode.ensureInputViewFocused() { + DispatchQueue.main.async { [weak self] in + guard let self else { + return + } + self.chatDisplayNode.ensureInputViewFocused() + } + } } else { completion(.immediate, {}) } @@ -4182,14 +4192,9 @@ extension ChatControllerImpl { return } self.updateChatPresentationInterfaceState(animated: true, interactive: true, { presentationInterfaceState in - let topicListDisplayMode: ChatPresentationInterfaceState.TopicListDisplayMode - switch presentationInterfaceState.topicListDisplayMode ?? .top { - case .top: - topicListDisplayMode = .side - case .side: - topicListDisplayMode = .top - } - return presentationInterfaceState.updatedTopicListDisplayMode(topicListDisplayMode) + var persistentData = presentationInterfaceState.persistentData + persistentData.topicListPanelLocation = !persistentData.topicListPanelLocation + return presentationInterfaceState.updatedPersistentData(persistentData) }) }, updateDisplayHistoryFilterAsList: { [weak self] displayAsList in guard let self else { diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerMediaRecording.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerMediaRecording.swift index 5bccd7f854..cb16ef2a24 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerMediaRecording.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerMediaRecording.swift @@ -366,7 +366,12 @@ extension ChatControllerImpl { let correlationId = Int64.random(in: 0 ..< Int64.max) var usedCorrelationId = false - if strongSelf.chatDisplayNode.shouldAnimateMessageTransition, let textInputPanelNode = strongSelf.chatDisplayNode.textInputPanelNode, let micButton = textInputPanelNode.micButton { + var shouldAnimateMessageTransition = strongSelf.chatDisplayNode.shouldAnimateMessageTransition + if strongSelf.chatLocation.threadId == nil, let channel = strongSelf.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = strongSelf.presentationInterfaceState.renderedPeer?.peers[linkedMonoforumId] as? TelegramChannel, mainChannel.hasPermission(.sendSomething) { + shouldAnimateMessageTransition = false + } + + if shouldAnimateMessageTransition, let textInputPanelNode = strongSelf.chatDisplayNode.textInputPanelNode, let micButton = textInputPanelNode.micButton { usedCorrelationId = true strongSelf.chatDisplayNode.messageTransitionNode.add(correlationId: correlationId, source: .audioMicInput(ChatMessageTransitionNodeImpl.Source.AudioMicInput(micButton: micButton)), initiated: { guard let strongSelf = self else { diff --git a/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift b/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift index 5ff4f37513..2f9a9a7201 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift @@ -430,6 +430,9 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch if message.minAutoremoveOrClearTimeout == viewOnceTimeout { canReplyInAnotherChat = false } + if let channel = message.peers[message.id.peerId] as? TelegramChannel, channel.isMonoForum { + canReplyInAnotherChat = false + } } if canReplyInAnotherChat { diff --git a/submodules/TelegramUI/Sources/Chat/ChatMessageDisplaySendMessageOptions.swift b/submodules/TelegramUI/Sources/Chat/ChatMessageDisplaySendMessageOptions.swift index aa4889525c..41a5182469 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatMessageDisplaySendMessageOptions.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatMessageDisplaySendMessageOptions.swift @@ -237,7 +237,8 @@ func chatMessageDisplaySendMessageOptions(selfController: ChatControllerImpl, no canMakePaidContent: false, currentPrice: nil, hasTimers: false, - sendPaidMessageStars: selfController.presentationInterfaceState.sendPaidMessageStars + sendPaidMessageStars: selfController.presentationInterfaceState.sendPaidMessageStars, + isMonoforum: selfController.presentationInterfaceState.renderedPeer?.peer?.isMonoForum ?? false )), hasEntityKeyboard: hasEntityKeyboard, gesture: gesture, diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 8d073cbc1a..ec5bd31af6 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -254,6 +254,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let contentDataReady = ValuePromise(false, ignoreRepeated: true) var contentDataDisposable: Disposable? var didHandlePerformDismissAction: Bool = false + var didInitializePersistentPeerInterfaceData: Bool = false var accountPeerDisposable: Disposable? @@ -6943,6 +6944,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = ChatInterfaceState.update(engine: self.context.engine, peerId: peerId, threadId: threadId, { _ in return interfaceState }).startStandalone() + + self.context.engine.peers.setPerstistentChatInterfaceState(peerId: peerId, state: CodableEntry(self.presentationInterfaceState.persistentData)) } override public func viewWillLeaveNavigation() { @@ -7835,8 +7838,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isMonoForum { attributes.removeAll(where: { $0 is SendAsMessageAttribute }) - if let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = self.presentationInterfaceState.renderedPeer?.peers[linkedMonoforumId] as? TelegramChannel, mainChannel.hasPermission(.sendSomething), let sendAsPeerId = self.presentationInterfaceState.currentSendAsPeerId { - attributes.append(SendAsMessageAttribute(peerId: sendAsPeerId)) + if let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = self.presentationInterfaceState.renderedPeer?.peers[linkedMonoforumId] as? TelegramChannel, mainChannel.hasPermission(.sendSomething) { + if let sendAsPeerId = self.presentationInterfaceState.currentSendAsPeerId { + attributes.append(SendAsMessageAttribute(peerId: sendAsPeerId)) + } else { + attributes.append(SendAsMessageAttribute(peerId: linkedMonoforumId)) + } } } if let sendAsPeerId = self.presentationInterfaceState.currentSendAsPeerId { diff --git a/submodules/TelegramUI/Sources/ChatControllerContentData.swift b/submodules/TelegramUI/Sources/ChatControllerContentData.swift index 3614bdb994..66080bef0a 100644 --- a/submodules/TelegramUI/Sources/ChatControllerContentData.swift +++ b/submodules/TelegramUI/Sources/ChatControllerContentData.swift @@ -174,6 +174,7 @@ extension ChatControllerImpl { private(set) var state: State = State() var initialInterfaceState: (interfaceState: ChatInterfaceState, editMessage: Message?)? var initialNavigationBadge: String? + var initialPersistentPeerData: ChatPresentationInterfaceState.PersistentPeerData? var overlayTitle: String? { var title: String? @@ -547,8 +548,7 @@ extension ChatControllerImpl { strongSelf.state.chatTitleContent = .custom(strings.Chat_TitlePinnedMessages(Int32(displayedCount ?? 1)), nil, false) } else if let channel = peer as? TelegramChannel, channel.isMonoForum { if let linkedMonoforumId = channel.linkedMonoforumId, let mainPeer = peerView.peers[linkedMonoforumId] { - //TODO:localize - strongSelf.state.chatTitleContent = .custom("\(mainPeer.debugDisplayTitle) Messages", nil, false) + strongSelf.state.chatTitleContent = .custom(mainPeer.debugDisplayTitle, "Direct messages", false) } else { strongSelf.state.chatTitleContent = .custom(channel.debugDisplayTitle, nil, false) } @@ -1447,11 +1447,25 @@ extension ChatControllerImpl { ) } + var currentSendAsPeerId: PeerId? + if let peer = peerView.peers[peerView.peerId] as? TelegramChannel, let cachedData = peerView.cachedData as? CachedChannelData { + if peer.isMonoForum { + if let linkedMonoforumId = peer.linkedMonoforumId, let mainChannel = peerView.peers[linkedMonoforumId] as? TelegramChannel, mainChannel.hasPermission(.sendSomething) { + currentSendAsPeerId = peer.linkedMonoforumId + } else { + currentSendAsPeerId = nil + } + } else { + currentSendAsPeerId = cachedData.sendAsPeerId + } + } + strongSelf.state.renderedPeer = renderedPeer strongSelf.state.savedMessagesTopicPeer = savedMessagesPeer?.peer strongSelf.state.hasSearchTags = hasSearchTags strongSelf.state.hasSavedChats = hasSavedChats strongSelf.state.hasScheduledMessages = hasScheduledMessages + strongSelf.state.currentSendAsPeerId = currentSendAsPeerId } else { let message = messageAndTopic.message @@ -1871,12 +1885,32 @@ extension ChatControllerImpl { strongSelf.onUpdated?(previousState) } + let initialPersistentPeerData: Signal + if let peerId = chatLocation.peerId { + initialPersistentPeerData = context.engine.peers.getPerstistentChatInterfaceState(peerId: peerId) + |> map { value in + return value?.get(ChatPresentationInterfaceState.PersistentPeerData.self) + } + } else { + initialPersistentPeerData = .single(nil) + } + let initialPersistentPeerDataReady = initialPersistentPeerData + |> deliverOnMainQueue + |> beforeNext { [weak self] value in + guard let self else { + return + } + self.initialPersistentPeerData = value + } + |> map { _ -> Bool in true } + self.isReady.set(combineLatest(queue: .mainQueue(), [ self.isPeerInfoReady.get(), self.isChatLocationInfoReady.get(), self.isCachedDataReady.get(), historyNode.isReady, - initialData |> map { _ -> Bool in true } + initialData |> map { _ -> Bool in true }, + initialPersistentPeerDataReady ]) |> map { values in return !values.contains(where: { !$0 }) diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 0d3d298a14..c65d45c690 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -1966,6 +1966,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { self.isLoadingEarlier = false let previousLoadingNode = self.loadingNode + self.backgroundNode.updateIsLooping(false) self.loadingNode = ChatLoadingNode(context: self.context, theme: self.chatPresentationInterfaceState.theme, chatWallpaper: self.chatPresentationInterfaceState.chatWallpaper, bubbleCorners: self.chatPresentationInterfaceState.bubbleCorners) self.loadingNode.frame = previousLoadingNode.frame self.loadingNode.isHidden = previousLoadingNode.isHidden @@ -3792,9 +3793,12 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { } } - func ensureInputViewFocused() { + @discardableResult func ensureInputViewFocused() -> Bool { if let inputPanelNode = self.inputPanelNode as? ChatTextInputPanelNode { inputPanelNode.ensureFocused() + return true + } else { + return false } } diff --git a/submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift b/submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift index a7115e2b14..ccd523a091 100644 --- a/submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift +++ b/submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift @@ -80,7 +80,7 @@ extension ChatControllerImpl { if let value = channel.hasBannedPermission(.banSendText, ignoreDefault: canByPassRestrictions) { banSendText = value } - if channel.hasBannedPermission(.banSendPolls, ignoreDefault: canByPassRestrictions) != nil { + if channel.hasBannedPermission(.banSendPolls, ignoreDefault: canByPassRestrictions) != nil || channel.isMonoForum { canSendPolls = false } } else if let group = peer as? TelegramGroup { @@ -764,7 +764,7 @@ extension ChatControllerImpl { if let value = channel.hasBannedPermission(.banSendMedia) { bannedSendMedia = value } - if channel.hasBannedPermission(.banSendPolls) != nil { + if channel.hasBannedPermission(.banSendPolls) != nil || channel.isMonoForum { canSendPolls = false } } else if let group = peer as? TelegramGroup { diff --git a/submodules/TelegramUI/Sources/ChatControllerOpenMessageShareMenu.swift b/submodules/TelegramUI/Sources/ChatControllerOpenMessageShareMenu.swift index ad379eadb4..a1eb16fc1c 100644 --- a/submodules/TelegramUI/Sources/ChatControllerOpenMessageShareMenu.swift +++ b/submodules/TelegramUI/Sources/ChatControllerOpenMessageShareMenu.swift @@ -169,7 +169,7 @@ extension ChatControllerImpl { let _ = (self.context.engine.data.get( EngineDataList( - peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init) + peerIds.map(TelegramEngine.EngineData.Item.Peer.RenderedPeer.init) ) ) |> deliverOnMainQueue).startStandalone(next: { [weak self] peerList in @@ -184,17 +184,17 @@ extension ChatControllerImpl { text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many savedMessages = true } else { - if peers.count == 1, let peer = peers.first { + if peers.count == 1, let peer = peers.first?.chatOrMonoforumMainPeer { var peerName = peer.id == self.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) peerName = peerName.replacingOccurrences(of: "**", with: "") text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string : presentationData.strings.Conversation_ForwardTooltip_Chat_Many(peerName).string - } else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last { + } else if peers.count == 2, let firstPeer = peers.first?.chatOrMonoforumMainPeer, let secondPeer = peers.last?.chatOrMonoforumMainPeer { var firstPeerName = firstPeer.id == self.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) firstPeerName = firstPeerName.replacingOccurrences(of: "**", with: "") var secondPeerName = secondPeer.id == self.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) secondPeerName = secondPeerName.replacingOccurrences(of: "**", with: "") text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string : presentationData.strings.Conversation_ForwardTooltip_TwoChats_Many(firstPeerName, secondPeerName).string - } else if let peer = peers.first { + } else if let peer = peers.first?.chatOrMonoforumMainPeer { var peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) peerName = peerName.replacingOccurrences(of: "**", with: "") text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string : presentationData.strings.Conversation_ForwardTooltip_ManyChats_Many(peerName, "\(peers.count - 1)").string diff --git a/submodules/TelegramUI/Sources/ChatInterfaceTitlePanelNodes.swift b/submodules/TelegramUI/Sources/ChatInterfaceTitlePanelNodes.swift index 1513f1b4fd..74b87fe086 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceTitlePanelNodes.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceTitlePanelNodes.swift @@ -231,8 +231,8 @@ func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceStat func titleTopicsPanelForChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: ChatTitleAccessoryPanelNode?, controllerInteraction: ChatControllerInteraction?, interfaceInteraction: ChatPanelInterfaceInteraction?, force: Bool) -> ChatTopicListTitleAccessoryPanelNode? { if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isForumOrMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = chatPresentationInterfaceState.renderedPeer?.peers[linkedMonoforumId] as? TelegramChannel, mainChannel.hasPermission(.sendSomething), chatPresentationInterfaceState.search == nil { - let topicListDisplayMode = chatPresentationInterfaceState.topicListDisplayMode ?? .top - if case .top = topicListDisplayMode, let peerId = chatPresentationInterfaceState.chatLocation.peerId { + let topicListDisplayModeOnTheSide = chatPresentationInterfaceState.persistentData.topicListPanelLocation + if !topicListDisplayModeOnTheSide, let peerId = chatPresentationInterfaceState.chatLocation.peerId { if let currentPanel = currentPanel as? ChatTopicListTitleAccessoryPanelNode { return currentPanel } else { @@ -242,8 +242,8 @@ func titleTopicsPanelForChatPresentationInterfaceState(_ chatPresentationInterfa } } } else if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isForum, (channel.flags.contains(.displayForumAsTabs) || context.sharedContext.immediateExperimentalUISettings.allForumsHaveTabs), chatPresentationInterfaceState.search == nil { - let topicListDisplayMode = chatPresentationInterfaceState.topicListDisplayMode ?? .top - if case .top = topicListDisplayMode, let peerId = chatPresentationInterfaceState.chatLocation.peerId { + let topicListDisplayModeOnTheSide = chatPresentationInterfaceState.persistentData.topicListPanelLocation + if !topicListDisplayModeOnTheSide, let peerId = chatPresentationInterfaceState.chatLocation.peerId { if let currentPanel = currentPanel as? ChatTopicListTitleAccessoryPanelNode { return currentPanel } else { @@ -263,17 +263,21 @@ func sidePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceState } if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = chatPresentationInterfaceState.renderedPeer?.peers[linkedMonoforumId] as? TelegramChannel, mainChannel.hasPermission(.sendSomething), chatPresentationInterfaceState.search == nil { - let topicListDisplayMode = chatPresentationInterfaceState.topicListDisplayMode ?? .top - if case .side = topicListDisplayMode { + let topicListDisplayModeOnTheSide = chatPresentationInterfaceState.persistentData.topicListPanelLocation + if topicListDisplayModeOnTheSide { return AnyComponentWithIdentity( id: "topics", component: AnyComponent(ChatSideTopicsPanel( context: context, theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings, + location: .side, peerId: peerId, isMonoforum: true, topicId: chatPresentationInterfaceState.chatLocation.threadId, + controller: { [weak interfaceInteraction] in + return interfaceInteraction?.chatController() + }, togglePanel: { [weak interfaceInteraction] in interfaceInteraction?.toggleChatSidebarMode() }, @@ -284,17 +288,21 @@ func sidePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceState ) } } else if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isForum, chatPresentationInterfaceState.search == nil { - let topicListDisplayMode = chatPresentationInterfaceState.topicListDisplayMode ?? .top - if case .side = topicListDisplayMode { + let topicListDisplayModeOnTheSide = chatPresentationInterfaceState.persistentData.topicListPanelLocation + if topicListDisplayModeOnTheSide { return AnyComponentWithIdentity( id: "topics", component: AnyComponent(ChatSideTopicsPanel( context: context, theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings, + location: .side, peerId: peerId, isMonoforum: false, topicId: chatPresentationInterfaceState.chatLocation.threadId, + controller: { [weak interfaceInteraction] in + return interfaceInteraction?.chatController() + }, togglePanel: { [weak interfaceInteraction] in interfaceInteraction?.toggleChatSidebarMode() }, diff --git a/submodules/TelegramUI/Sources/ChatTopicListTitleAccessoryPanelNode.swift b/submodules/TelegramUI/Sources/ChatTopicListTitleAccessoryPanelNode.swift index ed821174ce..fa55bbeddc 100644 --- a/submodules/TelegramUI/Sources/ChatTopicListTitleAccessoryPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTopicListTitleAccessoryPanelNode.swift @@ -14,173 +14,9 @@ import EmojiStatusComponent import SwiftSignalKit import BundleIconComponent import AvatarNode - -private final class CustomBadgeComponent: Component { - public let text: String - public let font: UIFont - public let background: UIColor - public let foreground: UIColor - public let insets: UIEdgeInsets - - public init( - text: String, - font: UIFont, - background: UIColor, - foreground: UIColor, - insets: UIEdgeInsets - ) { - self.text = text - self.font = font - self.background = background - self.foreground = foreground - self.insets = insets - } - - public static func ==(lhs: CustomBadgeComponent, rhs: CustomBadgeComponent) -> Bool { - if lhs.text != rhs.text { - return false - } - if lhs.font != rhs.font { - return false - } - if lhs.background != rhs.background { - return false - } - if lhs.foreground != rhs.foreground { - return false - } - if lhs.insets != rhs.insets { - return false - } - return true - } - - private struct TextLayout { - var size: CGSize - var opticalBounds: CGRect - - init(size: CGSize, opticalBounds: CGRect) { - self.size = size - self.opticalBounds = opticalBounds - } - } - - public final class View: UIView { - private let backgroundView: UIImageView - private let textContentsView: UIImageView - - private var textLayout: TextLayout? - - private var component: CustomBadgeComponent? - - override public init(frame: CGRect) { - self.backgroundView = UIImageView() - - self.textContentsView = UIImageView() - self.textContentsView.layer.anchorPoint = CGPoint() - - super.init(frame: frame) - - self.addSubview(self.backgroundView) - self.addSubview(self.textContentsView) - } - - required public init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - func update(component: CustomBadgeComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { - let previousComponent = self.component - self.component = component - - if component.text != previousComponent?.text || component.font != previousComponent?.font { - let attributedText = NSAttributedString(string: component.text, attributes: [ - NSAttributedString.Key.font: component.font, - NSAttributedString.Key.foregroundColor: UIColor.white - ]) - - var boundingRect = attributedText.boundingRect(with: availableSize, options: .usesLineFragmentOrigin, context: nil) - boundingRect.size.width = ceil(boundingRect.size.width) - boundingRect.size.height = ceil(boundingRect.size.height) - - if let context = DrawingContext(size: boundingRect.size, scale: 0.0, opaque: false, clear: true) { - context.withContext { c in - UIGraphicsPushContext(c) - defer { - UIGraphicsPopContext() - } - - attributedText.draw(at: CGPoint()) - } - var minFilledLineY = Int(context.scaledSize.height) - 1 - var maxFilledLineY = 0 - var minFilledLineX = Int(context.scaledSize.width) - 1 - var maxFilledLineX = 0 - for y in 0 ..< Int(context.scaledSize.height) { - let linePtr = context.bytes.advanced(by: max(0, y) * context.bytesPerRow).assumingMemoryBound(to: UInt32.self) - - for x in 0 ..< Int(context.scaledSize.width) { - let pixelPtr = linePtr.advanced(by: x) - if pixelPtr.pointee != 0 { - minFilledLineY = min(y, minFilledLineY) - maxFilledLineY = max(y, maxFilledLineY) - minFilledLineX = min(x, minFilledLineX) - maxFilledLineX = max(x, maxFilledLineX) - } - } - } - - var opticalBounds = CGRect() - if minFilledLineX <= maxFilledLineX && minFilledLineY <= maxFilledLineY { - opticalBounds.origin.x = CGFloat(minFilledLineX) / context.scale - opticalBounds.origin.y = CGFloat(minFilledLineY) / context.scale - opticalBounds.size.width = CGFloat(maxFilledLineX - minFilledLineX) / context.scale - opticalBounds.size.height = CGFloat(maxFilledLineY - minFilledLineY) / context.scale - } - - self.textContentsView.image = context.generateImage()?.withRenderingMode(.alwaysTemplate) - self.textLayout = TextLayout(size: boundingRect.size, opticalBounds: opticalBounds) - } else { - self.textLayout = TextLayout(size: boundingRect.size, opticalBounds: CGRect(origin: CGPoint(), size: boundingRect.size)) - } - } - - let textSize = self.textLayout?.size ?? CGSize(width: 1.0, height: 1.0) - - var size = CGSize(width: textSize.width + component.insets.left + component.insets.right, height: textSize.height + component.insets.top + component.insets.bottom) - size.width = max(size.width, size.height) - - let backgroundFrame = CGRect(origin: CGPoint(), size: size) - transition.setFrame(view: self.backgroundView, frame: backgroundFrame) - - let textFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) * 0.5), y: component.insets.top + UIScreenPixel), size: textSize) - /*if let textLayout = self.textLayout { - textFrame.origin.x = textLayout.opticalBounds.minX + floorToScreenPixels((backgroundFrame.width - textLayout.opticalBounds.width) * 0.5) - textFrame.origin.y = textLayout.opticalBounds.minY + floorToScreenPixels((backgroundFrame.height - textLayout.opticalBounds.height) * 0.5) - }*/ - - transition.setPosition(view: self.textContentsView, position: textFrame.origin) - self.textContentsView.bounds = CGRect(origin: CGPoint(), size: textFrame.size) - - if size.height != self.backgroundView.image?.size.height { - self.backgroundView.image = generateStretchableFilledCircleImage(diameter: size.height, color: .white)?.withRenderingMode(.alwaysTemplate) - } - - self.backgroundView.tintColor = component.background - self.textContentsView.tintColor = component.foreground - - return size - } - } - - public func makeView() -> View { - return View(frame: CGRect()) - } - - public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { - return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition) - } -} +import TextBadgeComponent +import ChatSideTopicsPanel +import ComponentDisplayAdapters final class ChatTopicListTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, ChatControllerCustomNavigationPanelNode { private struct Params: Equatable { @@ -213,601 +49,24 @@ final class ChatTopicListTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, C } } - private final class Item: Equatable { - typealias Id = EngineChatList.Item.Id - - let item: EngineChatList.Item - - var id: Id { - return self.item.id - } - - init(item: EngineChatList.Item) { - self.item = item - } - - public static func ==(lhs: Item, rhs: Item) -> Bool { - if lhs === rhs { - return true - } - if lhs.item != rhs.item { - return false - } - return true - } - } - - private final class ItemView: UIView { - private let context: AccountContext - private let action: () -> Void - - private let extractedContainerNode: ContextExtractedContentContainingNode - private let containerNode: ContextControllerSourceNode - - private let containerButton: HighlightTrackingButton - - private var icon: ComponentView? - private var avatarNode: AvatarNode? - private let title = ComponentView() - private var badge: ComponentView? - - init(context: AccountContext, action: @escaping (() -> Void), contextGesture: @escaping (ContextGesture, ContextExtractedContentContainingNode) -> Void) { - self.context = context - self.action = action - - self.extractedContainerNode = ContextExtractedContentContainingNode() - self.containerNode = ContextControllerSourceNode() - - self.containerButton = HighlightTrackingButton() - - super.init(frame: CGRect()) - - self.extractedContainerNode.contentNode.view.addSubview(self.containerButton) - - self.containerNode.addSubnode(self.extractedContainerNode) - self.containerNode.targetNodeForActivationProgress = self.extractedContainerNode.contentNode - self.addSubview(self.containerNode.view) - - self.containerButton.addTarget(self, action: #selector(self.pressed), for: .touchUpInside) - self.containerButton.highligthedChanged = { [weak self] highlighted in - if let self, self.bounds.width > 0.0 { - let topScale: CGFloat = (self.bounds.width - 1.0) / self.bounds.width - let maxScale: CGFloat = (self.bounds.width + 1.0) / self.bounds.width - - if highlighted { - self.layer.removeAnimation(forKey: "opacity") - self.layer.removeAnimation(forKey: "sublayerTransform") - let transition: ContainedViewLayoutTransition = .animated(duration: 0.2, curve: .easeInOut) - transition.updateTransformScale(layer: self.layer, scale: topScale) - } else { - let transition: ContainedViewLayoutTransition = .immediate - transition.updateTransformScale(layer: self.layer, scale: 1.0) - - self.layer.animateScale(from: topScale, to: maxScale, duration: 0.13, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in - guard let self else { - return - } - - self.layer.animateScale(from: maxScale, to: 1.0, duration: 0.1, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue) - }) - } - } - } - - self.containerNode.isGestureEnabled = false - } - - required init?(coder: NSCoder) { - preconditionFailure() - } - - @objc private func pressed() { - self.action() - } - - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - var mappedPoint = point - if self.bounds.insetBy(dx: -8.0, dy: -4.0).contains(point) { - mappedPoint = self.bounds.center - } - return super.hitTest(mappedPoint, with: event) - } - - func update(context: AccountContext, item: Item, isSelected: Bool, theme: PresentationTheme, height: CGFloat, transition: ComponentTransition) -> CGSize { - let alphaTransition: ComponentTransition = transition.animation.isImmediate ? .immediate : .easeInOut(duration: 0.25) - - let spacing: CGFloat = 3.0 - let badgeSpacing: CGFloat = 4.0 - - let iconSize = CGSize(width: 18.0, height: 18.0) - - var avatarIconContent: EmojiStatusComponent.Content? - if case let .forum(topicId) = item.item.id { - if topicId != 1, let threadData = item.item.threadData { - if let fileId = threadData.info.icon, fileId != 0 { - avatarIconContent = .animation(content: .customEmoji(fileId: fileId), size: iconSize, placeholderColor: theme.list.mediaPlaceholderColor, themeColor: theme.list.itemAccentColor, loopMode: .count(0)) - } else { - avatarIconContent = .topic(title: String(threadData.info.title.prefix(1)), color: threadData.info.iconColor, size: iconSize) - } - } else { - avatarIconContent = .image(image: PresentationResourcesChatList.generalTopicIcon(theme), tintColor: theme.rootController.navigationBar.secondaryTextColor) - } - } - - if let avatarIconContent { - let avatarIconComponent = EmojiStatusComponent( - context: context, - animationCache: context.animationCache, - animationRenderer: context.animationRenderer, - content: avatarIconContent, - isVisibleForAnimations: false, - action: nil - ) - let icon: ComponentView - if let current = self.icon { - icon = current - } else { - icon = ComponentView() - self.icon = icon - } - let _ = icon.update( - transition: .immediate, - component: AnyComponent(avatarIconComponent), - environment: {}, - containerSize: CGSize(width: 18.0, height: 18.0) - ) - } else if let icon = self.icon { - self.icon = nil - icon.view?.removeFromSuperview() - } - - let titleText: String - if case let .forum(topicId) = item.item.id { - let _ = topicId - if let threadData = item.item.threadData { - titleText = threadData.info.title - } else { - //TODO:localize - titleText = "General" - } - } else { - titleText = item.item.renderedPeer.chatMainPeer?.compactDisplayTitle ?? " " - } - let titleSize = self.title.update( - transition: .immediate, - component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: titleText, font: Font.medium(14.0), textColor: isSelected ? theme.rootController.navigationBar.accentTextColor : theme.rootController.navigationBar.secondaryTextColor)) - )), - environment: {}, - containerSize: CGSize(width: 100.0, height: 100.0) - ) - - var badgeSize: CGSize? - if let readCounters = item.item.readCounters, readCounters.count > 0 { - let badge: ComponentView - var badgeTransition = transition - if let current = self.badge { - badge = current - } else { - badgeTransition = .immediate - badge = ComponentView() - self.badge = badge - } - - badgeSize = badge.update( - transition: badgeTransition, - component: AnyComponent(CustomBadgeComponent( - text: "\(readCounters.count)", - font: Font.regular(12.0), - background: theme.list.itemCheckColors.fillColor, - foreground: theme.list.itemCheckColors.foregroundColor, - insets: UIEdgeInsets(top: 1.0, left: 5.0, bottom: 2.0, right: 5.0) - )), - environment: {}, - containerSize: CGSize(width: 100.0, height: 100.0) - ) - } - - var contentSize: CGFloat = iconSize.width + spacing + titleSize.width - if let badgeSize { - contentSize += badgeSpacing + badgeSize.width - } - - let size = CGSize(width: contentSize, height: height) - - let iconFrame = CGRect(origin: CGPoint(x: 0.0, y: 5.0 + floor((size.height - iconSize.height) * 0.5)), size: iconSize) - let titleFrame = CGRect(origin: CGPoint(x: iconFrame.maxX + spacing, y: 5.0 + floor((size.height - titleSize.height) * 0.5)), size: titleSize) - - if let icon = self.icon { - if let iconView = icon.view { - if iconView.superview == nil { - iconView.isUserInteractionEnabled = false - self.containerButton.addSubview(iconView) - } - iconView.frame = iconFrame - } - - if let avatarNode = self.avatarNode { - self.avatarNode = nil - avatarNode.view.removeFromSuperview() - } - } else { - let avatarNode: AvatarNode - if let current = self.avatarNode { - avatarNode = current - } else { - avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 7.0)) - self.avatarNode = avatarNode - self.containerButton.addSubview(avatarNode.view) - } - avatarNode.frame = iconFrame - avatarNode.updateSize(size: iconFrame.size) - - if let peer = item.item.renderedPeer.chatMainPeer { - if peer.smallProfileImage != nil { - avatarNode.setPeerV2(context: context, theme: theme, peer: peer, overrideImage: nil, emptyColor: .gray, clipStyle: .round, synchronousLoad: false, displayDimensions: iconFrame.size) - } else { - avatarNode.setPeer(context: context, theme: theme, peer: peer, overrideImage: nil, emptyColor: .gray, clipStyle: .round, synchronousLoad: false, displayDimensions: iconFrame.size) - } - } - } - - if let titleView = self.title.view { - if titleView.superview == nil { - titleView.isUserInteractionEnabled = false - self.containerButton.addSubview(titleView) - } - titleView.frame = titleFrame - } - - if let badgeSize, let badge = self.badge { - let badgeFrame = CGRect(origin: CGPoint(x: titleFrame.maxX + badgeSpacing, y: titleFrame.minY + floorToScreenPixels((titleFrame.height - badgeSize.height) * 0.5)), size: badgeSize) - - if let badgeView = badge.view { - if badgeView.superview == nil { - badgeView.isUserInteractionEnabled = false - self.containerButton.addSubview(badgeView) - badgeView.frame = badgeFrame - badgeView.alpha = 0.0 - } - transition.setPosition(view: badgeView, position: badgeFrame.center) - transition.setBounds(view: badgeView, bounds: CGRect(origin: CGPoint(), size: badgeFrame.size)) - transition.setScale(view: badgeView, scale: 1.0) - alphaTransition.setAlpha(view: badgeView, alpha: 1.0) - } - } else if let badge = self.badge { - self.badge = nil - if let badgeView = badge.view { - let badgeFrame = CGRect(origin: CGPoint(x: titleFrame.maxX + badgeSpacing, y: titleFrame.minX + floorToScreenPixels((titleFrame.height - badgeView.bounds.height) * 0.5)), size: badgeView.bounds.size) - transition.setPosition(view: badgeView, position: badgeFrame.center) - transition.setScale(view: badgeView, scale: 0.001) - alphaTransition.setAlpha(view: badgeView, alpha: 0.0, completion: { [weak badgeView] _ in - badgeView?.removeFromSuperview() - }) - } - } - - transition.setFrame(view: self.containerButton, frame: CGRect(origin: CGPoint(), size: size)) - - self.extractedContainerNode.frame = CGRect(origin: CGPoint(), size: size) - self.extractedContainerNode.contentNode.frame = CGRect(origin: CGPoint(), size: size) - self.extractedContainerNode.contentRect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height)) - self.containerNode.frame = CGRect(origin: CGPoint(), size: size) - - return size - } - } - - private final class TabItemView: UIView { - private let context: AccountContext - private let action: () -> Void - - private let extractedContainerNode: ContextExtractedContentContainingNode - private let containerNode: ContextControllerSourceNode - - private let containerButton: HighlightTrackingButton - - private let icon = ComponentView() - - init(context: AccountContext, action: @escaping (() -> Void)) { - self.context = context - self.action = action - - self.extractedContainerNode = ContextExtractedContentContainingNode() - self.containerNode = ContextControllerSourceNode() - - self.containerButton = HighlightTrackingButton() - - super.init(frame: CGRect()) - - self.extractedContainerNode.contentNode.view.addSubview(self.containerButton) - - self.containerNode.addSubnode(self.extractedContainerNode) - self.containerNode.targetNodeForActivationProgress = self.extractedContainerNode.contentNode - self.addSubview(self.containerNode.view) - - self.containerButton.addTarget(self, action: #selector(self.pressed), for: .touchUpInside) - self.containerButton.highligthedChanged = { [weak self] highlighted in - if let self, self.bounds.width > 0.0 { - let topScale: CGFloat = (self.bounds.width - 1.0) / self.bounds.width - let maxScale: CGFloat = (self.bounds.width + 1.0) / self.bounds.width - - if highlighted { - self.layer.removeAnimation(forKey: "opacity") - self.layer.removeAnimation(forKey: "sublayerTransform") - let transition: ContainedViewLayoutTransition = .animated(duration: 0.2, curve: .easeInOut) - transition.updateTransformScale(layer: self.layer, scale: topScale) - } else { - let transition: ContainedViewLayoutTransition = .immediate - transition.updateTransformScale(layer: self.layer, scale: 1.0) - - self.layer.animateScale(from: topScale, to: maxScale, duration: 0.13, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in - guard let self else { - return - } - - self.layer.animateScale(from: maxScale, to: 1.0, duration: 0.1, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue) - }) - } - } - } - - self.containerNode.isGestureEnabled = false - } - - required init?(coder: NSCoder) { - preconditionFailure() - } - - @objc private func pressed() { - self.action() - } - - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - var mappedPoint = point - if self.bounds.insetBy(dx: -8.0, dy: -4.0).contains(point) { - mappedPoint = self.bounds.center - } - return super.hitTest(mappedPoint, with: event) - } - - func update(context: AccountContext, theme: PresentationTheme, height: CGFloat, transition: ComponentTransition) -> CGSize { - let iconSize = self.icon.update( - transition: .immediate, - component: AnyComponent(BundleIconComponent( - name: "Chat/Title Panels/SidebarIcon", - tintColor: theme.rootController.navigationBar.secondaryTextColor, - maxSize: nil, - scaleFactor: 1.0 - )), - environment: {}, - containerSize: CGSize(width: 100.0, height: 100.0) - ) - - let contentSize: CGFloat = iconSize.width - let size = CGSize(width: contentSize, height: height) - - let iconFrame = CGRect(origin: CGPoint(x: 0.0, y: 5.0 + floor((size.height - iconSize.height) * 0.5)), size: iconSize) - - if let iconView = self.icon.view { - if iconView.superview == nil { - iconView.isUserInteractionEnabled = false - self.containerButton.addSubview(iconView) - } - iconView.frame = iconFrame - } - - transition.setFrame(view: self.containerButton, frame: CGRect(origin: CGPoint(), size: size)) - - self.extractedContainerNode.frame = CGRect(origin: CGPoint(), size: size) - self.extractedContainerNode.contentNode.frame = CGRect(origin: CGPoint(), size: size) - self.extractedContainerNode.contentRect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height)) - self.containerNode.frame = CGRect(origin: CGPoint(), size: size) - - return size - } - } - - private final class AllItemView: UIView { - private let context: AccountContext - private let action: () -> Void - - private let extractedContainerNode: ContextExtractedContentContainingNode - private let containerNode: ContextControllerSourceNode - - private let containerButton: HighlightTrackingButton - - private let title = ComponentView() - - init(context: AccountContext, action: @escaping (() -> Void)) { - self.context = context - self.action = action - - self.extractedContainerNode = ContextExtractedContentContainingNode() - self.containerNode = ContextControllerSourceNode() - - self.containerButton = HighlightTrackingButton() - - super.init(frame: CGRect()) - - self.extractedContainerNode.contentNode.view.addSubview(self.containerButton) - - self.containerNode.addSubnode(self.extractedContainerNode) - self.containerNode.targetNodeForActivationProgress = self.extractedContainerNode.contentNode - self.addSubview(self.containerNode.view) - - self.containerButton.addTarget(self, action: #selector(self.pressed), for: .touchUpInside) - self.containerButton.highligthedChanged = { [weak self] highlighted in - if let self, self.bounds.width > 0.0 { - let topScale: CGFloat = (self.bounds.width - 1.0) / self.bounds.width - let maxScale: CGFloat = (self.bounds.width + 1.0) / self.bounds.width - - if highlighted { - self.layer.removeAnimation(forKey: "opacity") - self.layer.removeAnimation(forKey: "sublayerTransform") - let transition: ContainedViewLayoutTransition = .animated(duration: 0.2, curve: .easeInOut) - transition.updateTransformScale(layer: self.layer, scale: topScale) - } else { - let transition: ContainedViewLayoutTransition = .immediate - transition.updateTransformScale(layer: self.layer, scale: 1.0) - - self.layer.animateScale(from: topScale, to: maxScale, duration: 0.13, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in - guard let self else { - return - } - - self.layer.animateScale(from: maxScale, to: 1.0, duration: 0.1, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue) - }) - } - } - } - - self.containerNode.isGestureEnabled = false - } - - required init?(coder: NSCoder) { - preconditionFailure() - } - - @objc private func pressed() { - self.action() - } - - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - var mappedPoint = point - if self.bounds.insetBy(dx: -8.0, dy: -4.0).contains(point) { - mappedPoint = self.bounds.center - } - return super.hitTest(mappedPoint, with: event) - } - - func update(context: AccountContext, isSelected: Bool, theme: PresentationTheme, height: CGFloat, transition: ComponentTransition) -> CGSize { - //TODO:localize - let titleText: String = "All" - let titleSize = self.title.update( - transition: .immediate, - component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: titleText, font: Font.medium(14.0), textColor: isSelected ? theme.rootController.navigationBar.accentTextColor : theme.rootController.navigationBar.secondaryTextColor)) - )), - environment: {}, - containerSize: CGSize(width: 100.0, height: 100.0) - ) - - let contentSize: CGFloat = titleSize.width - let size = CGSize(width: contentSize, height: height) - - let titleFrame = CGRect(origin: CGPoint(x: 0.0, y: 5.0 + floor((size.height - titleSize.height) * 0.5)), size: titleSize) - - if let titleView = self.title.view { - if titleView.superview == nil { - titleView.isUserInteractionEnabled = false - self.containerButton.addSubview(titleView) - } - titleView.frame = titleFrame - } - - transition.setFrame(view: self.containerButton, frame: CGRect(origin: CGPoint(), size: size)) - - self.extractedContainerNode.frame = CGRect(origin: CGPoint(), size: size) - self.extractedContainerNode.contentNode.frame = CGRect(origin: CGPoint(), size: size) - self.extractedContainerNode.contentRect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height)) - self.containerNode.frame = CGRect(origin: CGPoint(), size: size) - - return size - } - } - - private final class ScrollView: UIScrollView { - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - return super.hitTest(point, with: event) - } - - override func touchesShouldCancel(in view: UIView) -> Bool { - return true - } - } - - private enum ScrollId: Equatable { - case all - case topic(Int64) - } - - private let context: AccountContext - private let isMonoforum: Bool - - private let scrollView: ScrollView - private let scrollViewContainer: UIView - private let scrollViewMask: UIImageView - private var params: Params? - private var items: [Item] = [] - private var itemViews: [Item.Id: ItemView] = [:] - private var allItemView: AllItemView? - private var tabItemView: TabItemView? - private let selectedLineView: UIImageView - - private var itemsDisposable: Disposable? - - private var appliedScrollToId: ScrollId? + private let context: AccountContext + private let peerId: EnginePeer.Id + private let isMonoforum: Bool + private let panel = ComponentView() init(context: AccountContext, peerId: EnginePeer.Id, isMonoforum: Bool) { self.context = context + self.peerId = peerId self.isMonoforum = isMonoforum - self.selectedLineView = UIImageView() - - self.scrollView = ScrollView(frame: CGRect()) - self.scrollViewMask = UIImageView(image: generateGradientImage(size: CGSize(width: 8.0, height: 8.0), colors: [ - UIColor(white: 1.0, alpha: 0.0), - UIColor(white: 1.0, alpha: 1.0) - ], locations: [0.0, 1.0], direction: .horizontal)?.stretchableImage(withLeftCapWidth: 8, topCapHeight: 0)) - - self.scrollViewContainer = UIView() - super.init() - self.scrollView.delaysContentTouches = false - self.scrollView.canCancelContentTouches = true - self.scrollView.clipsToBounds = true - self.scrollView.contentInsetAdjustmentBehavior = .never - if #available(iOS 13.0, *) { - self.scrollView.automaticallyAdjustsScrollIndicatorInsets = false - } - self.scrollView.showsVerticalScrollIndicator = false - self.scrollView.showsHorizontalScrollIndicator = false - self.scrollView.alwaysBounceHorizontal = false - self.scrollView.alwaysBounceVertical = false - self.scrollView.scrollsToTop = false - self.scrollViewContainer.addSubview(self.scrollView) - self.scrollViewContainer.mask = self.scrollViewMask - - self.view.addSubview(self.scrollViewContainer) - - self.scrollView.addSubview(self.selectedLineView) - - self.scrollView.disablesInteractiveTransitionGestureRecognizer = true - - let threadListSignal: Signal = context.sharedContext.subscribeChatListData(context: context, location: isMonoforum ? .savedMessagesChats(peerId: peerId) : .forum(peerId: peerId)) - - self.itemsDisposable = (threadListSignal - |> deliverOnMainQueue).startStrict(next: { [weak self] chatList in - guard let self else { - return - } - self.items.removeAll() - - for item in chatList.items.reversed() { - self.items.append(Item(item: item)) - } - - self.update(transition: .immediate) - }) } deinit { - self.itemsDisposable?.dispose() } private func update(transition: ContainedViewLayoutTransition) { @@ -819,14 +78,6 @@ final class ChatTopicListTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, C override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> LayoutResult { let params = Params(width: width, leftInset: leftInset, rightInset: rightInset, interfaceState: interfaceState) if self.params != params { - if self.params?.interfaceState.theme !== params.interfaceState.theme { - self.selectedLineView.image = generateImage(CGSize(width: 7.0, height: 4.0), rotatedContext: { size, context in - context.clear(CGRect(origin: CGPoint(), size: size)) - context.setFillColor(params.interfaceState.theme.rootController.navigationBar.accentTextColor.cgColor) - context.fillEllipse(in: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: size.width))) - })?.stretchableImage(withLeftCapWidth: 4, topCapHeight: 1) - } - self.params = params self.update(params: params, transition: transition) } @@ -841,259 +92,65 @@ final class ChatTopicListTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, C } private func update(params: Params, transition: ContainedViewLayoutTransition) { - let hadItemViews = !self.itemViews.isEmpty - - var transition = transition - if !hadItemViews { - transition = .immediate - } - let panelHeight: CGFloat = 44.0 - let containerInsets = UIEdgeInsets(top: 0.0, left: params.leftInset + 16.0, bottom: 0.0, right: params.rightInset + 16.0) - let itemSpacing: CGFloat = 24.0 - - var leftContentInset: CGFloat = containerInsets.left + 8.0 - - do { - var itemTransition = transition - var animateIn = false - let itemView: TabItemView - if let current = self.tabItemView { - itemView = current - } else { - itemTransition = .immediate - animateIn = true - itemView = TabItemView(context: self.context, action: { [weak self] in + let panelFrame = CGRect(origin: CGPoint(), size: CGSize(width: params.width, height: panelHeight)) + let _ = self.panel.update( + transition: ComponentTransition(transition), + component: AnyComponent(ChatSideTopicsPanel( + context: self.context, + theme: params.interfaceState.theme, + strings: params.interfaceState.strings, + location: .top, + peerId: self.peerId, + isMonoforum: self.isMonoforum, + topicId: params.interfaceState.chatLocation.threadId, + controller: { [weak self] in + return self?.interfaceInteraction?.chatController() + }, + togglePanel: { [weak self] in guard let self else { return } self.interfaceInteraction?.toggleChatSidebarMode() - }) - self.tabItemView = itemView - self.view.addSubview(itemView) - } - - let itemSize = itemView.update(context: self.context, theme: params.interfaceState.theme, height: panelHeight, transition: .immediate) - let itemFrame = CGRect(origin: CGPoint(x: leftContentInset, y: -5.0), size: itemSize) - - itemTransition.updatePosition(layer: itemView.layer, position: itemFrame.center) - itemTransition.updateBounds(layer: itemView.layer, bounds: CGRect(origin: CGPoint(), size: itemFrame.size)) - - if animateIn && transition.isAnimated { - itemView.layer.animateAlpha(from: 0.0, to: itemView.alpha, duration: 0.15) - transition.animateTransformScale(view: itemView, from: 0.001) - } - - leftContentInset += itemSize.width + 8.0 - } - - var contentSize = CGSize(width: itemSpacing - 8.0, height: panelHeight) - - var validIds: [Item.Id] = [] - var isFirst = true - var selectedItemFrame: CGRect? - - do { - if isFirst { - isFirst = false - } else { - contentSize.width += itemSpacing - } - - var itemTransition = transition - var animateIn = false - let itemView: AllItemView - if let current = self.allItemView { - itemView = current - } else { - itemTransition = .immediate - animateIn = true - itemView = AllItemView(context: self.context, action: { [weak self] in + }, + updateTopicId: { [weak self] topicId, direction in guard let self else { return } - self.interfaceInteraction?.updateChatLocationThread(nil, .left) - }) - self.allItemView = itemView - self.scrollView.addSubview(itemView) - } - - var isSelected = false - if params.interfaceState.chatLocation.threadId == nil { - isSelected = true - } - let itemSize = itemView.update(context: self.context, isSelected: isSelected, theme: params.interfaceState.theme, height: panelHeight, transition: .immediate) - let itemFrame = CGRect(origin: CGPoint(x: contentSize.width, y: -5.0), size: itemSize) - - if isSelected { - selectedItemFrame = itemFrame - } - - itemTransition.updatePosition(layer: itemView.layer, position: itemFrame.center) - itemTransition.updateBounds(layer: itemView.layer, bounds: CGRect(origin: CGPoint(), size: itemFrame.size)) - - if animateIn && transition.isAnimated { - itemView.layer.animateAlpha(from: 0.0, to: itemView.alpha, duration: 0.15) - transition.animateTransformScale(view: itemView, from: 0.001) - } - - contentSize.width += itemSize.width - } - - for item in self.items { - if isFirst { - isFirst = false - } else { - contentSize.width += itemSpacing - } - let itemId = item.id - validIds.append(itemId) - - var itemTransition = transition - var animateIn = false - let itemView: ItemView - if let current = self.itemViews[itemId] { - itemView = current - } else { - itemTransition = .immediate - animateIn = true - let chatListItem = item.item - itemView = ItemView(context: self.context, action: { [weak self] in - guard let self else { - return - } - - let topicId: Int64 - if case let .forum(topicIdValue) = chatListItem.id { - topicId = topicIdValue - } else { - topicId = chatListItem.renderedPeer.peerId.toInt64() - } - - var direction = true - if let params = self.params, let lhsIndex = self.topicIndex(threadId: params.interfaceState.chatLocation.threadId), let rhsIndex = self.topicIndex(threadId: topicId) { - direction = lhsIndex < rhsIndex - } - self.interfaceInteraction?.updateChatLocationThread(topicId, direction ? .right : .left) - }, contextGesture: { gesture, sourceNode in - }) - self.itemViews[itemId] = itemView - self.scrollView.addSubview(itemView) - } - - var isSelected = false - if case let .forum(topicId) = item.item.id { - isSelected = params.interfaceState.chatLocation.threadId == topicId - } else { - isSelected = params.interfaceState.chatLocation.threadId == item.item.renderedPeer.peerId.toInt64() - } - let itemSize = itemView.update(context: self.context, item: item, isSelected: isSelected, theme: params.interfaceState.theme, height: panelHeight, transition: .immediate) - let itemFrame = CGRect(origin: CGPoint(x: contentSize.width, y: -5.0), size: itemSize) - - if isSelected { - selectedItemFrame = itemFrame - } - - itemTransition.updatePosition(layer: itemView.layer, position: itemFrame.center) - itemTransition.updateBounds(layer: itemView.layer, bounds: CGRect(origin: CGPoint(), size: itemFrame.size)) - - if animateIn && transition.isAnimated { - itemView.layer.animateAlpha(from: 0.0, to: itemView.alpha, duration: 0.15) - transition.animateTransformScale(view: itemView, from: 0.001) - } - - contentSize.width += itemSize.width - } - var removedIds: [Item.Id] = [] - for (id, itemView) in self.itemViews { - if !validIds.contains(id) { - removedIds.append(id) - - if transition.isAnimated { - itemView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.18, removeOnCompletion: false, completion: { [weak itemView] _ in - itemView?.removeFromSuperview() - }) - transition.updateTransformScale(layer: itemView.layer, scale: 0.001) - } else { - itemView.removeFromSuperview() } + )), + environment: { + ChatSidePanelEnvironment(insets: UIEdgeInsets( + top: 0.0, + left: params.leftInset, + bottom: 0.0, + right: params.rightInset + )) + }, + containerSize: panelFrame.size + ) + if let panelView = self.panel.view { + if panelView.superview == nil { + panelView.disablesInteractiveTransitionGestureRecognizer = true + self.view.addSubview(panelView) } - } - for id in removedIds { - self.itemViews.removeValue(forKey: id) - } - - if let selectedItemFrame { - let lineFrame = CGRect(origin: CGPoint(x: selectedItemFrame.minX, y: panelHeight - 4.0), size: CGSize(width: selectedItemFrame.width + 4.0, height: 4.0)) - if self.selectedLineView.isHidden { - self.selectedLineView.isHidden = false - self.selectedLineView.frame = lineFrame - } else { - transition.updateFrame(view: self.selectedLineView, frame: lineFrame) - } - } else { - self.selectedLineView.isHidden = true - } - - contentSize.width += containerInsets.right - - let scrollSize = CGSize(width: params.width - leftContentInset, height: contentSize.height) - self.scrollViewContainer.frame = CGRect(origin: CGPoint(x: leftContentInset, y: 0.0), size: scrollSize) - self.scrollViewMask.frame = CGRect(origin: CGPoint(), size: scrollSize) - - if self.scrollView.bounds.size != scrollSize { - self.scrollView.frame = CGRect(origin: CGPoint(), size: scrollSize) - } - if self.scrollView.contentSize != contentSize { - self.scrollView.contentSize = contentSize - } - - let scrollToId: ScrollId - if let threadId = params.interfaceState.chatLocation.threadId { - scrollToId = .topic(threadId) - } else { - scrollToId = .all - } - if self.appliedScrollToId != scrollToId { - if case let .topic(threadId) = scrollToId { - if let itemView = self.itemViews[.forum(threadId)] { - self.appliedScrollToId = scrollToId - self.scrollView.scrollRectToVisible(itemView.frame.insetBy(dx: -46.0, dy: 0.0), animated: hadItemViews) - } - } else if case .all = scrollToId { - self.appliedScrollToId = scrollToId - self.scrollView.scrollRectToVisible(CGRect(origin: CGPoint(), size: CGSize(width: 1.0, height: 1.0)), animated: hadItemViews) - } else { - self.appliedScrollToId = scrollToId - } + transition.updateFrame(view: panelView, frame: panelFrame) } } public func updateGlobalOffset(globalOffset: CGFloat, transition: ComponentTransition) { - if let tabItemView = self.tabItemView { - transition.setTransform(view: tabItemView, transform: CATransform3DMakeTranslation(0.0, -globalOffset, 0.0)) + if let panelView = self.panel.view as? ChatSideTopicsPanel.View { + panelView.updateGlobalOffset(globalOffset: globalOffset, transition: transition) } } public func topicIndex(threadId: Int64?) -> Int? { - if let threadId { - if let value = self.items.firstIndex(where: { item in - if item.id == .chatList(PeerId(threadId)) { - return true - } else if item.id == .forum(threadId) { - return true - } else { - return false - } - }) { - return value + 1 - } else { - return nil - } + if let panelView = self.panel.view as? ChatSideTopicsPanel.View { + return panelView.topicIndex(threadId: threadId) } else { - return 0 + return nil } } } diff --git a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift index dd14e47777..b05b3ca8eb 100644 --- a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift @@ -18,6 +18,7 @@ import PremiumUI import ChatControllerInteraction import ChatContextResultPeekContent import ChatInputContextPanelNode +import BatchVideoRendering private struct ChatContextResultStableId: Hashable { let result: ChatContextResult @@ -48,8 +49,8 @@ private struct HorizontalListContextResultsChatInputContextPanelEntry: Comparabl return lhs.index < rhs.index } - func item(context: AccountContext, resultSelected: @escaping (ChatContextResult, ASDisplayNode, CGRect) -> Bool) -> ListViewItem { - return HorizontalListContextResultsChatInputPanelItem(context: context, theme: self.theme, result: self.result, resultSelected: resultSelected) + func item(context: AccountContext, batchVideoContext: QueueLocalObject, resultSelected: @escaping (ChatContextResult, ASDisplayNode, CGRect) -> Bool) -> ListViewItem { + return HorizontalListContextResultsChatInputPanelItem(context: context, theme: self.theme, result: self.result, batchVideoContext: batchVideoContext, resultSelected: resultSelected) } } @@ -71,12 +72,12 @@ private final class HorizontalListContextResultsOpaqueState { } } -private func preparedTransition(from fromEntries: [HorizontalListContextResultsChatInputContextPanelEntry], to toEntries: [HorizontalListContextResultsChatInputContextPanelEntry], hasMore: Bool, context: AccountContext, resultSelected: @escaping (ChatContextResult, ASDisplayNode, CGRect) -> Bool) -> HorizontalListContextResultsChatInputContextPanelTransition { +private func preparedTransition(from fromEntries: [HorizontalListContextResultsChatInputContextPanelEntry], to toEntries: [HorizontalListContextResultsChatInputContextPanelEntry], hasMore: Bool, context: AccountContext, batchVideoContext: QueueLocalObject, resultSelected: @escaping (ChatContextResult, ASDisplayNode, CGRect) -> Bool) -> HorizontalListContextResultsChatInputContextPanelTransition { let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } - let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, resultSelected: resultSelected), directionHint: nil) } - let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, resultSelected: resultSelected), directionHint: nil) } + let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, batchVideoContext: batchVideoContext, resultSelected: resultSelected), directionHint: nil) } + let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, batchVideoContext: batchVideoContext, resultSelected: resultSelected), directionHint: nil) } return HorizontalListContextResultsChatInputContextPanelTransition(deletions: deletions, insertions: insertions, updates: updates, entryCount: toEntries.count, hasMore: hasMore) } @@ -93,6 +94,8 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont private var enqueuedTransitions: [(HorizontalListContextResultsChatInputContextPanelTransition, Bool)] = [] private var hasValidLayout = false + private let batchVideoContext: QueueLocalObject + override init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, fontSize: PresentationFontSize, chatPresentationContext: ChatPresentationContext) { self.separatorNode = ASDisplayNode() self.separatorNode.isLayerBacked = true @@ -108,6 +111,10 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont return strings.VoiceOver_ScrollStatus(row, count).string } + self.batchVideoContext = QueueLocalObject(queue: .mainQueue(), generate: { + return BatchVideoRenderingContext(context: context) + }) + super.init(context: context, theme: theme, strings: strings, fontSize: fontSize, chatPresentationContext: chatPresentationContext) self.isOpaque = false @@ -136,7 +143,7 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont self.listView.view.disablesInteractiveTransitionGestureRecognizer = true self.listView.view.disablesInteractiveKeyboardGestureRecognizer = true - self.view.addGestureRecognizer(PeekControllerGestureRecognizer(contentAtPoint: { [weak self] point in + self.view.addGestureRecognizer(PeekControllerGestureRecognizer(contentAtPoint: { [weak self] point -> Signal<(UIView, CGRect, PeekControllerContent)?, NoError>? in if let strongSelf = self { let convertedPoint = strongSelf.listView.view.convert(point, from: strongSelf.view) @@ -183,7 +190,7 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont let controller = PremiumIntroScreen(context: strongSelf.context, source: .stickers) strongSelf.interfaceInteraction?.getNavigationController()?.pushViewController(controller) })) - } else { + } else if let batchVideoContext = strongSelf.batchVideoContext.unsafeGet() { var menuItems: [ContextMenuItem] = [] if case let .internalReference(internalReference) = item.result, let file = internalReference.file, file.isAnimated { menuItems.append(.action(ContextMenuActionItem(text: strongSelf.strings.Preview_SaveGif, icon: { theme in @@ -229,7 +236,7 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont f(.default) let _ = item.resultSelected(item.result, itemNode, itemNode.bounds) }))) - selectedItemNodeAndContent = (itemNode.view, itemNode.bounds, ChatContextResultPeekContent(account: item.context.account, contextResult: item.result, menu: menuItems)) + selectedItemNodeAndContent = (itemNode.view, itemNode.bounds, ChatContextResultPeekContent(context: item.context, contextResult: item.result, menu: menuItems, batchVideoContext: batchVideoContext)) } } } @@ -312,7 +319,7 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont } let firstTime = self.currentEntries == nil - let transition = preparedTransition(from: self.currentEntries ?? [], to: entries, hasMore: results.nextOffset != nil, context: self.context, resultSelected: { [weak self] result, node, rect in + let transition = preparedTransition(from: self.currentEntries ?? [], to: entries, hasMore: results.nextOffset != nil, context: self.context, batchVideoContext: self.batchVideoContext, resultSelected: { [weak self] result, node, rect in if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction { return interfaceInteraction.sendContextResult(results, result, node, rect) } else { diff --git a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift index 94770716c2..4209c7fd69 100644 --- a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift @@ -15,20 +15,23 @@ import TelegramPresentationData import AccountContext import ShimmerEffect import SoftwareVideo -import MultiplexedVideoNode +import BatchVideoRendering +import GifVideoLayer final class HorizontalListContextResultsChatInputPanelItem: ListViewItem { let context: AccountContext let theme: PresentationTheme let result: ChatContextResult + let batchVideoContext: QueueLocalObject let resultSelected: (ChatContextResult, ASDisplayNode, CGRect) -> Bool let selectable: Bool = true - public init(context: AccountContext, theme: PresentationTheme, result: ChatContextResult, resultSelected: @escaping (ChatContextResult, ASDisplayNode, CGRect) -> Bool) { + public init(context: AccountContext, theme: PresentationTheme, result: ChatContextResult, batchVideoContext: QueueLocalObject, resultSelected: @escaping (ChatContextResult, ASDisplayNode, CGRect) -> Bool) { self.context = context self.theme = theme self.result = result + self.batchVideoContext = batchVideoContext self.resultSelected = resultSelected } @@ -90,7 +93,7 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode private let imageNode: TransformImageNode private var animationNode: AnimatedStickerNode? private var placeholderNode: StickerShimmerEffectNode? - private var videoLayer: (SoftwareVideoThumbnailNode, SoftwareVideoLayerFrameManager, SampleBufferLayer)? + private var videoLayer: GifVideoLayer? private var currentImageResource: TelegramMediaResource? private var currentVideoFile: TelegramMediaFile? private var currentAnimatedStickerFile: TelegramMediaFile? @@ -103,58 +106,17 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode override var visibility: ListViewItemNodeVisibility { didSet { - switch visibility { - case .visible: - self.ticking = true - default: - self.ticking = false + switch self.visibility { + case .visible: + self.videoLayer?.shouldBeAnimating = true + case .none: + self.videoLayer?.shouldBeAnimating = false } } } private let timebase: CMTimebase - private var displayLink: CADisplayLink? - private var ticking: Bool = false { - didSet { - if self.ticking != oldValue { - if self.ticking { - class DisplayLinkProxy: NSObject { - weak var target: HorizontalListContextResultsChatInputPanelItemNode? - init(target: HorizontalListContextResultsChatInputPanelItemNode) { - self.target = target - } - - @objc func displayLinkEvent() { - self.target?.displayLinkEvent() - } - } - - let displayLink = CADisplayLink(target: DisplayLinkProxy(target: self), selector: #selector(DisplayLinkProxy.displayLinkEvent)) - self.displayLink = displayLink - displayLink.add(to: RunLoop.main, forMode: .common) - if #available(iOS 10.0, *) { - displayLink.preferredFramesPerSecond = 25 - } else { - displayLink.frameInterval = 2 - } - displayLink.isPaused = false - CMTimebaseSetRate(self.timebase, rate: 1.0) - } else if let displayLink = self.displayLink { - self.displayLink = nil - displayLink.isPaused = true - displayLink.invalidate() - CMTimebaseSetRate(self.timebase, rate: 0.0) - } - } - } - } - - private func displayLinkEvent() { - let timestamp = CMTimebaseGetTime(self.timebase).seconds - self.videoLayer?.1.tick(timestamp: timestamp) - } - init() { self.imageNodeBackground = ASDisplayNode() self.imageNodeBackground.isLayerBacked = true @@ -197,10 +159,6 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode } deinit { - if let displayLink = self.displayLink { - displayLink.isPaused = true - displayLink.invalidate() - } self.statusDisposable.dispose() self.fetchDisposable.dispose() } @@ -384,30 +342,25 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode } if updatedVideoFile { - if let (thumbnailLayer, _, layer) = strongSelf.videoLayer { + if let videoLayer = strongSelf.videoLayer { strongSelf.videoLayer = nil - thumbnailLayer.removeFromSupernode() - layer.layer.removeFromSuperlayer() + videoLayer.removeFromSuperlayer() } - if let videoFile = videoFile { - let thumbnailLayer = SoftwareVideoThumbnailNode(account: item.context.account, fileReference: .standalone(media: videoFile), synchronousLoad: synchronousLoads) - thumbnailLayer.transform = CATransform3DMakeRotation(CGFloat.pi / 2.0, 0.0, 0.0, 1.0) - strongSelf.addSubnode(thumbnailLayer) - let layerHolder = takeSampleBufferLayer() - layerHolder.layer.videoGravity = AVLayerVideoGravity.resizeAspectFill - layerHolder.layer.transform = CATransform3DMakeRotation(CGFloat.pi / 2.0, 0.0, 0.0, 1.0) - strongSelf.layer.addSublayer(layerHolder.layer) + if let videoFile, let batchVideoContext = item.batchVideoContext.unsafeGet() { + let videoLayer = GifVideoLayer( + context: item.context, + batchVideoContext: batchVideoContext, + userLocation: .other, + file: .standalone(media: videoFile), + synchronousLoad: synchronousLoads + ) + videoLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill + videoLayer.transform = CATransform3DMakeRotation(CGFloat.pi / 2.0, 0.0, 0.0, 1.0) + strongSelf.layer.addSublayer(videoLayer) - let manager = SoftwareVideoLayerFrameManager(account: item.context.account, userLocation: .other, userContentType: .other, fileReference: .standalone(media: videoFile), layerHolder: layerHolder) - strongSelf.videoLayer = (thumbnailLayer, manager, layerHolder) - thumbnailLayer.ready = { [weak thumbnailLayer, weak manager] in - if let strongSelf = self, let thumbnailLayer = thumbnailLayer, let manager = manager { - if strongSelf.videoLayer?.0 === thumbnailLayer && strongSelf.videoLayer?.1 === manager { - manager.start() - } - } - } + strongSelf.videoLayer = videoLayer + videoLayer.shouldBeAnimating = strongSelf.visibility != .none } } @@ -477,11 +430,9 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode strongSelf.statusNode.transitionToState(.none, completion: { }) } - if let (thumbnailLayer, _, layer) = strongSelf.videoLayer { - thumbnailLayer.bounds = CGRect(origin: CGPoint(), size: CGSize(width: croppedImageDimensions.width, height: croppedImageDimensions.height)) - thumbnailLayer.position = CGPoint(x: height / 2.0, y: (nodeLayout.contentSize.height - sideInset) / 2.0 + sideInset) - layer.layer.bounds = CGRect(origin: CGPoint(), size: CGSize(width: croppedImageDimensions.width, height: croppedImageDimensions.height)) - layer.layer.position = CGPoint(x: height / 2.0, y: (nodeLayout.contentSize.height - sideInset) / 2.0 + sideInset) + if let videoLayer = strongSelf.videoLayer { + videoLayer.bounds = CGRect(origin: CGPoint(), size: CGSize(width: croppedImageDimensions.width, height: croppedImageDimensions.height)) + videoLayer.position = CGPoint(x: height / 2.0, y: (nodeLayout.contentSize.height - sideInset) / 2.0 + sideInset) } if let animationNode = strongSelf.animationNode { diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index 3d85b276be..dfdf148d15 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -85,6 +85,7 @@ import GiftStoreScreen import SendInviteLinkScreen import PostSuggestionsSettingsScreen import ForumSettingsScreen +import ForumCreateTopicScreen private final class AccountUserInterfaceInUseContext { let subscribers = Bag<(Bool) -> Void>() @@ -2609,6 +2610,25 @@ public final class SharedAccountContextImpl: SharedAccountContext { } } + public func makeEditForumTopicScreen(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64, threadInfo: EngineMessageHistoryThread.Info, isHidden: Bool) -> ViewController { + let controller = ForumCreateTopicScreen(context: context, peerId: peerId, mode: .edit(threadId: threadId, threadInfo: threadInfo, isHidden: isHidden)) + controller.navigationPresentation = .modal + controller.completion = { [weak controller] title, fileId, _, isHidden in + let _ = (context.engine.peers.editForumChannelTopic(id: peerId, threadId: threadId, title: title, iconFileId: fileId) + |> deliverOnMainQueue).startStandalone(completed: { + controller?.dismiss() + }) + + if let isHidden { + let _ = (context.engine.peers.setForumChannelTopicHidden(id: peerId, threadId: threadId, isHidden: isHidden) + |> deliverOnMainQueue).startStandalone(completed: { + controller?.dismiss() + }) + } + } + return controller + } + private func mapIntroSource(source: PremiumIntroSource) -> PremiumSource { let mappedSource: PremiumSource switch source { diff --git a/third-party/td/td b/third-party/td/td index f1b7500310..e894536b2f 160000 --- a/third-party/td/td +++ b/third-party/td/td @@ -1 +1 @@ -Subproject commit f1b7500310baa496c0b779e4273a3aff0f14f42f +Subproject commit e894536b2f46caad93f997448d2daff9431b19dd