diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index b17260e8b6..5770aad73e 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -555,6 +555,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { var nextChannelToReadDisplayName: Bool = false private var currentOverscrollExpandProgress: CGFloat = 0.0 private var freezeOverscrollControl: Bool = false + private var freezeOverscrollControlProgress: Bool = false private var feedback: HapticFeedback? var openNextChannelToRead: ((EnginePeer, TelegramEngine.NextUnreadChannelLocation) -> Void)? private var contentInsetAnimator: DisplayLinkAnimator? @@ -1273,8 +1274,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { strongSelf.freezeOverscrollControl = true strongSelf.openNextChannelToRead?(nextChannelToRead.peer, nextChannelToRead.location) } else { + strongSelf.freezeOverscrollControlProgress = true strongSelf.scroller.contentInset = UIEdgeInsets(top: 94.0 + 12.0, left: 0.0, bottom: 0.0, right: 0.0) - Queue.mainQueue().after(0.5, { + Queue.mainQueue().after(0.3, { let animator = DisplayLinkAnimator(duration: 0.2, from: 1.0, to: 0.0, update: { rawT in guard let strongSelf = self else { return @@ -1288,6 +1290,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } strongSelf.contentInsetAnimator = nil strongSelf.scroller.contentInset = UIEdgeInsets() + strongSelf.freezeOverscrollControlProgress = false }) strongSelf.contentInsetAnimator = animator }) @@ -1391,7 +1394,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { chatControllerNode.setChatInputPanelOverscrollNode(overscrollNode: nil) } - let overscrollFrame = CGRect(origin: CGPoint(x: 0.0, y: self.insets.top), size: CGSize(width: self.bounds.width, height: 94.0)) + var overscrollFrame = CGRect(origin: CGPoint(x: 0.0, y: self.insets.top), size: CGSize(width: self.bounds.width, height: 94.0)) + if self.freezeOverscrollControlProgress { + overscrollFrame.origin.y -= max(0.0, 94.0 - expandDistance) + } + + overscrollView.frame = self.view.convert(overscrollFrame, to: self.view.superview!) let _ = overscrollView.update( transition: .immediate, @@ -1402,7 +1410,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { unreadCount: self.nextChannelToRead?.unreadCount ?? 0, location: self.nextChannelToRead?.location ?? .same, context: self.context, - expandDistance: expandDistance, + expandDistance: self.freezeOverscrollControl ? 94.0 : expandDistance, + freezeProgress: false, absoluteRect: CGRect(origin: CGPoint(x: overscrollFrame.minX, y: self.bounds.height - overscrollFrame.minY), size: overscrollFrame.size), absoluteSize: self.bounds.size, wallpaperNode: chatControllerNode.backgroundNode @@ -1410,7 +1419,6 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { environment: {}, containerSize: CGSize(width: self.bounds.width, height: 200.0) ) - overscrollView.frame = self.view.convert(overscrollFrame, to: self.view.superview!) } else if let overscrollView = self.overscrollView { self.overscrollView = nil overscrollView.removeFromSuperview() diff --git a/submodules/TelegramUI/Sources/ChatOverscrollControl.swift b/submodules/TelegramUI/Sources/ChatOverscrollControl.swift index b642e42e96..78b22afba5 100644 --- a/submodules/TelegramUI/Sources/ChatOverscrollControl.swift +++ b/submodules/TelegramUI/Sources/ChatOverscrollControl.swift @@ -669,6 +669,7 @@ final class OverscrollContentsComponent: Component { let unreadCount: Int let location: TelegramEngine.NextUnreadChannelLocation let expandOffset: CGFloat + let freezeProgress: Bool let absoluteRect: CGRect let absoluteSize: CGSize let wallpaperNode: WallpaperBackgroundNode? @@ -681,6 +682,7 @@ final class OverscrollContentsComponent: Component { unreadCount: Int, location: TelegramEngine.NextUnreadChannelLocation, expandOffset: CGFloat, + freezeProgress: Bool, absoluteRect: CGRect, absoluteSize: CGSize, wallpaperNode: WallpaperBackgroundNode? @@ -692,6 +694,7 @@ final class OverscrollContentsComponent: Component { self.unreadCount = unreadCount self.location = location self.expandOffset = expandOffset + self.freezeProgress = freezeProgress self.absoluteRect = absoluteRect self.absoluteSize = absoluteSize self.wallpaperNode = wallpaperNode @@ -719,6 +722,9 @@ final class OverscrollContentsComponent: Component { if lhs.expandOffset != rhs.expandOffset { return false } + if lhs.freezeProgress != rhs.freezeProgress { + return false + } if lhs.absoluteRect != rhs.absoluteRect { return false } @@ -811,7 +817,14 @@ final class OverscrollContentsComponent: Component { let minBackgroundHeight: CGFloat = backgroundWidth + 5.0 let avatarInset: CGFloat = 6.0 - let isFullyExpanded = component.expandOffset >= fullHeight + let apparentExpandOffset: CGFloat + if component.freezeProgress { + apparentExpandOffset = fullHeight + } else { + apparentExpandOffset = component.expandOffset + } + + let isFullyExpanded = apparentExpandOffset >= fullHeight let isFolderMask: Bool switch component.location { @@ -821,20 +834,21 @@ final class OverscrollContentsComponent: Component { isFolderMask = false } - let expandProgress: CGFloat = max(0.1, min(1.0, component.expandOffset / fullHeight)) + let expandProgress: CGFloat = max(0.1, min(1.0, apparentExpandOffset / fullHeight)) + let trueExpandProgress: CGFloat = max(0.1, min(1.0, component.expandOffset / fullHeight)) func interpolate(from: CGFloat, to: CGFloat, value: CGFloat) -> CGFloat { return (1.0 - value) * from + value * to } - let backgroundHeight: CGFloat = interpolate(from: minBackgroundHeight, to: fullHeight, value: expandProgress) + let backgroundHeight: CGFloat = interpolate(from: minBackgroundHeight, to: fullHeight, value: trueExpandProgress) let backgroundFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - backgroundWidth) / 2.0), y: fullHeight - backgroundHeight), size: CGSize(width: backgroundWidth, height: backgroundHeight)) - let alphaProgress: CGFloat = max(0.0, min(1.0, component.expandOffset / 10.0)) + let alphaProgress: CGFloat = max(0.0, min(1.0, apparentExpandOffset / 10.0)) let maxAvatarScale: CGFloat = 1.0 - var avatarExpandProgress: CGFloat = max(0.01, min(maxAvatarScale, component.expandOffset / fullHeight)) + var avatarExpandProgress: CGFloat = max(0.01, min(maxAvatarScale, apparentExpandOffset / fullHeight)) avatarExpandProgress *= expandProgress let avatarOffsetProgress = interpolate(from: 0.1, to: 1.0, value: avatarExpandProgress) @@ -978,6 +992,7 @@ final class ChatOverscrollControl: CombinedComponent { let location: TelegramEngine.NextUnreadChannelLocation let context: AccountContext let expandDistance: CGFloat + let freezeProgress: Bool let absoluteRect: CGRect let absoluteSize: CGSize let wallpaperNode: WallpaperBackgroundNode? @@ -990,6 +1005,7 @@ final class ChatOverscrollControl: CombinedComponent { location: TelegramEngine.NextUnreadChannelLocation, context: AccountContext, expandDistance: CGFloat, + freezeProgress: Bool, absoluteRect: CGRect, absoluteSize: CGSize, wallpaperNode: WallpaperBackgroundNode? @@ -1001,6 +1017,7 @@ final class ChatOverscrollControl: CombinedComponent { self.location = location self.context = context self.expandDistance = expandDistance + self.freezeProgress = freezeProgress self.absoluteRect = absoluteRect self.absoluteSize = absoluteSize self.wallpaperNode = wallpaperNode @@ -1028,6 +1045,9 @@ final class ChatOverscrollControl: CombinedComponent { if lhs.expandDistance != rhs.expandDistance { return false } + if lhs.freezeProgress != rhs.freezeProgress { + return false + } if lhs.absoluteRect != rhs.absoluteRect { return false } @@ -1053,6 +1073,7 @@ final class ChatOverscrollControl: CombinedComponent { unreadCount: context.component.unreadCount, location: context.component.location, expandOffset: context.component.expandDistance, + freezeProgress: context.component.freezeProgress, absoluteRect: context.component.absoluteRect, absoluteSize: context.component.absoluteSize, wallpaperNode: context.component.wallpaperNode