Merge branch 'develop' into IOS-37_Widgets

This commit is contained in:
Marcus Kida 2023-02-07 09:53:01 +01:00
commit e88dea0034
No known key found for this signature in database
GPG Key ID: 19FF64E08013CA40
14 changed files with 101 additions and 51 deletions

View File

@ -186,7 +186,7 @@
"translated_from": "Translated from %s using %s",
"unknown_language": "Unknown",
"unknown_provider": "Unknown",
"show_original": "Shown Original"
"show_original": "Show Original"
},
"media": {
"accessibility_label": "%s, attachment %d of %d",

View File

@ -186,7 +186,7 @@
"translated_from": "Translated from %s using %s",
"unknown_language": "Unknown",
"unknown_provider": "Unknown",
"show_original": "Shown Original"
"show_original": "Show Original"
},
"media": {
"accessibility_label": "%s, attachment %d of %d",

View File

@ -62,6 +62,7 @@ extension HomeTimelineNavigationBarTitleView {
button.addTarget(self, action: #selector(HomeTimelineNavigationBarTitleView.buttonDidPressed(_:)), for: .touchUpInside)
logoButton.accessibilityIdentifier = "TitleButton"
logoButton.accessibilityTraits = [.header, .button]
button.accessibilityIdentifier = "TitleButton"
}
}

View File

@ -25,6 +25,7 @@ final class SearchHistorySectionHeaderCollectionReusableView: UICollectionReusab
label.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 22, weight: .bold))
label.textColor = Asset.Colors.Label.primary.color
label.text = L10n.Scene.Search.Searching.recentSearch
label.accessibilityTraits.insert(.header)
return label
}()
@ -32,6 +33,8 @@ final class SearchHistorySectionHeaderCollectionReusableView: UICollectionReusab
let button = UIButton(type: .system)
button.setImage(UIImage(systemName: "xmark.circle.fill"), for: .normal)
button.tintColor = Asset.Colors.Label.secondary.color
button.accessibilityLabel = L10n.Scene.Search.Searching.clear
return button
}()

View File

@ -51,9 +51,11 @@ extension SearchHistoryUserCollectionViewCell {
NSLayoutConstraint.activate([
userView.topAnchor.constraint(equalTo: contentView.topAnchor),
userView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
userView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 16),
contentView.trailingAnchor.constraint(equalTo: userView.trailingAnchor, constant: 16),
userView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])
userView.accessibilityTraits.insert(.button)
}
override func updateConfiguration(using state: UICellConfigurationState) {

View File

@ -108,6 +108,7 @@ extension StatusThreadRootTableViewCell {
statusView.viewModel.isContentReveal
? statusView.contentMetaText.textView
: statusView.spoilerOverlayView,
statusView.translatedInfoView,
statusView.mediaGridContainerView,
statusView.pollTableView,
statusView.pollStatusStackView,

View File

@ -61,6 +61,8 @@ extension UserTableViewCell {
separatorLine.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
separatorLine.heightAnchor.constraint(equalToConstant: UIView.separatorLineHeight(of: contentView)).priority(.required - 1),
])
userView.accessibilityTraits.insert(.button)
}
}

View File

@ -391,8 +391,8 @@ public enum L10n {
public static let url = L10n.tr("Localizable", "Common.Controls.Status.Tag.Url", fallback: "URL")
}
public enum Translation {
/// Shown Original
public static let showOriginal = L10n.tr("Localizable", "Common.Controls.Status.Translation.ShowOriginal", fallback: "Shown Original")
/// Show Original
public static let showOriginal = L10n.tr("Localizable", "Common.Controls.Status.Translation.ShowOriginal", fallback: "Show Original")
/// 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 %@")

View File

@ -137,7 +137,7 @@ Please check your internet connection.";
"Common.Controls.Status.Tag.Mention" = "Mention";
"Common.Controls.Status.Tag.Url" = "URL";
"Common.Controls.Status.TapToReveal" = "Tap to reveal";
"Common.Controls.Status.Translation.ShowOriginal" = "Shown Original";
"Common.Controls.Status.Translation.ShowOriginal" = "Show Original";
"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@";
"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown";
"Common.Controls.Status.Translation.UnknownProvider" = "Unknown";

View File

@ -36,6 +36,7 @@ open class AvatarButton: UIControl {
isAccessibilityElement = true
accessibilityLabel = L10n.Common.Controls.Status.showUserProfile
accessibilityTraits.insert(.image)
}
public override func layoutSubviews() {

View File

@ -356,6 +356,18 @@ extension StatusView.ViewModel {
statusView.authorView.contentSensitiveeToggleButton.setImage(image, for: .normal)
}
.store(in: &disposeBag)
$isCurrentlyTranslating
.receive(on: DispatchQueue.main)
.sink { isTranslating in
switch isTranslating {
case true:
statusView.isTranslatingLoadingView.startAnimating()
case false:
statusView.isTranslatingLoadingView.stopAnimating()
}
}
.store(in: &disposeBag)
}
private func bindMedia(statusView: StatusView) {
@ -820,14 +832,39 @@ extension StatusView.ViewModel {
}
.assign(to: \.toolbarActions, on: statusView)
.store(in: &disposeBag)
Publishers.CombineLatest3(
let translatedFromLabel = Publishers.CombineLatest($translatedFromLanguage, $translatedUsingProvider)
.map { (language, provider) -> String? in
if let language {
return L10n.Common.Controls.Status.Translation.translatedFrom(
Locale.current.localizedString(forIdentifier: language) ?? L10n.Common.Controls.Status.Translation.unknownLanguage,
provider ?? L10n.Common.Controls.Status.Translation.unknownProvider
)
}
return nil
}
translatedFromLabel
.receive(on: DispatchQueue.main)
.sink { label in
if let label {
statusView.translatedInfoLabel.text = label
statusView.translatedInfoView.accessibilityValue = label
statusView.translatedInfoView.isHidden = false
} else {
statusView.translatedInfoView.isHidden = true
}
}
.store(in: &disposeBag)
Publishers.CombineLatest4(
shortAuthorAccessibilityLabel,
contentAccessibilityLabel,
translatedFromLabel,
mediaAccessibilityLabel
)
.map { author, content, media in
var labels: [String?] = [content, media]
.map { author, content, translated, media in
var labels: [String?] = [content, translated, media]
if statusView.style != .notification {
labels.insert(author, at: 0)

View File

@ -190,15 +190,24 @@ public final class StatusView: UIView {
activityIndicatorView.stopAnimating()
return activityIndicatorView
}()
private let translatedInfoLabel: UILabel = {
let translatedInfoLabel: UILabel = {
let label = UILabel()
label.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .regular))
label.textColor = Asset.Colors.Label.secondary.color
label.numberOfLines = 0
return label
}()
lazy var translatedInfoView: UIView = {
let containerView = UIView()
private class TranslatedInfoView: UIView {
var revertAction: (() -> Void)?
override func accessibilityActivate() -> Bool {
revertAction?()
return true
}
}
public private(set) lazy var translatedInfoView: UIView = {
let containerView = TranslatedInfoView()
let revertButton = UIButton()
revertButton.titleLabel?.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .bold))
@ -230,7 +239,14 @@ public final class StatusView: UIView {
])
containerView.isHidden = true
containerView.isAccessibilityElement = true
containerView.accessibilityLabel = L10n.Common.Controls.Status.Translation.showOriginal
containerView.accessibilityTraits = [.button]
containerView.revertAction = { [weak self] in
self?.revertTranslation()
}
return containerView
}()
@ -270,7 +286,6 @@ public final class StatusView: UIView {
setPollDisplay(isDisplay: false)
setFilterHintLabelDisplay(isDisplay: false)
setStatusCardControlDisplay(isDisplay: false)
setupTranslationIndicator()
}
public override init(frame: CGRect) {
@ -612,10 +627,19 @@ extension StatusView {
get {
(contentMetaText.textView.accessibilityCustomActions ?? [])
+ toolbarActions
+ (hideTranslationAction.map { [$0] } ?? [])
+ (authorView.accessibilityCustomActions ?? [])
}
set { }
}
private var hideTranslationAction: UIAccessibilityCustomAction? {
guard viewModel.translatedFromLanguage != nil else { return nil }
return UIAccessibilityCustomAction(name: L10n.Common.Controls.Status.Translation.showOriginal) { [weak self] _ in
self?.revertTranslation()
return true
}
}
}
// MARK: - AdaptiveContainerView
@ -728,41 +752,6 @@ extension StatusView: MastodonMenuDelegate {
}
}
extension StatusView {
func setupTranslationIndicator() {
viewModel.$isCurrentlyTranslating
.receive(on: DispatchQueue.main)
.sink { [weak self] isTranslating in
switch isTranslating {
case true:
self?.isTranslatingLoadingView.startAnimating()
case false:
self?.isTranslatingLoadingView.stopAnimating()
}
}
.store(in: &disposeBag)
Publishers.CombineLatest(
viewModel.$translatedFromLanguage,
viewModel.$translatedUsingProvider
)
.receive(on: DispatchQueue.main)
.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,
translatedUsingProvider ?? L10n.Common.Controls.Status.Translation.unknownProvider
)
self.translatedInfoView.isHidden = false
} else {
self.translatedInfoView.isHidden = true
}
}
.store(in: &disposeBag)
}
}
// MARK: StatusCardControlDelegate
extension StatusView: StatusCardControlDelegate {
public func statusCardControl(_ statusCardControl: StatusCardControl, didTapURL url: URL) {

View File

@ -52,15 +52,27 @@ extension UserView.ViewModel {
}
.store(in: &disposeBag)
// username
$authorUsername
let displayUsername = $authorUsername
.map { text -> String in
guard let text = text else { return "" }
return "@\(text)"
}
displayUsername
.sink { username in
let metaContent = PlaintextMetaContent(string: username)
userView.authorUsernameLabel.configure(content: metaContent)
}
.store(in: &disposeBag)
Publishers.CombineLatest($authorName, displayUsername)
.sink { name, username in
if let name {
userView.accessibilityLabel = "\(name.string), \(username)"
} else {
userView.accessibilityLabel = username
}
}
.store(in: &disposeBag)
}
}

View File

@ -90,6 +90,8 @@ extension UserView {
avatarButton.isUserInteractionEnabled = false
authorNameLabel.isUserInteractionEnabled = false
authorUsernameLabel.isUserInteractionEnabled = false
isAccessibilityElement = true
}
}