mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Add translation API
This commit is contained in:
parent
b618777883
commit
4c36a2172f
@ -1046,9 +1046,10 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
})]
|
})]
|
||||||
|
|
||||||
if canTranslateText(context: context, text: text, showTranslate: translationSettings.showTranslate, ignoredLanguages: translationSettings.ignoredLanguages) {
|
let (canTranslate, language) = canTranslateText(context: context, text: text, showTranslate: translationSettings.showTranslate, ignoredLanguages: translationSettings.ignoredLanguages)
|
||||||
|
if canTranslate {
|
||||||
actions.append(ContextMenuAction(content: .text(title: strings.Conversation_ContextMenuTranslate, accessibilityLabel: strings.Conversation_ContextMenuTranslate), action: {
|
actions.append(ContextMenuAction(content: .text(title: strings.Conversation_ContextMenuTranslate, accessibilityLabel: strings.Conversation_ContextMenuTranslate), action: {
|
||||||
translateText(context: context, text: text)
|
translateText(context: context, text: text, fromLang: language)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,5 +313,9 @@ public extension TelegramEngine {
|
|||||||
public func messageReactionList(message: EngineMessage, reaction: String?) -> EngineMessageReactionListContext {
|
public func messageReactionList(message: EngineMessage, reaction: String?) -> EngineMessageReactionListContext {
|
||||||
return EngineMessageReactionListContext(account: self.account, message: message, reaction: reaction)
|
return EngineMessageReactionListContext(account: self.account, message: message, reaction: reaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func translate(text: String, fromLang: String?, toLang: String) -> Signal<String?, NoError> {
|
||||||
|
return _internal_translate(network: self.account.network, text: text, fromLang: fromLang, toLang: toLang)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
import Foundation
|
||||||
|
import Postbox
|
||||||
|
import SwiftSignalKit
|
||||||
|
import TelegramApi
|
||||||
|
import MtProtoKit
|
||||||
|
|
||||||
|
func _internal_translate(network: Network, text: String, fromLang: String?, toLang: String) -> Signal<String?, NoError> {
|
||||||
|
var flags: Int32 = 0
|
||||||
|
flags |= 1
|
||||||
|
if let _ = fromLang {
|
||||||
|
flags |= 2
|
||||||
|
}
|
||||||
|
|
||||||
|
return network.request(Api.functions.messages.translateText(flags: flags, peer: nil, msgId: nil, text: text, fromLang: fromLang, toLang: toLang))
|
||||||
|
|> map(Optional.init)
|
||||||
|
|> `catch` { _ -> Signal<Api.messages.TranslatedText?, NoError> in
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
|> mapToSignal { result -> Signal<String?, NoError> in
|
||||||
|
guard let result = result else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
switch result {
|
||||||
|
case .translateNoResult:
|
||||||
|
return .single(nil)
|
||||||
|
case let .translateResultText(text):
|
||||||
|
return .single(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2920,7 +2920,20 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
case .speak:
|
case .speak:
|
||||||
speakText(text.string)
|
speakText(text.string)
|
||||||
case .translate:
|
case .translate:
|
||||||
translateText(context: context, text: text.string)
|
let _ = (context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.translationSettings])
|
||||||
|
|> take(1)
|
||||||
|
|> deliverOnMainQueue).start(next: { sharedData in
|
||||||
|
let translationSettings: TranslationSettings
|
||||||
|
if let current = sharedData.entries[ApplicationSpecificSharedDataKeys.translationSettings]?.get(TranslationSettings.self) {
|
||||||
|
translationSettings = current
|
||||||
|
} else {
|
||||||
|
translationSettings = TranslationSettings.defaultSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
let (_, language) = canTranslateText(context: context, text: text.string, showTranslate: translationSettings.showTranslate, ignoredLanguages: translationSettings.ignoredLanguages)
|
||||||
|
|
||||||
|
translateText(context: context, text: text.string, fromLang: language)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}, displayImportedMessageTooltip: { [weak self] _ in
|
}, displayImportedMessageTooltip: { [weak self] _ in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
|
@ -819,7 +819,8 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
|||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
if canTranslateText(context: context, text: messageText, showTranslate: translationSettings.showTranslate, ignoredLanguages: translationSettings.ignoredLanguages) {
|
let (canTranslate, _) = canTranslateText(context: context, text: messageText, showTranslate: translationSettings.showTranslate, ignoredLanguages: translationSettings.ignoredLanguages)
|
||||||
|
if canTranslate {
|
||||||
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuTranslate, icon: { theme in
|
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuTranslate, icon: { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Translate"), color: theme.actionSheet.primaryTextColor)
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Translate"), color: theme.actionSheet.primaryTextColor)
|
||||||
}, action: { _, f in
|
}, action: { _, f in
|
||||||
|
@ -4977,10 +4977,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_TextCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_TextCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
||||||
})]
|
})]
|
||||||
|
|
||||||
|
let (canTranslate, language) = canTranslateText(context: context, text: text, showTranslate: translationSettings.showTranslate, ignoredLanguages: translationSettings.ignoredLanguages)
|
||||||
if canTranslateText(context: context, text: text, showTranslate: translationSettings.showTranslate, ignoredLanguages: translationSettings.ignoredLanguages) {
|
if canTranslate {
|
||||||
actions.append(ContextMenuAction(content: .text(title: presentationData.strings.Conversation_ContextMenuTranslate, accessibilityLabel: presentationData.strings.Conversation_ContextMenuTranslate), action: {
|
actions.append(ContextMenuAction(content: .text(title: presentationData.strings.Conversation_ContextMenuTranslate, accessibilityLabel: presentationData.strings.Conversation_ContextMenuTranslate), action: {
|
||||||
translateText(context: context, text: text)
|
translateText(context: context, text: text, fromLang: language)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import UIKit
|
|||||||
import Display
|
import Display
|
||||||
import AccountContext
|
import AccountContext
|
||||||
import NaturalLanguage
|
import NaturalLanguage
|
||||||
|
import TelegramCore
|
||||||
|
|
||||||
// Incuding at least one Objective-C class in a swift file ensures that it doesn't get stripped by the linker
|
// Incuding at least one Objective-C class in a swift file ensures that it doesn't get stripped by the linker
|
||||||
private final class LinkHelperClass: NSObject {
|
private final class LinkHelperClass: NSObject {
|
||||||
@ -26,9 +27,9 @@ public var supportedTranslationLanguages = [
|
|||||||
@available(iOS 12.0, *)
|
@available(iOS 12.0, *)
|
||||||
private let languageRecognizer = NLLanguageRecognizer()
|
private let languageRecognizer = NLLanguageRecognizer()
|
||||||
|
|
||||||
public func canTranslateText(context: AccountContext, text: String, showTranslate: Bool, ignoredLanguages: [String]?) -> Bool {
|
public func canTranslateText(context: AccountContext, text: String, showTranslate: Bool, ignoredLanguages: [String]?) -> (canTranslate: Bool, language: String?) {
|
||||||
guard showTranslate, text.count > 0 else {
|
guard showTranslate, text.count > 0 else {
|
||||||
return false
|
return (false, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if #available(iOS 15.0, *) {
|
if #available(iOS 15.0, *) {
|
||||||
@ -46,16 +47,16 @@ public func canTranslateText(context: AccountContext, text: String, showTranslat
|
|||||||
|
|
||||||
let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains($0.key.rawValue) }.sorted(by: { $0.value > $1.value })
|
let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains($0.key.rawValue) }.sorted(by: { $0.value > $1.value })
|
||||||
if let language = filteredLanguages.first(where: { supportedTranslationLanguages.contains($0.key.rawValue) }) {
|
if let language = filteredLanguages.first(where: { supportedTranslationLanguages.contains($0.key.rawValue) }) {
|
||||||
return !dontTranslateLanguages.contains(language.key.rawValue)
|
return (!dontTranslateLanguages.contains(language.key.rawValue), language.key.rawValue)
|
||||||
} else {
|
} else {
|
||||||
return false
|
return (false, nil)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false
|
return (false, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func translateText(context: AccountContext, text: String) {
|
public func translateText(context: AccountContext, text: String, fromLang: String? = nil) {
|
||||||
guard !text.isEmpty else {
|
guard !text.isEmpty else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -74,5 +75,8 @@ public func translateText(context: AccountContext, text: String) {
|
|||||||
textView.removeFromSuperview()
|
textView.removeFromSuperview()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let toLang = context.sharedContext.currentPresentationData.with { $0 }.strings.baseLanguageCode
|
||||||
|
let _ = context.engine.messages.translate(text: text, fromLang: fromLang, toLang: toLang).start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user