Various improvements

This commit is contained in:
Ali 2023-10-29 20:30:26 +04:00
parent bbb543f836
commit 34bd339d8c
10 changed files with 108 additions and 17 deletions

View File

@ -1473,7 +1473,7 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
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(_:)) {
} 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(_:)) || action == #selector(self.formatAttributesQuote(_:)) {
if case .format = self.inputMenu.state {
return ASEditableTextNodeTargetForAction(target: self)
} else {
@ -1646,6 +1646,14 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
self.updateSpoilersRevealed(animated: animated)
}
@objc func formatAttributesQuote(_ sender: Any) {
self.inputMenu.back()
self.interfaceInteraction?.updateTextInputStateAndMode { current, inputMode in
return (chatTextInputAddFormattingAttribute(current, attribute: ChatTextInputAttributes.quote), inputMode)
}
}
public func chatInputTextNode(shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
guard let editableTextNode = self.textInputNode else {
return true
@ -1728,6 +1736,10 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
return true
}
public func chatInputTextNodeTargetForAction(action: Selector) -> ChatInputTextNode.TargetForAction? {
return nil
}
@objc public func editableTextNodeShouldPaste(_ editableTextNode: ASEditableTextNode) -> Bool {
return self.chatInputTextNodeShouldPaste()
}

View File

@ -554,6 +554,13 @@ public class CreatePollTextInputItemNode: ListViewItemNode, ASEditableTextNodeDe
}
}
@objc func formatAttributesQuote(_ sender: Any) {
self.inputMenu.back()
if let item = self.item {
chatTextInputAddFormattingAttribute(item: item, textNode: self.textNode, theme: item.presentationData.theme, attribute: ChatTextInputAttributes.quote)
}
}
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

@ -947,7 +947,11 @@ public final class TextNodeLayout: NSObject {
rects.append((lineFrame, CGRect(origin: CGPoint(x: lineFrame.minX + min(leftOffset, rightOffset) + self.insets.left, y: lineFrame.minY + self.insets.top), size: CGSize(width: width, height: lineFrame.size.height))))
}
}
if !rects.isEmpty, let startEdge = startEdge, let endEdge = endEdge {
if !rects.isEmpty, var startEdge = startEdge, var endEdge = endEdge {
startEdge.x += self.insets.left
startEdge.y += self.insets.top
endEdge.x += self.insets.left
endEdge.y += self.insets.top
return (rects.map { $1 }, startEdge, endEdge)
}
return nil

View File

@ -17,6 +17,7 @@
@property (nonatomic, copy) bool (^ _Nullable shouldCopy)();
@property (nonatomic, copy) bool (^ _Nullable shouldPaste)();
@property (nonatomic, copy) bool (^ _Nullable shouldRespondToAction)(SEL _Nullable);
@property (nonatomic, copy) ChatInputTextViewImplTargetForAction * _Nullable (^ _Nullable targetForAction)(SEL _Nullable);
@property (nonatomic, copy) bool (^ _Nullable shouldReturn)();
@property (nonatomic, copy) void (^ _Nullable backspaceWhileEmpty)();
@property (nonatomic, copy) void (^ _Nullable dropAutocorrectioniOS16)();

View File

@ -68,6 +68,13 @@
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (_targetForAction) {
ChatInputTextViewImplTargetForAction *result = _targetForAction(action);
if (result) {
return result.target != nil;
}
}
if (_shouldRespondToAction) {
if (!_shouldRespondToAction(action)) {
return false;
@ -102,6 +109,13 @@
}
- (id)targetForAction:(SEL)action withSender:(id)__unused sender {
if (_targetForAction) {
ChatInputTextViewImplTargetForAction *result = _targetForAction(action);
if (result) {
return result.target;
}
}
return [super targetForAction:action withSender:sender];
}

View File

@ -22,9 +22,18 @@ public protocol ChatInputTextNodeDelegate: AnyObject {
func chatInputTextNodeShouldPaste() -> Bool
func chatInputTextNodeShouldRespondToAction(action: Selector) -> Bool
func chatInputTextNodeTargetForAction(action: Selector) -> ChatInputTextNode.TargetForAction?
}
open class ChatInputTextNode: ASDisplayNode, UITextViewDelegate {
public final class TargetForAction {
public let target: Any?
public init(target: Any?) {
self.target = target
}
}
public weak var delegate: ChatInputTextNodeDelegate? {
didSet {
self.textView.customDelegate = self.delegate
@ -124,6 +133,18 @@ open class ChatInputTextNode: ASDisplayNode, UITextViewDelegate {
return true
}
}
self.textView.targetForAction = { [weak self] action in
guard let self, let action else {
return nil
}
if let delegate = self.delegate {
return delegate.chatInputTextNodeTargetForAction(action: action).flatMap { value in
return ChatInputTextViewImplTargetForAction(target: value.target)
}
} else {
return nil
}
}
}
public func resetInitialPrimaryLanguage() {

View File

@ -267,6 +267,31 @@ public class ShareRootControllerImpl {
let accountManager = AccountManager<TelegramAccountManagerTypes>(basePath: rootPath + "/accounts-metadata", isTemporary: true, isReadOnly: false, useCaches: false, removeDatabaseOnError: false)
initializeAccountManagement()
do {
let semaphore = DispatchSemaphore(value: 0)
var loggingSettings = LoggingSettings.defaultSettings
if self.initializationData.appBuildType == .internal {
loggingSettings = LoggingSettings(logToFile: true, logToConsole: false, redactSensitiveData: true)
}
let _ = (accountManager.transaction { transaction -> LoggingSettings? in
if let value = transaction.getSharedData(SharedDataKeys.loggingSettings)?.get(LoggingSettings.self) {
return value
} else {
return nil
}
}).start(next: { value in
if let value {
loggingSettings = value
}
semaphore.signal()
})
semaphore.wait()
Logger.shared.logToFile = loggingSettings.logToFile
Logger.shared.logToConsole = loggingSettings.logToConsole
Logger.shared.redactSensitiveData = loggingSettings.redactSensitiveData
}
var initialPresentationDataAndSettings: InitialPresentationDataAndSettings?
let semaphore = DispatchSemaphore(value: 0)
let systemUserInterfaceStyle: WindowUserInterfaceStyle
@ -306,7 +331,6 @@ public class ShareRootControllerImpl {
|> mapToSignal { sharedContext, loggingSettings -> Signal<(SharedAccountContextImpl, Account, [AccountWithInfo]), ShareAuthorizationError> in
Logger.shared.logToFile = loggingSettings.logToFile
Logger.shared.logToConsole = loggingSettings.logToConsole
Logger.shared.redactSensitiveData = loggingSettings.redactSensitiveData
return combineLatest(sharedContext.activeAccountsWithInfo, accountManager.transaction { transaction -> (Set<AccountRecordId>, PeerId?) in

View File

@ -772,10 +772,12 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
self.textInputViewInternalInsets = UIEdgeInsets(top: 1.0, left: 13.0, bottom: 1.0, right: 13.0)
var hasSpoilers = true
var hasQuotes = true
if presentationInterfaceState.chatLocation.peerId?.namespace == Namespaces.Peer.SecretChat {
hasSpoilers = false
hasQuotes = false
}
self.inputMenu = TextInputMenu(hasSpoilers: hasSpoilers)
self.inputMenu = TextInputMenu(hasSpoilers: hasSpoilers, hasQuotes: hasQuotes)
self.clippingNode = ASDisplayNode()
self.clippingNode.clipsToBounds = true
@ -3954,18 +3956,17 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
}
public func chatInputTextNodeShouldRespondToAction(action: Selector) -> Bool {
guard let textInputNode = self.textInputNode else {
return true
}
let _ = textInputNode
/*if textInputNode.attributedText == nil || textInputNode.attributedText!.length == 0 || textInputNode.selectedRange.length == 0 {
print("action: \(action)")
}*/
return true
}
public func chatInputTextNodeTargetForAction(action: Selector) -> ChatInputTextNode.TargetForAction? {
if let target = self.editableTextNodeTarget(forAction: action) {
return ChatInputTextNode.TargetForAction(target: target.target)
} else {
return nil
}
}
func chatInputTextNodeShouldPaste() -> Bool {
let pasteboard = UIPasteboard.general

View File

@ -16,8 +16,10 @@ public final class TextInputMenu {
private var stringStrikethrough: String = "Strikethrough"
private var stringUnderline: String = "Underline"
private var stringSpoiler: String = "Spoiler"
private var stringQuote: String = "Quote"
private let hasSpoilers: Bool
private let hasQuotes: Bool
public private(set) var state: State = .inactive {
didSet {
@ -39,6 +41,9 @@ public final class TextInputMenu {
if self.hasSpoilers {
menuItems.insert(UIMenuItem(title: self.stringSpoiler, action: Selector(("formatAttributesSpoiler:"))), at: 0)
}
if self.hasQuotes {
menuItems.insert(UIMenuItem(title: self.stringQuote, action: Selector(("formatAttributesQuote:"))), at: 0)
}
UIMenuController.shared.menuItems = menuItems
}
@ -48,8 +53,9 @@ public final class TextInputMenu {
private var observer: NSObjectProtocol?
public init(hasSpoilers: Bool = false) {
public init(hasSpoilers: Bool = false, hasQuotes: Bool = false) {
self.hasSpoilers = hasSpoilers
self.hasQuotes = hasQuotes
self.observer = NotificationCenter.default.addObserver(forName: UIMenuController.didHideMenuNotification, object: nil, queue: nil, using: { [weak self] _ in
self?.back()
})
@ -69,6 +75,7 @@ public final class TextInputMenu {
self.stringStrikethrough = strings.TextFormat_Strikethrough
self.stringUnderline = strings.TextFormat_Underline
self.stringSpoiler = strings.TextFormat_Spoiler
self.stringQuote = strings.TextFormat_Quote
}
public func activate() {

View File

@ -589,7 +589,7 @@ public final class TextSelectionNode: ASDisplayNode {
highlightOverlay.innerRadius = 2.0
highlightOverlay.outerRadius = 2.0
highlightOverlay.inset = 1.0
highlightOverlay.useModernPathCalculation = true
highlightOverlay.useModernPathCalculation = false
self.highlightOverlay = highlightOverlay
self.highlightAreaNode.addSubnode(highlightOverlay)
@ -597,8 +597,8 @@ public final class TextSelectionNode: ASDisplayNode {
highlightOverlay.frame = self.bounds
highlightOverlay.updateRects(rects)
if let image = self.leftKnob.image {
self.leftKnob.frame = CGRect(origin: CGPoint(x: floor(startEdge.x - image.size.width / 2.0), y: startEdge.y + 1.0 - 12.0), size: CGSize(width: image.size.width, height: self.theme.knobDiameter + startEdge.height + 2.0))
self.rightKnob.frame = CGRect(origin: CGPoint(x: floor(endEdge.x + 1.0 - image.size.width / 2.0), y: endEdge.y + endEdge.height + 3.0 - (endEdge.height + 2.0)), size: CGSize(width: image.size.width, height: self.theme.knobDiameter + endEdge.height + 2.0))
self.leftKnob.frame = CGRect(origin: CGPoint(x: floor(startEdge.x - image.size.width / 2.0), y: startEdge.y - self.theme.knobDiameter), size: CGSize(width: image.size.width, height: self.theme.knobDiameter + startEdge.height))
self.rightKnob.frame = CGRect(origin: CGPoint(x: floor(endEdge.x - image.size.width / 2.0), y: endEdge.y), size: CGSize(width: image.size.width, height: self.theme.knobDiameter + endEdge.height))
}
if self.leftKnob.alpha.isZero {
highlightOverlay.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue)