Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 79 additions & 1 deletion TelegramUI/ContactsController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBa
}

public class ContactsController: ViewController {
private var validLayout: ContainerViewLayout?

private let context: AccountContext

private var contactsNode: ContactsControllerNode {
Expand Down Expand Up @@ -182,7 +184,7 @@ public class ContactsController: ViewController {
}

override public func loadDisplayNode() {
self.displayNode = ContactsControllerNode(context: self.context, sortOrder: sortOrderPromise.get() |> distinctUntilChanged, present: { [weak self] c, a in
self.displayNode = ContactsControllerNode(context: self.context, sortOrder: sortOrderPromise.get() |> distinctUntilChanged, controller: self, present: { [weak self] c, a in
self?.present(c, in: .window(.root), with: a)
})
self._ready.set(self.contactsNode.contactListNode.ready)
Expand Down Expand Up @@ -302,6 +304,8 @@ public class ContactsController: ViewController {

override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)

self.validLayout = layout

self.contactsNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationInsetHeight, actualNavigationBarHeight: self.navigationHeight, transition: transition)
}
Expand Down Expand Up @@ -388,4 +392,78 @@ public class ContactsController: ViewController {
}
})
}

func previewingController(from sourceView: UIView, for location: CGPoint) -> (UIViewController, CGRect)? {
guard let layout = self.validLayout, case .compact = layout.metrics.widthClass else {
return nil
}

let boundsSize = self.view.bounds.size
let contentSize: CGSize
if let metrics = DeviceMetrics.forScreenSize(layout.size) {
contentSize = metrics.previewingContentSize(inLandscape: boundsSize.width > boundsSize.height)
} else {
contentSize = boundsSize
}

var selectedNode: ContactsPeerItemNode?

if let searchController = self.contactsNode.searchDisplayController {
guard let contentNode = searchController.contentNode as? ContactsSearchContainerNode else {
return nil
}

let listLocation = self.view.convert(location, to: contentNode.listNode.view)

contentNode.listNode.forEachItemNode { itemNode in
if let itemNode = itemNode as? ContactsPeerItemNode, itemNode.frame.contains(listLocation), !itemNode.isDisplayingRevealedOptions {
selectedNode = itemNode
}
}
} else {
let listLocation = self.view.convert(location, to: self.contactsNode.contactListNode.listNode.view)

self.contactsNode.contactListNode.listNode.forEachItemNode { itemNode in
if let itemNode = itemNode as? ContactsPeerItemNode, itemNode.frame.contains(listLocation), !itemNode.isDisplayingRevealedOptions {
selectedNode = itemNode
}
}
}

if let selectedNode = selectedNode, let peer = selectedNode.item?.peer {
var sourceRect = selectedNode.view.superview!.convert(selectedNode.frame, to: sourceView)
sourceRect.size.height -= UIScreenPixel
switch peer {
case let .peer(peer, _):
guard let peer = peer else {
return nil
}
if peer.id.namespace != Namespaces.Peer.SecretChat {
let chatController = ChatController(context: self.context, chatLocation: .peer(peer.id), mode: .standard(previewing: true))
chatController.canReadHistory.set(false)
chatController.containerLayoutUpdated(ContainerViewLayout(size: contentSize, metrics: LayoutMetrics(), intrinsicInsets: UIEdgeInsets(), safeInsets: UIEdgeInsets(), statusBarHeight: nil, inputHeight: nil, standardInputHeight: 216.0, inputHeightIsInteractivellyChanging: false, inVoiceOver: false), transition: .immediate)
return (chatController, sourceRect)
} else {
return nil
}
case .deviceContact:
return nil
}
} else {
return nil
}
}

func previewingCommit(_ viewControllerToCommit: UIViewController) {
if let viewControllerToCommit = viewControllerToCommit as? ViewController {
if let chatController = viewControllerToCommit as? ChatController {
chatController.canReadHistory.set(true)
chatController.updatePresentationMode(.standard(previewing: false))
if let navigationController = self.navigationController as? NavigationController {
navigateToChatController(navigationController: navigationController, chatController: chatController, context: self.context, chatLocation: chatController.chatLocation, animated: false)
self.contactsNode.contactListNode.listNode.clearHighlightAnimated(true)
}
}
}
}
}
29 changes: 25 additions & 4 deletions TelegramUI/ContactsControllerNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,25 @@ import Postbox
import TelegramCore
import SwiftSignalKit

private final class ContactsControllerNodeView: UITracingLayerView, PreviewingHostView {
var previewingDelegate: PreviewingHostViewDelegate? {
return PreviewingHostViewDelegate(controllerForLocation: { [weak self] sourceView, point in
return self?.controller?.previewingController(from: sourceView, for: point)
}, commitController: { [weak self] controller in
self?.controller?.previewingCommit(controller)
})
}

weak var controller: ContactsController?
}

final class ContactsControllerNode: ASDisplayNode {
let contactListNode: ContactListNode

private let context: AccountContext
private var searchDisplayController: SearchDisplayController?
var searchDisplayController: SearchDisplayController?

weak var controller: ContactsController?

private var containerLayout: (ContainerViewLayout, CGFloat)?

Expand All @@ -23,8 +37,9 @@ final class ContactsControllerNode: ASDisplayNode {
private var presentationData: PresentationData
private var presentationDataDisposable: Disposable?

init(context: AccountContext, sortOrder: Signal<ContactsSortOrder, NoError>, present: @escaping (ViewController, Any?) -> Void) {
init(context: AccountContext, sortOrder: Signal<ContactsSortOrder, NoError>, controller: ContactsController, present: @escaping (ViewController, Any?) -> Void) {
self.context = context
self.controller = controller

self.presentationData = context.sharedContext.currentPresentationData.with { $0 }

Expand All @@ -50,9 +65,9 @@ final class ContactsControllerNode: ASDisplayNode {
self.contactListNode = ContactListNode(context: context, presentation: presentation, displaySortOptions: true)

super.init()

self.setViewBlock({
return UITracingLayerView()
return ContactsControllerNodeView()
})

self.backgroundColor = self.presentationData.theme.chatList.backgroundColor
Expand Down Expand Up @@ -101,6 +116,12 @@ final class ContactsControllerNode: ASDisplayNode {
})
}
}

override func didLoad() {
super.didLoad()

(self.view as? ContactsControllerNodeView)?.controller = self.controller
}

deinit {
self.presentationDataDisposable?.dispose()
Expand Down
3 changes: 2 additions & 1 deletion TelegramUI/ContactsPeerItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,8 @@ class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
return nil
}
}
private var item: ContactsPeerItem? {

var item: ContactsPeerItem? {
return self.layoutParams?.0
}

Expand Down
2 changes: 1 addition & 1 deletion TelegramUI/ContactsSearchContainerNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ final class ContactsSearchContainerNode: SearchDisplayControllerContentNode {
private let openPeer: (ContactListPeer) -> Void

private let dimNode: ASDisplayNode
private let listNode: ListView
let listNode: ListView

private let searchQuery = Promise<String?>()
private let searchDisposable = MetaDisposable()
Expand Down