diff --git a/DivKit/Actions/DivActionURLHandler.swift b/DivKit/Actions/DivActionURLHandler.swift index 52232854..5d808941 100644 --- a/DivKit/Actions/DivActionURLHandler.swift +++ b/DivKit/Actions/DivActionURLHandler.swift @@ -144,8 +144,8 @@ public final class DivActionURLHandler { index: index, numberOfPages: pagerState.numberOfPages ) - case is TabViewState: - setTabsCurrentItem(id: id, index: index) + case let tabsState as TabViewState: + setTabsCurrentItem(id: id, index: index, countOfPages: tabsState.countOfPages) default: return } @@ -172,7 +172,16 @@ public final class DivActionURLHandler { numberOfPages: pagerState.numberOfPages ) case let tabsState as TabViewState: - setTabsCurrentItem(id: id, index: Int(tabsState.selectedPageIndex) + 1) + let nextIndex = getNextIndex( + current: Int(tabsState.selectedPageIndex), + count: tabsState.countOfPages, + overflow: overflow + ) + setTabsCurrentItem( + id: id, + index: nextIndex, + countOfPages: tabsState.countOfPages + ) default: return } @@ -212,7 +221,16 @@ public final class DivActionURLHandler { numberOfPages: pagerState.numberOfPages ) case let tabsState as TabViewState: - setTabsCurrentItem(id: id, index: Int(tabsState.selectedPageIndex) - 1) + let prevIndex = getPreviousIndex( + current: Int(tabsState.selectedPageIndex), + count: tabsState.countOfPages, + overflow: overflow + ) + setTabsCurrentItem( + id: id, + index: prevIndex, + countOfPages: tabsState.countOfPages + ) default: return } @@ -253,10 +271,13 @@ public final class DivActionURLHandler { ) } - private func setTabsCurrentItem(id: String, index: Int) { + private func setTabsCurrentItem(id: String, index: Int, countOfPages: Int) { blockStateStorage.setState( id: id, - state: TabViewState(selectedPageIndex: CGFloat(max(0, index))) + state: TabViewState( + selectedPageIndex: CGFloat(max(0, index)), + countOfPages: countOfPages + ) ) } } diff --git a/DivKit/DivKitInfo.swift b/DivKit/DivKitInfo.swift index 7a52cc33..c943c24c 100644 --- a/DivKit/DivKitInfo.swift +++ b/DivKit/DivKitInfo.swift @@ -1,3 +1,3 @@ public enum DivKitInfo { - public static let version = "23.6.0" + public static let version = "23.7.0" } diff --git a/DivKit/Extensions/DelayExtensions.swift b/DivKit/Extensions/DelayExtensions.swift index b3d9624a..137e4e37 100644 --- a/DivKit/Extensions/DelayExtensions.swift +++ b/DivKit/Extensions/DelayExtensions.swift @@ -1,8 +1,7 @@ import LayoutKit extension Delay { - init?(milliseconds: Int) { - guard milliseconds >= 0 else { return nil } + init(milliseconds: Int) { self.init(Double(milliseconds) / 1000) } } diff --git a/DivKit/Extensions/DivAnimationExtensions.swift b/DivKit/Extensions/DivAnimationExtensions.swift index ff5ed5d2..34d19573 100644 --- a/DivKit/Extensions/DivAnimationExtensions.swift +++ b/DivKit/Extensions/DivAnimationExtensions.swift @@ -41,8 +41,8 @@ extension DivAnimation { kind: kind, start: startValue ?? kind.defaultStartValue(for: type), end: endValue ?? kind.defaultEndValue(for: type), - duration: Duration(milliseconds: resolveDuration(expressionResolver)) ?? .default, - delay: Delay(milliseconds: resolveStartDelay(expressionResolver)) ?? 0, + duration: Duration(milliseconds: resolveDuration(expressionResolver)), + delay: Delay(milliseconds: resolveStartDelay(expressionResolver)), timingFunction: resolveInterpolator(expressionResolver).asTimingFunction() ) @@ -106,7 +106,3 @@ extension TimeOrientation { } } } - -extension Duration { - fileprivate static let `default` = Duration(milliseconds: 100)! -} diff --git a/DivKit/Extensions/DivAppearanceTransitionExtensions.swift b/DivKit/Extensions/DivAppearanceTransitionExtensions.swift index 8890447e..5158f1f2 100644 --- a/DivKit/Extensions/DivAppearanceTransitionExtensions.swift +++ b/DivKit/Extensions/DivAppearanceTransitionExtensions.swift @@ -49,11 +49,9 @@ extension DivAppearanceTransition { kind: kind, start: type == .appearing ? value1 : value2, end: type == .appearing ? value2 : value1, - duration: Duration(milliseconds: transition.resolveDuration(expressionResolver)) - ?? 0.3, - delay: Delay(milliseconds: transition.resolveStartDelay(expressionResolver)) ?? 0, - timingFunction: transition.resolveInterpolator(expressionResolver) - .asTimingFunction() + duration: Duration(milliseconds: transition.resolveDuration(expressionResolver)), + delay: Delay(milliseconds: transition.resolveStartDelay(expressionResolver)), + timingFunction: transition.resolveInterpolator(expressionResolver).asTimingFunction() ) return [animation] diff --git a/DivKit/Extensions/DivBase/DivBaseExtensions.swift b/DivKit/Extensions/DivBase/DivBaseExtensions.swift index d97bb71f..81e8eb5e 100644 --- a/DivKit/Extensions/DivBase/DivBaseExtensions.swift +++ b/DivKit/Extensions/DivBase/DivBaseExtensions.swift @@ -362,7 +362,7 @@ extension DivTooltip { return BlockTooltip( id: id, block: block, - duration: Duration(milliseconds: resolveDuration(expressionResolver)) ?? 0, + duration: Duration(milliseconds: resolveDuration(expressionResolver)), offset: offset?.cast(with: expressionResolver) ?? .zero, position: position ) diff --git a/DivKit/Extensions/DivChangeTransitionExtensions.swift b/DivKit/Extensions/DivChangeTransitionExtensions.swift index e146ceaa..a0c43760 100644 --- a/DivKit/Extensions/DivChangeTransitionExtensions.swift +++ b/DivKit/Extensions/DivChangeTransitionExtensions.swift @@ -8,10 +8,8 @@ extension DivChangeTransition { switch self { case let .divChangeBoundsTransition(transition): return ChangeBoundsTransition( - duration: Duration( - milliseconds: transition.resolveDuration(expressionResolver) - ) ?? 0.3, - delay: Delay(milliseconds: transition.resolveStartDelay(expressionResolver)) ?? 0, + duration: Duration(milliseconds: transition.resolveDuration(expressionResolver)), + delay: Delay(milliseconds: transition.resolveStartDelay(expressionResolver)), timingFunction: transition.resolveInterpolator(expressionResolver) .asTimingFunction() ) diff --git a/DivKit/Extensions/DivFadeTransitionExtensions.swift b/DivKit/Extensions/DivFadeTransitionExtensions.swift index 5af29c70..9a06e83f 100644 --- a/DivKit/Extensions/DivFadeTransitionExtensions.swift +++ b/DivKit/Extensions/DivFadeTransitionExtensions.swift @@ -10,8 +10,8 @@ extension DivFadeTransition { kind: .fade, start: resolveAlpha(expressionResolver), end: 1, - duration: Duration(milliseconds: resolveDuration(expressionResolver)) ?? 0.3, - delay: Delay(milliseconds: resolveStartDelay(expressionResolver)) ?? 0, + duration: Duration(milliseconds: resolveDuration(expressionResolver)), + delay: Delay(milliseconds: resolveStartDelay(expressionResolver)), timingFunction: resolveInterpolator(expressionResolver).asTimingFunction() ) } diff --git a/DivKit/Extensions/DivStateExtensions.swift b/DivKit/Extensions/DivStateExtensions.swift index 4f0b4bab..0108c9ec 100644 --- a/DivKit/Extensions/DivStateExtensions.swift +++ b/DivKit/Extensions/DivStateExtensions.swift @@ -202,8 +202,8 @@ extension DivAnimation { kind: kind, start: resolveStartValue(expressionResolver) ?? kind.defaultStartValue(for: type), end: resolveEndValue(expressionResolver) ?? kind.defaultEndValue(for: type), - duration: Duration(milliseconds: resolveDuration(expressionResolver)) ?? 0.3, - delay: Delay(milliseconds: resolveStartDelay(expressionResolver)) ?? 0, + duration: Duration(milliseconds: resolveDuration(expressionResolver)), + delay: Delay(milliseconds: resolveStartDelay(expressionResolver)), timingFunction: resolveInterpolator(expressionResolver).asTimingFunction() ) diff --git a/DivKit/Extensions/DivTabsExtensions.swift b/DivKit/Extensions/DivTabsExtensions.swift index 25f2bff1..2f30e8b9 100644 --- a/DivKit/Extensions/DivTabsExtensions.swift +++ b/DivKit/Extensions/DivTabsExtensions.swift @@ -88,7 +88,8 @@ extension DivTabs: DivBlockModeling { index = CGFloat(resolveSelectedTab(context.expressionResolver)) } let newState = TabViewState( - selectedPageIndex: min(index, CGFloat(tabs.count) - 1) + selectedPageIndex: min(index, CGFloat(tabs.count) - 1), + countOfPages: tabs.count ) stateStorage.setState(path: path, state: newState) return newState diff --git a/DivKit/Extensions/DurationExtensions.swift b/DivKit/Extensions/DurationExtensions.swift index a8ae9e5c..36b0fc7e 100644 --- a/DivKit/Extensions/DurationExtensions.swift +++ b/DivKit/Extensions/DurationExtensions.swift @@ -1,8 +1,7 @@ import LayoutKit extension Duration { - init?(milliseconds: Int) { - guard milliseconds > 0 else { return nil } + init(milliseconds: Int) { self.init(Double(milliseconds) / 1000) } } diff --git a/LayoutKit/LayoutKit/Blocks/Duration.swift b/LayoutKit/LayoutKit/Blocks/Duration.swift index b8ff3aed..a6eb2dea 100644 --- a/LayoutKit/LayoutKit/Blocks/Duration.swift +++ b/LayoutKit/LayoutKit/Blocks/Duration.swift @@ -2,7 +2,7 @@ public struct Duration: ExpressibleByFloatLiteral, ExpressibleByIntegerLiteral, public let value: Double public init(_ value: Double) { - precondition(value > 0, "Duration must be positive number") + precondition(value >= 0, "Duration must be non-negative number") self.value = value } diff --git a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabContentsView.swift b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabContentsView.swift index 4c52a353..92c41c39 100644 --- a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabContentsView.swift +++ b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabContentsView.swift @@ -207,13 +207,15 @@ internal class TabContentsView: BlockView { private func updateSelectedPageIndexFromRelativeContentOffset(isIntermediate: Bool) { notifyDelegateAboutSelectedPageIndexChange( - relativeContentOffset, + selectedPageIndex: relativeContentOffset, + countOfPages: model.pages.count, isIntermediate: isIntermediate ) } private func notifyDelegateAboutSelectedPageIndexChange( - _ selectedPageIndex: CGFloat, + selectedPageIndex: CGFloat, + countOfPages: Int, isIntermediate: Bool ) { let roundedIndex = selectedPageIndex.rounded(.toNearestOrAwayFromZero) @@ -224,7 +226,7 @@ internal class TabContentsView: BlockView { let index = isIntermediate ? selectedPageIndex : roundedIndex self.selectedPageIndex = index updatesDelegate?.onSelectedPageIndexChanged(index, inModel: model) - let state = TabViewState(selectedPageIndex: index) + let state = TabViewState(selectedPageIndex: index, countOfPages: countOfPages) observer?.elementStateChanged(state, forPath: model.path) } } diff --git a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabViewState.swift b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabViewState.swift index 655e180a..fe8e6c8e 100644 --- a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabViewState.swift +++ b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabViewState.swift @@ -5,10 +5,12 @@ import CommonCore public struct TabViewState: ElementState, Equatable { public let selectedPageIndex: CGFloat + public let countOfPages: Int - public static let `default` = TabViewState(selectedPageIndex: 0) + public static let `default` = TabViewState(selectedPageIndex: 0, countOfPages: 0) - public init(selectedPageIndex: CGFloat) { + public init(selectedPageIndex: CGFloat, countOfPages: Int) { self.selectedPageIndex = selectedPageIndex + self.countOfPages = countOfPages } }