diff --git a/submodules/SparseItemGrid/Sources/SparseItemGrid.swift b/submodules/SparseItemGrid/Sources/SparseItemGrid.swift index 046efd81c5..e42f3017eb 100644 --- a/submodules/SparseItemGrid/Sources/SparseItemGrid.swift +++ b/submodules/SparseItemGrid/Sources/SparseItemGrid.swift @@ -329,6 +329,7 @@ public final class SparseItemGrid: ASDisplayNode { final class VisibleItem: SparseItemGridDisplayItem { let layer: SparseItemGridLayer? let view: SparseItemGridView? + var shimmerLayer: SparseItemGridShimmerLayer? init(layer: SparseItemGridLayer?, view: SparseItemGridView?) { self.layer = layer @@ -470,12 +471,12 @@ public final class SparseItemGrid: ASDisplayNode { self.view.addSubview(self.scrollView) } - func update(containerLayout: ContainerLayout, items: Items, restoreScrollPosition: (y: CGFloat, index: Int)?) { + func update(containerLayout: ContainerLayout, items: Items, restoreScrollPosition: (y: CGFloat, index: Int)?, synchronous: Bool) { if self.layout?.containerLayout != containerLayout || self.items !== items { self.layout = Layout(containerLayout: containerLayout, zoomLevel: self.zoomLevel) self.items = items - self.updateVisibleItems(resetScrolling: true, synchronous: false, restoreScrollPosition: restoreScrollPosition) + self.updateVisibleItems(resetScrolling: true, synchronous: synchronous, restoreScrollPosition: restoreScrollPosition) } } @@ -691,10 +692,6 @@ public final class SparseItemGrid: ASDisplayNode { self.scrollView.setContentOffset(self.scrollView.contentOffset, animated: false) } - func updateShimmerLayers() { - self.updateVisibleItems(resetScrolling: false, synchronous: false, restoreScrollPosition: nil) - } - private func updateVisibleItems(resetScrolling: Bool, synchronous: Bool, restoreScrollPosition: (y: CGFloat, index: Int)?) { guard let layout = self.layout, let items = self.items else { return @@ -770,19 +767,21 @@ public final class SparseItemGrid: ASDisplayNode { if itemLayer.needsShimmer { let placeholderLayer: SparseItemGridShimmerLayer - if self.visiblePlaceholders.count > usedPlaceholderCount { - placeholderLayer = self.visiblePlaceholders[usedPlaceholderCount] + if let current = itemLayer.shimmerLayer { + placeholderLayer = current } else { placeholderLayer = items.itemBinding.createShimmerLayer() ?? Shimmer.Layer() self.scrollView.layer.insertSublayer(placeholderLayer, at: 0) - self.visiblePlaceholders.append(placeholderLayer) + itemLayer.shimmerLayer = placeholderLayer } let itemFrame = layout.frame(at: index) placeholderLayer.frame = itemFrame self.shimmer.update(colors: shimmerColors, layer: placeholderLayer, containerSize: layout.containerLayout.size, frame: itemFrame.offsetBy(dx: 0.0, dy: -visibleBounds.minY)) placeholderLayer.update(size: itemFrame.size) - usedPlaceholderCount += 1 + } else if let placeholderLayer = itemLayer.shimmerLayer { + itemLayer.shimmerLayer = nil + placeholderLayer.removeFromSuperlayer() } validIds.insert(item.id) @@ -1185,7 +1184,7 @@ public final class SparseItemGrid: ASDisplayNode { }) nextViewport.frame = CGRect(origin: CGPoint(), size: containerLayout.size) - nextViewport.update(containerLayout: containerLayout, items: items, restoreScrollPosition: restoreScrollPosition) + nextViewport.update(containerLayout: containerLayout, items: items, restoreScrollPosition: restoreScrollPosition, synchronous: false) self.currentViewportTransition?.removeFromSupernode() @@ -1235,7 +1234,7 @@ public final class SparseItemGrid: ASDisplayNode { }) nextViewport.frame = CGRect(origin: CGPoint(), size: containerLayout.size) - nextViewport.update(containerLayout: containerLayout, items: items, restoreScrollPosition: restoreScrollPosition) + nextViewport.update(containerLayout: containerLayout, items: items, restoreScrollPosition: restoreScrollPosition, synchronous: false) let currentViewportTransition = ViewportTransition(interactiveState: interactiveState, layout: containerLayout, anchorItemIndex: anchorItemIndex, from: previousViewport, to: nextViewport, coveringOffsetUpdated: { [weak self] transition in self?.transitionCoveringOffsetUpdated(transition: transition) @@ -1272,7 +1271,7 @@ public final class SparseItemGrid: ASDisplayNode { strongSelf.scrollingArea.frame = CGRect(origin: CGPoint(), size: containerLayout.size) currentViewport.setScrollingArea(scrollingArea: strongSelf.scrollingArea) currentViewport.frame = CGRect(origin: CGPoint(), size: containerLayout.size) - currentViewport.update(containerLayout: containerLayout, items: items, restoreScrollPosition: nil) + currentViewport.update(containerLayout: containerLayout, items: items, restoreScrollPosition: nil, synchronous: false) } strongSelf.currentViewportTransition = nil @@ -1284,7 +1283,7 @@ public final class SparseItemGrid: ASDisplayNode { } } - public func update(size: CGSize, insets: UIEdgeInsets, scrollIndicatorInsets: UIEdgeInsets, lockScrollingAtTop: Bool, fixedItemHeight: CGFloat?, items: Items) { + public func update(size: CGSize, insets: UIEdgeInsets, scrollIndicatorInsets: UIEdgeInsets, lockScrollingAtTop: Bool, fixedItemHeight: CGFloat?, items: Items, synchronous: Bool) { let containerLayout = ContainerLayout(size: size, insets: insets, scrollIndicatorInsets: scrollIndicatorInsets, lockScrollingAtTop: lockScrollingAtTop, fixedItemHeight: fixedItemHeight) self.containerLayout = containerLayout self.items = items @@ -1312,7 +1311,7 @@ public final class SparseItemGrid: ASDisplayNode { } else if let currentViewport = self.currentViewport { self.scrollingArea.frame = CGRect(origin: CGPoint(), size: size) currentViewport.frame = CGRect(origin: CGPoint(), size: size) - currentViewport.update(containerLayout: containerLayout, items: items, restoreScrollPosition: nil) + currentViewport.update(containerLayout: containerLayout, items: items, restoreScrollPosition: nil, synchronous: synchronous) } } @@ -1395,7 +1394,7 @@ public final class SparseItemGrid: ASDisplayNode { self.scrollingArea.frame = CGRect(origin: CGPoint(), size: containerLayout.size) currentViewport.frame = CGRect(origin: CGPoint(), size: containerLayout.size) - currentViewport.update(containerLayout: containerLayout, items: items, restoreScrollPosition: restoreScrollPosition) + currentViewport.update(containerLayout: containerLayout, items: items, restoreScrollPosition: restoreScrollPosition, synchronous: false) let currentViewportTransition = ViewportTransition(interactiveState: nil, layout: containerLayout, anchorItemIndex: anchorItemIndex, from: previousViewport, to: currentViewport, coveringOffsetUpdated: { [weak self] transition in self?.transitionCoveringOffsetUpdated(transition: transition) @@ -1413,7 +1412,7 @@ public final class SparseItemGrid: ASDisplayNode { strongSelf.insertSubnode(currentViewport, belowSubnode: strongSelf.scrollingArea) strongSelf.scrollingArea.frame = CGRect(origin: CGPoint(), size: containerLayout.size) currentViewport.frame = CGRect(origin: CGPoint(), size: containerLayout.size) - currentViewport.update(containerLayout: containerLayout, items: items, restoreScrollPosition: nil) + currentViewport.update(containerLayout: containerLayout, items: items, restoreScrollPosition: nil, synchronous: false) } strongSelf.currentViewport?.setScrollingArea(scrollingArea: strongSelf.scrollingArea) @@ -1500,11 +1499,13 @@ public final class SparseItemGrid: ASDisplayNode { self.scrollingArea.hideScroller() } - public func updateShimmerLayers() { - self.currentViewport?.updateShimmerLayers() - if let currentViewportTransition = self.currentViewportTransition { - currentViewportTransition.fromViewport.updateShimmerLayers() - currentViewportTransition.toViewport.updateShimmerLayers() + public func updateShimmerLayers(item: SparseItemGridDisplayItem) { + guard let item = item as? Viewport.VisibleItem else { + return + } + if let itemShimmerLayer = item.shimmerLayer, !item.needsShimmer { + item.shimmerLayer = nil + itemShimmerLayer.removeFromSuperlayer() } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SparseMessageList.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SparseMessageList.swift index 1520e1b39d..d066374fb5 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SparseMessageList.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SparseMessageList.swift @@ -169,11 +169,11 @@ public final class SparseMessageList { private func resetTopSection() { let count: Int - #if DEBUG + /*#if DEBUG count = 20 - #else + #else*/ count = 200 - #endif + //#endif self.topItemsDisposable.set((self.account.postbox.aroundMessageHistoryViewForLocation(.peer(peerId), anchor: .upperBound, count: count, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: Set(), tagMask: self.messageTag, appendMessagesFromTheSameGroup: false, namespaces: .not(Set(Namespaces.Message.allScheduled)), orderStatistics: []) |> deliverOn(self.queue)).start(next: { [weak self] view, updateType, _ in guard let strongSelf = self else { diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift index 77cef28f0e..3c7ad9312d 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift @@ -979,7 +979,7 @@ private final class SparseItemGridBindingImpl: SparseItemGridBinding, ListShimme var coveringInsetOffsetUpdatedImpl: ((ContainedViewLayoutTransition) -> Void)? var onBeginFastScrollingImpl: (() -> Void)? var getShimmerColorsImpl: (() -> SparseItemGrid.ShimmerColors)? - var updateShimmerLayersImpl: (() -> Void)? + var updateShimmerLayersImpl: ((SparseItemGridDisplayItem) -> Void)? private var shimmerImages: [CGFloat: UIImage] = [:] @@ -1115,8 +1115,10 @@ private final class SparseItemGridBindingImpl: SparseItemGridBinding, ListShimme continue } + let displayItem = layers[i] + if self.useListItems { - guard let view = layers[i].view as? ItemView else { + guard let view = displayItem.view as? ItemView else { continue } view.bind( @@ -1129,7 +1131,7 @@ private final class SparseItemGridBindingImpl: SparseItemGridBinding, ListShimme size: view.bounds.size ) } else { - guard let layer = layers[i].layer as? ItemLayer else { + guard let layer = displayItem.layer as? ItemLayer else { continue } if layer.bounds.isEmpty { @@ -1171,7 +1173,7 @@ private final class SparseItemGridBindingImpl: SparseItemGridBinding, ListShimme } if let loadSignal = result.loadSignal { layer.disposable = (loadSignal - |> deliverOnMainQueue).start(next: { [weak self, weak layer] image in + |> deliverOnMainQueue).start(next: { [weak self, weak layer, weak displayItem] image in guard let layer = layer else { return } @@ -1193,7 +1195,9 @@ private final class SparseItemGridBindingImpl: SparseItemGridBinding, ListShimme layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - self?.updateShimmerLayersImpl?() + if let displayItem = displayItem { + self?.updateShimmerLayersImpl?(displayItem) + } } }) } @@ -1322,6 +1326,7 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro private let itemGridBinding: SparseItemGridBindingImpl private let directMediaImageCache: DirectMediaImageCache private var items: SparseItemGrid.Items? + private var didUpdateItemsOnce: Bool = false private var isDeceleratingAfterTracking = false @@ -1534,8 +1539,8 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro return SparseItemGrid.ShimmerColors(background: backgroundColor.argb, foreground: foregroundColor.argb) } - self.itemGridBinding.updateShimmerLayersImpl = { [weak self] in - self?.itemGrid.updateShimmerLayers() + self.itemGridBinding.updateShimmerLayersImpl = { [weak self] layer in + self?.itemGrid.updateShimmerLayers(item: layer) } self.itemGrid.cancelExternalContentGestures = { [weak self] in @@ -1646,14 +1651,15 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro self.storedStateDisposable = (visualMediaStoredState(postbox: context.account.postbox, peerId: peerId, messageTag: self.stateTag) |> deliverOnMainQueue).start(next: { [weak self] value in - guard let strongSelf = self, let value = value else { + guard let strongSelf = self else { return } - strongSelf.updateZoomLevel(level: ZoomLevel(rawValue: value.zoomLevel)) + if let value = value { + strongSelf.updateZoomLevel(level: ZoomLevel(rawValue: value.zoomLevel)) + } + strongSelf.requestHistoryAroundVisiblePosition(synchronous: false, reloadAtTop: false) }) - self.requestHistoryAroundVisiblePosition(synchronous: false, reloadAtTop: false) - self.hiddenMediaDisposable = context.sharedContext.mediaManager.galleryHiddenMediaManager.hiddenIds().start(next: { [weak self] ids in guard let strongSelf = self else { return @@ -2086,6 +2092,8 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro transition.updateFrame(node: self.itemGrid, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height))) if let items = self.items { + let wasFirstTime = !self.didUpdateItemsOnce + self.didUpdateItemsOnce = true let fixedItemHeight: CGFloat? switch self.contentType { case .files, .music, .voiceAndVideoMessages: @@ -2146,7 +2154,7 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro fixedItemHeight = nil } - self.itemGrid.update(size: size, insets: UIEdgeInsets(top: topInset, left: sideInset, bottom: bottomInset, right: sideInset), scrollIndicatorInsets: UIEdgeInsets(top: 0.0, left: sideInset, bottom: bottomInset, right: sideInset), lockScrollingAtTop: isScrollingLockedAtTop, fixedItemHeight: fixedItemHeight, items: items) + self.itemGrid.update(size: size, insets: UIEdgeInsets(top: topInset, left: sideInset, bottom: bottomInset, right: sideInset), scrollIndicatorInsets: UIEdgeInsets(top: 0.0, left: sideInset, bottom: bottomInset, right: sideInset), lockScrollingAtTop: isScrollingLockedAtTop, fixedItemHeight: fixedItemHeight, items: items, synchronous: wasFirstTime) } }