mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
b4595e72e9
@ -948,7 +948,7 @@ public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDele
|
|||||||
|
|
||||||
let offset = itemNode.listNode.visibleContentOffset()
|
let offset = itemNode.listNode.visibleContentOffset()
|
||||||
self.contentOffset = offset
|
self.contentOffset = offset
|
||||||
self.contentOffsetChanged?(offset)
|
self.contentOffsetChanged?(offset, self.currentItemNode)
|
||||||
|
|
||||||
self.isSettingUpContentOffset = false
|
self.isSettingUpContentOffset = false
|
||||||
return
|
return
|
||||||
@ -966,7 +966,7 @@ public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDele
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.contentOffset = offset
|
self.contentOffset = offset
|
||||||
self.contentOffsetChanged?(offset)
|
self.contentOffsetChanged?(offset, self.currentItemNode)
|
||||||
|
|
||||||
if !self.isInlineMode, self.currentItemNode.startedScrollingAtUpperBound && self.tempTopInset != 0.0 {
|
if !self.isInlineMode, self.currentItemNode.startedScrollingAtUpperBound && self.tempTopInset != 0.0 {
|
||||||
if case let .known(value) = offset {
|
if case let .known(value) = offset {
|
||||||
@ -983,15 +983,20 @@ public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDele
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
itemNode.listNode.didBeginInteractiveDragging = { [weak self] _ in
|
itemNode.listNode.didBeginInteractiveDragging = { [weak self] _ in
|
||||||
guard let self, !self.isInlineMode else {
|
guard let self else {
|
||||||
return
|
|
||||||
}
|
|
||||||
guard let validLayout = self.validLayout else {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.didBeginInteractiveDragging?()
|
self.didBeginInteractiveDragging?()
|
||||||
|
|
||||||
|
if self.isInlineMode {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let validLayout = self.validLayout else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let tempTopInset: CGFloat
|
let tempTopInset: CGFloat
|
||||||
if validLayout.inlineNavigationLocation != nil {
|
if validLayout.inlineNavigationLocation != nil {
|
||||||
tempTopInset = 0.0
|
tempTopInset = 0.0
|
||||||
@ -1108,7 +1113,7 @@ public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDele
|
|||||||
var groupSelected: ((EngineChatList.Group) -> Void)?
|
var groupSelected: ((EngineChatList.Group) -> Void)?
|
||||||
var updatePeerGrouping: ((EnginePeer.Id, Bool) -> Void)?
|
var updatePeerGrouping: ((EnginePeer.Id, Bool) -> Void)?
|
||||||
var contentOffset: ListViewVisibleContentOffset?
|
var contentOffset: ListViewVisibleContentOffset?
|
||||||
public var contentOffsetChanged: ((ListViewVisibleContentOffset) -> Void)?
|
public var contentOffsetChanged: ((ListViewVisibleContentOffset, ListView) -> Void)?
|
||||||
public var contentScrollingEnded: ((ListView) -> Bool)?
|
public var contentScrollingEnded: ((ListView) -> Bool)?
|
||||||
var didBeginInteractiveDragging: (() -> Void)?
|
var didBeginInteractiveDragging: (() -> Void)?
|
||||||
var endedInteractiveDragging: ((ListView) -> Void)?
|
var endedInteractiveDragging: ((ListView) -> Void)?
|
||||||
@ -1756,6 +1761,8 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
private var tempNavigationScrollingTransition: ContainedViewLayoutTransition?
|
private var tempNavigationScrollingTransition: ContainedViewLayoutTransition?
|
||||||
|
|
||||||
private var allowOverscrollStoryExpansion: Bool = false
|
private var allowOverscrollStoryExpansion: Bool = false
|
||||||
|
private var allowOverscrollItemExpansion: Bool = false
|
||||||
|
private var currentOverscrollItemExpansionTimestamp: Double?
|
||||||
|
|
||||||
private var containerLayout: (layout: ContainerViewLayout, navigationBarHeight: CGFloat, visualNavigationHeight: CGFloat, cleanNavigationBarHeight: CGFloat, storiesInset: CGFloat)?
|
private var containerLayout: (layout: ContainerViewLayout, navigationBarHeight: CGFloat, visualNavigationHeight: CGFloat, cleanNavigationBarHeight: CGFloat, storiesInset: CGFloat)?
|
||||||
|
|
||||||
@ -1807,8 +1814,8 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
|
|
||||||
self.addSubnode(self.mainContainerNode)
|
self.addSubnode(self.mainContainerNode)
|
||||||
|
|
||||||
self.mainContainerNode.contentOffsetChanged = { [weak self] offset in
|
self.mainContainerNode.contentOffsetChanged = { [weak self] offset, listView in
|
||||||
self?.contentOffsetChanged(offset: offset, isPrimary: true)
|
self?.contentOffsetChanged(offset: offset, listView: listView, isPrimary: true)
|
||||||
}
|
}
|
||||||
self.mainContainerNode.contentScrollingEnded = { [weak self] listView in
|
self.mainContainerNode.contentScrollingEnded = { [weak self] listView in
|
||||||
return self?.contentScrollingEnded(listView: listView, isPrimary: true) ?? false
|
return self?.contentScrollingEnded(listView: listView, isPrimary: true) ?? false
|
||||||
@ -2141,15 +2148,6 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
mainDelta = 0.0
|
mainDelta = 0.0
|
||||||
}
|
}
|
||||||
transition.updateSublayerTransformOffset(layer: self.mainContainerNode.layer, offset: CGPoint(x: 0.0, y: -mainDelta))
|
transition.updateSublayerTransformOffset(layer: self.mainContainerNode.layer, offset: CGPoint(x: 0.0, y: -mainDelta))
|
||||||
|
|
||||||
if self.inlineStackContainerNode == nil && self.allowOverscrollStoryExpansion {
|
|
||||||
if let controller = self.controller, let componentView = controller.chatListHeaderView(), let storyPeerListView = componentView.storyPeerListView(), let peerId = storyPeerListView.overscrollSelectedId {
|
|
||||||
self.allowOverscrollStoryExpansion = false
|
|
||||||
HapticFeedback().tap()
|
|
||||||
|
|
||||||
controller.openStories(peerId: peerId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func requestNavigationBarLayout(transition: Transition) {
|
func requestNavigationBarLayout(transition: Transition) {
|
||||||
@ -2408,11 +2406,70 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func contentOffsetChanged(offset: ListViewVisibleContentOffset, isPrimary: Bool) {
|
private func contentOffsetChanged(offset: ListViewVisibleContentOffset, listView: ListView, isPrimary: Bool) {
|
||||||
guard let containerLayout = self.containerLayout else {
|
guard let containerLayout = self.containerLayout else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.updateNavigationScrolling(navigationHeight: containerLayout.navigationBarHeight, transition: self.tempNavigationScrollingTransition ?? .immediate)
|
self.updateNavigationScrolling(navigationHeight: containerLayout.navigationBarHeight, transition: self.tempNavigationScrollingTransition ?? .immediate)
|
||||||
|
|
||||||
|
if listView.isDragging {
|
||||||
|
var overscrollSelectedId: EnginePeer.Id?
|
||||||
|
var overscrollHiddenChatItemsAllowed = false
|
||||||
|
if let controller = self.controller, let componentView = controller.chatListHeaderView(), let storyPeerListView = componentView.storyPeerListView() {
|
||||||
|
overscrollSelectedId = storyPeerListView.overscrollSelectedId
|
||||||
|
overscrollHiddenChatItemsAllowed = storyPeerListView.overscrollHiddenChatItemsAllowed
|
||||||
|
}
|
||||||
|
|
||||||
|
if let controller = self.controller {
|
||||||
|
if let peerId = overscrollSelectedId {
|
||||||
|
if self.allowOverscrollStoryExpansion && self.inlineStackContainerNode == nil && isPrimary {
|
||||||
|
self.allowOverscrollStoryExpansion = false
|
||||||
|
self.allowOverscrollItemExpansion = false
|
||||||
|
self.currentOverscrollItemExpansionTimestamp = nil
|
||||||
|
HapticFeedback().tap()
|
||||||
|
|
||||||
|
controller.openStories(peerId: peerId)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !overscrollHiddenChatItemsAllowed {
|
||||||
|
var manuallyAllow = false
|
||||||
|
|
||||||
|
if isPrimary {
|
||||||
|
if let storySubscriptions = controller.orderedStorySubscriptions, shouldDisplayStoriesInChatListHeader(storySubscriptions: storySubscriptions, isHidden: controller.location == .chatList(groupId: .archive)) {
|
||||||
|
} else {
|
||||||
|
manuallyAllow = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
manuallyAllow = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if manuallyAllow, case let .known(value) = offset, value + listView.tempTopInset <= -40.0 {
|
||||||
|
overscrollHiddenChatItemsAllowed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if overscrollHiddenChatItemsAllowed {
|
||||||
|
if self.allowOverscrollItemExpansion {
|
||||||
|
let timestamp = CACurrentMediaTime()
|
||||||
|
if let _ = self.currentOverscrollItemExpansionTimestamp {
|
||||||
|
} else {
|
||||||
|
self.currentOverscrollItemExpansionTimestamp = timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
if let currentOverscrollItemExpansionTimestamp = self.currentOverscrollItemExpansionTimestamp, currentOverscrollItemExpansionTimestamp <= timestamp - 0.2 {
|
||||||
|
self.allowOverscrollItemExpansion = false
|
||||||
|
|
||||||
|
if isPrimary {
|
||||||
|
self.mainContainerNode.currentItemNode.revealScrollHiddenItem()
|
||||||
|
} else {
|
||||||
|
self.inlineStackContainerNode?.currentItemNode.revealScrollHiddenItem()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func shouldStopScrolling(listView: ListView, velocity: CGFloat, isPrimary: Bool) -> Bool {
|
private func shouldStopScrolling(listView: ListView, velocity: CGFloat, isPrimary: Bool) -> Bool {
|
||||||
@ -2445,12 +2502,15 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
if isPrimary {
|
if isPrimary {
|
||||||
self.allowOverscrollStoryExpansion = true
|
self.allowOverscrollStoryExpansion = true
|
||||||
}
|
}
|
||||||
|
self.allowOverscrollItemExpansion = true
|
||||||
}
|
}
|
||||||
|
|
||||||
private func endedInteractiveDragging(listView: ListView, isPrimary: Bool) {
|
private func endedInteractiveDragging(listView: ListView, isPrimary: Bool) {
|
||||||
if isPrimary {
|
if isPrimary {
|
||||||
self.allowOverscrollStoryExpansion = false
|
self.allowOverscrollStoryExpansion = false
|
||||||
}
|
}
|
||||||
|
self.allowOverscrollItemExpansion = false
|
||||||
|
self.currentOverscrollItemExpansionTimestamp = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private func contentScrollingEnded(listView: ListView, isPrimary: Bool) -> Bool {
|
private func contentScrollingEnded(listView: ListView, isPrimary: Bool) -> Bool {
|
||||||
@ -2518,10 +2578,10 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
inlineStackContainerNode.groupSelected = self.mainContainerNode.groupSelected
|
inlineStackContainerNode.groupSelected = self.mainContainerNode.groupSelected
|
||||||
inlineStackContainerNode.updatePeerGrouping = self.mainContainerNode.updatePeerGrouping
|
inlineStackContainerNode.updatePeerGrouping = self.mainContainerNode.updatePeerGrouping
|
||||||
|
|
||||||
inlineStackContainerNode.contentOffsetChanged = { [weak self] offset in
|
inlineStackContainerNode.contentOffsetChanged = { [weak self] offset, listView in
|
||||||
self?.contentOffsetChanged(offset: offset, isPrimary: false)
|
self?.contentOffsetChanged(offset: offset, listView: listView, isPrimary: false)
|
||||||
}
|
}
|
||||||
inlineStackContainerNode.endedInteractiveDragging = { [weak self] listView in
|
inlineStackContainerNode.didBeginInteractiveDragging = { [weak self] in
|
||||||
self?.didBeginInteractiveDragging(isPrimary: false)
|
self?.didBeginInteractiveDragging(isPrimary: false)
|
||||||
}
|
}
|
||||||
inlineStackContainerNode.endedInteractiveDragging = { [weak self] listView in
|
inlineStackContainerNode.endedInteractiveDragging = { [weak self] listView in
|
||||||
|
@ -2858,32 +2858,7 @@ public final class ChatListNode: ListView {
|
|||||||
strongSelf.scrolledAtTopValue = atTop
|
strongSelf.scrolledAtTopValue = atTop
|
||||||
strongSelf.contentOffsetChanged?(offset)
|
strongSelf.contentOffsetChanged?(offset)
|
||||||
if revealHiddenItems && !strongSelf.currentState.hiddenItemShouldBeTemporaryRevealed {
|
if revealHiddenItems && !strongSelf.currentState.hiddenItemShouldBeTemporaryRevealed {
|
||||||
var isHiddenItemVisible = false
|
//strongSelf.revealScrollHiddenItem()
|
||||||
strongSelf.forEachItemNode({ itemNode in
|
|
||||||
if let itemNode = itemNode as? ChatListItemNode, let item = itemNode.item {
|
|
||||||
if case let .peer(peerData) = item.content, let threadInfo = peerData.threadInfo {
|
|
||||||
if threadInfo.isHidden {
|
|
||||||
isHiddenItemVisible = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if case let .groupReference(groupReference) = item.content {
|
|
||||||
if groupReference.hiddenByDefault {
|
|
||||||
isHiddenItemVisible = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if isHiddenItemVisible {
|
|
||||||
if strongSelf.hapticFeedback == nil {
|
|
||||||
strongSelf.hapticFeedback = HapticFeedback()
|
|
||||||
}
|
|
||||||
strongSelf.hapticFeedback?.impact(.medium)
|
|
||||||
strongSelf.updateState { state in
|
|
||||||
var state = state
|
|
||||||
state.hiddenItemShouldBeTemporaryRevealed = true
|
|
||||||
return state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2915,6 +2890,35 @@ public final class ChatListNode: ListView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func revealScrollHiddenItem() {
|
||||||
|
var isHiddenItemVisible = false
|
||||||
|
self.forEachItemNode({ itemNode in
|
||||||
|
if let itemNode = itemNode as? ChatListItemNode, let item = itemNode.item {
|
||||||
|
if case let .peer(peerData) = item.content, let threadInfo = peerData.threadInfo {
|
||||||
|
if threadInfo.isHidden {
|
||||||
|
isHiddenItemVisible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if case let .groupReference(groupReference) = item.content {
|
||||||
|
if groupReference.hiddenByDefault {
|
||||||
|
isHiddenItemVisible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if isHiddenItemVisible {
|
||||||
|
if self.hapticFeedback == nil {
|
||||||
|
self.hapticFeedback = HapticFeedback()
|
||||||
|
}
|
||||||
|
self.hapticFeedback?.impact(.medium)
|
||||||
|
self.updateState { state in
|
||||||
|
var state = state
|
||||||
|
state.hiddenItemShouldBeTemporaryRevealed = true
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func pollFilterUpdates() {
|
private func pollFilterUpdates() {
|
||||||
self.chatFolderUpdates.set(.single(nil))
|
self.chatFolderUpdates.set(.single(nil))
|
||||||
|
|
||||||
|
@ -354,6 +354,7 @@ public final class StoryPeerListComponent: Component {
|
|||||||
private var currentActivityFraction: CGFloat = 0.0
|
private var currentActivityFraction: CGFloat = 0.0
|
||||||
|
|
||||||
public private(set) var overscrollSelectedId: EnginePeer.Id?
|
public private(set) var overscrollSelectedId: EnginePeer.Id?
|
||||||
|
public private(set) var overscrollHiddenChatItemsAllowed: Bool = false
|
||||||
|
|
||||||
private var sharedBlurEffect: NSObject?
|
private var sharedBlurEffect: NSObject?
|
||||||
|
|
||||||
@ -712,7 +713,7 @@ public final class StoryPeerListComponent: Component {
|
|||||||
var rawProgress = CGFloat((timestamp - animationState.startTime) / animationState.duration)
|
var rawProgress = CGFloat((timestamp - animationState.startTime) / animationState.duration)
|
||||||
rawProgress = max(0.0, min(1.0, rawProgress))
|
rawProgress = max(0.0, min(1.0, rawProgress))
|
||||||
|
|
||||||
if !animationState.fromIsUnlocked && animationState.bounce && itemLayout.itemCount > 3 {
|
if !animationState.fromIsUnlocked && animationState.bounce {
|
||||||
let bounceStartFraction: CGFloat = 0.0
|
let bounceStartFraction: CGFloat = 0.0
|
||||||
let bounceGlobalFraction: CGFloat = animationState.interpolatedFraction(at: timestamp, effectiveFromFraction: 0.0, toFraction: 1.0, linear: true)
|
let bounceGlobalFraction: CGFloat = animationState.interpolatedFraction(at: timestamp, effectiveFromFraction: 0.0, toFraction: 1.0, linear: true)
|
||||||
let bounceFraction: CGFloat = 1.0 - max(0.0, min(1.0, bounceGlobalFraction - bounceStartFraction)) / (1.0 - bounceStartFraction)
|
let bounceFraction: CGFloat = 1.0 - max(0.0, min(1.0, bounceGlobalFraction - bounceStartFraction)) / (1.0 - bounceStartFraction)
|
||||||
@ -788,8 +789,8 @@ public final class StoryPeerListComponent: Component {
|
|||||||
let expandedItemWidth: CGFloat = 60.0
|
let expandedItemWidth: CGFloat = 60.0
|
||||||
|
|
||||||
let totalOverscrollFraction: CGFloat = max(0.0, collapsedState.maxFraction - 1.0)
|
let totalOverscrollFraction: CGFloat = max(0.0, collapsedState.maxFraction - 1.0)
|
||||||
let overscrollStage1 = min(0.7, totalOverscrollFraction)
|
let overscrollStage1 = min(0.5, totalOverscrollFraction)
|
||||||
let overscrollStage2 = max(0.0, totalOverscrollFraction - 0.7)
|
let overscrollStage2 = max(0.0, totalOverscrollFraction - 0.5)
|
||||||
|
|
||||||
//let realTimeOverscrollFraction: CGFloat = max(0.0, (1.0 - component.collapseFraction) - 1.0)
|
//let realTimeOverscrollFraction: CGFloat = max(0.0, (1.0 - component.collapseFraction) - 1.0)
|
||||||
let realTimeOverscrollFraction = totalOverscrollFraction
|
let realTimeOverscrollFraction = totalOverscrollFraction
|
||||||
@ -801,7 +802,14 @@ public final class StoryPeerListComponent: Component {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let overscrollFocusIndex, overscrollStage2 >= 0.6 {
|
|
||||||
|
if overscrollStage1 >= 0.5 {
|
||||||
|
self.overscrollHiddenChatItemsAllowed = true
|
||||||
|
} else {
|
||||||
|
self.overscrollHiddenChatItemsAllowed = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if let overscrollFocusIndex, overscrollStage2 >= 0.5 {
|
||||||
self.overscrollSelectedId = self.sortedItems[overscrollFocusIndex].peer.id
|
self.overscrollSelectedId = self.sortedItems[overscrollFocusIndex].peer.id
|
||||||
} else {
|
} else {
|
||||||
self.overscrollSelectedId = nil
|
self.overscrollSelectedId = nil
|
||||||
|
@ -262,7 +262,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.mainContainerNode?.contentOffsetChanged = { [weak self] offset in
|
self.mainContainerNode?.contentOffsetChanged = { [weak self] offset, _ in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user