mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
126 lines
5.3 KiB
Swift
126 lines
5.3 KiB
Swift
import Foundation
|
|
import AsyncDisplayKit
|
|
import Display
|
|
import SwiftSignalKit
|
|
import Postbox
|
|
import TelegramCore
|
|
|
|
private enum ChatListSearchEntry {
|
|
case message(Message)
|
|
}
|
|
|
|
final class ChatListSearchContainerNode: SearchDisplayControllerContentNode {
|
|
private let account: Account
|
|
private let openMessage: (Peer, MessageId) -> Void
|
|
|
|
private let recentPeersNode: ChatListSearchRecentPeersNode
|
|
private let listNode: ListView
|
|
|
|
private let searchQuery = Promise<String?>()
|
|
private let searchDisposable = MetaDisposable()
|
|
|
|
init(account: Account, openPeer: @escaping (PeerId) -> Void, openMessage: @escaping (Peer, MessageId) -> Void) {
|
|
self.account = account
|
|
self.openMessage = openMessage
|
|
|
|
self.recentPeersNode = ChatListSearchRecentPeersNode(account: account, peerSelected: openPeer)
|
|
self.listNode = ListView()
|
|
|
|
super.init()
|
|
|
|
self.backgroundColor = UIColor.white
|
|
|
|
self.addSubnode(self.recentPeersNode)
|
|
self.addSubnode(self.listNode)
|
|
|
|
self.listNode.isHidden = true
|
|
|
|
let searchItems = searchQuery.get()
|
|
|> mapToSignal { query -> Signal<[ChatListSearchEntry], NoError> in
|
|
if let query = query, !query.isEmpty {
|
|
return searchMessages(account: account, query: query)
|
|
|> delay(0.2, queue: Queue.concurrentDefaultQueue())
|
|
|> map { messages -> [ChatListSearchEntry] in
|
|
return messages.map({ .message($0) })
|
|
}
|
|
} else {
|
|
return .single([])
|
|
}
|
|
}
|
|
|
|
let previousSearchItems = Atomic<[ChatListSearchEntry]>(value: [])
|
|
|
|
self.searchDisposable.set((searchItems
|
|
|> deliverOnMainQueue).start(next: { [weak self] items in
|
|
if let strongSelf = self {
|
|
let previousItems = previousSearchItems.swap(items)
|
|
|
|
var listItems: [ListViewItem] = []
|
|
for item in items {
|
|
switch item {
|
|
case let .message(message):
|
|
listItems.append(ChatListItem(account: account, message: message, combinedReadState: nil, notificationSettings: nil, action: { [weak strongSelf] _ in
|
|
if let strongSelf = strongSelf, let peer = message.peers[message.id.peerId] {
|
|
strongSelf.listNode.clearHighlightAnimated(true)
|
|
strongSelf.openMessage(peer, message.id)
|
|
}
|
|
}))
|
|
}
|
|
}
|
|
|
|
strongSelf.listNode.deleteAndInsertItems(deleteIndices: (0 ..< previousItems.count).map({ ListViewDeleteItem(index: $0, directionHint: nil) }), insertIndicesAndItems: (0 ..< listItems.count).map({ ListViewInsertItem(index: $0, previousIndex: nil, item: listItems[$0], directionHint: .Down) }), updateIndicesAndItems: [], options: [])
|
|
}
|
|
}))
|
|
}
|
|
|
|
deinit {
|
|
self.searchDisposable.dispose()
|
|
}
|
|
|
|
override func searchTextUpdated(text: String) {
|
|
if text.isEmpty {
|
|
self.searchQuery.set(.single(nil))
|
|
self.recentPeersNode.isHidden = false
|
|
self.listNode.isHidden = true
|
|
} else {
|
|
self.searchQuery.set(.single(text))
|
|
self.recentPeersNode.isHidden = true
|
|
self.listNode.isHidden = false
|
|
}
|
|
}
|
|
|
|
override func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
|
|
super.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: transition)
|
|
|
|
let recentPeersSize = self.recentPeersNode.measure(CGSize(width: layout.size.width, height: CGFloat.infinity))
|
|
self.recentPeersNode.frame = CGRect(origin: CGPoint(x: 0.0, y: navigationBarHeight), size: recentPeersSize)
|
|
self.recentPeersNode.layout()
|
|
|
|
var duration: Double = 0.0
|
|
var curve: UInt = 0
|
|
switch transition {
|
|
case .immediate:
|
|
break
|
|
case let .animated(animationDuration, animationCurve):
|
|
duration = animationDuration
|
|
switch animationCurve {
|
|
case .easeInOut:
|
|
break
|
|
case .spring:
|
|
curve = 7
|
|
}
|
|
}
|
|
|
|
|
|
let listViewCurve: ListViewAnimationCurve
|
|
if curve == 7 {
|
|
listViewCurve = .Spring(duration: duration)
|
|
} else {
|
|
listViewCurve = .Default
|
|
}
|
|
|
|
self.listNode.frame = CGRect(origin: CGPoint(), size: layout.size)
|
|
self.listNode.deleteAndInsertItems(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: layout.size, insets: UIEdgeInsets(top: navigationBarHeight, left: 0.0, bottom: layout.insets(options: [.input]).bottom, right: 0.0), duration: duration, curve: listViewCurve), stationaryItemRange: nil, completion: { _ in })
|
|
}
|
|
}
|