Merge pull request #502 from j-f1/a11y-post-links

Add accessibility actions for links/mentions/hashtags in posts
This commit is contained in:
Nathan Mattes 2022-11-09 15:47:49 +01:00 committed by GitHub
commit ceee4bcf48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 89 additions and 3 deletions

View File

@ -136,6 +136,12 @@
"vote": "Vote",
"closed": "Closed"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hastag %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Reply",
"reblog": "Reblog",

View File

@ -136,6 +136,12 @@
"vote": "Vote",
"closed": "Closed"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hastag %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Reply",
"reblog": "Reblog",

View File

@ -99,6 +99,10 @@ extension StatusTableViewCell {
return true
}
override var accessibilityCustomActions: [UIAccessibilityCustomAction]? {
get { statusView.accessibilityCustomActions }
set { }
}
}
// MARK: - AdaptiveContainerMarginTableViewCell

View File

@ -314,6 +314,24 @@ public enum L10n {
/// Undo reblog
public static let unreblog = L10n.tr("Localizable", "Common.Controls.Status.Actions.Unreblog")
}
public enum MetaEntity {
/// Email address: %@
public static func email(_ p1: Any) -> String {
return L10n.tr("Localizable", "Common.Controls.Status.MetaEntity.Email", String(describing: p1))
}
/// Hastag %@
public static func hashtag(_ p1: Any) -> String {
return L10n.tr("Localizable", "Common.Controls.Status.MetaEntity.Hashtag", String(describing: p1))
}
/// Show Profile: %@
public static func mention(_ p1: Any) -> String {
return L10n.tr("Localizable", "Common.Controls.Status.MetaEntity.Mention", String(describing: p1))
}
/// Link: %@
public static func url(_ p1: Any) -> String {
return L10n.tr("Localizable", "Common.Controls.Status.MetaEntity.Url", String(describing: p1))
}
}
public enum Poll {
/// Closed
public static let closed = L10n.tr("Localizable", "Common.Controls.Status.Poll.Closed")

View File

@ -108,6 +108,10 @@ Please check your internet connection.";
"Common.Controls.Status.Actions.Unreblog" = "Undo reblog";
"Common.Controls.Status.ContentWarning" = "Content Warning";
"Common.Controls.Status.MediaContentWarning" = "Tap anywhere to reveal";
"Common.Controls.Status.MetaEntity.Email" = "Email address: %@";
"Common.Controls.Status.MetaEntity.Hashtag" = "Hastag %@";
"Common.Controls.Status.MetaEntity.Mention" = "Show Profile: %@";
"Common.Controls.Status.MetaEntity.Url" = "Link: %@";
"Common.Controls.Status.Poll.Closed" = "Closed";
"Common.Controls.Status.Poll.Vote" = "Vote";
"Common.Controls.Status.SensitiveContent" = "Sensitive Content";

View File

@ -0,0 +1,27 @@
//
// MetaEntity+Accessibility.swift
//
//
// Created by Jed Fox on 2022-11-03.
//
import Meta
import MastodonLocalization
extension Meta.Entity {
var accessibilityCustomActionLabel: String? {
switch meta {
case .url(_, trimmed: _, url: let url, userInfo: _):
return L10n.Common.Controls.Status.MetaEntity.url(url)
case .hashtag(_, hashtag: let hashtag, userInfo: _):
return L10n.Common.Controls.Status.MetaEntity.hashtag(hashtag)
case .mention(_, mention: let mention, userInfo: _):
return L10n.Common.Controls.Status.MetaEntity.mention(mention)
case .email(let email, userInfo: _):
return L10n.Common.Controls.Status.MetaEntity.email(email)
// emoji are not actionable
case .emoji:
return nil
}
}
}

View File

@ -315,7 +315,6 @@ extension StatusView.ViewModel {
statusView.contentMetaText.configure(
content: content
)
statusView.contentMetaText.textView.accessibilityLabel = content.string
statusView.contentMetaText.textView.accessibilityTraits = [.staticText]
statusView.contentMetaText.textView.accessibilityElementsHidden = false
} else {
@ -727,8 +726,23 @@ extension StatusView.ViewModel {
statusView.accessibilityLabel = accessibilityLabel
}
.store(in: &disposeBag)
Publishers.CombineLatest(
$content,
$isContentReveal.removeDuplicates()
)
.map { content, isRevealed in
guard isRevealed, let entities = content?.entities else { return [] }
return entities.compactMap { entity in
guard let name = entity.accessibilityCustomActionLabel else { return nil }
return UIAccessibilityCustomAction(name: name) { action in
statusView.delegate?.statusView(statusView, metaText: statusView.contentMetaText, didSelectMeta: entity.meta)
return true
}
}
}
.assign(to: \.accessibilityCustomActions, on: statusView.contentMetaText.textView)
.store(in: &disposeBag)
}
}

View File

@ -547,6 +547,13 @@ extension StatusView {
}
extension StatusView {
public override var accessibilityCustomActions: [UIAccessibilityCustomAction]? {
get { contentMetaText.textView.accessibilityCustomActions }
set { }
}
}
// MARK: - AdaptiveContainerView
extension StatusView: AdaptiveContainerView {
public func updateContainerViewComponentsLayoutMarginsRelativeArrangementBehavior(isEnabled: Bool) {