Merge commit '55c4015269d5a8fbd4f68bea9c6fb5e41f296b9f'

This commit is contained in:
Ali 2021-11-30 22:18:24 +04:00
commit 199bb36dfb
33 changed files with 676 additions and 61 deletions

View File

@ -7125,3 +7125,9 @@ Sorry for the inconvenience.";
"Login.EnterMissingDigits" = "Enter the missing digits"; "Login.EnterMissingDigits" = "Enter the missing digits";
"Channel.AdminLogFilter.EventsSentMessages" = "Sent Messages"; "Channel.AdminLogFilter.EventsSentMessages" = "Sent Messages";
"Contacts.AddContact" = "Add Contact";
"Conversation.LargeEmojiDisabledInfo" = "You have disabled large emoji, so they appear small and have no effects in chat.";
"Conversation.LargeEmojiEnable" = "Enable Large Emoji";
"Conversation.LargeEmojiEnabled" = "Large emoji enabled.";

View File

@ -500,19 +500,24 @@ private final class AuthTransferScanScreenNode: ViewControllerTracingNode, UIScr
transition.updateAlpha(node: self.textNode, alpha: controlsAlpha) transition.updateAlpha(node: self.textNode, alpha: controlsAlpha)
transition.updateAlpha(node: self.errorTextNode, alpha: controlsAlpha) transition.updateAlpha(node: self.errorTextNode, alpha: controlsAlpha)
transition.updateAlpha(node: self.torchButtonNode, alpha: controlsAlpha) transition.updateAlpha(node: self.torchButtonNode, alpha: controlsAlpha)
for view in self.highlightViews {
transition.updateAlpha(layer: view.layer, alpha: controlsAlpha)
}
let titleSize = self.titleNode.updateLayout(CGSize(width: layout.size.width - 16.0, height: layout.size.height)) let titleSize = self.titleNode.updateLayout(CGSize(width: layout.size.width - 16.0, height: layout.size.height))
let textSize = self.textNode.updateLayout(CGSize(width: layout.size.width - 16.0, height: layout.size.height)) let textSize = self.textNode.updateLayout(CGSize(width: layout.size.width - 16.0, height: layout.size.height))
let errorTextSize = self.errorTextNode.updateLayout(CGSize(width: layout.size.width - 16.0, height: layout.size.height)) let errorTextSize = self.errorTextNode.updateLayout(CGSize(width: layout.size.width - 16.0, height: layout.size.height))
let textFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - textSize.width) / 2.0), y: min(dimHeight - textSize.height - titleSpacing, navigationHeight + floorToScreenPixels((dimHeight - navigationHeight - textSize.height) / 2.0) + 5.0)), size: textSize) var textFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - textSize.width) / 2.0), y: max(dimHeight - textSize.height - titleSpacing, navigationHeight + floorToScreenPixels((dimHeight - navigationHeight - textSize.height) / 2.0) + 5.0)), size: textSize)
let titleFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width) / 2.0), y: textFrame.minY - 18.0 - titleSize.height), size: titleSize) let titleFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width) / 2.0), y: textFrame.minY - 18.0 - titleSize.height), size: titleSize)
var errorTextFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - errorTextSize.width) / 2.0), y: dimHeight + frameSide + 48.0), size: errorTextSize)
errorTextFrame.origin.y += floor(additionalTorchOffset / 2.0)
if titleFrame.minY < navigationHeight { if titleFrame.minY < navigationHeight {
transition.updateAlpha(node: self.titleNode, alpha: 0.0) transition.updateAlpha(node: self.titleNode, alpha: 0.0)
textFrame = textFrame.offsetBy(dx: 0.0, dy: -5.0)
} else { } else {
transition.updateAlpha(node: self.titleNode, alpha: controlsAlpha) transition.updateAlpha(node: self.titleNode, alpha: controlsAlpha)
} }
var errorTextFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - errorTextSize.width) / 2.0), y: dimHeight + frameSide + 48.0), size: errorTextSize)
errorTextFrame.origin.y += floor(additionalTorchOffset / 2.0)
transition.updateFrameAdditive(node: self.titleNode, frame: titleFrame) transition.updateFrameAdditive(node: self.titleNode, frame: titleFrame)
transition.updateFrameAdditive(node: self.textNode, frame: textFrame) transition.updateFrameAdditive(node: self.textNode, frame: textFrame)
transition.updateFrameAdditive(node: self.errorTextNode, frame: errorTextFrame) transition.updateFrameAdditive(node: self.errorTextNode, frame: errorTextFrame)

View File

@ -99,6 +99,8 @@ public final class CallListController: TelegramBaseController {
super.init(context: context, navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData), mediaAccessoryPanelVisibility: .none, locationBroadcastPanelSource: .none, groupCallPanelSource: .none) super.init(context: context, navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData), mediaAccessoryPanelVisibility: .none, locationBroadcastPanelSource: .none, groupCallPanelSource: .none)
self.tabBarItemContextActionType = .always
self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
if case .tab = self.mode { if case .tab = self.mode {
@ -394,7 +396,9 @@ public final class CallListController: TelegramBaseController {
}) })
} }
})) }))
(self.navigationController as? NavigationController)?.pushViewController(controller) if let navigationController = self.context.sharedContext.mainWindow?.viewController as? NavigationController {
navigationController.pushViewController(controller)
}
} }
@objc func editPressed() { @objc func editPressed() {
@ -464,4 +468,43 @@ public final class CallListController: TelegramBaseController {
} }
})) }))
} }
override public func tabBarItemContextAction(sourceNode: ContextExtractedContentContainingNode, gesture: ContextGesture) {
var items: [ContextMenuItem] = []
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Calls_StartNewCall, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddUser"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] c, f in
c.dismiss(completion: { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.callPressed()
})
})))
let controller = ContextController(account: self.context.account, presentationData: self.presentationData, source: .extracted(CallListTabBarContextExtractedContentSource(controller: self, sourceNode: sourceNode)), items: .single(ContextController.Items(items: items)), recognizer: nil, gesture: gesture)
self.context.sharedContext.mainWindow?.presentInGlobalOverlay(controller)
}
}
private final class CallListTabBarContextExtractedContentSource: ContextExtractedContentSource {
let keepInPlace: Bool = true
let ignoreContentTouches: Bool = true
let blurBackground: Bool = true
private let controller: ViewController
private let sourceNode: ContextExtractedContentContainingNode
init(controller: ViewController, sourceNode: ContextExtractedContentContainingNode) {
self.controller = controller
self.sourceNode = sourceNode
}
func takeView() -> ContextControllerTakeViewInfo? {
return ContextControllerTakeViewInfo(contentContainingNode: self.sourceNode, contentAreaInScreenSpace: UIScreen.main.bounds)
}
func putBack() -> ContextControllerPutBackViewInfo? {
return ContextControllerPutBackViewInfo(contentAreaInScreenSpace: UIScreen.main.bounds)
}
} }

View File

@ -17,6 +17,7 @@ import SearchUI
import TelegramPermissionsUI import TelegramPermissionsUI
import AppBundle import AppBundle
import StickerResources import StickerResources
import ContextUI
private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBarSearchContentNode) -> Bool { private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBarSearchContentNode) -> Bool {
if searchNode.expansionProgress > 0.0 && searchNode.expansionProgress < 1.0 { if searchNode.expansionProgress > 0.0 && searchNode.expansionProgress < 1.0 {
@ -100,6 +101,8 @@ public class ContactsController: ViewController {
super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData)) super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData))
self.tabBarItemContextActionType = .always
self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
self.title = self.presentationData.strings.Contacts_Title self.title = self.presentationData.strings.Contacts_Title
@ -311,12 +314,14 @@ public class ContactsController: ViewController {
let presentPeersNearby = { let presentPeersNearby = {
let controller = strongSelf.context.sharedContext.makePeersNearbyController(context: strongSelf.context) let controller = strongSelf.context.sharedContext.makePeersNearbyController(context: strongSelf.context)
controller.navigationPresentation = .master controller.navigationPresentation = .master
(strongSelf.navigationController as? NavigationController)?.pushViewController(controller, animated: true, completion: { [weak self] in if let navigationController = strongSelf.context.sharedContext.mainWindow?.viewController as? NavigationController {
navigationController.pushViewController(controller, animated: true, completion: { [weak self] in
if let strongSelf = self { if let strongSelf = self {
strongSelf.contactsNode.contactListNode.listNode.clearHighlightAnimated(true) strongSelf.contactsNode.contactListNode.listNode.clearHighlightAnimated(true)
} }
}) })
} }
}
switch status { switch status {
case .allowed: case .allowed:
@ -332,12 +337,14 @@ public class ContactsController: ViewController {
let _ = (strongSelf.navigationController as? NavigationController)?.popViewController(animated: true) let _ = (strongSelf.navigationController as? NavigationController)?.popViewController(animated: true)
} }
} }
(strongSelf.navigationController as? NavigationController)?.pushViewController(controller, completion: { [weak self] in if let navigationController = strongSelf.context.sharedContext.mainWindow?.viewController as? NavigationController {
navigationController.pushViewController(controller, completion: { [weak self] in
if let strongSelf = self { if let strongSelf = self {
strongSelf.contactsNode.contactListNode.listNode.clearHighlightAnimated(true) strongSelf.contactsNode.contactListNode.listNode.clearHighlightAnimated(true)
} }
}) })
} }
}
}) })
} }
@ -480,20 +487,26 @@ public class ContactsController: ViewController {
switch status { switch status {
case .allowed: case .allowed:
let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: "", lastName: "", phoneNumbers: [DeviceContactPhoneNumberData(label: "_$!<Mobile>!$_", value: "+")]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "") let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: "", lastName: "", phoneNumbers: [DeviceContactPhoneNumberData(label: "_$!<Mobile>!$_", value: "+")]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")
(strongSelf.navigationController as? NavigationController)?.pushViewController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .create(peer: nil, contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in if let navigationController = strongSelf.context.sharedContext.mainWindow?.viewController as? NavigationController {
navigationController.pushViewController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .create(peer: nil, contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
if let peer = peer { if let peer = peer {
DispatchQueue.main.async { DispatchQueue.main.async {
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) { if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
(strongSelf.navigationController as? NavigationController)?.pushViewController(infoController) if let navigationController = strongSelf.context.sharedContext.mainWindow?.viewController as? NavigationController {
navigationController.pushViewController(infoController)
}
} }
} }
} else { } else {
(strongSelf.navigationController as? NavigationController)?.pushViewController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .vcard(nil, stableId, contactData), completed: nil, cancelled: nil)) if let navigationController = strongSelf.context.sharedContext.mainWindow?.viewController as? NavigationController {
navigationController.pushViewController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .vcard(nil, stableId, contactData), completed: nil, cancelled: nil))
}
} }
}), completed: nil, cancelled: nil)) }), completed: nil, cancelled: nil))
}
case .notDetermined: case .notDetermined:
DeviceAccess.authorizeAccess(to: .contacts) DeviceAccess.authorizeAccess(to: .contacts)
default: default:
@ -504,4 +517,54 @@ public class ContactsController: ViewController {
} }
}) })
} }
override public func tabBarItemContextAction(sourceNode: ContextExtractedContentContainingNode, gesture: ContextGesture) {
var items: [ContextMenuItem] = []
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Contacts_AddContact, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddUser"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] c, f in
c.dismiss(completion: { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.addPressed()
})
})))
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Contacts_AddPeopleNearby, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Contact List/Context Menu/PeopleNearby"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] c, f in
c.dismiss(completion: { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.contactsNode.openPeopleNearby?()
})
})))
let controller = ContextController(account: self.context.account, presentationData: self.presentationData, source: .extracted(ContactsTabBarContextExtractedContentSource(controller: self, sourceNode: sourceNode)), items: .single(ContextController.Items(items: items)), recognizer: nil, gesture: gesture)
self.context.sharedContext.mainWindow?.presentInGlobalOverlay(controller)
}
}
private final class ContactsTabBarContextExtractedContentSource: ContextExtractedContentSource {
let keepInPlace: Bool = true
let ignoreContentTouches: Bool = true
let blurBackground: Bool = true
private let controller: ViewController
private let sourceNode: ContextExtractedContentContainingNode
init(controller: ViewController, sourceNode: ContextExtractedContentContainingNode) {
self.controller = controller
self.sourceNode = sourceNode
}
func takeView() -> ContextControllerTakeViewInfo? {
return ContextControllerTakeViewInfo(contentContainingNode: self.sourceNode, contentAreaInScreenSpace: UIScreen.main.bounds)
}
func putBack() -> ContextControllerPutBackViewInfo? {
return ContextControllerPutBackViewInfo(contentAreaInScreenSpace: UIScreen.main.bounds)
}
} }

View File

@ -550,6 +550,7 @@ open class NavigationBar: ASDisplayNode {
if self.badgeNode.text != actualText { if self.badgeNode.text != actualText {
self.badgeNode.text = actualText self.badgeNode.text = actualText
self.badgeNode.isHidden = actualText.isEmpty self.badgeNode.isHidden = actualText.isEmpty
self.backButtonNode.manualAlpha = self.badgeNode.isHidden ? 1.0 : 0.0
self.invalidateCalculatedLayout() self.invalidateCalculatedLayout()
self.requestLayout() self.requestLayout()
@ -835,7 +836,7 @@ open class NavigationBar: ASDisplayNode {
self.titleNode.accessibilityTraits = .header self.titleNode.accessibilityTraits = .header
self.backButtonNode = NavigationButtonNode() self.backButtonNode = NavigationButtonNode()
self.badgeNode = NavigationBarBadgeNode(fillColor: self.presentationData.theme.badgeBackgroundColor, strokeColor: self.presentationData.theme.badgeStrokeColor, textColor: self.presentationData.theme.badgeTextColor) self.badgeNode = NavigationBarBadgeNode(fillColor: self.presentationData.theme.buttonColor, strokeColor: self.presentationData.theme.buttonColor, textColor: self.presentationData.theme.badgeTextColor)
self.badgeNode.isUserInteractionEnabled = false self.badgeNode.isUserInteractionEnabled = false
self.badgeNode.isHidden = true self.badgeNode.isHidden = true
self.backButtonArrow = ASImageNode() self.backButtonArrow = ASImageNode()
@ -890,6 +891,7 @@ open class NavigationBar: ASDisplayNode {
self.backButtonNode.highlightChanged = { [weak self] index, highlighted in self.backButtonNode.highlightChanged = { [weak self] index, highlighted in
if let strongSelf = self, index == 0 { if let strongSelf = self, index == 0 {
strongSelf.backButtonArrow.alpha = (highlighted ? 0.4 : 1.0) strongSelf.backButtonArrow.alpha = (highlighted ? 0.4 : 1.0)
strongSelf.badgeNode.alpha = (highlighted ? 0.4 : 1.0)
} }
} }
self.backButtonNode.pressed = { [weak self] index in self.backButtonNode.pressed = { [weak self] index in
@ -957,7 +959,7 @@ open class NavigationBar: ASDisplayNode {
} }
self.stripeNode.backgroundColor = self.presentationData.theme.separatorColor self.stripeNode.backgroundColor = self.presentationData.theme.separatorColor
self.badgeNode.updateTheme(fillColor: self.presentationData.theme.badgeBackgroundColor, strokeColor: self.presentationData.theme.badgeStrokeColor, textColor: self.presentationData.theme.badgeTextColor) self.badgeNode.updateTheme(fillColor: self.presentationData.theme.buttonColor, strokeColor: self.presentationData.theme.buttonColor, textColor: self.presentationData.theme.badgeTextColor)
self.requestLayout() self.requestLayout()
} }
@ -1089,7 +1091,7 @@ open class NavigationBar: ASDisplayNode {
let badgeSize = self.badgeNode.measure(CGSize(width: 200.0, height: 100.0)) let badgeSize = self.badgeNode.measure(CGSize(width: 200.0, height: 100.0))
let backButtonArrowFrame = self.backButtonArrow.frame let backButtonArrowFrame = self.backButtonArrow.frame
transition.updateFrame(node: self.badgeNode, frame: CGRect(origin: backButtonArrowFrame.origin.offsetBy(dx: 7.0, dy: -9.0), size: badgeSize)) transition.updateFrame(node: self.badgeNode, frame: CGRect(origin: backButtonArrowFrame.origin.offsetBy(dx: 16.0, dy: 2.0), size: badgeSize))
if self.rightButtonNode.supernode != nil { if self.rightButtonNode.supernode != nil {
let rightButtonSize = self.rightButtonNode.updateLayout(constrainedSize: (CGSize(width: size.width, height: nominalHeight)), isLandscape: isLandscape) let rightButtonSize = self.rightButtonNode.updateLayout(constrainedSize: (CGSize(width: size.width, height: nominalHeight)), isLandscape: isLandscape)
@ -1122,7 +1124,7 @@ open class NavigationBar: ASDisplayNode {
transitionBackArrowNode.alpha = max(0.0, 1.0 - progress * 1.3) transitionBackArrowNode.alpha = max(0.0, 1.0 - progress * 1.3)
if let transitionBadgeNode = self.transitionBadgeNode { if let transitionBadgeNode = self.transitionBadgeNode {
transitionBadgeNode.frame = CGRect(origin: transitionBackArrowNode.frame.origin.offsetBy(dx: 7.0, dy: -9.0), size: transitionBadgeNode.bounds.size) transitionBadgeNode.frame = CGRect(origin: transitionBackArrowNode.frame.origin.offsetBy(dx: 16.0, dy: 2.0), size: transitionBadgeNode.bounds.size)
transitionBadgeNode.alpha = transitionBackArrowNode.alpha transitionBadgeNode.alpha = transitionBackArrowNode.alpha
} }
} }
@ -1284,7 +1286,7 @@ open class NavigationBar: ASDisplayNode {
public func makeTransitionBadgeNode() -> ASDisplayNode? { public func makeTransitionBadgeNode() -> ASDisplayNode? {
if self.badgeNode.supernode != nil && !self.badgeNode.isHidden { if self.badgeNode.supernode != nil && !self.badgeNode.isHidden {
let node = NavigationBarBadgeNode(fillColor: self.presentationData.theme.badgeBackgroundColor, strokeColor: self.presentationData.theme.badgeStrokeColor, textColor: self.presentationData.theme.badgeTextColor) let node = NavigationBarBadgeNode(fillColor: self.presentationData.theme.buttonColor, strokeColor: self.presentationData.theme.buttonColor, textColor: self.presentationData.theme.badgeTextColor)
node.text = self.badgeNode.text node.text = self.badgeNode.text
let nodeSize = node.measure(CGSize(width: 200.0, height: 100.0)) let nodeSize = node.measure(CGSize(width: 200.0, height: 100.0))
node.frame = CGRect(origin: CGPoint(), size: nodeSize) node.frame = CGRect(origin: CGPoint(), size: nodeSize)

View File

@ -31,7 +31,7 @@ public final class NavigationBarBadgeNode: ASDisplayNode {
self.backgroundNode = ASImageNode() self.backgroundNode = ASImageNode()
self.backgroundNode.isLayerBacked = true self.backgroundNode.isLayerBacked = true
self.backgroundNode.displaysAsynchronously = false self.backgroundNode.displaysAsynchronously = false
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 18.0, color: fillColor, strokeColor: strokeColor, strokeWidth: 1.0) self.backgroundNode.image = generateStretchableFilledCircleImage(radius: 18.0, color: fillColor, backgroundColor: nil)
super.init() super.init()
@ -43,14 +43,19 @@ public final class NavigationBarBadgeNode: ASDisplayNode {
self.fillColor = fillColor self.fillColor = fillColor
self.strokeColor = strokeColor self.strokeColor = strokeColor
self.textColor = textColor self.textColor = textColor
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 18.0, color: fillColor, strokeColor: strokeColor, strokeWidth: 1.0) self.backgroundNode.image = generateStretchableFilledCircleImage(radius: 18.0, color: fillColor, backgroundColor: nil)
self.textNode.attributedText = NSAttributedString(string: self.text, font: self.font, textColor: self.textColor) self.textNode.attributedText = NSAttributedString(string: self.text, font: self.font, textColor: self.textColor)
self.textNode.redrawIfPossible() self.textNode.redrawIfPossible()
} }
override public func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { override public func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
let badgeSize = self.textNode.updateLayout(constrainedSize) let badgeSize = self.textNode.updateLayout(constrainedSize)
let backgroundSize = CGSize(width: max(18.0, badgeSize.width + 10.0 + 1.0), height: 18.0) let backgroundSize: CGSize
if self.text.count < 2 {
backgroundSize = CGSize(width: 18.0, height: 18.0)
} else {
backgroundSize = CGSize(width: max(18.0, badgeSize.width + 10.0 + 1.0), height: 18.0)
}
let backgroundFrame = CGRect(origin: CGPoint(), size: backgroundSize) let backgroundFrame = CGRect(origin: CGPoint(), size: backgroundSize)
self.backgroundNode.frame = backgroundFrame self.backgroundNode.frame = backgroundFrame
self.textNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels(backgroundFrame.midX - badgeSize.width / 2.0), y: floorToScreenPixels((backgroundFrame.size.height - badgeSize.height) / 2.0)), size: badgeSize) self.textNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels(backgroundFrame.midX - badgeSize.width / 2.0), y: floorToScreenPixels((backgroundFrame.size.height - badgeSize.height) / 2.0)), size: badgeSize)

View File

@ -278,7 +278,11 @@ private final class NavigationButtonItemNode: ImmediateTextNode {
let result = node.view.hitTest(self.view.convert(point, to: node.view), with: event) let result = node.view.hitTest(self.view.convert(point, to: node.view), with: event)
return result return result
} else { } else {
return super.hitTest(point, with: event) let previousAlpha = self.alpha
self.alpha = 1.0
let result = super.hitTest(point, with: event)
self.alpha = previousAlpha
return result
} }
} }
@ -300,7 +304,9 @@ private final class NavigationButtonItemNode: ImmediateTextNode {
} }
if shouldChangeHighlight { if shouldChangeHighlight {
if self.alpha > 0.0 {
self.alpha = !self.isEnabled ? 1.0 : (highlighted ? 0.4 : 1.0) self.alpha = !self.isEnabled ? 1.0 : (highlighted ? 0.4 : 1.0)
}
self.highlightChanged(highlighted) self.highlightChanged(highlighted)
} }
} }
@ -379,6 +385,14 @@ public final class NavigationButtonNode: ASDisplayNode {
return self.nodes.first?.text ?? "" return self.nodes.first?.text ?? ""
} }
var manualAlpha: CGFloat = 1.0 {
didSet {
for node in self.nodes {
node.alpha = self.manualAlpha
}
}
}
func updateManualText(_ text: String, isBack: Bool = true) { func updateManualText(_ text: String, isBack: Bool = true) {
let node: NavigationButtonItemNode let node: NavigationButtonItemNode
if self.nodes.count > 0 { if self.nodes.count > 0 {
@ -404,6 +418,7 @@ public final class NavigationButtonNode: ASDisplayNode {
self.nodes.append(node) self.nodes.append(node)
self.addSubnode(node) self.addSubnode(node)
} }
node.alpha = self.manualAlpha
node.item = nil node.item = nil
node.image = nil node.image = nil
node.text = text node.text = text
@ -445,6 +460,7 @@ public final class NavigationButtonNode: ASDisplayNode {
self.nodes.append(node) self.nodes.append(node)
self.addSubnode(node) self.addSubnode(node)
} }
node.alpha = self.manualAlpha
node.item = items[i] node.item = items[i]
node.image = items[i].image node.image = items[i].image
node.text = items[i].title ?? "" node.text = items[i].title ?? ""

View File

@ -7,7 +7,11 @@ import SwipeToDismissGesture
open class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDelegate { open class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDelegate {
public var statusBar: StatusBar? public var statusBar: StatusBar?
public var navigationBar: NavigationBar? public var navigationBar: NavigationBar? {
didSet {
}
}
public let footerNode: GalleryFooterNode public let footerNode: GalleryFooterNode
public var currentThumbnailContainerNode: GalleryThumbnailContainerNode? public var currentThumbnailContainerNode: GalleryThumbnailContainerNode?
public var overlayNode: ASDisplayNode? public var overlayNode: ASDisplayNode?
@ -137,7 +141,6 @@ open class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGesture
self.view.addSubview(self.scrollView) self.view.addSubview(self.scrollView)
self.scrollView.addSubview(self.pager.view) self.scrollView.addSubview(self.pager.view)
self.addSubnode(self.footerNode)
var previousIndex: Int? var previousIndex: Int?
self.pager.centralItemIndexOffsetUpdated = { [weak self] itemsIndexAndProgress in self.pager.centralItemIndexOffsetUpdated = { [weak self] itemsIndexAndProgress in
@ -256,6 +259,9 @@ open class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGesture
if let navigationBar = self.navigationBar { if let navigationBar = self.navigationBar {
transition.updateFrame(node: navigationBar, frame: CGRect(origin: CGPoint(x: 0.0, y: self.areControlsHidden ? -navigationBarHeight : 0.0), size: CGSize(width: layout.size.width, height: navigationBarHeight))) transition.updateFrame(node: navigationBar, frame: CGRect(origin: CGPoint(x: 0.0, y: self.areControlsHidden ? -navigationBarHeight : 0.0), size: CGSize(width: layout.size.width, height: navigationBarHeight)))
if self.footerNode.supernode == nil {
self.addSubnode(self.footerNode)
}
} }
var thumbnailPanelHeight: CGFloat = 0.0 var thumbnailPanelHeight: CGFloat = 0.0

View File

@ -215,8 +215,6 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
private let recognitionDisposable = MetaDisposable() private let recognitionDisposable = MetaDisposable()
private var status: MediaResourceStatus? private var status: MediaResourceStatus?
private var textCopiedTooltipController: UndoOverlayController?
private let pagingEnabledPromise = ValuePromise<Bool>(true) private let pagingEnabledPromise = ValuePromise<Bool>(true)
init(context: AccountContext, presentationData: PresentationData, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void, openActionOptions: @escaping (GalleryControllerInteractionTapAction, Message) -> Void, present: @escaping (ViewController, Any?) -> Void) { init(context: AccountContext, presentationData: PresentationData, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void, openActionOptions: @escaping (GalleryControllerInteractionTapAction, Message) -> Void, present: @escaping (ViewController, Any?) -> Void) {
@ -260,8 +258,11 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
if let recognizedContentNode = strongSelf.recognizedContentNode { if let recognizedContentNode = strongSelf.recognizedContentNode {
strongSelf.imageNode.isUserInteractionEnabled = active strongSelf.imageNode.isUserInteractionEnabled = active
transition.updateAlpha(node: recognizedContentNode, alpha: active ? 1.0 : 0.0) transition.updateAlpha(node: recognizedContentNode, alpha: active ? 1.0 : 0.0)
if !active { if active {
strongSelf.updateControlsVisibility(false)
} else {
recognizedContentNode.dismissSelection() recognizedContentNode.dismissSelection()
strongSelf.updateControlsVisibility(true)
} }
strongSelf.pagingEnabledPromise.set(!active) strongSelf.pagingEnabledPromise.set(!active)
} }
@ -333,7 +334,6 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
if let controller = strongSelf.baseNavigationController()?.topViewController as? ViewController { if let controller = strongSelf.baseNavigationController()?.topViewController as? ViewController {
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with({ $0 }) let presentationData = strongSelf.context.sharedContext.currentPresentationData.with({ $0 })
let tooltipController = UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_TextCopied), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }) let tooltipController = UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_TextCopied), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false })
strongSelf.textCopiedTooltipController = tooltipController
controller.present(tooltipController, in: .window(.root)) controller.present(tooltipController, in: .window(.root))
} }
case .share: case .share:
@ -626,7 +626,19 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
} }
override func animateOut(to node: (ASDisplayNode, CGRect, () -> (UIView?, UIView?)), addToTransitionSurface: (UIView) -> Void, completion: @escaping () -> Void) { override func animateOut(to node: (ASDisplayNode, CGRect, () -> (UIView?, UIView?)), addToTransitionSurface: (UIView) -> Void, completion: @escaping () -> Void) {
self.textCopiedTooltipController?.dismiss() if let controller = self.baseNavigationController()?.topViewController as? ViewController {
controller.window?.forEachController({ controller in
if let controller = controller as? UndoOverlayController {
controller.dismissWithCommitAction()
}
})
controller.forEachController({ controller in
if let controller = controller as? UndoOverlayController {
controller.dismissWithCommitAction()
}
return true
})
}
self.fetchDisposable.set(nil) self.fetchDisposable.set(nil)
@ -1098,6 +1110,7 @@ private class ImageRecognitionOverlayContentNode: GalleryOverlayContentNode {
private let backgroundNode: ASImageNode private let backgroundNode: ASImageNode
private let selectedBackgroundNode: ASImageNode private let selectedBackgroundNode: ASImageNode
private let iconNode: ASImageNode private let iconNode: ASImageNode
private let selectedIconNode: ASImageNode
private let buttonNode: HighlightTrackingButtonNode private let buttonNode: HighlightTrackingButtonNode
var action: ((Bool) -> Void)? var action: ((Bool) -> Void)?
@ -1106,12 +1119,11 @@ private class ImageRecognitionOverlayContentNode: GalleryOverlayContentNode {
init(theme: PresentationTheme) { init(theme: PresentationTheme) {
self.backgroundNode = ASImageNode() self.backgroundNode = ASImageNode()
self.backgroundNode.displaysAsynchronously = false self.backgroundNode.displaysAsynchronously = false
self.backgroundNode.image = generateFilledCircleImage(diameter: 32.0, color: UIColor(white: 0.0, alpha: 0.6))
self.selectedBackgroundNode = ASImageNode() self.selectedBackgroundNode = ASImageNode()
self.selectedBackgroundNode.displaysAsynchronously = false self.selectedBackgroundNode.displaysAsynchronously = false
self.selectedBackgroundNode.isHidden = true self.selectedBackgroundNode.isHidden = true
self.selectedBackgroundNode.image = generateFilledCircleImage(diameter: 32.0, color: theme.list.itemAccentColor) self.selectedBackgroundNode.image = generateFilledCircleImage(diameter: 32.0, color: .white)
self.buttonNode = HighlightTrackingButtonNode() self.buttonNode = HighlightTrackingButtonNode()
self.buttonNode.alpha = 0.0 self.buttonNode.alpha = 0.0
@ -1121,6 +1133,12 @@ private class ImageRecognitionOverlayContentNode: GalleryOverlayContentNode {
self.iconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/LiveTextIcon"), color: .white) self.iconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/LiveTextIcon"), color: .white)
self.iconNode.contentMode = .center self.iconNode.contentMode = .center
self.selectedIconNode = ASImageNode()
self.selectedIconNode.displaysAsynchronously = false
self.selectedIconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/LiveTextIcon"), color: .black)
self.selectedIconNode.contentMode = .center
self.selectedIconNode.isHidden = true
super.init() super.init()
self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside) self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
@ -1128,13 +1146,16 @@ private class ImageRecognitionOverlayContentNode: GalleryOverlayContentNode {
self.buttonNode.addSubnode(self.backgroundNode) self.buttonNode.addSubnode(self.backgroundNode)
self.buttonNode.addSubnode(self.selectedBackgroundNode) self.buttonNode.addSubnode(self.selectedBackgroundNode)
self.buttonNode.addSubnode(self.iconNode) self.buttonNode.addSubnode(self.iconNode)
self.buttonNode.addSubnode(self.selectedIconNode)
} }
@objc private func buttonPressed() { @objc private func buttonPressed() {
let newValue = !self.buttonNode.isSelected let newValue = !self.buttonNode.isSelected
self.action?(newValue)
self.buttonNode.isSelected = newValue self.buttonNode.isSelected = newValue
self.selectedBackgroundNode.isHidden = !newValue self.selectedBackgroundNode.isHidden = !newValue
self.selectedIconNode.isHidden = !newValue
self.action?(newValue)
if self.interfaceIsHidden && !newValue { if self.interfaceIsHidden && !newValue {
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut) let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
@ -1159,6 +1180,7 @@ private class ImageRecognitionOverlayContentNode: GalleryOverlayContentNode {
self.backgroundNode.frame = CGRect(origin: CGPoint(x: 12.0, y: 12.0), size: buttonSize) self.backgroundNode.frame = CGRect(origin: CGPoint(x: 12.0, y: 12.0), size: buttonSize)
self.selectedBackgroundNode.frame = CGRect(origin: CGPoint(x: 12.0, y: 12.0), size: buttonSize) self.selectedBackgroundNode.frame = CGRect(origin: CGPoint(x: 12.0, y: 12.0), size: buttonSize)
self.iconNode.frame = CGRect(origin: CGPoint(x: 12.0, y: 12.0), size: buttonSize) self.iconNode.frame = CGRect(origin: CGPoint(x: 12.0, y: 12.0), size: buttonSize)
self.selectedIconNode.frame = CGRect(origin: CGPoint(x: 12.0, y: 12.0), size: buttonSize)
if self.appeared { if self.appeared {
if !self.buttonNode.isSelected && isHidden { if !self.buttonNode.isSelected && isHidden {
@ -1168,7 +1190,7 @@ private class ImageRecognitionOverlayContentNode: GalleryOverlayContentNode {
} }
} }
transition.updateFrame(node: self.buttonNode, frame: CGRect(x: size.width - rightInset - buttonSize.width - 24.0, y: size.height - bottomInset - buttonSize.height - 24.0, width: buttonSize.width + 24.0, height: buttonSize.height + 24.0)) transition.updateFrame(node: self.buttonNode, frame: CGRect(x: size.width - rightInset - buttonSize.width - 24.0, y: 41.0, width: buttonSize.width + 24.0, height: buttonSize.height + 24.0))
} }
override func animateIn(previousContentNode: GalleryOverlayContentNode?, transition: ContainedViewLayoutTransition) { override func animateIn(previousContentNode: GalleryOverlayContentNode?, transition: ContainedViewLayoutTransition) {

View File

@ -32,7 +32,7 @@ extension PeerStatusSettings {
if (flags & (1 << 8)) != 0 { if (flags & (1 << 8)) != 0 {
result.insert(.suggestAddMembers) result.insert(.suggestAddMembers)
} }
self = PeerStatusSettings(flags: result, geoDistance: geoDistance, requestChatTitle: requestChatTitle, requestChatDate: requestChatDate, requestChatIsChannel: (flags & (1 << 9)) != 0) self = PeerStatusSettings(flags: result, geoDistance: geoDistance, requestChatTitle: requestChatTitle, requestChatDate: requestChatDate, requestChatIsChannel: (flags & (1 << 10)) != 0)
} }
} }
} }

View File

@ -1,7 +1,7 @@
{ {
"info" : { "info" : {
"version" : 1, "author" : "xcode",
"author" : "xcode" "version" : 1
}, },
"properties" : { "properties" : {
"provides-namespace" : true "provides-namespace" : true

View File

@ -0,0 +1,9 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"provides-namespace" : true
}
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "peoplenearbyon_24.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,145 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 2.934998 1.735001 cm
0.000000 0.000000 0.000000 scn
7.330000 17.464998 m
7.330000 18.423212 8.106786 19.199999 9.065001 19.199999 c
10.023214 19.199999 10.800000 18.423212 10.800000 17.464998 c
10.800000 16.506784 10.023214 15.729999 9.065001 15.729999 c
8.106786 15.729999 7.330000 16.506784 7.330000 17.464998 c
h
9.065001 20.529999 m
7.372247 20.529999 6.000000 19.157751 6.000000 17.464998 c
6.000000 15.772245 7.372247 14.399999 9.065001 14.399999 c
10.757753 14.399999 12.130000 15.772245 12.130000 17.464998 c
12.130000 19.157751 10.757753 20.529999 9.065001 20.529999 c
h
1.330000 3.865000 m
1.330000 4.026144 1.400150 4.232668 1.634496 4.483692 c
1.872207 4.738321 2.249572 5.004240 2.774642 5.255713 c
3.677844 5.688284 4.928888 6.035789 6.400000 6.230032 c
6.400001 4.564999 l
6.400001 3.755901 7.055903 3.099998 7.865001 3.099998 c
10.265000 3.099998 l
11.074098 3.099998 11.730000 3.755901 11.730000 4.564999 c
11.730000 6.230032 l
13.201113 6.035789 14.452158 5.688284 15.355359 5.255713 c
15.880429 5.004240 16.257793 4.738321 16.495506 4.483692 c
16.729851 4.232668 16.800003 4.026144 16.800003 3.865000 c
16.800003 3.677490 16.702744 3.422382 16.359842 3.113541 c
16.017097 2.804838 15.483717 2.496361 14.767962 2.223692 c
13.341063 1.680111 11.324945 1.330000 9.065001 1.330000 c
6.805056 1.330000 4.788938 1.680111 3.362040 2.223692 c
2.646284 2.496361 2.112905 2.804838 1.770159 3.113541 c
1.427257 3.422382 1.330000 3.677490 1.330000 3.865000 c
h
2.200152 6.455237 m
3.300211 6.982090 4.758119 7.368791 6.400000 7.570784 c
6.400000 8.099998 l
5.859936 8.099998 l
5.076447 8.099998 4.338713 8.757976 4.479389 9.657219 c
4.588190 10.352705 4.856467 11.405879 5.540887 12.298394 c
6.249626 13.222622 7.373408 13.929998 9.065001 13.929998 c
10.756596 13.929998 11.880377 13.222621 12.589115 12.298393 c
13.273535 11.405878 13.541812 10.352703 13.650612 9.657217 c
13.791287 8.757974 13.053553 8.099998 12.270063 8.099998 c
11.730000 8.099998 l
11.730000 7.570784 l
13.371881 7.368791 14.829790 6.982090 15.929850 6.455237 c
16.545578 6.160346 17.079411 5.807216 17.467701 5.391293 c
17.859352 4.971766 18.130001 4.456234 18.130001 3.865000 c
18.130001 3.168854 17.757156 2.582132 17.249931 2.125290 c
16.742554 1.668306 16.045780 1.287239 15.241435 0.980824 c
13.628130 0.366230 11.444248 0.000000 9.065001 0.000000 c
6.685753 0.000000 4.501871 0.366230 2.888566 0.980824 c
2.084221 1.287239 1.387449 1.668306 0.880069 2.125290 c
0.372844 2.582132 0.000000 3.168854 0.000000 3.865000 c
0.000000 4.456234 0.270649 4.971766 0.662301 5.391293 c
1.050590 5.807216 1.584423 6.160346 2.200152 6.455237 c
h
6.596293 11.489061 m
6.105442 10.848969 5.886520 10.046863 5.793407 9.451655 c
5.793330 9.451145 l
5.800257 9.444448 5.821226 9.429998 5.859936 9.429998 c
7.065000 9.429998 l
7.432269 9.429998 7.730000 9.132269 7.730000 8.764999 c
7.730000 4.564999 l
7.730000 4.490440 7.790442 4.429998 7.865001 4.429998 c
8.533002 4.429998 l
8.533002 6.764999 l
8.533002 7.058815 8.771186 7.296999 9.065001 7.296999 c
9.358817 7.296999 9.597001 7.058815 9.597001 6.764999 c
9.597001 4.429998 l
10.265000 4.429998 l
10.339560 4.429998 10.400000 4.490440 10.400000 4.564999 c
10.400000 8.764999 l
10.400000 8.941368 10.470061 9.110514 10.594772 9.235225 c
10.719484 9.359937 10.888630 9.429998 11.064999 9.429998 c
12.270063 9.429998 l
12.308775 9.429998 12.329742 9.444448 12.336671 9.451145 c
12.336594 9.451655 l
12.243481 10.046862 12.024561 10.848969 11.533709 11.489061 c
11.067177 12.097442 10.327614 12.599998 9.065001 12.599998 c
7.802389 12.599998 7.062826 12.097442 6.596293 11.489061 c
h
f*
n
Q
endstream
endobj
3 0 obj
3674
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 24.000000 24.000000 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Pages 5 0 R
/Type /Catalog
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000003764 00000 n
0000003787 00000 n
0000003960 00000 n
0000004034 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
4093
%%EOF

View File

@ -118,7 +118,7 @@ final class ChatBotInfoItemNode: ListViewItemNode {
break break
case .ignore: case .ignore:
return .fail return .fail
case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy: case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy, .largeEmoji:
return .waitForSingleTap return .waitForSingleTap
} }
} }

View File

@ -3060,6 +3060,31 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
) )
} }
}) })
}, openLargeEmojiInfo: { [weak self] _, fitz, file in
guard let strongSelf = self else {
return
}
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
LargeEmojiActionSheetItem(context: strongSelf.context, text: strongSelf.presentationData.strings.Conversation_LargeEmojiDisabledInfo, fitz: fitz, file: file),
ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LargeEmojiEnable, color: .accent, action: { [weak actionSheet, weak self] in
actionSheet?.dismissAnimated()
guard let strongSelf = self else {
return
}
let _ = updatePresentationThemeSettingsInteractively(accountManager: strongSelf.context.sharedContext.accountManager, { current in
return current.withUpdatedLargeEmoji(true)
}).start()
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .emoji(name: "TwoFactorSetupRememberSuccess", text: strongSelf.presentationData.strings.Conversation_LargeEmojiEnabled), elevatedLayout: false, action: { _ in return false }), in: .current)
})
]), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
])])
strongSelf.chatDisplayNode.dismissInput()
strongSelf.present(actionSheet, in: .window(.root))
}, requestMessageUpdate: { [weak self] id in }, requestMessageUpdate: { [weak self] id in
if let strongSelf = self { if let strongSelf = self {
strongSelf.chatDisplayNode.historyNode.requestMessageUpdate(id) strongSelf.chatDisplayNode.historyNode.requestMessageUpdate(id)

View File

@ -122,6 +122,7 @@ public final class ChatControllerInteraction {
let getMessageTransitionNode: () -> ChatMessageTransitionNode? let getMessageTransitionNode: () -> ChatMessageTransitionNode?
let updateChoosingSticker: (Bool) -> Void let updateChoosingSticker: (Bool) -> Void
let commitEmojiInteraction: (MessageId, String, EmojiInteraction, TelegramMediaFile) -> Void let commitEmojiInteraction: (MessageId, String, EmojiInteraction, TelegramMediaFile) -> Void
let openLargeEmojiInfo: (String, String?, TelegramMediaFile) -> Void
let requestMessageUpdate: (MessageId) -> Void let requestMessageUpdate: (MessageId) -> Void
let cancelInteractiveKeyboardGestures: () -> Void let cancelInteractiveKeyboardGestures: () -> Void
@ -218,6 +219,7 @@ public final class ChatControllerInteraction {
getMessageTransitionNode: @escaping () -> ChatMessageTransitionNode?, getMessageTransitionNode: @escaping () -> ChatMessageTransitionNode?,
updateChoosingSticker: @escaping (Bool) -> Void, updateChoosingSticker: @escaping (Bool) -> Void,
commitEmojiInteraction: @escaping (MessageId, String, EmojiInteraction, TelegramMediaFile) -> Void, commitEmojiInteraction: @escaping (MessageId, String, EmojiInteraction, TelegramMediaFile) -> Void,
openLargeEmojiInfo: @escaping (String, String?, TelegramMediaFile) -> Void,
requestMessageUpdate: @escaping (MessageId) -> Void, requestMessageUpdate: @escaping (MessageId) -> Void,
cancelInteractiveKeyboardGestures: @escaping () -> Void, cancelInteractiveKeyboardGestures: @escaping () -> Void,
automaticMediaDownloadSettings: MediaAutoDownloadSettings, automaticMediaDownloadSettings: MediaAutoDownloadSettings,
@ -300,6 +302,7 @@ public final class ChatControllerInteraction {
self.getMessageTransitionNode = getMessageTransitionNode self.getMessageTransitionNode = getMessageTransitionNode
self.updateChoosingSticker = updateChoosingSticker self.updateChoosingSticker = updateChoosingSticker
self.commitEmojiInteraction = commitEmojiInteraction self.commitEmojiInteraction = commitEmojiInteraction
self.openLargeEmojiInfo = openLargeEmojiInfo
self.requestMessageUpdate = requestMessageUpdate self.requestMessageUpdate = requestMessageUpdate
self.cancelInteractiveKeyboardGestures = cancelInteractiveKeyboardGestures self.cancelInteractiveKeyboardGestures = cancelInteractiveKeyboardGestures
@ -356,6 +359,7 @@ public final class ChatControllerInteraction {
return nil return nil
}, updateChoosingSticker: { _ in }, updateChoosingSticker: { _ in
}, commitEmojiInteraction: { _, _, _, _ in }, commitEmojiInteraction: { _, _, _, _ in
}, openLargeEmojiInfo: { _, _, _ in
}, requestMessageUpdate: { _ in }, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: { }, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,

View File

@ -97,6 +97,7 @@ enum ChatMessageBubbleContentTapAction {
case ignore case ignore
case openPollResults(Data) case openPollResults(Data)
case copy(String) case copy(String)
case largeEmoji(String, String?, TelegramMediaFile)
} }
final class ChatMessageBubbleContentItem { final class ChatMessageBubbleContentItem {

View File

@ -782,7 +782,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
break break
case .ignore: case .ignore:
return .fail return .fail
case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy: case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy, .largeEmoji:
return .waitForSingleTap return .waitForSingleTap
} }
} }
@ -3098,6 +3098,12 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
item.controllerInteraction.copyText(text) item.controllerInteraction.copyText(text)
}) })
} }
case let .largeEmoji(emoji, fitz, file):
if let item = self.item {
return .optionalAction({
item.controllerInteraction.openLargeEmojiInfo(emoji, fitz, file)
})
}
} }
} }
return nil return nil
@ -3176,6 +3182,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
break break
case .copy: case .copy:
break break
case .largeEmoji:
break
} }
} }
if let tapMessage = tapMessage { if let tapMessage = tapMessage {

View File

@ -459,9 +459,25 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
return .bankCard(bankCard) return .bankCard(bankCard)
} else if let pre = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Pre)] as? String { } else if let pre = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Pre)] as? String {
return .copy(pre) return .copy(pre)
} else {
if let item = self.item, item.message.text.count == 1, !item.presentationData.largeEmoji {
let (emoji, fitz) = item.message.text.basicEmoji
var emojiFile: TelegramMediaFile?
emojiFile = item.associatedData.animatedEmojiStickers[emoji]?.first?.file
if emojiFile == nil {
emojiFile = item.associatedData.animatedEmojiStickers[emoji.strippedEmoji]?.first?.file
}
if let emojiFile = emojiFile {
return .largeEmoji(emoji, fitz, emojiFile)
} else { } else {
return .none return .none
} }
} else {
return .none
}
}
} else { } else {
if let _ = self.statusNode.hitTest(self.view.convert(point, to: self.statusNode.view), with: nil) { if let _ = self.statusNode.hitTest(self.view.convert(point, to: self.statusNode.view), with: nil) {
return .ignore return .ignore

View File

@ -529,6 +529,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
return nil return nil
}, updateChoosingSticker: { _ in }, updateChoosingSticker: { _ in
}, commitEmojiInteraction: { _, _, _, _ in }, commitEmojiInteraction: { _, _, _, _ in
}, openLargeEmojiInfo: { _, _, _ in
}, requestMessageUpdate: { _ in }, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: { }, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings, }, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings,

View File

@ -89,4 +89,14 @@ final class ChatTextInputMenu {
self.state = .general self.state = .general
} }
} }
func hide() {
self.back()
if #available(iOS 13.0, *) {
UIMenuController.shared.hideMenu()
} else {
UIMenuController.shared.isMenuVisible = false
}
UIMenuController.shared.update()
}
} }

View File

@ -2048,8 +2048,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
if let textInputNode = self.textInputNode, let presentationInterfaceState = self.presentationInterfaceState { if let textInputNode = self.textInputNode, let presentationInterfaceState = self.presentationInterfaceState {
if case .format = self.inputMenu.state { if case .format = self.inputMenu.state {
self.inputMenu.deactivate() self.inputMenu.hide()
UIMenuController.shared.update()
} }
let baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize) let baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)

View File

@ -155,6 +155,7 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
return nil return nil
}, updateChoosingSticker: { _ in }, updateChoosingSticker: { _ in
}, commitEmojiInteraction: { _, _, _, _ in }, commitEmojiInteraction: { _, _, _, _ in
}, openLargeEmojiInfo: { _, _, _ in
}, requestMessageUpdate: { _ in }, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: { }, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,

View File

@ -0,0 +1,185 @@
import Foundation
import UIKit
import Display
import Postbox
import SwiftSignalKit
import TelegramCore
import TelegramPresentationData
import TelegramUIPreferences
import AccountContext
import AnimatedStickerNode
import TelegramAnimatedStickerNode
import MediaResources
import StickerResources
import ShimmerEffect
public final class LargeEmojiActionSheetItem: ActionSheetItem {
let context: AccountContext
let text: String
let fitz: String?
let file: TelegramMediaFile
public init(context: AccountContext, text: String, fitz: String?, file: TelegramMediaFile) {
self.context = context
self.text = text
self.fitz = fitz
self.file = file
}
public func node(theme: ActionSheetControllerTheme) -> ActionSheetItemNode {
return LargeEmojiActionSheetItemNode(theme: theme, context: self.context, text: self.text, fitz: self.fitz, file: self.file)
}
public func updateNode(_ node: ActionSheetItemNode) {
}
}
private final class LargeEmojiActionSheetItemNode: ActionSheetItemNode {
private let theme: ActionSheetControllerTheme
private var placeholderNode: StickerShimmerEffectNode
private let imageNode: TransformImageNode
private let animationNode: AnimatedStickerNode
private let textNode: ImmediateTextNode
private let accessibilityArea: AccessibilityAreaNode
private let disposable = MetaDisposable()
private var setupTimestamp: Double?
init(theme: ActionSheetControllerTheme, context: AccountContext, text: String, fitz: String?, file: TelegramMediaFile) {
self.theme = theme
let textFont = Font.regular(floor(theme.baseFontSize * 13.0 / 17.0))
self.placeholderNode = StickerShimmerEffectNode()
self.placeholderNode.isUserInteractionEnabled = false
self.imageNode = TransformImageNode()
self.imageNode.displaysAsynchronously = false
var fitzModifier: EmojiFitzModifier?
if let fitz = fitz {
fitzModifier = EmojiFitzModifier(emoji: fitz)
}
self.animationNode = AnimatedStickerNode()
self.animationNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: file.resource, fitzModifier: fitzModifier), width: 192, height: 192, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.animationNode.visibility = true
self.textNode = ImmediateTextNode()
self.textNode.displaysAsynchronously = false
self.textNode.maximumNumberOfLines = 0
self.textNode.textAlignment = .center
self.textNode.isAccessibilityElement = false
self.accessibilityArea = AccessibilityAreaNode()
super.init(theme: theme)
self.hasSeparator = true
self.addSubnode(self.imageNode)
self.addSubnode(self.placeholderNode)
self.addSubnode(self.animationNode)
self.addSubnode(self.textNode)
self.addSubnode(self.accessibilityArea)
let attributedText = NSAttributedString(string: text, font: textFont, textColor: theme.secondaryTextColor)
self.textNode.attributedText = attributedText
self.accessibilityArea.accessibilityLabel = attributedText.string
self.accessibilityArea.accessibilityTraits = .staticText
let dimensions = file.dimensions ?? PixelDimensions(width: 512, height: 512)
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: context.account.postbox, file: file, small: false, size: dimensions.cgSize.aspectFilled(CGSize(width: 384.0, height: 384.0)), fitzModifier: fitzModifier, thumbnail: false, synchronousLoad: true), attemptSynchronously: true)
self.disposable.set(freeMediaFileInteractiveFetched(account: context.account, fileReference: .standalone(media: file)).start())
self.setupTimestamp = CACurrentMediaTime()
self.animationNode.started = { [weak self] in
if let strongSelf = self {
strongSelf.imageNode.alpha = 0.0
let current = CACurrentMediaTime()
if let setupTimestamp = strongSelf.setupTimestamp, current - setupTimestamp > 0.3 {
if !strongSelf.placeholderNode.alpha.isZero {
strongSelf.animationNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
strongSelf.removePlaceholder(animated: true)
}
} else {
strongSelf.removePlaceholder(animated: false)
}
}
}
var firstTime = true
self.imageNode.imageUpdated = { [weak self] image in
guard let strongSelf = self else {
return
}
if image != nil {
if firstTime && !strongSelf.placeholderNode.isEmpty {
strongSelf.imageNode.alpha = 0.0
} else {
if strongSelf.setupTimestamp == nil {
strongSelf.removePlaceholder(animated: true)
}
}
firstTime = false
}
}
if let immediateThumbnailData = file.immediateThumbnailData {
self.placeholderNode.update(backgroundColor: nil, foregroundColor: theme.secondaryTextColor.blitOver(theme.itemBackgroundColor, alpha: 0.55), shimmeringColor: theme.itemBackgroundColor.withAlphaComponent(0.4), data: immediateThumbnailData, size: CGSize(width: 96.0, height: 96.0), imageSize: dimensions.cgSize)
}
}
deinit {
self.disposable.dispose()
}
override func didLoad() {
super.didLoad()
self.animationNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tap)))
}
@objc private func tap() {
let _ = self.animationNode.playIfNeeded()
}
private func removePlaceholder(animated: Bool) {
self.placeholderNode.alpha = 0.0
if !animated {
self.placeholderNode.removeFromSupernode()
} else {
self.placeholderNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak self] _ in
self?.placeholderNode.removeFromSupernode()
})
}
}
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
let textSize = self.textNode.updateLayout(CGSize(width: constrainedSize.width - 120.0, height: .greatestFiniteMagnitude))
let topInset: CGFloat = 26.0
let textSpacing: CGFloat = 17.0
let bottomInset: CGFloat = 15.0
let iconSize = CGSize(width: 96.0, height: 96.0)
self.animationNode.frame = CGRect(origin: CGPoint(x: floor((constrainedSize.width - iconSize.width) / 2.0), y: topInset), size: iconSize)
self.animationNode.updateLayout(size: iconSize)
self.placeholderNode.frame = self.animationNode.frame
self.textNode.frame = CGRect(origin: CGPoint(x: floor((constrainedSize.width - textSize.width) / 2.0), y: topInset + iconSize.height + textSpacing), size: textSize)
let size = CGSize(width: constrainedSize.width, height: topInset + iconSize.height + textSpacing + textSize.height + bottomInset)
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
self.placeholderNode.updateAbsoluteRect(CGRect(origin: CGPoint(x: self.placeholderNode.frame.minX, y: self.placeholderNode.frame.minY), size: self.placeholderNode.frame.size), within: size)
self.updateInternalLayout(size, constrainedSize: constrainedSize)
return size
}
}

View File

@ -147,6 +147,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu
return nil return nil
}, updateChoosingSticker: { _ in }, updateChoosingSticker: { _ in
}, commitEmojiInteraction: { _, _, _, _ in }, commitEmojiInteraction: { _, _, _, _ in
}, openLargeEmojiInfo: { _, _, _ in
}, requestMessageUpdate: { _ in }, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: { }, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(loopAnimatedStickers: false), presentationContext: ChatPresentationContext(backgroundNode: nil)) }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(loopAnimatedStickers: false), presentationContext: ChatPresentationContext(backgroundNode: nil))

View File

@ -52,6 +52,22 @@ final class PeerInfoScreenLabeledValueItem: PeerInfoScreenItem {
} }
} }
private func generateExpandBackground(size: CGSize, color: UIColor) -> UIImage? {
return generateImage(size, rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
var locations: [CGFloat] = [0.0, 1.0]
let colors: [CGColor] = [color.withAlphaComponent(0.0).cgColor, color.cgColor]
let colorSpace = CGColorSpaceCreateDeviceRGB()
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 40.0, y: size.height), options: CGGradientDrawingOptions())
context.setFillColor(color.cgColor)
context.fill(CGRect(origin: CGPoint(x: 40.0, y: 0.0), size: CGSize(width: size.width - 40.0, height: size.height)))
})
}
private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode { private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
private let selectionNode: PeerInfoScreenSelectableBackgroundNode private let selectionNode: PeerInfoScreenSelectableBackgroundNode
private let maskNode: ASImageNode private let maskNode: ASImageNode
@ -59,6 +75,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
private let textNode: ImmediateTextNode private let textNode: ImmediateTextNode
private let bottomSeparatorNode: ASDisplayNode private let bottomSeparatorNode: ASDisplayNode
private let expandBackgroundNode: ASImageNode
private let expandNode: ImmediateTextNode private let expandNode: ImmediateTextNode
private let expandButonNode: HighlightTrackingButtonNode private let expandButonNode: HighlightTrackingButtonNode
@ -90,6 +107,9 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
self.bottomSeparatorNode = ASDisplayNode() self.bottomSeparatorNode = ASDisplayNode()
self.bottomSeparatorNode.isLayerBacked = true self.bottomSeparatorNode.isLayerBacked = true
self.expandBackgroundNode = ASImageNode()
self.expandBackgroundNode.displaysAsynchronously = false
self.expandNode = ImmediateTextNode() self.expandNode = ImmediateTextNode()
self.expandNode.displaysAsynchronously = false self.expandNode.displaysAsynchronously = false
self.expandNode.isUserInteractionEnabled = false self.expandNode.isUserInteractionEnabled = false
@ -110,6 +130,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
self.addSubnode(self.labelNode) self.addSubnode(self.labelNode)
self.addSubnode(self.textNode) self.addSubnode(self.textNode)
self.addSubnode(self.expandBackgroundNode)
self.addSubnode(self.expandNode) self.addSubnode(self.expandNode)
self.addSubnode(self.expandButonNode) self.addSubnode(self.expandButonNode)
@ -211,7 +232,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
textColorValue = presentationData.theme.list.itemAccentColor textColorValue = presentationData.theme.list.itemAccentColor
} }
self.expandNode.attributedText = NSAttributedString(string: presentationData.strings.PeerInfo_BioExpand, font: Font.regular(17.0), textColor: presentationData.theme.list.itemAccentColor) self.expandNode.attributedText = NSAttributedString(string: presentationData.strings.PeerInfo_BioExpand.uppercased(), font: Font.medium(16.0), textColor: presentationData.theme.list.itemAccentColor)
let expandSize = self.expandNode.updateLayout(CGSize(width: width, height: 100.0)) let expandSize = self.expandNode.updateLayout(CGSize(width: width, height: 100.0))
self.labelNode.attributedText = NSAttributedString(string: item.label, font: Font.regular(14.0), textColor: presentationData.theme.list.itemPrimaryTextColor) self.labelNode.attributedText = NSAttributedString(string: item.label, font: Font.regular(14.0), textColor: presentationData.theme.list.itemPrimaryTextColor)
@ -223,7 +244,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
self.textNode.attributedText = NSAttributedString(string: item.text, font: Font.regular(17.0), textColor: textColorValue) self.textNode.attributedText = NSAttributedString(string: item.text, font: Font.regular(17.0), textColor: textColorValue)
case let .multiLine(maxLines, enabledEntities): case let .multiLine(maxLines, enabledEntities):
self.textNode.maximumNumberOfLines = self.isExpanded ? maxLines : 3 self.textNode.maximumNumberOfLines = self.isExpanded ? maxLines : 3
self.textNode.cutout = self.isExpanded ? nil : TextNodeCutout(bottomRight: CGSize(width: expandSize.width + 4.0, height: expandSize.height)) // self.textNode.cutout = self.isExpanded ? nil : TextNodeCutout(bottomRight: CGSize(width: expandSize.width + 4.0, height: expandSize.height))
if enabledEntities.isEmpty { if enabledEntities.isEmpty {
self.textNode.attributedText = NSAttributedString(string: item.text, font: Font.regular(17.0), textColor: textColorValue) self.textNode.attributedText = NSAttributedString(string: item.text, font: Font.regular(17.0), textColor: textColorValue)
} else { } else {
@ -246,9 +267,11 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
let textSize = textLayout.size let textSize = textLayout.size
if case .multiLine = item.textBehavior, textLayout.truncated, !self.isExpanded { if case .multiLine = item.textBehavior, textLayout.truncated, !self.isExpanded {
self.expandBackgroundNode.isHidden = false
self.expandNode.isHidden = false self.expandNode.isHidden = false
self.expandButonNode.isHidden = false self.expandButonNode.isHidden = false
} else { } else {
self.expandBackgroundNode.isHidden = true
self.expandNode.isHidden = true self.expandNode.isHidden = true
self.expandButonNode.isHidden = true self.expandButonNode.isHidden = true
} }
@ -260,6 +283,12 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
self.expandNode.frame = expandFrame self.expandNode.frame = expandFrame
self.expandButonNode.frame = expandFrame.insetBy(dx: -8.0, dy: -8.0) self.expandButonNode.frame = expandFrame.insetBy(dx: -8.0, dy: -8.0)
var expandBackgroundFrame = expandFrame
expandBackgroundFrame.origin.x -= 50.0
expandBackgroundFrame.size.width += 50.0
self.expandBackgroundNode.frame = expandBackgroundFrame
self.expandBackgroundNode.image = generateExpandBackground(size: expandBackgroundFrame.size, color: presentationData.theme.list.itemBlocksBackgroundColor)
transition.updateFrame(node: self.labelNode, frame: labelFrame) transition.updateFrame(node: self.labelNode, frame: labelFrame)
transition.updateFrame(node: self.textNode, frame: textFrame) transition.updateFrame(node: self.textNode, frame: textFrame)

View File

@ -2151,6 +2151,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
return nil return nil
}, updateChoosingSticker: { _ in }, updateChoosingSticker: { _ in
}, commitEmojiInteraction: { _, _, _, _ in }, commitEmojiInteraction: { _, _, _, _ in
}, openLargeEmojiInfo: { _, _, _ in
}, requestMessageUpdate: { _ in }, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: { }, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,

View File

@ -829,8 +829,7 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, TGCaptionPanelView, A
if let textInputNode = self.textInputNode, let presentationInterfaceState = self.presentationInterfaceState { if let textInputNode = self.textInputNode, let presentationInterfaceState = self.presentationInterfaceState {
if case .format = self.inputMenu.state { if case .format = self.inputMenu.state {
self.inputMenu.deactivate() self.inputMenu.hide()
UIMenuController.shared.update()
} }
let baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize) let baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)

View File

@ -1292,6 +1292,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
return nil return nil
}, updateChoosingSticker: { _ in }, updateChoosingSticker: { _ in
}, commitEmojiInteraction: { _, _, _, _ in }, commitEmojiInteraction: { _, _, _, _ in
}, openLargeEmojiInfo: { _, _, _ in
}, requestMessageUpdate: { _ in }, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: { }, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,