diff --git a/ElementX/Resources/Localizations/en.lproj/Localizable.strings b/ElementX/Resources/Localizations/en.lproj/Localizable.strings
index c1594e4cd..79131f4d8 100644
--- a/ElementX/Resources/Localizations/en.lproj/Localizable.strings
+++ b/ElementX/Resources/Localizations/en.lproj/Localizable.strings
@@ -225,7 +225,6 @@
"common_reason" = "Reason";
"common_recovery_key" = "Recovery key";
"common_refreshing" = "Refreshing…";
-"common_replies" = "%1$d replies";
"common_replying_to" = "Replying to %1$@";
"common_report_a_bug" = "Report a bug";
"common_report_a_problem" = "Report a problem";
@@ -518,6 +517,8 @@
"screen_resolve_send_failure_you_unsigned_device_subtitle" = "One or more of your devices are unverified. You can send the message anyway, or you can cancel for now and try again later after you have verified all of your devices.";
"screen_resolve_send_failure_you_unsigned_device_title" = "Your message was not sent because you have not verified one or more of your devices";
"screen_room_event_pill" = "Message in %1$@";
+"screen_room_grouped_view_states_expand" = "Expand";
+"screen_room_grouped_view_states_reduce" = "Reduce";
"screen_room_mentions_at_room_subtitle" = "Notify the whole room";
"screen_room_multiple_knock_requests_view_all_button_title" = "View all";
"screen_room_pinned_banner_indicator" = "%1$@ of %2$@";
diff --git a/ElementX/Resources/Localizations/en.lproj/Localizable.stringsdict b/ElementX/Resources/Localizations/en.lproj/Localizable.stringsdict
index 0223b8c80..1c22beadc 100644
--- a/ElementX/Resources/Localizations/en.lproj/Localizable.stringsdict
+++ b/ElementX/Resources/Localizations/en.lproj/Localizable.stringsdict
@@ -98,6 +98,22 @@
%d votes
+ common_replies
+
+ NSStringLocalizedFormatKey
+ %#@COUNT@
+ COUNT
+
+ NSStringFormatSpecTypeKey
+ NSStringPluralRuleType
+ NSStringFormatValueTypeKey
+ d
+ one
+ %1$d reply
+ other
+ %1$d replies
+
+
notification_compat_summary_line_for_room
NSStringLocalizedFormatKey
diff --git a/ElementX/Sources/Generated/Strings.swift b/ElementX/Sources/Generated/Strings.swift
index 49a016b84..a6fc34ffe 100644
--- a/ElementX/Sources/Generated/Strings.swift
+++ b/ElementX/Sources/Generated/Strings.swift
@@ -522,7 +522,7 @@ internal enum L10n {
internal static var commonRecoveryKey: String { return L10n.tr("Localizable", "common_recovery_key") }
/// Refreshing…
internal static var commonRefreshing: String { return L10n.tr("Localizable", "common_refreshing") }
- /// %1$d replies
+ /// Plural format key: "%#@COUNT@"
internal static func commonReplies(_ p1: Int) -> String {
return L10n.tr("Localizable", "common_replies", p1)
}
@@ -2182,6 +2182,10 @@ internal enum L10n {
internal static func screenRoomEventPill(_ p1: Any) -> String {
return L10n.tr("Localizable", "screen_room_event_pill", String(describing: p1))
}
+ /// Expand
+ internal static var screenRoomGroupedViewStatesExpand: String { return L10n.tr("Localizable", "screen_room_grouped_view_states_expand") }
+ /// Reduce
+ internal static var screenRoomGroupedViewStatesReduce: String { return L10n.tr("Localizable", "screen_room_grouped_view_states_reduce") }
/// Would you like to invite them back?
internal static var screenRoomInviteAgainAlertMessage: String { return L10n.tr("Localizable", "screen_room_invite_again_alert_message") }
/// You are alone in this chat
diff --git a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/CollapsibleRoomTimelineView.swift b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/CollapsibleRoomTimelineView.swift
index 692217556..61716fecc 100644
--- a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/CollapsibleRoomTimelineView.swift
+++ b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/CollapsibleRoomTimelineView.swift
@@ -8,10 +8,16 @@
import SwiftUI
struct CollapsibleRoomTimelineView: View {
+ enum AccessibilityFocus {
+ case disclosure
+ case events
+ }
+
private let timelineItem: CollapsibleTimelineItem
private let groupedViewStates: [RoomTimelineItemViewState]
@State private var isExpanded = false
+ @AccessibilityFocusState private var accessibilityFocusState: AccessibilityFocus?
init(timelineItem: CollapsibleTimelineItem) {
self.timelineItem = timelineItem
@@ -21,13 +27,18 @@ struct CollapsibleRoomTimelineView: View {
var body: some View {
VStack(spacing: 0.0) {
Button {
- withElementAnimation {
+ if !UIAccessibility.isVoiceOverRunning {
+ withElementAnimation {
+ isExpanded.toggle()
+ }
+ } else {
isExpanded.toggle()
}
} label: {
HStack(alignment: .center, spacing: 8) {
Text(L10n.screenRoomTimelineStateChanges(timelineItem.items.count))
Text(Image(systemName: "chevron.forward"))
+ .accessibilityLabel(isExpanded ? L10n.screenRoomGroupedViewStatesReduce : L10n.screenRoomGroupedViewStatesExpand)
.rotationEffect(.degrees(isExpanded ? 90 : 0))
.animation(.elementDefault, value: isExpanded)
}
@@ -40,13 +51,21 @@ struct CollapsibleRoomTimelineView: View {
.buttonStyle(.plain)
.frame(maxWidth: .infinity)
.padding(.top, 8.0)
+ .accessibilityFocused($accessibilityFocusState, equals: .disclosure)
if isExpanded {
- ForEach(groupedViewStates) { viewState in
- RoomTimelineItemView(viewState: viewState)
+ VStack(spacing: 0.0) {
+ ForEach(groupedViewStates) { viewState in
+ RoomTimelineItemView(viewState: viewState)
+ }
}
+ .accessibilityElement(children: .contain)
+ .accessibilityFocused($accessibilityFocusState, equals: .events)
}
}
+ .onChange(of: isExpanded) { _, newValue in
+ accessibilityFocusState = newValue ? .events : .disclosure
+ }
}
}