From 7294ff6e1a20ef13227b116add623bab0c86cd9b Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 12 Nov 2022 15:04:44 -0500 Subject: [PATCH] Status VoiceOver improvements Closes #229 Closes #230 --- .../TimelineStatusCollectionViewCell.swift | 51 +++++++++++++++--- .../Status/TimelineStatusTableViewCell.swift | 53 ++++++++++++++----- 2 files changed, 84 insertions(+), 20 deletions(-) diff --git a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift index a964fb22..c9d1fee7 100644 --- a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift +++ b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift @@ -321,32 +321,67 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti // MARK: Accessibility - override var accessibilityLabel: String? { + override var isAccessibilityElement: Bool { + get { true } + set {} + } + + override var accessibilityAttributedLabel: NSAttributedString? { get { guard let status = mastodonController.persistentContainer.status(for: statusID) else { return nil } - var str = "\(status.account.displayOrUserName), \(contentTextView.text ?? "")" - + var str = AttributedString("\(status.account.displayOrUserName), ") + if statusState.collapsed ?? false { + if !status.spoilerText.isEmpty { + str += AttributedString(status.spoilerText) + str += ", " + } + str += "collapsed" + } else { + str += AttributedString(contentTextView.attributedText) + } + if status.attachments.count > 0 { // TODO: localize me - str += ", \(status.attachments.count) attachment\(status.attachments.count > 1 ? "s" : "")" + str += AttributedString(", \(status.attachments.count) attachment\(status.attachments.count > 1 ? "s" : "")") } if status.poll != nil { str += ", poll" } - str += ", \(status.createdAt.formatted(.relative(presentation: .numeric)))" + str += AttributedString(", \(status.createdAt.formatted(.relative(presentation: .numeric)))") + if status.visibility < .unlisted { + str += AttributedString(", \(status.visibility.displayName)") + } + if status.localOnly { + str += ", local" + } if let rebloggerID, let reblogger = mastodonController.persistentContainer.account(for: rebloggerID) { - str += ", reblogged by \(reblogger.displayOrUserName)" + str += AttributedString(", reblogged by \(reblogger.displayOrUserName)") + } + return NSAttributedString(str) + } + set {} + } + + override var accessibilityHint: String? { + get { + if statusState.collapsed ?? false { + return "Double tap to expand the post." + } else { + return nil } - return str } set {} } override func accessibilityActivate() -> Bool { - delegate?.selected(status: statusID, state: statusState.copy()) + if statusState.collapsed ?? false { + toggleCollapse() + } else { + delegate?.selected(status: statusID, state: statusState.copy()) + } return true } diff --git a/Tusker/Views/Status/TimelineStatusTableViewCell.swift b/Tusker/Views/Status/TimelineStatusTableViewCell.swift index 81471e45..f7cc2b98 100644 --- a/Tusker/Views/Status/TimelineStatusTableViewCell.swift +++ b/Tusker/Views/Status/TimelineStatusTableViewCell.swift @@ -249,33 +249,62 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell { // MARK: - Accessibility - override var accessibilityLabel: String? { + override var accessibilityAttributedLabel: NSAttributedString? { get { guard let status = mastodonController.persistentContainer.status(for: statusID) else { return nil } - var str = "\(status.account.displayName), \(contentTextView.text ?? "")" - + var str = AttributedString("\(status.account.displayOrUserName), ") + if statusState.collapsed ?? false { + if !status.spoilerText.isEmpty { + str += AttributedString(status.spoilerText) + str += ", " + } + str += "collapsed" + } else { + str += AttributedString(contentTextView.attributedText) + } + if status.attachments.count > 0 { - // todo: localize me - str += ", \(status.attachments.count) attachments" + // TODO: localize me + str += AttributedString(", \(status.attachments.count) attachment\(status.attachments.count > 1 ? "s" : "")") } if status.poll != nil { str += ", poll" } - str += ", \(TimelineStatusTableViewCell.relativeDateFormatter.localizedString(for: status.createdAt, relativeTo: Date()))" - if let rebloggerID = rebloggerID, - let reblogger = mastodonController.persistentContainer.account(for: rebloggerID) { - str += ", reblogged by \(reblogger.displayName)" + str += AttributedString(", \(status.createdAt.formatted(.relative(presentation: .numeric)))") + if status.visibility < .unlisted { + str += AttributedString(", \(status.visibility.displayName)") + } + if status.localOnly { + str += ", local" + } + if let rebloggerID, + let reblogger = mastodonController.persistentContainer.account(for: rebloggerID) { + str += AttributedString(", reblogged by \(reblogger.displayOrUserName)") + } + return NSAttributedString(str) + } + set {} + } + + override var accessibilityHint: String? { + get { + if statusState.collapsed ?? false { + return "Double tap to expand the post." + } else { + return nil } - - return str } set {} } override func accessibilityActivate() -> Bool { - didSelectCell() + if statusState.collapsed ?? false { + collapseButtonPressed() + } else { + didSelectCell() + } return true }