mirror of
git://jb55.com/damus
synced 2024-09-18 19:23:49 +00:00
Add translate.nostr.wine to available translation services
Closes: https://github.com/damus-io/damus/pull/1113 Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
parent
a58ca2918a
commit
957ac1dc03
@ -32,6 +32,7 @@ enum TranslationService: String, CaseIterable, Identifiable, StringCodable {
|
|||||||
case libretranslate
|
case libretranslate
|
||||||
case deepl
|
case deepl
|
||||||
case nokyctranslate
|
case nokyctranslate
|
||||||
|
case winetranslate
|
||||||
|
|
||||||
var model: Model {
|
var model: Model {
|
||||||
switch self {
|
switch self {
|
||||||
@ -43,6 +44,8 @@ enum TranslationService: String, CaseIterable, Identifiable, StringCodable {
|
|||||||
return .init(tag: self.rawValue, displayName: NSLocalizedString("DeepL (Proprietary, Higher Accuracy)", comment: "Dropdown option for selecting DeepL as the translation service."))
|
return .init(tag: self.rawValue, displayName: NSLocalizedString("DeepL (Proprietary, Higher Accuracy)", comment: "Dropdown option for selecting DeepL as the translation service."))
|
||||||
case .nokyctranslate:
|
case .nokyctranslate:
|
||||||
return .init(tag: self.rawValue, displayName: NSLocalizedString("NoKYCTranslate.com (Prepay with BTC)", comment: "Dropdown option for selecting NoKYCTranslate.com as the translation service."))
|
return .init(tag: self.rawValue, displayName: NSLocalizedString("NoKYCTranslate.com (Prepay with BTC)", comment: "Dropdown option for selecting NoKYCTranslate.com as the translation service."))
|
||||||
|
case .winetranslate:
|
||||||
|
return .init(tag: self.rawValue, displayName: NSLocalizedString("translate.nostr.wine (DeepL, Pay with BTC)", comment: "Dropdown option for selecting translate.nostr.wine as the translation service."))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,6 +244,15 @@ class UserSettingsStore: ObservableObject {
|
|||||||
internal_nokyctranslate_api_key = newValue == "" ? nil : newValue
|
internal_nokyctranslate_api_key = newValue == "" ? nil : newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var winetranslate_api_key: String {
|
||||||
|
get {
|
||||||
|
return internal_winetranslate_api_key ?? ""
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
internal_winetranslate_api_key = newValue == "" ? nil : newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// These internal keys are necessary because entries in the keychain need to be Optional,
|
// These internal keys are necessary because entries in the keychain need to be Optional,
|
||||||
// but the translation view needs non-Optional String in order to use them as Bindings.
|
// but the translation view needs non-Optional String in order to use them as Bindings.
|
||||||
@ -252,6 +261,9 @@ class UserSettingsStore: ObservableObject {
|
|||||||
|
|
||||||
@KeychainStorage(account: "nokyctranslate_apikey")
|
@KeychainStorage(account: "nokyctranslate_apikey")
|
||||||
var internal_nokyctranslate_api_key: String?
|
var internal_nokyctranslate_api_key: String?
|
||||||
|
|
||||||
|
@KeychainStorage(account: "winetranslate_apikey")
|
||||||
|
var internal_winetranslate_api_key: String?
|
||||||
|
|
||||||
@KeychainStorage(account: "libretranslate_apikey")
|
@KeychainStorage(account: "libretranslate_apikey")
|
||||||
var internal_libretranslate_api_key: String?
|
var internal_libretranslate_api_key: String?
|
||||||
@ -269,6 +281,8 @@ class UserSettingsStore: ObservableObject {
|
|||||||
return internal_deepl_api_key != nil
|
return internal_deepl_api_key != nil
|
||||||
case .nokyctranslate:
|
case .nokyctranslate:
|
||||||
return internal_nokyctranslate_api_key != nil
|
return internal_nokyctranslate_api_key != nil
|
||||||
|
case .winetranslate:
|
||||||
|
return internal_winetranslate_api_key != nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,8 @@ public struct Translator {
|
|||||||
return try await translateWithLibreTranslate(text, from: sourceLanguage, to: targetLanguage)
|
return try await translateWithLibreTranslate(text, from: sourceLanguage, to: targetLanguage)
|
||||||
case .nokyctranslate:
|
case .nokyctranslate:
|
||||||
return try await translateWithNoKYCTranslate(text, from: sourceLanguage, to: targetLanguage)
|
return try await translateWithNoKYCTranslate(text, from: sourceLanguage, to: targetLanguage)
|
||||||
|
case .winetranslate:
|
||||||
|
return try await translateWithWineTranslate(text, from: sourceLanguage, to: targetLanguage)
|
||||||
case .deepl:
|
case .deepl:
|
||||||
return try await translateWithDeepL(text, from: sourceLanguage, to: targetLanguage)
|
return try await translateWithDeepL(text, from: sourceLanguage, to: targetLanguage)
|
||||||
case .none:
|
case .none:
|
||||||
@ -111,6 +113,29 @@ public struct Translator {
|
|||||||
return response.translatedText
|
return response.translatedText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func translateWithWineTranslate(_ text: String, from sourceLanguage: String, to targetLanguage: String) async throws -> String? {
|
||||||
|
let url = try makeURL("https://translate.nostr.wine", path: "/translate")
|
||||||
|
|
||||||
|
var request = URLRequest(url: url)
|
||||||
|
request.httpMethod = "POST"
|
||||||
|
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||||
|
|
||||||
|
struct RequestBody: Encodable {
|
||||||
|
let q: String
|
||||||
|
let source: String
|
||||||
|
let target: String
|
||||||
|
let api_key: String?
|
||||||
|
}
|
||||||
|
let body = RequestBody(q: text, source: sourceLanguage, target: targetLanguage, api_key: userSettingsStore.winetranslate_api_key)
|
||||||
|
request.httpBody = try encoder.encode(body)
|
||||||
|
|
||||||
|
struct Response: Decodable {
|
||||||
|
let translatedText: String
|
||||||
|
}
|
||||||
|
let response: Response = try await decodedData(for: request)
|
||||||
|
return response.translatedText
|
||||||
|
}
|
||||||
|
|
||||||
private func makeURL(_ baseUrl: String, path: String) throws -> URL {
|
private func makeURL(_ baseUrl: String, path: String) throws -> URL {
|
||||||
guard var components = URLComponents(string: baseUrl) else {
|
guard var components = URLComponents(string: baseUrl) else {
|
||||||
throw URLError(.badURL)
|
throw URLError(.badURL)
|
||||||
|
@ -73,6 +73,17 @@ struct TranslationSettingsView: View {
|
|||||||
Link(NSLocalizedString("Get API Key with BTC/Lightning", comment: "Button to navigate to nokyctranslate website to get a translation API key."), destination: URL(string: "https://nokyctranslate.com")!)
|
Link(NSLocalizedString("Get API Key with BTC/Lightning", comment: "Button to navigate to nokyctranslate website to get a translation API key."), destination: URL(string: "https://nokyctranslate.com")!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if settings.translation_service == .winetranslate {
|
||||||
|
SecureField(NSLocalizedString("API Key (required)", comment: "Prompt for required entry of API Key to use translation server."), text: $settings.winetranslate_api_key)
|
||||||
|
.disableAutocorrection(true)
|
||||||
|
.disabled(settings.translation_service != .winetranslate)
|
||||||
|
.autocapitalization(UITextAutocapitalizationType.none)
|
||||||
|
|
||||||
|
if settings.winetranslate_api_key == "" {
|
||||||
|
Link(NSLocalizedString("Get API Key with BTC/Lightning", comment: "Button to navigate to translate.nostr.wine to get a translation API key."), destination: URL(string: "https://translate.nostr.wine")!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if settings.translation_service != .none {
|
if settings.translation_service != .none {
|
||||||
Toggle(NSLocalizedString("Automatically translate notes", comment: "Toggle to automatically translate notes."), isOn: $settings.auto_translate)
|
Toggle(NSLocalizedString("Automatically translate notes", comment: "Toggle to automatically translate notes."), isOn: $settings.auto_translate)
|
||||||
|
Loading…
Reference in New Issue
Block a user