This commit is contained in:
Isaac 2026-03-10 00:38:36 +01:00
parent 83af56d379
commit 9a4327116d
60 changed files with 237 additions and 70 deletions

View file

@ -86,7 +86,7 @@ private final class ArchivedStickersNoticeAlertContentNode: AlertContentNode {
self.textNode = ASTextNode()
self.textNode.maximumNumberOfLines = 4
self.listView = ListView()
self.listView = ListViewImpl()
self.listView.isOpaque = false
self.actionNodesSeparator = ASDisplayNode()

View file

@ -256,7 +256,7 @@ final class CallListControllerNode: ASDisplayNode {
self.statePromise = ValuePromise(self.currentState, ignoreRepeated: true)
self.focusOnItemTag = focusOnItemTag
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string

View file

@ -225,7 +225,7 @@ public final class ChatListSearchRecentPeersNode: ASDisplayNode {
self.peerContextAction = peerContextAction
self.isPeerSelected = isPeerSelected
self.listView = ListView()
self.listView = ListViewImpl()
self.listView.preloadPages = false
self.listView.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
self.listView.accessibilityPageScrolledString = { row, count in

View file

@ -1173,7 +1173,7 @@ final class ChatListControllerNode: ASDisplayNode, ASGestureRecognizerDelegate {
var cancelEditing: (() -> Void)?
var dismissSearch: (() -> Void)?
let debugListView = ListView()
let debugListView = ListViewImpl()
init(context: AccountContext, location: ChatListControllerLocation, previewing: Bool, controlsHistoryPreload: Bool, presentationData: PresentationData, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, controller: ChatListControllerImpl) {
self.context = context

View file

@ -1788,7 +1788,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
self.selectedMessages = interaction.getSelectedMessageIds()
self.selectedMessagesPromise.set(.single(self.selectedMessages))
self.recentListNode = ListView()
self.recentListNode = ListViewImpl()
self.recentListNode.preloadPages = false
self.recentListNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
self.recentListNode.accessibilityPageScrolledString = { row, count in
@ -1799,7 +1799,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
self.shimmerNode.isUserInteractionEnabled = false
self.shimmerNode.allowsGroupOpacity = true
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode?.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
self.listNode?.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string

View file

@ -1121,7 +1121,7 @@ public enum ChatListNodeEmptyState: Equatable {
case empty(isLoading: Bool, hasArchiveInfo: Bool)
}
public final class ChatListNode: ListView {
public final class ChatListNode: ListViewImpl {
public enum OpenStoriesSubject {
case peer(EnginePeer.Id)
case archive

View file

@ -1233,7 +1233,7 @@ public final class ContactListNode: ASDisplayNode {
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
self.presentationData = presentationData
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -299,7 +299,7 @@ public final class ContactsSearchContainerNode: SearchDisplayControllerContentNo
self.backgroundNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
self.backgroundNode.alpha = 0.0
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
self.listNode.alpha = 0.0

View file

@ -290,7 +290,7 @@ final class InviteContactsControllerNode: ASDisplayNode {
self.presentationDataPromise = Promise(self.presentationData)
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -38,7 +38,7 @@ private final class ListViewBackingLayer: CALayer {
}
public final class ListViewBackingView: UIView {
public fileprivate(set) weak var target: ListView?
public fileprivate(set) weak var target: ListViewImpl?
override public class var layerClass: AnyClass {
return ListViewBackingLayer.self
@ -154,7 +154,7 @@ private func cancelContextGestures(view: UIView) {
}
}
open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDelegate {
open class ListViewImpl: ASDisplayNode, ListView, ASScrollViewDelegate, ASGestureRecognizerDelegate {
public struct ScrollingIndicatorState {
public struct Item {
public var index: Int
@ -470,8 +470,8 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
override public init() {
class DisplayLinkProxy: NSObject {
weak var target: ListView?
init(target: ListView) {
weak var target: ListViewImpl?
init(target: ListViewImpl) {
self.target = target
}

View file

@ -0,0 +1,167 @@
import UIKit
import AsyncDisplayKit
import SwiftSignalKit
public protocol ListView: ASDisplayNode {
// MARK: - Configuration Properties (get/set)
var scroller: ListViewScroller { get }
var scrollEnabled: Bool { get set }
var preloadPages: Bool { get set }
var rotated: Bool { get set }
var experimentalSnapScrollToItem: Bool { get set }
var useMainQueueTransactions: Bool { get set }
var keepMinimalScrollHeightWithTopInset: CGFloat? { get set }
var itemNodeHitTest: ((CGPoint) -> Bool)? { get set }
var stackFromBottom: Bool { get set }
var stackFromBottomInsetItemFactor: CGFloat { get set }
var limitHitTestToNodes: Bool { get set }
var keepTopItemOverscrollBackground: ListViewKeepTopItemOverscrollBackground? { get set }
var keepBottomItemOverscrollBackground: UIColor? { get set }
var snapToBottomInsetUntilFirstInteraction: Bool { get set }
var allowInsetFixWhileTracking: Bool { get set }
var visualInsets: UIEdgeInsets? { get set }
var dynamicVisualInsets: (() -> UIEdgeInsets)? { get set }
var verticalScrollIndicatorColor: UIColor? { get set }
var verticalScrollIndicatorFollowsOverscroll: Bool { get set }
var globalIgnoreScrollingEvents: Bool { get set }
var ignoreStopScrolling: Bool { get set }
var synchronousNodes: Bool { get set }
var debugInfo: Bool { get set }
var useSingleDimensionTouchPoint: Bool { get set }
var defaultToSynchronousTransactionWhileScrolling: Bool { get set }
var enableExtractedBackgrounds: Bool { get set }
var itemHeaderNodesAlpha: CGFloat { get set }
var autoScrollWhenReordering: Bool { get set }
var reorderedItemHasShadow: Bool { get set }
var reorderingRequiresLongPress: Bool { get set }
var tempTopInset: CGFloat { get set }
var accessibilityPageScrolledString: ((String, String) -> String)? { get set }
// MARK: - Read-only State Properties
var visibleSize: CGSize { get }
var insets: UIEdgeInsets { get }
var headerInsets: UIEdgeInsets { get }
var scrollIndicatorInsets: UIEdgeInsets { get }
var isTracking: Bool { get }
var trackingOffset: CGFloat { get }
var beganTrackingAtTopOrigin: Bool { get }
var isDragging: Bool { get }
var isDeceleratingAfterTracking: Bool { get }
var isReordering: Bool { get }
var edgeEffectExtension: CGFloat { get }
var displayedItemRange: ListViewDisplayedItemRange { get }
var internalDisplayedItemRange: ListViewDisplayedItemRange? { get }
var opaqueTransactionState: Any? { get }
// MARK: - Callbacks
var displayedItemRangeChanged: (ListViewDisplayedItemRange, Any?) -> Void { get set }
var visibleContentOffsetChanged: (ListViewVisibleContentOffset, ContainedViewLayoutTransition) -> Void { get set }
var visibleBottomContentOffsetChanged: (ListViewVisibleContentOffset) -> Void { get set }
var beganInteractiveDragging: (CGPoint) -> Void { get set }
var endedInteractiveDragging: (CGPoint) -> Void { get set }
var didEndScrolling: ((Bool) -> Void)? { get set }
var didEndScrollingWithOverscroll: (() -> Void)? { get set }
var generalScrollDirectionUpdated: (GeneralScrollDirection) -> Void { get set }
var updateFloatingHeaderOffset: ((CGFloat, ContainedViewLayoutTransition) -> Void)? { get set }
var didScrollWithOffset: ((CGFloat, ContainedViewLayoutTransition, ListViewItemNode?, Bool) -> Void)? { get set }
var addContentOffset: ((CGFloat, ListViewItemNode?) -> Void)? { get set }
var shouldStopScrolling: ((CGFloat) -> Bool)? { get set }
var onContentsUpdated: ((ContainedViewLayoutTransition) -> Void)? { get set }
var onEdgeEffectExtensionUpdated: ((ContainedViewLayoutTransition) -> Void)? { get set }
var updateScrollingIndicator: ((ListViewImpl.ScrollingIndicatorState?, ContainedViewLayoutTransition) -> Void)? { get set }
var tapped: (() -> Void)? { get set }
var willBeginReorder: (CGPoint) -> Void { get set }
var reorderBegan: () -> Void { get set }
var reorderItem: (Int, Int, Any?) -> Signal<Bool, NoError> { get set }
var reorderCompleted: (Any?) -> Void { get set }
// MARK: - Methods
func transaction(
deleteIndices: [ListViewDeleteItem],
insertIndicesAndItems: [ListViewInsertItem],
updateIndicesAndItems: [ListViewUpdateItem],
options: ListViewDeleteAndInsertOptions,
scrollToItem: ListViewScrollToItem?,
additionalScrollDistance: CGFloat,
updateSizeAndInsets: ListViewUpdateSizeAndInsets?,
stationaryItemRange: (Int, Int)?,
updateOpaqueState: Any?,
completion: @escaping (ListViewDisplayedItemRange) -> Void
)
func addAfterTransactionsCompleted(_ f: @escaping () -> Void)
func visibleContentOffset() -> ListViewVisibleContentOffset
func visibleBottomContentOffset() -> ListViewVisibleContentOffset
func stopScrolling()
func cancelTracking()
@discardableResult func scrollToOffsetFromTop(_ offset: CGFloat, animated: Bool) -> Bool
@discardableResult func scrollWithDirection(_ direction: ListViewScrollDirection, distance: CGFloat) -> Bool
func transferVelocity(_ velocity: CGFloat)
func resetScrolledToItem()
func itemIndexAtPoint(_ point: CGPoint) -> Int?
func itemNodeAtIndex(_ index: Int) -> ListViewItemNode?
func indexOf(itemNode: ListViewItemNode) -> Int?
func forEachItemNode(_ f: (ASDisplayNode) -> Void)
func forEachRemovedItemNode(_ f: (ASDisplayNode) -> Void)
func forEachVisibleItemNode(_ f: (ASDisplayNode) -> Void)
func enumerateItemNodes(_ f: (ASDisplayNode) -> Bool)
func forEachItemHeaderNode(_ f: (ListViewItemHeaderNode) -> Void)
func forEachAccessoryItemNode(_ f: (ListViewAccessoryItemNode) -> Void)
func ensureItemNodeVisible(_ node: ListViewItemNode, animated: Bool, overflow: CGFloat, allowIntersection: Bool, atTop: Bool, curve: ListViewAnimationCurve)
func ensureItemNodeVisibleAtTopInset(_ node: ListViewItemNode)
func itemNodeRelativeOffset(_ node: ListViewItemNode) -> CGFloat?
func itemNodeVisibleInsideInsets(_ node: ListViewItemNode) -> Bool
func clearHighlightAnimated(_ animated: Bool)
func updateNodeHighlightsAnimated(_ animated: Bool)
func cancelSelection()
func updateVisibleItemRange(force: Bool)
func flashHeaderItems(duration: Double)
func withTransaction(_ f: @escaping () -> Void)
func customItemDeleteAnimationDuration(itemNode: ListViewItemNode) -> Double?
}
// MARK: - Default Parameter Values
// Swift protocols cannot have default parameter values, so we provide them via extensions.
public extension ListView {
func transaction(
deleteIndices: [ListViewDeleteItem],
insertIndicesAndItems: [ListViewInsertItem],
updateIndicesAndItems: [ListViewUpdateItem],
options: ListViewDeleteAndInsertOptions,
scrollToItem: ListViewScrollToItem? = nil,
additionalScrollDistance: CGFloat = 0.0,
updateSizeAndInsets: ListViewUpdateSizeAndInsets? = nil,
stationaryItemRange: (Int, Int)? = nil,
updateOpaqueState: Any?,
completion: @escaping (ListViewDisplayedItemRange) -> Void = { _ in }
) {
self.transaction(
deleteIndices: deleteIndices,
insertIndicesAndItems: insertIndicesAndItems,
updateIndicesAndItems: updateIndicesAndItems,
options: options,
scrollToItem: scrollToItem,
additionalScrollDistance: additionalScrollDistance,
updateSizeAndInsets: updateSizeAndInsets,
stationaryItemRange: stationaryItemRange,
updateOpaqueState: updateOpaqueState,
completion: completion
)
}
func updateVisibleItemRange() {
self.updateVisibleItemRange(force: false)
}
func flashHeaderItems() {
self.flashHeaderItems(duration: 2.0)
}
func ensureItemNodeVisible(_ node: ListViewItemNode, animated: Bool = true, overflow: CGFloat = 0.0, allowIntersection: Bool = false, atTop: Bool = false, curve: ListViewAnimationCurve = .Default(duration: 0.25)) {
self.ensureItemNodeVisible(node, animated: animated, overflow: overflow, allowIntersection: allowIntersection, atTop: atTop, curve: curve)
}
}

View file

@ -385,7 +385,7 @@ final class HashtagSearchRecentListNode: ASDisplayNode {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.presentationData = presentationData
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -362,7 +362,7 @@ public final class InviteLinkInviteController: ViewController {
self.historyBackgroundNode.addSubnode(self.historyBackgroundContentNode)
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
self.listNode.accessibilityPageScrolledString = { row, count in

View file

@ -567,7 +567,7 @@ public final class InviteLinkViewController: ViewController {
self.historyBackgroundNode.addSubnode(self.historyBackgroundContentNode)
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
self.listNode.accessibilityPageScrolledString = { row, count in

View file

@ -364,7 +364,7 @@ public final class InviteRequestsSearchContainerNode: SearchDisplayControllerCon
self.dimNode = ASDisplayNode()
self.dimNode.backgroundColor = UIColor.black.withAlphaComponent(0.5)
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -310,7 +310,7 @@ open class ItemListControllerNode: ASDisplayNode, ASGestureRecognizerDelegate {
self.navigationBar = navigationBar
self.listNodeContainer = ASDisplayNode()
self.listNode = ListView()
self.listNode = ListViewImpl()
self.leftOverlayNode = ASDisplayNode()
self.leftOverlayNode.isUserInteractionEnabled = false
self.rightOverlayNode = ASDisplayNode()

View file

@ -399,7 +399,7 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM
self.state = LocationPickerState()
self.statePromise = Promise(self.state)
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
self.listNode.verticalScrollIndicatorFollowsOverscroll = true

View file

@ -138,7 +138,7 @@ final class LocationSearchContainerNode: ASDisplayNode {
self.dimNode = ASDisplayNode()
self.dimNode.backgroundColor = .clear // UIColor.black.withAlphaComponent(0.5)
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
self.listNode.alpha = 0.0
self.listNode.accessibilityPageScrolledString = { row, count in

View file

@ -309,7 +309,7 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
self.state = LocationViewState()
self.statePromise = Promise(self.state)
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
self.listNode.verticalScrollIndicatorFollowsOverscroll = true

View file

@ -280,7 +280,7 @@ private class MediaGroupsAlbumGridItemNode: ListViewItemNode {
private var enqueuedTransitions: [MediaGroupsAlbumGridItemNodeTransition] = []
init() {
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
super.init(layerBacked: false, rotated: false, seeThrough: false)

View file

@ -208,7 +208,7 @@ public final class MediaGroupsScreen: ViewController, AttachmentContainable {
self.containerNode = ASDisplayNode()
self.backgroundNode = NavigationBackgroundNode(color: self.presentationData.theme.rootController.tabBar.backgroundColor)
self.listNode = ListView()
self.listNode = ListViewImpl()
super.init()

View file

@ -128,7 +128,7 @@ final class ChannelDiscussionGroupSearchContainerNode: SearchDisplayControllerCo
self.presentationDataPromise = Promise(self.presentationData)
self.dimNode = ASDisplayNode()
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -367,12 +367,12 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
}
self.presentationDataPromise = Promise(self.presentationData)
self.emptyQueryListNode = ListView()
self.emptyQueryListNode = ListViewImpl()
self.emptyQueryListNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -207,7 +207,7 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
init(context: AccountContext, presentationData: PresentationData, forceTheme: PresentationTheme?, peerId: EnginePeer.Id, mode: ChannelMembersSearchControllerMode, filters: [ChannelMembersSearchFilter]) {
self.context = context
self.listNode = ListView()
self.listNode = ListViewImpl()
self.peerId = peerId
self.mode = mode
self.filters = filters

View file

@ -166,7 +166,7 @@ class DeleteAccountPeersItemNode: ListViewItemNode, ItemListItemNode {
self.maskNode = ASImageNode()
self.maskNode.isUserInteractionEnabled = false
self.listView = ListView()
self.listView = ListViewImpl()
self.listView.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
super.init(layerBacked: false)

View file

@ -167,7 +167,7 @@ private final class LocalizationListSearchContainerNode: SearchDisplayController
self.dimNode = ASDisplayNode()
self.dimNode.backgroundColor = .clear
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}
@ -379,7 +379,7 @@ final class LocalizationListControllerNode: ViewControllerTracingNode {
self.push = push
self.focusOnItemTag = focusOnItemTag
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.keepTopItemOverscrollBackground = ListViewKeepTopItemOverscrollBackground(color: presentationData.theme.list.blocksBackgroundColor, direction: true)
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string

View file

@ -491,7 +491,7 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
self.present = present
self.pushController = pushController
self.stateValue = Atomic(value: NotificationExceptionState(mode: mode))
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.keepTopItemOverscrollBackground = ListViewKeepTopItemOverscrollBackground(color: presentationData.theme.chatList.backgroundColor, direction: true)
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
@ -985,7 +985,7 @@ private final class NotificationExceptionsSearchContainerNode: SearchDisplayCont
self.dimNode = ASDisplayNode()
self.dimNode.backgroundColor = .clear
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -285,14 +285,14 @@ public final class SettingsSearchContainerNode: SearchDisplayControllerContentNo
self.presentationData = presentationData
self.presentationDataPromise = Promise(self.presentationData)
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
self.listNode.isHidden = true
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}
self.recentListNode = ListView()
self.recentListNode = ListViewImpl()
self.recentListNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
self.recentListNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
self.recentListNode.accessibilityPageScrolledString = { row, count in

View file

@ -731,7 +731,7 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
self.maskNode = ASImageNode()
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
super.init(layerBacked: false)

View file

@ -125,7 +125,7 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
private struct State {
var containerSize: CGSize
var containerInsets: UIEdgeInsets
var scrollingState: ListView.ScrollingIndicatorState?
var scrollingState: ListViewImpl.ScrollingIndicatorState?
var isScrolling: Bool
var isDragging: Bool
var theme: PresentationTheme
@ -288,7 +288,7 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
public func update(
containerSize: CGSize,
containerInsets: UIEdgeInsets,
scrollingState: ListView.ScrollingIndicatorState?,
scrollingState: ListViewImpl.ScrollingIndicatorState?,
isScrolling: Bool,
theme: PresentationTheme,
transition: ContainedViewLayoutTransition

View file

@ -465,7 +465,7 @@ public final class AsyncListComponent: Component {
private var ignoreUpdateVisibleItems: Bool = false
public override init(frame: CGRect) {
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.useMainQueueTransactions = true
self.listNode.scroller.delaysContentTouches = false
self.listNode.reorderedItemHasShadow = false

View file

@ -317,7 +317,7 @@ public final class AttachmentFileSearchContainerNode: SearchDisplayControllerCon
self.backgroundNode = ASDisplayNode()
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -159,7 +159,7 @@ public final class ChatHistorySearchContainerNode: SearchDisplayControllerConten
self.dimNode = ASDisplayNode()
self.dimNode.backgroundColor = .clear
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -281,7 +281,7 @@ public final class ChatInlineSearchResultsListComponent: Component {
private var hintAnimateListTransition: Bool = false
override public init(frame: CGRect) {
self.listNode = ListView()
self.listNode = ListViewImpl()
super.init(frame: frame)

View file

@ -883,7 +883,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
self.scanButton.title = presentationData.strings.PeerInfo_QRCode_Scan
self.scanButton.icon = UIImage(bundleImageName: "Settings/ScanQr")
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
super.init()

View file

@ -129,7 +129,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
self.panelButtonNode.setTitle(self.presentationData.strings.Channel_AdminLog_Settings, with: Font.regular(17.0), with: self.presentationData.theme.chat.inputPanel.panelControlAccentColor, for: [])
self.panelInfoButtonNode = HighlightableButtonNode()
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.transform = CATransform3DMakeRotation(CGFloat(Double.pi), 0.0, 0.0, 1.0)
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string

View file

@ -930,7 +930,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, ASScrollViewDelega
self.otherButton = HighlightableButtonNode()
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
super.init()

View file

@ -118,7 +118,7 @@ public final class GroupStickerSearchContainerNode: SearchDisplayControllerConte
}
self.presentationDataPromise = Promise(self.presentationData)
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -113,7 +113,7 @@ final class MiniAppListScreenComponent: Component {
}
}
private final class ContentListNode: ListView {
private final class ContentListNode: ListViewImpl {
weak var parentView: View?
let context: AccountContext
var presentationData: PresentationData

View file

@ -110,7 +110,7 @@ final class PeerInfoGroupsInCommonPaneNode: ASDisplayNode, PeerInfoPaneNode {
self.groupsInCommonContext = groupsInCommonContext
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -320,7 +320,7 @@ final class PeerInfoMembersPaneNode: ASDisplayNode, PeerInfoPaneNode {
self.action = action
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -158,7 +158,7 @@ final class PeerInfoRecommendedPeersPaneNode: ASDisplayNode, PeerInfoPaneNode {
self.openPeerContextAction = openPeerContextAction
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -198,7 +198,7 @@ private final class OldChannelsSearchContainerNode: SearchDisplayControllerConte
self.presentationData = presentationData
self.presentationDataPromise = Promise(self.presentationData)
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
self.listNode.isHidden = true
self.listNode.accessibilityPageScrolledString = { row, count in

View file

@ -301,7 +301,7 @@ final class QuickReplySetupScreenComponent: Component {
}
}
private final class ContentListNode: ListView {
private final class ContentListNode: ListViewImpl {
weak var parentView: View?
let context: AccountContext
var presentationData: PresentationData

View file

@ -115,7 +115,7 @@ private final class LocalizationListSearchContainerNode: SearchDisplayController
self.dimNode = ASDisplayNode()
self.dimNode.backgroundColor = UIColor.black.withAlphaComponent(0.5)
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}
@ -329,7 +329,7 @@ final class LanguageSelectionScreenNode: ViewControllerTracingNode {
self.push = push
self.selectLocalization = selectLocalization
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.keepTopItemOverscrollBackground = ListViewKeepTopItemOverscrollBackground(color: presentationData.theme.list.blocksBackgroundColor, direction: true)
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string

View file

@ -142,7 +142,7 @@ final class PeerSelectionScreenComponent: Component {
}
}
private final class ContentListNode: ListView {
private final class ContentListNode: ListViewImpl {
weak var parentView: View?
let context: AccountContext
var presentationData: PresentationData

View file

@ -722,7 +722,7 @@ public class ThemeCarouselThemeItemNode: ListViewItemNode, ItemListItemNode {
self.maskNode = ASImageNode()
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
super.init(layerBacked: false)

View file

@ -546,7 +546,7 @@ public class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
self.maskNode = ASImageNode()
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
super.init(layerBacked: false)

View file

@ -111,7 +111,7 @@ private final class TimezoneListSearchContainerNode: SearchDisplayControllerCont
self.dimNode = ASDisplayNode()
self.dimNode.backgroundColor = .clear
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}
@ -392,7 +392,7 @@ final class TimezoneSelectionScreenNode: ViewControllerTracingNode {
self.present = present
self.push = push
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
}

View file

@ -354,7 +354,7 @@ final class ThemeGridSearchContentNode: SearchDisplayControllerContentNode {
self.presentationDataPromise = Promise(self.presentationData)
self.dimNode = ASDisplayNode()
self.recentListNode = ListView()
self.recentListNode = ListViewImpl()
self.recentListNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
self.recentListNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string

View file

@ -463,7 +463,7 @@ private struct ChatHistoryAnimatedEmojiConfiguration {
private var nextClientId: Int32 = 1
public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHistoryListNode {
public final class ChatHistoryListNodeImpl: ListViewImpl, ChatHistoryNode, ChatHistoryListNode {
static let fixedAdMessageStableId: UInt32 = UInt32.max - 5000
public let context: AccountContext

View file

@ -197,7 +197,7 @@ class ChatSearchResultsControllerNode: ViewControllerTracingNode, ASScrollViewDe
self.animationCache = context.animationCache
self.animationRenderer = context.animationRenderer
self.listNode = ListView()
self.listNode = ListViewImpl()
self.listNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string

View file

@ -297,7 +297,7 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode {
self.backgroundView = GlassBackgroundView()
self.backgroundView.layer.anchorPoint = CGPoint()
self.listView = ListView()
self.listView = ListViewImpl()
self.listView.anchorPoint = CGPoint()
self.listView.isOpaque = false
self.listView.stackFromBottom = true

View file

@ -79,7 +79,7 @@ final class CommandMenuChatInputContextPanelNode: ChatInputContextPanelNode {
self.backgroundView = GlassBackgroundView()
self.backgroundView.layer.anchorPoint = CGPoint()
self.listView = ListView()
self.listView = ListViewImpl()
self.listView.clipsToBounds = false
self.listView.isOpaque = false
self.listView.stackFromBottom = true

View file

@ -152,7 +152,7 @@ final class EmojisChatInputContextPanelNode: ChatInputContextPanelNode {
self.clippingNode = ASDisplayNode()
self.clippingNode.clipsToBounds = true
self.listView = ListView()
self.listView = ListViewImpl()
self.listView.isOpaque = false
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
self.listView.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)

View file

@ -96,7 +96,7 @@ final class HashtagChatInputContextPanelNode: ChatInputContextPanelNode {
self.backgroundView = GlassBackgroundView()
self.backgroundView.layer.anchorPoint = CGPoint()
self.listView = ListView()
self.listView = ListViewImpl()
self.listView.isOpaque = false
self.listView.stackFromBottom = true
self.listView.limitHitTestToNodes = true

View file

@ -96,7 +96,7 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
private let batchVideoContext: QueueLocalObject<BatchVideoRenderingContext>
override init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, fontSize: PresentationFontSize, chatPresentationContext: ChatPresentationContext) {
self.listView = ListView()
self.listView = ListViewImpl()
self.listView.isOpaque = true
self.listView.backgroundColor = theme.list.plainBackgroundColor
self.listView.transform = CATransform3DMakeRotation(-CGFloat(CGFloat.pi / 2.0), 0.0, 0.0, 1.0)

View file

@ -80,7 +80,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
self.backgroundView = GlassBackgroundView()
self.backgroundView.layer.anchorPoint = CGPoint()
self.listView = ListView()
self.listView = ListViewImpl()
self.listView.isOpaque = false
self.listView.stackFromBottom = true
self.listView.limitHitTestToNodes = true

View file

@ -144,7 +144,7 @@ final class VerticalListContextResultsChatInputContextPanelNode: ChatInputContex
self.backgroundView = GlassBackgroundView()
self.backgroundView.layer.anchorPoint = CGPoint()
self.listView = ListView()
self.listView = ListViewImpl()
self.listView.isOpaque = false
self.listView.stackFromBottom = true
self.listView.limitHitTestToNodes = true

View file

@ -226,7 +226,7 @@ class WebSearchControllerNode: ASDisplayNode {
self.gridNode = GridNode()
self.gridNode.backgroundColor = theme.list.plainBackgroundColor
self.recentQueriesNode = ListView()
self.recentQueriesNode = ListViewImpl()
self.recentQueriesNode.backgroundColor = theme.list.plainBackgroundColor
self.recentQueriesNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string