From c2232a596d207be0cf1be1a7091bedd1e1a51618 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 9 Nov 2022 16:59:02 -0500 Subject: [PATCH] Improve accessibility labels for reply/reblog posts --- .../StatusThreadRootTableViewCell.swift | 1 - .../View/Content/StatusView+ViewModel.swift | 68 +++++++++++++------ .../MastodonUI/View/Content/StatusView.swift | 1 + 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift b/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift index 64f3456b5..350bf8660 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/StatusThreadRootTableViewCell.swift @@ -96,7 +96,6 @@ extension StatusThreadRootTableViewCell { override var accessibilityElements: [Any]? { get { var elements = [ - statusView.headerContainerView, statusView.authorView, statusView.viewModel.isContentReveal ? statusView.contentMetaText.textView diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 530294ea7..66994f2a9 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -238,12 +238,11 @@ extension StatusView.ViewModel { } .store(in: &disposeBag) // username - let usernamePublisher = $authorUsername + $authorUsername .map { text -> String in guard let text = text else { return "" } return "@\(text)" } - usernamePublisher .sink { username in let metaContent = PlaintextMetaContent(string: username) authorView.authorUsernameLabel.configure(content: metaContent) @@ -270,18 +269,6 @@ extension StatusView.ViewModel { authorView.dateLabel.configure(content: PlaintextMetaContent(string: text)) } .store(in: &disposeBag) - - // accessibility label - 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) } private func bindContent(statusView: StatusView) { @@ -634,7 +621,7 @@ extension StatusView.ViewModel { } private func bindAccessibility(statusView: StatusView) { - let authorAccessibilityLabel = Publishers.CombineLatest3( + let shortAuthorAccessibilityLabel = Publishers.CombineLatest3( $header, $authorName, $timestampText @@ -644,19 +631,56 @@ extension StatusView.ViewModel { switch header { case .none: - break + strings.append(authorName?.string) case .reply(let info): + strings.append(authorName?.string) strings.append(info.header.string) case .repost(let info): strings.append(info.header.string) + strings.append(authorName?.string) } - strings.append(authorName?.string) strings.append(timestamp) return strings.compactMap { $0 }.joined(separator: ", ") } - + + let longTimestampFormatter = DateFormatter() + longTimestampFormatter.dateStyle = .medium + longTimestampFormatter.timeStyle = .short + let longTimestampLabel = Publishers.CombineLatest( + $timestampText, + $timestamp.map { timestamp in + if let timestamp { + return longTimestampFormatter.string(from: timestamp) + } + return "" + } + ) + .map { timestampText, longTimestamp in + "\(timestampText). \(longTimestamp)" + } + + Publishers.CombineLatest4( + $header, + $authorName, + $authorUsername, + longTimestampLabel + ) + .map { header, name, username, timestamp in + let nameAndUsername = "\(name?.string ?? "") @\(username ?? "")" + switch header { + case .none: + return "\(nameAndUsername), \(timestamp)" + case .repost(info: let info): + return "\(info.header.string) \(nameAndUsername), \(timestamp)" + case .reply(info: let info): + return "\(nameAndUsername) \(info.header.string), \(timestamp)" + } + } + .assign(to: \.accessibilityLabel, on: statusView.authorView) + .store(in: &disposeBag) + let contentAccessibilityLabel = Publishers.CombineLatest3( $isContentReveal, $spoilerContent, @@ -694,8 +718,8 @@ extension StatusView.ViewModel { statusView.spoilerOverlayView.accessibilityLabel = contentAccessibilityLabel } .store(in: &disposeBag) - - let meidaAccessibilityLabel = $mediaViewConfigurations + + let mediaAccessibilityLabel = $mediaViewConfigurations .map { configurations -> String? in let count = configurations.count return L10n.Plural.Count.media(count) @@ -704,9 +728,9 @@ extension StatusView.ViewModel { // TODO: Toolbar Publishers.CombineLatest3( - authorAccessibilityLabel, + shortAuthorAccessibilityLabel, contentAccessibilityLabel, - meidaAccessibilityLabel + mediaAccessibilityLabel ) .map { author, content, media in var labels: [String?] = [content, media] diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 563bc7e3d..21410b9e2 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -246,6 +246,7 @@ extension StatusView { // header headerIconImageView.isUserInteractionEnabled = false headerInfoLabel.isUserInteractionEnabled = false + headerInfoLabel.isAccessibilityElement = false let headerTapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer headerTapGestureRecognizer.addTarget(self, action: #selector(StatusView.headerDidPressed(_:))) headerContainerView.addGestureRecognizer(headerTapGestureRecognizer)