From bb071b461fdb81c931de761e6b406a19f8683bc4 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Fri, 10 Nov 2023 16:28:07 +0200 Subject: [PATCH] Fixes #660 - Expose message actions to voice over rotor --- ElementX.xcodeproj/project.pbxproj | 8 ++++---- .../Localizations/en.lproj/Localizable.strings | 5 +++-- ElementX/Sources/Generated/Strings.swift | 4 +++- ...swift => TimelineItemAccessibilityModifier.swift} | 12 +++++++++--- .../View/Style/TimelineItemBubbledStylerView.swift | 4 +++- .../View/Style/TimelineItemPlainStylerView.swift | 4 +++- changelog.d/660.feature | 1 + 7 files changed, 26 insertions(+), 12 deletions(-) rename ElementX/Sources/Screens/RoomScreen/View/Style/{TimelineAccessibilityModifier.swift => TimelineItemAccessibilityModifier.swift} (74%) create mode 100644 changelog.d/660.feature diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 3648d4aa25..9f488a23d9 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -397,6 +397,7 @@ 6A0E7551E0D1793245F34CDD /* ClientError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09A267106B9585D3D0CFC0D /* ClientError.swift */; }; 6AD722DD92E465E56D2885AB /* BugReportScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */; }; 6AECC84BE14A13440120FED8 /* NSESettingsProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB4F169D653296023ED65E6 /* NSESettingsProtocol.swift */; }; + 6B05AA5D9BBCD6D8D63B80EB /* TimelineItemAccessibilityModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74C6F3DAD167F972702C8893 /* TimelineItemAccessibilityModifier.swift */; }; 6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */; }; 6B4BF4A6450F55939B49FAEF /* PollOptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67779D9A1B797285A09B7720 /* PollOptionView.swift */; }; 6BAD956B909A6E29F6CC6E7C /* ButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC23C63849452BC86EA2852 /* ButtonStyle.swift */; }; @@ -621,7 +622,6 @@ A2A5AB2E8B3F5CA769E531FA /* TextBasedRoomTimelineViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E47F18A9A077E351CEA10D4 /* TextBasedRoomTimelineViewProtocol.swift */; }; A33784831AD880A670CAA9F9 /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */; }; A37EED79941AD3B7140B3822 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287FC98AF2664EAD79C0D902 /* UIDevice.swift */; }; - A387720CCE406FC524B240E4 /* TimelineAccessibilityModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525DA7B2B85E57C32E6C86FE /* TimelineAccessibilityModifier.swift */; }; A3A7A05E8F9B7EB0E1A09A2A /* SoftLogoutScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05596E4A11A8C9346E9E54AE /* SoftLogoutScreenCoordinator.swift */; }; A3D7110C1E75E7B4A73BE71C /* VoiceMessageRecorderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93C94C30E3135BC9290DE13 /* VoiceMessageRecorderTests.swift */; }; A3E390675E9730C176B59E1B /* ImageProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E8A8047B50E3607ACD354E /* ImageProviderProtocol.swift */; }; @@ -1324,7 +1324,6 @@ 51C454AE59914B551A6D02C0 /* UserProfileProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileProxy.swift; sourceTree = ""; }; 52135BD9E0E7A091688F627A /* MessageForwardingScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreenModels.swift; sourceTree = ""; }; 5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreen.swift; sourceTree = ""; }; - 525DA7B2B85E57C32E6C86FE /* TimelineAccessibilityModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineAccessibilityModifier.swift; sourceTree = ""; }; 5281C5CDC4A712265A0B5FBF /* PollRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollRoomTimelineItem.swift; sourceTree = ""; }; 52BD6ED18E2EB61E28C340AD /* AttributedString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedString.swift; sourceTree = ""; }; 52D7074991B3267B26D89B22 /* MockRoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomTimelineController.swift; sourceTree = ""; }; @@ -1437,6 +1436,7 @@ 74611A4182DCF5F4D42696EC /* XCTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestCase.swift; sourceTree = ""; }; 7475C5AE20BA896930907EA8 /* AudioRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRoomTimelineItemContent.swift; sourceTree = ""; }; 748AE77AC3B0A01223033B87 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 74C6F3DAD167F972702C8893 /* TimelineItemAccessibilityModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemAccessibilityModifier.swift; sourceTree = ""; }; 74DD0855F2F76D47E5555082 /* MediaUploadPreviewScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenCoordinator.swift; sourceTree = ""; }; 74E08B8A66948E9690F38B94 /* SecureBackupLogoutConfirmationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupLogoutConfirmationScreenViewModelProtocol.swift; sourceTree = ""; }; 752A0EB49BF5BCEA37EDF7A3 /* Signposter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Signposter.swift; sourceTree = ""; }; @@ -3864,8 +3864,8 @@ 21DC6A9917A7123E7E9A3F81 /* LongPressWithFeedback.swift */, 49E45C3DC740D3AB9A47FD32 /* SwipeToReplyView.swift */, 7CA3F8E905DF50BF22ECC18F /* ThreadDecorator.swift */, - 525DA7B2B85E57C32E6C86FE /* TimelineAccessibilityModifier.swift */, E2DCA495ED42D2463DDAA94D /* TimelineBubbleLayout.swift */, + 74C6F3DAD167F972702C8893 /* TimelineItemAccessibilityModifier.swift */, 98A2932515EA11D3DD8A3506 /* TimelineItemBubbledStylerView.swift */, 94BCC8A9C73C1F838122C645 /* TimelineItemPlainStylerView.swift */, 8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */, @@ -5828,9 +5828,9 @@ 53F1196F9C69512306A2693F /* TextRoomTimelineItemContent.swift in Sources */, 5E0F2E612718BB4397A6D40A /* TextRoomTimelineView.swift in Sources */, 5B2D1210B40570D87B11BD3B /* ThreadDecorator.swift in Sources */, - A387720CCE406FC524B240E4 /* TimelineAccessibilityModifier.swift in Sources */, 43EF6D8E694F54C5471BF5F3 /* TimelineBubbleLayout.swift in Sources */, 5D2AF8C0DF872E7985F8FE54 /* TimelineDeliveryStatusView.swift in Sources */, + 6B05AA5D9BBCD6D8D63B80EB /* TimelineItemAccessibilityModifier.swift in Sources */, 157E5FDDF419C0B2CA7E2C28 /* TimelineItemBubbledStylerView.swift in Sources */, FBCCF1EA25A071324FCD8544 /* TimelineItemDebugView.swift in Sources */, 020C530986D7B97631877FEF /* TimelineItemMacContextMenu.swift in Sources */, diff --git a/ElementX/Resources/Localizations/en.lproj/Localizable.strings b/ElementX/Resources/Localizations/en.lproj/Localizable.strings index 7537a9f840..f71ec10841 100644 --- a/ElementX/Resources/Localizations/en.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/en.lproj/Localizable.strings @@ -114,6 +114,7 @@ "common_link_copied_to_clipboard" = "Link copied to clipboard"; "common_loading" = "Loading…"; "common_message" = "Message"; +"common_message_actions" = "Message actions"; "common_message_layout" = "Message layout"; "common_message_removed" = "Message removed"; "common_modern" = "Modern"; @@ -543,7 +544,6 @@ "screen_signed_out_subtitle" = "You might have been signed out for one of the reasons listed below. Please sign in again to continue using %@."; "screen_signed_out_title" = "You’re signed out"; "screen_signout_confirmation_dialog_content" = "Are you sure you want to sign out?"; -"screen_signout_confirmation_dialog_title" = "Sign out"; "screen_signout_in_progress_dialog_content" = "Signing out…"; "screen_signout_key_backup_disabled_subtitle" = "You are about to sign out of your last session. If you sign out now, you will lose access to your encrypted messages."; "screen_signout_key_backup_disabled_title" = "You have turned off backup"; @@ -561,7 +561,7 @@ "screen_waitlist_title" = "You’re almost there."; "screen_waitlist_title_success" = "You're in."; "screen_welcome_bullet_1" = "Calls, polls, search and more will be added later this year."; -"screen_welcome_bullet_2" = "Message history for encrypted rooms won’t be available in this update."; +"screen_welcome_bullet_2" = "Message history for encrypted rooms isn’t available yet."; "screen_welcome_bullet_3" = "We’d love to hear from you, let us know what you think via the settings page."; "screen_welcome_button" = "Let's go!"; "screen_welcome_subtitle" = "Here’s what you need to know:"; @@ -651,5 +651,6 @@ "screen_room_error_failed_processing_media" = "Failed processing media to upload, please try again."; "screen_room_notification_settings_mode_mentions_and_keywords" = "Mentions and Keywords only"; "screen_signout_confirmation_dialog_submit" = "Sign out"; +"screen_signout_confirmation_dialog_title" = "Sign out"; "screen_signout_preference_item" = "Sign out"; "screen_waitlist_message_success" = "Welcome to %1$@!"; diff --git a/ElementX/Sources/Generated/Strings.swift b/ElementX/Sources/Generated/Strings.swift index c76b422985..60d7ed8562 100644 --- a/ElementX/Sources/Generated/Strings.swift +++ b/ElementX/Sources/Generated/Strings.swift @@ -254,6 +254,8 @@ public enum L10n { } /// Message public static var commonMessage: String { return L10n.tr("Localizable", "common_message") } + /// Message actions + public static var commonMessageActions: String { return L10n.tr("Localizable", "common_message_actions") } /// Message layout public static var commonMessageLayout: String { return L10n.tr("Localizable", "common_message_layout") } /// Message removed @@ -1344,7 +1346,7 @@ public enum L10n { public static var screenWaitlistTitleSuccess: String { return L10n.tr("Localizable", "screen_waitlist_title_success") } /// Calls, polls, search and more will be added later this year. public static var screenWelcomeBullet1: String { return L10n.tr("Localizable", "screen_welcome_bullet_1") } - /// Message history for encrypted rooms won’t be available in this update. + /// Message history for encrypted rooms isn’t available yet. public static var screenWelcomeBullet2: String { return L10n.tr("Localizable", "screen_welcome_bullet_2") } /// We’d love to hear from you, let us know what you think via the settings page. public static var screenWelcomeBullet3: String { return L10n.tr("Localizable", "screen_welcome_bullet_3") } diff --git a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineAccessibilityModifier.swift b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemAccessibilityModifier.swift similarity index 74% rename from ElementX/Sources/Screens/RoomScreen/View/Style/TimelineAccessibilityModifier.swift rename to ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemAccessibilityModifier.swift index 6a038bae5b..c657085de7 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineAccessibilityModifier.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemAccessibilityModifier.swift @@ -16,8 +16,9 @@ import SwiftUI -private struct TimelineAccessibilityModifier: ViewModifier { +private struct TimelineItemAccessibilityModifier: ViewModifier { let timelineItem: RoomTimelineItemProtocol + let action: () -> Void @ViewBuilder func body(content: Content) -> some View { @@ -33,6 +34,11 @@ private struct TimelineAccessibilityModifier: ViewModifier { } } .accessibilityElement(children: .combine) + .accessibilityActions { + Button(L10n.commonMessageActions) { + action() + } + } default: content .accessibilityElement(children: .combine) @@ -41,7 +47,7 @@ private struct TimelineAccessibilityModifier: ViewModifier { } extension View { - func timelineAccessibility(_ timelineItem: RoomTimelineItemProtocol) -> some View { - modifier(TimelineAccessibilityModifier(timelineItem: timelineItem)) + func timelineItemAccessibility(_ timelineItem: RoomTimelineItemProtocol, action: @escaping () -> Void) -> some View { + modifier(TimelineItemAccessibilityModifier(timelineItem: timelineItem, action: action)) } } diff --git a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemBubbledStylerView.swift b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemBubbledStylerView.swift index eb5c5e4138..8bb5c1b24e 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemBubbledStylerView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemBubbledStylerView.swift @@ -100,7 +100,9 @@ struct TimelineItemBubbledStylerView: View { // Figma overlaps reactions by 3 VStack(alignment: alignment, spacing: -3) { messageBubble - .timelineAccessibility(timelineItem) + .timelineItemAccessibility(timelineItem) { + context.send(viewAction: .timelineItemMenu(itemID: timelineItem.id)) + } if !timelineItem.properties.reactions.isEmpty { TimelineReactionsView(context: context, diff --git a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemPlainStylerView.swift b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemPlainStylerView.swift index 3b90d00309..a0f387e326 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemPlainStylerView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemPlainStylerView.swift @@ -64,7 +64,9 @@ struct TimelineItemPlainStylerView: View { content() .layoutPriority(1) - .timelineAccessibility(timelineItem) + .timelineItemAccessibility(timelineItem) { + context.send(viewAction: .timelineItemMenu(itemID: timelineItem.id)) + } } .onTapGesture(count: 2) { context.send(viewAction: .displayEmojiPicker(itemID: timelineItem.id)) diff --git a/changelog.d/660.feature b/changelog.d/660.feature new file mode 100644 index 0000000000..415dfce222 --- /dev/null +++ b/changelog.d/660.feature @@ -0,0 +1 @@ +Expose message actions to voice over rotor \ No newline at end of file