From 4fdbe44825e34bd419be03fc79c87007ab64d72b Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Fri, 30 May 2025 21:08:32 +0800 Subject: [PATCH 1/4] Various improvements --- .../Telegram-iOS/en.lproj/Localizable.strings | 3 +- .../Display/Source/TransformImageNode.swift | 59 +++++++++++++++---- .../MediaPlayer/Sources/MediaPlayerNode.swift | 2 +- .../ChatMessageInteractiveMediaNode.swift | 13 ++-- .../Sources/ChatSideTopicsPanel.swift | 2 +- .../ChatTitleView/Sources/ChatTitleView.swift | 2 + ...ChatControllerNavigationButtonAction.swift | 29 +++++---- .../Sources/ChatControllerContentData.swift | 4 +- .../Sources/ChatControllerNode.swift | 12 +--- .../Sources/ChatHistoryListNode.swift | 12 +++- .../ChatInterfaceStateContextMenus.swift | 6 +- .../Sources/NativeVideoContent.swift | 22 +++++-- 12 files changed, 116 insertions(+), 50 deletions(-) diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index dc8c198c7e..deffdc64bd 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -14383,7 +14383,7 @@ Sorry for the inconvenience."; "ChannelMessages.PriceSectionTitle" = "PRICE FOR EACH MESSAGE"; "ChannelMessages.PriceSectionFooter" = "You will receive 85% of the selected fee for each incoming message."; -"ChatList.MonoforumLabel" = "MESSAGES"; +"ChatList.MonoforumLabel" = "DIRECT"; "ChatList.MonoforumEmptyText" = "No messages here yet..."; "Chat.InlineTopicMenu.Reorder" = "Reorder"; @@ -14400,6 +14400,7 @@ Sorry for the inconvenience."; "Chat.EmptyStateMonoforum.Text" = "Send a direct message to the administrator of **%@**."; "Chat.EmptyStateMonoforumPaid.Text" = "**%1$@** charges **%2$@**\nper message to its admin."; +"Chat.Monoforum.Subtitle" = "Direct messages"; "Monoforum.NameFormat" = "%@ Messages"; diff --git a/submodules/Display/Source/TransformImageNode.swift b/submodules/Display/Source/TransformImageNode.swift index 4e06c3ab48..5d17ee0b23 100644 --- a/submodules/Display/Source/TransformImageNode.swift +++ b/submodules/Display/Source/TransformImageNode.swift @@ -97,22 +97,14 @@ open class TransformImageNode: ASDisplayNode { self.disposable.set((result |> deliverOnMainQueue).start(next: { [weak self] next in let apply: () -> Void = { if let strongSelf = self { + var animateFromContents: Any? + if strongSelf.contents == nil { if strongSelf.contentAnimations.contains(.firstUpdate) && !attemptSynchronously { strongSelf.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15) } } else if strongSelf.contentAnimations.contains(.subsequentUpdates) { - let tempLayer = CALayer() - if strongSelf.captureProtected { - setLayerDisableScreenshots(tempLayer, strongSelf.captureProtected) - } - tempLayer.frame = strongSelf.bounds - tempLayer.contentsGravity = strongSelf.layer.contentsGravity - tempLayer.contents = strongSelf.contents - strongSelf.layer.addSublayer(tempLayer) - tempLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false, completion: { [weak tempLayer] _ in - tempLayer?.removeFromSuperlayer() - }) + animateFromContents = strongSelf.contents } var imageUpdate: UIImage? @@ -129,6 +121,23 @@ open class TransformImageNode: ASDisplayNode { if let imageUpdated = strongSelf.imageUpdated { imageUpdated(imageUpdate) } + + if let animateFromContents { + let transition: ContainedViewLayoutTransition = .animated(duration: 0.2, curve: .linear) + transition.animateContents(layer: strongSelf.layer, from: animateFromContents) + + /*let tempLayer = CALayer() + if strongSelf.captureProtected { + setLayerDisableScreenshots(tempLayer, strongSelf.captureProtected) + } + tempLayer.frame = strongSelf.bounds + tempLayer.contentsGravity = strongSelf.layer.contentsGravity + tempLayer.contents = animateFromContents + strongSelf.layer.addSublayer(tempLayer) + tempLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false, completion: { [weak tempLayer] _ in + tempLayer?.removeFromSuperlayer() + })*/ + } } } if dispatchOnDisplayLink && !attemptSynchronously { @@ -168,6 +177,34 @@ open class TransformImageNode: ASDisplayNode { } } + public func asyncLayoutWithAnimation() -> (TransformImageArguments) -> ((ListViewItemUpdateAnimation) -> Void) { + let currentTransform = self.currentTransform + let currentArguments = self.currentArguments + return { [weak self] arguments in + let updatedImage: UIImage? + + if currentArguments != arguments { + updatedImage = currentTransform?(arguments)?.generateImage() + } else { + updatedImage = nil + } + return { animation in + guard let self else { + return + } + if let image = updatedImage { + self.contents = image.cgImage + self.image = image + self.currentArguments = arguments + if let _ = self.overlayColor { + self.applyOverlayColor(animated: false) + } + } + self.argumentsPromise.set(arguments) + } + } + } + public class func asyncLayout(_ maybeNode: TransformImageNode?) -> (TransformImageArguments) -> (() -> TransformImageNode) { return { arguments in let node: TransformImageNode diff --git a/submodules/MediaPlayer/Sources/MediaPlayerNode.swift b/submodules/MediaPlayer/Sources/MediaPlayerNode.swift index 7b1273f115..c8b563b5b8 100644 --- a/submodules/MediaPlayer/Sources/MediaPlayerNode.swift +++ b/submodules/MediaPlayer/Sources/MediaPlayerNode.swift @@ -402,7 +402,7 @@ public final class MediaPlayerNode: ASDisplayNode { } } - private func updateLayout() { + public func updateLayout() { let bounds = self.bounds if bounds.isEmpty { return diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageInteractiveMediaNode/Sources/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageInteractiveMediaNode/Sources/ChatMessageInteractiveMediaNode.swift index 3938669792..1bbecf6485 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageInteractiveMediaNode/Sources/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageInteractiveMediaNode/Sources/ChatMessageInteractiveMediaNode.swift @@ -858,7 +858,7 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr public func asyncLayout() -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ dateTimeFormat: PresentationDateTimeFormat, _ message: Message, _ associatedData: ChatMessageItemAssociatedData, _ attributes: ChatMessageEntryAttributes, _ media: Media, _ mediaIndex: Int?, _ dateAndStatus: ChatMessageDateAndStatus?, _ automaticDownload: InteractiveMediaNodeAutodownloadMode, _ peerType: MediaAutoDownloadPeerType, _ peerId: EnginePeer.Id?, _ sizeCalculation: InteractiveMediaNodeSizeCalculation, _ layoutConstants: ChatMessageItemLayoutConstants, _ contentMode: InteractiveMediaNodeContentMode, _ presentationContext: ChatPresentationContext) -> (CGSize, CGFloat, (CGSize, Bool, Bool, ImageCorners) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool) -> Void))) { let currentMessage = self.message let currentMedia = self.media - let imageLayout = self.imageNode.asyncLayout() + let imageLayout = self.imageNode.asyncLayoutWithAnimation() let statusLayout = self.dateAndStatusNode.asyncLayout() let currentVideoNode = self.videoNode @@ -1894,7 +1894,7 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr timestampMaskView.image = strongSelf.generateTimestampMaskImage(corners: arguments.corners) } strongSelf.currentImageArguments = arguments - imageApply() + imageApply(transition) if let statusApply = statusApply { let dateAndStatusFrame = CGRect(origin: CGPoint(x: cleanImageFrame.width - layoutConstants.image.statusInsets.right - statusSize.width, y: cleanImageFrame.height - layoutConstants.image.statusInsets.bottom - statusSize.height), size: statusSize) @@ -2084,8 +2084,13 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr strongSelf.imageNode.cornerRadius = 0.0 } - videoNode.updateLayout(size: arguments.drawingSize, transition: .immediate) - videoNode.frame = CGRect(origin: CGPoint(), size: imageFrame.size) + if videoNode.bounds.isEmpty { + videoNode.updateLayout(size: arguments.drawingSize, transition: .immediate) + videoNode.frame = CGRect(origin: CGPoint(), size: imageFrame.size) + } else { + videoNode.updateLayout(size: arguments.drawingSize, transition: transition.transition) + transition.animator.updateFrame(layer: videoNode.layer, frame: CGRect(origin: CGPoint(), size: imageFrame.size), completion: nil) + } if strongSelf.visibility && strongSelf.internallyVisible && !presentationData.isPreview { if !videoNode.canAttachContent { diff --git a/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift b/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift index a686733ac9..1c2ecc3235 100644 --- a/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift +++ b/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift @@ -1359,7 +1359,7 @@ public final class ChatSideTopicsPanel: Component { maximumNumberOfLines: 2 )), environment: {}, - containerSize: CGSize(width: 200.0, height: 200.0) + containerSize: CGSize(width: 400.0, height: 200.0) ) let contentSize: CGFloat = leftInset + rightInset + titleSize.height diff --git a/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleView.swift b/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleView.swift index 5a8b4b2d42..6141c84cfd 100644 --- a/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleView.swift +++ b/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleView.swift @@ -68,6 +68,8 @@ public enum ChatTitleContent: Equatable { return false } if lhs.peerPresences.count != rhs.peerPresences.count { + return false + } else { for (key, value) in lhs.peerPresences { if let rhsValue = rhs.peerPresences[key] { if !value.isEqual(to: rhsValue) { diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerNavigationButtonAction.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerNavigationButtonAction.swift index 332aa07e15..4cdf6e8435 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerNavigationButtonAction.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerNavigationButtonAction.swift @@ -397,21 +397,30 @@ extension ChatControllerImpl { self.navigationActionDisposable.set((peerView.get() |> take(1) |> deliverOnMainQueue).startStrict(next: { [weak self] peerView in - if let strongSelf = self, let peer = peerView.peers[peerView.peerId], peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil && !strongSelf.presentationInterfaceState.isNotAccessible { - - if peer.id == strongSelf.context.account.peerId { - if let peer = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer, let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: true, requestsContext: nil) { - strongSelf.effectiveNavigationController?.pushViewController(infoController) + guard let self else { + return + } + guard var peer = peerView.peers[peerView.peerId] else { + return + } + if let channel = peer as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainPeer = peerView.peers[linkedMonoforumId] { + peer = mainPeer + } + + if peer.restrictionText(platform: "ios", contentSettings: self.context.currentContentSettings.with { $0 }) == nil && !self.presentationInterfaceState.isNotAccessible { + if peer.id == self.context.account.peerId { + if let peer = self.presentationInterfaceState.renderedPeer?.chatMainPeer, let infoController = self.context.sharedContext.makePeerInfoController(context: self.context, updatedPresentationData: self.updatedPresentationData, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: true, requestsContext: nil) { + self.effectiveNavigationController?.pushViewController(infoController) } } else { var expandAvatar = expandAvatar if peer.smallProfileImage == nil { expandAvatar = false } - if let validLayout = strongSelf.validLayout, validLayout.deviceMetrics.type == .tablet { + if let validLayout = self.validLayout, validLayout.deviceMetrics.type == .tablet { expandAvatar = false } - let mode: PeerInfoControllerMode + let mode: PeerInfoControllerMode switch section { case .groupsInCommon: mode = .groupsInCommon @@ -420,12 +429,12 @@ extension ChatControllerImpl { default: mode = .generic } - if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, mode: mode, avatarInitiallyExpanded: expandAvatar, fromChat: true, requestsContext: strongSelf.contentData?.inviteRequestsContext) { - strongSelf.effectiveNavigationController?.pushViewController(infoController) + if let infoController = self.context.sharedContext.makePeerInfoController(context: self.context, updatedPresentationData: self.updatedPresentationData, peer: peer, mode: mode, avatarInitiallyExpanded: expandAvatar, fromChat: true, requestsContext: self.contentData?.inviteRequestsContext) { + self.effectiveNavigationController?.pushViewController(infoController) } } - let _ = strongSelf.dismissPreviewing?(false) + let _ = self.dismissPreviewing?(false) } })) case .replyThread: diff --git a/submodules/TelegramUI/Sources/ChatControllerContentData.swift b/submodules/TelegramUI/Sources/ChatControllerContentData.swift index 66080bef0a..55d1f8ff3f 100644 --- a/submodules/TelegramUI/Sources/ChatControllerContentData.swift +++ b/submodules/TelegramUI/Sources/ChatControllerContentData.swift @@ -548,9 +548,9 @@ 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] { - strongSelf.state.chatTitleContent = .custom(mainPeer.debugDisplayTitle, "Direct messages", false) + strongSelf.state.chatTitleContent = .custom(mainPeer.debugDisplayTitle, strings.Chat_Monoforum_Subtitle, true) } else { - strongSelf.state.chatTitleContent = .custom(channel.debugDisplayTitle, nil, false) + strongSelf.state.chatTitleContent = .custom(channel.debugDisplayTitle, nil, true) } } else { strongSelf.state.chatTitleContent = .peer(peerView: ChatTitleContent.PeerData(peerView: peerView), customTitle: nil, onlineMemberCount: onlineMemberCount, isScheduledMessages: isScheduledMessages, isMuted: nil, customMessageCount: nil, isEnabled: hasPeerInfo) diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 0769d003c6..397195770e 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -2552,17 +2552,9 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { if self.leftPanel != nil || dismissedLeftPanel != nil { titleTopicsAccessoryPanelNode.updateGlobalOffset(globalOffset: -titleTopicsAccessoryPanelFrame.height, transition: .immediate) } - - let topPanelTransition = ComponentTransition(transition) - /*switch topPanelTransition.animation { - case let .curve(duration, _): - topPanelTransition = topPanelTransition.withAnimation(.curve(duration: duration, curve: ComponentTransition.Animation.Curve(ChatMessageTransitionNodeImpl.verticalAnimationCurve))) - default: - break - }*/ - topPanelTransition.setFrame(view: titleTopicsAccessoryPanelNode.view, frame: titleTopicsAccessoryPanelFrame) - titleTopicsAccessoryPanelNode.updateGlobalOffset(globalOffset: 0.0, transition: topPanelTransition) + ComponentTransition(transition).setFrame(view: titleTopicsAccessoryPanelNode.view, frame: titleTopicsAccessoryPanelFrame) + titleTopicsAccessoryPanelNode.updateGlobalOffset(globalOffset: 0.0, transition: ComponentTransition(transition)) } else { let previousFrame = titleTopicsAccessoryPanelNode.frame titleTopicsAccessoryPanelNode.frame = titleTopicsAccessoryPanelFrame diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index 57c3f0e91e..6b3cff7b36 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -681,6 +681,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto private var loadedMessagesFromCachedDataDisposable: Disposable? + private var isSettingTopReplyThreadMessageShown: Bool = false let isTopReplyThreadMessageShown = ValuePromise(false, ignoreRepeated: true) private var topVisibleMessageRangeValueInitialized: Bool = false @@ -3178,8 +3179,15 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto } } - - self.isTopReplyThreadMessageShown.set(isTopReplyThreadMessageShownValue) + if !self.isSettingTopReplyThreadMessageShown { + self.isSettingTopReplyThreadMessageShown = true + self.isTopReplyThreadMessageShown.set(isTopReplyThreadMessageShownValue) + self.isSettingTopReplyThreadMessageShown = false + } else { + #if DEBUG + print("Ignore repeated isTopReplyThreadMessageShown update") + #endif + } self.updateTopVisibleMessageRange(topVisibleMessageRange) let _ = self.visibleMessageRange.swap(topVisibleMessageRange.flatMap { range in return VisibleMessageRange(lowerBound: range.lowerBound, upperBound: range.upperBound) diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index e7e6d16bc3..a0e51dbbc2 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -1591,7 +1591,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState } } - if let message = messages.first, message.id.namespace == Namespaces.Message.Cloud, let channel = message.peers[message.id.peerId] as? TelegramChannel, !(message.media.first is TelegramMediaAction), !isReplyThreadHead, !isMigrated { + if let message = messages.first, message.id.namespace == Namespaces.Message.Cloud, let channel = message.peers[message.id.peerId] as? TelegramChannel, !channel.isMonoForum, !(message.media.first is TelegramMediaAction), !isReplyThreadHead, !isMigrated { actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuCopyLink, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Link"), color: theme.actionSheet.primaryTextColor) }, action: { _, f in @@ -1893,8 +1893,8 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState var canViewStats = false var canViewAuthor = false - if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isMonoForum { - if message.effectivelyIncoming(context.account.peerId) { + if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isMonoForum, let associatedPeerId = channel.associatedPeerId { + if message.effectivelyIncoming(context.account.peerId), message.author?.id == associatedPeerId { canViewAuthor = true } } else if let messageReadStatsAreHidden = infoSummaryData.messageReadStatsAreHidden, !messageReadStatsAreHidden { diff --git a/submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift b/submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift index e8b67bd497..d4c389c80f 100644 --- a/submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift +++ b/submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift @@ -690,22 +690,34 @@ private final class NativeVideoContentNode: ASDisplayNode, UniversalVideoContent if let dimensions = self.dimensions { let imageSize = CGSize(width: floor(dimensions.width / 2.0), height: floor(dimensions.height / 2.0)) - let makeLayout = self.imageNode.asyncLayout() + let makeLayout = self.imageNode.asyncLayoutWithAnimation() let applyLayout = makeLayout(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets(), emptyColor: self.fileReference.media.isInstantVideo ? .clear : self.placeholderColor)) - applyLayout() + let mappedAnimation: ListViewItemUpdateAnimation + if case let .animated(duration, curve) = transition { + mappedAnimation = .System(duration: duration, transition: ControlledTransition(duration: duration, curve: curve, interactive: false)) + } else { + mappedAnimation = .None + } + applyLayout(mappedAnimation) } transition.updateFrame(node: self.imageNode, frame: CGRect(origin: CGPoint(), size: size)) let fromFrame = self.playerNode.frame let toFrame = CGRect(origin: CGPoint(), size: size).insetBy(dx: -1.0, dy: -1.0) if case let .animated(duration, curve) = transition, fromFrame != toFrame, !fromFrame.width.isZero, !fromFrame.height.isZero, !toFrame.width.isZero, !toFrame.height.isZero { - self.playerNode.frame = toFrame - transition.animatePosition(node: self.playerNode, from: CGPoint(x: fromFrame.center.x - toFrame.center.x, y: fromFrame.center.y - toFrame.center.y)) + let _ = duration + let _ = curve + self.playerNode.position = toFrame.center + self.playerNode.bounds = CGRect(origin: CGPoint(), size: toFrame.size) + self.playerNode.updateLayout() + transition.animatePosition(node: self.playerNode, from: CGPoint(x: fromFrame.center.x, y: fromFrame.center.y)) let transform = CATransform3DScale(CATransform3DIdentity, fromFrame.width / toFrame.width, fromFrame.height / toFrame.height, 1.0) self.playerNode.layer.animate(from: NSValue(caTransform3D: transform), to: NSValue(caTransform3D: CATransform3DIdentity), keyPath: "transform", timingFunction: curve.timingFunction, duration: duration) } else { - transition.updateFrame(node: self.playerNode, frame: toFrame) + transition.updatePosition(node: self.playerNode, position: toFrame.center) + transition.updateBounds(node: self.playerNode, bounds: CGRect(origin: CGPoint(), size: toFrame.size)) + self.playerNode.updateLayout() } if let thumbnailNode = self.thumbnailNode { transition.updateFrame(node: thumbnailNode, frame: CGRect(origin: CGPoint(), size: size).insetBy(dx: -1.0, dy: -1.0)) From d9a2d0627092c77c1aeb89da99cdb0da7813cd3e Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Fri, 30 May 2025 23:06:26 +0800 Subject: [PATCH 2/4] Various improvements --- .../Telegram-iOS/en.lproj/Localizable.strings | 2 + .../Postbox/Sources/MessageHistoryView.swift | 99 ++++++++++++++++++- .../Sources/MessageHistoryViewState.swift | 3 + .../Sources/MessagePriceItem.swift | 3 +- 4 files changed, 103 insertions(+), 4 deletions(-) diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index deffdc64bd..90d84f161d 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -14410,3 +14410,5 @@ Sorry for the inconvenience."; "Stars.SendMessage.AdjustmentSectionFooterValue" = "You will receive **%@ Stars**."; "Stars.SendMessage.AdjustmentSectionFooterEmpty" = "You will receive **80%**."; "Stars.SendMessage.AdjustmentAction" = "OK"; + +"Stars.SendMessage.PriceFree" = "Free"; diff --git a/submodules/Postbox/Sources/MessageHistoryView.swift b/submodules/Postbox/Sources/MessageHistoryView.swift index 94b0a438a5..b35d8366c3 100644 --- a/submodules/Postbox/Sources/MessageHistoryView.swift +++ b/submodules/Postbox/Sources/MessageHistoryView.swift @@ -313,6 +313,7 @@ final class MutableMessageHistoryView: MutablePostboxView { private let clipHoles: Bool private let trackHoles: Bool private let anchor: HistoryViewInputAnchor + fileprivate var mapReadStatesFromThreads: Bool = false fileprivate var combinedReadStates: MessageHistoryViewReadState? fileprivate var transientReadStates: MessageHistoryViewReadState? @@ -322,6 +323,7 @@ final class MutableMessageHistoryView: MutablePostboxView { fileprivate var topTaggedMessages: [MessageId.Namespace: MessageHistoryTopTaggedMessage?] fileprivate var additionalDatas: [AdditionalMessageHistoryViewDataEntry] + fileprivate var threadMaxOutgoingReadId: [Int64: Int32] = [:] fileprivate(set) var sampledState: HistoryViewSample @@ -373,8 +375,14 @@ final class MutableMessageHistoryView: MutablePostboxView { switch peerIds { case let .associated(peerId, _): self.isAddedToChatList = postbox.chatListTable.getPeerChatListIndex(peerId: peerId) != nil - case let .single(peerId, _): + case let .single(peerId, threadId): self.isAddedToChatList = postbox.chatListTable.getPeerChatListIndex(peerId: peerId) != nil + if threadId == nil, let peer = postbox.peerTable.get(peerId) { + let value = postbox.seedConfiguration.peerSummaryIsThreadBased(peer, peer.associatedPeerId.flatMap(postbox.peerTable.get)) + if value.value && value.threadsArePeers { + self.mapReadStatesFromThreads = true + } + } case let .external(input): switch input.content { case let .thread(peerId, _, _): @@ -401,6 +409,8 @@ final class MutableMessageHistoryView: MutablePostboxView { self.render(postbox: postbox) let _ = self.updateStoryStats(postbox: postbox) + + let _ = self.updateThreadInfos(postbox: postbox, updatedIds: nil) } private func reset(postbox: PostboxImpl) { @@ -1023,9 +1033,81 @@ final class MutableMessageHistoryView: MutablePostboxView { } } + if !transaction.updatedPeerThreadInfos.isEmpty { + if self.updateThreadInfos(postbox: postbox, updatedIds: transaction.updatedPeerThreadInfos) { + hasChanges = true + } + } + return hasChanges } + private func updateThreadInfos(postbox: PostboxImpl, updatedIds: Set?) -> Bool { + if self.mapReadStatesFromThreads, case let .single(peerId, peerThreadId) = self.peerIds, peerThreadId == nil { + switch self.sampledState { + case .loading: + if !self.threadMaxOutgoingReadId.isEmpty { + self.threadMaxOutgoingReadId.removeAll() + return true + } else { + return false + } + case let .loaded(loaded): + //TODO:release + let currentIds = Set(self.threadMaxOutgoingReadId.keys) + + var threadIds: Set = [] + for entry in loaded.entries { + if let threadId = entry.message.threadId { + threadIds.insert(threadId) + } + } + + var updated = false + if currentIds != threadIds { + updated = true + + for id in currentIds.subtracting(threadIds) { + self.threadMaxOutgoingReadId.removeValue(forKey: id) + } + } + + for threadId in threadIds { + var fetch = false + if let updatedIds { + if updatedIds.contains(MessageHistoryThreadsTable.ItemId(peerId: peerId, threadId: threadId)) { + fetch = true + } + } else { + fetch = self.threadMaxOutgoingReadId[threadId] == nil + } + + if fetch { + var maxOutgoingReadId: Int32? + if let threadData = postbox.messageHistoryThreadIndexTable.get(peerId: peerId, threadId: threadId) { + maxOutgoingReadId = threadData.summary.maxOutgoingReadId + } + + let current = self.threadMaxOutgoingReadId[threadId] + if let maxOutgoingReadId { + if current != maxOutgoingReadId { + self.threadMaxOutgoingReadId[threadId] = maxOutgoingReadId + updated = true + } + } else if current != nil { + self.threadMaxOutgoingReadId.removeValue(forKey: threadId) + updated = true + } + } + } + + return updated + } + } else { + return false + } + } + private func render(postbox: PostboxImpl) { for namespace in self.topTaggedMessages.keys { if let entry = self.topTaggedMessages[namespace]!, case let .intermediate(message) = entry { @@ -1166,7 +1248,20 @@ public final class MessageHistoryView: PostboxView { } self.isLoadingEarlier = isLoadingEarlier entries = [] - if let transientReadStates = mutableView.transientReadStates, case let .peer(states) = transientReadStates { + if mutableView.mapReadStatesFromThreads { + for entry in state.entries { + if mutableView.namespaces.contains(entry.message.id.namespace) { + var read = false + if let threadId = entry.message.threadId { + if let maxId = mutableView.threadMaxOutgoingReadId[threadId] { + read = entry.message.id.id <= maxId + } + } + + entries.append(MessageHistoryEntry(message: entry.message, isRead: read, location: entry.location, monthLocation: entry.monthLocation, attributes: entry.attributes)) + } + } + } else if let transientReadStates = mutableView.transientReadStates, case let .peer(states) = transientReadStates { for entry in state.entries { if mutableView.namespaces.contains(entry.message.id.namespace) { let read: Bool diff --git a/submodules/Postbox/Sources/MessageHistoryViewState.swift b/submodules/Postbox/Sources/MessageHistoryViewState.swift index 02a4cf1532..7b665d1152 100644 --- a/submodules/Postbox/Sources/MessageHistoryViewState.swift +++ b/submodules/Postbox/Sources/MessageHistoryViewState.swift @@ -1308,6 +1308,7 @@ final class HistoryViewLoadedState { let halfLimit: Int let seedConfiguration: SeedConfiguration var orderedEntriesBySpace: [PeerIdAndNamespace: OrderedHistoryViewEntries] + var threadSummaries: [Int64: Int32] var holes: HistoryViewHoles var spacesWithRemovals = Set() @@ -1321,6 +1322,7 @@ final class HistoryViewLoadedState { self.halfLimit = halfLimit self.seedConfiguration = postbox.seedConfiguration self.orderedEntriesBySpace = [:] + self.threadSummaries = [:] self.holes = holes var peerIds: [PeerId] = [] @@ -1854,6 +1856,7 @@ final class HistoryViewLoadedState { var holesToLower = false var holesToHigher = false var result: [MessageHistoryMessageEntry] = [] + if combinedSpacesAndIndicesByDirection.lowerOrAtAnchor.isEmpty && combinedSpacesAndIndicesByDirection.higherThanAnchor.isEmpty { if !clipRanges.isEmpty { holesToLower = true diff --git a/submodules/TelegramUI/Components/PeerInfo/MessagePriceItem/Sources/MessagePriceItem.swift b/submodules/TelegramUI/Components/PeerInfo/MessagePriceItem/Sources/MessagePriceItem.swift index d907298c7e..a51864febf 100644 --- a/submodules/TelegramUI/Components/PeerInfo/MessagePriceItem/Sources/MessagePriceItem.swift +++ b/submodules/TelegramUI/Components/PeerInfo/MessagePriceItem/Sources/MessagePriceItem.swift @@ -368,8 +368,7 @@ private class MessagePriceItemNode: ListViewItemNode { strongSelf.leftTextNode.attributedText = NSAttributedString(string: "\(item.minValue)", font: Font.regular(13.0), textColor: item.theme.list.itemSecondaryTextColor) strongSelf.rightTextNode.attributedText = NSAttributedString(string: "\(item.maxValue)", font: Font.regular(13.0), textColor: item.theme.list.itemSecondaryTextColor) - //TODO:localize - let centralLeftText = item.value == 0 ? "Free" : item.strings.Privacy_Messages_Stars(Int32(item.value)) + let centralLeftText = item.value == 0 ? item.strings.Stars_SendMessage_PriceFree : item.strings.Privacy_Messages_Stars(Int32(item.value)) strongSelf.centerLeftTextNode.attributedText = NSAttributedString(string: centralLeftText, font: textFont, textColor: item.openSetCustom != nil ? item.theme.list.itemAccentColor : item.theme.list.itemPrimaryTextColor) strongSelf.centerRightTextNode.attributedText = NSAttributedString(string: item.price, font: smallTextFont, textColor: item.openSetCustom != nil ? item.theme.list.itemAccentColor.withMultipliedAlpha(0.5) : item.theme.list.itemSecondaryTextColor) From 5b2a54163b5f223c8b6362edb8a3436342bd29e7 Mon Sep 17 00:00:00 2001 From: Mikhail Filimonov Date: Tue, 3 Jun 2025 11:55:11 +0100 Subject: [PATCH 3/4] todo peerIds --- .../Sources/SyncCore/SyncCore_TelegramMediaTodo.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaTodo.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaTodo.swift index 7c7109f6d1..e7a98d613e 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaTodo.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaTodo.swift @@ -69,7 +69,7 @@ public final class TelegramMediaTodo: Media, Equatable { return nil } public var peerIds: [PeerId] { - return [] + return completions.map(\.completedBy) } public let flags: Flags From 1dd07df394592ca56be43b49b25810dd2487d7a9 Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Fri, 6 Jun 2025 00:51:05 +0800 Subject: [PATCH 4/4] Update API --- submodules/TelegramApi/Sources/Api0.swift | 7 +- submodules/TelegramApi/Sources/Api15.swift | 74 +++++++++++++------ submodules/TelegramApi/Sources/Api24.swift | 22 ++++-- submodules/TelegramApi/Sources/Api34.swift | 38 ++++++---- submodules/TelegramApi/Sources/Api38.swift | 49 ++++++------ .../ApiUtils/StoreMessage_Telegram.swift | 17 +++-- .../ApiUtils/TelegramMediaAction.swift | 3 + .../Sources/State/ApplyUpdateMessage.swift | 2 +- .../Sources/State/PaidMessages.swift | 5 +- .../Sources/State/UpdatesApiUtils.swift | 8 +- .../TelegramEngine/Messages/AdMessages.swift | 13 +++- .../Sources/ServiceMessageStrings.swift | 5 ++ 12 files changed, 159 insertions(+), 84 deletions(-) diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index be04611d4f..644cb83ce5 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -559,7 +559,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-808853502] = { return Api.MediaAreaCoordinates.parse_mediaAreaCoordinates($0) } dict[-356721331] = { return Api.Message.parse_message($0) } dict[-1868117372] = { return Api.Message.parse_messageEmpty($0) } - dict[-741178048] = { return Api.Message.parse_messageService($0) } + dict[2055212554] = { return Api.Message.parse_messageService($0) } dict[-872240531] = { return Api.MessageAction.parse_messageActionBoostApply($0) } dict[-988359047] = { return Api.MessageAction.parse_messageActionBotAllowed($0) } dict[-1781355374] = { return Api.MessageAction.parse_messageActionChannelCreate($0) } @@ -607,6 +607,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[1192749220] = { return Api.MessageAction.parse_messageActionStarGift($0) } dict[775611918] = { return Api.MessageAction.parse_messageActionStarGiftUnique($0) } dict[1474192222] = { return Api.MessageAction.parse_messageActionSuggestProfilePhoto($0) } + dict[-940721021] = { return Api.MessageAction.parse_messageActionTodoAppendTasks($0) } dict[-864265079] = { return Api.MessageAction.parse_messageActionTodoCompletions($0) } dict[228168278] = { return Api.MessageAction.parse_messageActionTopicCreate($0) } dict[-1064024032] = { return Api.MessageAction.parse_messageActionTopicEdit($0) } @@ -938,7 +939,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-651419003] = { return Api.SendMessageAction.parse_speakingInGroupCallAction($0) } dict[-1239335713] = { return Api.ShippingOption.parse_shippingOption($0) } dict[-425595208] = { return Api.SmsJob.parse_smsJob($0) } - dict[1301522832] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) } + dict[2109703795] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) } dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) } dict[-963180333] = { return Api.SponsoredPeer.parse_sponsoredPeer($0) } dict[-970274264] = { return Api.StarGift.parse_starGift($0) } @@ -1397,7 +1398,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[1404185519] = { return Api.messages.SearchResultsPositions.parse_searchResultsPositions($0) } dict[-1802240206] = { return Api.messages.SentEncryptedMessage.parse_sentEncryptedFile($0) } dict[1443858741] = { return Api.messages.SentEncryptedMessage.parse_sentEncryptedMessage($0) } - dict[-907141753] = { return Api.messages.SponsoredMessages.parse_sponsoredMessages($0) } + dict[-2464403] = { return Api.messages.SponsoredMessages.parse_sponsoredMessages($0) } dict[406407439] = { return Api.messages.SponsoredMessages.parse_sponsoredMessagesEmpty($0) } dict[1846886166] = { return Api.messages.StickerSet.parse_stickerSet($0) } dict[-738646805] = { return Api.messages.StickerSet.parse_stickerSetNotModified($0) } diff --git a/submodules/TelegramApi/Sources/Api15.swift b/submodules/TelegramApi/Sources/Api15.swift index 8df4f48c65..237813eda5 100644 --- a/submodules/TelegramApi/Sources/Api15.swift +++ b/submodules/TelegramApi/Sources/Api15.swift @@ -62,7 +62,7 @@ public extension Api { indirect enum Message: TypeConstructorDescription { case message(flags: Int32, flags2: Int32, id: Int32, fromId: Api.Peer?, fromBoostsApplied: Int32?, peerId: Api.Peer, savedPeerId: Api.Peer?, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int64?, viaBusinessBotId: Int64?, replyTo: Api.MessageReplyHeader?, date: Int32, message: String, media: Api.MessageMedia?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, views: Int32?, forwards: Int32?, replies: Api.MessageReplies?, editDate: Int32?, postAuthor: String?, groupedId: Int64?, reactions: Api.MessageReactions?, restrictionReason: [Api.RestrictionReason]?, ttlPeriod: Int32?, quickReplyShortcutId: Int32?, effect: Int64?, factcheck: Api.FactCheck?, reportDeliveryUntilDate: Int32?, paidMessageStars: Int64?) case messageEmpty(flags: Int32, id: Int32, peerId: Api.Peer?) - case messageService(flags: Int32, id: Int32, fromId: Api.Peer?, peerId: Api.Peer, replyTo: Api.MessageReplyHeader?, date: Int32, action: Api.MessageAction, reactions: Api.MessageReactions?, ttlPeriod: Int32?) + case messageService(flags: Int32, id: Int32, fromId: Api.Peer?, peerId: Api.Peer, savedPeerId: Api.Peer?, replyTo: Api.MessageReplyHeader?, date: Int32, action: Api.MessageAction, reactions: Api.MessageReactions?, ttlPeriod: Int32?) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { @@ -117,14 +117,15 @@ public extension Api { serializeInt32(id, buffer: buffer, boxed: false) if Int(flags) & Int(1 << 0) != 0 {peerId!.serialize(buffer, true)} break - case .messageService(let flags, let id, let fromId, let peerId, let replyTo, let date, let action, let reactions, let ttlPeriod): + case .messageService(let flags, let id, let fromId, let peerId, let savedPeerId, let replyTo, let date, let action, let reactions, let ttlPeriod): if boxed { - buffer.appendInt32(-741178048) + buffer.appendInt32(2055212554) } serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(id, buffer: buffer, boxed: false) if Int(flags) & Int(1 << 8) != 0 {fromId!.serialize(buffer, true)} peerId.serialize(buffer, true) + if Int(flags) & Int(1 << 28) != 0 {savedPeerId!.serialize(buffer, true)} if Int(flags) & Int(1 << 3) != 0 {replyTo!.serialize(buffer, true)} serializeInt32(date, buffer: buffer, boxed: false) action.serialize(buffer, true) @@ -140,8 +141,8 @@ public extension Api { return ("message", [("flags", flags as Any), ("flags2", flags2 as Any), ("id", id as Any), ("fromId", fromId as Any), ("fromBoostsApplied", fromBoostsApplied as Any), ("peerId", peerId as Any), ("savedPeerId", savedPeerId as Any), ("fwdFrom", fwdFrom as Any), ("viaBotId", viaBotId as Any), ("viaBusinessBotId", viaBusinessBotId as Any), ("replyTo", replyTo as Any), ("date", date as Any), ("message", message as Any), ("media", media as Any), ("replyMarkup", replyMarkup as Any), ("entities", entities as Any), ("views", views as Any), ("forwards", forwards as Any), ("replies", replies as Any), ("editDate", editDate as Any), ("postAuthor", postAuthor as Any), ("groupedId", groupedId as Any), ("reactions", reactions as Any), ("restrictionReason", restrictionReason as Any), ("ttlPeriod", ttlPeriod as Any), ("quickReplyShortcutId", quickReplyShortcutId as Any), ("effect", effect as Any), ("factcheck", factcheck as Any), ("reportDeliveryUntilDate", reportDeliveryUntilDate as Any), ("paidMessageStars", paidMessageStars as Any)]) case .messageEmpty(let flags, let id, let peerId): return ("messageEmpty", [("flags", flags as Any), ("id", id as Any), ("peerId", peerId as Any)]) - case .messageService(let flags, let id, let fromId, let peerId, let replyTo, let date, let action, let reactions, let ttlPeriod): - return ("messageService", [("flags", flags as Any), ("id", id as Any), ("fromId", fromId as Any), ("peerId", peerId as Any), ("replyTo", replyTo as Any), ("date", date as Any), ("action", action as Any), ("reactions", reactions as Any), ("ttlPeriod", ttlPeriod as Any)]) + case .messageService(let flags, let id, let fromId, let peerId, let savedPeerId, let replyTo, let date, let action, let reactions, let ttlPeriod): + return ("messageService", [("flags", flags as Any), ("id", id as Any), ("fromId", fromId as Any), ("peerId", peerId as Any), ("savedPeerId", savedPeerId as Any), ("replyTo", replyTo as Any), ("date", date as Any), ("action", action as Any), ("reactions", reactions as Any), ("ttlPeriod", ttlPeriod as Any)]) } } @@ -299,33 +300,38 @@ public extension Api { if let signature = reader.readInt32() { _4 = Api.parse(reader, signature: signature) as? Api.Peer } - var _5: Api.MessageReplyHeader? + var _5: Api.Peer? + if Int(_1!) & Int(1 << 28) != 0 {if let signature = reader.readInt32() { + _5 = Api.parse(reader, signature: signature) as? Api.Peer + } } + var _6: Api.MessageReplyHeader? if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() { - _5 = Api.parse(reader, signature: signature) as? Api.MessageReplyHeader + _6 = Api.parse(reader, signature: signature) as? Api.MessageReplyHeader } } - var _6: Int32? - _6 = reader.readInt32() - var _7: Api.MessageAction? + var _7: Int32? + _7 = reader.readInt32() + var _8: Api.MessageAction? if let signature = reader.readInt32() { - _7 = Api.parse(reader, signature: signature) as? Api.MessageAction + _8 = Api.parse(reader, signature: signature) as? Api.MessageAction } - var _8: Api.MessageReactions? + var _9: Api.MessageReactions? if Int(_1!) & Int(1 << 20) != 0 {if let signature = reader.readInt32() { - _8 = Api.parse(reader, signature: signature) as? Api.MessageReactions + _9 = Api.parse(reader, signature: signature) as? Api.MessageReactions } } - var _9: Int32? - if Int(_1!) & Int(1 << 25) != 0 {_9 = reader.readInt32() } + var _10: Int32? + if Int(_1!) & Int(1 << 25) != 0 {_10 = reader.readInt32() } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = (Int(_1!) & Int(1 << 8) == 0) || _3 != nil let _c4 = _4 != nil - let _c5 = (Int(_1!) & Int(1 << 3) == 0) || _5 != nil - let _c6 = _6 != nil + let _c5 = (Int(_1!) & Int(1 << 28) == 0) || _5 != nil + let _c6 = (Int(_1!) & Int(1 << 3) == 0) || _6 != nil let _c7 = _7 != nil - let _c8 = (Int(_1!) & Int(1 << 20) == 0) || _8 != nil - let _c9 = (Int(_1!) & Int(1 << 25) == 0) || _9 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 { - return Api.Message.messageService(flags: _1!, id: _2!, fromId: _3, peerId: _4!, replyTo: _5, date: _6!, action: _7!, reactions: _8, ttlPeriod: _9) + let _c8 = _8 != nil + let _c9 = (Int(_1!) & Int(1 << 20) == 0) || _9 != nil + let _c10 = (Int(_1!) & Int(1 << 25) == 0) || _10 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 { + return Api.Message.messageService(flags: _1!, id: _2!, fromId: _3, peerId: _4!, savedPeerId: _5, replyTo: _6, date: _7!, action: _8!, reactions: _9, ttlPeriod: _10) } else { return nil @@ -383,6 +389,7 @@ public extension Api { case messageActionStarGift(flags: Int32, gift: Api.StarGift, message: Api.TextWithEntities?, convertStars: Int64?, upgradeMsgId: Int32?, upgradeStars: Int64?, fromId: Api.Peer?, peer: Api.Peer?, savedId: Int64?) case messageActionStarGiftUnique(flags: Int32, gift: Api.StarGift, canExportAt: Int32?, transferStars: Int64?, fromId: Api.Peer?, peer: Api.Peer?, savedId: Int64?, resaleStars: Int64?, canTransferAt: Int32?, canResellAt: Int32?) case messageActionSuggestProfilePhoto(photo: Api.Photo) + case messageActionTodoAppendTasks(list: [Api.TodoItem]) case messageActionTodoCompletions(completed: [Int32], incompleted: [Int32]) case messageActionTopicCreate(flags: Int32, title: String, iconColor: Int32, iconEmojiId: Int64?) case messageActionTopicEdit(flags: Int32, title: String?, iconEmojiId: Int64?, closed: Api.Bool?, hidden: Api.Bool?) @@ -790,6 +797,16 @@ public extension Api { } photo.serialize(buffer, true) break + case .messageActionTodoAppendTasks(let list): + if boxed { + buffer.appendInt32(-940721021) + } + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(list.count)) + for item in list { + item.serialize(buffer, true) + } + break case .messageActionTodoCompletions(let completed, let incompleted): if boxed { buffer.appendInt32(-864265079) @@ -936,6 +953,8 @@ public extension Api { return ("messageActionStarGiftUnique", [("flags", flags as Any), ("gift", gift as Any), ("canExportAt", canExportAt as Any), ("transferStars", transferStars as Any), ("fromId", fromId as Any), ("peer", peer as Any), ("savedId", savedId as Any), ("resaleStars", resaleStars as Any), ("canTransferAt", canTransferAt as Any), ("canResellAt", canResellAt as Any)]) case .messageActionSuggestProfilePhoto(let photo): return ("messageActionSuggestProfilePhoto", [("photo", photo as Any)]) + case .messageActionTodoAppendTasks(let list): + return ("messageActionTodoAppendTasks", [("list", list as Any)]) case .messageActionTodoCompletions(let completed, let incompleted): return ("messageActionTodoCompletions", [("completed", completed as Any), ("incompleted", incompleted as Any)]) case .messageActionTopicCreate(let flags, let title, let iconColor, let iconEmojiId): @@ -1733,6 +1752,19 @@ public extension Api { return nil } } + public static func parse_messageActionTodoAppendTasks(_ reader: BufferReader) -> MessageAction? { + var _1: [Api.TodoItem]? + if let _ = reader.readInt32() { + _1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.TodoItem.self) + } + let _c1 = _1 != nil + if _c1 { + return Api.MessageAction.messageActionTodoAppendTasks(list: _1!) + } + else { + return nil + } + } public static func parse_messageActionTodoCompletions(_ reader: BufferReader) -> MessageAction? { var _1: [Int32]? if let _ = reader.readInt32() { diff --git a/submodules/TelegramApi/Sources/Api24.swift b/submodules/TelegramApi/Sources/Api24.swift index deb0fe67e3..ecb0e13970 100644 --- a/submodules/TelegramApi/Sources/Api24.swift +++ b/submodules/TelegramApi/Sources/Api24.swift @@ -442,13 +442,13 @@ public extension Api { } public extension Api { indirect enum SponsoredMessage: TypeConstructorDescription { - case sponsoredMessage(flags: Int32, randomId: Buffer, url: String, title: String, message: String, entities: [Api.MessageEntity]?, photo: Api.Photo?, media: Api.MessageMedia?, color: Api.PeerColor?, buttonText: String, sponsorInfo: String?, additionalInfo: String?) + case sponsoredMessage(flags: Int32, randomId: Buffer, url: String, title: String, message: String, entities: [Api.MessageEntity]?, photo: Api.Photo?, media: Api.MessageMedia?, color: Api.PeerColor?, buttonText: String, sponsorInfo: String?, additionalInfo: String?, minDisplayDuration: Int32?, maxDisplayDuration: Int32?) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .sponsoredMessage(let flags, let randomId, let url, let title, let message, let entities, let photo, let media, let color, let buttonText, let sponsorInfo, let additionalInfo): + case .sponsoredMessage(let flags, let randomId, let url, let title, let message, let entities, let photo, let media, let color, let buttonText, let sponsorInfo, let additionalInfo, let minDisplayDuration, let maxDisplayDuration): if boxed { - buffer.appendInt32(1301522832) + buffer.appendInt32(2109703795) } serializeInt32(flags, buffer: buffer, boxed: false) serializeBytes(randomId, buffer: buffer, boxed: false) @@ -466,14 +466,16 @@ public extension Api { serializeString(buttonText, buffer: buffer, boxed: false) if Int(flags) & Int(1 << 7) != 0 {serializeString(sponsorInfo!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 8) != 0 {serializeString(additionalInfo!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 15) != 0 {serializeInt32(minDisplayDuration!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 15) != 0 {serializeInt32(maxDisplayDuration!, buffer: buffer, boxed: false)} break } } public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .sponsoredMessage(let flags, let randomId, let url, let title, let message, let entities, let photo, let media, let color, let buttonText, let sponsorInfo, let additionalInfo): - return ("sponsoredMessage", [("flags", flags as Any), ("randomId", randomId as Any), ("url", url as Any), ("title", title as Any), ("message", message as Any), ("entities", entities as Any), ("photo", photo as Any), ("media", media as Any), ("color", color as Any), ("buttonText", buttonText as Any), ("sponsorInfo", sponsorInfo as Any), ("additionalInfo", additionalInfo as Any)]) + case .sponsoredMessage(let flags, let randomId, let url, let title, let message, let entities, let photo, let media, let color, let buttonText, let sponsorInfo, let additionalInfo, let minDisplayDuration, let maxDisplayDuration): + return ("sponsoredMessage", [("flags", flags as Any), ("randomId", randomId as Any), ("url", url as Any), ("title", title as Any), ("message", message as Any), ("entities", entities as Any), ("photo", photo as Any), ("media", media as Any), ("color", color as Any), ("buttonText", buttonText as Any), ("sponsorInfo", sponsorInfo as Any), ("additionalInfo", additionalInfo as Any), ("minDisplayDuration", minDisplayDuration as Any), ("maxDisplayDuration", maxDisplayDuration as Any)]) } } @@ -510,6 +512,10 @@ public extension Api { if Int(_1!) & Int(1 << 7) != 0 {_11 = parseString(reader) } var _12: String? if Int(_1!) & Int(1 << 8) != 0 {_12 = parseString(reader) } + var _13: Int32? + if Int(_1!) & Int(1 << 15) != 0 {_13 = reader.readInt32() } + var _14: Int32? + if Int(_1!) & Int(1 << 15) != 0 {_14 = reader.readInt32() } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = _3 != nil @@ -522,8 +528,10 @@ public extension Api { let _c10 = _10 != nil let _c11 = (Int(_1!) & Int(1 << 7) == 0) || _11 != nil let _c12 = (Int(_1!) & Int(1 << 8) == 0) || _12 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 { - return Api.SponsoredMessage.sponsoredMessage(flags: _1!, randomId: _2!, url: _3!, title: _4!, message: _5!, entities: _6, photo: _7, media: _8, color: _9, buttonText: _10!, sponsorInfo: _11, additionalInfo: _12) + let _c13 = (Int(_1!) & Int(1 << 15) == 0) || _13 != nil + let _c14 = (Int(_1!) & Int(1 << 15) == 0) || _14 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 { + return Api.SponsoredMessage.sponsoredMessage(flags: _1!, randomId: _2!, url: _3!, title: _4!, message: _5!, entities: _6, photo: _7, media: _8, color: _9, buttonText: _10!, sponsorInfo: _11, additionalInfo: _12, minDisplayDuration: _13, maxDisplayDuration: _14) } else { return nil diff --git a/submodules/TelegramApi/Sources/Api34.swift b/submodules/TelegramApi/Sources/Api34.swift index b2ea498c9f..1c8af79156 100644 --- a/submodules/TelegramApi/Sources/Api34.swift +++ b/submodules/TelegramApi/Sources/Api34.swift @@ -304,17 +304,19 @@ public extension Api.messages { } public extension Api.messages { enum SponsoredMessages: TypeConstructorDescription { - case sponsoredMessages(flags: Int32, postsBetween: Int32?, messages: [Api.SponsoredMessage], chats: [Api.Chat], users: [Api.User]) + case sponsoredMessages(flags: Int32, postsBetween: Int32?, startDelay: Int32?, betweenDelay: Int32?, messages: [Api.SponsoredMessage], chats: [Api.Chat], users: [Api.User]) case sponsoredMessagesEmpty public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .sponsoredMessages(let flags, let postsBetween, let messages, let chats, let users): + case .sponsoredMessages(let flags, let postsBetween, let startDelay, let betweenDelay, let messages, let chats, let users): if boxed { - buffer.appendInt32(-907141753) + buffer.appendInt32(-2464403) } serializeInt32(flags, buffer: buffer, boxed: false) if Int(flags) & Int(1 << 0) != 0 {serializeInt32(postsBetween!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 1) != 0 {serializeInt32(startDelay!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 2) != 0 {serializeInt32(betweenDelay!, buffer: buffer, boxed: false)} buffer.appendInt32(481674261) buffer.appendInt32(Int32(messages.count)) for item in messages { @@ -342,8 +344,8 @@ public extension Api.messages { public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .sponsoredMessages(let flags, let postsBetween, let messages, let chats, let users): - return ("sponsoredMessages", [("flags", flags as Any), ("postsBetween", postsBetween as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)]) + case .sponsoredMessages(let flags, let postsBetween, let startDelay, let betweenDelay, let messages, let chats, let users): + return ("sponsoredMessages", [("flags", flags as Any), ("postsBetween", postsBetween as Any), ("startDelay", startDelay as Any), ("betweenDelay", betweenDelay as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)]) case .sponsoredMessagesEmpty: return ("sponsoredMessagesEmpty", []) } @@ -354,25 +356,31 @@ public extension Api.messages { _1 = reader.readInt32() var _2: Int32? if Int(_1!) & Int(1 << 0) != 0 {_2 = reader.readInt32() } - var _3: [Api.SponsoredMessage]? + var _3: Int32? + if Int(_1!) & Int(1 << 1) != 0 {_3 = reader.readInt32() } + var _4: Int32? + if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() } + var _5: [Api.SponsoredMessage]? if let _ = reader.readInt32() { - _3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SponsoredMessage.self) + _5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SponsoredMessage.self) } - var _4: [Api.Chat]? + var _6: [Api.Chat]? if let _ = reader.readInt32() { - _4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self) + _6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self) } - var _5: [Api.User]? + var _7: [Api.User]? if let _ = reader.readInt32() { - _5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) + _7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) } let _c1 = _1 != nil let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil - let _c3 = _3 != nil - let _c4 = _4 != nil + let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil + let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil let _c5 = _5 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 { - return Api.messages.SponsoredMessages.sponsoredMessages(flags: _1!, postsBetween: _2, messages: _3!, chats: _4!, users: _5!) + let _c6 = _6 != nil + let _c7 = _7 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 { + return Api.messages.SponsoredMessages.sponsoredMessages(flags: _1!, postsBetween: _2, startDelay: _3, betweenDelay: _4, messages: _5!, chats: _6!, users: _7!) } else { return nil diff --git a/submodules/TelegramApi/Sources/Api38.swift b/submodules/TelegramApi/Sources/Api38.swift index f78a34a36e..1c436d111e 100644 --- a/submodules/TelegramApi/Sources/Api38.swift +++ b/submodules/TelegramApi/Sources/Api38.swift @@ -21,22 +21,6 @@ public extension Api.functions.account { }) } } -public extension Api.functions.account { - static func addNoPaidMessagesException(flags: Int32, userId: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(1869122215) - serializeInt32(flags, buffer: buffer, boxed: false) - userId.serialize(buffer, true) - return (FunctionDescription(name: "account.addNoPaidMessagesException", parameters: [("flags", String(describing: flags)), ("userId", String(describing: userId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in - let reader = BufferReader(buffer) - var result: Api.Bool? - if let signature = reader.readInt32() { - result = Api.parse(reader, signature: signature) as? Api.Bool - } - return result - }) - } -} public extension Api.functions.account { static func cancelPasswordEmail() -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() @@ -666,11 +650,13 @@ public extension Api.functions.account { } } public extension Api.functions.account { - static func getPaidMessagesRevenue(userId: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func getPaidMessagesRevenue(flags: Int32, parentPeer: Api.InputPeer?, userId: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(-249139400) + buffer.appendInt32(431639143) + serializeInt32(flags, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 0) != 0 {parentPeer!.serialize(buffer, true)} userId.serialize(buffer, true) - return (FunctionDescription(name: "account.getPaidMessagesRevenue", parameters: [("userId", String(describing: userId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.account.PaidMessagesRevenue? in + return (FunctionDescription(name: "account.getPaidMessagesRevenue", parameters: [("flags", String(describing: flags)), ("parentPeer", String(describing: parentPeer)), ("userId", String(describing: userId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.account.PaidMessagesRevenue? in let reader = BufferReader(buffer) var result: Api.account.PaidMessagesRevenue? if let signature = reader.readInt32() { @@ -1437,6 +1423,23 @@ public extension Api.functions.account { }) } } +public extension Api.functions.account { + static func toggleNoPaidMessagesException(flags: Int32, parentPeer: Api.InputPeer?, userId: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(-30483850) + serializeInt32(flags, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 1) != 0 {parentPeer!.serialize(buffer, true)} + userId.serialize(buffer, true) + return (FunctionDescription(name: "account.toggleNoPaidMessagesException", parameters: [("flags", String(describing: flags)), ("parentPeer", String(describing: parentPeer)), ("userId", String(describing: userId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in + let reader = BufferReader(buffer) + var result: Api.Bool? + if let signature = reader.readInt32() { + result = Api.parse(reader, signature: signature) as? Api.Bool + } + return result + }) + } +} public extension Api.functions.account { static func toggleSponsoredMessages(enabled: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() @@ -7086,11 +7089,13 @@ public extension Api.functions.messages { } } public extension Api.functions.messages { - static func getSponsoredMessages(peer: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func getSponsoredMessages(flags: Int32, peer: Api.InputPeer, msgId: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(-1680673735) + buffer.appendInt32(1030547536) + serializeInt32(flags, buffer: buffer, boxed: false) peer.serialize(buffer, true) - return (FunctionDescription(name: "messages.getSponsoredMessages", parameters: [("peer", String(describing: peer))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.SponsoredMessages? in + if Int(flags) & Int(1 << 0) != 0 {serializeInt32(msgId!, buffer: buffer, boxed: false)} + return (FunctionDescription(name: "messages.getSponsoredMessages", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("msgId", String(describing: msgId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.SponsoredMessages? in let reader = BufferReader(buffer) var result: Api.messages.SponsoredMessages? if let signature = reader.readInt32() { diff --git a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift index e540775579..32f998d09c 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift @@ -137,7 +137,7 @@ func apiMessagePeerId(_ messsage: Api.Message) -> PeerId? { } else { return nil } - case let .messageService(_, _, _, chatPeerId, _, _, _, _, _): + case let .messageService(_, _, _, chatPeerId, _, _, _, _, _, _): return chatPeerId.peerId } } @@ -218,7 +218,7 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] { return result case .messageEmpty: return [] - case let .messageService(_, _, fromId, chatPeerId, _, _, action, _, _): + case let .messageService(_, _, fromId, chatPeerId, savedPeerId, _, _, action, _, _): let peerId: PeerId = chatPeerId.peerId var result = [peerId] @@ -227,9 +227,12 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] { if resolvedFromId != peerId { result.append(resolvedFromId) } + if let savedPeerId, resolvedFromId != savedPeerId.peerId { + result.append(savedPeerId.peerId) + } switch action { - case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionGiftStars, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults, .messageActionBoostApply, .messageActionRequestedPeerSentMe, .messageActionStarGift, .messageActionStarGiftUnique, .messageActionPaidMessagesRefunded, .messageActionPaidMessagesPrice, .messageActionTodoCompletions: + case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionGiftStars, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults, .messageActionBoostApply, .messageActionRequestedPeerSentMe, .messageActionStarGift, .messageActionStarGiftUnique, .messageActionPaidMessagesRefunded, .messageActionPaidMessagesPrice, .messageActionTodoCompletions, .messageActionTodoAppendTasks: break case let .messageActionChannelMigrateFrom(_, chatId): result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId))) @@ -301,7 +304,7 @@ func apiMessageAssociatedMessageIds(_ message: Api.Message) -> (replyIds: Refere } case .messageEmpty: break - case let .messageService(_, id, _, chatPeerId, replyHeader, _, _, _, _): + case let .messageService(_, id, _, chatPeerId, _, replyHeader, _, _, _, _): if let replyHeader = replyHeader { switch replyHeader { case let .messageReplyHeader(_, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset): @@ -1061,14 +1064,16 @@ extension StoreMessage { self.init(id: MessageId(peerId: peerId, namespace: namespace, id: id), globallyUniqueId: nil, groupingKey: groupingId, threadId: threadId, timestamp: date, flags: storeFlags, tags: tags, globalTags: globalTags, localTags: [], forwardInfo: forwardInfo, authorId: authorId, text: messageText, attributes: attributes, media: medias) case .messageEmpty: return nil - case let .messageService(flags, id, fromId, chatPeerId, replyTo, date, action, reactions, ttlPeriod): + case let .messageService(flags, id, fromId, chatPeerId, savedPeerId, replyTo, date, action, reactions, ttlPeriod): let peerId: PeerId = chatPeerId.peerId let authorId: PeerId? = fromId?.peerId ?? chatPeerId.peerId var attributes: [MessageAttribute] = [] var threadId: Int64? - if let replyTo = replyTo { + if let savedPeerId { + threadId = savedPeerId.peerId.toInt64() + } else if let replyTo = replyTo { var threadMessageId: MessageId? switch replyTo { case let .messageReplyHeader(innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset): diff --git a/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaAction.swift b/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaAction.swift index b10c3671c1..8edf2aff8a 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaAction.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaAction.swift @@ -226,6 +226,9 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe ))) case let .messageActionTodoCompletions(completed, incompleted): return TelegramMediaAction(action: .todoCompletions(completed: completed, incompleted: incompleted)) + case .messageActionTodoAppendTasks: + //TODO:release + return nil } } diff --git a/submodules/TelegramCore/Sources/State/ApplyUpdateMessage.swift b/submodules/TelegramCore/Sources/State/ApplyUpdateMessage.swift index 3507b5eda5..77627e29b3 100644 --- a/submodules/TelegramCore/Sources/State/ApplyUpdateMessage.swift +++ b/submodules/TelegramCore/Sources/State/ApplyUpdateMessage.swift @@ -108,7 +108,7 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes updatedTimestamp = date case .messageEmpty: break - case let .messageService(_, _, _, _, _, date, _, _, _): + case let .messageService(_, _, _, _, _, _, date, _, _, _): updatedTimestamp = date } } else { diff --git a/submodules/TelegramCore/Sources/State/PaidMessages.swift b/submodules/TelegramCore/Sources/State/PaidMessages.swift index d72997b581..02b40e1907 100644 --- a/submodules/TelegramCore/Sources/State/PaidMessages.swift +++ b/submodules/TelegramCore/Sources/State/PaidMessages.swift @@ -11,7 +11,7 @@ func _internal_getPaidMessagesRevenue(account: Account, peerId: PeerId) -> Signa guard let inputUser else { return .single(nil) } - return account.network.request(Api.functions.account.getPaidMessagesRevenue(userId: inputUser)) + return account.network.request(Api.functions.account.getPaidMessagesRevenue(flags: 0, parentPeer: nil, userId: inputUser)) |> map(Optional.init) |> `catch` { _ -> Signal in return .single(nil) @@ -40,7 +40,8 @@ func _internal_addNoPaidMessagesException(account: Account, peerId: PeerId, refu if refundCharged { flags |= (1 << 0) } - return account.network.request(Api.functions.account.addNoPaidMessagesException(flags: flags, userId: inputUser)) + + return account.network.request(Api.functions.account.toggleNoPaidMessagesException(flags: flags, parentPeer: nil, userId: inputUser)) |> `catch` { _ -> Signal in return .single(.boolFalse) } |> mapToSignal { _ in diff --git a/submodules/TelegramCore/Sources/State/UpdatesApiUtils.swift b/submodules/TelegramCore/Sources/State/UpdatesApiUtils.swift index b3a7ef1dfb..f2291524a3 100644 --- a/submodules/TelegramCore/Sources/State/UpdatesApiUtils.swift +++ b/submodules/TelegramCore/Sources/State/UpdatesApiUtils.swift @@ -108,7 +108,7 @@ extension Api.Message { return id case let .messageEmpty(_, id, _): return id - case let .messageService(_, id, _, _, _, _, _, _, _): + case let .messageService(_, id, _, _, _, _, _, _, _, _): return id } } @@ -128,7 +128,7 @@ extension Api.Message { } else { return nil } - case let .messageService(_, id, _, chatPeerId, _, _, _, _, _): + case let .messageService(_, id, _, chatPeerId, _, _, _, _, _, _): let peerId: PeerId = chatPeerId.peerId return MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: id) } @@ -141,7 +141,7 @@ extension Api.Message { return peerId case let .messageEmpty(_, _, peerId): return peerId?.peerId - case let .messageService(_, _, _, chatPeerId, _, _, _, _, _): + case let .messageService(_, _, _, chatPeerId, _, _, _, _, _, _): let peerId: PeerId = chatPeerId.peerId return peerId } @@ -151,7 +151,7 @@ extension Api.Message { switch self { case let .message(_, _, _, _, _, _, _, _, _, _, _, date, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _): return date - case let .messageService(_, _, _, _, _, date, _, _, _): + case let .messageService(_, _, _, _, _, _, date, _, _, _): return date case .messageEmpty: return nil diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift index 05a1a8dba1..de9516cd91 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift @@ -430,7 +430,7 @@ private class AdMessagesHistoryContextImpl { guard let inputPeer else { return .single((nil, [])) } - return account.network.request(Api.functions.messages.getSponsoredMessages(peer: inputPeer)) + return account.network.request(Api.functions.messages.getSponsoredMessages(flags: 0, peer: inputPeer, msgId: nil)) |> map(Optional.init) |> `catch` { _ -> Signal in return .single(nil) @@ -442,7 +442,10 @@ private class AdMessagesHistoryContextImpl { return account.postbox.transaction { transaction -> (interPostInterval: Int32?, messages: [Message]) in switch result { - case let .sponsoredMessages(_, postsBetween, messages, chats, users): + case let .sponsoredMessages(_, postsBetween, startDelay, betweenDelay, messages, chats, users): + //TODO:release + let _ = startDelay + let _ = betweenDelay let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users) updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers) @@ -450,7 +453,11 @@ private class AdMessagesHistoryContextImpl { for message in messages { switch message { - case let .sponsoredMessage(flags, randomId, url, title, message, entities, photo, media, color, buttonText, sponsorInfo, additionalInfo): + case let .sponsoredMessage(flags, randomId, url, title, message, entities, photo, media, color, buttonText, sponsorInfo, additionalInfo, minDisplayDuration, maxDisplayDuration): + //TODO:release + let _ = minDisplayDuration + let _ = maxDisplayDuration + var parsedEntities: [MessageTextEntity] = [] if let entities = entities { parsedEntities = messageTextEntitiesFromApiEntities(entities) diff --git a/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift b/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift index 17874db695..0b500598aa 100644 --- a/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift +++ b/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift @@ -1288,6 +1288,11 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, } case .unknown: attributedString = nil + case let .todoCompletions(completed, incompleted): + //TODO:release + let _ = completed + let _ = incompleted + attributedString = nil } break } else if let expiredMedia = media as? TelegramMediaExpiredContent {