diff --git a/submodules/Display/Source/ListView.swift b/submodules/Display/Source/ListView.swift index b23f716edb..80f7a26266 100644 --- a/submodules/Display/Source/ListView.swift +++ b/submodules/Display/Source/ListView.swift @@ -383,8 +383,41 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture private let waitingForNodesDisposable = MetaDisposable() private var auxiliaryDisplayLink: CADisplayLink? + private var auxiliaryDisplayLinkHandle: SharedDisplayLinkDriver.Link? + private var debugView: UIView? private var isAuxiliaryDisplayLinkEnabled: Bool = false { didSet { + if self.isAuxiliaryDisplayLinkEnabled { + if self.auxiliaryDisplayLinkHandle == nil { + self.auxiliaryDisplayLinkHandle = SharedDisplayLinkDriver.shared.add(needsHighestFramerate: true, { [weak self] in + guard let self else { + return + } + if self.debugView == nil { + let debugView = UIView(frame: CGRect(origin: CGPoint(), size: CGSize(width: 1.0, height: 1.0))) + debugView.backgroundColor = .black + debugView.alpha = 0.0001 + self.debugView = debugView + self.view.addSubview(debugView) + } + if let debugView = self.debugView { + if debugView.frame.origin.x == 0.0 { + debugView.frame = CGRect(origin: CGPoint(x: 1.0, y: 0.0), size: CGSize(width: 1.0, height: 1.0)) + } else { + debugView.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 1.0, height: 1.0)) + } + } + }) + } + } else if let auxiliaryDisplayLinkHandle = self.auxiliaryDisplayLinkHandle { + self.auxiliaryDisplayLinkHandle = nil + auxiliaryDisplayLinkHandle.invalidate() + if let debugView = self.debugView { + self.debugView = nil + debugView.removeFromSuperview() + } + } + /*if self.isAuxiliaryDisplayLinkEnabled != oldValue { if self.isAuxiliaryDisplayLinkEnabled { if self.auxiliaryDisplayLink == nil { @@ -3536,7 +3569,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } } - private func updateItemHeaders(leftInset: CGFloat, rightInset: CGFloat, synchronousLoad: Bool, transition: (ContainedViewLayoutTransition, Bool, CGFloat) = (.immediate, false, 0.0), animateInsertion: Bool = false) { + private func updateItemHeaders(leftInset: CGFloat, rightInset: CGFloat, synchronousLoad: Bool, transition: (ContainedViewLayoutTransition, Bool, CGFloat) = (.immediate, false, 0.0), animateInsertion: Bool = false) { self.assignHeaderSpaceAffinities() let upperDisplayBound = self.headerInsets.top diff --git a/submodules/Display/Source/TextNode.swift b/submodules/Display/Source/TextNode.swift index 2ae7dc5339..e7cbc85bbd 100644 --- a/submodules/Display/Source/TextNode.swift +++ b/submodules/Display/Source/TextNode.swift @@ -1513,18 +1513,21 @@ open class TextNode: ASDisplayNode { var fixDoubleEmoji = false if glyphCount == 2, let font = attributes["NSFont"] as? UIFont, font.fontName.contains("ColorEmoji"), let string = layout.attributedString { let range = CTRunGetStringRange(run) - let substring = string.attributedSubstring(from: NSMakeRange(range.location, range.length)).string - let heart = Unicode.Scalar(0x2764)! - let man = Unicode.Scalar(0x1F468)! - let woman = Unicode.Scalar(0x1F469)! - let leftHand = Unicode.Scalar(0x1FAF1)! - let rightHand = Unicode.Scalar(0x1FAF2)! - - if substring.unicodeScalars.contains(heart) && (substring.unicodeScalars.contains(man) || substring.unicodeScalars.contains(woman)) { - fixDoubleEmoji = true - } else if substring.unicodeScalars.contains(leftHand) && substring.unicodeScalars.contains(rightHand) { - fixDoubleEmoji = true + if range.location < string.length && (range.location + range.length) < string.length { + let substring = string.attributedSubstring(from: NSMakeRange(range.location, range.length)).string + + let heart = Unicode.Scalar(0x2764)! + let man = Unicode.Scalar(0x1F468)! + let woman = Unicode.Scalar(0x1F469)! + let leftHand = Unicode.Scalar(0x1FAF1)! + let rightHand = Unicode.Scalar(0x1FAF2)! + + if substring.unicodeScalars.contains(heart) && (substring.unicodeScalars.contains(man) || substring.unicodeScalars.contains(woman)) { + fixDoubleEmoji = true + } else if substring.unicodeScalars.contains(leftHand) && substring.unicodeScalars.contains(rightHand) { + fixDoubleEmoji = true + } } } diff --git a/submodules/Postbox/Sources/ChatListTable.swift b/submodules/Postbox/Sources/ChatListTable.swift index 14bb307fa3..3d2d766506 100644 --- a/submodules/Postbox/Sources/ChatListTable.swift +++ b/submodules/Postbox/Sources/ChatListTable.swift @@ -265,30 +265,26 @@ final class ChatListTable: Table { } } - func getUnreadChatListPeerIds(postbox: PostboxImpl, currentTransaction: Transaction, groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate?) -> [PeerId] { + func getUnreadChatListPeerIds(postbox: PostboxImpl, currentTransaction: Transaction, groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate?, additionalFilter: ((Peer) -> Bool)?, stopOnFirstMatch: Bool) -> [PeerId] { let globalNotificationSettings = postbox.getGlobalNotificationSettings(transaction: currentTransaction) var result: [PeerId] = [] self.valueBox.range(self.table, start: self.upperBound(groupId: groupId), end: self.lowerBound(groupId: groupId), keys: { key in let (_, _, messageIndex, _) = extractKey(key) - if let state = postbox.readStateTable.getCombinedState(messageIndex.id.peerId), state.isUnread { - let passFilter: Bool + if let state = postbox.readStateTable.getCombinedState(messageIndex.id.peerId), state.isUnread, let peer = postbox.peerTable.get(messageIndex.id.peerId) { + var passFilter: Bool if let filterPredicate = filterPredicate { - if let peer = postbox.peerTable.get(messageIndex.id.peerId) { - let isUnread = postbox.readStateTable.getCombinedState(messageIndex.id.peerId)?.isUnread ?? false - let isContact = postbox.contactsTable.isContact(peerId: messageIndex.id.peerId) - - let isRemovedFromTotalUnreadCount = resolvedIsRemovedFromTotalUnreadCount(globalSettings: globalNotificationSettings, peer: peer, peerSettings: postbox.peerNotificationSettingsTable.getEffective(messageIndex.id.peerId)) - - let messageTagSummaryResult = resolveChatListMessageTagSummaryResultCalculation(postbox: postbox, peerId: peer.id, threadId: nil, calculation: filterPredicate.messageTagSummary) - - if filterPredicate.pinnedPeerIds.contains(peer.id) { - passFilter = true - } else if filterPredicate.includes(peer: peer, groupId: groupId, isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount, isUnread: isUnread, isContact: isContact, messageTagSummaryResult: messageTagSummaryResult) { - passFilter = true - } else { - passFilter = false - } + let isUnread = postbox.readStateTable.getCombinedState(messageIndex.id.peerId)?.isUnread ?? false + let isContact = postbox.contactsTable.isContact(peerId: messageIndex.id.peerId) + + let isRemovedFromTotalUnreadCount = resolvedIsRemovedFromTotalUnreadCount(globalSettings: globalNotificationSettings, peer: peer, peerSettings: postbox.peerNotificationSettingsTable.getEffective(messageIndex.id.peerId)) + + let messageTagSummaryResult = resolveChatListMessageTagSummaryResultCalculation(postbox: postbox, peerId: peer.id, threadId: nil, calculation: filterPredicate.messageTagSummary) + + if filterPredicate.pinnedPeerIds.contains(peer.id) { + passFilter = true + } else if filterPredicate.includes(peer: peer, groupId: groupId, isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount, isUnread: isUnread, isContact: isContact, messageTagSummaryResult: messageTagSummaryResult) { + passFilter = true } else { passFilter = false } @@ -296,8 +292,17 @@ final class ChatListTable: Table { passFilter = true } + if passFilter, let additionalFilter = additionalFilter { + if !additionalFilter(peer) { + passFilter = false + } + } + if passFilter { result.append(messageIndex.id.peerId) + if stopOnFirstMatch { + return false + } } } return true diff --git a/submodules/Postbox/Sources/Postbox.swift b/submodules/Postbox/Sources/Postbox.swift index 60cdc42df3..17f075d869 100644 --- a/submodules/Postbox/Sources/Postbox.swift +++ b/submodules/Postbox/Sources/Postbox.swift @@ -389,10 +389,10 @@ public final class Transaction { return self.postbox?.chatListTable.getPeerChatListIndex(peerId: peerId) } - public func getUnreadChatListPeerIds(groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate?) -> [PeerId] { + public func getUnreadChatListPeerIds(groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate?, additionalFilter: ((Peer) -> Bool)?, stopOnFirstMatch: Bool) -> [PeerId] { assert(!self.disposed) if let postbox = self.postbox { - return postbox.chatListTable.getUnreadChatListPeerIds(postbox: postbox, currentTransaction: self, groupId: groupId, filterPredicate: filterPredicate) + return postbox.chatListTable.getUnreadChatListPeerIds(postbox: postbox, currentTransaction: self, groupId: groupId, filterPredicate: filterPredicate, additionalFilter: additionalFilter, stopOnFirstMatch: stopOnFirstMatch) } else { return [] } @@ -1564,7 +1564,7 @@ final class PostboxImpl { var installedMessageActionsByPeerId: [PeerId: Bag<([StoreMessage], Transaction) -> Void>] = [:] var installedStoreOrUpdateMessageActionsByPeerId: [PeerId: Bag] = [:] - init(queue: Queue, basePath: String, seedConfiguration: SeedConfiguration, valueBox: SqliteValueBox, timestampForAbsoluteTimeBasedOperations: Int32, isTemporary: Bool, tempDir: TempBoxDirectory?, useCaches: Bool) { + init(queue: Queue, basePath: String, seedConfiguration: SeedConfiguration, valueBox: SqliteValueBox, timestampForAbsoluteTimeBasedOperations: Int32, isTemporary: Bool, tempDir: TempBoxDirectory?, useCaches: Bool, isInTransaction: Atomic) { assert(queue.isCurrent()) let startTime = CFAbsoluteTimeGetCurrent() @@ -1576,6 +1576,8 @@ final class PostboxImpl { self.valueBox = valueBox + self.isInTransaction = isInTransaction + self.metadataTable = MetadataTable(valueBox: self.valueBox, table: MetadataTable.tableSpec(0), useCaches: useCaches) self.keychainTable = KeychainTable(valueBox: self.valueBox, table: KeychainTable.tableSpec(1), useCaches: useCaches) @@ -2597,7 +2599,7 @@ final class PostboxImpl { return result } - private let canBeginTransactionsValue = Atomic(value: true) + let canBeginTransactionsValue = Atomic(value: true) public func setCanBeginTransactions(_ value: Bool) { self.queue.async { let previous = self.canBeginTransactionsValue.swap(value) @@ -2625,7 +2627,11 @@ final class PostboxImpl { } } + let isInTransaction: Atomic + private func internalTransaction(_ f: (Transaction) -> T) -> (result: T, updatedTransactionStateVersion: Int64?, updatedMasterClientId: Int64?) { + let _ = self.isInTransaction.swap(true) + self.valueBox.begin() let transaction = Transaction(queue: self.queue, postbox: self) self.afterBegin(transaction: transaction) @@ -2634,6 +2640,8 @@ final class PostboxImpl { transaction.disposed = true self.valueBox.commit() + let _ = self.isInTransaction.swap(false) + if let currentUpdatedState = self.currentUpdatedState { self.statePipe.putNext(currentUpdatedState) } @@ -3848,6 +3856,8 @@ public class Postbox { public let seedConfiguration: SeedConfiguration public let mediaBox: MediaBox + + private let isInTransaction = Atomic(value: false) init( queue: Queue, @@ -3866,8 +3876,10 @@ public class Postbox { postboxLog("MediaBox path: \(basePath + "/media")") self.mediaBox = MediaBox(basePath: basePath + "/media") + let isInTransaction = self.isInTransaction + self.impl = QueueLocalObject(queue: queue, generate: { - return PostboxImpl( + let impl = PostboxImpl( queue: queue, basePath: basePath, seedConfiguration: seedConfiguration, @@ -3875,8 +3887,10 @@ public class Postbox { timestampForAbsoluteTimeBasedOperations: timestampForAbsoluteTimeBasedOperations, isTemporary: isTemporary, tempDir: tempDir, - useCaches: useCaches + useCaches: useCaches, + isInTransaction: isInTransaction ) + return impl }) } @@ -3898,6 +3912,12 @@ public class Postbox { } public func setCanBeginTransactions(_ value: Bool) { + #if DEBUG + if !value { + assert(!self.isInTransaction.with({ $0 })) + } + #endif + self.impl.with { impl in impl.setCanBeginTransactions(value) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/ApplyMaxReadIndexInteractively.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ApplyMaxReadIndexInteractively.swift index 32ddd48b9c..d37f5b10cf 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/ApplyMaxReadIndexInteractively.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ApplyMaxReadIndexInteractively.swift @@ -235,7 +235,7 @@ public func clearPeerUnseenReactionsInteractively(account: Account, peerId: Peer } func _internal_markAllChatsAsReadInteractively(transaction: Transaction, network: Network, viewTracker: AccountViewTracker, groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate?) { - for peerId in transaction.getUnreadChatListPeerIds(groupId: groupId, filterPredicate: filterPredicate) { + for peerId in transaction.getUnreadChatListPeerIds(groupId: groupId, filterPredicate: filterPredicate, additionalFilter: nil, stopOnFirstMatch: false) { _internal_togglePeerUnreadMarkInteractively(transaction: transaction, network: network, viewTracker: viewTracker, peerId: peerId, setToValue: false) } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift index d13561386f..9c69b711a4 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift @@ -441,7 +441,7 @@ public extension TelegramEngine { public func unreadChatListPeerIds(groupId: EngineChatList.Group, filterPredicate: ChatListFilterPredicate?) -> Signal<[EnginePeer.Id], NoError> { return self.account.postbox.transaction { transaction -> [EnginePeer.Id] in - return transaction.getUnreadChatListPeerIds(groupId: groupId._asGroup(), filterPredicate: filterPredicate) + return transaction.getUnreadChatListPeerIds(groupId: groupId._asGroup(), filterPredicate: filterPredicate, additionalFilter: nil, stopOnFirstMatch: false) } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift index 0a0dc662cc..a7e94bff98 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift @@ -632,15 +632,23 @@ public extension TelegramEngine { public func getNextUnreadChannel(peerId: PeerId, chatListFilterId: Int32?, getFilterPredicate: @escaping (ChatListFilterData) -> ChatListFilterPredicate) -> Signal<(peer: EnginePeer, unreadCount: Int, location: NextUnreadChannelLocation)?, NoError> { return self.account.postbox.transaction { transaction -> (peer: EnginePeer, unreadCount: Int, location: NextUnreadChannelLocation)? in func getForFilter(predicate: ChatListFilterPredicate?, isArchived: Bool) -> (peer: EnginePeer, unreadCount: Int)? { + let additionalFilter: (Peer) -> Bool = { peer in + if let channel = peer as? TelegramChannel, case .broadcast = channel.info { + return true + } else { + return false + } + } + var peerIds: [PeerId] = [] if predicate != nil { - peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: .root, filterPredicate: predicate)) - peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: Namespaces.PeerGroup.archive, filterPredicate: predicate)) + peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: .root, filterPredicate: predicate, additionalFilter: additionalFilter, stopOnFirstMatch: true)) + peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: Namespaces.PeerGroup.archive, filterPredicate: predicate, additionalFilter: additionalFilter, stopOnFirstMatch: true)) } else { if isArchived { - peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: Namespaces.PeerGroup.archive, filterPredicate: nil)) + peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: Namespaces.PeerGroup.archive, filterPredicate: nil, additionalFilter: additionalFilter, stopOnFirstMatch: true)) } else { - peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: .root, filterPredicate: nil)) + peerIds.append(contentsOf: transaction.getUnreadChatListPeerIds(groupId: .root, filterPredicate: nil, additionalFilter: additionalFilter, stopOnFirstMatch: true)) } } diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift index d8d1b9c547..f4bb19fa0e 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift @@ -30,7 +30,7 @@ public func selectReactionFillStaticColor(theme: PresentationTheme, wallpaper: T public func dateFillNeedsBlur(theme: PresentationTheme, wallpaper: TelegramWallpaper) -> Bool { if !DeviceMetrics.performance.isGraphicallyCapable { - return false + //return false } if case .builtin = wallpaper { diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index 97aa66f2ed..4ce39c04a8 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -938,9 +938,11 @@ private func extractAccountManagerState(records: AccountRecordsView PortalView? { + return nil + } + func makeDimmedNode() -> ASDisplayNode? { return nil } diff --git a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift index ed96b11a3b..7aa3e948ae 100644 --- a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift +++ b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift @@ -66,6 +66,7 @@ public protocol WallpaperBackgroundNode: ASDisplayNode { func updateBubbleTheme(bubbleTheme: PresentationTheme, bubbleCorners: PresentationChatBubbleCorners) func hasBubbleBackground(for type: WallpaperBubbleType) -> Bool func makeBubbleBackground(for type: WallpaperBubbleType) -> WallpaperBubbleBackgroundNode? + func makeFreeBackground() -> PortalView? func hasExtraBubbleBackground() -> Bool @@ -586,6 +587,10 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode private let contentNode: ASDisplayNode private var blurredBackgroundContents: UIImage? + private var blurredBackgroundPortalSourceView: PortalSourceView? + private var blurredBackgroundDimmedNode: GradientBackgroundNode.CloneNode? + private var blurredBackgroundDimmedOverlayView: UIView? + private var blurredBackgroundContentView: UIImageView? private var gradientBackgroundNode: GradientBackgroundNode? private var outgoingBubbleGradientBackgroundNode: GradientBackgroundNode? @@ -715,6 +720,17 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode super.init() + if #available(iOS 12.0, *) { + let blurredBackgroundPortalSourceView = PortalSourceView() + self.blurredBackgroundPortalSourceView = blurredBackgroundPortalSourceView + blurredBackgroundPortalSourceView.alpha = 0.0001 + self.view.addSubview(blurredBackgroundPortalSourceView) + + let blurredBackgroundContentView = UIImageView() + self.blurredBackgroundContentView = blurredBackgroundContentView + blurredBackgroundPortalSourceView.addSubview(blurredBackgroundContentView) + } + self.clipsToBounds = true self.contentNode.frame = self.bounds self.addSubnode(self.contentNode) @@ -763,11 +779,28 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode scheduleLoopingEvent = true } } + if let gradientBackgroundNode = self.gradientBackgroundNode { + if self.blurredBackgroundDimmedNode == nil { + let blurredBackgroundDimmedNode = GradientBackgroundNode.CloneNode(parentNode: gradientBackgroundNode) + self.blurredBackgroundDimmedNode = blurredBackgroundDimmedNode + self.blurredBackgroundPortalSourceView?.addSubnode(blurredBackgroundDimmedNode) + } + if self.blurredBackgroundDimmedOverlayView == nil { + let blurredBackgroundDimmedOverlayView = UIView() + self.blurredBackgroundDimmedOverlayView = blurredBackgroundDimmedOverlayView + self.blurredBackgroundPortalSourceView?.addSubview(blurredBackgroundDimmedOverlayView) + } + } self.gradientBackgroundNode?.updateColors(colors: mappedColors) + + if let bubbleTheme = self.bubbleTheme { + self.blurredBackgroundDimmedOverlayView?.backgroundColor = selectDateFillStaticColor(theme: bubbleTheme, wallpaper: wallpaper) + } self.contentNode.backgroundColor = nil self.contentNode.contents = nil self.blurredBackgroundContents = nil + self.blurredBackgroundContentView?.image = self.blurredBackgroundContents self.motionEnabled = false self.wallpaperDisposable.set(nil) } else { @@ -777,6 +810,14 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode gradientBackgroundNode.setPatternOverlay(layer: nil) self.layer.insertSublayer(self.patternImageLayer, above: self.contentNode.layer) } + if let blurredBackgroundDimmedNode = self.blurredBackgroundDimmedNode { + self.blurredBackgroundDimmedNode = nil + blurredBackgroundDimmedNode.removeFromSupernode() + } + if let blurredBackgroundDimmedOverlayView = self.blurredBackgroundDimmedOverlayView { + self.blurredBackgroundDimmedOverlayView = nil + blurredBackgroundDimmedOverlayView.removeFromSuperview() + } self.motionEnabled = wallpaper.settings?.motion ?? false @@ -797,17 +838,20 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode }) self.contentNode.contents = image?.cgImage self.blurredBackgroundContents = image + self.blurredBackgroundContentView?.image = self.blurredBackgroundContents self.wallpaperDisposable.set(nil) } else if gradientColors.count >= 1 { self.contentNode.backgroundColor = UIColor(rgb: gradientColors[0]) self.contentNode.contents = nil self.blurredBackgroundContents = nil + self.blurredBackgroundContentView?.image = self.blurredBackgroundContents self.wallpaperDisposable.set(nil) } else { self.contentNode.backgroundColor = .white if let image = chatControllerBackgroundImage(theme: nil, wallpaper: wallpaper, mediaBox: self.context.sharedContext.accountManager.mediaBox, knockoutMode: false) { self.contentNode.contents = image.cgImage self.blurredBackgroundContents = generateBlurredContents(image: image) + self.blurredBackgroundContentView?.image = self.blurredBackgroundContents self.wallpaperDisposable.set(nil) Queue.mainQueue().justDispatch { self._isReady.set(true) @@ -815,6 +859,7 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode } else if let image = chatControllerBackgroundImage(theme: nil, wallpaper: wallpaper, mediaBox: self.context.account.postbox.mediaBox, knockoutMode: false) { self.contentNode.contents = image.cgImage self.blurredBackgroundContents = generateBlurredContents(image: image) + self.blurredBackgroundContentView?.image = self.blurredBackgroundContents self.wallpaperDisposable.set(nil) Queue.mainQueue().justDispatch { self._isReady.set(true) @@ -831,6 +876,7 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode } else { strongSelf.blurredBackgroundContents = nil } + strongSelf.blurredBackgroundContentView?.image = strongSelf.blurredBackgroundContents strongSelf._isReady.set(true) })) } @@ -1078,6 +1124,19 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) { let isFirstLayout = self.validLayout == nil self.validLayout = size + + if let blurredBackgroundPortalSourceView = self.blurredBackgroundPortalSourceView { + transition.updateFrame(view: blurredBackgroundPortalSourceView, frame: CGRect(origin: CGPoint(), size: size)) + } + if let blurredBackgroundContentView = self.blurredBackgroundContentView { + transition.updateFrame(view: blurredBackgroundContentView, frame: CGRect(origin: CGPoint(), size: size)) + } + if let blurredBackgroundDimmedNode = self.blurredBackgroundDimmedNode { + transition.updateFrame(view: blurredBackgroundDimmedNode.view, frame: CGRect(origin: CGPoint(), size: size)) + } + if let blurredBackgroundDimmedOverlayView = self.blurredBackgroundDimmedOverlayView { + transition.updateFrame(view: blurredBackgroundDimmedOverlayView, frame: CGRect(origin: CGPoint(), size: size)) + } transition.updatePosition(node: self.contentNode, position: CGPoint(x: size.width / 2.0, y: size.height / 2.0)) transition.updateBounds(node: self.contentNode, bounds: CGRect(origin: CGPoint(), size: size)) @@ -1152,6 +1211,10 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode } else if let _ = self.outgoingBubbleGradientBackgroundNode { self.outgoingBubbleGradientBackgroundNode = nil } + + if let wallpaper = self.wallpaper { + self.blurredBackgroundDimmedOverlayView?.backgroundColor = selectDateFillStaticColor(theme: bubbleTheme, wallpaper: wallpaper) + } self.updateBubbles() } @@ -1217,6 +1280,17 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode return node } + func makeFreeBackground() -> PortalView? { + guard let blurredBackgroundPortalSourceView = self.blurredBackgroundPortalSourceView else { + return nil + } + guard let portalView = PortalView(matchPosition: true) else { + return nil + } + blurredBackgroundPortalSourceView.addPortal(view: portalView) + return portalView + } + func hasExtraBubbleBackground() -> Bool { var isInvertedGradient = false switch self.wallpaper { @@ -2076,6 +2150,10 @@ final class WallpaperBackgroundNodeMergedImpl: ASDisplayNode, WallpaperBackgroun return node } + func makeFreeBackground() -> PortalView? { + return nil + } + func hasExtraBubbleBackground() -> Bool { return false }