diff --git a/submodules/ChatListUI/Sources/ChatListControllerNode.swift b/submodules/ChatListUI/Sources/ChatListControllerNode.swift index 7974b65990..da8ffefc24 100644 --- a/submodules/ChatListUI/Sources/ChatListControllerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListControllerNode.swift @@ -1957,8 +1957,13 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate { offset = 0.0 } + var allowAvatarsExpansion: Bool = true + if !self.mainContainerNode.currentItemNode.startedScrollingAtUpperBound && !self.mainContainerNode.storiesUnlocked { + allowAvatarsExpansion = false + } + if let navigationBarComponentView = self.navigationBarView.view as? ChatListNavigationBar.View { - navigationBarComponentView.applyScroll(offset: offset, transition: Transition(transition)) + navigationBarComponentView.applyScroll(offset: offset, allowAvatarsExpansion: allowAvatarsExpansion, transition: Transition(transition)) } } @@ -2209,7 +2214,7 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate { func willScrollToTop() { if let navigationBarComponentView = self.navigationBarView.view as? ChatListNavigationBar.View { - navigationBarComponentView.applyScroll(offset: 0.0, transition: Transition(animation: .curve(duration: 0.3, curve: .slide))) + navigationBarComponentView.applyScroll(offset: 0.0, allowAvatarsExpansion: false, transition: Transition(animation: .curve(duration: 0.3, curve: .slide))) } } diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index 54e6ef2d50..fe5bf95e5b 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -1193,6 +1193,8 @@ public final class ChatListNode: ListView { } } + public private(set) var startedScrollingAtUpperBound: Bool = false + public init(context: AccountContext, location: ChatListControllerLocation, chatListFilter: ChatListFilter? = nil, previewing: Bool, fillPreloadItems: Bool, mode: ChatListNodeMode, isPeerEnabled: ((EnginePeer) -> Bool)? = nil, theme: PresentationTheme, fontSize: PresentationFontSize, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, disableAnimations: Bool, isInlineMode: Bool) { self.context = context self.location = location @@ -2719,7 +2721,6 @@ public final class ChatListNode: ListView { } } } - var startedScrollingAtUpperBound = false var startedScrollingWithCanExpandHiddenItems = false self.beganInteractiveDragging = { [weak self] _ in @@ -2727,10 +2728,10 @@ public final class ChatListNode: ListView { return } switch strongSelf.visibleContentOffset() { - case .none, .unknown: - startedScrollingAtUpperBound = false - case let .known(value): - startedScrollingAtUpperBound = value <= 0.0 + case .none, .unknown: + strongSelf.startedScrollingAtUpperBound = false + case let .known(value): + strongSelf.startedScrollingAtUpperBound = value <= 0.0 } if let canExpandHiddenItems = strongSelf.canExpandHiddenItems { @@ -2752,7 +2753,7 @@ public final class ChatListNode: ListView { guard let strongSelf = self else { return } - startedScrollingAtUpperBound = false + strongSelf.startedScrollingAtUpperBound = false let _ = strongSelf.contentScrollingEnded?(strongSelf) let revealHiddenItems: Bool switch strongSelf.visibleContentOffset() { @@ -2795,7 +2796,7 @@ public final class ChatListNode: ListView { atTop = false case let .known(value): atTop = value <= 0.0 - if startedScrollingAtUpperBound && startedScrollingWithCanExpandHiddenItems && strongSelf.isTracking { + if strongSelf.startedScrollingAtUpperBound && startedScrollingWithCanExpandHiddenItems && strongSelf.isTracking { revealHiddenItems = value <= -60.0 } } diff --git a/submodules/ContactListUI/Sources/ContactsControllerNode.swift b/submodules/ContactListUI/Sources/ContactsControllerNode.swift index 145357d2de..11eff8d81b 100644 --- a/submodules/ContactListUI/Sources/ContactsControllerNode.swift +++ b/submodules/ContactListUI/Sources/ContactsControllerNode.swift @@ -435,7 +435,7 @@ final class ContactsControllerNode: ASDisplayNode { } if let navigationBarComponentView = self.navigationBarView.view as? ChatListNavigationBar.View { - navigationBarComponentView.applyScroll(offset: offset, transition: Transition(transition)) + navigationBarComponentView.applyScroll(offset: offset, allowAvatarsExpansion: true, transition: Transition(transition)) } } diff --git a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift index 235181bea9..a8111a250c 100644 --- a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift +++ b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift @@ -142,6 +142,7 @@ public final class ChatListNavigationBar: Component { private var currentLayout: CurrentLayout? private var rawScrollOffset: CGFloat? + private var currentAllowAvatarsExpansion: Bool = false public private(set) var clippedScrollOffset: CGFloat? public var deferScrollApplication: Bool = false @@ -191,14 +192,19 @@ public final class ChatListNavigationBar: Component { public func applyCurrentScroll(transition: Transition) { if let rawScrollOffset = self.rawScrollOffset, self.hasDeferredScrollOffset { - self.applyScroll(offset: rawScrollOffset, transition: transition) + self.applyScroll(offset: rawScrollOffset, allowAvatarsExpansion: self.currentAllowAvatarsExpansion, transition: transition) } } - public func applyScroll(offset: CGFloat, forceUpdate: Bool = false, transition: Transition) { + public func applyScroll(offset: CGFloat, allowAvatarsExpansion: Bool, forceUpdate: Bool = false, transition: Transition) { + if self.currentAllowAvatarsExpansion != allowAvatarsExpansion, allowAvatarsExpansion { + self.addStoriesUnlockedAnimation(duration: 0.3) + } + let transition = transition self.rawScrollOffset = offset + self.currentAllowAvatarsExpansion = allowAvatarsExpansion if self.deferScrollApplication && !forceUpdate { self.hasDeferredScrollOffset = true @@ -286,7 +292,7 @@ public final class ChatListNavigationBar: Component { let clippedStoriesOffset = max(0.0, min(clippedScrollOffset, defaultStoriesOffsetDistance)) var storiesOffsetFraction: CGFloat var storiesUnlockedOffsetFraction: CGFloat - if !component.isSearchActive, component.secondaryTransition == 0.0, let storySubscriptions = component.storySubscriptions, !storySubscriptions.items.isEmpty { + if !component.isSearchActive, component.secondaryTransition == 0.0, let storySubscriptions = component.storySubscriptions, !storySubscriptions.items.isEmpty, allowAvatarsExpansion { if component.storiesUnlocked { storiesOffsetFraction = clippedStoriesOffset / defaultStoriesOffsetDistance storiesUnlockedOffsetFraction = 1.0 @@ -490,45 +496,52 @@ public final class ChatListNavigationBar: Component { if uploadProgressUpdated { if let rawScrollOffset = self.rawScrollOffset { - self.applyScroll(offset: rawScrollOffset, forceUpdate: true, transition: transition) + self.applyScroll(offset: rawScrollOffset, allowAvatarsExpansion: self.currentAllowAvatarsExpansion, forceUpdate: true, transition: transition) } } if storiesUnlockedUpdated, case let .curve(duration, _) = transition.animation { - self.applyScrollFractionAnimator?.invalidate() - self.applyScrollFractionAnimator = nil - - self.storiesOffsetStartFraction = self.storiesOffsetFraction - self.storiesUnlockedStartFraction = self.storiesUnlockedFraction - - let storiesUnlocked = component.storiesUnlocked - - self.applyScrollFraction = 0.0 - self.applyScrollUnlockedFraction = 0.0 - self.applyScrollFractionAnimator = DisplayLinkAnimator(duration: duration * UIView.animationDurationFactor(), from: 0.0, to: 1.0, update: { [weak self] value in - guard let self else { - return - } - - let t = listViewAnimationCurveSystem(value) - self.applyScrollFraction = t - self.applyScrollUnlockedFraction = storiesUnlocked ? t : (1.0 - t) - - if let rawScrollOffset = self.rawScrollOffset { - self.hasDeferredScrollOffset = true - self.applyScroll(offset: rawScrollOffset, transition: transition) - } - }, completion: { [weak self] in - guard let self else { - return - } - self.applyScrollFractionAnimator?.invalidate() - self.applyScrollFractionAnimator = nil - }) + self.addStoriesUnlockedAnimation(duration: duration) } return size } + + private func addStoriesUnlockedAnimation(duration: Double) { + guard let component = self.component else { + return + } + self.applyScrollFractionAnimator?.invalidate() + self.applyScrollFractionAnimator = nil + + self.storiesOffsetStartFraction = self.storiesOffsetFraction + self.storiesUnlockedStartFraction = self.storiesUnlockedFraction + + let storiesUnlocked = component.storiesUnlocked + + self.applyScrollFraction = 0.0 + self.applyScrollUnlockedFraction = 0.0 + self.applyScrollFractionAnimator = DisplayLinkAnimator(duration: duration * UIView.animationDurationFactor(), from: 0.0, to: 1.0, update: { [weak self] value in + guard let self else { + return + } + + let t = listViewAnimationCurveSystem(value) + self.applyScrollFraction = t + self.applyScrollUnlockedFraction = storiesUnlocked ? t : (1.0 - t) + + if let rawScrollOffset = self.rawScrollOffset { + self.hasDeferredScrollOffset = true + self.applyScroll(offset: rawScrollOffset, allowAvatarsExpansion: self.currentAllowAvatarsExpansion, transition: .immediate) + } + }, completion: { [weak self] in + guard let self else { + return + } + self.applyScrollFractionAnimator?.invalidate() + self.applyScrollFractionAnimator = nil + }) + } } public func makeView() -> View { diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index 1467a13e6b..d1f22cf607 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -728,9 +728,10 @@ public final class StoryItemSetContainerComponent: Component { to: CGPoint(x: 0.0, y: self.bounds.height - self.contentContainerView.frame.maxY), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, + removeOnCompletion: false, additive: true ) - viewListView.layer.animateAlpha(from: 0.0, to: viewListView.alpha, duration: 0.28) + viewListView.layer.animateAlpha(from: viewListView.alpha, to: 0.0, duration: 0.28, removeOnCompletion: false) } if let captionItemView = self.captionItem?.view.view { captionItemView.layer.animatePosition(