feat: Show translation provider
This commit is contained in:
parent
3b77ed7612
commit
258aea3682
|
@ -183,8 +183,9 @@
|
|||
"direct": "Only mentioned user can see this post."
|
||||
},
|
||||
"translation": {
|
||||
"translated_from": "Translated from %s",
|
||||
"translated_from": "Translated from %s using %s",
|
||||
"unknown_language": "Unknown",
|
||||
"unknown_provider": "Unknown",
|
||||
"show_original": "Shown Original"
|
||||
}
|
||||
},
|
||||
|
|
|
@ -39,7 +39,7 @@ extension DataSourceFacade {
|
|||
}
|
||||
|
||||
private extension DataSourceFacade {
|
||||
static func translateStatus(provider: Provider, status: Status) async throws -> String? {
|
||||
static func translateStatus(provider: Provider, status: Status) async throws -> Status.TranslatedContent? {
|
||||
do {
|
||||
let value = try await provider.context
|
||||
.apiService
|
||||
|
@ -52,7 +52,7 @@ private extension DataSourceFacade {
|
|||
throw TranslationFailure.emptyOrInvalidResponse
|
||||
}
|
||||
|
||||
return content
|
||||
return Status.TranslatedContent(content: content, provider: value.provider)
|
||||
} catch {
|
||||
throw TranslationFailure.emptyOrInvalidResponse
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21509" systemVersion="21G217" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21513" systemVersion="22C65" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="Application" representedClassName="CoreDataStack.Application" syncable="YES">
|
||||
<attribute name="identifier" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
|
@ -218,7 +218,7 @@
|
|||
<attribute name="sensitive" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="spoilerText" optional="YES" attributeType="String"/>
|
||||
<attribute name="text" optional="YES" attributeType="String"/>
|
||||
<attribute name="translatedContent" optional="YES" transient="YES" attributeType="String"/>
|
||||
<attribute name="translatedContent" optional="YES" transient="YES" attributeType="Transformable"/>
|
||||
<attribute name="updatedAt" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="uri" attributeType="String"/>
|
||||
<attribute name="url" optional="YES" attributeType="String"/>
|
||||
|
|
|
@ -11,6 +11,16 @@ 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
|
||||
|
@ -103,7 +113,7 @@ public final class Status: NSManagedObject {
|
|||
@NSManaged public private(set) var revealedAt: Date?
|
||||
|
||||
// sourcery: autoUpdatableObject
|
||||
@NSManaged public private(set) var translatedContent: String?
|
||||
@NSManaged public private(set) var translatedContent: TranslatedContent?
|
||||
}
|
||||
|
||||
extension Status {
|
||||
|
@ -504,7 +514,7 @@ extension Status: AutoUpdatableObject {
|
|||
self.revealedAt = revealedAt
|
||||
}
|
||||
}
|
||||
public func update(translatedContent: String?) {
|
||||
public func update(translatedContent: TranslatedContent?) {
|
||||
if self.translatedContent != translatedContent {
|
||||
self.translatedContent = translatedContent
|
||||
}
|
||||
|
|
|
@ -381,12 +381,14 @@ public enum L10n {
|
|||
public enum Translation {
|
||||
/// Show Original
|
||||
public static let showOriginal = L10n.tr("Localizable", "Common.Controls.Status.Translation.ShowOriginal", fallback: "Show Original")
|
||||
/// Translated from %@
|
||||
public static func translatedFrom(_ p1: Any) -> String {
|
||||
return L10n.tr("Localizable", "Common.Controls.Status.Translation.TranslatedFrom", String(describing: p1), fallback: "Translated from %@")
|
||||
/// Translated from %@ using %@
|
||||
public static func translatedFrom(_ p1: Any, _ p2: Any) -> String {
|
||||
return L10n.tr("Localizable", "Common.Controls.Status.Translation.TranslatedFrom", String(describing: p1), String(describing: p2), fallback: "Translated from %@ using %@")
|
||||
}
|
||||
/// Unknown
|
||||
public static let unknownLanguage = L10n.tr("Localizable", "Common.Controls.Status.Translation.UnknownLanguage", fallback: "Unknown")
|
||||
/// Unknown
|
||||
public static let unknownProvider = L10n.tr("Localizable", "Common.Controls.Status.Translation.UnknownProvider", fallback: "Unknown")
|
||||
}
|
||||
public enum Visibility {
|
||||
/// Only mentioned user can see this post.
|
||||
|
|
|
@ -134,8 +134,9 @@ Please check your internet connection.";
|
|||
"Common.Controls.Status.Tag.Url" = "URL";
|
||||
"Common.Controls.Status.TapToReveal" = "Tap to reveal";
|
||||
"Common.Controls.Status.Translation.ShowOriginal" = "Show Original";
|
||||
"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@";
|
||||
"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@";
|
||||
"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown";
|
||||
"Common.Controls.Status.Translation.UnknownProvider" = "Unknown";
|
||||
"Common.Controls.Status.UserReblogged" = "%@ reblogged";
|
||||
"Common.Controls.Status.UserRepliedTo" = "Replied to %@";
|
||||
"Common.Controls.Status.Visibility.Direct" = "Only mentioned user can see this post.";
|
||||
|
|
|
@ -62,8 +62,9 @@ Please check your internet connection.";
|
|||
"Common.Controls.Actions.SignUp" = "Create account";
|
||||
"Common.Controls.Actions.Skip" = "Skip";
|
||||
"Common.Controls.Actions.TakePhoto" = "Take Photo";
|
||||
"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@";
|
||||
"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@ using %@";
|
||||
"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown";
|
||||
"Common.Controls.Actions.TranslatePost.UnknownProvider" = "Unknown";
|
||||
"Common.Controls.Actions.TryAgain" = "Try Again";
|
||||
"Common.Controls.Actions.UnblockDomain" = "Unblock %@";
|
||||
"Common.Controls.Friendship.Block" = "Block";
|
||||
|
@ -130,8 +131,9 @@ Please check your internet connection.";
|
|||
"Common.Controls.Status.Tag.Url" = "URL";
|
||||
"Common.Controls.Status.TapToReveal" = "Tap to reveal";
|
||||
"Common.Controls.Status.Translation.ShowOriginal" = "Show Original";
|
||||
"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@";
|
||||
"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@";
|
||||
"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown";
|
||||
"Common.Controls.Status.Translation.UnknownProvider" = "Unknown";
|
||||
"Common.Controls.Status.UserReblogged" = "%@ reblogged";
|
||||
"Common.Controls.Status.UserRepliedTo" = "Replied to %@";
|
||||
"Common.Controls.Status.Visibility.Direct" = "Only mentioned user can see this post.";
|
||||
|
|
|
@ -246,13 +246,14 @@ extension StatusView {
|
|||
func revertTranslation() {
|
||||
guard let originalStatus = viewModel.originalStatus else { return }
|
||||
viewModel.translatedFromLanguage = nil
|
||||
viewModel.translatedUsingProvider = nil
|
||||
originalStatus.reblog?.update(translatedContent: nil)
|
||||
originalStatus.update(translatedContent: nil)
|
||||
configure(status: originalStatus)
|
||||
}
|
||||
|
||||
func configureTranslated(status: Status) {
|
||||
let translatedContent: String? = {
|
||||
let translatedContent: Status.TranslatedContent? = {
|
||||
if let translatedContent = status.reblog?.translatedContent {
|
||||
return translatedContent
|
||||
}
|
||||
|
@ -269,10 +270,11 @@ extension StatusView {
|
|||
|
||||
// content
|
||||
do {
|
||||
let content = MastodonContent(content: translatedContent, emojis: status.emojis.asDictionary)
|
||||
let content = MastodonContent(content: translatedContent.content, 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.isCurrentlyTranslating = false
|
||||
} catch {
|
||||
assertionFailure(error.localizedDescription)
|
||||
|
|
|
@ -49,7 +49,8 @@ extension StatusView {
|
|||
// Translation
|
||||
@Published public var isCurrentlyTranslating = false
|
||||
@Published public var translatedFromLanguage: String?
|
||||
|
||||
@Published public var translatedUsingProvider: String?
|
||||
|
||||
@Published public var timestamp: Date?
|
||||
public var timestampFormatter: ((_ date: Date) -> String)?
|
||||
@Published public var timestampText = ""
|
||||
|
@ -145,6 +146,7 @@ extension StatusView {
|
|||
isMediaSensitive = false
|
||||
isSensitiveToggled = false
|
||||
translatedFromLanguage = nil
|
||||
translatedUsingProvider = nil
|
||||
isCurrentlyTranslating = false
|
||||
|
||||
activeFilters = []
|
||||
|
@ -629,7 +631,9 @@ extension StatusView.ViewModel {
|
|||
guard
|
||||
let context = self.context,
|
||||
let authContext = self.authContext
|
||||
else { return nil }
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
var configuration: Mastodon.Entity.V2.Instance.Configuration? = nil
|
||||
context.managedObjectContext.performAndWait {
|
||||
|
|
|
@ -191,6 +191,7 @@ public final class StatusView: UIView {
|
|||
let label = UILabel()
|
||||
label.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .regular))
|
||||
label.textColor = Asset.Colors.Label.secondary.color
|
||||
label.numberOfLines = 2
|
||||
return label
|
||||
}()
|
||||
lazy var translatedInfoView: UIView = {
|
||||
|
@ -212,10 +213,14 @@ public final class StatusView: UIView {
|
|||
containerView.addSubview($0)
|
||||
}
|
||||
|
||||
translatedInfoLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
||||
revertButton.setContentHuggingPriority(.required, for: .horizontal)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
containerView.heightAnchor.constraint(equalToConstant: 24),
|
||||
translatedInfoLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
|
||||
translatedInfoLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
|
||||
translatedInfoLabel.trailingAnchor.constraint(equalTo: revertButton.leadingAnchor, constant: -16),
|
||||
revertButton.topAnchor.constraint(equalTo: containerView.topAnchor),
|
||||
revertButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -16),
|
||||
revertButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)
|
||||
|
@ -735,12 +740,18 @@ extension StatusView {
|
|||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
viewModel.$translatedFromLanguage
|
||||
Publishers.CombineLatest(
|
||||
viewModel.$translatedFromLanguage,
|
||||
viewModel.$translatedUsingProvider
|
||||
)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] translatedFromLanguage in
|
||||
.sink { [weak self] translatedFromLanguage, translatedUsingProvider in
|
||||
guard let self = self else { return }
|
||||
if let translatedFromLanguage = translatedFromLanguage {
|
||||
self.translatedInfoLabel.text = L10n.Common.Controls.Status.Translation.translatedFrom(Locale.current.localizedString(forIdentifier: translatedFromLanguage) ?? L10n.Common.Controls.Status.Translation.unknownLanguage)
|
||||
self.translatedInfoLabel.text = L10n.Common.Controls.Status.Translation.translatedFrom(
|
||||
Locale.current.localizedString(forIdentifier: translatedFromLanguage) ?? L10n.Common.Controls.Status.Translation.unknownLanguage,
|
||||
translatedUsingProvider ?? L10n.Common.Controls.Status.Translation.unknownProvider
|
||||
)
|
||||
self.translatedInfoView.isHidden = false
|
||||
} else {
|
||||
self.translatedInfoView.isHidden = true
|
||||
|
|
Loading…
Reference in New Issue