Files
divkit/client/ios/DivKit/Extensions/DivGallery/DivGalleryExtensions.swift
T
babaevmm 16904977c6 fix crash in empty gallery
commit_hash:6e311d5222658a089990926b66a34d05b5021523
2025-10-27 22:42:48 +03:00

123 lines
3.5 KiB
Swift

import CoreGraphics
import LayoutKit
import VGSL
extension DivGallery: DivBlockModeling, DivGalleryProtocol {
public func makeBlock(context: DivBlockModelingContext) throws -> Block {
let context = modifiedContextParentPath(context)
return try modifyError({ DivBlockModelingError($0.message, path: context.path) }) {
try applyBaseProperties(
to: { try makeBaseBlock(context: context) },
context: context,
actionsHolder: nil,
applyPaddings: false
)
}
}
private func makeBaseBlock(context: DivBlockModelingContext) throws -> Block {
let expressionResolver = context.expressionResolver
let itemSpacing = resolveItemSpacing(expressionResolver)
let model = try makeGalleryModel(
context: context,
direction: resolveOrientation(expressionResolver).direction,
alignment: .center,
spacing: CGFloat(itemSpacing),
crossSpacing: CGFloat(resolveCrossSpacing(expressionResolver) ?? itemSpacing),
defaultCrossAlignment: resolveCrossContentAlignment(expressionResolver).blockAlignment,
scrollMode: resolveScrollMode(expressionResolver).blockScrollMode,
columnCount: resolveColumnCount(expressionResolver),
scrollbar: resolveScrollbar(expressionResolver).blockScrollbar
)
return try GalleryBlock(
model: model,
state: getState(context: context, itemsCount: model.items.count),
widthTrait: resolveWidthTrait(context),
heightTrait: resolveHeightTrait(context)
)
}
private func getState(
context: DivBlockModelingContext,
itemsCount: Int
) -> GalleryViewState {
let path = context.path
let index: CGFloat
let scrollRange: CGFloat?
let animated: Bool
if let state: GalleryViewState = context.blockStateStorage.getState(path) {
switch state.contentPosition {
case .offset:
return state
case let .paging(savedIndex):
index = savedIndex
}
scrollRange = state.scrollRange
animated = state.animated
} else {
index = CGFloat(resolveDefaultItem(context.expressionResolver))
if index == 0 {
let newState = GalleryViewState(contentOffset: 0, itemsCount: itemsCount)
context.blockStateStorage.setState(path: path, state: newState)
return newState
}
scrollRange = nil
animated = true
}
let clampedIndex = index.clamp(0.0...CGFloat(max(itemsCount - 1, 0)))
let newState = GalleryViewState(
contentPosition: .paging(index: clampedIndex),
itemsCount: itemsCount,
isScrolling: false,
scrollRange: scrollRange,
animated: animated
)
context.blockStateStorage.setState(path: path, state: newState)
return newState
}
}
extension DivGallery.Orientation {
fileprivate var direction: ScrollDirection {
switch self {
case .horizontal:
.horizontal
case .vertical:
.vertical
}
}
}
extension DivGallery.ScrollMode {
fileprivate var blockScrollMode: GalleryViewModel.ScrollMode {
switch self {
case .default:
.default
case .paging:
.autoPaging(inertionEnabled: true)
}
}
}
extension DivGallery.CrossContentAlignment {
fileprivate var blockAlignment: Alignment {
switch self {
case .start: .leading
case .center: .center
case .end: .trailing
}
}
}
extension DivGallery.Scrollbar {
fileprivate var blockScrollbar: GalleryViewModel.Scrollbar {
switch self {
case .none:
.none
case .auto:
.auto
}
}
}