mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
Various improvements
This commit is contained in:
@@ -154,7 +154,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
private var searchContentNode: NavigationBarSearchContentNode?
|
private var searchContentNode: NavigationBarSearchContentNode?
|
||||||
|
|
||||||
private let tabContainerNode: ChatListFilterTabContainerNode
|
private let tabContainerNode: ChatListFilterTabContainerNode
|
||||||
private var tabContainerData: ([ChatListFilterTabEntry], Bool)?
|
private var tabContainerData: ([ChatListFilterTabEntry], Bool, Int32?)?
|
||||||
|
|
||||||
private var hasDownloads: Bool = false
|
private var hasDownloads: Bool = false
|
||||||
private var activeDownloadsDisposable: Disposable?
|
private var activeDownloadsDisposable: Disposable?
|
||||||
@@ -764,7 +764,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
strongSelf.tabContainerNode.cancelAnimations()
|
strongSelf.tabContainerNode.cancelAnimations()
|
||||||
strongSelf.chatListDisplayNode.inlineTabContainerNode.cancelAnimations()
|
strongSelf.chatListDisplayNode.inlineTabContainerNode.cancelAnimations()
|
||||||
}
|
}
|
||||||
strongSelf.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: tabContainerData.0, selectedFilter: filter, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || (strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, canReorderAllChats: strongSelf.isPremium, transitionFraction: fraction, presentationData: strongSelf.presentationData, transition: transition)
|
strongSelf.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: tabContainerData.0, selectedFilter: filter, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || (strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, canReorderAllChats: strongSelf.isPremium, filtersLimit: tabContainerData.2, transitionFraction: fraction, presentationData: strongSelf.presentationData, transition: transition)
|
||||||
strongSelf.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: tabContainerData.0, selectedFilter: filter, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || (strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: fraction, presentationData: strongSelf.presentationData, transition: transition)
|
strongSelf.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: tabContainerData.0, selectedFilter: filter, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || (strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: fraction, presentationData: strongSelf.presentationData, transition: transition)
|
||||||
}
|
}
|
||||||
self.reloadFilters()
|
self.reloadFilters()
|
||||||
@@ -835,7 +835,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
self.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationData: self.presentationData))
|
self.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationData: self.presentationData))
|
||||||
|
|
||||||
if let layout = self.validLayout {
|
if let layout = self.validLayout {
|
||||||
self.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || (self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !self.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, canReorderAllChats: self.isPremium, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .immediate)
|
self.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || (self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !self.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, canReorderAllChats: self.isPremium, filtersLimit: self.tabContainerData?.2, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .immediate)
|
||||||
self.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || (self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !self.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .immediate)
|
self.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || (self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !self.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .immediate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1506,6 +1506,22 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.chatListDisplayNode.containerNode.displayFilterLimit = { [weak self] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let context = strongSelf.context
|
||||||
|
var replaceImpl: ((ViewController) -> Void)?
|
||||||
|
let controller = PremiumLimitScreen(context: context, subject: .folders, count: strongSelf.tabContainerNode.filtersCount, action: {
|
||||||
|
let controller = PremiumIntroScreen(context: context, source: .folders)
|
||||||
|
replaceImpl?(controller)
|
||||||
|
})
|
||||||
|
replaceImpl = { [weak controller] c in
|
||||||
|
controller?.replace(with: c)
|
||||||
|
}
|
||||||
|
strongSelf.push(controller)
|
||||||
|
}
|
||||||
|
|
||||||
guard case .root = self.groupId else {
|
guard case .root = self.groupId else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -1820,7 +1836,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
let navigationBarHeight = self.navigationBar?.frame.maxY ?? 0.0
|
let navigationBarHeight = self.navigationBar?.frame.maxY ?? 0.0
|
||||||
|
|
||||||
transition.updateFrame(node: self.tabContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: navigationBarHeight - self.additionalNavigationBarHeight - 46.0 + tabContainerOffset), size: CGSize(width: layout.size.width, height: 46.0)))
|
transition.updateFrame(node: self.tabContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: navigationBarHeight - self.additionalNavigationBarHeight - 46.0 + tabContainerOffset), size: CGSize(width: layout.size.width, height: 46.0)))
|
||||||
self.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || (self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !self.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, canReorderAllChats: self.isPremium, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .animated(duration: 0.4, curve: .spring))
|
self.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || (self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !self.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, canReorderAllChats: self.isPremium, filtersLimit: self.tabContainerData?.2, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .animated(duration: 0.4, curve: .spring))
|
||||||
if let tabContainerData = self.tabContainerData {
|
if let tabContainerData = self.tabContainerData {
|
||||||
self.chatListDisplayNode.inlineTabContainerNode.isHidden = !tabContainerData.1 || tabContainerData.0.count <= 1
|
self.chatListDisplayNode.inlineTabContainerNode.isHidden = !tabContainerData.1 || tabContainerData.0.count <= 1
|
||||||
} else {
|
} else {
|
||||||
@@ -1957,9 +1973,10 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
]),
|
]),
|
||||||
filterItems,
|
filterItems,
|
||||||
displayTabsAtBottom,
|
displayTabsAtBottom,
|
||||||
self.context.account.postbox.peerView(id: self.context.account.peerId)
|
self.context.account.postbox.peerView(id: self.context.account.peerId),
|
||||||
|
self.context.engine.data.get(TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: false))
|
||||||
)
|
)
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] _, countAndFilterItems, displayTabsAtBottom, peerView in
|
|> deliverOnMainQueue).start(next: { [weak self] _, countAndFilterItems, displayTabsAtBottom, peerView, limits in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -1973,7 +1990,11 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
for (filter, unreadCount, hasUnmutedUnread) in items {
|
for (filter, unreadCount, hasUnmutedUnread) in items {
|
||||||
switch filter {
|
switch filter {
|
||||||
case .allChats:
|
case .allChats:
|
||||||
filterItems.append(.all(unreadCount: 0))
|
if !isPremium && filterItems.count > 0 {
|
||||||
|
filterItems.insert(.all(unreadCount: 0), at: 0)
|
||||||
|
} else {
|
||||||
|
filterItems.append(.all(unreadCount: 0))
|
||||||
|
}
|
||||||
case let .filter(id, title, _, _):
|
case let .filter(id, title, _, _):
|
||||||
filterItems.append(.filter(id: id, text: title, unread: ChatListFilterTabEntryUnreadCount(value: unreadCount, hasUnmuted: hasUnmutedUnread)))
|
filterItems.append(.filter(id: id, text: title, unread: ChatListFilterTabEntryUnreadCount(value: unreadCount, hasUnmuted: hasUnmutedUnread)))
|
||||||
}
|
}
|
||||||
@@ -2022,14 +2043,19 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
selectedEntryId = .all
|
selectedEntryId = .all
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strongSelf.tabContainerData = (resolvedItems, displayTabsAtBottom)
|
let filtersLimit = !isPremium ? limits.maxFoldersCount : nil
|
||||||
|
strongSelf.tabContainerData = (resolvedItems, displayTabsAtBottom, filtersLimit)
|
||||||
var availableFilters: [ChatListContainerNodeFilter] = []
|
var availableFilters: [ChatListContainerNodeFilter] = []
|
||||||
var hasAllChats = false
|
var hasAllChats = false
|
||||||
for item in items {
|
for item in items {
|
||||||
switch item.0 {
|
switch item.0 {
|
||||||
case .allChats:
|
case .allChats:
|
||||||
hasAllChats = true
|
hasAllChats = true
|
||||||
availableFilters.append(.all)
|
if !isPremium && availableFilters.count > 0 {
|
||||||
|
availableFilters.insert(.all, at: 0)
|
||||||
|
} else {
|
||||||
|
availableFilters.append(.all)
|
||||||
|
}
|
||||||
case .filter:
|
case .filter:
|
||||||
availableFilters.append(.filter(item.0))
|
availableFilters.append(.filter(item.0))
|
||||||
}
|
}
|
||||||
@@ -2037,7 +2063,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
if !hasAllChats {
|
if !hasAllChats {
|
||||||
availableFilters.insert(.all, at: 0)
|
availableFilters.insert(.all, at: 0)
|
||||||
}
|
}
|
||||||
strongSelf.chatListDisplayNode.containerNode.updateAvailableFilters(availableFilters)
|
strongSelf.chatListDisplayNode.containerNode.updateAvailableFilters(availableFilters, limit: filtersLimit)
|
||||||
|
|
||||||
if !strongSelf.initializedFilters && selectedEntryId != strongSelf.chatListDisplayNode.containerNode.currentItemFilter {
|
if !strongSelf.initializedFilters && selectedEntryId != strongSelf.chatListDisplayNode.containerNode.currentItemFilter {
|
||||||
strongSelf.chatListDisplayNode.containerNode.switchToFilter(id: selectedEntryId, animated: false, completion: nil)
|
strongSelf.chatListDisplayNode.containerNode.switchToFilter(id: selectedEntryId, animated: false, completion: nil)
|
||||||
@@ -2062,7 +2088,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
strongSelf.containerLayoutUpdated(layout, transition: transition)
|
strongSelf.containerLayoutUpdated(layout, transition: transition)
|
||||||
(strongSelf.parent as? TabBarController)?.updateLayout(transition: transition)
|
(strongSelf.parent as? TabBarController)?.updateLayout(transition: transition)
|
||||||
} else {
|
} else {
|
||||||
strongSelf.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: resolvedItems, selectedFilter: selectedEntryId, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || (strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, canReorderAllChats: isPremium, transitionFraction: strongSelf.chatListDisplayNode.containerNode.transitionFraction, presentationData: strongSelf.presentationData, transition: .animated(duration: 0.4, curve: .spring))
|
strongSelf.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: resolvedItems, selectedFilter: selectedEntryId, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || (strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, canReorderAllChats: isPremium, filtersLimit: filtersLimit, transitionFraction: strongSelf.chatListDisplayNode.containerNode.transitionFraction, presentationData: strongSelf.presentationData, transition: .animated(duration: 0.4, curve: .spring))
|
||||||
strongSelf.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: resolvedItems, selectedFilter: selectedEntryId, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || (strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: strongSelf.chatListDisplayNode.containerNode.transitionFraction, presentationData: strongSelf.presentationData, transition: .animated(duration: 0.4, curve: .spring))
|
strongSelf.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: resolvedItems, selectedFilter: selectedEntryId, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || (strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: strongSelf.chatListDisplayNode.containerNode.transitionFraction, presentationData: strongSelf.presentationData, transition: .animated(duration: 0.4, curve: .spring))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2185,7 +2211,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
}
|
}
|
||||||
|
|
||||||
let tabsIsEmpty: Bool
|
let tabsIsEmpty: Bool
|
||||||
if let (resolvedItems, displayTabsAtBottom) = strongSelf.tabContainerData {
|
if let (resolvedItems, displayTabsAtBottom, _) = strongSelf.tabContainerData {
|
||||||
tabsIsEmpty = resolvedItems.count <= 1 || displayTabsAtBottom
|
tabsIsEmpty = resolvedItems.count <= 1 || displayTabsAtBottom
|
||||||
} else {
|
} else {
|
||||||
tabsIsEmpty = true
|
tabsIsEmpty = true
|
||||||
@@ -2259,7 +2285,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
}
|
}
|
||||||
|
|
||||||
let tabsIsEmpty: Bool
|
let tabsIsEmpty: Bool
|
||||||
if let (resolvedItems, displayTabsAtBottom) = self.tabContainerData {
|
if let (resolvedItems, displayTabsAtBottom, _) = self.tabContainerData {
|
||||||
tabsIsEmpty = resolvedItems.count <= 1 || displayTabsAtBottom
|
tabsIsEmpty = resolvedItems.count <= 1 || displayTabsAtBottom
|
||||||
} else {
|
} else {
|
||||||
tabsIsEmpty = true
|
tabsIsEmpty = true
|
||||||
|
|||||||
@@ -432,6 +432,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
private var itemNodes: [ChatListFilterTabEntryId: ChatListContainerItemNode] = [:]
|
private var itemNodes: [ChatListFilterTabEntryId: ChatListContainerItemNode] = [:]
|
||||||
private var pendingItemNode: (ChatListFilterTabEntryId, ChatListContainerItemNode, Disposable)?
|
private var pendingItemNode: (ChatListFilterTabEntryId, ChatListContainerItemNode, Disposable)?
|
||||||
private var availableFilters: [ChatListContainerNodeFilter] = [.all]
|
private var availableFilters: [ChatListContainerNodeFilter] = [.all]
|
||||||
|
private var filtersLimit: Int32? = nil
|
||||||
private var selectedId: ChatListFilterTabEntryId
|
private var selectedId: ChatListFilterTabEntryId
|
||||||
|
|
||||||
private(set) var transitionFraction: CGFloat = 0.0
|
private(set) var transitionFraction: CGFloat = 0.0
|
||||||
@@ -578,6 +579,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
var activateChatPreview: ((ChatListItem, ASDisplayNode, ContextGesture?) -> Void)?
|
var activateChatPreview: ((ChatListItem, ASDisplayNode, ContextGesture?) -> Void)?
|
||||||
var addedVisibleChatsWithPeerIds: (([EnginePeer.Id]) -> Void)?
|
var addedVisibleChatsWithPeerIds: (([EnginePeer.Id]) -> Void)?
|
||||||
var didBeginSelectingChats: (() -> Void)?
|
var didBeginSelectingChats: (() -> Void)?
|
||||||
|
var displayFilterLimit: (() -> Void)?
|
||||||
|
|
||||||
init(context: AccountContext, groupId: EngineChatList.Group, previewing: Bool, controlsHistoryPreload: Bool, presentationData: PresentationData, filterBecameEmpty: @escaping (ChatListFilter?) -> Void, filterEmptyAction: @escaping (ChatListFilter?) -> Void) {
|
init(context: AccountContext, groupId: EngineChatList.Group, previewing: Bool, controlsHistoryPreload: Bool, presentationData: PresentationData, filterBecameEmpty: @escaping (ChatListFilter?) -> Void, filterEmptyAction: @escaping (ChatListFilter?) -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
@@ -649,6 +651,8 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc private func panGesture(_ recognizer: UIPanGestureRecognizer) {
|
@objc private func panGesture(_ recognizer: UIPanGestureRecognizer) {
|
||||||
|
let filtersLimit = self.filtersLimit.flatMap({ $0 + 1 }) ?? Int32(self.availableFilters.count)
|
||||||
|
|
||||||
switch recognizer.state {
|
switch recognizer.state {
|
||||||
case .began:
|
case .began:
|
||||||
self.onFilterSwitch?()
|
self.onFilterSwitch?()
|
||||||
@@ -688,9 +692,18 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
let overscroll = translation.x
|
let overscroll = translation.x
|
||||||
transitionFraction = rubberBandingOffset(offset: overscroll, bandingStart: 0.0) / layout.size.width
|
transitionFraction = rubberBandingOffset(offset: overscroll, bandingStart: 0.0) / layout.size.width
|
||||||
}
|
}
|
||||||
if selectedIndex >= self.availableFilters.count - 1 && translation.x < 0.0 {
|
|
||||||
|
if selectedIndex >= filtersLimit - 1 && translation.x < 0.0 {
|
||||||
let overscroll = -translation.x
|
let overscroll = -translation.x
|
||||||
transitionFraction = -rubberBandingOffset(offset: overscroll, bandingStart: 0.0) / layout.size.width
|
transitionFraction = -rubberBandingOffset(offset: overscroll, bandingStart: 0.0) / layout.size.width
|
||||||
|
|
||||||
|
if self.filtersLimit != nil {
|
||||||
|
transitionFraction = 0.0
|
||||||
|
recognizer.isEnabled = false
|
||||||
|
recognizer.isEnabled = true
|
||||||
|
|
||||||
|
self.displayFilterLimit?()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.transitionFraction = transitionFraction + self.transitionFractionOffset
|
self.transitionFraction = transitionFraction + self.transitionFractionOffset
|
||||||
if let currentItemNode = self.currentItemNodeValue {
|
if let currentItemNode = self.currentItemNodeValue {
|
||||||
@@ -731,7 +744,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
if let directionIsToRight = directionIsToRight {
|
if let directionIsToRight = directionIsToRight {
|
||||||
var updatedIndex = selectedIndex
|
var updatedIndex = selectedIndex
|
||||||
if directionIsToRight {
|
if directionIsToRight {
|
||||||
updatedIndex = min(updatedIndex + 1, self.availableFilters.count - 1)
|
updatedIndex = min(updatedIndex + 1, Int(filtersLimit) - 1)
|
||||||
} else {
|
} else {
|
||||||
updatedIndex = max(updatedIndex - 1, 0)
|
updatedIndex = max(updatedIndex - 1, 0)
|
||||||
}
|
}
|
||||||
@@ -807,13 +820,14 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateAvailableFilters(_ availableFilters: [ChatListContainerNodeFilter]) {
|
func updateAvailableFilters(_ availableFilters: [ChatListContainerNodeFilter], limit: Int32?) {
|
||||||
if self.availableFilters != availableFilters {
|
if self.availableFilters != availableFilters {
|
||||||
let apply: () -> Void = { [weak self] in
|
let apply: () -> Void = { [weak self] in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
strongSelf.availableFilters = availableFilters
|
strongSelf.availableFilters = availableFilters
|
||||||
|
strongSelf.filtersLimit = limit
|
||||||
if let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, isReorderingFilters, isEditing) = strongSelf.validLayout {
|
if let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, isReorderingFilters, isEditing) = strongSelf.validLayout {
|
||||||
strongSelf.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, isReorderingFilters: isReorderingFilters, isEditing: isEditing, transition: .immediate)
|
strongSelf.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, isReorderingFilters: isReorderingFilters, isEditing: isEditing, transition: .immediate)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -476,7 +476,7 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
|
|||||||
private var reorderedItemIds: [ChatListFilterTabEntryId]?
|
private var reorderedItemIds: [ChatListFilterTabEntryId]?
|
||||||
private lazy var hapticFeedback = { HapticFeedback() }()
|
private lazy var hapticFeedback = { HapticFeedback() }()
|
||||||
|
|
||||||
private var currentParams: (size: CGSize, sideInset: CGFloat, filters: [ChatListFilterTabEntry], selectedFilter: ChatListFilterTabEntryId?, isReordering: Bool, isEditing: Bool, canReorderAllChats: Bool, transitionFraction: CGFloat, presentationData: PresentationData)?
|
private var currentParams: (size: CGSize, sideInset: CGFloat, filters: [ChatListFilterTabEntry], selectedFilter: ChatListFilterTabEntryId?, isReordering: Bool, isEditing: Bool, canReorderAllChats: Bool, filtersLimit: Int32?, transitionFraction: CGFloat, presentationData: PresentationData)?
|
||||||
|
|
||||||
var reorderedFilterIds: [Int32]? {
|
var reorderedFilterIds: [Int32]? {
|
||||||
return self.reorderedItemIds.flatMap {
|
return self.reorderedItemIds.flatMap {
|
||||||
@@ -492,7 +492,7 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var filtersCount: Int32 {
|
var filtersCount: Int32 {
|
||||||
if let (_, _, filters, _, _, _, _, _, _) = self.currentParams {
|
if let (_, _, filters, _, _, _, _, _, _, _) = self.currentParams {
|
||||||
let filters = filters.filter { filter in
|
let filters = filters.filter { filter in
|
||||||
if case .all = filter {
|
if case .all = filter {
|
||||||
return false
|
return false
|
||||||
@@ -570,8 +570,8 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
|
|||||||
strongSelf.addSubnode(itemNode)
|
strongSelf.addSubnode(itemNode)
|
||||||
|
|
||||||
strongSelf.reorderingItemPosition = (itemNode.frame.minX, 0.0)
|
strongSelf.reorderingItemPosition = (itemNode.frame.minX, 0.0)
|
||||||
if let (size, sideInset, filters, selectedFilter, isReordering, isEditing, canReorderAllChats, transitionFraction, presentationData) = strongSelf.currentParams {
|
if let (size, sideInset, filters, selectedFilter, isReordering, isEditing, canReorderAllChats, filtersLimit, transitionFraction, presentationData) = strongSelf.currentParams {
|
||||||
strongSelf.update(size: size, sideInset: sideInset, filters: filters, selectedFilter: selectedFilter, isReordering: isReordering, isEditing: isEditing, canReorderAllChats: canReorderAllChats, transitionFraction: transitionFraction, presentationData: presentationData, transition: .animated(duration: 0.25, curve: .easeInOut))
|
strongSelf.update(size: size, sideInset: sideInset, filters: filters, selectedFilter: selectedFilter, isReordering: isReordering, isEditing: isEditing, canReorderAllChats: canReorderAllChats, filtersLimit: filtersLimit, transitionFraction: transitionFraction, presentationData: presentationData, transition: .animated(duration: 0.25, curve: .easeInOut))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -590,8 +590,8 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
|
|||||||
strongSelf.reorderingItemPosition = nil
|
strongSelf.reorderingItemPosition = nil
|
||||||
strongSelf.reorderingAutoScrollAnimator?.invalidate()
|
strongSelf.reorderingAutoScrollAnimator?.invalidate()
|
||||||
strongSelf.reorderingAutoScrollAnimator = nil
|
strongSelf.reorderingAutoScrollAnimator = nil
|
||||||
if let (size, sideInset, filters, selectedFilter, isReordering, isEditing, canReorderAllChats, transitionFraction, presentationData) = strongSelf.currentParams {
|
if let (size, sideInset, filters, selectedFilter, isReordering, isEditing, canReorderAllChats, filtersLimit, transitionFraction, presentationData) = strongSelf.currentParams {
|
||||||
strongSelf.update(size: size, sideInset: sideInset, filters: filters, selectedFilter: selectedFilter, isReordering: isReordering, isEditing: isEditing, canReorderAllChats: canReorderAllChats, transitionFraction: transitionFraction, presentationData: presentationData, transition: .animated(duration: 0.25, curve: .easeInOut))
|
strongSelf.update(size: size, sideInset: sideInset, filters: filters, selectedFilter: selectedFilter, isReordering: isReordering, isEditing: isEditing, canReorderAllChats: canReorderAllChats, filtersLimit: filtersLimit, transitionFraction: transitionFraction, presentationData: presentationData, transition: .animated(duration: 0.25, curve: .easeInOut))
|
||||||
}
|
}
|
||||||
}, moved: { [weak self] offset in
|
}, moved: { [weak self] offset in
|
||||||
guard let strongSelf = self, let reorderingItem = strongSelf.reorderingItem else {
|
guard let strongSelf = self, let reorderingItem = strongSelf.reorderingItem else {
|
||||||
@@ -626,8 +626,8 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
|
|||||||
updatedReorderedItemIds.insert(reorderingItem, at: targetIndex)
|
updatedReorderedItemIds.insert(reorderingItem, at: targetIndex)
|
||||||
}
|
}
|
||||||
strongSelf.reorderedItemIds = updatedReorderedItemIds
|
strongSelf.reorderedItemIds = updatedReorderedItemIds
|
||||||
if let (size, sideInset, filters, selectedFilter, isReordering, isEditing, canReorderAllChats, transitionFraction, presentationData) = strongSelf.currentParams {
|
if let (size, sideInset, filters, selectedFilter, isReordering, isEditing, canReorderAllChats, filtersLimit, transitionFraction, presentationData) = strongSelf.currentParams {
|
||||||
strongSelf.update(size: size, sideInset: sideInset, filters: filters, selectedFilter: selectedFilter, isReordering: isReordering, isEditing: isEditing, canReorderAllChats: canReorderAllChats, transitionFraction: transitionFraction, presentationData: presentationData, transition: .animated(duration: 0.25, curve: .easeInOut))
|
strongSelf.update(size: size, sideInset: sideInset, filters: filters, selectedFilter: selectedFilter, isReordering: isReordering, isEditing: isEditing, canReorderAllChats: canReorderAllChats, filtersLimit: filtersLimit, transitionFraction: transitionFraction, presentationData: presentationData, transition: .animated(duration: 0.25, curve: .easeInOut))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@@ -637,8 +637,8 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
|
|||||||
|
|
||||||
strongSelf.reorderingItemPosition = (initial, offset)
|
strongSelf.reorderingItemPosition = (initial, offset)
|
||||||
}
|
}
|
||||||
if let (size, sideInset, filters, selectedFilter, isReordering, isEditing, canReorderAllChats, transitionFraction, presentationData) = strongSelf.currentParams {
|
if let (size, sideInset, filters, selectedFilter, isReordering, isEditing, canReorderAllChats, filtersLimit, transitionFraction, presentationData) = strongSelf.currentParams {
|
||||||
strongSelf.update(size: size, sideInset: sideInset, filters: filters, selectedFilter: selectedFilter, isReordering: isReordering, isEditing: isEditing, canReorderAllChats: canReorderAllChats, transitionFraction: transitionFraction, presentationData: presentationData, transition: .immediate)
|
strongSelf.update(size: size, sideInset: sideInset, filters: filters, selectedFilter: selectedFilter, isReordering: isReordering, isEditing: isEditing, canReorderAllChats: canReorderAllChats, filtersLimit: filtersLimit, transitionFraction: transitionFraction, presentationData: presentationData, transition: .immediate)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
self.reorderingGesture = reorderingGesture
|
self.reorderingGesture = reorderingGesture
|
||||||
@@ -654,7 +654,7 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
|
|||||||
self.scrollNode.layer.removeAllAnimations()
|
self.scrollNode.layer.removeAllAnimations()
|
||||||
}
|
}
|
||||||
|
|
||||||
func update(size: CGSize, sideInset: CGFloat, filters: [ChatListFilterTabEntry], selectedFilter: ChatListFilterTabEntryId?, isReordering: Bool, isEditing: Bool, canReorderAllChats: Bool, transitionFraction: CGFloat, presentationData: PresentationData, transition proposedTransition: ContainedViewLayoutTransition) {
|
func update(size: CGSize, sideInset: CGFloat, filters: [ChatListFilterTabEntry], selectedFilter: ChatListFilterTabEntryId?, isReordering: Bool, isEditing: Bool, canReorderAllChats: Bool, filtersLimit: Int32?, transitionFraction: CGFloat, presentationData: PresentationData, transition proposedTransition: ContainedViewLayoutTransition) {
|
||||||
let isFirstTime = self.currentParams == nil
|
let isFirstTime = self.currentParams == nil
|
||||||
let transition: ContainedViewLayoutTransition = isFirstTime ? .immediate : proposedTransition
|
let transition: ContainedViewLayoutTransition = isFirstTime ? .immediate : proposedTransition
|
||||||
|
|
||||||
@@ -699,7 +699,7 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
|
|||||||
self.reorderedItemIds = nil
|
self.reorderedItemIds = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
self.currentParams = (size: size, sideInset: sideInset, filters: filters, selectedFilter: selectedFilter, isReordering, isEditing, canReorderAllChats, transitionFraction, presentationData: presentationData)
|
self.currentParams = (size: size, sideInset: sideInset, filters: filters, selectedFilter: selectedFilter, isReordering, isEditing, canReorderAllChats, filtersLimit, transitionFraction, presentationData: presentationData)
|
||||||
|
|
||||||
self.reorderingGesture?.isEnabled = isReordering
|
self.reorderingGesture?.isEnabled = isReordering
|
||||||
|
|
||||||
@@ -723,7 +723,6 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let folderLimit: Int = 4
|
|
||||||
var folderIndex = 0
|
var folderIndex = 0
|
||||||
for i in 0 ..< reorderedFilters.count {
|
for i in 0 ..< reorderedFilters.count {
|
||||||
let filter = reorderedFilters[i]
|
let filter = reorderedFilters[i]
|
||||||
@@ -769,7 +768,9 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
|
|||||||
unreadCount = unread.value
|
unreadCount = unread.value
|
||||||
unreadHasUnmuted = unread.hasUnmuted
|
unreadHasUnmuted = unread.hasUnmuted
|
||||||
|
|
||||||
isDisabled = !canReorderAllChats && folderIndex >= folderLimit
|
if let filtersLimit = filtersLimit {
|
||||||
|
isDisabled = !canReorderAllChats && folderIndex >= filtersLimit
|
||||||
|
}
|
||||||
folderIndex += 1
|
folderIndex += 1
|
||||||
}
|
}
|
||||||
if !wasAdded && (itemNode.unreadCount != 0) != (unreadCount != 0) {
|
if !wasAdded && (itemNode.unreadCount != 0) != (unreadCount != 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user