mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Folder improvements
This commit is contained in:
parent
a7c2818fa9
commit
ec69b23599
@ -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 }))
|
||||
}
|
||||
})
|
||||
})))
|
||||
|
||||
|
@ -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 }
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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<Bool, NoError> in
|
||||
if let tabBarItem = tabBarItem, tabBarItem.image == nil {
|
||||
|
@ -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()
|
||||
|
@ -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) {
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user