Moved ChatListController to temporary global 3d touch API

This commit is contained in:
Peter Iakovlev
2018-11-13 18:08:39 +04:00
parent 4c7026ced7
commit 04ab5d412a
8 changed files with 176 additions and 60 deletions

View File

@@ -451,9 +451,56 @@ final class BotCheckoutControllerNode: ItemListControllerNode<BotCheckoutEntry>,
}
var dismissImpl: (() -> Void)?
let canSave = paymentForm.canSaveCredentials || paymentForm.passwordMissing
let controller = BotCheckoutNativeCardEntryController(account: strongSelf.account, additionalFields: additionalFields, publishableKey: publishableKey, completion: { method in
applyPaymentMethod(method)
guard let strongSelf = self else {
return
}
if canSave && paymentForm.passwordMissing {
switch method {
case let .webToken(webToken) where webToken.saveOnServer:
var text = strongSelf.presentationData.strings.Checkout_NewCard_SaveInfoEnableHelp
text = text.replacingOccurrences(of: "[", with: "")
text = text.replacingOccurrences(of: "]", with: "")
present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_NotNow, action: {
var updatedToken = webToken
updatedToken.saveOnServer = false
applyPaymentMethod(.webToken(updatedToken))
}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Yes, action: {
guard let strongSelf = self else {
return
}
if paymentForm.passwordMissing {
var updatedToken = webToken
updatedToken.saveOnServer = false
applyPaymentMethod(.webToken(updatedToken))
let controller = SetupTwoStepVerificationController(account: strongSelf.account, initialState: .automatic, stateUpdated: { update, shouldDismiss, controller in
if shouldDismiss {
controller.dismiss()
}
switch update {
case .noPassword, .awaitingEmailConfirmation:
break
case .passwordSet:
var updatedToken = webToken
updatedToken.saveOnServer = true
applyPaymentMethod(.webToken(updatedToken))
}
})
strongSelf.present(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
} else {
var updatedToken = webToken
updatedToken.saveOnServer = true
applyPaymentMethod(.webToken(updatedToken))
}
})]), nil)
default:
break
}
} else {
applyPaymentMethod(method)
}
dismissImpl?()
})
dismissImpl = { [weak controller] in

View File

@@ -5,12 +5,21 @@ import Display
private let titleFont = Font.regular(17.0)
final class BotPaymentSwitchItemNode: BotPaymentItemNode {
private let toggled: (Bool) -> Void
private let title: String
private let titleNode: ASTextNode
private let switchNode: SwitchNode
private let buttonNode: HighlightableButtonNode
private var theme: PresentationTheme?
var canBeSwitched: Bool {
didSet {
}
}
var isOn: Bool {
get {
return self.switchNode.isOn
@@ -21,8 +30,10 @@ final class BotPaymentSwitchItemNode: BotPaymentItemNode {
}
}
init(title: String, isOn: Bool) {
init(title: String, isOn: Bool, canBeSwitched: Bool = true, toggled: @escaping (Bool) -> Void = { _ in }) {
self.title = title
self.canBeSwitched = canBeSwitched
self.toggled = toggled
self.titleNode = ASTextNode()
self.titleNode.maximumNumberOfLines = 1
@@ -30,10 +41,21 @@ final class BotPaymentSwitchItemNode: BotPaymentItemNode {
self.switchNode = SwitchNode()
self.switchNode.setOn(isOn, animated: false)
self.buttonNode = HighlightableButtonNode()
super.init(needsBackground: true)
self.addSubnode(self.titleNode)
self.addSubnode(self.switchNode)
self.addSubnode(self.buttonNode)
self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
if canBeSwitched {
self.switchNode.isUserInteractionEnabled = true
self.buttonNode.isUserInteractionEnabled = false
} else {
self.switchNode.isUserInteractionEnabled = false
self.buttonNode.isUserInteractionEnabled = true
}
}
override func layoutContents(theme: PresentationTheme, width: CGFloat, measuredInset: CGFloat, transition: ContainedViewLayoutTransition) -> CGFloat {
@@ -53,8 +75,14 @@ final class BotPaymentSwitchItemNode: BotPaymentItemNode {
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: leftInset, y: 11.0), size: titleSize))
let switchSize = self.switchNode.measure(CGSize(width: 100.0, height: 100.0))
transition.updateFrame(node: self.switchNode, frame: CGRect(origin: CGPoint(x: width - switchSize.width - 15.0, y: 6.0), size: switchSize))
let switchFrame = CGRect(origin: CGPoint(x: width - switchSize.width - 15.0, y: 6.0), size: switchSize)
transition.updateFrame(node: self.switchNode, frame: switchFrame)
transition.updateFrame(node: self.buttonNode, frame: switchFrame)
return 44.0
}
@objc private func buttonPressed() {
self.toggled(!self.isOn)
}
}

View File

@@ -4,28 +4,6 @@ import SwiftSignalKit
import Display
import TelegramCore
//private let tabImageNone = UIImage(bundleImageName: "Chat List/Tabs/IconChats")?.precomposed()
//private let tabImageUp = tabImageNone.flatMap({ image in
// return generateImage(image.size, contextGenerator: { size, context in
// context.clear(CGRect(origin: CGPoint(), size: size))
// context.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: size))
// context.setBlendMode(.copy)
// context.setFillColor(UIColor.clear.cgColor)
// context.translateBy(x: 0.0, y: 7.0)
// let _ = try? drawSvgPath(context, path: "M14.6557321,9.04533883 C14.9642504,8.81236784 15.4032142,8.87361104 15.6361852,9.18212936 C15.8691562,9.49064768 15.807913,9.9296115 15.4993947,10.1625825 L11.612306,13.0978342 C11.3601561,13.2882398 11.0117095,13.2861239 10.7618904,13.0926701 L6.97141581,10.1574184 C6.66574952,9.92071787 6.60984175,9.48104267 6.84654232,9.17537638 C7.08324289,8.86971009 7.5229181,8.81380232 7.82858438,9.05050289 L11.1958257,11.658013 L14.6557321,9.04533883 Z ")
// })
//})
//private let tabImageUnread = tabImageNone.flatMap({ image in
// return generateImage(image.size, contextGenerator: { size, context in
// context.clear(CGRect(origin: CGPoint(), size: size))
// context.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: size))
// context.setBlendMode(.copy)
// context.setFillColor(UIColor.clear.cgColor)
// context.translateBy(x: 0.0, y: 7.0)
// let _ = try? drawSvgPath(context, path: "M14.6557321,12.0977948 L11.1958257,9.48512064 L7.82858438,12.0926307 C7.5229181,12.3293313 7.08324289,12.2734235 6.84654232,11.9677572 C6.60984175,11.662091 6.66574952,11.2224158 6.97141581,10.9857152 L10.7618904,8.05046348 C11.0117095,7.85700968 11.3601561,7.85489378 11.612306,8.04529942 L15.4993947,10.9805511 C15.807913,11.2135221 15.8691562,11.6524859 15.6361852,11.9610043 C15.4032142,12.2695226 14.9642504,12.3307658 14.6557321,12.0977948 Z ")
// })
//})
public class ChatListController: TelegramController, KeyShortcutResponder, UIViewControllerPreviewingDelegate {
private var validLayout: ContainerViewLayout?
@@ -284,7 +262,7 @@ public class ChatListController: TelegramController, KeyShortcutResponder, UIVie
}
override public func loadDisplayNode() {
self.displayNode = ChatListControllerNode(account: self.account, groupId: self.groupId, controlsHistoryPreload: self.controlsHistoryPreload, presentationData: self.presentationData)
self.displayNode = ChatListControllerNode(account: self.account, groupId: self.groupId, controlsHistoryPreload: self.controlsHistoryPreload, presentationData: self.presentationData, controller: self)
self.chatListDisplayNode.navigationBar = self.navigationBar
@@ -520,7 +498,7 @@ public class ChatListController: TelegramController, KeyShortcutResponder, UIVie
if !self.didSetup3dTouch {
self.didSetup3dTouch = true
if #available(iOSApplicationExtension 9.0, *) {
self.registerForPreviewing(with: self, sourceView: self.view, theme: PeekControllerTheme(presentationTheme: self.presentationData.theme), onlyNative: false)
self.registerForPreviewingNonNative(with: self, sourceView: self.view, theme: PeekControllerTheme(presentationTheme: self.presentationData.theme))
}
}
@@ -678,6 +656,19 @@ public class ChatListController: TelegramController, KeyShortcutResponder, UIVie
}
public func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
if #available(iOSApplicationExtension 9.0, *) {
if let (controller, rect) = self.previewingController(from: previewingContext.sourceView, for: location) {
previewingContext.sourceRect = rect
return controller
} else {
return nil
}
} else {
return nil
}
}
func previewingController(from sourceView: UIView, for location: CGPoint) -> (UIViewController, CGRect)? {
guard let layout = self.validLayout, case .compact = layout.metrics.widthClass else {
return nil
}
@@ -693,11 +684,8 @@ public class ChatListController: TelegramController, KeyShortcutResponder, UIVie
if let searchController = self.chatListDisplayNode.searchDisplayController {
if let (view, action) = searchController.previewViewAndActionAtLocation(location) {
if let peerId = action as? PeerId, peerId.namespace != Namespaces.Peer.SecretChat {
if #available(iOSApplicationExtension 9.0, *) {
var sourceRect = view.superview!.convert(view.frame, to: self.view)
sourceRect.size.height -= UIScreenPixel
previewingContext.sourceRect = sourceRect
}
var sourceRect = view.superview!.convert(view.frame, to: sourceView)
sourceRect.size.height -= UIScreenPixel
let chatController = ChatController(account: self.account, chatLocation: .peer(peerId), mode: .standard(previewing: true))
// chatController.peekActions = .remove({ [weak self] in
@@ -709,18 +697,15 @@ public class ChatListController: TelegramController, KeyShortcutResponder, UIVie
// })
chatController.canReadHistory.set(false)
chatController.containerLayoutUpdated(ContainerViewLayout(size: contentSize, metrics: LayoutMetrics(), intrinsicInsets: UIEdgeInsets(), safeInsets: UIEdgeInsets(), statusBarHeight: nil, inputHeight: nil, standardInputHeight: 216.0, inputHeightIsInteractivellyChanging: false), transition: .immediate)
return chatController
return (chatController, sourceRect)
} else if let messageId = action as? MessageId, messageId.peerId.namespace != Namespaces.Peer.SecretChat {
if #available(iOSApplicationExtension 9.0, *) {
var sourceRect = view.superview!.convert(view.frame, to: self.view)
sourceRect.size.height -= UIScreenPixel
previewingContext.sourceRect = sourceRect
}
var sourceRect = view.superview!.convert(view.frame, to: sourceView)
sourceRect.size.height -= UIScreenPixel
let chatController = ChatController(account: self.account, chatLocation: .peer(messageId.peerId), messageId: messageId, 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), transition: .immediate)
return chatController
return (chatController, sourceRect)
}
}
return nil
@@ -745,25 +730,22 @@ public class ChatListController: TelegramController, KeyShortcutResponder, UIVie
}
}
if let selectedNode = selectedNode, let item = selectedNode.item {
if #available(iOSApplicationExtension 9.0, *) {
var sourceRect = selectedNode.view.superview!.convert(selectedNode.frame, to: self.view)
sourceRect.size.height -= UIScreenPixel
previewingContext.sourceRect = sourceRect
}
var sourceRect = selectedNode.view.superview!.convert(selectedNode.frame, to: sourceView)
sourceRect.size.height -= UIScreenPixel
switch item.content {
case let .peer(_, peer, _, _, _, _, _, _, _):
if peer.peerId.namespace != Namespaces.Peer.SecretChat {
let chatController = ChatController(account: self.account, chatLocation: .peer(peer.peerId), 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), transition: .immediate)
return chatController
return (chatController, sourceRect)
} else {
return nil
}
case let .groupReference(groupId, _, _, _):
let chatListController = ChatListController(account: self.account, groupId: groupId, controlsHistoryPreload: false)
chatListController.containerLayoutUpdated(ContainerViewLayout(size: contentSize, metrics: LayoutMetrics(), intrinsicInsets: UIEdgeInsets(), safeInsets: UIEdgeInsets(), statusBarHeight: nil, inputHeight: nil, standardInputHeight: 216.0, inputHeightIsInteractivellyChanging: false), transition: .immediate)
return chatListController
return (chatListController, sourceRect)
}
} else {
return nil
@@ -771,6 +753,10 @@ public class ChatListController: TelegramController, KeyShortcutResponder, UIVie
}
public func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
self.previewingCommit(viewControllerToCommit)
}
func previewingCommit(_ viewControllerToCommit: UIViewController) {
if let viewControllerToCommit = viewControllerToCommit as? ViewController {
if let chatController = viewControllerToCommit as? ChatController {
chatController.canReadHistory.set(true)

View File

@@ -4,6 +4,18 @@ import Display
import Postbox
import TelegramCore
private final class ChatListControllerNodeView: 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: ChatListController?
}
class ChatListControllerNode: ASDisplayNode {
private let account: Account
private let groupId: PeerGroupId?
@@ -11,6 +23,7 @@ class ChatListControllerNode: ASDisplayNode {
private var chatListEmptyNode: ChatListEmptyNode?
let chatListNode: ChatListNode
var navigationBar: NavigationBar?
weak var controller: ChatListController?
private(set) var searchDisplayController: SearchDisplayController?
@@ -24,17 +37,19 @@ class ChatListControllerNode: ASDisplayNode {
var themeAndStrings: (PresentationTheme, PresentationStrings, dateTimeFormat: PresentationDateTimeFormat)
init(account: Account, groupId: PeerGroupId?, controlsHistoryPreload: Bool, presentationData: PresentationData) {
init(account: Account, groupId: PeerGroupId?, controlsHistoryPreload: Bool, presentationData: PresentationData, controller: ChatListController) {
self.account = account
self.groupId = groupId
self.chatListNode = ChatListNode(account: account, groupId: groupId, controlsHistoryPreload: controlsHistoryPreload, mode: .chatList, theme: presentationData.theme, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameSortOrder: presentationData.nameSortOrder, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: presentationData.disableAnimations)
self.themeAndStrings = (presentationData.theme, presentationData.strings, presentationData.dateTimeFormat)
self.controller = controller
super.init()
self.setViewBlock({
return UITracingLayerView()
return ChatListControllerNodeView()
})
self.backgroundColor = presentationData.theme.chatList.backgroundColor
@@ -62,6 +77,12 @@ class ChatListControllerNode: ASDisplayNode {
}
}
override func didLoad() {
super.didLoad()
(self.view as? ChatListControllerNodeView)?.controller = self.controller
}
func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, disableAnimations: Bool) {
self.themeAndStrings = (theme, strings, dateTimeFormat)

View File

@@ -109,7 +109,7 @@ final class ChatRecentActionsController: TelegramController {
self.displayNode = ChatRecentActionsControllerNode(account: self.account, peer: self.peer, presentationData: self.presentationData, interaction: self.interaction, pushController: { [weak self] c in
(self?.navigationController as? NavigationController)?.pushViewController(c)
}, presentController: { [weak self] c, a in
self?.present(c, in: .window(.root), with: a)
self?.present(c, in: .window(.root), with: a, blockInteraction: true)
}, getNavigationController: { [weak self] in
return self?.navigationController as? NavigationController
})

View File

@@ -87,7 +87,7 @@ public class PeerMediaCollectionController: TelegramController {
return openChatMessage(account: account, message: galleryMessage.message, standalone: false, reverseMessageGalleryOrder: true, navigationController: navigationController, dismissInput: {
self?.mediaCollectionDisplayNode.view.endEditing(true)
}, present: { c, a in
self?.present(c, in: .window(.root), with: a)
self?.present(c, in: .window(.root), with: a, blockInteraction: true)
}, transitionNode: { messageId, media in
if let strongSelf = self {
return strongSelf.mediaCollectionDisplayNode.transitionNodeForGallery(messageId: messageId, media: media)

View File

@@ -1463,17 +1463,51 @@ func internalMediaGridMessageVideo(postbox: Postbox, videoReference: FileMediaRe
let blurSourceImage = thumbnailImage ?? fullSizeImage
if let fullSizeImage = blurSourceImage {
var sideBlurredImage: UIImage?
let thumbnailSize = CGSize(width: fullSizeImage.width, height: fullSizeImage.height)
let thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 74.0, height: 74.0))
let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0)
thumbnailContext.withFlippedContext { c in
c.interpolationQuality = .none
c.draw(fullSizeImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize))
if true {
let initialThumbnailContextFittingSize = fittedSize.fitted(CGSize(width: 100.0, height: 100.0))
let thumbnailContextSize = thumbnailSize.aspectFitted(initialThumbnailContextFittingSize)
let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0)
thumbnailContext.withFlippedContext { c in
c.interpolationQuality = .none
c.draw(fullSizeImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize))
}
telegramFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes)
var thumbnailContextFittingSize = CGSize(width: floor(arguments.drawingSize.width * 0.5), height: floor(arguments.drawingSize.width * 0.5))
if thumbnailContextFittingSize.width < 150.0 || thumbnailContextFittingSize.height < 150.0 {
thumbnailContextFittingSize = thumbnailContextFittingSize.aspectFilled(CGSize(width: 150.0, height: 150.0))
}
if thumbnailContextFittingSize.width > thumbnailContextSize.width {
let additionalContextSize = thumbnailContextFittingSize
let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0)
additionalBlurContext.withFlippedContext { c in
c.interpolationQuality = .default
if let image = thumbnailContext.generateImage()?.cgImage {
c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize))
}
}
telegramFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes)
sideBlurredImage = additionalBlurContext.generateImage()
} else {
sideBlurredImage = thumbnailContext.generateImage()
}
} else {
let thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 74.0, height: 74.0))
let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0)
thumbnailContext.withFlippedContext { c in
c.interpolationQuality = .none
c.draw(fullSizeImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize))
}
telegramFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes)
telegramFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes)
sideBlurredImage = thumbnailContext.generateImage()
}
telegramFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes)
telegramFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes)
if let blurredImage = thumbnailContext.generateImage() {
if let blurredImage = sideBlurredImage {
let filledSize = thumbnailSize.aspectFilled(arguments.drawingRect.size)
c.interpolationQuality = .medium
c.draw(blurredImage.cgImage!, in: CGRect(origin: CGPoint(x: arguments.drawingRect.minX + (arguments.drawingRect.width - filledSize.width) / 2.0, y: arguments.drawingRect.minY + (arguments.drawingRect.height - filledSize.height) / 2.0), size: filledSize))

View File

@@ -22,7 +22,7 @@ private func presentLiveLocationController(account: Account, peerId: PeerId, con
let _ = openChatMessage(account: account, message: message, standalone: false, reverseMessageGalleryOrder: false, navigationController: strongController.navigationController as? NavigationController, modal: true, dismissInput: {
controller?.view.endEditing(true)
}, present: { c, a in
controller?.present(c, in: .window(.root), with: a)
controller?.present(c, in: .window(.root), with: a, blockInteraction: true)
}, transitionNode: { _, _ in
return nil
}, addToTransitionSurface: { _ in