Merge commit 'ba1c3c09d8' into experimental-3

This commit is contained in:
Ali 2022-09-16 22:59:21 +04:00
commit 2f2880b34d
19 changed files with 314 additions and 51 deletions

View file

@ -8079,3 +8079,4 @@ Sorry for the inconvenience.";
"PeerInfo.LabelAllReactions" = "All Reactions";
"TextFormat.Format" = "Format";

View file

@ -1203,4 +1203,12 @@
return 0;
}
- (UIMenu *)textView:(UITextView *)textView editMenuForTextInRange:(NSRange)range suggestedActions:(NSArray<UIMenuElement *> *)suggestedActions API_AVAILABLE(ios(16.0)) {
if ([_delegate respondsToSelector:@selector(editableTextNodeMenu:forTextRange:suggestedActions:)]) {
return [_delegate editableTextNodeMenu:self forTextRange:range suggestedActions:suggestedActions];
} else {
return [UIMenu menuWithChildren:suggestedActions];
}
}
@end

View file

@ -221,6 +221,9 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)editableTextNodeShouldReturn:(ASEditableTextNode *)editableTextNode;
- (void)editableTextNodeBackspaceWhileEmpty:(ASEditableTextNode *)editableTextNode;
- (UIMenu *)editableTextNodeMenu:(ASEditableTextNode *)editableTextNode forTextRange:(NSRange)textRange suggestedActions:(NSArray<UIMenuElement *> *)suggestedActions API_AVAILABLE(ios(16.0));
@end
NS_ASSUME_NONNULL_END

View file

@ -1422,13 +1422,17 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
else if action == makeSelectorFromString("_accessibilitySpeakLanguageSelection:") || action == makeSelectorFromString("_accessibilityPauseSpeaking:") || action == makeSelectorFromString("_accessibilitySpeakSentence:") {
return ASEditableTextNodeTargetForAction(target: nil)
} else if action == makeSelectorFromString("_showTextStyleOptions:") {
if case .general = self.inputMenu.state {
if let textInputNode = self.textInputNode, textInputNode.attributedText == nil || textInputNode.attributedText!.length == 0 || textInputNode.selectedRange.length == 0 {
if #available(iOS 16.0, *) {
return ASEditableTextNodeTargetForAction(target: nil)
} else {
if case .general = self.inputMenu.state {
if let textInputNode = self.textInputNode, textInputNode.attributedText == nil || textInputNode.attributedText!.length == 0 || textInputNode.selectedRange.length == 0 {
return ASEditableTextNodeTargetForAction(target: nil)
}
return ASEditableTextNodeTargetForAction(target: self)
} else {
return ASEditableTextNodeTargetForAction(target: nil)
}
return ASEditableTextNodeTargetForAction(target: self)
} else {
return ASEditableTextNodeTargetForAction(target: nil)
}
} else if action == #selector(self.formatAttributesBold(_:)) || action == #selector(self.formatAttributesItalic(_:)) || action == #selector(self.formatAttributesMonospace(_:)) || action == #selector(self.formatAttributesLink(_:)) || action == #selector(self.formatAttributesStrikethrough(_:)) || action == #selector(self.formatAttributesUnderline(_:)) || action == #selector(self.formatAttributesSpoiler(_:)) {
if case .format = self.inputMenu.state {
@ -1443,6 +1447,65 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
return nil
}
@available(iOS 16.0, *)
public func editableTextNodeMenu(_ editableTextNode: ASEditableTextNode, forTextRange textRange: NSRange, suggestedActions: [UIMenuElement]) -> UIMenu {
var actions = suggestedActions
if editableTextNode.attributedText == nil || editableTextNode.attributedText!.length == 0 || editableTextNode.selectedRange.length == 0 {
} else {
var children: [UIAction] = [
UIAction(title: self.strings?.TextFormat_Bold ?? "Bold", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesBold(strongSelf)
}
},
UIAction(title: self.strings?.TextFormat_Italic ?? "Italic", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesItalic(strongSelf)
}
},
UIAction(title: self.strings?.TextFormat_Monospace ?? "Monospace", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesMonospace(strongSelf)
}
},
UIAction(title: self.strings?.TextFormat_Link ?? "Link", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesLink(strongSelf)
}
},
UIAction(title: self.strings?.TextFormat_Strikethrough ?? "Strikethrough", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesStrikethrough(strongSelf)
}
},
UIAction(title: self.strings?.TextFormat_Underline ?? "Underline", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesUnderline(strongSelf)
}
}
]
var hasSpoilers = true
if self.presentationInterfaceState?.chatLocation.peerId?.namespace == Namespaces.Peer.SecretChat {
hasSpoilers = false
}
if hasSpoilers {
children.append(UIAction(title: self.strings?.TextFormat_Spoiler ?? "Spoiler", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesSpoiler(strongSelf)
}
})
}
let formatMenu = UIMenu(title: self.strings?.TextFormat_Format ?? "Format", image: nil, children: children)
actions.insert(formatMenu, at: 3)
}
return UIMenu(children: actions)
}
@objc func _accessibilitySpeak(_ sender: Any) {
var text = ""
self.interfaceInteraction?.updateTextInputStateAndMode { current, inputMode in

View file

@ -155,8 +155,8 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .empty)).start()
}
})
if let splahController = splashController {
controller.animateWithSplashController(splahController)
if let splashController = splashController {
controller.animateWithSplashController(splashController)
}
controller.accountUpdated = { [weak self] updatedAccount in
guard let strongSelf = self else {
@ -1033,6 +1033,11 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
break
}
}
if let validLayout = self.validLayout, case .tablet = validLayout.deviceMetrics.type {
previousSplashController = nil
}
controllers.append(self.phoneEntryController(countryCode: countryCode, number: number, splashController: previousSplashController))
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty && (previousSplashController == nil || self.viewControllers.count > 2))
case let .confirmationCodeEntry(number, type, _, timeout, nextType, _):

View file

@ -426,7 +426,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
}
self.animationNode.completed = { [weak self] _ in
self?.animationNode.isHidden = true
self?.animationNode.removeFromSupernode()
self?.managedAnimationNode.isHidden = false
}
}

View file

@ -1741,7 +1741,6 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
if let _ = updatedTheme {
strongSelf.separatorNode.backgroundColor = item.presentationData.theme.chatList.itemSeparatorColor
strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.chatList.itemHighlightedBackgroundColor
}
let revealOffset = strongSelf.revealOffset
@ -2115,22 +2114,28 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
transition.updateFrame(node: strongSelf.backgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.contentSize.width, height: itemHeight)))
let backgroundColor: UIColor
let highlightedBackgroundColor: UIColor
if item.selected {
backgroundColor = theme.itemSelectedBackgroundColor
highlightedBackgroundColor = theme.itemHighlightedBackgroundColor
} else if item.index.pinningIndex != nil {
if case let .groupReference(_, _, _, _, hiddenByDefault) = item.content, hiddenByDefault {
backgroundColor = theme.itemBackgroundColor
highlightedBackgroundColor = theme.itemHighlightedBackgroundColor
} else {
backgroundColor = theme.pinnedItemBackgroundColor
highlightedBackgroundColor = theme.pinnedItemHighlightedBackgroundColor
}
} else {
backgroundColor = theme.itemBackgroundColor
highlightedBackgroundColor = theme.itemHighlightedBackgroundColor
}
if animated {
transition.updateBackgroundColor(node: strongSelf.backgroundNode, color: backgroundColor)
} else {
strongSelf.backgroundNode.backgroundColor = backgroundColor
}
strongSelf.highlightedBackgroundNode.backgroundColor = highlightedBackgroundColor
let topNegativeInset: CGFloat = 0.0
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: layoutOffset - separatorHeight - topNegativeInset), size: CGSize(width: layout.contentSize.width, height: layout.contentSize.height + separatorHeight + topNegativeInset))

View file

@ -426,14 +426,18 @@ public class CreatePollTextInputItemNode: ListViewItemNode, ASEditableTextNodeDe
public func editableTextNodeTarget(forAction action: Selector) -> ASEditableTextNodeTargetForAction? {
if action == makeSelectorFromString("_showTextStyleOptions:") {
if case .general = self.inputMenu.state {
if self.textNode.attributedText == nil || self.textNode.attributedText!.length == 0 || self.textNode.selectedRange.length == 0 {
return ASEditableTextNodeTargetForAction(target: nil)
}
return ASEditableTextNodeTargetForAction(target: self)
} else {
return ASEditableTextNodeTargetForAction(target: nil)
}
if #available(iOS 16.0, *) {
return ASEditableTextNodeTargetForAction(target: nil)
} else {
if case .general = self.inputMenu.state {
if self.textNode.attributedText == nil || self.textNode.attributedText!.length == 0 || self.textNode.selectedRange.length == 0 {
return ASEditableTextNodeTargetForAction(target: nil)
}
return ASEditableTextNodeTargetForAction(target: self)
} else {
return ASEditableTextNodeTargetForAction(target: nil)
}
}
} else if action == #selector(self.formatAttributesBold(_:)) || action == #selector(self.formatAttributesItalic(_:)) || action == #selector(self.formatAttributesMonospace(_:)) || action == #selector(self.formatAttributesLink(_:)) || action == #selector(self.formatAttributesStrikethrough(_:)) || action == #selector(self.formatAttributesUnderline(_:)) {
if case .format = self.inputMenu.state {
return ASEditableTextNodeTargetForAction(target: self)
@ -451,6 +455,58 @@ public class CreatePollTextInputItemNode: ListViewItemNode, ASEditableTextNodeDe
self.inputMenu.format(view: self.textNode.view, rect: self.textNode.selectionRect.offsetBy(dx: 0.0, dy: -self.textNode.textView.contentOffset.y).insetBy(dx: 0.0, dy: -1.0))
}
@available(iOS 16.0, *)
public func editableTextNodeMenu(_ editableTextNode: ASEditableTextNode, forTextRange textRange: NSRange, suggestedActions: [UIMenuElement]) -> UIMenu {
var actions = suggestedActions
if editableTextNode.attributedText == nil || editableTextNode.attributedText!.length == 0 || editableTextNode.selectedRange.length == 0 {
} else if let strings = self.item?.presentationData.strings {
let children: [UIAction] = [
UIAction(title: strings.TextFormat_Bold, image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesBold(strongSelf)
}
},
UIAction(title: strings.TextFormat_Italic, image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesItalic(strongSelf)
}
},
UIAction(title: strings.TextFormat_Monospace, image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesMonospace(strongSelf)
}
},
UIAction(title: strings.TextFormat_Link, image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesLink(strongSelf)
}
},
UIAction(title: strings.TextFormat_Strikethrough, image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesStrikethrough(strongSelf)
}
},
UIAction(title: strings.TextFormat_Underline, image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesUnderline(strongSelf)
}
},
UIAction(title: strings.TextFormat_Spoiler, image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesSpoiler(strongSelf)
}
}
]
let formatMenu = UIMenu(title: strings.TextFormat_Format, image: nil, children: children)
actions.insert(formatMenu, at: 3)
}
return UIMenu(children: actions)
}
@objc func formatAttributesBold(_ sender: Any) {
self.inputMenu.back()
if let item = self.item {
@ -491,6 +547,13 @@ public class CreatePollTextInputItemNode: ListViewItemNode, ASEditableTextNodeDe
}
}
@objc func formatAttributesSpoiler(_ sender: Any) {
self.inputMenu.back()
if let item = self.item {
chatTextInputAddFormattingAttribute(item: item, textNode: self.textNode, theme: item.presentationData.theme, attribute: ChatTextInputAttributes.spoiler)
}
}
public func editableTextNode(_ editableTextNode: ASEditableTextNode, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if let item = self.item {
if text.count > 1, let processPaste = item.processPaste {

View file

@ -158,7 +158,7 @@ open class NavigationController: UINavigationController, ContainableController,
private var globalOverlayContainerParent: GlobalOverlayContainerParent?
public var globalOverlayControllersUpdated: (() -> Void)?
private var validLayout: ContainerViewLayout?
public private(set) var validLayout: ContainerViewLayout?
private var validStatusBarStyle: NavigationStatusBarStyle?
private var validStatusBarHidden: Bool = false
@ -1309,6 +1309,18 @@ open class NavigationController: UINavigationController, ContainableController,
completion()
}
public func updateContainerPulled(_ pushed: Bool) {
guard self.modalContainers.isEmpty else {
return
}
if let rootContainer = self.rootContainer, case let .flat(container) = rootContainer {
let scale: CGFloat = pushed ? 1.06 : 1.0
container.view.layer.transform = CATransform3DMakeScale(scale, scale, 1.0)
container.view.layer.animateScale(from: pushed ? 1.0 : 1.06, to: scale, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
}
}
open override func pushViewController(_ viewController: UIViewController, animated: Bool) {
var controllers = self.viewControllers
controllers.append(viewController)

View file

@ -240,6 +240,8 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
super.init()
self.clipsToBounds = true
self.imageNode.imageUpdated = { [weak self] _ in
self?._ready.set(.single(Void()))
}
@ -290,6 +292,11 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
return self._ready.get()
}
override func screenFrameUpdated(_ frame: CGRect) {
let center = frame.midX - self.frame.width / 2.0
self.subnodeTransform = CATransform3DMakeTranslation(-center * 0.16, 0.0, 0.0)
}
override func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: transition)

View file

@ -814,6 +814,8 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
super.init()
self.clipsToBounds = true
self.moreBarButton.addTarget(self, action: #selector(self.moreButtonPressed), forControlEvents: .touchUpInside)
self.footerContentNode.interacting = { [weak self] value in
@ -966,6 +968,12 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
return self._ready.get()
}
override func screenFrameUpdated(_ frame: CGRect) {
let center = frame.midX - self.frame.width / 2.0
self.subnodeTransform = CATransform3DMakeTranslation(-center * 0.16, 0.0, 0.0)
}
override func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
if let _ = self.customUnembedWhenPortrait, layout.size.width < layout.size.height {
self.expandIntoCustomPiP()

View file

@ -465,7 +465,8 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
itemSeparatorColor: UIColor(rgb: 0x545458, alpha: 0.55),
itemBackgroundColor: UIColor(rgb: 0x000000),
pinnedItemBackgroundColor: UIColor(rgb: 0x1c1c1d),
itemHighlightedBackgroundColor: UIColor(rgb: 0x191919),
itemHighlightedBackgroundColor: UIColor(rgb: 0xffffff, alpha: 0.07),
pinnedItemHighlightedBackgroundColor: UIColor(rgb: 0xffffff, alpha: 0.07),
itemSelectedBackgroundColor: UIColor(rgb: 0x191919),
titleColor: UIColor(rgb: 0xffffff),
secretTitleColor: UIColor(rgb: 0x00b12c),

View file

@ -685,6 +685,7 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
itemBackgroundColor: additionalBackgroundColor,
pinnedItemBackgroundColor: mainBackgroundColor,
itemHighlightedBackgroundColor: mainSelectionColor,
pinnedItemHighlightedBackgroundColor: mainSelectionColor,
itemSelectedBackgroundColor: mainSelectionColor,
titleColor: UIColor(rgb: 0xffffff),
secretTitleColor: UIColor(rgb: 0x89df9e),

View file

@ -526,6 +526,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
itemBackgroundColor: UIColor(rgb: 0xffffff),
pinnedItemBackgroundColor: UIColor(rgb: 0xf7f7f7),
itemHighlightedBackgroundColor: UIColor(rgb: 0xe5e5ea),
pinnedItemHighlightedBackgroundColor: UIColor(rgb: 0xe5e5ea),
itemSelectedBackgroundColor: UIColor(rgb: 0xe9f0fa),
titleColor: UIColor(rgb: 0x000000),
secretTitleColor: UIColor(rgb: 0x00b12c),

View file

@ -561,6 +561,7 @@ public final class PresentationThemeChatList {
public let itemBackgroundColor: UIColor
public let pinnedItemBackgroundColor: UIColor
public let itemHighlightedBackgroundColor: UIColor
public let pinnedItemHighlightedBackgroundColor: UIColor
public let itemSelectedBackgroundColor: UIColor
public let titleColor: UIColor
public let secretTitleColor: UIColor
@ -597,6 +598,7 @@ public final class PresentationThemeChatList {
itemBackgroundColor: UIColor,
pinnedItemBackgroundColor: UIColor,
itemHighlightedBackgroundColor: UIColor,
pinnedItemHighlightedBackgroundColor: UIColor,
itemSelectedBackgroundColor: UIColor,
titleColor: UIColor,
secretTitleColor: UIColor,
@ -632,6 +634,7 @@ public final class PresentationThemeChatList {
self.itemBackgroundColor = itemBackgroundColor
self.pinnedItemBackgroundColor = pinnedItemBackgroundColor
self.itemHighlightedBackgroundColor = itemHighlightedBackgroundColor
self.pinnedItemHighlightedBackgroundColor = pinnedItemHighlightedBackgroundColor
self.itemSelectedBackgroundColor = itemSelectedBackgroundColor
self.titleColor = titleColor
self.secretTitleColor = secretTitleColor
@ -669,6 +672,7 @@ public final class PresentationThemeChatList {
itemBackgroundColor: UIColor? = nil,
pinnedItemBackgroundColor: UIColor? = nil,
itemHighlightedBackgroundColor: UIColor? = nil,
pinnedItemHighlightedBackgroundColor: UIColor? = nil,
itemSelectedBackgroundColor: UIColor? = nil,
titleColor: UIColor? = nil,
secretTitleColor: UIColor? = nil,
@ -705,6 +709,7 @@ public final class PresentationThemeChatList {
itemBackgroundColor: itemBackgroundColor ?? self.itemBackgroundColor,
pinnedItemBackgroundColor: pinnedItemBackgroundColor ?? self.pinnedItemBackgroundColor,
itemHighlightedBackgroundColor: itemHighlightedBackgroundColor ?? self.itemHighlightedBackgroundColor,
pinnedItemHighlightedBackgroundColor: pinnedItemHighlightedBackgroundColor ?? self.pinnedItemHighlightedBackgroundColor,
itemSelectedBackgroundColor: itemSelectedBackgroundColor ?? self.itemSelectedBackgroundColor,
titleColor: titleColor ?? self.titleColor,
secretTitleColor: secretTitleColor ?? self.secretTitleColor,

View file

@ -966,6 +966,7 @@ extension PresentationThemeChatList: Codable {
case itemBg
case pinnedItemBg
case itemHighlightedBg
case pinnedItemHighlightedBg
case itemSelectedBg
case title
case secretTitle
@ -1005,6 +1006,7 @@ extension PresentationThemeChatList: Codable {
itemBackgroundColor: try decodeColor(values, .itemBg),
pinnedItemBackgroundColor: try decodeColor(values, .pinnedItemBg),
itemHighlightedBackgroundColor: try decodeColor(values, .itemHighlightedBg),
pinnedItemHighlightedBackgroundColor: try decodeColor(values, .pinnedItemHighlightedBg, fallbackKey: "\(codingPath).itemHighlightedBg"),
itemSelectedBackgroundColor: try decodeColor(values, .itemSelectedBg),
titleColor: try decodeColor(values, .title),
secretTitleColor: try decodeColor(values, .secretTitle),

View file

@ -853,7 +853,43 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
}
adjustedBoundingSize.width = max(boundingWidth, adjustedBoundingSize.width)
var contentMediaHeight: CGFloat?
if let (contentImageSize, _) = contentImageSizeAndApply {
contentMediaHeight = contentImageSize.height
}
if let (contentFileSize, _) = contentFileSizeAndApply {
contentMediaHeight = contentFileSize.height
}
if let (videoLayout, _) = contentInstantVideoSizeAndApply {
contentMediaHeight = videoLayout.contentSize.height
}
var textVerticalOffset: CGFloat = 0.0
if let contentMediaHeight = contentMediaHeight, let (_, flags) = mediaAndFlags, flags.contains(.preferMediaBeforeText) {
textVerticalOffset = contentMediaHeight + 7.0
}
let adjustedTextFrame = textFrame.offsetBy(dx: 0.0, dy: textVerticalOffset)
var statusFrame: CGRect?
if let statusSizeAndApply = statusSizeAndApply {
var finalStatusFrame = CGRect(origin: CGPoint(x: adjustedTextFrame.minX, y: adjustedTextFrame.maxY), size: statusSizeAndApply.0)
if let imageFrame = imageFrame {
if finalStatusFrame.maxY < imageFrame.maxY + 10.0 {
finalStatusFrame.origin.y = max(finalStatusFrame.minY, imageFrame.maxY + 2.0)
if finalStatusFrame.height == 0.0 {
finalStatusFrame.origin.y += 14.0
adjustedBoundingSize.height += 14.0
adjustedLineHeight += 14.0
}
}
}
statusFrame = finalStatusFrame
}
return (adjustedBoundingSize, { [weak self] animation, synchronousLoads, applyInfo in
if let strongSelf = self {
strongSelf.context = context
@ -900,12 +936,8 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
} else if strongSelf.inlineImageNode.supernode != nil {
strongSelf.inlineImageNode.removeFromSupernode()
}
var contentMediaHeight: CGFloat?
if let (contentImageSize, contentImageApply) = contentImageSizeAndApply {
contentMediaHeight = contentImageSize.height
let contentImageNode = contentImageApply(animation, synchronousLoads)
if strongSelf.contentImageNode !== contentImageNode {
strongSelf.contentImageNode = contentImageNode
@ -960,8 +992,6 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
}
if let (contentFileSize, contentFileApply) = contentFileSizeAndApply {
contentMediaHeight = contentFileSize.height
let contentFileNode = contentFileApply(synchronousLoads, animation, applyInfo)
if strongSelf.contentFileNode !== contentFileNode {
strongSelf.contentFileNode = contentFileNode
@ -988,7 +1018,6 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
}
if let (videoLayout, apply) = contentInstantVideoSizeAndApply {
contentMediaHeight = videoLayout.contentSize.height
let contentInstantVideoNode = apply(.unconstrained(width: boundingWidth - insets.left - insets.right), animation)
if strongSelf.contentInstantVideoNode !== contentInstantVideoNode {
strongSelf.contentInstantVideoNode = contentInstantVideoNode
@ -1003,23 +1032,9 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
contentInstantVideoNode.removeFromSupernode()
strongSelf.contentInstantVideoNode = nil
}
var textVerticalOffset: CGFloat = 0.0
if let contentMediaHeight = contentMediaHeight, let (_, flags) = mediaAndFlags, flags.contains(.preferMediaBeforeText) {
textVerticalOffset = contentMediaHeight + 7.0
}
strongSelf.textNode.textNode.frame = textFrame.offsetBy(dx: 0.0, dy: textVerticalOffset)
if let statusSizeAndApply = statusSizeAndApply {
var statusFrame = CGRect(origin: CGPoint(x: strongSelf.textNode.textNode.frame.minX, y: strongSelf.textNode.textNode.frame.maxY), size: statusSizeAndApply.0)
if let imageFrame = imageFrame {
if statusFrame.maxY < imageFrame.maxY + 10.0 {
statusFrame.origin.y = max(statusFrame.minY, imageFrame.maxY + 2.0)
if statusFrame.height == 0.0 {
statusFrame.origin.y += 14.0
}
}
}
strongSelf.textNode.textNode.frame = adjustedTextFrame
if let statusSizeAndApply = statusSizeAndApply, let statusFrame = statusFrame {
if strongSelf.statusNode.supernode == nil {
strongSelf.addSubnode(strongSelf.statusNode)
strongSelf.statusNode.frame = statusFrame

View file

@ -2997,13 +2997,17 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
else if action == makeSelectorFromString("_accessibilitySpeakLanguageSelection:") || action == makeSelectorFromString("_accessibilityPauseSpeaking:") || action == makeSelectorFromString("_accessibilitySpeakSentence:") {
return ASEditableTextNodeTargetForAction(target: nil)
} else if action == makeSelectorFromString("_showTextStyleOptions:") {
if case .general = self.inputMenu.state {
if let textInputNode = self.textInputNode, textInputNode.attributedText == nil || textInputNode.attributedText!.length == 0 || textInputNode.selectedRange.length == 0 {
if #available(iOS 16.0, *) {
return ASEditableTextNodeTargetForAction(target: nil)
} else {
if case .general = self.inputMenu.state {
if let textInputNode = self.textInputNode, textInputNode.attributedText == nil || textInputNode.attributedText!.length == 0 || textInputNode.selectedRange.length == 0 {
return ASEditableTextNodeTargetForAction(target: nil)
}
return ASEditableTextNodeTargetForAction(target: self)
} else {
return ASEditableTextNodeTargetForAction(target: nil)
}
return ASEditableTextNodeTargetForAction(target: self)
} else {
return ASEditableTextNodeTargetForAction(target: nil)
}
} else if action == #selector(self.formatAttributesBold(_:)) || action == #selector(self.formatAttributesItalic(_:)) || action == #selector(self.formatAttributesMonospace(_:)) || action == #selector(self.formatAttributesLink(_:)) || action == #selector(self.formatAttributesStrikethrough(_:)) || action == #selector(self.formatAttributesUnderline(_:)) || action == #selector(self.formatAttributesSpoiler(_:)) {
if case .format = self.inputMenu.state {
@ -3044,6 +3048,65 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
return nil
}
@available(iOS 16.0, *)
func editableTextNodeMenu(_ editableTextNode: ASEditableTextNode, forTextRange textRange: NSRange, suggestedActions: [UIMenuElement]) -> UIMenu {
var actions = suggestedActions
if editableTextNode.attributedText == nil || editableTextNode.attributedText!.length == 0 || editableTextNode.selectedRange.length == 0 {
} else {
var children: [UIAction] = [
UIAction(title: self.strings?.TextFormat_Bold ?? "Bold", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesBold(strongSelf)
}
},
UIAction(title: self.strings?.TextFormat_Italic ?? "Italic", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesItalic(strongSelf)
}
},
UIAction(title: self.strings?.TextFormat_Monospace ?? "Monospace", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesMonospace(strongSelf)
}
},
UIAction(title: self.strings?.TextFormat_Link ?? "Link", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesLink(strongSelf)
}
},
UIAction(title: self.strings?.TextFormat_Strikethrough ?? "Strikethrough", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesStrikethrough(strongSelf)
}
},
UIAction(title: self.strings?.TextFormat_Underline ?? "Underline", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesUnderline(strongSelf)
}
}
]
var hasSpoilers = true
if self.presentationInterfaceState?.chatLocation.peerId?.namespace == Namespaces.Peer.SecretChat {
hasSpoilers = false
}
if hasSpoilers {
children.append(UIAction(title: self.strings?.TextFormat_Spoiler ?? "Spoiler", image: nil) { [weak self] (action) in
if let strongSelf = self {
strongSelf.formatAttributesSpoiler(strongSelf)
}
})
}
let formatMenu = UIMenu(title: self.strings?.TextFormat_Format ?? "Format", image: nil, children: children)
actions.insert(formatMenu, at: 3)
}
return UIMenu(children: actions)
}
@objc func _accessibilitySpeak(_ sender: Any) {
var text = ""
self.interfaceInteraction?.updateTextInputStateAndMode { current, inputMode in

View file

@ -745,7 +745,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
transition.updateAlpha(node: self.coveringBackgroundNode, alpha: expansionFraction)
self.backgroundColor = presentationData.theme.list.itemBlocksBackgroundColor
self.backgroundColor = presentationData.theme.list.plainBackgroundColor
self.coveringBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.opaqueBackgroundColor, transition: .immediate)
self.separatorNode.backgroundColor = presentationData.theme.list.itemBlocksSeparatorColor
self.tabsSeparatorNode.backgroundColor = presentationData.theme.list.itemBlocksSeparatorColor