diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 710f1e3687..b937c1e766 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -167,7 +167,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, super.init(context: context, navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData), mediaAccessoryPanelVisibility: .always, locationBroadcastPanelSource: .summary) - self.hasTabBarItemContextAction = true + self.tabBarItemContextActionType = .whenActive self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style @@ -2260,16 +2260,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, guard let strongSelf = self else { return } - if presetList.isEmpty { - if let navigationController = strongSelf.navigationController as? NavigationController { - var viewControllers = navigationController.viewControllers - //viewControllers.append(chatListFilterPresetListController(context: strongSelf.context, updated: { _ in })) - viewControllers.append(chatListFilterPresetController(context: strongSelf.context, currentPreset: nil, updated: { _ in })) - navigationController.setViewControllers(viewControllers, animated: true) - } - } else { - strongSelf.push(chatListFilterPresetListController(context: strongSelf.context, updated: { _ in })) - } + strongSelf.push(chatListFilterPresetListController(context: strongSelf.context, updated: { _ in })) }) }))) diff --git a/submodules/ChatListUI/Sources/ChatListFilterPresetController.swift b/submodules/ChatListUI/Sources/ChatListFilterPresetController.swift index 7a13cff698..148141f4e8 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterPresetController.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterPresetController.swift @@ -232,7 +232,7 @@ private enum ChatListFilterPresetEntry: ItemListNodeEntry { case .includePeersHeader, .addIncludePeer, .includeCategory, .includePeer, .includePeerInfo: return ChatListFilterPresetControllerSection.includePeers.rawValue case .excludePeersHeader, .addExcludePeer, .excludeCategory, .excludePeer, .excludePeerInfo: - return ChatListFilterPresetControllerSection.includePeers.rawValue + return ChatListFilterPresetControllerSection.excludePeers.rawValue } } @@ -859,7 +859,9 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat let (state, includePeers, excludePeers) = stateWithPeers let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { - let _ = attemptNavigationImpl?() + if attemptNavigationImpl?() ?? true { + dismissImpl?() + } }) let rightNavigationButton = ItemListNavigationButton(content: .text(currentPreset == nil ? presentationData.strings.Common_Create : presentationData.strings.Common_Done), style: .bold, enabled: state.isComplete, action: { let state = stateValue.with { $0 } diff --git a/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift b/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift index 0daef2a67d..092a2aaec1 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift @@ -305,7 +305,7 @@ public func chatListFilterPresetListController(context: AccountContext, updated: }) } - let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text("Filters"), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false) + let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text("Folders"), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false) let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: chatListFilterPresetListControllerEntries(presentationData: presentationData, state: state, filters: filtersWithCounts, suggestedFilters: suggestedFilters, settings: filterSettings), style: .blocks, animateChanges: true) return (controllerState, (listState, arguments)) diff --git a/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift b/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift index a72ba28b9a..91a0a72887 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift @@ -387,6 +387,7 @@ final class ChatListFilterTabContainerNode: ASDisplayNode { private var reorderingItemPosition: (initial: CGFloat, offset: CGFloat)? private var reorderingAutoScrollAnimator: ConstantDisplayLinkAnimator? private var reorderedItemIds: [ChatListFilterTabEntryId]? + private lazy var hapticFeedback = { HapticFeedback() }() private var currentParams: (size: CGSize, sideInset: CGFloat, filters: [ChatListFilterTabEntry], selectedFilter: ChatListFilterTabEntryId?, isReordering: Bool, isEditing: Bool, transitionFraction: CGFloat, presentationData: PresentationData)? @@ -443,6 +444,8 @@ final class ChatListFilterTabContainerNode: ASDisplayNode { for (id, itemNode) in strongSelf.itemNodes { let itemFrame = itemNode.view.convert(itemNode.bounds, to: strongSelf.view) if itemFrame.contains(point) { + strongSelf.hapticFeedback.impact() + strongSelf.reorderingItem = id itemNode.frame = itemFrame strongSelf.reorderingAutoScrollAnimator = ConstantDisplayLinkAnimator(update: { @@ -507,6 +510,8 @@ final class ChatListFilterTabContainerNode: ASDisplayNode { targetIndex = max(1, min(reorderedItemIds.count - 1, itemIndex)) } if targetIndex != currentItemIndex { + strongSelf.hapticFeedback.tap() + var updatedReorderedItemIds = reorderedItemIds if targetIndex > currentItemIndex { updatedReorderedItemIds.insert(reorderingItem, at: targetIndex + 1) diff --git a/submodules/Display/Source/ImmediateTextNode.swift b/submodules/Display/Source/ImmediateTextNode.swift index fd336ce84d..75116832f0 100644 --- a/submodules/Display/Source/ImmediateTextNode.swift +++ b/submodules/Display/Source/ImmediateTextNode.swift @@ -197,6 +197,12 @@ public class ImmediateTextNode: TextNode { } public class ASTextNode: ImmediateTextNode { + override public var attributedText: NSAttributedString? { + didSet { + self.setNeedsLayout() + } + } + override public init() { super.init() diff --git a/submodules/Display/Source/TabBarController.swift b/submodules/Display/Source/TabBarController.swift index 359eedfd26..d8102845b4 100644 --- a/submodules/Display/Source/TabBarController.swift +++ b/submodules/Display/Source/TabBarController.swift @@ -393,7 +393,7 @@ open class TabBarController: ViewController { } } self.controllers = controllers - self.tabBarControllerNode.tabBarNode.tabBarItems = self.controllers.map({ TabBarNodeItem(item: $0.tabBarItem, hasContext: $0.hasTabBarItemContextAction) }) + self.tabBarControllerNode.tabBarNode.tabBarItems = self.controllers.map({ TabBarNodeItem(item: $0.tabBarItem, contextActionType: $0.tabBarItemContextActionType) }) let signals = combineLatest(self.controllers.map({ $0.tabBarItem }).map { tabBarItem -> Signal in if let tabBarItem = tabBarItem, tabBarItem.image == nil { diff --git a/submodules/Display/Source/TabBarNode.swift b/submodules/Display/Source/TabBarNode.swift index 13a530be66..1f500076dc 100644 --- a/submodules/Display/Source/TabBarNode.swift +++ b/submodules/Display/Source/TabBarNode.swift @@ -102,6 +102,7 @@ private final class TabBarItemNode: ASDisplayNode { let contextImageNode: ASImageNode let contextTextImageNode: ASImageNode var contentWidth: CGFloat? + var isSelected: Bool = false var swiped: ((TabBarItemSwipeDirection) -> Void)? @@ -253,10 +254,24 @@ private final class TabBarNodeContainer { } contextAction(strongSelf.imageNode.extractedContainerNode, gesture) } - imageNode.swiped = { [weak self] direction in + imageNode.swiped = { [weak imageNode] direction in + guard let imageNode = imageNode, imageNode.isSelected else { + return + } swipeAction(direction) } - imageNode.containerNode.isGestureEnabled = item.hasContext + imageNode.containerNode.isGestureEnabled = item.contextActionType != .none + let contextActionType = item.contextActionType + imageNode.containerNode.shouldBegin = { [weak imageNode] _ in + switch contextActionType { + case .none: + return false + case .always: + return true + case .whenActive: + return imageNode?.isSelected ?? false + } + } } deinit { @@ -269,11 +284,11 @@ private final class TabBarNodeContainer { final class TabBarNodeItem { let item: UITabBarItem - let hasContext: Bool + let contextActionType: TabBarItemContextActionType - init(item: UITabBarItem, hasContext: Bool) { + init(item: UITabBarItem, contextActionType: TabBarItemContextActionType) { self.item = item - self.hasContext = hasContext + self.contextActionType = contextActionType } } @@ -429,6 +444,7 @@ class TabBarNode: ASDisplayNode { node.imageNode.image = image node.accessibilityLabel = item.item.title node.contentWidth = max(contentWidth, imageContentWidth) + node.isSelected = true } else { let (textImage, contentWidth) = tabBarItemImage(item.item.image, title: item.item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarTextColor, horizontal: self.horizontal, imageMode: false, centered: self.centered) let (image, imageContentWidth) = tabBarItemImage(item.item.image, title: item.item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarIconColor, horizontal: self.horizontal, imageMode: true, centered: self.centered) @@ -436,6 +452,7 @@ class TabBarNode: ASDisplayNode { node.accessibilityLabel = item.item.title node.imageNode.image = image node.contentWidth = max(contentWidth, imageContentWidth) + node.isSelected = false } container.badgeBackgroundNode.image = self.badgeImage node.extractedContainerNode.contentNode.addSubnode(container.badgeContainerNode) @@ -468,6 +485,7 @@ class TabBarNode: ASDisplayNode { node.contextTextImageNode.image = contextTextImage node.contextImageNode.image = contextImage node.contentWidth = max(contentWidth, imageContentWidth) + node.isSelected = true } else { let (textImage, contentWidth) = tabBarItemImage(item.item.image, title: item.item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarTextColor, horizontal: self.horizontal, imageMode: false, centered: self.centered) let (image, imageContentWidth) = tabBarItemImage(item.item.image, title: item.item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarIconColor, horizontal: self.horizontal, imageMode: true, centered: self.centered) @@ -479,6 +497,7 @@ class TabBarNode: ASDisplayNode { node.contextTextImageNode.image = contextTextImage node.contextImageNode.image = contextImage node.contentWidth = max(contentWidth, imageContentWidth) + node.isSelected = false } let updatedImageSize = node.imageNode.image?.size ?? CGSize() diff --git a/submodules/Display/Source/ViewController.swift b/submodules/Display/Source/ViewController.swift index 1200e0ba38..06fdcddc18 100644 --- a/submodules/Display/Source/ViewController.swift +++ b/submodules/Display/Source/ViewController.swift @@ -67,6 +67,12 @@ public enum ViewControllerNavigationPresentation { case modalInLargeLayout } +public enum TabBarItemContextActionType { + case none + case always + case whenActive +} + @objc open class ViewController: UIViewController, ContainableController { private var validLayout: ContainerViewLayout? public var currentlyAppliedLayout: ContainerViewLayout? { @@ -625,7 +631,7 @@ public enum ViewControllerNavigationPresentation { open func toolbarActionSelected(action: ToolbarActionOption) { } - open var hasTabBarItemContextAction: Bool = false + open var tabBarItemContextActionType: TabBarItemContextActionType = .none open func tabBarItemContextAction(sourceNode: ContextExtractedContentContainingNode, gesture: ContextGesture) { } diff --git a/submodules/SettingsUI/Sources/SettingsController.swift b/submodules/SettingsUI/Sources/SettingsController.swift index ccd1c45b22..cbc0798ea0 100644 --- a/submodules/SettingsUI/Sources/SettingsController.swift +++ b/submodules/SettingsUI/Sources/SettingsController.swift @@ -770,7 +770,7 @@ private final class SettingsControllerImpl: ItemListController, SettingsControll super.init(presentationData: ItemListPresentationData(presentationData), updatedPresentationData: updatedPresentationData |> map(ItemListPresentationData.init(_:)), state: state, tabBarItem: tabBarItem) - self.hasTabBarItemContextAction = true + self.tabBarItemContextActionType = .always self.accountsAndPeersDisposable = (accountsAndPeers |> deliverOnMainQueue).start(next: { [weak self] value in diff --git a/submodules/TelegramCore/Sources/ChatListFiltering.swift b/submodules/TelegramCore/Sources/ChatListFiltering.swift index e3ca7635fd..0db9b496b6 100644 --- a/submodules/TelegramCore/Sources/ChatListFiltering.swift +++ b/submodules/TelegramCore/Sources/ChatListFiltering.swift @@ -172,7 +172,7 @@ extension ChatListFilter { categories: ChatListFilterPeerCategories(apiFlags: flags), excludeMuted: (flags & (1 << 11)) != 0, excludeRead: (flags & (1 << 12)) != 0, - excludeArchived: false, + excludeArchived: (flags & (1 << 13)) != 0, includePeers: includePeers.compactMap { peer -> PeerId? in switch peer { case let .inputPeerUser(userId, _): @@ -210,6 +210,9 @@ extension ChatListFilter { if self.data.excludeRead { flags |= 1 << 12 } + if self.data.excludeArchived { + flags |= 1 << 13 + } flags |= self.data.categories.apiFlags return .dialogFilter(flags: flags, id: self.id, title: self.title, includePeers: self.data.includePeers.compactMap { peerId -> Api.InputPeer? in return transaction.getPeer(peerId).flatMap(apiInputPeer) diff --git a/submodules/TelegramUI/Sources/ChatHistoryNavigationButtonNode.swift b/submodules/TelegramUI/Sources/ChatHistoryNavigationButtonNode.swift index 6d27116d42..4105b4aeea 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryNavigationButtonNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryNavigationButtonNode.swift @@ -89,6 +89,7 @@ class ChatHistoryNavigationButtonNode: ASControlNode { if let string = self.badgeTextNode.attributedText?.string { self.badgeTextNode.attributedText = NSAttributedString(string: string, font: badgeFont, textColor: theme.chat.historyNavigation.badgeTextColor) + self.badgeTextNode.redrawIfPossible() } } } diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaBadge.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaBadge.swift index b713b25614..09ff15c32c 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaBadge.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaBadge.swift @@ -122,7 +122,7 @@ final class ChatMessageInteractiveMediaBadge: ASDisplayNode { } self.durationNode.attributedText = convertedText let durationSize = self.durationNode.measure(CGSize(width: 160.0, height: 160.0)) - self.durationNode.frame = CGRect(x: 7.0 + inset, y: 2.0, width: durationSize.width, height: durationSize.height) + self.durationNode.frame = CGRect(x: 7.0 + inset, y: 3.0, width: durationSize.width, height: durationSize.height) currentContentSize = CGSize(width: widthForString(text.string) + 14.0 + inset, height: 18.0) if let iconNode = self.iconNode { @@ -188,7 +188,7 @@ final class ChatMessageInteractiveMediaBadge: ASDisplayNode { transition.updateAlpha(node: statusNode, alpha: active ? 1.0 : 0.0) } - let durationFrame = CGRect(x: active ? 42.0 : 7.0, y: active ? 6.0 : 2.0, width: durationSize.width, height: durationSize.height) + let durationFrame = CGRect(x: active ? 42.0 : 7.0, y: active ? 6.0 : 3.0, width: durationSize.width, height: durationSize.height) self.durationNode.bounds = CGRect(origin: CGPoint(), size: durationFrame.size) textTransition.updatePosition(node: self.durationNode, position: durationFrame.center)