diff --git a/submodules/InviteLinksUI/Sources/InviteLinkQRCodeController.swift b/submodules/InviteLinksUI/Sources/InviteLinkQRCodeController.swift index bc25d13400..b98ee3789a 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkQRCodeController.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkQRCodeController.swift @@ -24,10 +24,9 @@ private func shareQrCode(context: AccountContext, link: String, view: UIView) { } let activityController = UIActivityViewController(activityItems: [image], applicationActivities: nil) - if let window = view.window, let rootViewController = window.rootViewController { + if let window = view.window { activityController.popoverPresentationController?.sourceView = window activityController.popoverPresentationController?.sourceRect = CGRect(origin: CGPoint(x: window.bounds.width / 2.0, y: window.bounds.size.height - 1.0), size: CGSize(width: 1.0, height: 1.0)) - rootViewController.present(activityController, animated: true, completion: nil) } context.sharedContext.applicationBindings.presentNativeController(activityController) }) diff --git a/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift b/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift index a02f5c4fd1..c44e07caa6 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift @@ -575,7 +575,7 @@ public final class InviteLinkViewController: ViewController { let subtitle: String let subtitleExpired: Bool if let usageLimit = invite.usageLimit { - let remaining = usageLimit - state.count + let remaining = max(0, usageLimit - state.count) subtitle = presentationData.strings.InviteLink_PeopleRemaining(remaining).uppercased() subtitleExpired = remaining <= 0 } else { diff --git a/submodules/TelegramCore/Sources/ApiGroupOrChannel.swift b/submodules/TelegramCore/Sources/ApiGroupOrChannel.swift index 52821a2f2c..281b43981c 100644 --- a/submodules/TelegramCore/Sources/ApiGroupOrChannel.swift +++ b/submodules/TelegramCore/Sources/ApiGroupOrChannel.swift @@ -200,6 +200,9 @@ func mergeChannel(lhs: TelegramChannel?, rhs: TelegramChannel) -> TelegramChanne } var channelFlags = lhs.flags + if rhs.flags.contains(.isGigagroup) { + channelFlags.insert(.isGigagroup) + } if rhs.flags.contains(.isVerified) { channelFlags.insert(.isVerified) } else { diff --git a/submodules/TelegramUI/BUILD b/submodules/TelegramUI/BUILD index ec6c098d39..cb39ede213 100644 --- a/submodules/TelegramUI/BUILD +++ b/submodules/TelegramUI/BUILD @@ -217,6 +217,7 @@ swift_library( "//submodules/ChatHistoryImportTasks:ChatHistoryImportTasks", "//submodules/DatePickerNode:DatePickerNode", "//submodules/ConfettiEffect:ConfettiEffect", + "//submodules/Speak:Speak", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index cbc6d1d22d..7dad6971f0 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -1,4 +1,3 @@ - import Foundation import UIKit import Postbox @@ -64,6 +63,7 @@ import InviteLinksUI import ChatHistoryImportTasks import Markdown import TelegramPermissionsUI +import Speak extension ChatLocation { var peerId: PeerId { @@ -2286,7 +2286,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G window.rootViewController?.present(controller, animated: true) } case .speak: - strongSelf.speakText(text.string) + speakText(text.string) } }, updateMessageLike: { [weak self] messageId, isLiked in guard let strongSelf = self else { @@ -12181,15 +12181,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return false } } - - private func speakText(_ text: String) { - let speechSynthesizer = AVSpeechSynthesizer() - let utterance = AVSpeechUtterance(string: text) - if #available(iOS 11.0, *), let language = NSLinguisticTagger.dominantLanguage(for: text) { - utterance.voice = AVSpeechSynthesisVoice(language: language) - } - speechSynthesizer.speak(utterance) - } } private final class ContextControllerContentSourceImpl: ContextControllerContentSource { diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index a18fc581af..c8fa228555 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -14,6 +14,7 @@ import TouchDownGesture import ImageTransparency import ActivityIndicator import AnimationUI +import Speak private let accessoryButtonFont = Font.medium(14.0) private let counterFont = Font.with(size: 14.0, design: .regular, traits: [.monospacedNumbers]) @@ -1775,7 +1776,18 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { } func editableTextNodeTarget(forAction action: Selector) -> ASEditableTextNodeTargetForAction? { - if action == Selector(("_showTextStyleOptions:")) { + if action == Selector(("_accessibilitySpeak:")) { + if let textInputNode = self.textInputNode, textInputNode.selectedRange.length > 0 { + return ASEditableTextNodeTargetForAction(target: self) + } else { + return ASEditableTextNodeTargetForAction(target: nil) + } + } else if action == Selector("_accessibilitySpeakLanguageSelection:") { + return ASEditableTextNodeTargetForAction(target: nil) + } else if action == Selector("_accessibilityPauseSpeaking:") { + return ASEditableTextNodeTargetForAction(target: nil) + } + else if action == Selector(("_showTextStyleOptions:")) { 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) @@ -1797,6 +1809,15 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { return nil } + @objc func _accessibilitySpeak(_ sender: Any) { + var text = "" + self.interfaceInteraction?.updateTextInputStateAndMode { current, inputMode in + text = current.inputText.attributedSubstring(from: NSMakeRange(current.selectionRange.lowerBound, current.selectionRange.count)).string + return (current, inputMode) + } + speakText(text) + } + @objc func _showTextStyleOptions(_ sender: Any) { if let textInputNode = self.textInputNode { self.inputMenu.format(view: textInputNode.view, rect: textInputNode.selectionRect.offsetBy(dx: 0.0, dy: -textInputNode.textView.contentOffset.y).insetBy(dx: 0.0, dy: -1.0))