From 265659c8cb173ca51ea297423022a3cc405cd605 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 19 Oct 2022 16:13:21 +1100 Subject: [PATCH] add accessibility labels for automation test --- Session/Calls/CallVC.swift | 1 + Session/Closed Groups/EditClosedGroupVC.swift | 9 ++++++++ .../Context Menu/ContextMenuVC+Action.swift | 12 +++++++--- .../ContextMenuVC+ActionView.swift | 2 +- .../ConversationVC+Interaction.swift | 4 ++++ Session/Conversations/ConversationVC.swift | 12 +++++++--- .../ExpandingAttachmentsButton.swift | 8 +++---- .../Conversations/Input View/InputView.swift | 18 +++++++++++---- .../Input View/MentionSelectionView.swift | 1 + .../Content Views/MediaPlaceholderView.swift | 2 +- .../Message Cells/VisibleMessageCell.swift | 1 + .../Settings/ThreadSettingsViewModel.swift | 16 ++++++++++++- .../ConversationTitleView.swift | 1 + .../Views & Modals/InfoBanner.swift | 7 +++--- Session/Home/HomeVC.swift | 6 ++--- .../New Conversation/NewConversationVC.swift | 15 ++++++++++-- Session/Home/New Conversation/NewDMVC.swift | 2 ++ .../CropScaleImageViewController.swift | 1 + .../SendMediaNavigationController.swift | 1 + Session/Onboarding/DisplayNameVC.swift | 3 ++- Session/Onboarding/LandingVC.swift | 2 ++ Session/Onboarding/LinkDeviceVC.swift | 3 ++- Session/Onboarding/PNModeVC.swift | 1 + Session/Onboarding/RegisterVC.swift | 3 ++- Session/Onboarding/SeedReminderView.swift | 1 + Session/Onboarding/SeedVC.swift | 2 ++ .../Settings/PrivacySettingsViewModel.swift | 2 ++ Session/Settings/SettingsViewModel.swift | 6 +++-- Session/Shared/Types/SessionCell+Info.swift | 23 ++++++++++++++++++- .../Types/SessionTableViewModel+NavItem.swift | 11 +++++++-- Session/Shared/UserSelectionVC.swift | 5 +++- Session/Shared/Views/SessionAvatarCell.swift | 3 +++ .../Views/SessionCell+AccessoryView.swift | 11 ++++++++- Session/Shared/Views/SessionCell.swift | 7 ++++-- .../Components/ConfirmationModal.swift | 23 +++++++++++++++++++ SignalUtilitiesKit/Utilities/UIView+OWS.swift | 20 ++++++++-------- 36 files changed, 197 insertions(+), 48 deletions(-) diff --git a/Session/Calls/CallVC.swift b/Session/Calls/CallVC.swift index 652c87888..b960976ed 100644 --- a/Session/Calls/CallVC.swift +++ b/Session/Calls/CallVC.swift @@ -111,6 +111,7 @@ final class CallVC: UIViewController, VideoPreviewDelegate { private lazy var hangUpButton: UIButton = { let result = UIButton(type: .custom) + result.accessibilityLabel = "End call button" result.setImage( UIImage(named: "EndCall")? .withRenderingMode(.alwaysTemplate), diff --git a/Session/Closed Groups/EditClosedGroupVC.swift b/Session/Closed Groups/EditClosedGroupVC.swift index 42c150a15..3e00e0a26 100644 --- a/Session/Closed Groups/EditClosedGroupVC.swift +++ b/Session/Closed Groups/EditClosedGroupVC.swift @@ -30,6 +30,7 @@ final class EditClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegat private lazy var groupNameLabel: UILabel = { let result: UILabel = UILabel() + result.accessibilityLabel = "Group name" result.font = .boldSystemFont(ofSize: Values.veryLargeFontSize) result.themeTextColor = .textPrimary result.lineBreakMode = .byTruncatingTail @@ -50,6 +51,7 @@ final class EditClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegat private lazy var addMembersButton: SessionButton = { let result: SessionButton = SessionButton(style: .bordered, size: .medium) + result.accessibilityLabel = "Add members" result.setTitle("vc_conversation_settings_invite_button_title".localized(), for: .normal) result.addTarget(self, action: #selector(addMembers), for: UIControl.Event.touchUpInside) result.contentEdgeInsets = UIEdgeInsets(top: 0, leading: Values.mediumSpacing, bottom: 0, trailing: Values.mediumSpacing) @@ -59,6 +61,7 @@ final class EditClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegat @objc private lazy var tableView: UITableView = { let result: UITableView = UITableView() + result.accessibilityLabel = "Contact" result.dataSource = self result.delegate = self result.separatorStyle = .none @@ -264,6 +267,12 @@ final class EditClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegat } let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleDoneButtonTapped)) + if isEditingGroupName { + doneButton.accessibilityLabel = "Accept name change" + } + else { + doneButton.accessibilityLabel = "Apply changes" + } doneButton.themeTintColor = .textPrimary navigationItem.rightBarButtonItem = doneButton } diff --git a/Session/Conversations/Context Menu/ContextMenuVC+Action.swift b/Session/Conversations/Context Menu/ContextMenuVC+Action.swift index 282f90ade..b8f19816b 100644 --- a/Session/Conversations/Context Menu/ContextMenuVC+Action.swift +++ b/Session/Conversations/Context Menu/ContextMenuVC+Action.swift @@ -10,6 +10,7 @@ extension ContextMenuVC { let isEmojiAction: Bool let isEmojiPlus: Bool let isDismissAction: Bool + let accessibilityLabel: String? let work: () -> Void // MARK: - Initialization @@ -20,6 +21,7 @@ extension ContextMenuVC { isEmojiAction: Bool = false, isEmojiPlus: Bool = false, isDismissAction: Bool = false, + accessibilityLabel: String? = nil, work: @escaping () -> Void ) { self.icon = icon @@ -27,6 +29,7 @@ extension ContextMenuVC { self.isEmojiAction = isEmojiAction self.isEmojiPlus = isEmojiPlus self.isDismissAction = isDismissAction + self.accessibilityLabel = accessibilityLabel self.work = work } @@ -35,7 +38,8 @@ extension ContextMenuVC { static func reply(_ cellViewModel: MessageViewModel, _ delegate: ContextMenuActionDelegate?) -> Action { return Action( icon: UIImage(named: "ic_reply"), - title: "context_menu_reply".localized() + title: "context_menu_reply".localized(), + accessibilityLabel: "Reply to message" ) { delegate?.reply(cellViewModel) } } @@ -56,14 +60,16 @@ extension ContextMenuVC { static func delete(_ cellViewModel: MessageViewModel, _ delegate: ContextMenuActionDelegate?) -> Action { return Action( icon: UIImage(named: "ic_trash"), - title: "TXT_DELETE_TITLE".localized() + title: "TXT_DELETE_TITLE".localized(), + accessibilityLabel: "Delete message" ) { delegate?.delete(cellViewModel) } } static func save(_ cellViewModel: MessageViewModel, _ delegate: ContextMenuActionDelegate?) -> Action { return Action( icon: UIImage(named: "ic_download"), - title: "context_menu_save".localized() + title: "context_menu_save".localized(), + accessibilityLabel: "Save attachment" ) { delegate?.save(cellViewModel) } } diff --git a/Session/Conversations/Context Menu/ContextMenuVC+ActionView.swift b/Session/Conversations/Context Menu/ContextMenuVC+ActionView.swift index 07ebbc5ca..ac061dd5d 100644 --- a/Session/Conversations/Context Menu/ContextMenuVC+ActionView.swift +++ b/Session/Conversations/Context Menu/ContextMenuVC+ActionView.swift @@ -40,7 +40,7 @@ extension ContextMenuVC { self.dismiss = dismiss super.init(frame: CGRect.zero) - + self.accessibilityLabel = action.accessibilityLabel setUpViewHierarchy() } diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index a0fbbfcb8..a79a92fdd 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -69,6 +69,8 @@ extension ConversationVC: title: "modal_call_permission_request_title".localized(), explanation: "modal_call_permission_request_explanation".localized(), confirmTitle: "vc_settings_title".localized(), + confirmAccessibilityLabel: "Settings", + cancelAccessibilityLabel: "Cancel", dismissOnConfirm: false // Custom dismissal logic ) { [weak self] _ in self?.dismiss(animated: true) { @@ -854,6 +856,8 @@ extension ConversationVC: range: (message as NSString).range(of: cellViewModel.authorName) ), confirmTitle: "modal_download_button_title".localized(), + confirmAccessibilityLabel: "Download media", + cancelAccessibilityLabel: "Don't download media", dismissOnConfirm: false // Custom dismissal logic ) { [weak self] _ in self?.viewModel.trustContact() diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 620a4c4ea..205c08314 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -191,8 +191,10 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl lazy var blockedBanner: InfoBanner = { let result: InfoBanner = InfoBanner( message: self.viewModel.blockedBannerMessage, - backgroundColor: .danger + backgroundColor: .danger, + messageLabelAccessibilityLabel: "Blocked banner text" ) + result.accessibilityLabel = "Blocked banner" let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(unblock)) result.addGestureRecognizer(tapGestureRecognizer) @@ -240,6 +242,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl private lazy var messageRequestAcceptButton: UIButton = { let result: SessionButton = SessionButton(style: .bordered, size: .medium) + result.accessibilityLabel = "Accept message request" result.translatesAutoresizingMaskIntoConstraints = false result.setTitle("TXT_DELETE_ACCEPT".localized(), for: .normal) result.addTarget(self, action: #selector(acceptMessageRequest), for: .touchUpInside) @@ -249,6 +252,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl private lazy var messageRequestDeleteButton: UIButton = { let result: SessionButton = SessionButton(style: .destructive, size: .medium) + result.accessibilityLabel = "Decline message request" result.translatesAutoresizingMaskIntoConstraints = false result.setTitle("TXT_DECLINE_TITLE".localized(), for: .normal) result.addTarget(self, action: #selector(deleteMessageRequest), for: .touchUpInside) @@ -258,6 +262,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl private lazy var messageRequestBlockButton: UIButton = { let result: UIButton = UIButton() + result.accessibilityLabel = "Block message request" result.translatesAutoresizingMaskIntoConstraints = false result.clipsToBounds = true result.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16) @@ -1036,7 +1041,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl profilePictureView.addGestureRecognizer(tapGestureRecognizer) let settingsButtonItem: UIBarButtonItem = UIBarButtonItem(customView: profilePictureView) - settingsButtonItem.accessibilityLabel = "Settings button" + settingsButtonItem.accessibilityLabel = "More options" settingsButtonItem.isAccessibilityElement = true if SessionCall.isEnabled && !threadData.threadIsNoteToSelf { @@ -1046,6 +1051,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl target: self, action: #selector(startCall) ) + callButton.accessibilityLabel = "Call button" navigationItem.rightBarButtonItems = [settingsButtonItem, callButton] } @@ -1055,7 +1061,7 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl default: let rightBarButtonItem: UIBarButtonItem = UIBarButtonItem(image: UIImage(named: "Gear"), style: .plain, target: self, action: #selector(openSettings)) - rightBarButtonItem.accessibilityLabel = "Settings button" + rightBarButtonItem.accessibilityLabel = "More options" rightBarButtonItem.isAccessibilityElement = true navigationItem.rightBarButtonItems = [rightBarButtonItem] diff --git a/Session/Conversations/Input View/ExpandingAttachmentsButton.swift b/Session/Conversations/Input View/ExpandingAttachmentsButton.swift index f2e983a03..cff2fda71 100644 --- a/Session/Conversations/Input View/ExpandingAttachmentsButton.swift +++ b/Session/Conversations/Input View/ExpandingAttachmentsButton.swift @@ -26,28 +26,28 @@ final class ExpandingAttachmentsButton: UIView, InputViewButtonDelegate { // MARK: UI Components lazy var gifButton: InputViewButton = { let result = InputViewButton(icon: #imageLiteral(resourceName: "actionsheet_gif_black"), delegate: self, hasOpaqueBackground: true) - result.accessibilityLabel = "accessibility_gif_button".localized() + result.accessibilityLabel = "GIF button" return result }() lazy var gifButtonContainer = container(for: gifButton) lazy var documentButton: InputViewButton = { let result = InputViewButton(icon: #imageLiteral(resourceName: "actionsheet_document_black"), delegate: self, hasOpaqueBackground: true) - result.accessibilityLabel = "accessibility_document_button".localized() + result.accessibilityLabel = "Documents folder" return result }() lazy var documentButtonContainer = container(for: documentButton) lazy var libraryButton: InputViewButton = { let result = InputViewButton(icon: #imageLiteral(resourceName: "actionsheet_camera_roll_black"), delegate: self, hasOpaqueBackground: true) - result.accessibilityLabel = "accessibility_library_button".localized() + result.accessibilityLabel = "Images folder" return result }() lazy var libraryButtonContainer = container(for: libraryButton) lazy var cameraButton: InputViewButton = { let result = InputViewButton(icon: #imageLiteral(resourceName: "actionsheet_camera_black"), delegate: self, hasOpaqueBackground: true) - result.accessibilityLabel = "accessibility_camera_button".localized() + result.accessibilityLabel = "Select camera button" return result }() diff --git a/Session/Conversations/Input View/InputView.swift b/Session/Conversations/Input View/InputView.swift index 8fd6d99f6..5139a2379 100644 --- a/Session/Conversations/Input View/InputView.swift +++ b/Session/Conversations/Input View/InputView.swift @@ -50,12 +50,16 @@ final class InputView: UIView, InputViewButtonDelegate, InputTextViewDelegate, M // MARK: - UI private var bottomStackView: UIStackView? - private lazy var attachmentsButton = ExpandingAttachmentsButton(delegate: delegate) + private lazy var attachmentsButton: ExpandingAttachmentsButton = { + let result = ExpandingAttachmentsButton(delegate: delegate) + result.accessibilityLabel = "Attachments button" + + return result + }() private lazy var voiceMessageButton: InputViewButton = { let result = InputViewButton(icon: #imageLiteral(resourceName: "Microphone"), delegate: self) - result.accessibilityLabel = "VOICE_MESSAGE_TOO_SHORT_ALERT_TITLE".localized() - result.accessibilityHint = "VOICE_MESSAGE_TOO_SHORT_ALERT_MESSAGE".localized() + result.accessibilityLabel = "New voice message" return result }() @@ -63,7 +67,7 @@ final class InputView: UIView, InputViewButtonDelegate, InputTextViewDelegate, M private lazy var sendButton: InputViewButton = { let result = InputViewButton(icon: #imageLiteral(resourceName: "ArrowUp"), isSendButton: true, delegate: self) result.isHidden = true - result.accessibilityLabel = "ATTACHMENT_APPROVAL_SEND_BUTTON".localized() + result.accessibilityLabel = "Send message button" return result }() @@ -78,6 +82,7 @@ final class InputView: UIView, InputViewButtonDelegate, InputTextViewDelegate, M private lazy var mentionsViewContainer: UIView = { let result: UIView = UIView() + result.accessibilityLabel = "Mentions list" result.alpha = 0 let backgroundView = UIView() @@ -107,7 +112,10 @@ final class InputView: UIView, InputViewButtonDelegate, InputTextViewDelegate, M // setUpViewHierarchy() for why these values are the way they are. let adjustment = (InputViewButton.expandedSize - InputViewButton.size) / 2 let maxWidth = UIScreen.main.bounds.width - 2 * InputViewButton.expandedSize - 2 * Values.smallSpacing - 2 * (Values.mediumSpacing - adjustment) - return InputTextView(delegate: self, maxWidth: maxWidth) + let result = InputTextView(delegate: self, maxWidth: maxWidth) + result.accessibilityLabel = "Message input box" + + return result }() private lazy var disabledInputLabel: UILabel = { diff --git a/Session/Conversations/Input View/MentionSelectionView.swift b/Session/Conversations/Input View/MentionSelectionView.swift index 70ceb6b4f..881059cc3 100644 --- a/Session/Conversations/Input View/MentionSelectionView.swift +++ b/Session/Conversations/Input View/MentionSelectionView.swift @@ -24,6 +24,7 @@ final class MentionSelectionView: UIView, UITableViewDataSource, UITableViewDele private lazy var tableView: UITableView = { let result: UITableView = UITableView() + result.accessibilityLabel = "Contact" result.dataSource = self result.delegate = self result.separatorStyle = .none diff --git a/Session/Conversations/Message Cells/Content Views/MediaPlaceholderView.swift b/Session/Conversations/Message Cells/Content Views/MediaPlaceholderView.swift index 09939731c..754ded084 100644 --- a/Session/Conversations/Message Cells/Content Views/MediaPlaceholderView.swift +++ b/Session/Conversations/Message Cells/Content Views/MediaPlaceholderView.swift @@ -12,7 +12,7 @@ final class MediaPlaceholderView: UIView { init(cellViewModel: MessageViewModel, textColor: ThemeValue) { super.init(frame: CGRect.zero) - + self.accessibilityLabel = "Untrusted attachment message" setUpViewHierarchy(cellViewModel: cellViewModel, textColor: textColor) } diff --git a/Session/Conversations/Message Cells/VisibleMessageCell.swift b/Session/Conversations/Message Cells/VisibleMessageCell.swift index 84e3004ed..a7285d316 100644 --- a/Session/Conversations/Message Cells/VisibleMessageCell.swift +++ b/Session/Conversations/Message Cells/VisibleMessageCell.swift @@ -144,6 +144,7 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate { internal lazy var messageStatusImageView: UIImageView = { let result = UIImageView() + result.accessibilityLabel = "Message sent status tick" result.contentMode = .scaleAspectFit result.layer.cornerRadius = VisibleMessageCell.messageStatusImageViewSize / 2 result.layer.masksToBounds = true diff --git a/Session/Conversations/Settings/ThreadSettingsViewModel.swift b/Session/Conversations/Settings/ThreadSettingsViewModel.swift index e771e26fb..178a5ea03 100644 --- a/Session/Conversations/Settings/ThreadSettingsViewModel.swift +++ b/Session/Conversations/Settings/ThreadSettingsViewModel.swift @@ -151,7 +151,8 @@ class ThreadSettingsViewModel: SessionTableViewModel Void)? @@ -41,6 +44,9 @@ extension SessionCell { isEnabled: Bool = true, shouldHaveBackground: Bool = true, accessibilityIdentifier: String? = nil, + accessibilityLabel: String? = nil, + leftAccessoryAccessibilityLabel: String? = nil, + rightAccessoryAccessibilityLabel: String? = nil, confirmationInfo: ConfirmationModal.Info? = nil, onTap: ((UIView?) -> Void)? ) { @@ -55,6 +61,9 @@ extension SessionCell { self.isEnabled = isEnabled self.shouldHaveBackground = shouldHaveBackground self.accessibilityIdentifier = accessibilityIdentifier + self.accessibilityLabel = accessibilityLabel + self.leftAccessoryAccessibilityLabel = leftAccessoryAccessibilityLabel + self.rightAccessoryAccessibilityLabel = rightAccessoryAccessibilityLabel self.confirmationInfo = confirmationInfo self.onTap = onTap } @@ -71,6 +80,9 @@ extension SessionCell { isEnabled: Bool = true, shouldHaveBackground: Bool = true, accessibilityIdentifier: String? = nil, + accessibilityLabel: String? = nil, + leftAccessoryAccessibilityLabel: String? = nil, + rightAccessoryAccessibilityLabel: String? = nil, confirmationInfo: ConfirmationModal.Info? = nil, onTap: (() -> Void)? = nil ) { @@ -85,6 +97,9 @@ extension SessionCell { self.isEnabled = isEnabled self.shouldHaveBackground = shouldHaveBackground self.accessibilityIdentifier = accessibilityIdentifier + self.accessibilityLabel = accessibilityLabel + self.leftAccessoryAccessibilityLabel = leftAccessoryAccessibilityLabel + self.rightAccessoryAccessibilityLabel = rightAccessoryAccessibilityLabel self.confirmationInfo = confirmationInfo self.onTap = (onTap != nil ? { _ in onTap?() } : nil) } @@ -104,6 +119,9 @@ extension SessionCell { isEnabled.hash(into: &hasher) shouldHaveBackground.hash(into: &hasher) accessibilityIdentifier.hash(into: &hasher) + accessibilityLabel.hash(into: &hasher) + leftAccessoryAccessibilityLabel.hash(into: &hasher) + rightAccessoryAccessibilityLabel.hash(into: &hasher) confirmationInfo.hash(into: &hasher) } @@ -118,7 +136,10 @@ extension SessionCell { lhs.extraAction == rhs.extraAction && lhs.isEnabled == rhs.isEnabled && lhs.shouldHaveBackground == rhs.shouldHaveBackground && - lhs.accessibilityIdentifier == rhs.accessibilityIdentifier + lhs.accessibilityIdentifier == rhs.accessibilityIdentifier && + lhs.accessibilityLabel == rhs.accessibilityLabel && + lhs.leftAccessoryAccessibilityLabel == rhs.leftAccessoryAccessibilityLabel && + lhs.rightAccessoryAccessibilityLabel == rhs.rightAccessoryAccessibilityLabel ) } } diff --git a/Session/Shared/Types/SessionTableViewModel+NavItem.swift b/Session/Shared/Types/SessionTableViewModel+NavItem.swift index b1eb7714b..17efd8153 100644 --- a/Session/Shared/Types/SessionTableViewModel+NavItem.swift +++ b/Session/Shared/Types/SessionTableViewModel+NavItem.swift @@ -12,6 +12,7 @@ extension SessionTableViewModel { let style: UIBarButtonItem.Style let systemItem: UIBarButtonItem.SystemItem? let accessibilityIdentifier: String + let accessibilityLabel: String? let action: (() -> Void)? // MARK: - Initialization @@ -20,6 +21,7 @@ extension SessionTableViewModel { id: NavItemId, systemItem: UIBarButtonItem.SystemItem?, accessibilityIdentifier: String, + accessibilityLabel: String? = nil, action: (() -> Void)? = nil ) { self.id = id @@ -27,6 +29,7 @@ extension SessionTableViewModel { self.style = .plain self.systemItem = systemItem self.accessibilityIdentifier = accessibilityIdentifier + self.accessibilityLabel = accessibilityLabel self.action = action } @@ -35,6 +38,7 @@ extension SessionTableViewModel { image: UIImage?, style: UIBarButtonItem.Style, accessibilityIdentifier: String, + accessibilityLabel: String? = nil, action: (() -> Void)? = nil ) { self.id = id @@ -42,6 +46,7 @@ extension SessionTableViewModel { self.style = style self.systemItem = nil self.accessibilityIdentifier = accessibilityIdentifier + self.accessibilityLabel = accessibilityLabel self.action = action } @@ -54,7 +59,8 @@ extension SessionTableViewModel { style: style, target: nil, action: nil, - accessibilityIdentifier: accessibilityIdentifier + accessibilityIdentifier: accessibilityIdentifier, + accessibilityLabel: accessibilityLabel ) } @@ -62,7 +68,8 @@ extension SessionTableViewModel { barButtonSystemItem: systemItem, target: nil, action: nil, - accessibilityIdentifier: accessibilityIdentifier + accessibilityIdentifier: accessibilityIdentifier, + accessibilityLabel: accessibilityLabel ) } diff --git a/Session/Shared/UserSelectionVC.swift b/Session/Shared/UserSelectionVC.swift index 3bbc97ab4..808fb542d 100644 --- a/Session/Shared/UserSelectionVC.swift +++ b/Session/Shared/UserSelectionVC.swift @@ -48,7 +48,10 @@ final class UserSelectionVC: BaseVC, UITableViewDataSource, UITableViewDelegate setNavBarTitle(navBarTitle) - navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleDoneButtonTapped)) + let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleDoneButtonTapped)) + doneButton.accessibilityLabel = "Done" + navigationItem.rightBarButtonItem = doneButton + view.addSubview(tableView) tableView.pin(to: view) } diff --git a/Session/Shared/Views/SessionAvatarCell.swift b/Session/Shared/Views/SessionAvatarCell.swift index 8016641bb..c6166a0bf 100644 --- a/Session/Shared/Views/SessionAvatarCell.swift +++ b/Session/Shared/Views/SessionAvatarCell.swift @@ -52,6 +52,7 @@ class SessionAvatarCell: UITableViewCell { fileprivate let profilePictureView: ProfilePictureView = { let view: ProfilePictureView = ProfilePictureView() + view.accessibilityLabel = "Profile picture" view.translatesAutoresizingMaskIntoConstraints = false view.size = Values.largeProfilePictureSize @@ -69,6 +70,7 @@ class SessionAvatarCell: UITableViewCell { private lazy var displayNameLabel: UILabel = { let label: UILabel = UILabel() + label.accessibilityLabel = "Username" label.translatesAutoresizingMaskIntoConstraints = false label.font = .ows_mediumFont(withSize: Values.veryLargeFontSize) label.themeTextColor = .textPrimary @@ -98,6 +100,7 @@ class SessionAvatarCell: UITableViewCell { private let descriptionLabel: SRCopyableLabel = { let label: SRCopyableLabel = SRCopyableLabel() + label.accessibilityLabel = "Session ID" label.translatesAutoresizingMaskIntoConstraints = false label.themeTextColor = .textPrimary label.textAlignment = .center diff --git a/Session/Shared/Views/SessionCell+AccessoryView.swift b/Session/Shared/Views/SessionCell+AccessoryView.swift index c904af354..dffda5793 100644 --- a/Session/Shared/Views/SessionCell+AccessoryView.swift +++ b/Session/Shared/Views/SessionCell+AccessoryView.swift @@ -225,7 +225,8 @@ extension SessionCell { public func update( with accessory: Accessory?, tintColor: ThemeValue, - isEnabled: Bool + isEnabled: Bool, + accessibilityLabel: String? ) { guard let accessory: Accessory = accessory else { return } @@ -234,6 +235,7 @@ extension SessionCell { switch accessory { case .icon(let image, let iconSize, let customTint, let shouldFill): + imageView.accessibilityLabel = accessibilityLabel imageView.image = image imageView.themeTintColor = (customTint ?? tintColor) imageView.contentMode = (shouldFill ? .scaleAspectFill : .scaleAspectFit) @@ -256,6 +258,7 @@ extension SessionCell { case .iconAsync(let iconSize, let customTint, let shouldFill, let setter): setter(imageView) + imageView.accessibilityLabel = accessibilityLabel imageView.themeTintColor = (customTint ?? tintColor) imageView.contentMode = (shouldFill ? .scaleAspectFill : .scaleAspectFit) imageView.isHidden = false @@ -276,6 +279,7 @@ extension SessionCell { imageViewConstraints.forEach { $0.isActive = true } case .toggle(let dataSource): + toggleSwitch.accessibilityLabel = accessibilityLabel toggleSwitch.isHidden = false toggleSwitch.isEnabled = isEnabled toggleSwitchConstraints.forEach { $0.isActive = true } @@ -287,6 +291,7 @@ extension SessionCell { } case .dropDown(let dataSource): + dropDownLabel.accessibilityLabel = accessibilityLabel dropDownLabel.text = dataSource.currentStringValue dropDownStackView.isHidden = false dropDownStackViewConstraints.forEach { $0.isActive = true } @@ -302,6 +307,7 @@ extension SessionCell { ) radioBorderView.layer.cornerRadius = (size.borderSize / 2) + radioView.accessibilityLabel = accessibilityLabel radioView.alpha = (wasOldSelection ? 0.3 : 1) radioView.isHidden = (!isSelected && !storedSelection) radioView.themeBackgroundColor = (isSelected || wasOldSelection ? @@ -322,12 +328,14 @@ extension SessionCell { radioBorderViewConstraints.forEach { $0.isActive = true } case .highlightingBackgroundLabel(let title): + highlightingBackgroundLabel.accessibilityLabel = accessibilityLabel highlightingBackgroundLabel.text = title highlightingBackgroundLabel.themeTextColor = tintColor highlightingBackgroundLabel.isHidden = false highlightingBackgroundLabelConstraints.forEach { $0.isActive = true } case .profile(let profileId, let profile): + profilePictureView.accessibilityLabel = accessibilityLabel profilePictureView.update( publicKey: profileId, profile: profile, @@ -338,6 +346,7 @@ extension SessionCell { case .customView(let viewGenerator): let generatedView: UIView = viewGenerator() + generatedView.accessibilityLabel = accessibilityLabel addSubview(generatedView) generatedView.pin(.top, to: .top, of: self) diff --git a/Session/Shared/Views/SessionCell.swift b/Session/Shared/Views/SessionCell.swift index 0cc4c6a4a..3cef4932b 100644 --- a/Session/Shared/Views/SessionCell.swift +++ b/Session/Shared/Views/SessionCell.swift @@ -308,6 +308,7 @@ public class SessionCell: UITableViewCell { self.subtitleExtraView = info.subtitleExtraViewGenerator?() self.onExtraActionTap = info.extraAction?.onTap self.accessibilityIdentifier = info.accessibilityIdentifier + self.accessibilityLabel = info.accessibilityLabel let leftFitToEdge: Bool = (info.leftAccessory?.shouldFitToEdge == true) let rightFitToEdge: Bool = (!leftFitToEdge && info.rightAccessory?.shouldFitToEdge == true) @@ -315,12 +316,14 @@ public class SessionCell: UITableViewCell { leftAccessoryView.update( with: info.leftAccessory, tintColor: info.tintColor, - isEnabled: info.isEnabled + isEnabled: info.isEnabled, + accessibilityLabel: info.leftAccessoryAccessibilityLabel ) rightAccessoryView.update( with: info.rightAccessory, tintColor: info.tintColor, - isEnabled: info.isEnabled + isEnabled: info.isEnabled, + accessibilityLabel: info.rightAccessoryAccessibilityLabel ) rightAccessoryFillConstraint.isActive = rightFitToEdge contentStackView.layoutMargins = UIEdgeInsets( diff --git a/SessionUIKit/Components/ConfirmationModal.swift b/SessionUIKit/Components/ConfirmationModal.swift index 5c75e5851..e588fd361 100644 --- a/SessionUIKit/Components/ConfirmationModal.swift +++ b/SessionUIKit/Components/ConfirmationModal.swift @@ -21,10 +21,13 @@ public class ConfirmationModal: Modal { let title: String let explanation: String? let attributedExplanation: NSAttributedString? + let accessibilityLabel: String? public let stateToShow: State let confirmTitle: String? + let confirmAccessibilityLabel: String? let confirmStyle: ThemeValue let cancelTitle: String + let cancelAccessibilityLabel: String? let cancelStyle: ThemeValue let dismissOnConfirm: Bool let onConfirm: ((UIViewController) -> ())? @@ -36,10 +39,13 @@ public class ConfirmationModal: Modal { title: String, explanation: String? = nil, attributedExplanation: NSAttributedString? = nil, + accessibilityLabel: String? = nil, stateToShow: State = .always, confirmTitle: String? = nil, + confirmAccessibilityLabel: String? = nil, confirmStyle: ThemeValue = .alert_text, cancelTitle: String = "TXT_CANCEL_TITLE".localized(), + cancelAccessibilityLabel: String? = nil, cancelStyle: ThemeValue = .danger, dismissOnConfirm: Bool = true, onConfirm: ((UIViewController) -> ())? = nil, @@ -48,10 +54,13 @@ public class ConfirmationModal: Modal { self.title = title self.explanation = explanation self.attributedExplanation = attributedExplanation + self.accessibilityLabel = accessibilityLabel self.stateToShow = stateToShow self.confirmTitle = confirmTitle + self.confirmAccessibilityLabel = confirmAccessibilityLabel self.confirmStyle = confirmStyle self.cancelTitle = cancelTitle + self.cancelAccessibilityLabel = cancelAccessibilityLabel self.cancelStyle = cancelStyle self.dismissOnConfirm = dismissOnConfirm self.onConfirm = onConfirm @@ -67,10 +76,14 @@ public class ConfirmationModal: Modal { return Info( title: self.title, explanation: self.explanation, + attributedExplanation: self.attributedExplanation, + accessibilityLabel: self.accessibilityLabel, stateToShow: self.stateToShow, confirmTitle: self.confirmTitle, + confirmAccessibilityLabel: self.confirmAccessibilityLabel, confirmStyle: self.confirmStyle, cancelTitle: self.cancelTitle, + cancelAccessibilityLabel: self.cancelAccessibilityLabel, cancelStyle: self.cancelStyle, dismissOnConfirm: self.dismissOnConfirm, onConfirm: (onConfirm ?? self.onConfirm), @@ -85,10 +98,13 @@ public class ConfirmationModal: Modal { lhs.title == rhs.title && lhs.explanation == rhs.explanation && lhs.attributedExplanation == rhs.attributedExplanation && + lhs.accessibilityLabel == rhs.accessibilityLabel && lhs.stateToShow == rhs.stateToShow && lhs.confirmTitle == rhs.confirmTitle && + lhs.confirmAccessibilityLabel == rhs.confirmAccessibilityLabel && lhs.confirmStyle == rhs.confirmStyle && lhs.cancelTitle == rhs.cancelTitle && + lhs.cancelAccessibilityLabel == rhs.cancelAccessibilityLabel && lhs.cancelStyle == rhs.cancelStyle && lhs.dismissOnConfirm == rhs.dismissOnConfirm ) @@ -98,10 +114,13 @@ public class ConfirmationModal: Modal { title.hash(into: &hasher) explanation.hash(into: &hasher) attributedExplanation.hash(into: &hasher) + accessibilityLabel.hash(into: &hasher) stateToShow.hash(into: &hasher) confirmTitle.hash(into: &hasher) + confirmAccessibilityLabel.hash(into: &hasher) confirmStyle.hash(into: &hasher) cancelTitle.hash(into: &hasher) + cancelAccessibilityLabel.hash(into: &hasher) cancelStyle.hash(into: &hasher) dismissOnConfirm.hash(into: &hasher) } @@ -207,11 +226,15 @@ public class ConfirmationModal: Modal { info.explanation == nil && info.attributedExplanation == nil ) + confirmButton.accessibilityLabel = info.confirmAccessibilityLabel confirmButton.setTitle(info.confirmTitle, for: .normal) confirmButton.setThemeTitleColor(info.confirmStyle, for: .normal) confirmButton.isHidden = (info.confirmTitle == nil) + cancelButton.accessibilityLabel = info.cancelAccessibilityLabel cancelButton.setTitle(info.cancelTitle, for: .normal) cancelButton.setThemeTitleColor(info.cancelStyle, for: .normal) + + self.accessibilityLabel = info.accessibilityLabel } required init?(coder: NSCoder) { diff --git a/SignalUtilitiesKit/Utilities/UIView+OWS.swift b/SignalUtilitiesKit/Utilities/UIView+OWS.swift index a2a257324..b3a9978e4 100644 --- a/SignalUtilitiesKit/Utilities/UIView+OWS.swift +++ b/SignalUtilitiesKit/Utilities/UIView+OWS.swift @@ -291,43 +291,43 @@ public extension UIBezierPath { @objc public extension UIBarButtonItem { - convenience init(image: UIImage?, style: UIBarButtonItem.Style, target: Any?, action: Selector?, accessibilityIdentifier: String) { + convenience init(image: UIImage?, style: UIBarButtonItem.Style, target: Any?, action: Selector?, accessibilityIdentifier: String, accessibilityLabel: String? = nil) { self.init(image: image, style: style, target: target, action: action) self.accessibilityIdentifier = accessibilityIdentifier - self.accessibilityLabel = accessibilityIdentifier + self.accessibilityLabel = accessibilityLabel == nil ? accessibilityIdentifier : accessibilityLabel self.isAccessibilityElement = true } - convenience init(image: UIImage?, landscapeImagePhone: UIImage?, style: UIBarButtonItem.Style, target: Any?, action: Selector?, accessibilityIdentifier: String) { + convenience init(image: UIImage?, landscapeImagePhone: UIImage?, style: UIBarButtonItem.Style, target: Any?, action: Selector?, accessibilityIdentifier: String, accessibilityLabel: String? = nil) { self.init(image: image, landscapeImagePhone: landscapeImagePhone, style: style, target: target, action: action) self.accessibilityIdentifier = accessibilityIdentifier - self.accessibilityLabel = accessibilityIdentifier + self.accessibilityLabel = accessibilityLabel == nil ? accessibilityIdentifier : accessibilityLabel self.isAccessibilityElement = true } - convenience init(title: String?, style: UIBarButtonItem.Style, target: Any?, action: Selector?, accessibilityIdentifier: String) { + convenience init(title: String?, style: UIBarButtonItem.Style, target: Any?, action: Selector?, accessibilityIdentifier: String, accessibilityLabel: String? = nil) { self.init(title: title, style: style, target: target, action: action) self.accessibilityIdentifier = accessibilityIdentifier - self.accessibilityLabel = accessibilityIdentifier + self.accessibilityLabel = accessibilityLabel == nil ? accessibilityIdentifier : accessibilityLabel self.isAccessibilityElement = true } - convenience init(barButtonSystemItem systemItem: UIBarButtonItem.SystemItem, target: Any?, action: Selector?, accessibilityIdentifier: String) { + convenience init(barButtonSystemItem systemItem: UIBarButtonItem.SystemItem, target: Any?, action: Selector?, accessibilityIdentifier: String, accessibilityLabel: String? = nil) { self.init(barButtonSystemItem: systemItem, target: target, action: action) self.accessibilityIdentifier = accessibilityIdentifier - self.accessibilityLabel = accessibilityIdentifier + self.accessibilityLabel = accessibilityLabel == nil ? accessibilityIdentifier : accessibilityLabel self.isAccessibilityElement = true } - convenience init(customView: UIView, accessibilityIdentifier: String) { + convenience init(customView: UIView, accessibilityIdentifier: String, accessibilityLabel: String? = nil) { self.init(customView: customView) self.accessibilityIdentifier = accessibilityIdentifier - self.accessibilityLabel = accessibilityIdentifier + self.accessibilityLabel = accessibilityLabel == nil ? accessibilityIdentifier : accessibilityLabel self.isAccessibilityElement = true } }