From 8f3caba0891a9da53c6e589dd1aacb45e436ea31 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 31 Oct 2022 12:40:18 -0400 Subject: [PATCH] Remove the status metric view from the accessibility hierarchy --- .../View/Content/StatusMetricView.swift | 2 ++ .../View/Content/StatusView+ViewModel.swift | 13 ++++++---- .../MastodonUI/View/Content/StatusView.swift | 8 +++++++ .../View/Control/ActionToolbarContainer.swift | 24 +++++++++++++++++-- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusMetricView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusMetricView.swift index d5f6a0709..f1ca95b3e 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusMetricView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusMetricView.swift @@ -100,6 +100,8 @@ extension StatusMetricView { reblogButton.addTarget(self, action: #selector(StatusMetricView.reblogButtonDidPressed(_:)), for: .touchUpInside) favoriteButton.addTarget(self, action: #selector(StatusMetricView.favoriteButtonDidPressed(_:)), for: .touchUpInside) + + accessibilityElementsHidden = true } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index af2bba14a..0e005f3a5 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -258,8 +258,7 @@ extension StatusView.ViewModel { return text } .removeDuplicates() - - timestampPublisher.assign(to: &$timestampText) + .assign(to: &$timestampText) $timestampText .sink { [weak self] text in @@ -269,9 +268,13 @@ extension StatusView.ViewModel { .store(in: &disposeBag) // accessibility label - Publishers.CombineLatest3($authorName, usernamePublisher, timestampPublisher) - .map { name, username, timestamp in - "\(name?.string ?? "") \(username), \(timestamp)" + Publishers.CombineLatest4($authorName, usernamePublisher, $timestampText, $timestamp) + .map { name, username, timestampText, timestamp in + let formatter = DateFormatter() + formatter.dateStyle = .medium + formatter.timeStyle = .short + let longTimestamp = timestamp.map { formatter.string(from: $0) } ?? "" + return "\(name?.string ?? "") \(username), \(timestampText). \(longTimestamp)" } .assign(to: \.accessibilityLabel, on: authorView) .store(in: &disposeBag) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 1c9ed673d..6740715ca 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -623,6 +623,14 @@ extension StatusView: ActionToolbarContainerDelegate { public func actionToolbarContainer(_ actionToolbarContainer: ActionToolbarContainer, buttonDidPressed button: UIButton, action: ActionToolbarContainer.Action) { delegate?.statusView(self, actionToolbarContainer: actionToolbarContainer, buttonDidPressed: button, action: action) } + + public func actionToolbarContainer(_ actionToolbarContainer: ActionToolbarContainer, showReblogs action: UIAccessibilityCustomAction) { + delegate?.statusView(self, statusMetricView: statusMetricView, reblogButtonDidPressed: statusMetricView.reblogButton) + } + + public func actionToolbarContainer(_ actionToolbarContainer: ActionToolbarContainer, showFavorites action: UIAccessibilityCustomAction) { + delegate?.statusView(self, statusMetricView: statusMetricView, favoriteButtonDidPressed: statusMetricView.favoriteButton) + } } // MARK: - StatusMetricViewDelegate diff --git a/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift b/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift index 4a5c44850..be6506642 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift @@ -12,6 +12,8 @@ import MastodonLocalization public protocol ActionToolbarContainerDelegate: AnyObject { func actionToolbarContainer(_ actionToolbarContainer: ActionToolbarContainer, buttonDidPressed button: UIButton, action: ActionToolbarContainer.Action) + func actionToolbarContainer(_ actionToolbarContainer: ActionToolbarContainer, showReblogs action: UIAccessibilityCustomAction) + func actionToolbarContainer(_ actionToolbarContainer: ActionToolbarContainer, showFavorites action: UIAccessibilityCustomAction) } public final class ActionToolbarContainer: UIView { @@ -222,6 +224,7 @@ extension ActionToolbarContainer { public func configureReblog(count: Int, isEnabled: Bool, isHighlighted: Bool) { let title = ActionToolbarContainer.title(from: count) reblogButton.setTitle(title, for: .normal) + reblogButton.accessibilityValue = L10n.Plural.Count.reblog(count) reblogButton.isEnabled = isEnabled reblogButton.setImage(ActionToolbarContainer.reblogImage, for: .normal) let tintColor = isHighlighted ? Asset.Colors.successGreen.color : Asset.Colors.Button.actionToolbar.color @@ -231,15 +234,24 @@ extension ActionToolbarContainer { if isHighlighted { reblogButton.accessibilityTraits.insert(.selected) + reblogButton.accessibilityLabel = L10n.Common.Controls.Status.Actions.unreblog } else { reblogButton.accessibilityTraits.remove(.selected) + reblogButton.accessibilityLabel = L10n.Common.Controls.Status.Actions.reblog } - reblogButton.accessibilityLabel = L10n.Plural.Count.reblog(count) + reblogButton.accessibilityCustomActions = [ + UIAccessibilityCustomAction(name: "Show All Reblogs") { [weak self] action in + guard let self = self else { return false } + self.delegate?.actionToolbarContainer(self, showReblogs: action) + return true + } + ] } public func configureFavorite(count: Int, isEnabled: Bool, isHighlighted: Bool) { let title = ActionToolbarContainer.title(from: count) favoriteButton.setTitle(title, for: .normal) + favoriteButton.accessibilityValue = L10n.Plural.Count.favorite(count) favoriteButton.isEnabled = isEnabled let image = isHighlighted ? ActionToolbarContainer.starFillImage : ActionToolbarContainer.starImage favoriteButton.setImage(image, for: .normal) @@ -250,10 +262,18 @@ extension ActionToolbarContainer { if isHighlighted { favoriteButton.accessibilityTraits.insert(.selected) + favoriteButton.accessibilityLabel = L10n.Common.Controls.Status.Actions.unfavorite } else { favoriteButton.accessibilityTraits.remove(.selected) + favoriteButton.accessibilityLabel = L10n.Common.Controls.Status.Actions.favorite } - favoriteButton.accessibilityLabel = L10n.Plural.Count.favorite(count) + favoriteButton.accessibilityCustomActions = [ + UIAccessibilityCustomAction(name: "Show All Favorites") { [weak self] action in + guard let self = self else { return false } + self.delegate?.actionToolbarContainer(self, showFavorites: action) + return true + } + ] } }