mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-06-12 18:29:26 +00:00
Implement a first version of Apple's Translation
The user can now choose between his instance's server, DeepL (with API key) and Apple's Translation framework. A translation is cleared if the translation type is changed. The strings aren't yet written, but the translations settings view's inconsistent background is now fixed.
This commit is contained in:
parent
e21ec0bd1f
commit
022f2f9a49
|
@ -11,8 +11,8 @@ struct TranslationSettingsView: View {
|
|||
|
||||
var body: some View {
|
||||
Form {
|
||||
deepLToggle
|
||||
if preferences.alwaysUseDeepl {
|
||||
translationSelector
|
||||
if preferences.preferredTranslationType == .useDeepl {
|
||||
Section("settings.translation.user-api-key") {
|
||||
deepLPicker
|
||||
SecureField("settings.translation.user-api-key", text: $apiKey)
|
||||
|
@ -51,10 +51,12 @@ struct TranslationSettingsView: View {
|
|||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var deepLToggle: some View {
|
||||
private var translationSelector: some View {
|
||||
@Bindable var preferences = preferences
|
||||
Toggle(isOn: $preferences.alwaysUseDeepl) {
|
||||
Text("settings.translation.always-deepl")
|
||||
Picker("settings.translation.preferred-translation-type", selection: $preferences.preferredTranslationType) {
|
||||
ForEach(TranslationType.allCases, id: \.self) { type in
|
||||
Text(type.rawValue).tag(type)
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
|
@ -80,6 +82,9 @@ struct TranslationSettingsView: View {
|
|||
} footer: {
|
||||
Text("settings.translation.auto-detect-post-language-footer")
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
|
||||
private func writeNewValue() {
|
||||
|
|
|
@ -59867,6 +59867,7 @@
|
|||
}
|
||||
},
|
||||
"settings.translation.always-deepl" : {
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"be" : {
|
||||
"stringUnit" : {
|
||||
|
@ -60573,6 +60574,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings.translation.preferred-translation-type" : {
|
||||
|
||||
},
|
||||
"settings.translation.user-api-key" : {
|
||||
"localizations" : {
|
||||
|
|
|
@ -24,7 +24,7 @@ public enum DeepLUserAPIHandler {
|
|||
}
|
||||
|
||||
public static func readIfAllowed() -> String? {
|
||||
guard UserPreferences.shared.alwaysUseDeepl else { return nil }
|
||||
guard UserPreferences.shared.preferredTranslationType == .useDeepl else { return nil }
|
||||
|
||||
return readValue()
|
||||
}
|
||||
|
@ -35,7 +35,11 @@ public enum DeepLUserAPIHandler {
|
|||
}
|
||||
|
||||
public static func deactivateToggleIfNoKey() {
|
||||
UserPreferences.shared.alwaysUseDeepl = shouldAlwaysUseDeepl
|
||||
if UserPreferences.shared.preferredTranslationType == .useDeepl {
|
||||
if readValue() == nil {
|
||||
UserPreferences.shared.preferredTranslationType = .useServerIfPossible
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static var shouldAlwaysUseDeepl: Bool {
|
||||
|
|
5
Packages/Env/Sources/Env/TranslationType.swift
Normal file
5
Packages/Env/Sources/Env/TranslationType.swift
Normal file
|
@ -0,0 +1,5 @@
|
|||
public enum TranslationType: String, CaseIterable {
|
||||
case useServerIfPossible
|
||||
case useDeepl
|
||||
case useApple
|
||||
}
|
|
@ -185,11 +185,7 @@ import SwiftUI
|
|||
}
|
||||
}
|
||||
|
||||
public var alwaysUseDeepl: Bool {
|
||||
didSet {
|
||||
storage.alwaysUseDeepl = alwaysUseDeepl
|
||||
}
|
||||
}
|
||||
public var preferredTranslationType: TranslationType
|
||||
|
||||
public var userDeeplAPIFree: Bool {
|
||||
didSet {
|
||||
|
@ -482,7 +478,7 @@ import SwiftUI
|
|||
appDefaultPostsSensitive = storage.appDefaultPostsSensitive
|
||||
appRequireAltText = storage.appRequireAltText
|
||||
autoPlayVideo = storage.autoPlayVideo
|
||||
alwaysUseDeepl = storage.alwaysUseDeepl
|
||||
preferredTranslationType = .useServerIfPossible
|
||||
userDeeplAPIFree = storage.userDeeplAPIFree
|
||||
autoDetectPostLanguage = storage.autoDetectPostLanguage
|
||||
inAppBrowserReaderView = storage.inAppBrowserReaderView
|
||||
|
|
|
@ -31,6 +31,15 @@ import SwiftUI
|
|||
var translation: Translation?
|
||||
var isLoadingTranslation: Bool = false
|
||||
var showDeleteAlert: Bool = false
|
||||
var showAppleTranslation = false
|
||||
var preferredTranslationType = TranslationType.useServerIfPossible {
|
||||
didSet {
|
||||
if oldValue != preferredTranslationType {
|
||||
translation = nil
|
||||
showAppleTranslation = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private(set) var actionsAccountsFetched: Bool = false
|
||||
var favoriters: [Account] = []
|
||||
|
@ -297,10 +306,16 @@ import SwiftUI
|
|||
}
|
||||
|
||||
func translate(userLang: String) async {
|
||||
updatePreferredTranslation()
|
||||
if preferredTranslationType == .useApple {
|
||||
showAppleTranslation = true
|
||||
return
|
||||
}
|
||||
|
||||
withAnimation {
|
||||
isLoadingTranslation = true
|
||||
}
|
||||
if !alwaysTranslateWithDeepl {
|
||||
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,
|
||||
|
@ -342,8 +357,14 @@ import SwiftUI
|
|||
DeepLUserAPIHandler.readIfAllowed()
|
||||
}
|
||||
|
||||
var alwaysTranslateWithDeepl: Bool {
|
||||
DeepLUserAPIHandler.shouldAlwaysUseDeepl
|
||||
func updatePreferredTranslation() {
|
||||
if DeepLUserAPIHandler.shouldAlwaysUseDeepl {
|
||||
preferredTranslationType = .useDeepl
|
||||
} else if UserPreferences.shared.preferredTranslationType == .useApple {
|
||||
preferredTranslationType = .useApple
|
||||
} else {
|
||||
preferredTranslationType = .useServerIfPossible
|
||||
}
|
||||
}
|
||||
|
||||
func fetchRemoteStatus() async -> Bool {
|
||||
|
|
|
@ -2,6 +2,7 @@ import DesignSystem
|
|||
import Env
|
||||
import Models
|
||||
import SwiftUI
|
||||
import Translation
|
||||
|
||||
@MainActor
|
||||
struct StatusRowTranslateView: View {
|
||||
|
@ -35,7 +36,8 @@ struct StatusRowTranslateView: View {
|
|||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
@ViewBuilder
|
||||
var translateButton: some View {
|
||||
if !isInCaptureMode,
|
||||
!isCompact,
|
||||
let userLang = preferences.serverPreferences?.postLanguage,
|
||||
|
@ -54,8 +56,26 @@ struct StatusRowTranslateView: View {
|
|||
}
|
||||
.buttonStyle(.borderless)
|
||||
}
|
||||
}
|
||||
|
||||
if let translation = viewModel.translation, !viewModel.isLoadingTranslation {
|
||||
@ViewBuilder
|
||||
var generalTranslateButton: some View {
|
||||
if #available(iOS 17.4, *) {
|
||||
@Bindable var viewModel = viewModel
|
||||
translateButton
|
||||
.translationPresentation(isPresented: $viewModel.showAppleTranslation, text: viewModel.finalStatus.content.asRawText)
|
||||
} else {
|
||||
translateButton
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
generalTranslateButton
|
||||
.onChange(of: preferences.preferredTranslationType) { _, _ in
|
||||
_ = viewModel.updatePreferredTranslation()
|
||||
}
|
||||
|
||||
if let translation = viewModel.translation, !viewModel.isLoadingTranslation, preferences.preferredTranslationType != .useApple {
|
||||
GroupBox {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(translation.content.asSafeMarkdownAttributedString)
|
||||
|
|
Loading…
Reference in a new issue