feat: Show translation provider

This commit is contained in:
Marcus Kida 2022-12-19 07:32:48 +01:00
parent 3b77ed7612
commit 258aea3682
No known key found for this signature in database
GPG Key ID: 19FF64E08013CA40
10 changed files with 53 additions and 20 deletions

View File

@ -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"
}
},

View File

@ -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
}

View File

@ -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"/>

View File

@ -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
}

View File

@ -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.

View File

@ -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.";

View File

@ -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.";

View File

@ -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)

View File

@ -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 {

View File

@ -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