From 624d0d49d586d237b72cd7cac9d1ecd16c49ff78 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 4 Jul 2023 12:12:16 +0200 Subject: [PATCH] Restore changes --- .../Sources/Node/ChatListNode.swift | 2 +- .../Sources/PeerInfoAvatarListNode.swift | 6 +- .../Sources/ReactionContextNode.swift | 12 ++-- .../Messages/StoryListContext.swift | 29 ++++++-- .../Sources/ChatListNavigationBar.swift | 6 +- .../Sources/StoryChatContent.swift | 68 +++++++++++++++---- .../Sources/StoryContent.swift | 8 ++- .../StoryContentCaptionComponent.swift | 9 ++- .../StoryItemSetContainerComponent.swift | 38 ++++++----- .../Sources/StorySetIndicatorComponent.swift | 2 +- .../ChatMessageBubbleContentNode.swift | 4 ++ .../Sources/ChatMessageBubbleItemNode.swift | 5 ++ ...MessageInstantVideoBubbleContentNode.swift | 4 ++ .../ChatMessageInstantVideoItemNode.swift | 36 ++++++---- ...atMessageInteractiveInstantVideoNode.swift | 59 ++++++++++++---- .../Sources/StringWithAppliedEntities.swift | 11 ++- 16 files changed, 217 insertions(+), 82 deletions(-) diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index 12b26eb8cd..0cbd837165 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -1243,7 +1243,7 @@ public final class ChatListNode: ListView { super.init() - self.useMainQueueTransactions = true + //self.useMainQueueTransactions = true self.verticalScrollIndicatorColor = theme.list.scrollIndicatorColor self.verticalScrollIndicatorFollowsOverscroll = true diff --git a/submodules/PeerInfoAvatarListNode/Sources/PeerInfoAvatarListNode.swift b/submodules/PeerInfoAvatarListNode/Sources/PeerInfoAvatarListNode.swift index 727b0facf7..c350abe96f 100644 --- a/submodules/PeerInfoAvatarListNode/Sources/PeerInfoAvatarListNode.swift +++ b/submodules/PeerInfoAvatarListNode/Sources/PeerInfoAvatarListNode.swift @@ -840,8 +840,8 @@ public final class PeerInfoAvatarListContainerNode: ASDisplayNode { self.controlsContainerNode.addSubnode(self.stripContainerNode) self.controlsClippingNode.addSubnode(self.controlsContainerNode) self.controlsClippingOffsetNode.addSubnode(self.controlsClippingNode) - self.stripContainerNode.addSubnode(self.setByYouNode) - self.stripContainerNode.addSubnode(self.setByYouImageNode) + self.addSubnode(self.setByYouNode) + self.addSubnode(self.setByYouImageNode) self.view.disablesInteractiveTransitionGestureRecognizerNow = { [weak self] in guard let strongSelf = self else { @@ -1435,7 +1435,7 @@ public final class PeerInfoAvatarListContainerNode: ASDisplayNode { transition.updateAlpha(node: self.setByYouNode, alpha: 0.7) self.setByYouNode.attributedText = NSAttributedString(string: photoTitle, font: Font.regular(12.0), textColor: UIColor.white) let setByYouSize = self.setByYouNode.updateLayout(size) - self.setByYouNode.frame = CGRect(origin: CGPoint(x: size.width - setByYouSize.width - 14.0, y: size.height - setByYouSize.height - 58.0), size: setByYouSize) + self.setByYouNode.frame = CGRect(origin: CGPoint(x: size.width - setByYouSize.width - 14.0, y: size.height - setByYouSize.height - 18.0), size: setByYouSize) self.setByYouNode.isUserInteractionEnabled = hasLink } else { transition.updateAlpha(node: self.setByYouNode, alpha: 0.0) diff --git a/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift b/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift index a4fd22e857..b056ce2cf9 100644 --- a/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift +++ b/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift @@ -284,6 +284,8 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate { public var isReactionSearchActive: Bool = false + public var reduceMotion: Bool = false + public static func randomGenericReactionEffect(context: AccountContext) -> Signal { return context.engine.stickers.loadedStickerPack(reference: .emojiGenericAnimations, forceActualized: false) |> map { result -> [TelegramMediaFile]? in @@ -907,7 +909,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate { } if animateIn { - itemNode.appear(animated: !self.context.sharedContext.currentPresentationData.with({ $0 }).reduceMotion) + itemNode.appear(animated: !self.context.sharedContext.currentPresentationData.with({ $0 }).reduceMotion && !self.reduceMotion) } if self.getEmojiContent != nil, i == itemLayout.visibleItemCount - 1, let itemNode = itemNode as? ReactionNode { @@ -1197,7 +1199,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate { } } - if let animateInFromAnchorRect = animateInFromAnchorRect { + if let animateInFromAnchorRect = animateInFromAnchorRect, !self.reduceMotion { let springDuration: Double = 0.5 let springDamping: CGFloat = 104.0 let springScaleDelay: Double = 0.1 @@ -1606,11 +1608,13 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate { let mainCircleDelay: Double = 0.01 - self.backgroundNode.animateIn() + if !self.presentationData.reduceMotion && !self.reduceMotion { + self.backgroundNode.animateIn() + } self.didAnimateIn = true - if !self.presentationData.reduceMotion { + if !self.presentationData.reduceMotion && !self.reduceMotion { for i in 0 ..< self.items.count { guard let itemNode = self.visibleItemNodes[i] else { continue diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/StoryListContext.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/StoryListContext.swift index 4861eac853..f7ada43e54 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/StoryListContext.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/StoryListContext.swift @@ -466,17 +466,18 @@ public final class PeerStoryListContext { self.peerId = peerId self.isArchived = isArchived - self.stateValue = State(peerReference: nil, items: [], totalCount: 0, loadMoreToken: 0, isCached: true) + self.stateValue = State(peerReference: nil, items: [], totalCount: 0, loadMoreToken: 0, isCached: true, allEntityFiles: [:]) - let _ = (account.postbox.transaction { transaction -> (PeerReference?, [EngineStoryItem], Int) in + let _ = (account.postbox.transaction { transaction -> (PeerReference?, [EngineStoryItem], Int, [MediaId: TelegramMediaFile]) in let key = ValueBoxKey(length: 8 + 1) key.setInt64(0, value: peerId.toInt64()) key.setInt8(8, value: isArchived ? 1 : 0) let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key))?.get(CachedPeerStoryListHead.self) guard let cached = cached else { - return (nil, [], 0) + return (nil, [], 0, [:]) } var items: [EngineStoryItem] = [] + var allEntityFiles: [MediaId: TelegramMediaFile] = [:] for storedItem in cached.items { if case let .item(item) = storedItem, let media = item.media { let mappedItem = EngineStoryItem( @@ -504,19 +505,30 @@ public final class PeerStoryListContext { isEdited: item.isEdited ) items.append(mappedItem) + + for entity in mappedItem.entities { + if case let .CustomEmoji(_, fileId) = entity.type { + let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId) + if allEntityFiles[mediaId] == nil { + if let file = transaction.getMedia(mediaId) as? TelegramMediaFile { + allEntityFiles[file.fileId] = file + } + } + } + } } } let peerReference = transaction.getPeer(peerId).flatMap(PeerReference.init) - return (peerReference, items, Int(cached.totalCount)) + return (peerReference, items, Int(cached.totalCount), allEntityFiles) } - |> deliverOn(self.queue)).start(next: { [weak self] peerReference, items, totalCount in + |> deliverOn(self.queue)).start(next: { [weak self] peerReference, items, totalCount, allEntityFiles in guard let `self` = self else { return } - self.stateValue = State(peerReference: peerReference, items: items, totalCount: totalCount, loadMoreToken: 0, isCached: true) + self.stateValue = State(peerReference: peerReference, items: items, totalCount: totalCount, loadMoreToken: 0, isCached: true, allEntityFiles: allEntityFiles) self.loadMore() }) } @@ -828,19 +840,22 @@ public final class PeerStoryListContext { public var totalCount: Int public var loadMoreToken: Int? public var isCached: Bool + public var allEntityFiles: [MediaId: TelegramMediaFile] init( peerReference: PeerReference?, items: [EngineStoryItem], totalCount: Int, loadMoreToken: Int?, - isCached: Bool + isCached: Bool, + allEntityFiles: [MediaId: TelegramMediaFile] ) { self.peerReference = peerReference self.items = items self.totalCount = totalCount self.loadMoreToken = loadMoreToken self.isCached = isCached + self.allEntityFiles = allEntityFiles } } diff --git a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift index 9f8317ce2c..82925bfecd 100644 --- a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift +++ b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift @@ -145,7 +145,7 @@ public final class ChatListNavigationBar: Component { public static let searchScrollHeight: CGFloat = 52.0 public static let storiesScrollHeight: CGFloat = { - return 79.0 + return 83.0 }() public final class View: UIView { @@ -404,7 +404,7 @@ public final class ChatListNavigationBar: Component { if component.statusBarHeight < 1.0 { headerContentY = 0.0 } else { - headerContentY = component.statusBarHeight + 12.0 + headerContentY = component.statusBarHeight + 5.0 } } let headerContentFrame = CGRect(origin: CGPoint(x: 0.0, y: headerContentY), size: headerContentSize) @@ -579,7 +579,7 @@ public final class ChatListNavigationBar: Component { var contentHeight = component.statusBarHeight if component.statusBarHeight >= 1.0 { - contentHeight += 10.0 + contentHeight += 3.0 } contentHeight += 44.0 diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryChatContent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryChatContent.swift index dcc296e21b..2a048f019a 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryChatContent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryChatContent.swift @@ -63,9 +63,11 @@ public final class StoryContentContextImpl: StoryContentContext { ), context.engine.data.subscribe(TelegramEngine.EngineData.Item.NotificationSettings.Global()) ) - |> mapToSignal { _, views, globalNotificationSettings -> Signal<(CombinedView, [PeerId: Peer], EngineGlobalNotificationSettings), NoError> in - return context.account.postbox.transaction { transaction -> (CombinedView, [PeerId: Peer], EngineGlobalNotificationSettings) in + |> mapToSignal { _, views, globalNotificationSettings -> Signal<(CombinedView, [PeerId: Peer], EngineGlobalNotificationSettings, [MediaId: TelegramMediaFile]), NoError> in + return context.account.postbox.transaction { transaction -> (CombinedView, [PeerId: Peer], EngineGlobalNotificationSettings, [MediaId: TelegramMediaFile]) in var peers: [PeerId: Peer] = [:] + var allEntityFiles: [MediaId: TelegramMediaFile] = [:] + if let itemsView = views.views[PostboxViewKey.storyItems(peerId: peerId)] as? StoryItemsView { for item in itemsView.items { if let item = item.value.get(Stories.StoredItem.self), case let .item(itemValue) = item { @@ -76,13 +78,24 @@ public final class StoryContentContextImpl: StoryContentContext { } } } + for entity in itemValue.entities { + if case let .CustomEmoji(_, fileId) = entity.type { + let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId) + if allEntityFiles[mediaId] == nil { + if let file = transaction.getMedia(mediaId) as? TelegramMediaFile { + allEntityFiles[file.fileId] = file + } + } + } + } } } } - return (views, peers, globalNotificationSettings) + + return (views, peers, globalNotificationSettings, allEntityFiles) } } - |> deliverOnMainQueue).start(next: { [weak self] views, peers, globalNotificationSettings in + |> deliverOnMainQueue).start(next: { [weak self] views, peers, globalNotificationSettings, allEntityFiles in guard let self else { return } @@ -257,7 +270,8 @@ public final class StoryContentContextImpl: StoryContentContext { return StoryContentItem( position: nil, peerId: peer.id, - storyItem: item + storyItem: item, + entityFiles: extractItemEntityFiles(item: item, allEntityFiles: allEntityFiles) ) } @@ -268,7 +282,8 @@ public final class StoryContentContextImpl: StoryContentContext { item: StoryContentItem( position: mappedFocusedIndex ?? focusedIndex, peerId: peer.id, - storyItem: mappedItem + storyItem: mappedItem, + entityFiles: extractItemEntityFiles(item: mappedItem, allEntityFiles: allEntityFiles) ), totalCount: totalCount, previousItemId: previousItemId, @@ -907,11 +922,12 @@ public final class SingleStoryContentContextImpl: StoryContentContext { TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: storyId.peerId), TelegramEngine.EngineData.Item.NotificationSettings.Global() ), - context.account.postbox.transaction { transaction -> (Stories.StoredItem?, [PeerId: Peer]) in + context.account.postbox.transaction { transaction -> (Stories.StoredItem?, [PeerId: Peer], [MediaId: TelegramMediaFile]) in guard let item = transaction.getStory(id: storyId)?.get(Stories.StoredItem.self) else { - return (nil, [:]) + return (nil, [:], [:]) } var peers: [PeerId: Peer] = [:] + var allEntityFiles: [MediaId: TelegramMediaFile] = [:] if case let .item(item) = item { if let views = item.views { for id in views.seenPeerIds { @@ -920,8 +936,18 @@ public final class SingleStoryContentContextImpl: StoryContentContext { } } } + for entity in item.entities { + if case let .CustomEmoji(_, fileId) = entity.type { + let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId) + if allEntityFiles[mediaId] == nil { + if let file = transaction.getMedia(mediaId) as? TelegramMediaFile { + allEntityFiles[file.fileId] = file + } + } + } + } } - return (item, peers) + return (item, peers, allEntityFiles) } ) |> deliverOnMainQueue).start(next: { [weak self] data, itemAndPeers in @@ -930,7 +956,7 @@ public final class SingleStoryContentContextImpl: StoryContentContext { } let (peer, areVoiceMessagesAvailable, notificationSettings, globalNotificationSettings) = data - let (item, peers) = itemAndPeers + let (item, peers, allEntityFiles) = itemAndPeers guard let peer else { return @@ -981,7 +1007,8 @@ public final class SingleStoryContentContextImpl: StoryContentContext { let mainItem = StoryContentItem( position: 0, peerId: peer.id, - storyItem: mappedItem + storyItem: mappedItem, + entityFiles: extractItemEntityFiles(item: mappedItem, allEntityFiles: allEntityFiles) ) let stateValue = StoryContentContextState( slice: StoryContentContextState.FocusedSlice( @@ -1130,7 +1157,8 @@ public final class PeerStoryListContentContextImpl: StoryContentContext { return StoryContentItem( position: nil, peerId: peer.id, - storyItem: stateItem + storyItem: stateItem, + entityFiles: extractItemEntityFiles(item: stateItem, allEntityFiles: state.allEntityFiles) ) } @@ -1141,7 +1169,8 @@ public final class PeerStoryListContentContextImpl: StoryContentContext { item: StoryContentItem( position: nil, peerId: peer.id, - storyItem: item + storyItem: item, + entityFiles: extractItemEntityFiles(item: item, allEntityFiles: state.allEntityFiles) ), totalCount: state.totalCount, previousItemId: focusedIndex == 0 ? nil : state.items[focusedIndex - 1].id, @@ -1326,3 +1355,16 @@ public func preloadStoryMedia(context: AccountContext, peer: PeerReference, stor return combineLatest(signals) |> ignoreValues } + +func extractItemEntityFiles(item: EngineStoryItem, allEntityFiles: [MediaId: TelegramMediaFile]) -> [MediaId: TelegramMediaFile] { + var result: [MediaId: TelegramMediaFile] = [:] + for entity in item.entities { + if case let .CustomEmoji(_, fileId) = entity.type { + let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId) + if let file = allEntityFiles[mediaId] { + result[file.fileId] = file + } + } + } + return result +} diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContent.swift index fdf0210e1e..f4f6add294 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContent.swift @@ -80,15 +80,18 @@ public final class StoryContentItem: Equatable { public let position: Int? public let peerId: EnginePeer.Id? public let storyItem: EngineStoryItem + public let entityFiles: [EngineMedia.Id: TelegramMediaFile] public init( position: Int?, peerId: EnginePeer.Id?, - storyItem: EngineStoryItem + storyItem: EngineStoryItem, + entityFiles: [EngineMedia.Id: TelegramMediaFile] ) { self.position = position self.peerId = peerId self.storyItem = storyItem + self.entityFiles = entityFiles } public static func ==(lhs: StoryContentItem, rhs: StoryContentItem) -> Bool { @@ -101,6 +104,9 @@ public final class StoryContentItem: Equatable { if lhs.storyItem != rhs.storyItem { return false } + if lhs.entityFiles != rhs.entityFiles { + return false + } return true } } diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift index a957c5d8e9..83b14615f3 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift @@ -43,6 +43,7 @@ final class StoryContentCaptionComponent: Component { let context: AccountContext let text: String let entities: [MessageTextEntity] + let entityFiles: [EngineMedia.Id: TelegramMediaFile] let action: (Action) -> Void init( @@ -50,12 +51,14 @@ final class StoryContentCaptionComponent: Component { context: AccountContext, text: String, entities: [MessageTextEntity], + entityFiles: [EngineMedia.Id: TelegramMediaFile], action: @escaping (Action) -> Void ) { self.externalState = externalState self.context = context self.text = text self.entities = entities + self.entityFiles = entityFiles self.action = action } @@ -72,6 +75,9 @@ final class StoryContentCaptionComponent: Component { if lhs.entities != rhs.entities { return false } + if lhs.entityFiles != rhs.entityFiles { + return false + } return true } @@ -359,7 +365,8 @@ final class StoryContentCaptionComponent: Component { boldItalicFont: Font.semiboldItalic(16.0), fixedFont: Font.monospace(16.0), blockQuoteFont: Font.monospace(16.0), - message: nil + message: nil, + entityFiles: component.entityFiles ) let makeLayout = TextNodeWithEntities.asyncLayout(self.textNode) diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index 922de341dd..10aed94931 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -2518,6 +2518,7 @@ public final class StoryItemSetContainerComponent: Component { context: component.context, text: component.slice.item.storyItem.text, entities: component.slice.item.storyItem.entities, + entityFiles: component.slice.item.entityFiles, action: { [weak self] action in guard let self, let component = self.component else { return @@ -2649,7 +2650,7 @@ public final class StoryItemSetContainerComponent: Component { reactionContextNode.displayTail = false self.reactionContextNode = reactionContextNode - reactionContextNode.reactionSelected = { [weak self] updateReaction, _ in + reactionContextNode.reactionSelected = { [weak self, weak reactionContextNode] updateReaction, _ in guard let self, let component = self.component else { return } @@ -2673,23 +2674,24 @@ public final class StoryItemSetContainerComponent: Component { targetView.isUserInteractionEnabled = false self.addSubview(targetView) - reactionContextNode.willAnimateOutToReaction(value: updateReaction.reaction) - reactionContextNode.animateOutToReaction(value: updateReaction.reaction, targetView: targetView, hideNode: false, animateTargetContainer: nil, addStandaloneReactionAnimation: "".isEmpty ? nil : { [weak self] standaloneReactionAnimation in - guard let self else { - return - } - standaloneReactionAnimation.frame = self.bounds - self.addSubview(standaloneReactionAnimation.view) - }, completion: { [weak targetView, weak reactionContextNode] in - targetView?.removeFromSuperview() - if let reactionContextNode { - reactionContextNode.layer.animateScale(from: 1.0, to: 0.001, duration: 0.3, removeOnCompletion: false) - reactionContextNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak reactionContextNode] _ in - reactionContextNode?.view.removeFromSuperview() - }) - } - }) - + if let reactionContextNode { + reactionContextNode.willAnimateOutToReaction(value: updateReaction.reaction) + reactionContextNode.animateOutToReaction(value: updateReaction.reaction, targetView: targetView, hideNode: false, animateTargetContainer: nil, addStandaloneReactionAnimation: "".isEmpty ? nil : { [weak self] standaloneReactionAnimation in + guard let self else { + return + } + standaloneReactionAnimation.frame = self.bounds + self.addSubview(standaloneReactionAnimation.view) + }, completion: { [weak targetView, weak reactionContextNode] in + targetView?.removeFromSuperview() + if let reactionContextNode { + reactionContextNode.layer.animateScale(from: 1.0, to: 0.001, duration: 0.3, removeOnCompletion: false) + reactionContextNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak reactionContextNode] _ in + reactionContextNode?.view.removeFromSuperview() + }) + } + }) + } if hasFirstResponder(self) { self.sendMessageContext.currentInputMode = .text diff --git a/submodules/TelegramUI/Components/Stories/StorySetIndicatorComponent/Sources/StorySetIndicatorComponent.swift b/submodules/TelegramUI/Components/Stories/StorySetIndicatorComponent/Sources/StorySetIndicatorComponent.swift index 47141b8e51..7114f82d76 100644 --- a/submodules/TelegramUI/Components/Stories/StorySetIndicatorComponent/Sources/StorySetIndicatorComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StorySetIndicatorComponent/Sources/StorySetIndicatorComponent.swift @@ -345,7 +345,7 @@ public final class StorySetIndicatorComponent: Component { if component.hasUnseen { borderColors = [component.theme.chatList.storyUnseenColors.topColor.argb, component.theme.chatList.storyUnseenColors.bottomColor.argb] } else { - borderColors = [component.theme.chatList.storySeenColors.topColor.argb, component.theme.chatList.storySeenColors.bottomColor.argb] + borderColors = [UIColor(white: 1.0, alpha: 0.3).argb, UIColor(white: 1.0, alpha: 0.3).argb] } let imageSize = CGSize(width: maxItemsWidth, height: outerDiameter) diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift index 7d2c2ea41c..dc5858ffd2 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift @@ -254,6 +254,10 @@ class ChatMessageBubbleContentNode: ASDisplayNode { return nil } + func targetForStoryTransition(id: StoryId) -> UIView? { + return nil + } + func getStatusNode() -> ASDisplayNode? { return nil } diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index 89893bbeab..c5e210744b 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -4589,6 +4589,11 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode guard let item = self.item else { return nil } + for contentNode in self.contentNodes { + if let value = contentNode.targetForStoryTransition(id: id) { + return value + } + } for attribute in item.message.attributes { if let attribute = attribute as? ReplyStoryAttribute { if attribute.storyId == id { diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoBubbleContentNode.swift index 4f9bfd4deb..a236a18bac 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoBubbleContentNode.swift @@ -429,6 +429,10 @@ class ChatMessageInstantVideoBubbleContentNode: ChatMessageBubbleContentNode { return nil } + override func targetForStoryTransition(id: StoryId) -> UIView? { + return self.interactiveVideoNode.targetForStoryTransition(id: id) + } + override var disablesClipping: Bool { return true } diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index 7917a3d28f..93b6519861 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -431,6 +431,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD } } + var replyMessage: Message? + var replyStory: StoryId? for attribute in item.message.attributes { if let attribute = attribute as? InlineBotMessageAttribute { var inlineBotNameString: String? @@ -467,28 +469,34 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD } } - if let replyAttribute = attribute as? ReplyMessageAttribute, let replyMessage = item.message.associatedMessages[replyAttribute.messageId] { + if let replyAttribute = attribute as? ReplyMessageAttribute { if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.messageId == replyAttribute.messageId { } else { - replyInfoApply = makeReplyInfoLayout(ChatMessageReplyInfoNode.Arguments( - presentationData: item.presentationData, - strings: item.presentationData.strings, - context: item.context, - type: .standalone, - message: replyMessage, - story: nil, - parentMessage: item.message, - constrainedSize: CGSize(width: availableWidth, height: CGFloat.greatestFiniteMagnitude), - animationCache: item.controllerInteraction.presentationContext.animationCache, - animationRenderer: item.controllerInteraction.presentationContext.animationRenderer, - associatedData: item.associatedData - )) + replyMessage = item.message.associatedMessages[replyAttribute.messageId] } + } else if let attribute = attribute as? ReplyStoryAttribute { + replyStory = attribute.storyId } else if let _ = attribute as? InlineBotMessageAttribute { } else if let attribute = attribute as? ReplyMarkupMessageAttribute, attribute.flags.contains(.inline), !attribute.rows.isEmpty { replyMarkup = attribute } } + + if replyMessage != nil || replyStory != nil { + replyInfoApply = makeReplyInfoLayout(ChatMessageReplyInfoNode.Arguments( + presentationData: item.presentationData, + strings: item.presentationData.strings, + context: item.context, + type: .standalone, + message: replyMessage, + story: replyStory, + parentMessage: item.message, + constrainedSize: CGSize(width: max(0, availableWidth), height: CGFloat.greatestFiniteMagnitude), + animationCache: item.controllerInteraction.presentationContext.animationCache, + animationRenderer: item.controllerInteraction.presentationContext.animationRenderer, + associatedData: item.associatedData + )) + } var updatedShareButtonNode: ChatMessageShareButton? if needsShareButton { diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift index c6f3efe3db..b7ae99114b 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift @@ -316,6 +316,9 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { let availableContentWidth = width - bubbleEdgeInset * 2.0 - bubbleContentInsetsLeft - 20.0 if !ignoreHeaders { + var replyMessage: Message? + var replyStory: StoryId? + for attribute in item.message.attributes { if let attribute = attribute as? InlineBotMessageAttribute { var inlineBotNameString: String? @@ -338,23 +341,32 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { } } - if let replyAttribute = attribute as? ReplyMessageAttribute, let replyMessage = item.message.associatedMessages[replyAttribute.messageId] { + if let replyAttribute = attribute as? ReplyMessageAttribute { if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.messageId == replyAttribute.messageId { } else { - replyInfoApply = makeReplyInfoLayout(ChatMessageReplyInfoNode.Arguments( - presentationData: item.presentationData, - strings: item.presentationData.strings, - context: item.context, - type: .standalone, - message: replyMessage, - story: nil, - parentMessage: item.message, - constrainedSize: CGSize(width: availableWidth, height: CGFloat.greatestFiniteMagnitude), - animationCache: item.controllerInteraction.presentationContext.animationCache, - animationRenderer: item.controllerInteraction.presentationContext.animationRenderer, - associatedData: item.associatedData - )) + replyMessage = item.message.associatedMessages[replyAttribute.messageId] } + } else if let attribute = attribute as? ReplyStoryAttribute { + replyStory = attribute.storyId + } + } + + if replyMessage != nil || replyStory != nil { + if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.messageId == replyMessage?.id { + } else { + replyInfoApply = makeReplyInfoLayout(ChatMessageReplyInfoNode.Arguments( + presentationData: item.presentationData, + strings: item.presentationData.strings, + context: item.context, + type: .standalone, + message: replyMessage, + story: replyStory, + parentMessage: item.message, + constrainedSize: CGSize(width: availableWidth, height: CGFloat.greatestFiniteMagnitude), + animationCache: item.controllerInteraction.presentationContext.animationCache, + animationRenderer: item.controllerInteraction.presentationContext.animationRenderer, + associatedData: item.associatedData + )) } } } @@ -1259,6 +1271,9 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { if let attribute = attribute as? ReplyMessageAttribute { item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId) return + } else if let attribute = attribute as? ReplyStoryAttribute { + item.controllerInteraction.navigateToStory(item.message, attribute.storyId) + return } } } @@ -1815,4 +1830,20 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { self.canAttachContent = false } + + func targetForStoryTransition(id: StoryId) -> UIView? { + guard let item = self.item else { + return nil + } + for attribute in item.message.attributes { + if let attribute = attribute as? ReplyStoryAttribute { + if attribute.storyId == id { + if let replyInfoNode = self.replyInfoNode { + return replyInfoNode.mediaTransitionView() + } + } + } + } + return nil + } } diff --git a/submodules/TextFormat/Sources/StringWithAppliedEntities.swift b/submodules/TextFormat/Sources/StringWithAppliedEntities.swift index ec6f8826a0..a8cf179e0e 100644 --- a/submodules/TextFormat/Sources/StringWithAppliedEntities.swift +++ b/submodules/TextFormat/Sources/StringWithAppliedEntities.swift @@ -52,7 +52,7 @@ public func chatInputStateStringWithAppliedEntities(_ text: String, entities: [M return string } -public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], baseColor: UIColor, linkColor: UIColor, baseFont: UIFont, linkFont: UIFont, boldFont: UIFont, italicFont: UIFont, boldItalicFont: UIFont, fixedFont: UIFont, blockQuoteFont: UIFont, underlineLinks: Bool = true, external: Bool = false, message: Message?) -> NSAttributedString { +public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], baseColor: UIColor, linkColor: UIColor, baseFont: UIFont, linkFont: UIFont, boldFont: UIFont, italicFont: UIFont, boldItalicFont: UIFont, fixedFont: UIFont, blockQuoteFont: UIFont, underlineLinks: Bool = true, external: Bool = false, message: Message?, entityFiles: [MediaId: TelegramMediaFile] = [:]) -> NSAttributedString { var nsString: NSString? let string = NSMutableAttributedString(string: text, attributes: [NSAttributedString.Key.font: baseFont, NSAttributedString.Key.foregroundColor: baseColor]) var skipEntity = false @@ -252,7 +252,14 @@ public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEnti } } case let .CustomEmoji(_, fileId): - string.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: fileId, file: message?.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile), range: range) + let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId) + var emojiFile: TelegramMediaFile? + if let file = message?.associatedMedia[mediaId] as? TelegramMediaFile { + emojiFile = file + } else { + emojiFile = entityFiles[mediaId] + } + string.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: fileId, file: emojiFile), range: range) default: break }