Fixed crash of infinite scroll pager built with item_builder

commit_hash:0aa265991666f9e70459d1bfa1804f60c8698f08
This commit is contained in:
denlvovich
2025-08-05 12:40:04 +03:00
parent 52c06a652a
commit cfad5bcceb
3 changed files with 27 additions and 19 deletions
@@ -22,7 +22,7 @@ extension DivGalleryProtocol {
scrollMode: GalleryViewModel.ScrollMode,
columnCount: Int? = nil,
infiniteScroll: Bool = false,
bufferSize: Int = 1,
layoutMode: PagerBlock.LayoutMode? = nil,
scrollbar: GalleryViewModel.Scrollbar = .none,
transformation: ElementsTransformation? = nil
) throws -> GalleryViewModel {
@@ -41,10 +41,10 @@ extension DivGalleryProtocol {
)
}
if let itemBuilder {
children = itemBuilder.makeBlocks(context: context, mappedBy: blockMapper)
children = if let itemBuilder {
itemBuilder.makeBlocks(context: context, mappedBy: blockMapper)
} else {
children = nonNilItems.makeBlocks(
nonNilItems.makeBlocks(
context: context,
sizeModifier: DivGallerySizeModifier(
context: context,
@@ -54,7 +54,10 @@ extension DivGalleryProtocol {
mappedBy: blockMapper
)
}
let itemsCount = children.count
let bufferSize = layoutMode.map { min($0.bufferSize(itemsCount: itemsCount), itemsCount) } ?? 1
if infiniteScroll {
let leadingBuffer = children[..<bufferSize]
let trailingBuffer = children[(children.count - bufferSize)...]
@@ -125,3 +128,16 @@ extension DivGalleryProtocol {
return String(typeName)
}
}
extension PagerBlock.LayoutMode {
fileprivate func bufferSize(itemsCount: Int) -> Int {
switch self {
case let .pageSize(relativeValue):
Int(1 / relativeValue.rawValue) + 1
case .neighbourPageSize:
2
case .pageContentSize:
itemsCount
}
}
}
@@ -37,7 +37,7 @@ extension DivPager: DivBlockModeling, DivGalleryProtocol {
defaultCrossAlignment: crossAlignment,
scrollMode: .autoPaging(inertionEnabled: false),
infiniteScroll: resolveInfiniteScroll(expressionResolver),
bufferSize: min(layoutMode.bufferSize(itemsCount: items.count), items.count),
layoutMode: layoutMode,
transformation: pageTransformation?.resolve(
expressionResolver,
scrollDirection: scrollDirection
@@ -73,19 +73,6 @@ extension DivPager: DivBlockModeling, DivGalleryProtocol {
}
}
extension PagerBlock.LayoutMode {
fileprivate func bufferSize(itemsCount: Int) -> Int {
switch self {
case let .pageSize(relativeValue):
Int(1 / relativeValue.rawValue) + 1
case .neighbourPageSize:
2
case .pageContentSize:
itemsCount
}
}
}
extension DivPager.Orientation {
var direction: ScrollDirection {
switch self {
@@ -15,6 +15,11 @@ enum InfiniteScroll {
alignment: Alignment = .center,
insetMode: InsetMode = .fixed(values: .zero)
) -> Position? {
guard bufferSize > 0 else {
assertionFailure("Buffer size couldn't be less than one element for infinite scroll")
return nil
}
let itemsCount = origins.count
let cycleStartIndex = bufferSize
let cycleEndIndex = itemsCount - bufferSize - 1