mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-25 17:51:01 +00:00
Add native translate for media description edit + profile bio
This commit is contained in:
parent
bab2b4be9c
commit
69cb9a20f9
8 changed files with 47 additions and 63 deletions
|
@ -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),
|
||||||
|
|
|
@ -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)
|
||||||
|
if #available(iOS 17.4, *) {
|
||||||
Button {
|
Button {
|
||||||
Task {
|
showTranslateView = true
|
||||||
await viewModel.translate(userLang: lang)
|
|
||||||
}
|
|
||||||
} label: {
|
} label: {
|
||||||
Label("status.action.translate", systemImage: "captions.bubble")
|
Label("status.action.translate", systemImage: "captions.bubble")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if viewModel.relationship?.following == true {
|
if viewModel.relationship?.following == true {
|
||||||
Button {
|
Button {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
15
Packages/Env/Sources/Env/Ext/TranslationView.swift
Normal file
15
Packages/Env/Sources/Env/Ext/TranslationView.swift
Normal 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
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue