Get rid of translation-persistence

This commit is contained in:
Nathan Mattes 2023-10-16 13:28:12 +02:00
parent 8381a44b71
commit 87cb71da5d
8 changed files with 50 additions and 78 deletions

View File

@ -151,7 +151,7 @@ extension DataSourceFacade {
struct MenuContext {
let author: ManagedObjectRecord<MastodonUser>?
let status: ManagedObjectRecord<Status>?
let statusViewModel: StatusView.ViewModel?
let button: UIButton?
let barButtonItem: UIBarButtonItem?
}
@ -266,7 +266,7 @@ extension DataSourceFacade {
context: dependency.context,
authContext: dependency.authContext,
user: user,
status: menuContext.status
status: menuContext.statusViewModel?.originalStatus?.asRecord
)
_ = dependency.coordinator.present(
@ -297,7 +297,7 @@ extension DataSourceFacade {
)
case .bookmarkStatus:
Task {
guard let status = menuContext.status else {
guard let status = menuContext.statusViewModel?.originalStatus?.asRecord else {
assertionFailure()
return
}
@ -310,7 +310,7 @@ extension DataSourceFacade {
Task {
let managedObjectContext = dependency.context.managedObjectContext
guard let status: ManagedObjectRecord<Status> = try? await managedObjectContext.perform(block: {
guard let object = menuContext.status?.object(in: managedObjectContext) else { return nil }
guard let object = menuContext.statusViewModel?.originalStatus?.asRecord.object(in: managedObjectContext) else { return nil }
let objectID = (object.reblog ?? object).objectID
return .init(objectID: objectID)
}) else {
@ -344,7 +344,7 @@ extension DataSourceFacade {
style: .destructive
) { [weak dependency] _ in
guard let dependency = dependency else { return }
guard let status = menuContext.status else { return }
guard let status = menuContext.statusViewModel?.originalStatus?.asRecord else { return }
Task {
try await DataSourceFacade.responseToDeleteStatus(
dependency: dependency,
@ -358,12 +358,12 @@ extension DataSourceFacade {
dependency.present(alertController, animated: true)
case .translateStatus:
guard let status = menuContext.status else { return }
guard let status = menuContext.statusViewModel?.originalStatus?.asRecord else { return }
do {
try await DataSourceFacade.translateStatus(
provider: dependency,
status: status
)
let translation = try await DataSourceFacade.translateStatus(provider: dependency,status: status)
menuContext.statusViewModel?.translation = translation
} catch TranslationFailure.emptyOrInvalidResponse {
let alertController = UIAlertController(title: L10n.Common.Alerts.TranslationFailed.title, message: L10n.Common.Alerts.TranslationFailed.message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: L10n.Common.Alerts.TranslationFailed.button, style: .default))
@ -371,7 +371,7 @@ extension DataSourceFacade {
}
case .editStatus:
guard let status = menuContext.status?.object(in: dependency.context.managedObjectContext) else { return }
guard let status = menuContext.statusViewModel?.originalStatus?.asRecord.object(in: dependency.context.managedObjectContext) else { return }
let statusSource = try await dependency.context.apiService.getStatusSource(
forStatusID: status.id,

View File

@ -9,6 +9,7 @@ import UIKit
import CoreData
import CoreDataStack
import MastodonCore
import MastodonSDK
typealias Provider = UIViewController & NeedsDependency & AuthContextProvider
@ -20,26 +21,26 @@ extension DataSourceFacade {
public static func translateStatus(
provider: Provider,
status: ManagedObjectRecord<Status>
) async throws {
) async throws -> Mastodon.Entity.Translation? {
let selectionFeedbackGenerator = await UISelectionFeedbackGenerator()
await selectionFeedbackGenerator.selectionChanged()
guard
let status = status.object(in: provider.context.managedObjectContext)
else {
return
return nil
}
if let reblog = status.reblog {
try await translateAndApply(provider: provider, status: reblog)
return try await translateStatus(provider: provider, status: reblog)
} else {
try await translateAndApply(provider: provider, status: status)
return try await translateStatus(provider: provider, status: status)
}
}
}
private extension DataSourceFacade {
static func translateStatus(provider: Provider, status: Status) async throws -> Status.TranslatedContent? {
static func translateStatus(provider: Provider, status: Status) async throws -> Mastodon.Entity.Translation? {
do {
let value = try await provider.context
.apiService
@ -49,22 +50,12 @@ private extension DataSourceFacade {
).value
guard let content = value.content else {
throw TranslationFailure.emptyOrInvalidResponse
return nil
}
return Status.TranslatedContent(content: content, provider: value.provider)
return value
} catch {
throw TranslationFailure.emptyOrInvalidResponse
}
}
static func translateAndApply(provider: Provider, status: Status) async throws {
do {
let translated = try await translateStatus(provider: provider, status: status)
status.update(translatedContent: translated)
} catch {
status.update(translatedContent: nil)
throw TranslationFailure.emptyOrInvalidResponse
}
}
}

View File

@ -44,7 +44,7 @@ extension NotificationTableViewCellDelegate where Self: DataSourceProvider & Aut
action: action,
menuContext: .init(
author: author,
status: nil,
statusViewModel: nil,
button: button,
barButtonItem: nil
)

View File

@ -498,13 +498,23 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte
}
}
}
let statusViewModel: StatusView.ViewModel?
if let cell = cell as? StatusTableViewCell {
statusViewModel = await cell.statusView.viewModel
} else if let cell = cell as? StatusThreadRootTableViewCell {
statusViewModel = await cell.statusView.viewModel
} else {
statusViewModel = nil
}
try await DataSourceFacade.responseToMenuAction(
dependency: self,
action: action,
menuContext: .init(
author: author,
status: status,
statusViewModel: statusViewModel,
button: button,
barButtonItem: nil
)

View File

@ -894,7 +894,7 @@ extension ProfileViewController: MastodonMenuDelegate {
action: action,
menuContext: DataSourceFacade.MenuContext(
author: userRecord,
status: nil,
statusViewModel: nil,
button: nil,
barButtonItem: self.moreMenuBarButtonItem
)

View File

@ -10,17 +10,7 @@ import Foundation
public final class Status: NSManagedObject {
public typealias ID = String
public class TranslatedContent: NSObject {
public let content: String
public let provider: String?
public init(content: String, provider: String?) {
self.content = content
self.provider = provider
}
}
// sourcery: autoGenerateProperty
@NSManaged public private(set) var identifier: ID
// sourcery: autoGenerateProperty
@ -118,9 +108,6 @@ public final class Status: NSManagedObject {
@NSManaged public private(set) var deletedAt: Date?
// sourcery: autoUpdatableObject
@NSManaged public private(set) var revealedAt: Date?
// sourcery: autoUpdatableObject
@NSManaged public private(set) var translatedContent: TranslatedContent?
}
extension Status {
@ -535,11 +522,6 @@ extension Status: AutoUpdatableObject {
self.revealedAt = revealedAt
}
}
public func update(translatedContent: TranslatedContent?) {
if self.translatedContent != translatedContent {
self.translatedContent = translatedContent
}
}
public func update(attachments: [MastodonAttachment]) {
if self.attachments != attachments {
self.attachments = attachments

View File

@ -85,13 +85,10 @@ extension StatusView {
configureToolbar(status: status)
configureFilter(status: status)
viewModel.originalStatus = status
[
status.publisher(for: \.translatedContent),
status.reblog?.publisher(for: \.translatedContent)
].compactMap { $0 }
.last?
viewModel.$translation
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
.sink { [weak self] translation in
self?.configureTranslated(status: status)
}
.store(in: &disposeBag)
@ -293,36 +290,26 @@ extension StatusView {
public func revertTranslation() {
guard let originalStatus = viewModel.originalStatus else { return }
viewModel.translatedFromLanguage = nil
viewModel.translatedUsingProvider = nil
originalStatus.reblog?.update(translatedContent: nil)
originalStatus.update(translatedContent: nil)
viewModel.translation = nil
configure(status: originalStatus)
}
func configureTranslated(status: Status) {
let translatedContent: Status.TranslatedContent? = {
if let translatedContent = status.reblog?.translatedContent {
return translatedContent
}
return status.translatedContent
}()
guard
let translatedContent = translatedContent
else {
guard let translation = viewModel.translation,
let translatedContent = translation.content,
let sourceLanguage = translation.sourceLanguage,
let provider = translation.provider else {
viewModel.isCurrentlyTranslating = false
return
}
// content
do {
let content = MastodonContent(content: translatedContent.content, emojis: status.emojis.asDictionary)
let content = MastodonContent(content: translatedContent, emojis: status.emojis.asDictionary)
let metaContent = try MastodonMetaContent.convert(document: content)
viewModel.content = metaContent
viewModel.translatedFromLanguage = status.reblog?.language ?? status.language
viewModel.translatedUsingProvider = status.reblog?.translatedContent?.provider ?? status.translatedContent?.provider
viewModel.translatedFromLanguage = sourceLanguage
viewModel.translatedUsingProvider = provider
viewModel.isCurrentlyTranslating = false
} catch {
assertionFailure(error.localizedDescription)
@ -351,7 +338,7 @@ extension StatusView {
}
private func configureContent(status: Status) {
guard status.translatedContent == nil else {
guard viewModel.translation == nil else {
return configureTranslated(status: status)
}

View File

@ -48,6 +48,7 @@ extension StatusView {
@Published public var isCurrentlyTranslating = false
@Published public var translatedFromLanguage: String?
@Published public var translatedUsingProvider: String?
@Published public var translation: Mastodon.Entity.Translation? = nil
@Published public var timestamp: Date?
public var timestampFormatter: ((_ date: Date, _ isEdited: Bool) -> String)?
@ -151,7 +152,8 @@ extension StatusView {
translatedFromLanguage = nil
translatedUsingProvider = nil
isCurrentlyTranslating = false
translation = nil
activeFilters = []
filterContext = nil
}
@ -657,7 +659,7 @@ extension StatusView.ViewModel {
$isFollowed
)
let publishersThree = Publishers.CombineLatest(
$translatedFromLanguage,
$translation,
$language
)