mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 09:20:08 +00:00
Saved message search
This commit is contained in:
parent
960d968e0f
commit
ca4eb2cb69
@ -912,6 +912,24 @@ public extension Peer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct ChatControllerCustomNavigationPanelNodeLayoutResult {
|
||||||
|
public var backgroundHeight: CGFloat
|
||||||
|
public var insetHeight: CGFloat
|
||||||
|
public var hitTestSlop: CGFloat
|
||||||
|
|
||||||
|
public init(backgroundHeight: CGFloat, insetHeight: CGFloat, hitTestSlop: CGFloat) {
|
||||||
|
self.backgroundHeight = backgroundHeight
|
||||||
|
self.insetHeight = insetHeight
|
||||||
|
self.hitTestSlop = hitTestSlop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol ChatControllerCustomNavigationPanelNode: ASDisplayNode {
|
||||||
|
typealias LayoutResult = ChatControllerCustomNavigationPanelNodeLayoutResult
|
||||||
|
|
||||||
|
func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition, chatController: ChatController) -> LayoutResult
|
||||||
|
}
|
||||||
|
|
||||||
public protocol ChatController: ViewController {
|
public protocol ChatController: ViewController {
|
||||||
var chatLocation: ChatLocation { get }
|
var chatLocation: ChatLocation { get }
|
||||||
var canReadHistory: ValuePromise<Bool> { get }
|
var canReadHistory: ValuePromise<Bool> { get }
|
||||||
@ -919,9 +937,14 @@ public protocol ChatController: ViewController {
|
|||||||
|
|
||||||
var purposefulAction: (() -> Void)? { get set }
|
var purposefulAction: (() -> Void)? { get set }
|
||||||
|
|
||||||
|
var stateUpdated: ((ContainedViewLayoutTransition) -> Void)? { get set }
|
||||||
|
|
||||||
var selectedMessageIds: Set<EngineMessage.Id>? { get }
|
var selectedMessageIds: Set<EngineMessage.Id>? { get }
|
||||||
var presentationInterfaceStateSignal: Signal<Any, NoError> { get }
|
var presentationInterfaceStateSignal: Signal<Any, NoError> { get }
|
||||||
|
|
||||||
|
var customNavigationBarContentNode: NavigationBarContentNode? { get }
|
||||||
|
var customNavigationPanelNode: ChatControllerCustomNavigationPanelNode? { get }
|
||||||
|
|
||||||
func updatePresentationMode(_ mode: ChatControllerPresentationMode)
|
func updatePresentationMode(_ mode: ChatControllerPresentationMode)
|
||||||
func beginMessageSearch(_ query: String)
|
func beginMessageSearch(_ query: String)
|
||||||
func displayPromoAnnouncement(text: String)
|
func displayPromoAnnouncement(text: String)
|
||||||
|
|||||||
@ -994,6 +994,35 @@ public extension ContainedViewLayoutTransition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateTintColor(view: UIView, color: UIColor, completion: ((Bool) -> Void)? = nil) {
|
||||||
|
if let current = view.tintColor, current == color {
|
||||||
|
completion?(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch self {
|
||||||
|
case .immediate:
|
||||||
|
view.tintColor = color
|
||||||
|
completion?(true)
|
||||||
|
case let .animated(duration, curve):
|
||||||
|
let previousColor: CGColor = view.layer.layerTintColor ?? UIColor.clear.cgColor
|
||||||
|
view.tintColor = color
|
||||||
|
|
||||||
|
view.layer.animate(
|
||||||
|
from: previousColor,
|
||||||
|
to: color.cgColor,
|
||||||
|
keyPath: "contentsMultiplyColor",
|
||||||
|
timingFunction: curve.timingFunction,
|
||||||
|
duration: duration,
|
||||||
|
delay: 0.0,
|
||||||
|
mediaTimingFunction: curve.mediaTimingFunction,
|
||||||
|
removeOnCompletion: true,
|
||||||
|
additive: false,
|
||||||
|
completion: completion
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updateContentsRect(layer: CALayer, contentsRect: CGRect, completion: ((Bool) -> Void)? = nil) {
|
func updateContentsRect(layer: CALayer, contentsRect: CGRect, completion: ((Bool) -> Void)? = nil) {
|
||||||
if layer.contentsRect == contentsRect {
|
if layer.contentsRect == contentsRect {
|
||||||
if let completion = completion {
|
if let completion = completion {
|
||||||
|
|||||||
@ -493,6 +493,8 @@ open class NavigationBar: ASDisplayNode {
|
|||||||
public var makeCustomTransitionNode: ((NavigationBar, Bool) -> CustomNavigationTransitionNode?)?
|
public var makeCustomTransitionNode: ((NavigationBar, Bool) -> CustomNavigationTransitionNode?)?
|
||||||
public var allowsCustomTransition: (() -> Bool)?
|
public var allowsCustomTransition: (() -> Bool)?
|
||||||
|
|
||||||
|
public var customSetContentNode: ((NavigationBarContentNode?, Bool) -> Void)?
|
||||||
|
|
||||||
private var collapsed: Bool {
|
private var collapsed: Bool {
|
||||||
get {
|
get {
|
||||||
return self.frame.size.height.isLess(than: 44.0)
|
return self.frame.size.height.isLess(than: 44.0)
|
||||||
@ -1649,6 +1651,11 @@ open class NavigationBar: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func setContentNode(_ contentNode: NavigationBarContentNode?, animated: Bool) {
|
public func setContentNode(_ contentNode: NavigationBarContentNode?, animated: Bool) {
|
||||||
|
if let customSetContentNode = self.customSetContentNode {
|
||||||
|
customSetContentNode(contentNode, animated)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if self.contentNode !== contentNode {
|
if self.contentNode !== contentNode {
|
||||||
if let previous = self.contentNode {
|
if let previous = self.contentNode {
|
||||||
if animated {
|
if animated {
|
||||||
|
|||||||
@ -110,7 +110,7 @@ private extension MessageHistoryInput {
|
|||||||
assert(Set(items.map({ $0.stableId })).count == items.count)
|
assert(Set(items.map({ $0.stableId })).count == items.count)
|
||||||
|
|
||||||
if items.count > limit {
|
if items.count > limit {
|
||||||
let overLimit = limit - items.count
|
let overLimit = items.count - limit
|
||||||
switch direction {
|
switch direction {
|
||||||
case .lowToHigh:
|
case .lowToHigh:
|
||||||
items.removeFirst(overLimit)
|
items.removeFirst(overLimit)
|
||||||
|
|||||||
@ -21,6 +21,7 @@ public enum PresentationResourceKey: Int32 {
|
|||||||
case navigationSearchIcon
|
case navigationSearchIcon
|
||||||
case navigationCompactSearchIcon
|
case navigationCompactSearchIcon
|
||||||
case navigationCompactTagsSearchIcon
|
case navigationCompactTagsSearchIcon
|
||||||
|
case navigationCompactTagsSearchWhiteIcon
|
||||||
case navigationCalendarIcon
|
case navigationCalendarIcon
|
||||||
case navigationMoreIcon
|
case navigationMoreIcon
|
||||||
case navigationMoreCircledIcon
|
case navigationMoreCircledIcon
|
||||||
|
|||||||
@ -79,6 +79,12 @@ public struct PresentationResourcesRootController {
|
|||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/NavigationSearchTagsIcon"), color: theme.rootController.navigationBar.accentTextColor)
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/NavigationSearchTagsIcon"), color: theme.rootController.navigationBar.accentTextColor)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func navigationCompactTagsSearchWhiteIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||||
|
return theme.image(PresentationResourceKey.navigationCompactTagsSearchIcon.rawValue, { theme in
|
||||||
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/NavigationSearchTagsIcon"), color: .white)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public static func navigationCalendarIcon(_ theme: PresentationTheme) -> UIImage? {
|
public static func navigationCalendarIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||||
return theme.image(PresentationResourceKey.navigationCalendarIcon.rawValue, { theme in
|
return theme.image(PresentationResourceKey.navigationCalendarIcon.rawValue, { theme in
|
||||||
|
|||||||
@ -427,15 +427,15 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
|||||||
if let tagButton {
|
if let tagButton {
|
||||||
buttons = [
|
buttons = [
|
||||||
self.deleteButton,
|
self.deleteButton,
|
||||||
self.forwardButton,
|
|
||||||
tagButton,
|
tagButton,
|
||||||
|
self.forwardButton,
|
||||||
self.shareButton
|
self.shareButton
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
buttons = [
|
buttons = [
|
||||||
self.deleteButton,
|
self.deleteButton,
|
||||||
self.forwardButton,
|
self.shareButton,
|
||||||
self.shareButton
|
self.forwardButton
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
} else if !self.deleteButton.isHidden {
|
} else if !self.deleteButton.isHidden {
|
||||||
@ -459,17 +459,17 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
|||||||
if let tagButton {
|
if let tagButton {
|
||||||
buttons = [
|
buttons = [
|
||||||
self.deleteButton,
|
self.deleteButton,
|
||||||
self.forwardButton,
|
|
||||||
self.reportButton,
|
self.reportButton,
|
||||||
tagButton,
|
tagButton,
|
||||||
self.shareButton
|
self.shareButton,
|
||||||
|
self.forwardButton
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
buttons = [
|
buttons = [
|
||||||
self.deleteButton,
|
self.deleteButton,
|
||||||
self.forwardButton,
|
|
||||||
self.reportButton,
|
self.reportButton,
|
||||||
self.shareButton
|
self.shareButton,
|
||||||
|
self.forwardButton
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,83 @@ import TelegramUIPreferences
|
|||||||
import AppBundle
|
import AppBundle
|
||||||
import PeerInfoPaneNode
|
import PeerInfoPaneNode
|
||||||
|
|
||||||
|
private final class SearchNavigationContentNode: ASDisplayNode, PeerInfoPanelNodeNavigationContentNode {
|
||||||
|
private struct Params: Equatable {
|
||||||
|
var width: CGFloat
|
||||||
|
var defaultHeight: CGFloat
|
||||||
|
var insets: UIEdgeInsets
|
||||||
|
|
||||||
|
init(width: CGFloat, defaultHeight: CGFloat, insets: UIEdgeInsets) {
|
||||||
|
self.width = width
|
||||||
|
self.defaultHeight = defaultHeight
|
||||||
|
self.insets = insets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
weak var chatController: ChatController?
|
||||||
|
let contentNode: NavigationBarContentNode
|
||||||
|
|
||||||
|
var panelNode: ChatControllerCustomNavigationPanelNode?
|
||||||
|
private var appliedPanelNode: ChatControllerCustomNavigationPanelNode?
|
||||||
|
|
||||||
|
private var params: Params?
|
||||||
|
|
||||||
|
init(chatController: ChatController, contentNode: NavigationBarContentNode) {
|
||||||
|
self.chatController = chatController
|
||||||
|
self.contentNode = contentNode
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
self.addSubnode(self.contentNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(transition: ContainedViewLayoutTransition) {
|
||||||
|
if let params = self.params {
|
||||||
|
let _ = self.update(width: params.width, defaultHeight: params.defaultHeight, insets: params.insets, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(width: CGFloat, defaultHeight: CGFloat, insets: UIEdgeInsets, transition: ContainedViewLayoutTransition) -> CGFloat {
|
||||||
|
self.params = Params(width: width, defaultHeight: defaultHeight, insets: insets)
|
||||||
|
|
||||||
|
let size = CGSize(width: width, height: defaultHeight)
|
||||||
|
transition.updateFrame(node: self.contentNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 10.0), size: size))
|
||||||
|
self.contentNode.updateLayout(size: size, leftInset: insets.left, rightInset: insets.right, transition: transition)
|
||||||
|
|
||||||
|
var contentHeight: CGFloat = size.height + 10.0
|
||||||
|
|
||||||
|
if self.appliedPanelNode !== self.panelNode {
|
||||||
|
if let previous = self.appliedPanelNode {
|
||||||
|
transition.updateAlpha(node: previous, alpha: 0.0, completion: { [weak previous] _ in
|
||||||
|
previous?.removeFromSupernode()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
self.appliedPanelNode = self.panelNode
|
||||||
|
if let panelNode = self.panelNode, let chatController = self.chatController {
|
||||||
|
self.addSubnode(panelNode)
|
||||||
|
let panelLayout = panelNode.updateLayout(width: width, leftInset: insets.left, rightInset: insets.right, transition: .immediate, chatController: chatController)
|
||||||
|
let panelHeight = panelLayout.backgroundHeight
|
||||||
|
let panelFrame = CGRect(origin: CGPoint(x: 0.0, y: contentHeight), size: CGSize(width: width, height: panelHeight))
|
||||||
|
panelNode.frame = panelFrame
|
||||||
|
panelNode.alpha = 0.0
|
||||||
|
transition.updateAlpha(node: panelNode, alpha: 1.0)
|
||||||
|
|
||||||
|
contentHeight += panelHeight - 1.0
|
||||||
|
}
|
||||||
|
} else if let panelNode = self.panelNode, let chatController = self.chatController {
|
||||||
|
let panelLayout = panelNode.updateLayout(width: width, leftInset: insets.left, rightInset: insets.right, transition: transition, chatController: chatController)
|
||||||
|
let panelHeight = panelLayout.backgroundHeight
|
||||||
|
let panelFrame = CGRect(origin: CGPoint(x: 0.0, y: contentHeight), size: CGSize(width: width, height: panelHeight))
|
||||||
|
transition.updateFrame(node: panelNode, frame: panelFrame)
|
||||||
|
|
||||||
|
contentHeight += panelHeight - 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
return contentHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public final class PeerInfoChatPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScrollViewDelegate, UIGestureRecognizerDelegate {
|
public final class PeerInfoChatPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScrollViewDelegate, UIGestureRecognizerDelegate {
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private let peerId: EnginePeer.Id
|
private let peerId: EnginePeer.Id
|
||||||
@ -51,6 +128,12 @@ public final class PeerInfoChatPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro
|
|||||||
public var tabBarOffset: CGFloat {
|
public var tabBarOffset: CGFloat {
|
||||||
return 0.0
|
return 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var searchNavigationContentNode: SearchNavigationContentNode?
|
||||||
|
public var navigationContentNode: PeerInfoPanelNodeNavigationContentNode? {
|
||||||
|
return self.searchNavigationContentNode
|
||||||
|
}
|
||||||
|
public var externalDataUpdated: ((ContainedViewLayoutTransition) -> Void)?
|
||||||
|
|
||||||
private var presentationData: PresentationData
|
private var presentationData: PresentationData
|
||||||
private var presentationDataDisposable: Disposable?
|
private var presentationDataDisposable: Disposable?
|
||||||
@ -77,6 +160,29 @@ public final class PeerInfoChatPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro
|
|||||||
|
|
||||||
self.addSubnode(self.chatController.displayNode)
|
self.addSubnode(self.chatController.displayNode)
|
||||||
self.chatController.displayNode.clipsToBounds = true
|
self.chatController.displayNode.clipsToBounds = true
|
||||||
|
|
||||||
|
self.chatController.stateUpdated = { [weak self] transition in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let contentNode = self.chatController.customNavigationBarContentNode {
|
||||||
|
if self.searchNavigationContentNode?.contentNode !== contentNode {
|
||||||
|
self.searchNavigationContentNode = SearchNavigationContentNode(chatController: self.chatController, contentNode: contentNode)
|
||||||
|
self.searchNavigationContentNode?.panelNode = self.chatController.customNavigationPanelNode
|
||||||
|
self.externalDataUpdated?(transition)
|
||||||
|
} else if self.searchNavigationContentNode?.panelNode !== self.chatController.customNavigationPanelNode {
|
||||||
|
self.searchNavigationContentNode?.panelNode = self.chatController.customNavigationPanelNode
|
||||||
|
self.externalDataUpdated?(transition)
|
||||||
|
} else {
|
||||||
|
self.searchNavigationContentNode?.update(transition: transition)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if self.searchNavigationContentNode !== nil {
|
||||||
|
self.searchNavigationContentNode = nil
|
||||||
|
self.externalDataUpdated?(transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
@ -124,6 +230,9 @@ public final class PeerInfoChatPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro
|
|||||||
super.didLoad()
|
super.didLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func activateSearch() {
|
||||||
|
self.chatController.activateSearch(domain: .everything, query: "")
|
||||||
|
}
|
||||||
|
|
||||||
override public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
|
override public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -39,6 +39,10 @@ public struct PeerInfoStatusData: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public protocol PeerInfoPanelNodeNavigationContentNode: ASDisplayNode {
|
||||||
|
func update(width: CGFloat, defaultHeight: CGFloat, insets: UIEdgeInsets, transition: ContainedViewLayoutTransition) -> CGFloat
|
||||||
|
}
|
||||||
|
|
||||||
public protocol PeerInfoPaneNode: ASDisplayNode {
|
public protocol PeerInfoPaneNode: ASDisplayNode {
|
||||||
var isReady: Signal<Bool, NoError> { get }
|
var isReady: Signal<Bool, NoError> { get }
|
||||||
|
|
||||||
@ -48,6 +52,9 @@ public protocol PeerInfoPaneNode: ASDisplayNode {
|
|||||||
var tabBarOffsetUpdated: ((ContainedViewLayoutTransition) -> Void)? { get set }
|
var tabBarOffsetUpdated: ((ContainedViewLayoutTransition) -> Void)? { get set }
|
||||||
var tabBarOffset: CGFloat { get }
|
var tabBarOffset: CGFloat { get }
|
||||||
|
|
||||||
|
var navigationContentNode: PeerInfoPanelNodeNavigationContentNode? { get }
|
||||||
|
var externalDataUpdated: ((ContainedViewLayoutTransition) -> Void)? { get set }
|
||||||
|
|
||||||
func update(size: CGSize, topInset: CGFloat, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, presentationData: PresentationData, synchronous: Bool, transition: ContainedViewLayoutTransition)
|
func update(size: CGSize, topInset: CGFloat, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, presentationData: PresentationData, synchronous: Bool, transition: ContainedViewLayoutTransition)
|
||||||
func scrollToTop() -> Bool
|
func scrollToTop() -> Bool
|
||||||
func transferVelocity(_ velocity: CGFloat)
|
func transferVelocity(_ velocity: CGFloat)
|
||||||
@ -59,3 +66,15 @@ public protocol PeerInfoPaneNode: ASDisplayNode {
|
|||||||
func updateSelectedMessages(animated: Bool)
|
func updateSelectedMessages(animated: Bool)
|
||||||
func ensureMessageIsVisible(id: MessageId)
|
func ensureMessageIsVisible(id: MessageId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public extension PeerInfoPaneNode {
|
||||||
|
var navigationContentNode: PeerInfoPanelNodeNavigationContentNode? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var externalDataUpdated: ((ContainedViewLayoutTransition) -> Void)? {
|
||||||
|
get {
|
||||||
|
return nil
|
||||||
|
} set(value) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -207,6 +207,7 @@ final class PeerInfoScreenData {
|
|||||||
let appConfiguration: AppConfiguration?
|
let appConfiguration: AppConfiguration?
|
||||||
let isPowerSavingEnabled: Bool?
|
let isPowerSavingEnabled: Bool?
|
||||||
let accountIsPremium: Bool
|
let accountIsPremium: Bool
|
||||||
|
let hasSavedMessageTags: Bool
|
||||||
|
|
||||||
let _isContact: Bool
|
let _isContact: Bool
|
||||||
var forceIsContact: Bool = false
|
var forceIsContact: Bool = false
|
||||||
@ -242,7 +243,8 @@ final class PeerInfoScreenData {
|
|||||||
threadData: MessageHistoryThreadData?,
|
threadData: MessageHistoryThreadData?,
|
||||||
appConfiguration: AppConfiguration?,
|
appConfiguration: AppConfiguration?,
|
||||||
isPowerSavingEnabled: Bool?,
|
isPowerSavingEnabled: Bool?,
|
||||||
accountIsPremium: Bool
|
accountIsPremium: Bool,
|
||||||
|
hasSavedMessageTags: Bool
|
||||||
) {
|
) {
|
||||||
self.peer = peer
|
self.peer = peer
|
||||||
self.chatPeer = chatPeer
|
self.chatPeer = chatPeer
|
||||||
@ -267,6 +269,7 @@ final class PeerInfoScreenData {
|
|||||||
self.appConfiguration = appConfiguration
|
self.appConfiguration = appConfiguration
|
||||||
self.isPowerSavingEnabled = isPowerSavingEnabled
|
self.isPowerSavingEnabled = isPowerSavingEnabled
|
||||||
self.accountIsPremium = accountIsPremium
|
self.accountIsPremium = accountIsPremium
|
||||||
|
self.hasSavedMessageTags = hasSavedMessageTags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -662,7 +665,8 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
|||||||
threadData: nil,
|
threadData: nil,
|
||||||
appConfiguration: appConfiguration,
|
appConfiguration: appConfiguration,
|
||||||
isPowerSavingEnabled: isPowerSavingEnabled,
|
isPowerSavingEnabled: isPowerSavingEnabled,
|
||||||
accountIsPremium: peer?.isPremium ?? false
|
accountIsPremium: peer?.isPremium ?? false,
|
||||||
|
hasSavedMessageTags: false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -697,7 +701,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
threadData: nil,
|
threadData: nil,
|
||||||
appConfiguration: nil,
|
appConfiguration: nil,
|
||||||
isPowerSavingEnabled: nil,
|
isPowerSavingEnabled: nil,
|
||||||
accountIsPremium: false
|
accountIsPremium: false,
|
||||||
|
hasSavedMessageTags: false
|
||||||
))
|
))
|
||||||
case let .user(userPeerId, secretChatId, kind):
|
case let .user(userPeerId, secretChatId, kind):
|
||||||
let groupsInCommon: GroupsInCommonContext?
|
let groupsInCommon: GroupsInCommonContext?
|
||||||
@ -853,6 +858,19 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
hasSavedMessagesChats = .single(false)
|
hasSavedMessagesChats = .single(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let hasSavedMessageTags: Signal<Bool, NoError>
|
||||||
|
if let peerId = chatLocation.peerId {
|
||||||
|
hasSavedMessageTags = context.engine.data.subscribe(
|
||||||
|
TelegramEngine.EngineData.Item.Messages.SavedMessageTagStats(peerId: context.account.peerId, threadId: peerId.toInt64())
|
||||||
|
)
|
||||||
|
|> map { tags -> Bool in
|
||||||
|
return !tags.isEmpty
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged
|
||||||
|
} else {
|
||||||
|
hasSavedMessageTags = .single(false)
|
||||||
|
}
|
||||||
|
|
||||||
return combineLatest(
|
return combineLatest(
|
||||||
context.account.viewTracker.peerView(peerId, updateData: true),
|
context.account.viewTracker.peerView(peerId, updateData: true),
|
||||||
peerInfoAvailableMediaPanes(context: context, peerId: peerId, chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder),
|
peerInfoAvailableMediaPanes(context: context, peerId: peerId, chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder),
|
||||||
@ -863,9 +881,10 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
accountIsPremium,
|
accountIsPremium,
|
||||||
savedMessagesPeer,
|
savedMessagesPeer,
|
||||||
hasSavedMessagesChats,
|
hasSavedMessagesChats,
|
||||||
hasSavedMessages
|
hasSavedMessages,
|
||||||
|
hasSavedMessageTags
|
||||||
)
|
)
|
||||||
|> map { peerView, availablePanes, globalNotificationSettings, encryptionKeyFingerprint, status, hasStories, accountIsPremium, savedMessagesPeer, hasSavedMessagesChats, hasSavedMessages -> PeerInfoScreenData in
|
|> map { peerView, availablePanes, globalNotificationSettings, encryptionKeyFingerprint, status, hasStories, accountIsPremium, savedMessagesPeer, hasSavedMessagesChats, hasSavedMessages, hasSavedMessageTags -> PeerInfoScreenData in
|
||||||
var availablePanes = availablePanes
|
var availablePanes = availablePanes
|
||||||
|
|
||||||
if let hasStories {
|
if let hasStories {
|
||||||
@ -924,7 +943,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
threadData: nil,
|
threadData: nil,
|
||||||
appConfiguration: nil,
|
appConfiguration: nil,
|
||||||
isPowerSavingEnabled: nil,
|
isPowerSavingEnabled: nil,
|
||||||
accountIsPremium: accountIsPremium
|
accountIsPremium: accountIsPremium,
|
||||||
|
hasSavedMessageTags: hasSavedMessageTags
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
case .channel:
|
case .channel:
|
||||||
@ -985,6 +1005,19 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
hasSavedMessagesChats = .single(false)
|
hasSavedMessagesChats = .single(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let hasSavedMessageTags: Signal<Bool, NoError>
|
||||||
|
if let peerId = chatLocation.peerId {
|
||||||
|
hasSavedMessageTags = context.engine.data.subscribe(
|
||||||
|
TelegramEngine.EngineData.Item.Messages.SavedMessageTagStats(peerId: context.account.peerId, threadId: peerId.toInt64())
|
||||||
|
)
|
||||||
|
|> map { tags -> Bool in
|
||||||
|
return !tags.isEmpty
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged
|
||||||
|
} else {
|
||||||
|
hasSavedMessageTags = .single(false)
|
||||||
|
}
|
||||||
|
|
||||||
return combineLatest(
|
return combineLatest(
|
||||||
context.account.viewTracker.peerView(peerId, updateData: true),
|
context.account.viewTracker.peerView(peerId, updateData: true),
|
||||||
peerInfoAvailableMediaPanes(context: context, peerId: peerId, chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder),
|
peerInfoAvailableMediaPanes(context: context, peerId: peerId, chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder),
|
||||||
@ -998,9 +1031,10 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
accountIsPremium,
|
accountIsPremium,
|
||||||
context.engine.peers.recommendedChannels(peerId: peerId),
|
context.engine.peers.recommendedChannels(peerId: peerId),
|
||||||
hasSavedMessages,
|
hasSavedMessages,
|
||||||
hasSavedMessagesChats
|
hasSavedMessagesChats,
|
||||||
|
hasSavedMessageTags
|
||||||
)
|
)
|
||||||
|> map { peerView, availablePanes, globalNotificationSettings, status, currentInvitationsContext, invitations, currentRequestsContext, requests, hasStories, accountIsPremium, recommendedChannels, hasSavedMessages, hasSavedMessagesChats -> PeerInfoScreenData in
|
|> map { peerView, availablePanes, globalNotificationSettings, status, currentInvitationsContext, invitations, currentRequestsContext, requests, hasStories, accountIsPremium, recommendedChannels, hasSavedMessages, hasSavedMessagesChats, hasSavedMessageTags -> PeerInfoScreenData in
|
||||||
var availablePanes = availablePanes
|
var availablePanes = availablePanes
|
||||||
if let hasStories {
|
if let hasStories {
|
||||||
if hasStories {
|
if hasStories {
|
||||||
@ -1072,7 +1106,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
threadData: nil,
|
threadData: nil,
|
||||||
appConfiguration: nil,
|
appConfiguration: nil,
|
||||||
isPowerSavingEnabled: nil,
|
isPowerSavingEnabled: nil,
|
||||||
accountIsPremium: accountIsPremium
|
accountIsPremium: accountIsPremium,
|
||||||
|
hasSavedMessageTags: hasSavedMessageTags
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
case let .group(groupId):
|
case let .group(groupId):
|
||||||
@ -1219,6 +1254,19 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
hasSavedMessagesChats = .single(false)
|
hasSavedMessagesChats = .single(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let hasSavedMessageTags: Signal<Bool, NoError>
|
||||||
|
if let peerId = chatLocation.peerId {
|
||||||
|
hasSavedMessageTags = context.engine.data.subscribe(
|
||||||
|
TelegramEngine.EngineData.Item.Messages.SavedMessageTagStats(peerId: context.account.peerId, threadId: peerId.toInt64())
|
||||||
|
)
|
||||||
|
|> map { tags -> Bool in
|
||||||
|
return !tags.isEmpty
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged
|
||||||
|
} else {
|
||||||
|
hasSavedMessageTags = .single(false)
|
||||||
|
}
|
||||||
|
|
||||||
return combineLatest(queue: .mainQueue(),
|
return combineLatest(queue: .mainQueue(),
|
||||||
context.account.viewTracker.peerView(groupId, updateData: true),
|
context.account.viewTracker.peerView(groupId, updateData: true),
|
||||||
peerInfoAvailableMediaPanes(context: context, peerId: groupId, chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder),
|
peerInfoAvailableMediaPanes(context: context, peerId: groupId, chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder),
|
||||||
@ -1233,9 +1281,10 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration]),
|
context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration]),
|
||||||
accountIsPremium,
|
accountIsPremium,
|
||||||
hasSavedMessages,
|
hasSavedMessages,
|
||||||
hasSavedMessagesChats
|
hasSavedMessagesChats,
|
||||||
|
hasSavedMessageTags
|
||||||
)
|
)
|
||||||
|> mapToSignal { peerView, availablePanes, globalNotificationSettings, status, membersData, currentInvitationsContext, invitations, currentRequestsContext, requests, threadData, preferencesView, accountIsPremium, hasSavedMessages, hasSavedMessagesChats -> Signal<PeerInfoScreenData, NoError> in
|
|> mapToSignal { peerView, availablePanes, globalNotificationSettings, status, membersData, currentInvitationsContext, invitations, currentRequestsContext, requests, threadData, preferencesView, accountIsPremium, hasSavedMessages, hasSavedMessagesChats, hasSavedMessageTags -> Signal<PeerInfoScreenData, NoError> in
|
||||||
var discussionPeer: Peer?
|
var discussionPeer: Peer?
|
||||||
if case let .known(maybeLinkedDiscussionPeerId) = (peerView.cachedData as? CachedChannelData)?.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId, let peer = peerView.peers[linkedDiscussionPeerId] {
|
if case let .known(maybeLinkedDiscussionPeerId) = (peerView.cachedData as? CachedChannelData)?.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId, let peer = peerView.peers[linkedDiscussionPeerId] {
|
||||||
discussionPeer = peer
|
discussionPeer = peer
|
||||||
@ -1320,7 +1369,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
threadData: threadData,
|
threadData: threadData,
|
||||||
appConfiguration: appConfiguration,
|
appConfiguration: appConfiguration,
|
||||||
isPowerSavingEnabled: nil,
|
isPowerSavingEnabled: nil,
|
||||||
accountIsPremium: accountIsPremium
|
accountIsPremium: accountIsPremium,
|
||||||
|
hasSavedMessageTags: hasSavedMessageTags
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -178,7 +178,7 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode {
|
|||||||
self.backgroundNode.updateColor(color: backgroundColor, transition: transition)
|
self.backgroundNode.updateColor(color: backgroundColor, transition: transition)
|
||||||
|
|
||||||
transition.updateTintColor(layer: self.textNode.layer, color: self.contentsColor)
|
transition.updateTintColor(layer: self.textNode.layer, color: self.contentsColor)
|
||||||
transition.updateTintColor(layer: self.iconNode.layer, color: self.contentsColor)
|
transition.updateTintColor(view: self.iconNode.view, color: self.contentsColor)
|
||||||
transition.updateStrokeColor(layer: self.backIconLayer, strokeColor: self.contentsColor)
|
transition.updateStrokeColor(layer: self.backIconLayer, strokeColor: self.contentsColor)
|
||||||
|
|
||||||
switch self.key {
|
switch self.key {
|
||||||
@ -247,9 +247,13 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode {
|
|||||||
case .search:
|
case .search:
|
||||||
text = ""
|
text = ""
|
||||||
accessibilityText = presentationData.strings.Common_Search
|
accessibilityText = presentationData.strings.Common_Search
|
||||||
icon = nil// PresentationResourcesRootController.navigationCompactSearchIcon(presentationData.theme)
|
icon = nil
|
||||||
isAnimation = true
|
isAnimation = true
|
||||||
animationState = .search
|
animationState = .search
|
||||||
|
case .searchWithTags:
|
||||||
|
text = ""
|
||||||
|
accessibilityText = presentationData.strings.Common_Search
|
||||||
|
icon = PresentationResourcesRootController.navigationCompactTagsSearchWhiteIcon(presentationData.theme)
|
||||||
case .editPhoto:
|
case .editPhoto:
|
||||||
text = presentationData.strings.Settings_EditPhoto
|
text = presentationData.strings.Settings_EditPhoto
|
||||||
accessibilityText = text
|
accessibilityText = text
|
||||||
|
|||||||
@ -13,6 +13,7 @@ enum PeerInfoHeaderNavigationButtonKey {
|
|||||||
case select
|
case select
|
||||||
case selectionDone
|
case selectionDone
|
||||||
case search
|
case search
|
||||||
|
case searchWithTags
|
||||||
case editPhoto
|
case editPhoto
|
||||||
case editVideo
|
case editVideo
|
||||||
case more
|
case more
|
||||||
@ -210,7 +211,7 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode {
|
|||||||
if wasAdded {
|
if wasAdded {
|
||||||
buttonNode.updateContentsColor(backgroundColor: self.backgroundContentColor, contentsColor: self.contentsColor, canBeExpanded: self.canBeExpanded, transition: .immediate)
|
buttonNode.updateContentsColor(backgroundColor: self.backgroundContentColor, contentsColor: self.contentsColor, canBeExpanded: self.canBeExpanded, transition: .immediate)
|
||||||
|
|
||||||
if key == .moreToSearch {
|
if key == .moreToSearch || key == .searchWithTags {
|
||||||
buttonNode.layer.animateScale(from: 0.001, to: 1.0, duration: 0.2)
|
buttonNode.layer.animateScale(from: 0.001, to: 1.0, duration: 0.2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +237,7 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode {
|
|||||||
}
|
}
|
||||||
for key in removeKeys {
|
for key in removeKeys {
|
||||||
if let buttonNode = self.rightButtonNodes.removeValue(forKey: key) {
|
if let buttonNode = self.rightButtonNodes.removeValue(forKey: key) {
|
||||||
if key == .moreToSearch {
|
if key == .moreToSearch || key == .searchWithTags {
|
||||||
buttonNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak buttonNode] _ in
|
buttonNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak buttonNode] _ in
|
||||||
buttonNode?.removeFromSupernode()
|
buttonNode?.removeFromSupernode()
|
||||||
})
|
})
|
||||||
|
|||||||
@ -169,6 +169,9 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
var emojiStatusPackDisposable = MetaDisposable()
|
var emojiStatusPackDisposable = MetaDisposable()
|
||||||
var emojiStatusFileAndPackTitle = Promise<(TelegramMediaFile, LoadedStickerPack)?>()
|
var emojiStatusFileAndPackTitle = Promise<(TelegramMediaFile, LoadedStickerPack)?>()
|
||||||
|
|
||||||
|
var customNavigationContentNode: PeerInfoPanelNodeNavigationContentNode?
|
||||||
|
private var appliedCustomNavigationContentNode: PeerInfoPanelNodeNavigationContentNode?
|
||||||
|
|
||||||
private var validLayout: (width: CGFloat, deviceMetrics: DeviceMetrics)?
|
private var validLayout: (width: CGFloat, deviceMetrics: DeviceMetrics)?
|
||||||
|
|
||||||
init(context: AccountContext, controller: PeerInfoScreenImpl, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, isMediaOnly: Bool, isSettings: Bool, forumTopicThreadId: Int64?, chatLocation: ChatLocation) {
|
init(context: AccountContext, controller: PeerInfoScreenImpl, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, isMediaOnly: Bool, isSettings: Bool, forumTopicThreadId: Int64?, chatLocation: ChatLocation) {
|
||||||
@ -451,6 +454,24 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
|
|
||||||
private var currentPanelStatusData: PeerInfoStatusData?
|
private var currentPanelStatusData: PeerInfoStatusData?
|
||||||
func update(width: CGFloat, containerHeight: CGFloat, containerInset: CGFloat, statusBarHeight: CGFloat, navigationHeight: CGFloat, isModalOverlay: Bool, isMediaOnly: Bool, contentOffset: CGFloat, paneContainerY: CGFloat, presentationData: PresentationData, peer: Peer?, cachedData: CachedPeerData?, threadData: MessageHistoryThreadData?, peerNotificationSettings: TelegramPeerNotificationSettings?, threadNotificationSettings: TelegramPeerNotificationSettings?, globalNotificationSettings: EngineGlobalNotificationSettings?, statusData: PeerInfoStatusData?, panelStatusData: (PeerInfoStatusData?, PeerInfoStatusData?, CGFloat?), isSecretChat: Bool, isContact: Bool, isSettings: Bool, state: PeerInfoState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, transition: ContainedViewLayoutTransition, additive: Bool, animateHeader: Bool) -> CGFloat {
|
func update(width: CGFloat, containerHeight: CGFloat, containerInset: CGFloat, statusBarHeight: CGFloat, navigationHeight: CGFloat, isModalOverlay: Bool, isMediaOnly: Bool, contentOffset: CGFloat, paneContainerY: CGFloat, presentationData: PresentationData, peer: Peer?, cachedData: CachedPeerData?, threadData: MessageHistoryThreadData?, peerNotificationSettings: TelegramPeerNotificationSettings?, threadNotificationSettings: TelegramPeerNotificationSettings?, globalNotificationSettings: EngineGlobalNotificationSettings?, statusData: PeerInfoStatusData?, panelStatusData: (PeerInfoStatusData?, PeerInfoStatusData?, CGFloat?), isSecretChat: Bool, isContact: Bool, isSettings: Bool, state: PeerInfoState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, transition: ContainedViewLayoutTransition, additive: Bool, animateHeader: Bool) -> CGFloat {
|
||||||
|
if self.appliedCustomNavigationContentNode !== self.customNavigationContentNode {
|
||||||
|
if let previous = self.appliedCustomNavigationContentNode {
|
||||||
|
transition.updateAlpha(node: previous, alpha: 0.0, completion: { [weak previous] _ in
|
||||||
|
previous?.removeFromSupernode()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
self.appliedCustomNavigationContentNode = self.customNavigationContentNode
|
||||||
|
if let customNavigationContentNode = self.customNavigationContentNode {
|
||||||
|
self.addSubnode(customNavigationContentNode)
|
||||||
|
customNavigationContentNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: width, height: navigationHeight))
|
||||||
|
customNavigationContentNode.alpha = 0.0
|
||||||
|
transition.updateAlpha(node: customNavigationContentNode, alpha: 1.0)
|
||||||
|
}
|
||||||
|
} else if let customNavigationContentNode = self.customNavigationContentNode {
|
||||||
|
transition.updateFrame(node: customNavigationContentNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: width, height: navigationHeight)))
|
||||||
|
}
|
||||||
|
|
||||||
var threadData = threadData
|
var threadData = threadData
|
||||||
if case let .replyThread(replyThreadMessage) = self.chatLocation, replyThreadMessage.peerId == self.context.account.peerId {
|
if case let .replyThread(replyThreadMessage) = self.chatLocation, replyThreadMessage.peerId == self.context.account.peerId {
|
||||||
threadData = nil
|
threadData = nil
|
||||||
@ -516,7 +537,9 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
isForum = true
|
isForum = true
|
||||||
}
|
}
|
||||||
|
|
||||||
self.regularContentNode.alpha = state.isEditing ? 0.0 : 1.0
|
transition.updateAlpha(node: self.regularContentNode, alpha: (state.isEditing || self.customNavigationContentNode != nil) ? 0.0 : 1.0)
|
||||||
|
transition.updateAlpha(node: self.navigationButtonContainer, alpha: self.customNavigationContentNode != nil ? 0.0 : 1.0)
|
||||||
|
|
||||||
self.editingContentNode.alpha = state.isEditing ? 1.0 : 0.0
|
self.editingContentNode.alpha = state.isEditing ? 1.0 : 0.0
|
||||||
|
|
||||||
let editingContentHeight = self.editingContentNode.update(width: width, safeInset: containerInset, statusBarHeight: statusBarHeight, navigationHeight: navigationHeight, isModalOverlay: isModalOverlay, peer: state.isEditing ? peer : nil, threadData: threadData, chatLocation: self.chatLocation, cachedData: cachedData, isContact: isContact, isSettings: isSettings, presentationData: presentationData, transition: transition)
|
let editingContentHeight = self.editingContentNode.update(width: width, safeInset: containerInset, statusBarHeight: statusBarHeight, navigationHeight: navigationHeight, isModalOverlay: isModalOverlay, peer: state.isEditing ? peer : nil, threadData: threadData, chatLocation: self.chatLocation, cachedData: cachedData, isContact: isContact, isSettings: isSettings, presentationData: presentationData, transition: transition)
|
||||||
@ -1362,6 +1385,9 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
if self.navigationTransition == nil && !self.isSettings && effectiveSeparatorAlpha == 1.0 && secondarySeparatorAlpha < 1.0 {
|
if self.navigationTransition == nil && !self.isSettings && effectiveSeparatorAlpha == 1.0 && secondarySeparatorAlpha < 1.0 {
|
||||||
effectiveSeparatorAlpha = secondarySeparatorAlpha
|
effectiveSeparatorAlpha = secondarySeparatorAlpha
|
||||||
}
|
}
|
||||||
|
if self.customNavigationContentNode != nil {
|
||||||
|
effectiveSeparatorAlpha = 0.0
|
||||||
|
}
|
||||||
transition.updateAlpha(node: self.separatorNode, alpha: effectiveSeparatorAlpha)
|
transition.updateAlpha(node: self.separatorNode, alpha: effectiveSeparatorAlpha)
|
||||||
|
|
||||||
self.titleNode.update(stateFractions: [
|
self.titleNode.update(stateFractions: [
|
||||||
@ -1984,6 +2010,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
transition.updateFrame(node: self.regularContentNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: resolvedHeight)))
|
transition.updateFrame(node: self.regularContentNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: resolvedHeight)))
|
||||||
|
|
||||||
transition.updateFrameAdditive(node: self.buttonsContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: apparentBackgroundHeight - backgroundHeight), size: CGSize(width: width, height: 1000.0)))
|
transition.updateFrameAdditive(node: self.buttonsContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: apparentBackgroundHeight - backgroundHeight), size: CGSize(width: width, height: 1000.0)))
|
||||||
|
|
||||||
navigationTransition.updateAlpha(node: self.buttonsContainerNode, alpha: backgroundBannerAlpha)
|
navigationTransition.updateAlpha(node: self.buttonsContainerNode, alpha: backgroundBannerAlpha)
|
||||||
@ -2078,6 +2105,13 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let customNavigationContentNode = self.customNavigationContentNode {
|
||||||
|
if let result = customNavigationContentNode.view.hitTest(self.view.convert(point, to: customNavigationContentNode.view), with: event) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
return self.view
|
||||||
|
}
|
||||||
|
|
||||||
let setByFrame = self.avatarListNode.listContainerNode.setByYouNode.view.convert(self.avatarListNode.listContainerNode.setByYouNode.bounds, to: self.view).insetBy(dx: -44.0, dy: 0.0)
|
let setByFrame = self.avatarListNode.listContainerNode.setByYouNode.view.convert(self.avatarListNode.listContainerNode.setByYouNode.bounds, to: self.view).insetBy(dx: -44.0, dy: 0.0)
|
||||||
if self.avatarListNode.listContainerNode.setByYouNode.alpha > 0.0, setByFrame.contains(point) {
|
if self.avatarListNode.listContainerNode.setByYouNode.alpha > 0.0, setByFrame.contains(point) {
|
||||||
return self.avatarListNode.listContainerNode.setByYouNode.view
|
return self.avatarListNode.listContainerNode.setByYouNode.view
|
||||||
|
|||||||
@ -366,7 +366,8 @@ private final class PeerInfoPendingPane {
|
|||||||
parentController: ViewController?,
|
parentController: ViewController?,
|
||||||
openMediaCalendar: @escaping () -> Void,
|
openMediaCalendar: @escaping () -> Void,
|
||||||
paneDidScroll: @escaping () -> Void,
|
paneDidScroll: @escaping () -> Void,
|
||||||
ensureRectVisible: @escaping (UIView, CGRect) -> Void
|
ensureRectVisible: @escaping (UIView, CGRect) -> Void,
|
||||||
|
externalDataUpdated: @escaping (ContainedViewLayoutTransition) -> Void
|
||||||
) {
|
) {
|
||||||
let captureProtected = data.peer?.isCopyProtectionEnabled ?? false
|
let captureProtected = data.peer?.isCopyProtectionEnabled ?? false
|
||||||
let paneNode: PeerInfoPaneNode
|
let paneNode: PeerInfoPaneNode
|
||||||
@ -425,6 +426,7 @@ private final class PeerInfoPendingPane {
|
|||||||
case .savedMessages:
|
case .savedMessages:
|
||||||
paneNode = PeerInfoChatPaneNode(context: context, peerId: peerId, navigationController: chatControllerInteraction.navigationController)
|
paneNode = PeerInfoChatPaneNode(context: context, peerId: peerId, navigationController: chatControllerInteraction.navigationController)
|
||||||
}
|
}
|
||||||
|
paneNode.externalDataUpdated = externalDataUpdated
|
||||||
paneNode.parentController = parentController
|
paneNode.parentController = parentController
|
||||||
self.pane = PeerInfoPaneWrapper(key: key, node: paneNode)
|
self.pane = PeerInfoPaneWrapper(key: key, node: paneNode)
|
||||||
self.disposable = (paneNode.isReady
|
self.disposable = (paneNode.isReady
|
||||||
@ -458,7 +460,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
let isReady = Promise<Bool>()
|
let isReady = Promise<Bool>()
|
||||||
var didSetIsReady = false
|
var didSetIsReady = false
|
||||||
|
|
||||||
private var currentParams: (size: CGSize, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, expansionFraction: CGFloat, presentationData: PresentationData, data: PeerInfoScreenData?)?
|
private var currentParams: (size: CGSize, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, expansionFraction: CGFloat, presentationData: PresentationData, data: PeerInfoScreenData?, areTabsHidden: Bool)?
|
||||||
|
|
||||||
private(set) var currentPaneKey: PeerInfoPaneKey?
|
private(set) var currentPaneKey: PeerInfoPaneKey?
|
||||||
var pendingSwitchToPaneKey: PeerInfoPaneKey?
|
var pendingSwitchToPaneKey: PeerInfoPaneKey?
|
||||||
@ -495,6 +497,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
|
|
||||||
var currentPaneUpdated: ((Bool) -> Void)?
|
var currentPaneUpdated: ((Bool) -> Void)?
|
||||||
var requestExpandTabs: (() -> Bool)?
|
var requestExpandTabs: (() -> Bool)?
|
||||||
|
var requestUpdate: ((ContainedViewLayoutTransition) -> Void)?
|
||||||
|
|
||||||
var openMediaCalendar: (() -> Void)?
|
var openMediaCalendar: (() -> Void)?
|
||||||
var paneDidScroll: (() -> Void)?
|
var paneDidScroll: (() -> Void)?
|
||||||
@ -550,8 +553,8 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
if strongSelf.currentPanes[key] != nil {
|
if strongSelf.currentPanes[key] != nil {
|
||||||
strongSelf.currentPaneKey = key
|
strongSelf.currentPaneKey = key
|
||||||
|
|
||||||
if let (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data) = strongSelf.currentParams {
|
if let (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data, areTabsHidden) = strongSelf.currentParams {
|
||||||
strongSelf.update(size: size, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, expansionFraction: expansionFraction, presentationData: presentationData, data: data, transition: .animated(duration: 0.4, curve: .spring))
|
strongSelf.update(size: size, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, expansionFraction: expansionFraction, presentationData: presentationData, data: data, areTabsHidden: areTabsHidden, transition: .animated(duration: 0.4, curve: .spring))
|
||||||
|
|
||||||
strongSelf.currentPaneUpdated?(true)
|
strongSelf.currentPaneUpdated?(true)
|
||||||
|
|
||||||
@ -563,8 +566,8 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
strongSelf.pendingSwitchToPaneKey = key
|
strongSelf.pendingSwitchToPaneKey = key
|
||||||
strongSelf.expandOnSwitch = true
|
strongSelf.expandOnSwitch = true
|
||||||
|
|
||||||
if let (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data) = strongSelf.currentParams {
|
if let (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data, areTabsHidden) = strongSelf.currentParams {
|
||||||
strongSelf.update(size: size, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, expansionFraction: expansionFraction, presentationData: presentationData, data: data, transition: .animated(duration: 0.4, curve: .spring))
|
strongSelf.update(size: size, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, expansionFraction: expansionFraction, presentationData: presentationData, data: data, areTabsHidden: areTabsHidden, transition: .animated(duration: 0.4, curve: .spring))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -586,6 +589,9 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
}
|
}
|
||||||
return [.leftCenter, .rightCenter]
|
return [.leftCenter, .rightCenter]
|
||||||
}
|
}
|
||||||
|
if strongSelf.currentPane?.node.navigationContentNode != nil {
|
||||||
|
return []
|
||||||
|
}
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
return .left
|
return .left
|
||||||
}
|
}
|
||||||
@ -629,7 +635,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
|
|
||||||
cancelContextGestures(view: self.view)
|
cancelContextGestures(view: self.view)
|
||||||
case .changed:
|
case .changed:
|
||||||
if let (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data) = self.currentParams, let availablePanes = data?.availablePanes, availablePanes.count > 1, let currentPaneKey = self.currentPaneKey, let currentIndex = availablePanes.firstIndex(of: currentPaneKey) {
|
if let (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data, areTabsHidden) = self.currentParams, let availablePanes = data?.availablePanes, availablePanes.count > 1, let currentPaneKey = self.currentPaneKey, let currentIndex = availablePanes.firstIndex(of: currentPaneKey) {
|
||||||
let translation = recognizer.translation(in: self.view)
|
let translation = recognizer.translation(in: self.view)
|
||||||
var transitionFraction = translation.x / size.width
|
var transitionFraction = translation.x / size.width
|
||||||
if currentIndex <= 0 {
|
if currentIndex <= 0 {
|
||||||
@ -644,11 +650,11 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
// print(transitionFraction)
|
// print(transitionFraction)
|
||||||
self.paneTransitionPromise.set(transitionFraction)
|
self.paneTransitionPromise.set(transitionFraction)
|
||||||
|
|
||||||
self.update(size: size, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, expansionFraction: expansionFraction, presentationData: presentationData, data: data, transition: .immediate)
|
self.update(size: size, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, expansionFraction: expansionFraction, presentationData: presentationData, data: data, areTabsHidden: areTabsHidden, transition: .immediate)
|
||||||
self.currentPaneUpdated?(false)
|
self.currentPaneUpdated?(false)
|
||||||
}
|
}
|
||||||
case .cancelled, .ended:
|
case .cancelled, .ended:
|
||||||
if let (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data) = self.currentParams, let availablePanes = data?.availablePanes, availablePanes.count > 1, let currentPaneKey = self.currentPaneKey, let currentIndex = availablePanes.firstIndex(of: currentPaneKey) {
|
if let (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data, areTabsHidden) = self.currentParams, let availablePanes = data?.availablePanes, availablePanes.count > 1, let currentPaneKey = self.currentPaneKey, let currentIndex = availablePanes.firstIndex(of: currentPaneKey) {
|
||||||
let translation = recognizer.translation(in: self.view)
|
let translation = recognizer.translation(in: self.view)
|
||||||
let velocity = recognizer.velocity(in: self.view)
|
let velocity = recognizer.velocity(in: self.view)
|
||||||
var directionIsToRight: Bool?
|
var directionIsToRight: Bool?
|
||||||
@ -672,7 +678,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.transitionFraction = 0.0
|
self.transitionFraction = 0.0
|
||||||
self.update(size: size, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, expansionFraction: expansionFraction, presentationData: presentationData, data: data, transition: .animated(duration: 0.35, curve: .spring))
|
self.update(size: size, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, expansionFraction: expansionFraction, presentationData: presentationData, data: data, areTabsHidden: areTabsHidden, transition: .animated(duration: 0.35, curve: .spring))
|
||||||
self.currentPaneUpdated?(false)
|
self.currentPaneUpdated?(false)
|
||||||
|
|
||||||
self.currentPaneStatusPromise.set(self.currentPane?.node.status ?? .single(nil))
|
self.currentPaneStatusPromise.set(self.currentPane?.node.status ?? .single(nil))
|
||||||
@ -711,7 +717,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func update(size: CGSize, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, expansionFraction: CGFloat, presentationData: PresentationData, data: PeerInfoScreenData?, transition: ContainedViewLayoutTransition) {
|
func update(size: CGSize, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, expansionFraction: CGFloat, presentationData: PresentationData, data: PeerInfoScreenData?, areTabsHidden: Bool, transition: ContainedViewLayoutTransition) {
|
||||||
let previousAvailablePanes = self.currentAvailablePanes
|
let previousAvailablePanes = self.currentAvailablePanes
|
||||||
let availablePanes = data?.availablePanes ?? []
|
let availablePanes = data?.availablePanes ?? []
|
||||||
self.currentAvailablePanes = data?.availablePanes
|
self.currentAvailablePanes = data?.availablePanes
|
||||||
@ -755,7 +761,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
currentIndex = nil
|
currentIndex = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
self.currentParams = (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data)
|
self.currentParams = (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data, areTabsHidden)
|
||||||
|
|
||||||
transition.updateAlpha(node: self.coveringBackgroundNode, alpha: expansionFraction)
|
transition.updateAlpha(node: self.coveringBackgroundNode, alpha: expansionFraction)
|
||||||
|
|
||||||
@ -770,6 +776,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
let isScrollingLockedAtTop = expansionFraction < 1.0 - CGFloat.ulpOfOne
|
let isScrollingLockedAtTop = expansionFraction < 1.0 - CGFloat.ulpOfOne
|
||||||
|
|
||||||
let tabsHeight: CGFloat = 48.0
|
let tabsHeight: CGFloat = 48.0
|
||||||
|
let effectiveTabsHeight: CGFloat = areTabsHidden ? 0.0 : tabsHeight
|
||||||
|
|
||||||
let paneFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height))
|
let paneFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height))
|
||||||
|
|
||||||
@ -825,12 +832,12 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if let (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data) = strongSelf.currentParams {
|
if let (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data, areTabsHidden) = strongSelf.currentParams {
|
||||||
var transition: ContainedViewLayoutTransition = .immediate
|
var transition: ContainedViewLayoutTransition = .immediate
|
||||||
if strongSelf.pendingSwitchToPaneKey == key && strongSelf.currentPaneKey != nil {
|
if strongSelf.pendingSwitchToPaneKey == key && strongSelf.currentPaneKey != nil {
|
||||||
transition = .animated(duration: 0.4, curve: .spring)
|
transition = .animated(duration: 0.4, curve: .spring)
|
||||||
}
|
}
|
||||||
strongSelf.update(size: size, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, expansionFraction: expansionFraction, presentationData: presentationData, data: data, transition: transition)
|
strongSelf.update(size: size, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, expansionFraction: expansionFraction, presentationData: presentationData, data: data, areTabsHidden: areTabsHidden, transition: transition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if leftScope {
|
if leftScope {
|
||||||
@ -849,18 +856,24 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.ensurePaneRectVisible?(self.view, sourceView.convert(rect, to: self.view))
|
self.ensurePaneRectVisible?(self.view, sourceView.convert(rect, to: self.view))
|
||||||
|
},
|
||||||
|
externalDataUpdated: { [weak self] transition in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.requestUpdate?(transition)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
self.pendingPanes[key] = pane
|
self.pendingPanes[key] = pane
|
||||||
pane.pane.node.frame = paneFrame
|
pane.pane.node.frame = paneFrame
|
||||||
pane.pane.update(size: paneFrame.size, topInset: tabsHeight, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expansionFraction, presentationData: presentationData, synchronous: true, transition: .immediate)
|
pane.pane.update(size: paneFrame.size, topInset: effectiveTabsHeight, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expansionFraction, presentationData: presentationData, synchronous: true, transition: .immediate)
|
||||||
let paneNode = pane.pane.node
|
let paneNode = pane.pane.node
|
||||||
pane.pane.node.tabBarOffsetUpdated = { [weak self, weak paneNode] transition in
|
pane.pane.node.tabBarOffsetUpdated = { [weak self, weak paneNode] transition in
|
||||||
guard let strongSelf = self, let paneNode = paneNode, let currentPane = strongSelf.currentPane, paneNode === currentPane.node else {
|
guard let strongSelf = self, let paneNode = paneNode, let currentPane = strongSelf.currentPane, paneNode === currentPane.node else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if let (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data) = strongSelf.currentParams {
|
if let (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data, areTabsHidden) = strongSelf.currentParams {
|
||||||
strongSelf.update(size: size, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, expansionFraction: expansionFraction, presentationData: presentationData, data: data, transition: transition)
|
strongSelf.update(size: size, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, expansionFraction: expansionFraction, presentationData: presentationData, data: data, areTabsHidden: areTabsHidden, transition: transition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leftScope = true
|
leftScope = true
|
||||||
@ -869,7 +882,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
|
|
||||||
for (key, pane) in self.pendingPanes {
|
for (key, pane) in self.pendingPanes {
|
||||||
pane.pane.node.frame = paneFrame
|
pane.pane.node.frame = paneFrame
|
||||||
pane.pane.update(size: paneFrame.size, topInset: tabsHeight, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expansionFraction, presentationData: presentationData, synchronous: self.currentPaneKey == nil, transition: .immediate)
|
pane.pane.update(size: paneFrame.size, topInset: effectiveTabsHeight, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expansionFraction, presentationData: presentationData, synchronous: self.currentPaneKey == nil, transition: .immediate)
|
||||||
|
|
||||||
if pane.isReady {
|
if pane.isReady {
|
||||||
self.pendingPanes.removeValue(forKey: key)
|
self.pendingPanes.removeValue(forKey: key)
|
||||||
@ -930,7 +943,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
pane.isAnimatingOut = false
|
pane.isAnimatingOut = false
|
||||||
if let (_, _, _, _, _, _, _, data) = strongSelf.currentParams {
|
if let (_, _, _, _, _, _, _, data, _) = strongSelf.currentParams {
|
||||||
if let availablePanes = data?.availablePanes, let currentPaneKey = strongSelf.currentPaneKey, let currentIndex = availablePanes.firstIndex(of: currentPaneKey), let paneIndex = availablePanes.firstIndex(of: key), abs(paneIndex - currentIndex) <= 1 {
|
if let availablePanes = data?.availablePanes, let currentPaneKey = strongSelf.currentPaneKey, let currentIndex = availablePanes.firstIndex(of: currentPaneKey), let paneIndex = availablePanes.firstIndex(of: key), abs(paneIndex - currentIndex) <= 1 {
|
||||||
} else {
|
} else {
|
||||||
if let pane = strongSelf.currentPanes.removeValue(forKey: key) {
|
if let pane = strongSelf.currentPanes.removeValue(forKey: key) {
|
||||||
@ -961,7 +974,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
paneCompletion()
|
paneCompletion()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pane.update(size: paneFrame.size, topInset: tabsHeight, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expansionFraction, presentationData: presentationData, synchronous: paneWasAdded, transition: paneTransition)
|
pane.update(size: paneFrame.size, topInset: effectiveTabsHeight, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expansionFraction, presentationData: presentationData, synchronous: paneWasAdded, transition: paneTransition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -973,7 +986,14 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
if isScrollingLockedAtTop || self.isMediaOnly {
|
if isScrollingLockedAtTop || self.isMediaOnly {
|
||||||
tabsOffset = 0.0
|
tabsOffset = 0.0
|
||||||
}
|
}
|
||||||
var tabsAlpha = 1.0 - tabsOffset / tabsHeight
|
|
||||||
|
var tabsAlpha: CGFloat
|
||||||
|
if areTabsHidden {
|
||||||
|
tabsAlpha = 0.0
|
||||||
|
tabsOffset = tabsHeight
|
||||||
|
} else {
|
||||||
|
tabsAlpha = 1.0 - tabsOffset / tabsHeight
|
||||||
|
}
|
||||||
tabsAlpha *= tabsAlpha
|
tabsAlpha *= tabsAlpha
|
||||||
transition.updateFrame(node: self.tabsContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -tabsOffset), size: CGSize(width: size.width, height: tabsHeight)))
|
transition.updateFrame(node: self.tabsContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -tabsOffset), size: CGSize(width: size.width, height: tabsHeight)))
|
||||||
transition.updateAlpha(node: self.tabsContainerNode, alpha: tabsAlpha)
|
transition.updateAlpha(node: self.tabsContainerNode, alpha: tabsAlpha)
|
||||||
@ -1019,7 +1039,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
|||||||
for (_, pane) in self.pendingPanes {
|
for (_, pane) in self.pendingPanes {
|
||||||
let paneTransition: ContainedViewLayoutTransition = .immediate
|
let paneTransition: ContainedViewLayoutTransition = .immediate
|
||||||
paneTransition.updateFrame(node: pane.pane.node, frame: paneFrame)
|
paneTransition.updateFrame(node: pane.pane.node, frame: paneFrame)
|
||||||
pane.pane.update(size: paneFrame.size, topInset: tabsHeight, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expansionFraction, presentationData: presentationData, synchronous: true, transition: paneTransition)
|
pane.pane.update(size: paneFrame.size, topInset: effectiveTabsHeight, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expansionFraction, presentationData: presentationData, synchronous: true, transition: paneTransition)
|
||||||
}
|
}
|
||||||
|
|
||||||
var removeKeys: [PeerInfoPaneKey] = []
|
var removeKeys: [PeerInfoPaneKey] = []
|
||||||
|
|||||||
@ -102,6 +102,7 @@ import PeerInfoPaneNode
|
|||||||
import MediaPickerUI
|
import MediaPickerUI
|
||||||
import AttachmentUI
|
import AttachmentUI
|
||||||
import BoostLevelIconComponent
|
import BoostLevelIconComponent
|
||||||
|
import PeerInfoChatPaneNode
|
||||||
|
|
||||||
public enum PeerInfoAvatarEditingMode {
|
public enum PeerInfoAvatarEditingMode {
|
||||||
case generic
|
case generic
|
||||||
@ -3145,6 +3146,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.paneContainerNode.requestUpdate = { [weak self] transition in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let (layout, navigationHeight) = self.validLayout {
|
||||||
|
self.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: transition, additive: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.paneContainerNode.ensurePaneRectVisible = { [weak self] sourceView, rect in
|
self.paneContainerNode.ensurePaneRectVisible = { [weak self] sourceView, rect in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
@ -3748,8 +3758,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
}
|
}
|
||||||
strongSelf.chatInterfaceInteraction.selectionState = strongSelf.state.selectedMessageIds.flatMap { ChatInterfaceSelectionState(selectedIds: $0) }
|
strongSelf.chatInterfaceInteraction.selectionState = strongSelf.state.selectedMessageIds.flatMap { ChatInterfaceSelectionState(selectedIds: $0) }
|
||||||
strongSelf.paneContainerNode.updateSelectedMessageIds(strongSelf.state.selectedMessageIds, animated: true)
|
strongSelf.paneContainerNode.updateSelectedMessageIds(strongSelf.state.selectedMessageIds, animated: true)
|
||||||
case .search:
|
case .search, .searchWithTags:
|
||||||
strongSelf.headerNode.navigationButtonContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue)
|
|
||||||
strongSelf.activateSearch()
|
strongSelf.activateSearch()
|
||||||
case .more:
|
case .more:
|
||||||
if let source = source {
|
if let source = source {
|
||||||
@ -9269,6 +9278,13 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let currentPaneKey = self.paneContainerNode.currentPaneKey, case .savedMessages = currentPaneKey, let paneNode = self.paneContainerNode.currentPane?.node as? PeerInfoChatPaneNode {
|
||||||
|
paneNode.activateSearch()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.headerNode.navigationButtonContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue)
|
||||||
|
|
||||||
if self.isSettings {
|
if self.isSettings {
|
||||||
(self.controller?.parent as? TabBarController)?.updateIsTabBarHidden(true, transition: .animated(duration: 0.3, curve: .linear))
|
(self.controller?.parent as? TabBarController)?.updateIsTabBarHidden(true, transition: .animated(duration: 0.3, curve: .linear))
|
||||||
|
|
||||||
@ -9803,9 +9819,31 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func updateNavigationHeight(width: CGFloat, defaultHeight: CGFloat, insets: UIEdgeInsets, transition: ContainedViewLayoutTransition) -> CGFloat {
|
||||||
|
var navigationHeight = defaultHeight
|
||||||
|
if let customNavigationContentNode = self.headerNode.customNavigationContentNode {
|
||||||
|
var mappedTransition = transition
|
||||||
|
if customNavigationContentNode.supernode == nil {
|
||||||
|
mappedTransition = .immediate
|
||||||
|
}
|
||||||
|
let contentHeight = customNavigationContentNode.update(width: width, defaultHeight: defaultHeight, insets: insets, transition: mappedTransition)
|
||||||
|
navigationHeight = contentHeight
|
||||||
|
}
|
||||||
|
return navigationHeight
|
||||||
|
}
|
||||||
|
|
||||||
func containerLayoutUpdated(layout: ContainerViewLayout, navigationHeight: CGFloat, transition: ContainedViewLayoutTransition, additive: Bool = false) {
|
func containerLayoutUpdated(layout: ContainerViewLayout, navigationHeight: CGFloat, transition: ContainedViewLayoutTransition, additive: Bool = false) {
|
||||||
self.validLayout = (layout, navigationHeight)
|
self.validLayout = (layout, navigationHeight)
|
||||||
|
|
||||||
|
self.headerNode.customNavigationContentNode = self.paneContainerNode.currentPane?.node.navigationContentNode
|
||||||
|
|
||||||
|
let isScrollEnabled = !self.isMediaOnly && self.headerNode.customNavigationContentNode == nil
|
||||||
|
if self.scrollNode.view.isScrollEnabled != isScrollEnabled {
|
||||||
|
self.scrollNode.view.isScrollEnabled = isScrollEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
let navigationHeight = self.updateNavigationHeight(width: layout.size.width, defaultHeight: navigationHeight, insets: UIEdgeInsets(top: 0.0, left: layout.safeInsets.left, bottom: 0.0, right: layout.safeInsets.right), transition: transition)
|
||||||
|
|
||||||
if self.headerNode.isAvatarExpanded && layout.size.width > layout.size.height {
|
if self.headerNode.isAvatarExpanded && layout.size.width > layout.size.height {
|
||||||
self.headerNode.updateIsAvatarExpanded(false, transition: transition)
|
self.headerNode.updateIsAvatarExpanded(false, transition: transition)
|
||||||
self.updateNavigationExpansionPresentation(isExpanded: false, animated: true)
|
self.updateNavigationExpansionPresentation(isExpanded: false, animated: true)
|
||||||
@ -10188,6 +10226,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let (layout, navigationHeight) = self.validLayout {
|
if let (layout, navigationHeight) = self.validLayout {
|
||||||
|
let navigationHeight = self.updateNavigationHeight(width: layout.size.width, defaultHeight: navigationHeight, insets: UIEdgeInsets(top: 0.0, left: layout.safeInsets.left, bottom: 0.0, right: layout.safeInsets.right), transition: transition)
|
||||||
|
|
||||||
if !additive {
|
if !additive {
|
||||||
let sectionInset: CGFloat
|
let sectionInset: CGFloat
|
||||||
if layout.size.width >= 375.0 {
|
if layout.size.width >= 375.0 {
|
||||||
@ -10222,7 +10262,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
let navigationBarHeight: CGFloat = !self.isSettings && layout.isModalOverlay ? 56.0 : 44.0
|
let navigationBarHeight: CGFloat = !self.isSettings && layout.isModalOverlay ? 56.0 : 44.0
|
||||||
self.paneContainerNode.update(size: self.paneContainerNode.bounds.size, sideInset: layout.safeInsets.left, bottomInset: bottomInset, deviceMetrics: layout.deviceMetrics, visibleHeight: visibleHeight, expansionFraction: effectiveAreaExpansionFraction, presentationData: self.presentationData, data: self.data, transition: transition)
|
self.paneContainerNode.update(size: self.paneContainerNode.bounds.size, sideInset: layout.safeInsets.left, bottomInset: bottomInset, deviceMetrics: layout.deviceMetrics, visibleHeight: visibleHeight, expansionFraction: effectiveAreaExpansionFraction, presentationData: self.presentationData, data: self.data, areTabsHidden: self.headerNode.customNavigationContentNode != nil, transition: transition)
|
||||||
|
|
||||||
transition.updateFrame(node: self.headerNode.navigationButtonContainer, frame: CGRect(origin: CGPoint(x: layout.safeInsets.left, y: layout.statusBarHeight ?? 0.0), size: CGSize(width: layout.size.width - layout.safeInsets.left * 2.0, height: navigationBarHeight)))
|
transition.updateFrame(node: self.headerNode.navigationButtonContainer, frame: CGRect(origin: CGPoint(x: layout.safeInsets.left, y: layout.statusBarHeight ?? 0.0), size: CGSize(width: layout.size.width - layout.safeInsets.left * 2.0, height: navigationBarHeight)))
|
||||||
|
|
||||||
@ -10249,6 +10289,12 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
switch currentPaneKey {
|
switch currentPaneKey {
|
||||||
case .files, .music, .links, .members, .savedMessagesChats:
|
case .files, .music, .links, .members, .savedMessagesChats:
|
||||||
rightNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .search, isForExpandedView: true))
|
rightNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .search, isForExpandedView: true))
|
||||||
|
case .savedMessages:
|
||||||
|
if let data = self.data, data.hasSavedMessageTags {
|
||||||
|
rightNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .searchWithTags, isForExpandedView: true))
|
||||||
|
} else {
|
||||||
|
rightNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .search, isForExpandedView: true))
|
||||||
|
}
|
||||||
case .media:
|
case .media:
|
||||||
rightNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .more, isForExpandedView: true))
|
rightNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .more, isForExpandedView: true))
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -524,4 +524,14 @@ func updateChatPresentationInterfaceStateImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
selfController.updateDownButtonVisibility()
|
selfController.updateDownButtonVisibility()
|
||||||
|
|
||||||
|
if case .standard(.embedded) = selfController.presentationInterfaceState.mode, let controllerInteraction = selfController.controllerInteraction, let interfaceInteraction = selfController.interfaceInteraction {
|
||||||
|
if let titleAccessoryPanelNode = titlePanelForChatPresentationInterfaceState(selfController.presentationInterfaceState, context: selfController.context, currentPanel: selfController.customNavigationPanelNode as? ChatTitleAccessoryPanelNode, controllerInteraction: controllerInteraction, interfaceInteraction: interfaceInteraction) {
|
||||||
|
selfController.customNavigationPanelNode = titleAccessoryPanelNode as? ChatControllerCustomNavigationPanelNode
|
||||||
|
} else {
|
||||||
|
selfController.customNavigationPanelNode = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selfController.stateUpdated?(transition)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -506,6 +506,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
weak var currentWebAppController: ViewController?
|
weak var currentWebAppController: ViewController?
|
||||||
|
|
||||||
weak var currentImportMessageTooltip: UndoOverlayController?
|
weak var currentImportMessageTooltip: UndoOverlayController?
|
||||||
|
|
||||||
|
public var customNavigationBarContentNode: NavigationBarContentNode?
|
||||||
|
public var customNavigationPanelNode: ChatControllerCustomNavigationPanelNode?
|
||||||
|
public var stateUpdated: ((ContainedViewLayoutTransition) -> Void)?
|
||||||
|
|
||||||
public override var customData: Any? {
|
public override var customData: Any? {
|
||||||
return self.chatLocation
|
return self.chatLocation
|
||||||
|
|||||||
@ -1656,13 +1656,15 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
transition.updateFrame(node: backgroundEffectNode, frame: CGRect(origin: CGPoint(), size: layout.size))
|
transition.updateFrame(node: backgroundEffectNode, frame: CGRect(origin: CGPoint(), size: layout.size))
|
||||||
}
|
}
|
||||||
|
|
||||||
transition.updateFrame(node: self.backgroundNode, frame: contentBounds)
|
let wallpaperBounds = CGRect(x: 0.0, y: 0.0, width: layout.size.width - wrappingInsets.left - wrappingInsets.right, height: layout.size.height)
|
||||||
|
|
||||||
|
transition.updateFrame(node: self.backgroundNode, frame: wallpaperBounds)
|
||||||
|
|
||||||
var displayMode: WallpaperDisplayMode = .aspectFill
|
var displayMode: WallpaperDisplayMode = .aspectFill
|
||||||
if case .regular = layout.metrics.widthClass, layout.size.height == layout.deviceMetrics.screenSize.width {
|
if case .regular = layout.metrics.widthClass, layout.size.height == layout.deviceMetrics.screenSize.width {
|
||||||
displayMode = .aspectFit
|
displayMode = .aspectFit
|
||||||
}
|
}
|
||||||
self.backgroundNode.updateLayout(size: contentBounds.size, displayMode: displayMode, transition: transition)
|
self.backgroundNode.updateLayout(size: wallpaperBounds.size, displayMode: displayMode, transition: transition)
|
||||||
|
|
||||||
transition.updateBounds(node: self.historyNodeContainer, bounds: contentBounds)
|
transition.updateBounds(node: self.historyNodeContainer, bounds: contentBounds)
|
||||||
transition.updatePosition(node: self.historyNodeContainer, position: contentBounds.center)
|
transition.updatePosition(node: self.historyNodeContainer, position: contentBounds.center)
|
||||||
@ -1796,6 +1798,11 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
if self.dismissedAsOverlay {
|
if self.dismissedAsOverlay {
|
||||||
inputBackgroundFrame.origin.y = layout.size.height
|
inputBackgroundFrame.origin.y = layout.size.height
|
||||||
}
|
}
|
||||||
|
if case .standard(.embedded) = self.chatPresentationInterfaceState.mode {
|
||||||
|
if self.inputPanelNode == nil {
|
||||||
|
inputBackgroundFrame.origin.y = layout.size.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let additionalScrollDistance: CGFloat = 0.0
|
let additionalScrollDistance: CGFloat = 0.0
|
||||||
var scrollToTop = false
|
var scrollToTop = false
|
||||||
@ -2033,11 +2040,6 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
inputPanelUpdateTransition = .immediate
|
inputPanelUpdateTransition = .immediate
|
||||||
}
|
}
|
||||||
|
|
||||||
if case .standard(.embedded) = self.chatPresentationInterfaceState.mode {
|
|
||||||
self.inputPanelBackgroundNode.isHidden = true
|
|
||||||
self.inputPanelBackgroundSeparatorNode.isHidden = true
|
|
||||||
self.inputPanelBottomBackgroundSeparatorNode.isHidden = true
|
|
||||||
}
|
|
||||||
self.inputPanelBackgroundNode.update(size: CGSize(width: intrinsicInputPanelBackgroundNodeSize.width, height: intrinsicInputPanelBackgroundNodeSize.height + inputPanelBackgroundExtension), transition: inputPanelUpdateTransition, beginWithCurrentState: true)
|
self.inputPanelBackgroundNode.update(size: CGSize(width: intrinsicInputPanelBackgroundNodeSize.width, height: intrinsicInputPanelBackgroundNodeSize.height + inputPanelBackgroundExtension), transition: inputPanelUpdateTransition, beginWithCurrentState: true)
|
||||||
self.inputPanelBottomBackgroundSeparatorBaseOffset = intrinsicInputPanelBackgroundNodeSize.height
|
self.inputPanelBottomBackgroundSeparatorBaseOffset = intrinsicInputPanelBackgroundNodeSize.height
|
||||||
inputPanelUpdateTransition.updateFrame(node: self.inputPanelBottomBackgroundSeparatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: intrinsicInputPanelBackgroundNodeSize.height + inputPanelBackgroundExtension), size: CGSize(width: intrinsicInputPanelBackgroundNodeSize.width, height: UIScreenPixel)), beginWithCurrentState: true)
|
inputPanelUpdateTransition.updateFrame(node: self.inputPanelBottomBackgroundSeparatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: intrinsicInputPanelBackgroundNodeSize.height + inputPanelBackgroundExtension), size: CGSize(width: intrinsicInputPanelBackgroundNodeSize.width, height: UIScreenPixel)), beginWithCurrentState: true)
|
||||||
@ -2661,13 +2663,18 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
self.searchNavigationNode = ChatSearchNavigationContentNode(context: self.context, theme: self.chatPresentationInterfaceState.theme, strings: self.chatPresentationInterfaceState.strings, chatLocation: self.chatPresentationInterfaceState.chatLocation, interaction: interfaceInteraction, presentationInterfaceState: self.chatPresentationInterfaceState)
|
self.searchNavigationNode = ChatSearchNavigationContentNode(context: self.context, theme: self.chatPresentationInterfaceState.theme, strings: self.chatPresentationInterfaceState.strings, chatLocation: self.chatPresentationInterfaceState.chatLocation, interaction: interfaceInteraction, presentationInterfaceState: self.chatPresentationInterfaceState)
|
||||||
}
|
}
|
||||||
self.navigationBar?.setContentNode(self.searchNavigationNode, animated: transitionIsAnimated)
|
if let navigationBar = self.navigationBar {
|
||||||
|
navigationBar.setContentNode(self.searchNavigationNode, animated: transitionIsAnimated)
|
||||||
|
} else {
|
||||||
|
self.controller?.customNavigationBarContentNode = self.searchNavigationNode
|
||||||
|
}
|
||||||
self.searchNavigationNode?.update(presentationInterfaceState: self.chatPresentationInterfaceState)
|
self.searchNavigationNode?.update(presentationInterfaceState: self.chatPresentationInterfaceState)
|
||||||
if activate {
|
if activate {
|
||||||
self.searchNavigationNode?.activate()
|
self.searchNavigationNode?.activate()
|
||||||
}
|
}
|
||||||
} else if let _ = self.searchNavigationNode {
|
} else if let _ = self.searchNavigationNode {
|
||||||
self.searchNavigationNode = nil
|
self.searchNavigationNode = nil
|
||||||
|
self.controller?.customNavigationBarContentNode = nil
|
||||||
self.navigationBar?.setContentNode(nil, animated: transitionIsAnimated)
|
self.navigationBar?.setContentNode(nil, animated: transitionIsAnimated)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,10 +10,6 @@ import ChatChannelSubscriberInputPanelNode
|
|||||||
import ChatMessageSelectionInputPanelNode
|
import ChatMessageSelectionInputPanelNode
|
||||||
|
|
||||||
func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: ChatInputPanelNode?, currentSecondaryPanel: ChatInputPanelNode?, textInputPanelNode: ChatTextInputPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> (primary: ChatInputPanelNode?, secondary: ChatInputPanelNode?) {
|
func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: ChatInputPanelNode?, currentSecondaryPanel: ChatInputPanelNode?, textInputPanelNode: ChatTextInputPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> (primary: ChatInputPanelNode?, secondary: ChatInputPanelNode?) {
|
||||||
if case .standard(.embedded) = chatPresentationInterfaceState.mode {
|
|
||||||
return (nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let renderedPeer = chatPresentationInterfaceState.renderedPeer, renderedPeer.peer?.restrictionText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) != nil {
|
if let renderedPeer = chatPresentationInterfaceState.renderedPeer, renderedPeer.peer?.restrictionText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) != nil {
|
||||||
return (nil, nil)
|
return (nil, nil)
|
||||||
}
|
}
|
||||||
@ -65,6 +61,10 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if case .standard(.embedded) = chatPresentationInterfaceState.mode {
|
||||||
|
return (nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
if let selectionState = chatPresentationInterfaceState.interfaceState.selectionState {
|
if let selectionState = chatPresentationInterfaceState.interfaceState.selectionState {
|
||||||
if let _ = chatPresentationInterfaceState.reportReason {
|
if let _ = chatPresentationInterfaceState.reportReason {
|
||||||
if let currentPanel = (currentPanel as? ChatMessageReportInputPanelNode) ?? (currentSecondaryPanel as? ChatMessageReportInputPanelNode) {
|
if let currentPanel = (currentPanel as? ChatMessageReportInputPanelNode) ?? (currentSecondaryPanel as? ChatMessageReportInputPanelNode) {
|
||||||
|
|||||||
@ -25,7 +25,7 @@ private let backgroundTagImage: UIImage? = {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, UIScrollViewDelegate {
|
final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, ChatControllerCustomNavigationPanelNode, UIScrollViewDelegate {
|
||||||
private struct Params: Equatable {
|
private struct Params: Equatable {
|
||||||
var width: CGFloat
|
var width: CGFloat
|
||||||
var leftInset: CGFloat
|
var leftInset: CGFloat
|
||||||
@ -551,6 +551,10 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, UISc
|
|||||||
return LayoutResult(backgroundHeight: panelHeight, insetHeight: panelHeight, hitTestSlop: 0.0)
|
return LayoutResult(backgroundHeight: panelHeight, insetHeight: panelHeight, hitTestSlop: 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition, chatController: ChatController) -> LayoutResult {
|
||||||
|
return self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, transition: transition, interfaceState: (chatController as! ChatControllerImpl).presentationInterfaceState)
|
||||||
|
}
|
||||||
|
|
||||||
private func update(params: Params, transition: ContainedViewLayoutTransition) {
|
private func update(params: Params, transition: ContainedViewLayoutTransition) {
|
||||||
let panelHeight: CGFloat = 39.0
|
let panelHeight: CGFloat = 39.0
|
||||||
|
|
||||||
|
|||||||
@ -3,13 +3,10 @@ import UIKit
|
|||||||
import Display
|
import Display
|
||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
import ChatPresentationInterfaceState
|
import ChatPresentationInterfaceState
|
||||||
|
import AccountContext
|
||||||
|
|
||||||
class ChatTitleAccessoryPanelNode: ASDisplayNode {
|
class ChatTitleAccessoryPanelNode: ASDisplayNode {
|
||||||
struct LayoutResult {
|
typealias LayoutResult = ChatControllerCustomNavigationPanelNode.LayoutResult
|
||||||
var backgroundHeight: CGFloat
|
|
||||||
var insetHeight: CGFloat
|
|
||||||
var hitTestSlop: CGFloat
|
|
||||||
}
|
|
||||||
|
|
||||||
var interfaceInteraction: ChatPanelInterfaceInteraction?
|
var interfaceInteraction: ChatPanelInterfaceInteraction?
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user