From b3bc6dc273995d3e57d96c4c4624447a3099b907 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 9 Nov 2022 15:50:36 -0500 Subject: [PATCH] Add accessibility labels to notifications, only have 1 element per notification --- .../Content/NotificationView+ViewModel.swift | 46 +++++++++++++------ .../View/Content/NotificationView.swift | 9 ++++ .../View/Content/StatusView+ViewModel.swift | 14 +++--- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift index d7ba51e17..524c92146 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift @@ -54,7 +54,7 @@ extension NotificationView.ViewModel { bindAuthor(notificationView: notificationView) bindAuthorMenu(notificationView: notificationView) bindFollowRequest(notificationView: notificationView) - + $authContext .assign(to: \.authContext, on: notificationView.statusView.viewModel) .store(in: &disposeBag) @@ -100,21 +100,20 @@ extension NotificationView.ViewModel { } .store(in: &disposeBag) // timestamp - Publishers.CombineLatest( + let formattedTimestamp = Publishers.CombineLatest( $timestamp, timestampUpdatePublisher.prepend(Date()).eraseToAnyPublisher() ) - .sink { [weak self] timestamp, _ in - guard let self = self else { return } - guard let timestamp = timestamp else { - notificationView.dateLabel.configure(content: PlaintextMetaContent(string: "")) - return - } - - let text = timestamp.localizedTimeAgoSinceNow - notificationView.dateLabel.configure(content: PlaintextMetaContent(string: text)) + .map { timestamp, _ in + timestamp?.localizedTimeAgoSinceNow ?? "" } - .store(in: &disposeBag) + + formattedTimestamp + .sink { timestamp in + notificationView.dateLabel.configure(content: PlaintextMetaContent(string: timestamp)) + } + .store(in: &disposeBag) + // notification type indicator $notificationIndicatorText .sink { text in @@ -125,6 +124,27 @@ extension NotificationView.ViewModel { } } .store(in: &disposeBag) + + Publishers.CombineLatest4( + $authorName, + $authorUsername, + $notificationIndicatorText, + formattedTimestamp + ) + .sink { name, username, type, timestamp in + notificationView.accessibilityLabel = [ + "\(name?.string ?? "") \(type?.string ?? "")", + username.map { "@\($0)" } ?? "", + timestamp + ].joined(separator: ", ") + if !notificationView.statusView.isHidden { + notificationView.accessibilityLabel! += ", " + (notificationView.statusView.accessibilityLabel ?? "") + } + if !notificationView.quoteStatusViewContainerView.isHidden { + notificationView.accessibilityLabel! += ", " + (notificationView.quoteStatusView.accessibilityLabel ?? "") + } + } + .store(in: &disposeBag) } private func bindAuthorMenu(notificationView: NotificationView) { @@ -207,5 +227,5 @@ extension NotificationView.ViewModel { } .store(in: &disposeBag) } - + } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift index e52422770..f6821dec7 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift @@ -382,6 +382,15 @@ extension NotificationView { statusView.delegate = self quoteStatusView.delegate = self + + isAccessibilityElement = true + } +} + +extension NotificationView { + public override var accessibilityElements: [Any]? { + get { [] } + set {} } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 416226cbb..530294ea7 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -709,13 +709,13 @@ extension StatusView.ViewModel { meidaAccessibilityLabel ) .map { author, content, media in - let group = [ - author, - content, - media - ] - - return group + var labels: [String?] = [content, media] + + if statusView.style != .notification { + labels.insert(author, at: 0) + } + + return labels .compactMap { $0 } .joined(separator: ", ") }