diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index b547ea561f..165ccc3dec 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -8895,3 +8895,14 @@ Sorry for the inconvenience."; "Premium.Purchase.OnlyOneSubscriptionAllowed" = "You have already purchased Telegram Premium for another account. You can only have one Telegram Premium subscription on one Apple ID."; "Call.VoiceOver.Minimize" = "Minimize Call"; + +"Login.VoiceOver.PhoneCountryCode" = "Phone country code"; +"Login.VoiceOver.PhoneNumber" = "Phone number"; +"Login.VoiceOver.Password" = "Password"; + +"Gallery.VoiceOver.Delete" = "Delete"; +"Gallery.VoiceOver.Fullscreen" = "Fullscreen"; +"Gallery.VoiceOver.Share" = "Share"; +"Gallery.VoiceOver.Edit" = "Edit"; +"Gallery.VoiceOver.Stickers" = "Stickers"; +"Gallery.VoiceOver.PictureInPicture" = "Picture-in-Picture"; diff --git a/submodules/AttachmentUI/Sources/AttachmentPanel.swift b/submodules/AttachmentUI/Sources/AttachmentPanel.swift index 1640c9d4de..bcca2e3b1f 100644 --- a/submodules/AttachmentUI/Sources/AttachmentPanel.swift +++ b/submodules/AttachmentUI/Sources/AttachmentPanel.swift @@ -894,6 +894,26 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate { containerSize: CGSize(width: buttonWidth, height: buttonSize.height) ) buttonTransition.setFrame(view: buttonView, frame: buttonFrame) + var accessibilityTitle = "" + switch type { + case .gallery: + accessibilityTitle = self.presentationData.strings.Attachment_Gallery + case .file: + accessibilityTitle = self.presentationData.strings.Attachment_File + case .location: + accessibilityTitle = self.presentationData.strings.Attachment_Location + case .contact: + accessibilityTitle = self.presentationData.strings.Attachment_Contact + case .poll: + accessibilityTitle = self.presentationData.strings.Attachment_Poll + case let .app(_, appName, _): + accessibilityTitle = appName + case .standalone: + accessibilityTitle = "" + } + buttonView.isAccessibilityElement = true + buttonView.accessibilityLabel = accessibilityTitle + buttonView.accessibilityTraits = [.button] } } diff --git a/submodules/AuthorizationUI/Sources/AuthorizationSequenceCodeEntryControllerNode.swift b/submodules/AuthorizationUI/Sources/AuthorizationSequenceCodeEntryControllerNode.swift index 7fe7482657..bff27a5960 100644 --- a/submodules/AuthorizationUI/Sources/AuthorizationSequenceCodeEntryControllerNode.swift +++ b/submodules/AuthorizationUI/Sources/AuthorizationSequenceCodeEntryControllerNode.swift @@ -22,11 +22,14 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF private let animationNode: AnimatedStickerNode private let titleNode: ImmediateTextNode + private let titleActivateAreaNode: AccessibilityAreaNode private let titleIconNode: ASImageNode private let currentOptionNode: ImmediateTextNode + private let currentOptionActivateAreaNode: AccessibilityAreaNode private var dustNode: InvisibleInkDustNode? private let currentOptionInfoNode: ASTextNode + private let currentOptionInfoActivateAreaNode: AccessibilityAreaNode private let nextOptionTitleNode: ImmediateTextNode private let nextOptionButtonNode: HighlightableButtonNode @@ -91,6 +94,9 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF self.titleNode.isUserInteractionEnabled = false self.titleNode.displaysAsynchronously = false + self.titleActivateAreaNode = AccessibilityAreaNode() + self.titleActivateAreaNode.accessibilityTraits = .staticText + self.titleIconNode = ASImageNode() self.titleIconNode.isLayerBacked = true self.titleIconNode.displayWithoutProcessing = true @@ -102,10 +108,16 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF self.currentOptionNode.lineSpacing = 0.1 self.currentOptionNode.maximumNumberOfLines = 0 + self.currentOptionActivateAreaNode = AccessibilityAreaNode() + self.currentOptionActivateAreaNode.accessibilityTraits = .staticText + self.currentOptionInfoNode = ASTextNode() self.currentOptionInfoNode.isUserInteractionEnabled = false self.currentOptionInfoNode.displaysAsynchronously = false + self.currentOptionInfoActivateAreaNode = AccessibilityAreaNode() + self.currentOptionInfoActivateAreaNode.accessibilityTraits = .staticText + self.nextOptionTitleNode = ImmediateTextNode() self.nextOptionButtonNode = HighlightableButtonNode() @@ -113,6 +125,12 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF let (nextOptionText, nextOptionActive) = authorizationNextOptionText(currentType: .sms(length: 5), nextType: .call, timeout: 60, strings: self.strings, primaryColor: self.theme.list.itemPrimaryTextColor, accentColor: self.theme.list.itemAccentColor) self.nextOptionTitleNode.attributedText = nextOptionText self.nextOptionButtonNode.isUserInteractionEnabled = nextOptionActive + self.nextOptionButtonNode.accessibilityLabel = nextOptionText.string + if nextOptionActive { + self.nextOptionButtonNode.accessibilityTraits = [.button] + } else { + self.nextOptionButtonNode.accessibilityTraits = [.button, .notEnabled] + } self.nextOptionButtonNode.addSubnode(self.nextOptionTitleNode) self.codeInputView = CodeInputView() @@ -156,8 +174,10 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF self.addSubnode(self.codeInputView) self.addSubnode(self.titleNode) + self.addSubnode(self.titleActivateAreaNode) self.addSubnode(self.titleIconNode) self.addSubnode(self.currentOptionNode) + self.addSubnode(self.currentOptionActivateAreaNode) self.addSubnode(self.currentOptionInfoNode) self.addSubnode(self.nextOptionButtonNode) self.addSubnode(self.animationNode) @@ -266,10 +286,18 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF self.appleSignInAllowed = appleSignInAllowed self.currentOptionNode.attributedText = authorizationCurrentOptionText(codeType, phoneNumber: self.phoneNumber, email: self.email, strings: self.strings, primaryColor: self.theme.list.itemPrimaryTextColor, accentColor: self.theme.list.itemAccentColor) + self.currentOptionActivateAreaNode.accessibilityLabel = self.currentOptionNode.attributedText?.string ?? "" if case .missedCall = codeType { self.currentOptionInfoNode.attributedText = NSAttributedString(string: self.strings.Login_CodePhonePatternInfoText, font: Font.regular(17.0), textColor: self.theme.list.itemPrimaryTextColor, paragraphAlignment: .center) + self.currentOptionInfoActivateAreaNode.accessibilityLabel = self.currentOptionInfoNode.attributedText?.string ?? "" + if self.currentOptionInfoActivateAreaNode.supernode == nil { + self.addSubnode(self.currentOptionInfoActivateAreaNode) + } } else { self.currentOptionInfoNode.attributedText = NSAttributedString(string: "", font: Font.regular(17.0), textColor: self.theme.list.itemPrimaryTextColor) + if self.currentOptionInfoActivateAreaNode.supernode != nil { + self.currentOptionInfoActivateAreaNode.removeFromSupernode() + } } if let timeout = timeout { #if DEBUG @@ -283,7 +311,12 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF let (nextOptionText, nextOptionActive) = authorizationNextOptionText(currentType: codeType, nextType: nextType, timeout: strongSelf.currentTimeoutTime, strings: strongSelf.strings, primaryColor: strongSelf.theme.list.itemPrimaryTextColor, accentColor: strongSelf.theme.list.itemAccentColor) strongSelf.nextOptionTitleNode.attributedText = nextOptionText strongSelf.nextOptionButtonNode.isUserInteractionEnabled = nextOptionActive - + strongSelf.nextOptionButtonNode.accessibilityLabel = nextOptionText.string + if nextOptionActive { + strongSelf.nextOptionButtonNode.accessibilityTraits = [.button] + } else { + strongSelf.nextOptionButtonNode.accessibilityTraits = [.button, .notEnabled] + } if let layoutArguments = strongSelf.layoutArguments { strongSelf.containerLayoutUpdated(layoutArguments.0, navigationBarHeight: layoutArguments.1, transition: .immediate) } @@ -301,7 +334,12 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF let (nextOptionText, nextOptionActive) = authorizationNextOptionText(currentType: codeType, nextType: nextType, timeout: self.currentTimeoutTime, strings: self.strings, primaryColor: self.theme.list.itemPrimaryTextColor, accentColor: self.theme.list.itemAccentColor) self.nextOptionTitleNode.attributedText = nextOptionText self.nextOptionButtonNode.isUserInteractionEnabled = nextOptionActive - + self.nextOptionButtonNode.accessibilityLabel = nextOptionText.string + if nextOptionActive { + self.nextOptionButtonNode.accessibilityTraits = [.button] + } else { + self.nextOptionButtonNode.accessibilityTraits = [.button, .notEnabled] + } if let layoutArguments = self.layoutArguments { self.containerLayoutUpdated(layoutArguments.0, navigationBarHeight: layoutArguments.1, transition: .immediate) } @@ -347,6 +385,8 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_EnterCodeTelegramTitle, font: Font.semibold(40.0), textColor: self.theme.list.itemPrimaryTextColor) } + self.titleActivateAreaNode.accessibilityLabel = self.titleNode.attributedText?.string ?? "" + if let inputHeight = layout.inputHeight { if let codeType = self.codeType, case .email = codeType { insets.bottom = max(inputHeight, insets.bottom) @@ -525,6 +565,10 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF } self.nextOptionTitleNode.frame = self.nextOptionButtonNode.bounds + + self.titleActivateAreaNode.frame = self.titleNode.frame + self.currentOptionActivateAreaNode.frame = self.currentOptionNode.frame + self.currentOptionInfoActivateAreaNode.frame = self.currentOptionInfoNode.frame } func activateInput() { diff --git a/submodules/AuthorizationUI/Sources/AuthorizationSequencePasswordEntryControllerNode.swift b/submodules/AuthorizationUI/Sources/AuthorizationSequencePasswordEntryControllerNode.swift index d53a11d8f1..f67dfecd9c 100644 --- a/submodules/AuthorizationUI/Sources/AuthorizationSequencePasswordEntryControllerNode.swift +++ b/submodules/AuthorizationUI/Sources/AuthorizationSequencePasswordEntryControllerNode.swift @@ -15,7 +15,9 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT private let animationNode: AnimatedStickerNode private let titleNode: ASTextNode + private let titleActivateAreaNode: AccessibilityAreaNode private let noticeNode: ASTextNode + private let noticeActivateAreaNode: AccessibilityAreaNode private let forgotNode: HighlightableButtonNode private let resetNode: HighlightableButtonNode private let proceedNode: SolidRoundedButtonNode @@ -68,15 +70,23 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT self.titleNode.displaysAsynchronously = false self.titleNode.attributedText = NSAttributedString(string: strings.LoginPassword_Title, font: Font.semibold(28.0), textColor: self.theme.list.itemPrimaryTextColor) + self.titleActivateAreaNode = AccessibilityAreaNode() + self.titleActivateAreaNode.accessibilityTraits = .staticText + self.noticeNode = ASTextNode() self.noticeNode.isUserInteractionEnabled = false self.noticeNode.displaysAsynchronously = false self.noticeNode.lineSpacing = 0.1 self.noticeNode.attributedText = NSAttributedString(string: strings.TwoStepAuth_EnterPasswordHelp, font: Font.regular(17.0), textColor: self.theme.list.itemPrimaryTextColor, paragraphAlignment: .center) + self.noticeActivateAreaNode = AccessibilityAreaNode() + self.noticeActivateAreaNode.accessibilityTraits = .staticText + self.forgotNode = HighlightableButtonNode() self.forgotNode.displaysAsynchronously = false self.forgotNode.setAttributedTitle(NSAttributedString(string: self.strings.TwoStepAuth_EnterPasswordForgot, font: Font.regular(16.0), textColor: self.theme.list.itemAccentColor, paragraphAlignment: .center), for: []) + self.forgotNode.accessibilityLabel = self.strings.TwoStepAuth_EnterPasswordForgot + self.forgotNode.accessibilityTraits = [.button] self.resetNode = HighlightableButtonNode() self.resetNode.displaysAsynchronously = false @@ -95,6 +105,7 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT self.codeField.textField.keyboardAppearance = self.theme.rootController.keyboardColor.keyboardAppearance self.codeField.textField.disableAutomaticKeyboardHandling = [.forward, .backward] self.codeField.textField.tintColor = self.theme.list.itemAccentColor + self.codeField.textField.accessibilityHint = self.strings.Login_VoiceOver_Password self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0, gloss: false) self.proceedNode.progressType = .embedded @@ -114,9 +125,11 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT self.addSubnode(self.codeSeparatorNode) self.addSubnode(self.codeField) self.addSubnode(self.titleNode) + self.addSubnode(self.titleActivateAreaNode) self.addSubnode(self.forgotNode) self.addSubnode(self.resetNode) self.addSubnode(self.noticeNode) + self.addSubnode(self.noticeActivateAreaNode) self.addSubnode(self.animationNode) self.addSubnode(self.proceedNode) @@ -214,6 +227,12 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT self.animationNode.updateLayout(size: animationSize) let _ = layoutAuthorizationItems(bounds: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: layout.size.height - insets.top - insets.bottom - additionalBottomInset)), items: items, transition: transition, failIfDoesNotFit: false) + + self.titleActivateAreaNode.accessibilityLabel = self.titleNode.attributedText?.string ?? "" + self.noticeActivateAreaNode.accessibilityLabel = self.noticeNode.attributedText?.string ?? "" + + self.titleActivateAreaNode.frame = self.titleNode.frame + self.noticeActivateAreaNode.frame = self.noticeNode.frame } func activateInput() { diff --git a/submodules/AuthorizationUI/Sources/AuthorizationSequencePhoneEntryControllerNode.swift b/submodules/AuthorizationUI/Sources/AuthorizationSequencePhoneEntryControllerNode.swift index aaf572aa59..d28dfd9e8c 100644 --- a/submodules/AuthorizationUI/Sources/AuthorizationSequencePhoneEntryControllerNode.swift +++ b/submodules/AuthorizationUI/Sources/AuthorizationSequencePhoneEntryControllerNode.swift @@ -110,6 +110,8 @@ private final class PhoneAndCountryNode: ASDisplayNode { self.phoneInputNode.numberField.textField.textColor = theme.list.itemPrimaryTextColor self.phoneInputNode.countryCodeField.textField.tintColor = theme.list.itemAccentColor self.phoneInputNode.numberField.textField.tintColor = theme.list.itemAccentColor + self.phoneInputNode.countryCodeField.accessibilityHint = strings.Login_VoiceOver_PhoneCountryCode + self.phoneInputNode.numberField.accessibilityHint = strings.Login_VoiceOver_PhoneNumber self.phoneInputNode.countryCodeField.textField.tintColor = theme.list.itemAccentColor self.phoneInputNode.numberField.textField.tintColor = theme.list.itemAccentColor @@ -172,6 +174,9 @@ private final class PhoneAndCountryNode: ASDisplayNode { strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = NSAttributedString(string: strings.Login_PhonePlaceholder, font: Font.regular(20.0), textColor: theme.list.itemPlaceholderTextColor) } + strongSelf.countryButton.accessibilityLabel = strongSelf.countryButton.attributedTitle(for: .normal)?.string ?? "" + strongSelf.countryButton.accessibilityTraits = [.button] + if strongSelf.hasCountry { strongSelf.hasNumberUpdated?(!strongSelf.phoneInputNode.codeAndNumber.2.isEmpty) } else { @@ -289,7 +294,9 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode { private let animationNode: AnimatedStickerNode private let managedAnimationNode: ManagedPhoneAnimationNode private let titleNode: ASTextNode + private let titleActivateAreaNode: AccessibilityAreaNode private let noticeNode: ASTextNode + private let noticeActivateAreaNode: AccessibilityAreaNode private let phoneAndCountryNode: PhoneAndCountryNode private let contactSyncNode: ContactSyncNode private let proceedNode: SolidRoundedButtonNode @@ -378,12 +385,18 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode { self.titleNode.displaysAsynchronously = false self.titleNode.attributedText = NSAttributedString(string: account == nil ? strings.Login_NewNumber : strings.Login_PhoneTitle, font: Font.light(30.0), textColor: theme.list.itemPrimaryTextColor) + self.titleActivateAreaNode = AccessibilityAreaNode() + self.titleActivateAreaNode.accessibilityTraits = .staticText + self.noticeNode = ASTextNode() self.noticeNode.maximumNumberOfLines = 0 self.noticeNode.isUserInteractionEnabled = true self.noticeNode.displaysAsynchronously = false self.noticeNode.lineSpacing = 0.1 + self.noticeActivateAreaNode = AccessibilityAreaNode() + self.noticeActivateAreaNode.accessibilityTraits = .staticText + self.noticeNode.attributedText = NSAttributedString(string: account == nil ? strings.ChangePhoneNumberNumber_Help : strings.Login_PhoneAndCountryHelp, font: Font.regular(17.0), textColor: theme.list.itemPrimaryTextColor, paragraphAlignment: .center) self.contactSyncNode = ContactSyncNode(theme: theme, strings: strings) @@ -404,6 +417,8 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode { self.addSubnode(self.titleNode) self.addSubnode(self.noticeNode) + self.addSubnode(self.titleActivateAreaNode) + self.addSubnode(self.noticeActivateAreaNode) self.addSubnode(self.phoneAndCountryNode) self.addSubnode(self.contactSyncNode) self.addSubnode(self.proceedNode) @@ -534,6 +549,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode { let additionalBottomInset: CGFloat = layout.size.width > 320.0 ? 80.0 : 10.0 self.titleNode.attributedText = NSAttributedString(string: self.account == nil ? strings.Login_NewNumber : strings.Login_PhoneTitle, font: Font.bold(28.0), textColor: self.theme.list.itemPrimaryTextColor) + self.titleActivateAreaNode.accessibilityLabel = self.titleNode.attributedText?.string ?? "" let inset: CGFloat = 24.0 let maximumWidth: CGFloat = min(430.0, layout.size.width) @@ -587,6 +603,10 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode { let _ = layoutAuthorizationItems(bounds: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: layout.size.height - insets.top - insets.bottom - additionalBottomInset)), items: items, transition: transition, failIfDoesNotFit: false) transition.updateFrame(node: self.managedAnimationNode, frame: self.animationNode.frame) + + self.titleActivateAreaNode.frame = self.titleNode.frame + self.noticeActivateAreaNode.accessibilityLabel = self.noticeNode.attributedText?.string ?? "" + self.noticeActivateAreaNode.frame = self.noticeNode.frame } func activateInput() { @@ -726,6 +746,7 @@ final class PhoneConfirmationController: ViewController { class Node: ASDisplayNode { private let theme: PresentationTheme + private let strings: PresentationStrings private let code: String private let number: String @@ -740,6 +761,7 @@ final class PhoneConfirmationController: ViewController { private let phoneTargetNode: ImmediateTextNode private let textNode: ImmediateTextNode + private let textActivateAreaNode: AccessibilityAreaNode private let cancelButton: HighlightableButtonNode fileprivate let proceedNode: SolidRoundedButtonNode @@ -751,6 +773,7 @@ final class PhoneConfirmationController: ViewController { init(theme: PresentationTheme, strings: PresentationStrings, code: String, number: String) { self.theme = theme + self.strings = strings self.code = code self.number = number @@ -767,8 +790,13 @@ final class PhoneConfirmationController: ViewController { self.textNode.attributedText = NSAttributedString(string: strings.Login_PhoneNumberConfirmation, font: Font.regular(17.0), textColor: theme.list.itemPrimaryTextColor) self.textNode.textAlignment = .center + self.textActivateAreaNode = AccessibilityAreaNode() + self.textActivateAreaNode.accessibilityTraits = .staticText + self.cancelButton = HighlightableButtonNode() self.cancelButton.setTitle(strings.Login_Edit, with: Font.regular(19.0), with: theme.list.itemAccentColor, for: .normal) + self.cancelButton.accessibilityTraits = [.button] + self.cancelButton.accessibilityLabel = strings.Login_Edit self.proceedNode = SolidRoundedButtonNode(title: strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: theme), height: 50.0, cornerRadius: 11.0, gloss: false) self.proceedNode.progressType = .embedded @@ -814,6 +842,7 @@ final class PhoneConfirmationController: ViewController { self.addSubnode(self.phoneTargetNode) self.addSubnode(self.textNode) + self.addSubnode(self.textActivateAreaNode) self.addSubnode(self.cancelButton) self.addSubnode(self.proceedNode) @@ -1009,6 +1038,8 @@ final class PhoneConfirmationController: ViewController { let textSize = self.textNode.updateLayout(backgroundSize) transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((backgroundSize.width - textSize.width) / 2.0), y: 88.0), size: textSize).offsetBy(dx: backgroundFrame.minX, dy: backgroundFrame.minY)) + self.textActivateAreaNode.frame = self.textNode.frame + self.textActivateAreaNode.accessibilityLabel = "\(self.code) \(self.number). \(self.strings.Login_PhoneNumberConfirmation)" let proceedWidth = backgroundSize.width - 16.0 * 2.0 let proceedHeight = self.proceedNode.updateLayout(width: proceedWidth, transition: transition) diff --git a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift index 4ae0fc051c..d495ab1dbf 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift @@ -196,7 +196,7 @@ private enum ChatListRecentEntry: Comparable, Identifiable { } return ContactsPeerItem( - presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings), + presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder), sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, context: context, diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index 0b3757cf34..99c8479b81 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -319,7 +319,7 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL } } return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListAdditionalCategoryItem( - presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings), + presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder), context: context, title: title, image: image, @@ -525,7 +525,7 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL } return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ContactsPeerItem( - presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings), + presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder), sortOrder: presentationData.nameSortOrder, displayOrder: presentationData.nameDisplayOrder, context: context, @@ -564,7 +564,7 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL let status: ContactsPeerItemStatus = .none return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ContactsPeerItem( - presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings), + presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder), sortOrder: presentationData.nameSortOrder, displayOrder: presentationData.nameDisplayOrder, context: context, @@ -778,7 +778,7 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL } return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ContactsPeerItem( - presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings), + presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder), sortOrder: presentationData.nameSortOrder, displayOrder: presentationData.nameDisplayOrder, context: context, @@ -817,7 +817,7 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL let status: ContactsPeerItemStatus = .none return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ContactsPeerItem( - presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings), + presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder), sortOrder: presentationData.nameSortOrder, displayOrder: presentationData.nameDisplayOrder, context: context, @@ -887,7 +887,7 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL } } return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListAdditionalCategoryItem( - presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings), + presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder), context: context, title: title, image: image, diff --git a/submodules/CountrySelectionUI/Sources/AuthorizationSequenceCountrySelectionControllerNode.swift b/submodules/CountrySelectionUI/Sources/AuthorizationSequenceCountrySelectionControllerNode.swift index ce30ca2f17..9acd1d0382 100644 --- a/submodules/CountrySelectionUI/Sources/AuthorizationSequenceCountrySelectionControllerNode.swift +++ b/submodules/CountrySelectionUI/Sources/AuthorizationSequenceCountrySelectionControllerNode.swift @@ -64,7 +64,7 @@ func localizedCountryNamesAndCodes(strings: PresentationStrings) -> [((String, S let locale = localeWithStrings(strings) var result: [((String, String), String, [Int])] = [] for country in AuthorizationSequenceCountrySelectionController.countries() { - if country.hidden { + if country.hidden || country.id == "FT" { continue } if let englishCountryName = usEnglishLocale.localizedString(forRegionCode: country.id), let countryName = locale.localizedString(forRegionCode: country.id) { @@ -362,20 +362,24 @@ final class AuthorizationSequenceCountrySelectionControllerNode: ASDisplayNode, } var countryName: String + var cleanCountryName: String let originalCountryName: String let code: String if tableView === self.tableView { - countryName = self.sections[indexPath.section].1[indexPath.row].0.1 - countryName = "\(emojiFlagForISOCountryCode(self.sections[indexPath.section].1[indexPath.row].1)) \(countryName)" + cleanCountryName = self.sections[indexPath.section].1[indexPath.row].0.1 + countryName = "\(emojiFlagForISOCountryCode(self.sections[indexPath.section].1[indexPath.row].1)) \(cleanCountryName)" originalCountryName = self.sections[indexPath.section].1[indexPath.row].0.0 code = "+\(self.sections[indexPath.section].1[indexPath.row].2)" } else { - countryName = self.searchResults[indexPath.row].0.1 - countryName = "\(emojiFlagForISOCountryCode(self.searchResults[indexPath.row].1)) \(countryName)" + cleanCountryName = self.searchResults[indexPath.row].0.1 + countryName = "\(emojiFlagForISOCountryCode(self.searchResults[indexPath.row].1)) \(cleanCountryName)" originalCountryName = self.searchResults[indexPath.row].0.0 code = "+\(self.searchResults[indexPath.row].2)" } + cell.accessibilityLabel = cleanCountryName + cell.accessibilityValue = code + cell.textLabel?.text = countryName cell.detailTextLabel?.text = originalCountryName if self.displayCodes, let label = cell.accessoryView as? UILabel { diff --git a/submodules/Display/Source/NavigationButtonNode.swift b/submodules/Display/Source/NavigationButtonNode.swift index b8528c798d..46a5ad84cc 100644 --- a/submodules/Display/Source/NavigationButtonNode.swift +++ b/submodules/Display/Source/NavigationButtonNode.swift @@ -48,7 +48,9 @@ private final class NavigationButtonItemNode: ImmediateTextNode { self.attributedText = NSAttributedString(string: text, attributes: self.attributesForCurrentState()) if _image == nil { - self.item?.accessibilityLabel = value + if self.item?.accessibilityLabel == nil { + self.item?.accessibilityLabel = value + } } } } diff --git a/submodules/GalleryUI/Sources/ChatItemGalleryFooterContentNode.swift b/submodules/GalleryUI/Sources/ChatItemGalleryFooterContentNode.swift index 8701104e79..7052f480ff 100644 --- a/submodules/GalleryUI/Sources/ChatItemGalleryFooterContentNode.swift +++ b/submodules/GalleryUI/Sources/ChatItemGalleryFooterContentNode.swift @@ -341,6 +341,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll self.authorNameNode.maximumNumberOfLines = 1 self.authorNameNode.isUserInteractionEnabled = false self.authorNameNode.displaysAsynchronously = false + self.dateNode = ASTextNode() self.dateNode.maximumNumberOfLines = 1 self.dateNode.isUserInteractionEnabled = false @@ -428,9 +429,20 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll self.contentNode.addSubnode(self.statusButtonNode) self.deleteButton.addTarget(self, action: #selector(self.deleteButtonPressed), for: [.touchUpInside]) + self.deleteButton.accessibilityTraits = [.button] + self.deleteButton.accessibilityLabel = presentationData.strings.Gallery_VoiceOver_Delete + self.fullscreenButton.addTarget(self, action: #selector(self.fullscreenButtonPressed), for: [.touchUpInside]) + self.fullscreenButton.accessibilityTraits = [.button] + self.fullscreenButton.accessibilityLabel = presentationData.strings.Gallery_VoiceOver_Fullscreen + self.actionButton.addTarget(self, action: #selector(self.actionButtonPressed), for: [.touchUpInside]) + self.actionButton.accessibilityTraits = [.button] + self.actionButton.accessibilityLabel = presentationData.strings.Gallery_VoiceOver_Share + self.editButton.addTarget(self, action: #selector(self.editButtonPressed), for: [.touchUpInside]) + self.editButton.accessibilityTraits = [.button] + self.editButton.accessibilityLabel = presentationData.strings.Gallery_VoiceOver_Edit self.backwardButton.addTarget(self, action: #selector(self.backwardButtonPressed), forControlEvents: .touchUpInside) self.forwardButton.addTarget(self, action: #selector(self.forwardButtonPressed), forControlEvents: .touchUpInside) @@ -595,12 +607,15 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll } else { self.authorNameNode.attributedText = nil } + self.authorNameNode.accessibilityLabel = self.authorNameNode.attributedText?.string + if let dateText = dateText { self.dateNode.attributedText = NSAttributedString(string: dateText, font: dateFont, textColor: .white) } else { self.dateNode.attributedText = nil } - + self.dateNode.accessibilityLabel = self.dateNode.attributedText?.string + self.requestLayout?(.immediate) } @@ -763,8 +778,11 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll } else { self.authorNameNode.attributedText = nil } + self.authorNameNode.accessibilityLabel = self.authorNameNode.attributedText?.string + self.dateNode.attributedText = NSAttributedString(string: dateText, font: dateFont, textColor: .white) - + self.dateNode.accessibilityLabel = self.dateNode.attributedText?.string + if canFullscreen { self.fullscreenButton.isHidden = false self.deleteButton.isHidden = true diff --git a/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift b/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift index 3520026a4c..fad7948100 100644 --- a/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift @@ -443,10 +443,12 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode { var barButtonItems: [UIBarButtonItem] = [] if imageReference.media.flags.contains(.hasStickers) { let rightBarButtonItem = UIBarButtonItem(image: generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/Stickers"), color: .white), style: .plain, target: self, action: #selector(self.openStickersButtonPressed)) + rightBarButtonItem.accessibilityLabel = self.presentationData.strings.Gallery_VoiceOver_Stickers barButtonItems.append(rightBarButtonItem) } if self.message != nil { let moreMenuItem = UIBarButtonItem(customDisplayNode: self.moreBarButton)! + moreMenuItem.accessibilityLabel = self.presentationData.strings.Common_More barButtonItems.append(moreMenuItem) } self._rightBarButtonItems.set(.single(barButtonItems)) @@ -646,6 +648,7 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode { var barButtonItems: [UIBarButtonItem] = [] if self.message != nil { let moreMenuItem = UIBarButtonItem(customDisplayNode: self.moreBarButton)! + moreMenuItem.accessibilityLabel = self.presentationData.strings.Common_More barButtonItems.append(moreMenuItem) } self._rightBarButtonItems.set(.single(barButtonItems)) diff --git a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift index a5446f038f..d8dc50ca3d 100644 --- a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift @@ -1420,10 +1420,12 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { var barButtonItems: [UIBarButtonItem] = [] if hasLinkedStickers { let rightBarButtonItem = UIBarButtonItem(image: generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/Stickers"), color: .white), style: .plain, target: self, action: #selector(self.openStickersButtonPressed)) + rightBarButtonItem.accessibilityLabel = self.presentationData.strings.Gallery_VoiceOver_Stickers barButtonItems.append(rightBarButtonItem) } if forceEnablePiP || (!isAnimated && !disablePlayerControls && !disablePictureInPicture) { let rightBarButtonItem = UIBarButtonItem(image: pictureInPictureButtonImage, style: .plain, target: self, action: #selector(self.pictureInPictureButtonPressed)) + rightBarButtonItem.accessibilityLabel = self.presentationData.strings.Gallery_VoiceOver_PictureInPicture self.pictureInPictureButton = rightBarButtonItem barButtonItems.append(rightBarButtonItem) self.hasPictureInPicture = true @@ -1452,6 +1454,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { if hasMoreButton { let moreMenuItem = UIBarButtonItem(customDisplayNode: self.moreBarButton)! + moreMenuItem.accessibilityLabel = self.presentationData.strings.Common_More barButtonItems.append(moreMenuItem) } } diff --git a/submodules/ItemListUI/Sources/ItemListItem.swift b/submodules/ItemListUI/Sources/ItemListItem.swift index 5ad5eab690..6fc5f3d183 100644 --- a/submodules/ItemListUI/Sources/ItemListItem.swift +++ b/submodules/ItemListUI/Sources/ItemListItem.swift @@ -159,11 +159,13 @@ public final class ItemListPresentationData: Equatable { public let theme: PresentationTheme public let fontSize: PresentationFontSize public let strings: PresentationStrings + public let nameDisplayOrder: PresentationPersonNameOrder - public init(theme: PresentationTheme, fontSize: PresentationFontSize, strings: PresentationStrings) { + public init(theme: PresentationTheme, fontSize: PresentationFontSize, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder) { self.theme = theme self.fontSize = fontSize self.strings = strings + self.nameDisplayOrder = nameDisplayOrder } public static func ==(lhs: ItemListPresentationData, rhs: ItemListPresentationData) -> Bool { @@ -176,6 +178,9 @@ public final class ItemListPresentationData: Equatable { if lhs.fontSize != rhs.fontSize { return false } + if lhs.nameDisplayOrder != rhs.nameDisplayOrder { + return false + } return true } } @@ -226,6 +231,6 @@ public extension PresentationFontSize { public extension ItemListPresentationData { convenience init(_ presentationData: PresentationData) { - self.init(theme: presentationData.theme, fontSize: presentationData.listsFontSize, strings: presentationData.strings) + self.init(theme: presentationData.theme, fontSize: presentationData.listsFontSize, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder) } } diff --git a/submodules/PeerInfoUI/Sources/ItemListCallListItem.swift b/submodules/PeerInfoUI/Sources/ItemListCallListItem.swift index 2e02353f11..47a0bdcb54 100644 --- a/submodules/PeerInfoUI/Sources/ItemListCallListItem.swift +++ b/submodules/PeerInfoUI/Sources/ItemListCallListItem.swift @@ -232,15 +232,20 @@ public class ItemListCallListItemNode: ListViewItemNode { insets = UIEdgeInsets() } + var accessibilityText = "" + let earliestMessage = item.messages.sorted(by: {$0.timestamp < $1.timestamp}).first! let titleText = stringForDate(timestamp: earliestMessage.timestamp, strings: item.presentationData.strings) let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: titleText, font: titleFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - 20.0 - leftInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + accessibilityText.append(titleText) + accessibilityText.append(". ") contentHeight += titleLayout.size.height + 18.0 var index = 0 var nodesLayout: [(TextNodeLayout, TextNodeLayout)] = [] var nodesApply: [(() -> TextNode, () -> TextNode)] = [] + for message in item.messages { let makeTimeLayout = makeNodesLayout[index].0 let time = stringForMessageTimestamp(timestamp: message.timestamp, dateTimeFormat: item.dateTimeFormat) @@ -250,6 +255,8 @@ public class ItemListCallListItemNode: ListViewItemNode { let type = stringForCallType(message: message, strings: item.presentationData.strings) let (typeLayout, typeApply) = makeTypeLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: type, font: typeFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - 20.0 - leftInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + accessibilityText.append("\(time) - \(type)") + nodesLayout.append((timeLayout, typeLayout)) nodesApply.append((timeApply, typeApply)) @@ -336,6 +343,8 @@ public class ItemListCallListItemNode: ListViewItemNode { index += 1 } + strongSelf.accessibilityArea.accessibilityLabel = accessibilityText + strongSelf.accessibilityArea.accessibilityTraits = .staticText strongSelf.accessibilityArea.frame = CGRect(origin: CGPoint(), size: layout.contentSize) } }) diff --git a/submodules/SolidRoundedButtonNode/Sources/SolidRoundedButtonNode.swift b/submodules/SolidRoundedButtonNode/Sources/SolidRoundedButtonNode.swift index d34ac8b555..1d7d2be654 100644 --- a/submodules/SolidRoundedButtonNode/Sources/SolidRoundedButtonNode.swift +++ b/submodules/SolidRoundedButtonNode/Sources/SolidRoundedButtonNode.swift @@ -101,6 +101,7 @@ public final class SolidRoundedButtonNode: ASDisplayNode { if self.isEnabled != oldValue { self.updateColors(animated: true) } + self.updateAccessibilityLabels() } } @@ -130,6 +131,11 @@ public final class SolidRoundedButtonNode: ASDisplayNode { private func updateAccessibilityLabels() { self.accessibilityLabel = (self.title ?? "") + " " + (self.subtitle ?? "") + if !self.isEnabled { + self.accessibilityTraits = [.button, .notEnabled] + } else { + self.accessibilityTraits = [.button] + } } private var animationTimer: SwiftSignalKit.Timer? @@ -289,6 +295,8 @@ public final class SolidRoundedButtonNode: ASDisplayNode { } } } + + self.updateAccessibilityLabels() } public override func didLoad() { @@ -795,6 +803,11 @@ public final class SolidRoundedButtonView: UIView { private func updateAccessibilityLabels() { self.accessibilityLabel = (self.title ?? "") + " " + (self.subtitle ?? "") self.accessibilityValue = self.label + if !self.isEnabled { + self.accessibilityTraits = [.button, .notEnabled] + } else { + self.accessibilityTraits = [.button] + } } public var icon: UIImage? { @@ -808,6 +821,7 @@ public final class SolidRoundedButtonView: UIView { if self.isEnabled != oldValue { self.titleNode.alpha = self.isEnabled ? 1.0 : 0.6 } + self.updateAccessibilityLabels() } } @@ -976,6 +990,8 @@ public final class SolidRoundedButtonView: UIView { if #available(iOS 13.0, *) { self.buttonBackgroundNode.layer.cornerCurve = .continuous } + + self.updateAccessibilityLabels() } required public init(coder: NSCoder) { diff --git a/submodules/TelegramUI/Sources/ChatMessageItemView.swift b/submodules/TelegramUI/Sources/ChatMessageItemView.swift index d582dce5e1..5783330741 100644 --- a/submodules/TelegramUI/Sources/ChatMessageItemView.swift +++ b/submodules/TelegramUI/Sources/ChatMessageItemView.swift @@ -214,6 +214,7 @@ final class ChatMessageAccessibilityData { loop: for media in message.media { if let _ = media as? TelegramMediaImage { + traits.insert(.image) if isIncoming { if announceIncomingAuthors, let authorName = authorName { label = item.presentationData.strings.VoiceOver_Chat_PhotoFrom(authorName).string diff --git a/submodules/TelegramUI/Sources/ChatTextInputAudioRecordingCancelIndicator.swift b/submodules/TelegramUI/Sources/ChatTextInputAudioRecordingCancelIndicator.swift index 7e0dcdb4c1..5d94685c16 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputAudioRecordingCancelIndicator.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputAudioRecordingCancelIndicator.swift @@ -32,6 +32,8 @@ final class ChatTextInputAudioRecordingCancelIndicator: ASDisplayNode { self.cancelButton = HighlightableButtonNode() self.cancelButton.setTitle(strings.Common_Cancel, with: cancelFont, with: theme.chat.inputPanel.panelControlAccentColor, for: []) self.cancelButton.alpha = 0.0 + self.cancelButton.accessibilityLabel = strings.Common_Cancel + self.cancelButton.accessibilityTraits = [.button] self.strings = strings diff --git a/submodules/TelegramUI/Sources/CommandChatInputContextPanelNode.swift b/submodules/TelegramUI/Sources/CommandChatInputContextPanelNode.swift index 8cb47032d5..09970ca2c7 100644 --- a/submodules/TelegramUI/Sources/CommandChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/Sources/CommandChatInputContextPanelNode.swift @@ -10,6 +10,7 @@ import MergeLists import AccountContext import ChatPresentationInterfaceState import ChatControllerInteraction +import ItemListUI private struct CommandChatInputContextPanelEntryStableId: Hashable { let command: PeerCommand @@ -36,8 +37,8 @@ private struct CommandChatInputContextPanelEntry: Comparable, Identifiable { return lhs.index < rhs.index } - func item(context: AccountContext, fontSize: PresentationFontSize, commandSelected: @escaping (PeerCommand, Bool) -> Void) -> ListViewItem { - return CommandChatInputPanelItem(context: context, theme: self.theme, fontSize: fontSize, command: self.command, commandSelected: commandSelected) + func item(context: AccountContext, presentationData: PresentationData, commandSelected: @escaping (PeerCommand, Bool) -> Void) -> ListViewItem { + return CommandChatInputPanelItem(context: context, presentationData: ItemListPresentationData(presentationData), command: self.command, commandSelected: commandSelected) } } @@ -47,12 +48,12 @@ private struct CommandChatInputContextPanelTransition { let updates: [ListViewUpdateItem] } -private func preparedTransition(from fromEntries: [CommandChatInputContextPanelEntry], to toEntries: [CommandChatInputContextPanelEntry], context: AccountContext, fontSize: PresentationFontSize, commandSelected: @escaping (PeerCommand, Bool) -> Void) -> CommandChatInputContextPanelTransition { +private func preparedTransition(from fromEntries: [CommandChatInputContextPanelEntry], to toEntries: [CommandChatInputContextPanelEntry], context: AccountContext, presentationData: PresentationData, commandSelected: @escaping (PeerCommand, Bool) -> Void) -> CommandChatInputContextPanelTransition { let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } - let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, fontSize: fontSize, commandSelected: commandSelected), directionHint: nil) } - let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, fontSize: fontSize, commandSelected: commandSelected), directionHint: nil) } + let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, commandSelected: commandSelected), directionHint: nil) } + let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, commandSelected: commandSelected), directionHint: nil) } return CommandChatInputContextPanelTransition(deletions: deletions, insertions: insertions, updates: updates) } @@ -101,7 +102,8 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode { private func prepareTransition(from: [CommandChatInputContextPanelEntry]? , to: [CommandChatInputContextPanelEntry]) { let firstTime = self.currentEntries == nil - let transition = preparedTransition(from: from ?? [], to: to, context: self.context, fontSize: self.fontSize, commandSelected: { [weak self] command, sendImmediately in + let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } + let transition = preparedTransition(from: from ?? [], to: to, context: self.context, presentationData: presentationData, commandSelected: { [weak self] command, sendImmediately in if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction { if sendImmediately { interfaceInteraction.sendBotCommand(command.peer, "/" + command.command.text) diff --git a/submodules/TelegramUI/Sources/CommandChatInputPanelItem.swift b/submodules/TelegramUI/Sources/CommandChatInputPanelItem.swift index 4339046032..d92ac6b563 100644 --- a/submodules/TelegramUI/Sources/CommandChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/CommandChatInputPanelItem.swift @@ -9,20 +9,19 @@ import TelegramPresentationData import TelegramUIPreferences import AvatarNode import AccountContext +import ItemListUI final class CommandChatInputPanelItem: ListViewItem { fileprivate let context: AccountContext - fileprivate let theme: PresentationTheme - fileprivate let fontSize: PresentationFontSize + fileprivate let presentationData: ItemListPresentationData fileprivate let command: PeerCommand fileprivate let commandSelected: (PeerCommand, Bool) -> Void let selectable: Bool = true - public init(context: AccountContext, theme: PresentationTheme, fontSize: PresentationFontSize, command: PeerCommand, commandSelected: @escaping (PeerCommand, Bool) -> Void) { + public init(context: AccountContext, presentationData: ItemListPresentationData, command: PeerCommand, commandSelected: @escaping (PeerCommand, Bool) -> Void) { self.context = context - self.theme = theme - self.fontSize = fontSize + self.presentationData = presentationData self.command = command self.commandSelected = commandSelected } @@ -92,6 +91,8 @@ final class CommandChatInputPanelItemNode: ListViewItemNode { private let highlightedBackgroundNode: ASDisplayNode private let arrowNode: ASButtonNode + private let activateAreaNode: AccessibilityAreaNode + init() { self.avatarNode = AvatarNode(font: avatarFont) self.textNode = TextNode() @@ -107,6 +108,9 @@ final class CommandChatInputPanelItemNode: ListViewItemNode { self.arrowNode = HighlightableButtonNode() + self.activateAreaNode = AccessibilityAreaNode() + self.activateAreaNode.accessibilityTraits = [.button] + super.init(layerBacked: false, dynamicBounce: false) self.addSubnode(self.topSeparatorNode) @@ -117,6 +121,8 @@ final class CommandChatInputPanelItemNode: ListViewItemNode { self.addSubnode(self.arrowNode) self.arrowNode.addTarget(self, action: #selector(self.arrowButtonPressed), forControlEvents: [.touchUpInside]) + + self.addSubnode(self.activateAreaNode) } override public func layoutForParams(_ params: ListViewItemLayoutParams, item: ListViewItem, previousItem: ListViewItem?, nextItem: ListViewItem?) { @@ -134,37 +140,40 @@ final class CommandChatInputPanelItemNode: ListViewItemNode { let makeTextLayout = TextNode.asyncLayout(self.textNode) return { [weak self] item, params, mergedTop, mergedBottom in - let textFont = Font.medium(floor(item.fontSize.baseDisplaySize * 14.0 / 17.0)) - let descriptionFont = Font.regular(floor(item.fontSize.baseDisplaySize * 14.0 / 17.0)) + let textFont = Font.medium(floor(item.presentationData.fontSize.baseDisplaySize * 14.0 / 17.0)) + let descriptionFont = Font.regular(floor(item.presentationData.fontSize.baseDisplaySize * 14.0 / 17.0)) let leftInset: CGFloat = 55.0 + params.leftInset let rightInset: CGFloat = 10.0 + params.rightInset + let peerName = EnginePeer(item.command.peer).displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder) + let commandString = NSMutableAttributedString() - commandString.append(NSAttributedString(string: "/" + item.command.command.text, font: textFont, textColor: item.theme.list.itemPrimaryTextColor)) + commandString.append(NSAttributedString(string: "/" + item.command.command.text, font: textFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor)) + let command = commandString.string if !item.command.command.description.isEmpty { - commandString.append(NSAttributedString(string: " " + item.command.command.description, font: descriptionFont, textColor: item.theme.list.itemSecondaryTextColor)) + commandString.append(NSAttributedString(string: " " + item.command.command.description, font: descriptionFont, textColor: item.presentationData.theme.list.itemSecondaryTextColor)) } let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: commandString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset - 40.0, height: 100.0), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) let nodeLayout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: HashtagChatInputPanelItemNode.itemHeight), insets: UIEdgeInsets()) - let iconImage = PresentationResourcesChat.chatCommandPanelArrowImage(item.theme) + let iconImage = PresentationResourcesChat.chatCommandPanelArrowImage(item.presentationData.theme) return (nodeLayout, { _ in if let strongSelf = self { strongSelf.item = item - strongSelf.separatorNode.backgroundColor = item.theme.list.itemPlainSeparatorColor - strongSelf.topSeparatorNode.backgroundColor = item.theme.list.itemPlainSeparatorColor - strongSelf.backgroundColor = item.theme.list.plainBackgroundColor - strongSelf.highlightedBackgroundNode.backgroundColor = item.theme.list.itemHighlightedBackgroundColor + strongSelf.separatorNode.backgroundColor = item.presentationData.theme.list.itemPlainSeparatorColor + strongSelf.topSeparatorNode.backgroundColor = item.presentationData.theme.list.itemPlainSeparatorColor + strongSelf.backgroundColor = item.presentationData.theme.list.plainBackgroundColor + strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.list.itemHighlightedBackgroundColor strongSelf.arrowNode.setImage(iconImage, for: []) - strongSelf.avatarNode.setPeer(context: item.context, theme: item.theme, peer: EnginePeer(item.command.peer), emptyColor: item.theme.list.mediaPlaceholderColor) + strongSelf.avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: EnginePeer(item.command.peer), emptyColor: item.presentationData.theme.list.mediaPlaceholderColor) let _ = textApply() @@ -181,6 +190,10 @@ final class CommandChatInputPanelItemNode: ListViewItemNode { strongSelf.separatorNode.frame = CGRect(origin: CGPoint(x: leftInset, y: nodeLayout.contentSize.height - UIScreenPixel), size: CGSize(width: params.width - leftInset, height: UIScreenPixel)) strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: params.width, height: nodeLayout.size.height + UIScreenPixel)) + + strongSelf.activateAreaNode.accessibilityLabel = "\(peerName), \(command)" + strongSelf.activateAreaNode.accessibilityValue = item.command.command.description + strongSelf.activateAreaNode.frame = CGRect(origin: .zero, size: nodeLayout.size) } }) } diff --git a/submodules/TelegramUI/Sources/CommandMenuChatInputContextPanelNode.swift b/submodules/TelegramUI/Sources/CommandMenuChatInputContextPanelNode.swift index 250c514c00..293bc1aa91 100644 --- a/submodules/TelegramUI/Sources/CommandMenuChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/Sources/CommandMenuChatInputContextPanelNode.swift @@ -72,6 +72,7 @@ final class CommandMenuChatInputContextPanelNode: ChatInputContextPanelNode { self.listView.clipsToBounds = false self.listView.isOpaque = false self.listView.stackFromBottom = true + self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor self.listView.limitHitTestToNodes = true self.listView.view.disablesInteractiveTransitionGestureRecognizer = true self.listView.accessibilityPageScrolledString = { row, count in @@ -234,7 +235,7 @@ final class CommandMenuChatInputContextPanelNode: ChatInputContextPanelNode { self.listView.keepBottomItemOverscrollBackground = self.theme.list.plainBackgroundColor let new = self.currentEntries?.map({$0.withUpdatedTheme(interfaceState.theme)}) ?? [] - prepareTransition(from: self.currentEntries, to: new) + self.prepareTransition(from: self.currentEntries, to: new) } } diff --git a/submodules/TelegramUI/Sources/CommandMenuChatInputPanelItem.swift b/submodules/TelegramUI/Sources/CommandMenuChatInputPanelItem.swift index d54c6e9b13..49855b427a 100644 --- a/submodules/TelegramUI/Sources/CommandMenuChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/CommandMenuChatInputPanelItem.swift @@ -118,6 +118,8 @@ final class CommandMenuChatInputPanelItemNode: ListViewItemNode { private let backgroundNode: ASDisplayNode private let highlightedBackgroundNode: ASDisplayNode + private let activateAreaNode: AccessibilityAreaNode + init() { self.textNode = TextNode() self.commandNode = TextNode() @@ -139,6 +141,9 @@ final class CommandMenuChatInputPanelItemNode: ListViewItemNode { self.backgroundNode = ASDisplayNode() self.backgroundNode.clipsToBounds = true + self.activateAreaNode = AccessibilityAreaNode() + self.activateAreaNode.accessibilityTraits = [.button] + super.init(layerBacked: false, dynamicBounce: false) self.addSubnode(self.clippingNode) @@ -148,6 +153,8 @@ final class CommandMenuChatInputPanelItemNode: ListViewItemNode { self.backgroundNode.addSubnode(self.textNode) self.backgroundNode.addSubnode(self.commandNode) self.backgroundNode.addSubnode(self.separatorNode) + + self.addSubnode(self.activateAreaNode) } override func didLoad() { @@ -227,6 +234,10 @@ final class CommandMenuChatInputPanelItemNode: ListViewItemNode { strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: params.width, height: nodeLayout.size.height + UIScreenPixel)) + strongSelf.activateAreaNode.accessibilityLabel = textString.string + strongSelf.activateAreaNode.accessibilityValue = commandString.string + strongSelf.activateAreaNode.frame = CGRect(origin: .zero, size: nodeLayout.size) + if !mergedTop { strongSelf.shadowNode.isHidden = false strongSelf.shadowNode.frame = CGRect(origin: CGPoint(x: -shadowBlur, y: 0.0), size: CGSize(width: nodeLayout.size.width + shadowBlur * 2.0, height: backgroundCornerRadius + shadowBlur)) diff --git a/submodules/TelegramUI/Sources/HashtagChatInputPanelItem.swift b/submodules/TelegramUI/Sources/HashtagChatInputPanelItem.swift index e3279bc37a..e059fdb382 100644 --- a/submodules/TelegramUI/Sources/HashtagChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/HashtagChatInputPanelItem.swift @@ -98,6 +98,8 @@ final class HashtagChatInputPanelItemNode: ListViewItemNode { private var recognizer: ItemListRevealOptionsGestureRecognizer? private var hapticFeedback: HapticFeedback? + private let activateAreaNode: AccessibilityAreaNode + private var item: HashtagChatInputPanelItem? private var validLayout: (CGSize, CGFloat, CGFloat)? @@ -114,11 +116,16 @@ final class HashtagChatInputPanelItemNode: ListViewItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true + self.activateAreaNode = AccessibilityAreaNode() + self.activateAreaNode.accessibilityTraits = [.button] + super.init(layerBacked: false, dynamicBounce: false) self.addSubnode(self.topSeparatorNode) self.addSubnode(self.separatorNode) self.addSubnode(self.textNode) + + self.addSubnode(self.activateAreaNode) } override func didLoad() { @@ -150,7 +157,8 @@ final class HashtagChatInputPanelItemNode: ListViewItemNode { let leftInset: CGFloat = 15.0 + params.leftInset - let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "#\(item.text)", font: textFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: baseWidth, height: 100.0), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let title = "#\(item.text)" + let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: textFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: baseWidth, height: 100.0), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) let nodeLayout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: HashtagChatInputPanelItemNode.itemHeight), insets: UIEdgeInsets()) @@ -177,6 +185,9 @@ final class HashtagChatInputPanelItemNode: ListViewItemNode { strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: params.width, height: nodeLayout.size.height + UIScreenPixel)) + strongSelf.activateAreaNode.accessibilityLabel = title + strongSelf.activateAreaNode.frame = CGRect(origin: .zero, size: nodeLayout.size) + strongSelf.setRevealOptions([ItemListRevealOption(key: 0, title: item.presentationData.strings.Common_Delete, icon: .none, color: item.presentationData.theme.list.itemDisclosureActions.destructive.fillColor, textColor: item.presentationData.theme.list.itemDisclosureActions.destructive.foregroundColor)]) strongSelf.setRevealOptionsOpened(item.revealed, animated: animation.isAnimated) } diff --git a/submodules/TelegramUI/Sources/MentionChatInputPanelItem.swift b/submodules/TelegramUI/Sources/MentionChatInputPanelItem.swift index d7c4606ef0..d7ab86afb6 100644 --- a/submodules/TelegramUI/Sources/MentionChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/MentionChatInputPanelItem.swift @@ -108,6 +108,8 @@ final class MentionChatInputPanelItemNode: ListViewItemNode { private var recognizer: ItemListRevealOptionsGestureRecognizer? private var hapticFeedback: HapticFeedback? + private let activateAreaNode: AccessibilityAreaNode + private var item: MentionChatInputPanelItem? private var validLayout: (CGSize, CGFloat, CGFloat)? @@ -125,6 +127,9 @@ final class MentionChatInputPanelItemNode: ListViewItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true + self.activateAreaNode = AccessibilityAreaNode() + self.activateAreaNode.accessibilityTraits = [.button] + super.init(layerBacked: false, dynamicBounce: false) self.addSubnode(self.topSeparatorNode) @@ -132,6 +137,8 @@ final class MentionChatInputPanelItemNode: ListViewItemNode { self.addSubnode(self.avatarNode) self.addSubnode(self.textNode) + + self.addSubnode(self.activateAreaNode) } override func didLoad() { @@ -171,10 +178,14 @@ final class MentionChatInputPanelItemNode: ListViewItemNode { updatedInverted = item.inverted } + + let title = EnginePeer(item.peer).displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder) + var username: String? let string = NSMutableAttributedString() - string.append(NSAttributedString(string: item.peer.debugDisplayTitle, font: primaryFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor)) + string.append(NSAttributedString(string: title, font: primaryFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor)) if let addressName = item.peer.addressName, !addressName.isEmpty { string.append(NSAttributedString(string: " @\(addressName)", font: secondaryFont, textColor: item.presentationData.theme.list.itemSecondaryTextColor)) + username = "@\(addressName)" } let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: string, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset, height: 100.0), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) @@ -215,6 +226,10 @@ final class MentionChatInputPanelItemNode: ListViewItemNode { strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: params.width, height: nodeLayout.size.height + UIScreenPixel)) + strongSelf.activateAreaNode.accessibilityLabel = title + strongSelf.activateAreaNode.accessibilityValue = username + strongSelf.activateAreaNode.frame = CGRect(origin: .zero, size: nodeLayout.size) + if let peer = item.peer as? TelegramUser, let _ = peer.botInfo { strongSelf.setRevealOptions([ItemListRevealOption(key: 0, title: item.presentationData.strings.Common_Delete, icon: .none, color: item.presentationData.theme.list.itemDisclosureActions.destructive.fillColor, textColor: item.presentationData.theme.list.itemDisclosureActions.destructive.foregroundColor)]) strongSelf.setRevealOptionsOpened(item.revealed, animated: animation.isAnimated) diff --git a/submodules/TelegramUI/Sources/MultiScaleTextNode.swift b/submodules/TelegramUI/Sources/MultiScaleTextNode.swift index 37548d5d82..00526bc900 100644 --- a/submodules/TelegramUI/Sources/MultiScaleTextNode.swift +++ b/submodules/TelegramUI/Sources/MultiScaleTextNode.swift @@ -63,6 +63,8 @@ final class MultiScaleTextNode: ASDisplayNode { for (key, state) in states { if let node = self.stateNodes[key] { node.textNode.attributedText = NSAttributedString(string: text, font: state.attributes.font, textColor: state.attributes.color) + node.textNode.isAccessibilityElement = true + node.textNode.accessibilityLabel = text let nodeSize = node.textNode.updateLayout(state.constrainedSize) let nodeLayout = MultiScaleTextLayout(size: nodeSize) if key == mainState { diff --git a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenCallListItem.swift b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenCallListItem.swift index 5b2aa97897..40adb5bbea 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenCallListItem.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenCallListItem.swift @@ -30,6 +30,7 @@ final class PeerInfoScreenCallListItem: PeerInfoScreenItem { private final class PeerInfoScreenCallListItemNode: PeerInfoScreenItemNode { private let selectionNode: PeerInfoScreenSelectableBackgroundNode private let bottomSeparatorNode: ASDisplayNode + private let maskNode: ASImageNode private var item: PeerInfoScreenCallListItem? private var itemNode: ItemListCallListItemNode? @@ -42,6 +43,9 @@ private final class PeerInfoScreenCallListItemNode: PeerInfoScreenItemNode { self.bottomSeparatorNode = ASDisplayNode() self.bottomSeparatorNode.isLayerBacked = true + self.maskNode = ASImageNode() + self.maskNode.isUserInteractionEnabled = false + super.init() bringToFrontForHighlightImpl = { [weak self] in @@ -50,6 +54,7 @@ private final class PeerInfoScreenCallListItemNode: PeerInfoScreenItemNode { self.addSubnode(self.bottomSeparatorNode) self.addSubnode(self.selectionNode) + self.addSubnode(self.maskNode) } override func update(width: CGFloat, safeInsets: UIEdgeInsets, presentationData: PresentationData, item: PeerInfoScreenItem, topItem: PeerInfoScreenItem?, bottomItem: PeerInfoScreenItem?, hasCorners: Bool, transition: ContainedViewLayoutTransition) -> CGFloat { @@ -106,6 +111,14 @@ private final class PeerInfoScreenCallListItemNode: PeerInfoScreenItemNode { transition.updateFrame(node: self.bottomSeparatorNode, frame: CGRect(origin: CGPoint(x: sideInset, y: height - UIScreenPixel), size: CGSize(width: width - sideInset, height: UIScreenPixel))) transition.updateAlpha(node: self.bottomSeparatorNode, alpha: bottomItem == nil ? 0.0 : 1.0) + let hasCorners = hasCorners && (topItem == nil || bottomItem == nil) + let hasTopCorners = hasCorners && topItem == nil + let hasBottomCorners = hasCorners && bottomItem == nil + + self.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil + self.maskNode.frame = CGRect(origin: CGPoint(x: safeInsets.left, y: 0.0), size: CGSize(width: width - safeInsets.left - safeInsets.right, height: height)) + self.bottomSeparatorNode.isHidden = hasBottomCorners + return height } } diff --git a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenLabeledValueItem.swift b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenLabeledValueItem.swift index 788cdfb4a1..9aa643886c 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenLabeledValueItem.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenLabeledValueItem.swift @@ -527,7 +527,6 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode { self.activateArea.accessibilityLabel = item.label self.activateArea.accessibilityValue = item.text - let contentSize = CGSize(width: width, height: height) self.containerNode.frame = CGRect(origin: CGPoint(), size: contentSize) self.contextSourceNode.frame = CGRect(origin: CGPoint(), size: contentSize) diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift index ebca5e5cee..2fa0a79bec 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift @@ -2918,7 +2918,6 @@ final class PeerInfoHeaderNode: ASDisplayNode { TitleNodeStateRegular: MultiScaleTextState(attributes: titleAttributes, constrainedSize: titleConstrainedSize), TitleNodeStateExpanded: MultiScaleTextState(attributes: smallTitleAttributes, constrainedSize: titleConstrainedSize) ], mainState: TitleNodeStateRegular) - self.titleNode.accessibilityLabel = titleStringText let subtitleNodeLayout = self.subtitleNode.updateLayout(text: subtitleStringText, states: [ TitleNodeStateRegular: MultiScaleTextState(attributes: subtitleAttributes, constrainedSize: titleConstrainedSize),