mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-06-12 18:29:26 +00:00
Remove the DeepL fallback
The DeepL fallback for the instance translation service is removed, error messages are shown if a translation fails.
This commit is contained in:
parent
8f06719b23
commit
b4a1b09864
|
@ -31,7 +31,9 @@ struct SettingsTabs: View {
|
|||
@Binding var popToRootTab: Tab
|
||||
|
||||
let isModal: Bool
|
||||
|
||||
|
||||
@State private var startingPoint: SettingsStartingPoint? = nil
|
||||
|
||||
var body: some View {
|
||||
NavigationStack(path: $routerPath.path) {
|
||||
Form {
|
||||
|
@ -64,6 +66,32 @@ struct SettingsTabs: View {
|
|||
}
|
||||
.withAppRouter()
|
||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||
.onAppear {
|
||||
startingPoint = RouterPath.settingsStartingPoint
|
||||
RouterPath.settingsStartingPoint = nil
|
||||
}
|
||||
.navigationDestination(item: $startingPoint) { targetView in
|
||||
switch targetView {
|
||||
case .display:
|
||||
DisplaySettingsView()
|
||||
case .haptic:
|
||||
HapticSettingsView()
|
||||
case .remoteTimelines:
|
||||
RemoteTimelinesSettingView()
|
||||
case .tagGroups:
|
||||
TagsGroupSettingView()
|
||||
case .recentTags:
|
||||
RecenTagsSettingView()
|
||||
case .content:
|
||||
ContentSettingsView()
|
||||
case .swipeActions:
|
||||
SwipeActionsSettingsView()
|
||||
case .tabAndSidebarEntries:
|
||||
EmptyView()
|
||||
case .translation:
|
||||
TranslationSettingsView()
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
routerPath.client = client
|
||||
|
|
|
@ -18412,6 +18412,126 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"action.cancel" : {
|
||||
"comment" : "MARK: Common strings",
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"be" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Скасаваць"
|
||||
}
|
||||
},
|
||||
"ca" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cancel·la"
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Abbrechen"
|
||||
}
|
||||
},
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cancel"
|
||||
}
|
||||
},
|
||||
"en-GB" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cancel"
|
||||
}
|
||||
},
|
||||
"es" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cancelar"
|
||||
}
|
||||
},
|
||||
"eu" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Utzi"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Annuler"
|
||||
}
|
||||
},
|
||||
"it" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Annulla"
|
||||
}
|
||||
},
|
||||
"ja" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "キャンセル"
|
||||
}
|
||||
},
|
||||
"ko" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "취소"
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Avbryt"
|
||||
}
|
||||
},
|
||||
"nl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Annuleer"
|
||||
}
|
||||
},
|
||||
"pl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Anuluj"
|
||||
}
|
||||
},
|
||||
"pt-BR" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cancelar"
|
||||
}
|
||||
},
|
||||
"tr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "İptal Et"
|
||||
}
|
||||
},
|
||||
"uk" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Відміна"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "取消"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "取消"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"action.delete" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
|
@ -20304,6 +20424,40 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"alert.translation-error.deepl" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "DeepL konnte nicht erreicht werden!\nIst der API-Schlüssel korrekt?"
|
||||
}
|
||||
},
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "DeepL couldn't be reached!\nIs the API Key correct?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"alert.translation-error.instance" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Der Übersetzung-Service deiner Instanz konnte nicht erreicht werden!"
|
||||
}
|
||||
},
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "The Translation Service of your Instance couldn't be reached!"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"An error occured while posting to Mastodon, please try again." : {
|
||||
"localizations" : {
|
||||
"de" : {
|
||||
|
@ -81080,126 +81234,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"action.cancel" : {
|
||||
"comment" : "MARK: Common strings",
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"be" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Скасаваць"
|
||||
}
|
||||
},
|
||||
"ca" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cancel·la"
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Abbrechen"
|
||||
}
|
||||
},
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cancel"
|
||||
}
|
||||
},
|
||||
"en-GB" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cancel"
|
||||
}
|
||||
},
|
||||
"es" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cancelar"
|
||||
}
|
||||
},
|
||||
"eu" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Utzi"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Annuler"
|
||||
}
|
||||
},
|
||||
"it" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Annulla"
|
||||
}
|
||||
},
|
||||
"ja" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "キャンセル"
|
||||
}
|
||||
},
|
||||
"ko" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "취소"
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Avbryt"
|
||||
}
|
||||
},
|
||||
"nl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Annuleer"
|
||||
}
|
||||
},
|
||||
"pl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Anuluj"
|
||||
}
|
||||
},
|
||||
"pt-BR" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cancelar"
|
||||
}
|
||||
},
|
||||
"tr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "İptal Et"
|
||||
}
|
||||
},
|
||||
"uk" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Відміна"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "取消"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "取消"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Visibility" : {
|
||||
"localizations" : {
|
||||
|
@ -81223,4 +81257,4 @@
|
|||
}
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>DEEPL_SECRET</key>
|
||||
<string>NICE_TRY_AGAIN</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -115,6 +115,18 @@ public enum SheetDestination: Identifiable, Hashable {
|
|||
}
|
||||
}
|
||||
|
||||
public enum SettingsStartingPoint {
|
||||
case display
|
||||
case haptic
|
||||
case remoteTimelines
|
||||
case tagGroups
|
||||
case recentTags
|
||||
case content
|
||||
case swipeActions
|
||||
case tabAndSidebarEntries
|
||||
case translation
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@Observable public class RouterPath {
|
||||
public var client: Client?
|
||||
|
@ -123,6 +135,8 @@ public enum SheetDestination: Identifiable, Hashable {
|
|||
public var path: [RouterDestination] = []
|
||||
public var presentedSheet: SheetDestination?
|
||||
|
||||
public static var settingsStartingPoint: SettingsStartingPoint? = nil
|
||||
|
||||
public init() {}
|
||||
|
||||
public func navigate(to: RouterDestination) {
|
||||
|
|
|
@ -12,20 +12,8 @@ public struct DeepLClient: Sendable {
|
|||
"https://api\(deeplUserAPIFree && (deeplUserAPIKey != nil) ? "-free" : "").deepl.com/v2/translate"
|
||||
}
|
||||
|
||||
private var APIKey: String {
|
||||
if let deeplUserAPIKey {
|
||||
return deeplUserAPIKey
|
||||
}
|
||||
|
||||
if let path = Bundle.main.path(forResource: "Secret", ofType: "plist") {
|
||||
let secret = NSDictionary(contentsOfFile: path)
|
||||
return secret?["DEEPL_SECRET"] as? String ?? ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
private var authorizationHeaderValue: String {
|
||||
"DeepL-Auth-Key \(APIKey)"
|
||||
"DeepL-Auth-Key \(deeplUserAPIKey ?? "")"
|
||||
}
|
||||
|
||||
public struct Response: Decodable {
|
||||
|
@ -49,26 +37,22 @@ public struct DeepLClient: Sendable {
|
|||
}
|
||||
|
||||
public func request(target: String, text: String) async throws -> Translation {
|
||||
do {
|
||||
var components = URLComponents(string: endpoint)!
|
||||
var queryItems: [URLQueryItem] = []
|
||||
queryItems.append(.init(name: "text", value: text))
|
||||
queryItems.append(.init(name: "target_lang", value: target.uppercased()))
|
||||
components.queryItems = queryItems
|
||||
var request = URLRequest(url: components.url!)
|
||||
request.httpMethod = "POST"
|
||||
request.setValue(authorizationHeaderValue, forHTTPHeaderField: "Authorization")
|
||||
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
let (result, _) = try await URLSession.shared.data(for: request)
|
||||
let response = try decoder.decode(Response.self, from: result)
|
||||
if let translation = response.translations.first {
|
||||
return .init(content: translation.text.removingPercentEncoding ?? "",
|
||||
detectedSourceLanguage: translation.detectedSourceLanguage,
|
||||
provider: "DeepL.com")
|
||||
}
|
||||
throw DeepLError.notFound
|
||||
} catch {
|
||||
throw error
|
||||
var components = URLComponents(string: endpoint)!
|
||||
var queryItems: [URLQueryItem] = []
|
||||
queryItems.append(.init(name: "text", value: text))
|
||||
queryItems.append(.init(name: "target_lang", value: target.uppercased()))
|
||||
components.queryItems = queryItems
|
||||
var request = URLRequest(url: components.url!)
|
||||
request.httpMethod = "POST"
|
||||
request.setValue(authorizationHeaderValue, forHTTPHeaderField: "Authorization")
|
||||
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
let (result, _) = try await URLSession.shared.data(for: request)
|
||||
let response = try decoder.decode(Response.self, from: result)
|
||||
if let translation = response.translations.first {
|
||||
return .init(content: translation.text.removingPercentEncoding ?? "",
|
||||
detectedSourceLanguage: translation.detectedSourceLanguage,
|
||||
provider: "DeepL.com")
|
||||
}
|
||||
throw DeepLError.notFound
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ public struct StatusRowView: View {
|
|||
@Environment(\.accessibilityVoiceOverEnabled) private var accessibilityVoiceOverEnabled
|
||||
@Environment(\.isStatusFocused) private var isFocused
|
||||
@Environment(\.indentationLevel) private var indentationLevel
|
||||
@Environment(RouterPath.self) private var routerPath: RouterPath
|
||||
|
||||
@Environment(QuickLook.self) private var quickLook
|
||||
@Environment(Theme.self) private var theme
|
||||
|
@ -232,6 +233,20 @@ public struct StatusRowView: View {
|
|||
StatusDataControllerProvider.shared.dataController(for: viewModel.finalStatus,
|
||||
client: viewModel.client)
|
||||
)
|
||||
.alert("alert.translation-error.deepl", isPresented: $viewModel.deeplTranslationError) {
|
||||
Button("alert.button.ok", role: .cancel) {}
|
||||
Button("settings.general.translate") {
|
||||
RouterPath.settingsStartingPoint = .translation
|
||||
routerPath.presentedSheet = .settings
|
||||
}
|
||||
}
|
||||
.alert("alert.translation-error.instance", isPresented: $viewModel.instanceTranslationError) {
|
||||
Button("alert.button.ok", role: .cancel) {}
|
||||
Button("settings.general.translate") {
|
||||
RouterPath.settingsStartingPoint = .translation
|
||||
routerPath.presentedSheet = .settings
|
||||
}
|
||||
}
|
||||
#if canImport(_Translation_SwiftUI)
|
||||
.addTranslateView(isPresented: $viewModel.showAppleTranslation, text: viewModel.finalStatus.content.asRawText)
|
||||
#endif
|
||||
|
|
|
@ -40,6 +40,8 @@ import SwiftUI
|
|||
}
|
||||
}
|
||||
}
|
||||
var deeplTranslationError = false
|
||||
var instanceTranslationError = false
|
||||
|
||||
private(set) var actionsAccountsFetched: Bool = false
|
||||
var favoriters: [Account] = []
|
||||
|
@ -316,21 +318,21 @@ import SwiftUI
|
|||
isLoadingTranslation = true
|
||||
}
|
||||
if preferredTranslationType != .useDeepl {
|
||||
do {
|
||||
// We first use instance translation API if available.
|
||||
let translation: Translation = try await client.post(endpoint: Statuses.translate(id: finalStatus.id,
|
||||
let translation: Translation? = try? await client.post(endpoint: Statuses.translate(id: finalStatus.id,
|
||||
lang: userLang))
|
||||
withAnimation {
|
||||
self.translation = translation
|
||||
isLoadingTranslation = false
|
||||
self.translation = translation
|
||||
isLoadingTranslation = false
|
||||
}
|
||||
|
||||
return
|
||||
} catch {}
|
||||
if translation == nil {
|
||||
instanceTranslationError = true
|
||||
}
|
||||
} else {
|
||||
await translateWithDeepL(userLang: userLang)
|
||||
if translation == nil {
|
||||
deeplTranslationError = true
|
||||
}
|
||||
}
|
||||
|
||||
// If not or fail we use Ice Cubes own DeepL client.
|
||||
await translateWithDeepL(userLang: userLang)
|
||||
}
|
||||
|
||||
func translateWithDeepL(userLang: String) async {
|
||||
|
|
Loading…
Reference in a new issue