Skip to content

Commit

Permalink
Various accessibility fixes (#1694)
Browse files Browse the repository at this point in the history
* Hide the accessibility label for the swipe to reply menu

* Fixes #1104 - Add accessibility labels for timeline media

* Import new common strings

* Add sender to accessibility lables for all messages

* Improve accessibility labels for replies

* Add hint and selection to reaction accessibility labels

* Add changelog

* Address PR comments
  • Loading branch information
stefanceriu authored Sep 13, 2023
1 parent e8b8da6 commit f96969a
Show file tree
Hide file tree
Showing 12 changed files with 58 additions and 16 deletions.
2 changes: 2 additions & 0 deletions ElementX/Resources/Localizations/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"common_forward_message" = "Forward message";
"common_gif" = "GIF";
"common_image" = "Image";
"common_in_reply_to" = "In reply to %1$@";
"common_invite_unknown_profile" = "This Matrix ID can't be found, so the invite might not be received.";
"common_leaving_room" = "Leaving room";
"common_link_copied_to_clipboard" = "Link copied to clipboard";
Expand All @@ -99,6 +100,7 @@
"common_poll_total_votes" = "Total votes: %1$@";
"common_poll_undisclosed_text" = "Results will show after the poll has ended";
"common_privacy_policy" = "Privacy policy";
"common_reaction" = "Reaction";
"common_reactions" = "Reactions";
"common_refreshing" = "Refreshing…";
"common_replying_to" = "Replying to %1$@";
Expand Down
6 changes: 6 additions & 0 deletions ElementX/Sources/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ public enum L10n {
public static var commonGif: String { return L10n.tr("Localizable", "common_gif") }
/// Image
public static var commonImage: String { return L10n.tr("Localizable", "common_image") }
/// In reply to %1$@
public static func commonInReplyTo(_ p1: Any) -> String {
return L10n.tr("Localizable", "common_in_reply_to", String(describing: p1))
}
/// This Matrix ID can't be found, so the invite might not be received.
public static var commonInviteUnknownProfile: String { return L10n.tr("Localizable", "common_invite_unknown_profile") }
/// Leaving room
Expand Down Expand Up @@ -226,6 +230,8 @@ public enum L10n {
}
/// Privacy policy
public static var commonPrivacyPolicy: String { return L10n.tr("Localizable", "common_privacy_policy") }
/// Reaction
public static var commonReaction: String { return L10n.tr("Localizable", "common_reaction") }
/// Reactions
public static var commonReactions: String { return L10n.tr("Localizable", "common_reactions") }
/// Refreshing…
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ struct TimelineReplyView: View {
Text(sender.displayName ?? sender.id)
.font(.compound.bodySMSemibold)
.foregroundColor(.compound.textPrimary)
.accessibilityLabel(L10n.commonInReplyTo(sender.displayName ?? sender.id))

Text(messagePreview)
.font(.compound.bodyMD)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,13 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
if shouldShowSenderDetails {
HStack(alignment: .top, spacing: 4) {
TimelineSenderAvatarView(timelineItem: timelineItem)
.accessibilityHidden(true)
Text(timelineItem.sender.displayName ?? timelineItem.sender.id)
.font(.compound.bodySMSemibold)
.foregroundColor(.compound.avatarColor(for: timelineItem.sender.id).foreground)
.lineLimit(1)
.padding(.vertical, senderNameVerticalPadding)
}
.accessibilityElement(children: .combine)
.accessibilityHidden(true)
.onTapGesture {
context.send(viewAction: .tappedOnUser(userID: timelineItem.sender.id))
}
Expand All @@ -98,6 +97,12 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
// Figma overlaps reactions by 3
VStack(alignment: alignment, spacing: -3) {
messageBubble
.accessibilityRepresentation {
VStack {
Text(timelineItem.sender.displayName ?? timelineItem.sender.id)
messageBubble
}
}
.accessibilityElement(children: .combine)

if !timelineItem.properties.reactions.isEmpty {
Expand Down Expand Up @@ -126,6 +131,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
}
.swipeRightAction {
Image(systemName: "arrowshape.turn.up.left")
.accessibilityHidden(true)
} shouldStartAction: {
context.viewState.timelineItemMenuActionProvider?(timelineItem.id)?.canReply ?? false
} action: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ struct TimelineReactionButton: View {
.longPressWithFeedback {
showReactionSummary(reaction.key)
}
.accessibilityHint(L10n.commonReaction)
.accessibilityAddTraits(reaction.isHighlighted ? .isSelected : [])
}

var label: some View {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ struct AudioRoomTimelineView: View {
}
.padding(.vertical, 12)
.padding(.horizontal, 6)
.accessibilityElement(children: .ignore)
.accessibilityLabel(L10n.commonAudio)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ struct FileRoomTimelineView: View {
}
.padding(.vertical, 12)
.padding(.horizontal, 6)
.accessibilityElement(children: .ignore)
.accessibilityLabel(L10n.commonFile)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ struct ImageRoomTimelineView: View {
}
.frame(maxHeight: min(300, max(100, timelineItem.content.height ?? .infinity)))
.aspectRatio(timelineItem.content.aspectRatio, contentMode: .fit)
.accessibilityElement(children: .ignore)
.accessibilityLabel(L10n.commonImage)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,40 @@ struct LocationRoomTimelineView: View {

var body: some View {
TimelineStyler(timelineItem: timelineItem) {
if let geoURI = timelineItem.content.geoURI {
VStack(alignment: .leading, spacing: 0) {
descriptionView
.frame(maxWidth: mapAspectRatio * mapMaxHeight, alignment: .leading)

MapLibreStaticMapView(geoURI: geoURI, mapSize: .init(width: mapAspectRatio * mapMaxHeight, height: mapMaxHeight)) {
LocationMarkerView()
}
.frame(maxHeight: mapMaxHeight)
.aspectRatio(mapAspectRatio, contentMode: .fit)
.clipped()
mainContent
.accessibilityElement(children: .ignore)
.accessibilityLabel(accessibilityLabel)
}
}

@ViewBuilder
private var mainContent: some View {
if let geoURI = timelineItem.content.geoURI {
VStack(alignment: .leading, spacing: 0) {
descriptionView
.frame(maxWidth: mapAspectRatio * mapMaxHeight, alignment: .leading)

MapLibreStaticMapView(geoURI: geoURI, mapSize: .init(width: mapAspectRatio * mapMaxHeight, height: mapMaxHeight)) {
LocationMarkerView()
}
} else {
FormattedBodyText(text: timelineItem.body, additionalWhitespacesCount: timelineItem.additionalWhitespaces(timelineStyle: timelineStyle))
.frame(maxHeight: mapMaxHeight)
.aspectRatio(mapAspectRatio, contentMode: .fit)
.clipped()
}
} else {
FormattedBodyText(text: timelineItem.body, additionalWhitespacesCount: timelineItem.additionalWhitespaces(timelineStyle: timelineStyle))
}
}

// MARK: - Private

private var accessibilityLabel: String {
if let description = timelineItem.content.description {
return "\(L10n.commonSharedLocation), \(description)"
}

return L10n.commonSharedLocation
}

@ViewBuilder
private var descriptionView: some View {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ struct StickerRoomTimelineView: View {
}
.frame(maxHeight: min(300, max(100, timelineItem.height ?? .infinity)))
.aspectRatio(timelineItem.aspectRatio, contentMode: .fit)
.accessibilityElement(children: .ignore)
.accessibilityLabel("\(L10n.commonSticker), \(timelineItem.body)")
}
.accessibilityLabel(timelineItem.body)
}

private var placeholder: some View {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ struct VideoRoomTimelineView: View {
thumbnail
.frame(maxHeight: min(300, max(100, timelineItem.content.height ?? .infinity)))
.aspectRatio(timelineItem.content.aspectRatio, contentMode: .fit)
.accessibilityElement(children: .ignore)
.accessibilityLabel(L10n.commonVideo)
}
}

Expand Down
1 change: 1 addition & 0 deletions changelog.d/1104.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Various accessibility fixes: add labels on timeline media, hide swipe to reply button, add sender on all messages, improve replies and reactions

0 comments on commit f96969a

Please sign in to comment.