Add native translate for media description edit + profile bio

This commit is contained in:
Thomas Ricouard 2024-05-14 19:36:25 +02:00
parent bab2b4be9c
commit 69cb9a20f9
8 changed files with 47 additions and 63 deletions

View file

@ -33,7 +33,7 @@ struct MentionsWidgetProvider: AppIntentTimelineProvider {
oauthToken: configuration.account.account.oauthToken) oauthToken: configuration.account.account.oauthToken)
var excludedTypes = Models.Notification.NotificationType.allCases var excludedTypes = Models.Notification.NotificationType.allCases
excludedTypes.removeAll(where: { $0 == .mention }) excludedTypes.removeAll(where: { $0 == .mention })
var notifications: [Models.Notification] = let notifications: [Models.Notification] =
try await client.get(endpoint: Notifications.notifications(minId: nil, try await client.get(endpoint: Notifications.notifications(minId: nil,
maxId: nil, maxId: nil,
types: excludedTypes.map(\.rawValue), types: excludedTypes.map(\.rawValue),

View file

@ -9,6 +9,7 @@ public struct AccountDetailContextMenu: View {
@Environment(UserPreferences.self) private var preferences @Environment(UserPreferences.self) private var preferences
@Binding var showBlockConfirmation: Bool @Binding var showBlockConfirmation: Bool
@Binding var showTranslateView: Bool
var viewModel: AccountDetailViewModel var viewModel: AccountDetailViewModel
@ -136,15 +137,15 @@ public struct AccountDetailContextMenu: View {
#endif #endif
} }
if let lang = preferences.serverPreferences?.postLanguage ?? Locale.current.language.languageCode?.identifier { #if canImport(_Translation_SwiftUI)
Button { if #available(iOS 17.4, *) {
Task { Button {
await viewModel.translate(userLang: lang) showTranslateView = true
} label: {
Label("status.action.translate", systemImage: "captions.bubble")
}
} }
} label: { #endif
Label("status.action.translate", systemImage: "captions.bubble")
}
}
if viewModel.relationship?.following == true { if viewModel.relationship?.following == true {
Button { Button {

View file

@ -24,6 +24,7 @@ public struct AccountDetailView: View {
@State private var isCurrentUser: Bool = false @State private var isCurrentUser: Bool = false
@State private var showBlockConfirmation: Bool = false @State private var showBlockConfirmation: Bool = false
@State private var isEditingRelationshipNote: Bool = false @State private var isEditingRelationshipNote: Bool = false
@State private var showTranslateView: Bool = false
@State private var displayTitle: Bool = false @State private var displayTitle: Bool = false
@ -285,7 +286,9 @@ public struct AccountDetailView: View {
} }
Menu { Menu {
AccountDetailContextMenu(showBlockConfirmation: $showBlockConfirmation, viewModel: viewModel) AccountDetailContextMenu(showBlockConfirmation: $showBlockConfirmation,
showTranslateView: $showTranslateView,
viewModel: viewModel)
if !viewModel.isCurrentUser { if !viewModel.isCurrentUser {
Button { Button {
@ -380,6 +383,9 @@ public struct AccountDetailView: View {
} message: { } message: {
Text("account.action.block-user-confirmation") Text("account.action.block-user-confirmation")
} }
#if canImport(_Translation_SwiftUI)
.addTranslateView(isPresented: $showTranslateView, text: viewModel.account?.note.asRawText ?? "")
#endif
} }
} }
} }

View file

@ -273,22 +273,4 @@ import SwiftUI
func statusDidAppear(status _: Models.Status) {} func statusDidAppear(status _: Models.Status) {}
func statusDidDisappear(status _: Status) {} func statusDidDisappear(status _: Status) {}
func translate(userLang: String) async {
guard let account else { return }
withAnimation {
isLoadingTranslation = true
}
let userAPIKey = DeepLUserAPIHandler.readKeyIfAllowed()
let userAPIFree = UserPreferences.shared.userDeeplAPIFree
let deeplClient = DeepLClient(userAPIKey: userAPIKey, userAPIFree: userAPIFree)
let translation = try? await deeplClient.request(target: userLang, text: account.note.asRawText)
withAnimation {
self.translation = translation
isLoadingTranslation = false
}
}
} }

View file

@ -32,6 +32,7 @@ public struct AccountsListRow: View {
@State private var isEditingRelationshipNote: Bool = false @State private var isEditingRelationshipNote: Bool = false
@State private var showBlockConfirmation: Bool = false @State private var showBlockConfirmation: Bool = false
@State private var showTranslateView: Bool = false
let isFollowRequest: Bool let isFollowRequest: Bool
let requestUpdated: (() -> Void)? let requestUpdated: (() -> Void)?
@ -108,8 +109,13 @@ public struct AccountsListRow: View {
.onTapGesture { .onTapGesture {
routerPath.navigate(to: .accountDetailWithAccount(account: viewModel.account)) routerPath.navigate(to: .accountDetailWithAccount(account: viewModel.account))
} }
#if canImport(_Translation_SwiftUI)
.addTranslateView(isPresented: $showTranslateView, text: viewModel.account.note.asRawText)
#endif
.contextMenu { .contextMenu {
AccountDetailContextMenu(showBlockConfirmation: $showBlockConfirmation, viewModel: .init(account: viewModel.account)) AccountDetailContextMenu(showBlockConfirmation: $showBlockConfirmation,
showTranslateView: $showTranslateView,
viewModel: .init(account: viewModel.account))
} preview: { } preview: {
List { List {
AccountDetailHeaderView(viewModel: .init(account: viewModel.account), AccountDetailHeaderView(viewModel: .init(account: viewModel.account),

View file

@ -0,0 +1,15 @@
import SwiftUI
#if canImport(_Translation_SwiftUI)
import Translation
extension View {
public func addTranslateView(isPresented: Binding<Bool>, text: String) -> some View {
if #available(iOS 17.4, *) {
return self.translationPresentation(isPresented: isPresented, text: text)
} else {
return self
}
}
}
#endif

View file

@ -24,6 +24,7 @@ extension StatusEditor {
@State private var isGeneratingDescription: Bool = false @State private var isGeneratingDescription: Bool = false
@State private var showTranslateButton: Bool = false @State private var showTranslateButton: Bool = false
@State private var showTranslateView: Bool = false
@State private var isTranslating: Bool = false @State private var isTranslating: Bool = false
var body: some View { var body: some View {
@ -111,12 +112,14 @@ extension StatusEditor {
Task { Task {
if let description = await generateDescription(url: url) { if let description = await generateDescription(url: url) {
imageDescription = description imageDescription = description
#if canImport(_Translation_SwiftUI)
let lang = preferences.serverPreferences?.postLanguage ?? Locale.current.language.languageCode?.identifier let lang = preferences.serverPreferences?.postLanguage ?? Locale.current.language.languageCode?.identifier
if lang != nil, lang != "en" { if #available(iOS 17.4, *), lang != nil, lang != "en", DeepLUserAPIHandler.readKey().isEmpty == false {
withAnimation { withAnimation {
showTranslateButton = true showTranslateButton = true
} }
} }
#endif
} }
} }
} label: { } label: {
@ -133,14 +136,7 @@ extension StatusEditor {
private var translateButton: some View { private var translateButton: some View {
if showTranslateButton { if showTranslateButton {
Button { Button {
Task { showTranslateView = true
if let description = await translateDescription() {
imageDescription = description
withAnimation {
showTranslateButton = false
}
}
}
} label: { } label: {
if isTranslating { if isTranslating {
ProgressView() ProgressView()
@ -148,6 +144,9 @@ extension StatusEditor {
Text("status.action.translate") Text("status.action.translate")
} }
} }
#if canImport(_Translation_SwiftUI)
.addTranslateView(isPresented: $showTranslateView, text: imageDescription)
#endif
} }
} }
@ -158,17 +157,5 @@ extension StatusEditor {
isGeneratingDescription = false isGeneratingDescription = false
return response?.trimmedText return response?.trimmedText
} }
private func translateDescription() async -> String? {
isTranslating = true
let userAPIKey = DeepLUserAPIHandler.readKeyIfAllowed()
let userAPIFree = UserPreferences.shared.userDeeplAPIFree
let deeplClient = DeepLClient(userAPIKey: userAPIKey, userAPIFree: userAPIFree)
let lang = preferences.serverPreferences?.postLanguage ?? Locale.current.language.languageCode?.identifier
guard let lang else { return nil }
let translation = try? await deeplClient.request(target: lang, text: imageDescription)
isTranslating = false
return translation?.content.asRawText
}
} }
} }

View file

@ -5,19 +5,6 @@ import Foundation
import Models import Models
import Network import Network
import SwiftUI import SwiftUI
#if canImport(_Translation_SwiftUI)
import Translation
extension View {
func addTranslateView(isPresented: Binding<Bool>, text: String) -> some View {
if #available(iOS 17.4, *) {
return self.translationPresentation(isPresented: isPresented, text: text)
} else {
return self
}
}
}
#endif
@MainActor @MainActor
public struct StatusRowView: View { public struct StatusRowView: View {