mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Various Voice Over Improvements
This commit is contained in:
parent
3ea2032fa7
commit
5f0a33e414
@ -4683,6 +4683,16 @@ Sorry for the inconvenience.";
|
||||
"VoiceOver.MessageContextReply" = "Reply";
|
||||
"VoiceOver.MessageContextOpenMessageMenu" = "Open message menu";
|
||||
|
||||
"VoiceOver.Keyboard" = "Keyboard";
|
||||
"VoiceOver.Stickers" = "Stickers";
|
||||
"VoiceOver.ScheduledMessages" = "Scheduled Messages";
|
||||
"VoiceOver.BotCommands" = "Bot Commands";
|
||||
"VoiceOver.BotKeyboard" = "Bot Keyboard";
|
||||
"VoiceOver.SilentPostOn" = "Silent Broadcast On";
|
||||
"VoiceOver.SilentPostOff" = "Silent Broadcast Off";
|
||||
"VoiceOver.SelfDestructTimerOn" = "Self-destruct Timer: %@";
|
||||
"VoiceOver.SelfDestructTimerOff" = "Self-destruct Timer Off";
|
||||
|
||||
"ProxyServer.VoiceOver.Active" = "Active";
|
||||
|
||||
"Conversation.ScheduleMessage.Title" = "Schedule Message";
|
||||
|
@ -142,6 +142,8 @@ private final class ItemNode: ASDisplayNode {
|
||||
|
||||
super.init()
|
||||
|
||||
self.isAccessibilityElement = true
|
||||
|
||||
self.extractedContainerNode.contentNode.addSubnode(self.extractedBackgroundNode)
|
||||
self.extractedContainerNode.contentNode.addSubnode(self.titleContainer)
|
||||
self.titleContainer.addSubnode(self.titleNode)
|
||||
@ -495,6 +497,7 @@ final class ChatListFilterTabContainerNode: ASDisplayNode {
|
||||
super.init()
|
||||
|
||||
self.scrollNode.view.showsHorizontalScrollIndicator = false
|
||||
self.scrollNode.view.showsVerticalScrollIndicator = false
|
||||
self.scrollNode.view.scrollsToTop = false
|
||||
self.scrollNode.view.delaysContentTouches = false
|
||||
self.scrollNode.view.canCancelContentTouches = true
|
||||
|
@ -124,6 +124,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
private let dimNode: ASDisplayNode
|
||||
private let withoutBlurDimNode: ASDisplayNode
|
||||
private let dismissNode: ASDisplayNode
|
||||
private let dismissAccessibilityArea: AccessibilityAreaNode
|
||||
|
||||
private let clippingNode: ASDisplayNode
|
||||
private let scrollNode: ASScrollNode
|
||||
@ -184,9 +185,9 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
self.withoutBlurDimNode.alpha = 0.0
|
||||
|
||||
self.dismissNode = ASDisplayNode()
|
||||
self.dismissNode.isAccessibilityElement = true
|
||||
self.dismissNode.accessibilityLabel = presentationData.strings.VoiceOver_DismissContextMenu
|
||||
self.dismissNode.accessibilityTraits = .button
|
||||
self.dismissAccessibilityArea = AccessibilityAreaNode()
|
||||
self.dismissAccessibilityArea.accessibilityLabel = presentationData.strings.VoiceOver_DismissContextMenu
|
||||
self.dismissAccessibilityArea.accessibilityTraits = .button
|
||||
|
||||
self.clippingNode = ASDisplayNode()
|
||||
self.clippingNode.clipsToBounds = true
|
||||
@ -242,6 +243,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
|
||||
self.clippingNode.addSubnode(self.scrollNode)
|
||||
self.scrollNode.addSubnode(self.dismissNode)
|
||||
self.scrollNode.addSubnode(self.dismissAccessibilityArea)
|
||||
|
||||
self.scrollNode.addSubnode(self.actionsContainerNode)
|
||||
self.reactionContextNode.flatMap(self.addSubnode)
|
||||
@ -439,6 +441,11 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
}
|
||||
|
||||
self.initializeContent()
|
||||
|
||||
self.dismissAccessibilityArea.activate = { [weak self] in
|
||||
self?.dimNodeTapped()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
@ -1406,7 +1413,8 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
}
|
||||
}
|
||||
|
||||
transition.updateFrame(node: self.dismissNode, frame: CGRect(origin: CGPoint(), size: scrollNode.view.contentSize))
|
||||
transition.updateFrame(node: self.dismissNode, frame: CGRect(origin: CGPoint(), size: self.scrollNode.view.contentSize))
|
||||
self.dismissAccessibilityArea.frame = CGRect(origin: CGPoint(), size: self.scrollNode.view.contentSize)
|
||||
}
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -19,37 +19,37 @@ import Speak
|
||||
private let accessoryButtonFont = Font.medium(14.0)
|
||||
private let counterFont = Font.with(size: 14.0, design: .regular, traits: [.monospacedNumbers])
|
||||
|
||||
private final class AccessoryItemIconButton: HighlightTrackingButton {
|
||||
private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
|
||||
private let item: ChatTextInputAccessoryItem
|
||||
private var width: CGFloat
|
||||
private let imageNode: ASImageNode
|
||||
private var imageEdgeInsets = UIEdgeInsets()
|
||||
|
||||
init(item: ChatTextInputAccessoryItem, theme: PresentationTheme, strings: PresentationStrings) {
|
||||
self.imageNode = ASImageNode()
|
||||
self.imageNode.isLayerBacked = true
|
||||
self.imageNode.displaysAsynchronously = false
|
||||
self.imageNode.displayWithoutProcessing = true
|
||||
|
||||
self.item = item
|
||||
|
||||
let (image, text, alpha, insets) = AccessoryItemIconButton.imageAndInsets(item: item, theme: theme, strings: strings)
|
||||
let (image, text, accessibilityLabel, alpha, insets) = AccessoryItemIconButtonNode.imageAndInsets(item: item, theme: theme, strings: strings)
|
||||
|
||||
self.width = AccessoryItemIconButton.calculateWidth(item: item, image: image, text: text, strings: strings)
|
||||
self.width = AccessoryItemIconButtonNode.calculateWidth(item: item, image: image, text: text, strings: strings)
|
||||
|
||||
super.init(frame: CGRect())
|
||||
super.init()
|
||||
|
||||
self.isAccessibilityElement = true
|
||||
self.accessibilityTraits = [.button]
|
||||
|
||||
self.addSubnode(self.imageNode)
|
||||
|
||||
if let text = text {
|
||||
self.titleLabel?.font = accessoryButtonFont
|
||||
self.setTitleColor(theme.chat.inputPanel.inputControlColor, for: [])
|
||||
self.setTitle(text, for: [])
|
||||
self.setAttributedTitle(NSAttributedString(string: text, font: accessoryButtonFont, textColor: theme.chat.inputPanel.inputControlColor), for: .normal)
|
||||
} else {
|
||||
self.setAttributedTitle(NSAttributedString(), for: .normal)
|
||||
}
|
||||
|
||||
self.imageNode.image = image
|
||||
self.imageNode.alpha = alpha
|
||||
self.imageEdgeInsets = insets
|
||||
|
||||
self.accessibilityLabel = accessibilityLabel
|
||||
|
||||
self.highligthedChanged = { [weak self] highlighted in
|
||||
if let strongSelf = self {
|
||||
if highlighted {
|
||||
@ -64,51 +64,51 @@ private final class AccessoryItemIconButton: HighlightTrackingButton {
|
||||
}
|
||||
|
||||
func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) {
|
||||
let (image, text, alpha, insets) = AccessoryItemIconButton.imageAndInsets(item: item, theme: theme, strings: strings)
|
||||
let (image, text, accessibilityLabel, alpha, insets) = AccessoryItemIconButtonNode.imageAndInsets(item: item, theme: theme, strings: strings)
|
||||
|
||||
self.width = AccessoryItemIconButton.calculateWidth(item: item, image: image, text: text, strings: strings)
|
||||
self.width = AccessoryItemIconButtonNode.calculateWidth(item: item, image: image, text: text, strings: strings)
|
||||
|
||||
if let text = text {
|
||||
self.titleLabel?.font = accessoryButtonFont
|
||||
self.setTitleColor(theme.chat.inputPanel.inputControlColor, for: [])
|
||||
self.setTitle(text, for: [])
|
||||
self.setAttributedTitle(NSAttributedString(string: text, font: accessoryButtonFont, textColor: theme.chat.inputPanel.inputControlColor), for: .normal)
|
||||
} else {
|
||||
self.setTitle("", for: [])
|
||||
self.setAttributedTitle(NSAttributedString(), for: .normal)
|
||||
}
|
||||
|
||||
self.imageNode.image = image
|
||||
self.imageEdgeInsets = insets
|
||||
self.imageNode.alpha = alpha
|
||||
|
||||
self.accessibilityLabel = accessibilityLabel
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
static func imageAndInsets(item: ChatTextInputAccessoryItem, theme: PresentationTheme, strings: PresentationStrings) -> (UIImage?, String?, CGFloat, UIEdgeInsets) {
|
||||
static func imageAndInsets(item: ChatTextInputAccessoryItem, theme: PresentationTheme, strings: PresentationStrings) -> (UIImage?, String?, String, CGFloat, UIEdgeInsets) {
|
||||
switch item {
|
||||
case .keyboard:
|
||||
return (PresentationResourcesChat.chatInputTextFieldKeyboardImage(theme), nil, 1.0, UIEdgeInsets())
|
||||
return (PresentationResourcesChat.chatInputTextFieldKeyboardImage(theme), nil, strings.VoiceOver_Keyboard, 1.0, UIEdgeInsets())
|
||||
case let .stickers(enabled):
|
||||
return (PresentationResourcesChat.chatInputTextFieldStickersImage(theme), nil, enabled ? 1.0 : 0.4, UIEdgeInsets())
|
||||
return (PresentationResourcesChat.chatInputTextFieldStickersImage(theme), nil, strings.VoiceOver_Stickers, enabled ? 1.0 : 0.4, UIEdgeInsets())
|
||||
case .inputButtons:
|
||||
return (PresentationResourcesChat.chatInputTextFieldInputButtonsImage(theme), nil, 1.0, UIEdgeInsets())
|
||||
return (PresentationResourcesChat.chatInputTextFieldInputButtonsImage(theme), nil, strings.VoiceOver_BotKeyboard, 1.0, UIEdgeInsets())
|
||||
case .commands:
|
||||
return (PresentationResourcesChat.chatInputTextFieldCommandsImage(theme), nil, 1.0, UIEdgeInsets())
|
||||
return (PresentationResourcesChat.chatInputTextFieldCommandsImage(theme), nil, strings.VoiceOver_BotCommands, 1.0, UIEdgeInsets())
|
||||
case let .silentPost(value):
|
||||
if value {
|
||||
return (PresentationResourcesChat.chatInputTextFieldSilentPostOnImage(theme), nil, 1.0, UIEdgeInsets())
|
||||
return (PresentationResourcesChat.chatInputTextFieldSilentPostOnImage(theme), nil, strings.VoiceOver_SilentPostOn, 1.0, UIEdgeInsets())
|
||||
} else {
|
||||
return (PresentationResourcesChat.chatInputTextFieldSilentPostOffImage(theme), nil, 1.0, UIEdgeInsets())
|
||||
return (PresentationResourcesChat.chatInputTextFieldSilentPostOffImage(theme), nil, strings.VoiceOver_SilentPostOff, 1.0, UIEdgeInsets())
|
||||
}
|
||||
case let .messageAutoremoveTimeout(timeout):
|
||||
if let timeout = timeout {
|
||||
return (nil, shortTimeIntervalString(strings: strings, value: timeout), 1.0, UIEdgeInsets())
|
||||
return (nil, shortTimeIntervalString(strings: strings, value: timeout), strings.VoiceOver_SelfDestructTimerOn(timeIntervalString(strings: strings, value: timeout)).0, 1.0, UIEdgeInsets())
|
||||
} else {
|
||||
return (PresentationResourcesChat.chatInputTextFieldTimerImage(theme), nil, 1.0, UIEdgeInsets(top: 0.0, left: 0.0, bottom: 1.0, right: 0.0))
|
||||
return (PresentationResourcesChat.chatInputTextFieldTimerImage(theme), nil, strings.VoiceOver_SelfDestructTimerOff, 1.0, UIEdgeInsets(top: 0.0, left: 0.0, bottom: 1.0, right: 0.0))
|
||||
}
|
||||
case .scheduledMessages:
|
||||
return (PresentationResourcesChat.chatInputTextFieldScheduleImage(theme), nil, 1.0, UIEdgeInsets())
|
||||
return (PresentationResourcesChat.chatInputTextFieldScheduleImage(theme), nil, strings.VoiceOver_ScheduledMessages, 1.0, UIEdgeInsets())
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,7 +220,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
var audioRecordingCancelIndicator: ChatTextInputAudioRecordingCancelIndicator?
|
||||
var animatingBinNode: AnimationNode?
|
||||
|
||||
private var accessoryItemButtons: [(ChatTextInputAccessoryItem, AccessoryItemIconButton)] = []
|
||||
private var accessoryItemButtons: [(ChatTextInputAccessoryItem, AccessoryItemIconButtonNode)] = []
|
||||
|
||||
private var validLayout: (CGFloat, CGFloat, CGFloat, UIEdgeInsets, CGFloat, LayoutMetrics, Bool)?
|
||||
|
||||
@ -316,9 +316,9 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
|
||||
if updateAccessoryButtons {
|
||||
var updatedButtons: [(ChatTextInputAccessoryItem, AccessoryItemIconButton)] = []
|
||||
var updatedButtons: [(ChatTextInputAccessoryItem, AccessoryItemIconButtonNode)] = []
|
||||
for item in accessoryItems {
|
||||
var itemAndButton: (ChatTextInputAccessoryItem, AccessoryItemIconButton)?
|
||||
var itemAndButton: (ChatTextInputAccessoryItem, AccessoryItemIconButtonNode)?
|
||||
for i in 0 ..< self.accessoryItemButtons.count {
|
||||
if self.accessoryItemButtons[i].0 == item {
|
||||
itemAndButton = self.accessoryItemButtons[i]
|
||||
@ -327,14 +327,14 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
}
|
||||
if itemAndButton == nil {
|
||||
let button = AccessoryItemIconButton(item: item, theme: currentState.theme, strings: currentState.strings)
|
||||
button.addTarget(self, action: #selector(self.accessoryItemButtonPressed(_:)), for: [.touchUpInside])
|
||||
let button = AccessoryItemIconButtonNode(item: item, theme: currentState.theme, strings: currentState.strings)
|
||||
button.addTarget(self, action: #selector(self.accessoryItemButtonPressed(_:)), forControlEvents: .touchUpInside)
|
||||
itemAndButton = (item, button)
|
||||
}
|
||||
updatedButtons.append(itemAndButton!)
|
||||
}
|
||||
for (_, button) in self.accessoryItemButtons {
|
||||
button.removeFromSuperview()
|
||||
button.removeFromSupernode()
|
||||
}
|
||||
self.accessoryItemButtons = updatedButtons
|
||||
}
|
||||
@ -904,11 +904,11 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
updateAccessoryButtons = true
|
||||
}
|
||||
|
||||
var removeAccessoryButtons: [AccessoryItemIconButton]?
|
||||
var removeAccessoryButtons: [AccessoryItemIconButtonNode]?
|
||||
if updateAccessoryButtons {
|
||||
var updatedButtons: [(ChatTextInputAccessoryItem, AccessoryItemIconButton)] = []
|
||||
var updatedButtons: [(ChatTextInputAccessoryItem, AccessoryItemIconButtonNode)] = []
|
||||
for item in interfaceState.inputTextPanelState.accessoryItems {
|
||||
var itemAndButton: (ChatTextInputAccessoryItem, AccessoryItemIconButton)?
|
||||
var itemAndButton: (ChatTextInputAccessoryItem, AccessoryItemIconButtonNode)?
|
||||
for i in 0 ..< self.accessoryItemButtons.count {
|
||||
if self.accessoryItemButtons[i].0 == item {
|
||||
itemAndButton = self.accessoryItemButtons[i]
|
||||
@ -917,8 +917,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
}
|
||||
if itemAndButton == nil {
|
||||
let button = AccessoryItemIconButton(item: item, theme: interfaceState.theme, strings: interfaceState.strings)
|
||||
button.addTarget(self, action: #selector(self.accessoryItemButtonPressed(_:)), for: [.touchUpInside])
|
||||
let button = AccessoryItemIconButtonNode(item: item, theme: interfaceState.theme, strings: interfaceState.strings)
|
||||
button.addTarget(self, action: #selector(self.accessoryItemButtonPressed(_:)), forControlEvents: .touchUpInside)
|
||||
itemAndButton = (item, button)
|
||||
}
|
||||
updatedButtons.append(itemAndButton!)
|
||||
@ -930,7 +930,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
removeAccessoryButtons!.append(button)
|
||||
} else {
|
||||
button.removeFromSuperview()
|
||||
button.removeFromSupernode()
|
||||
}
|
||||
}
|
||||
self.accessoryItemButtons = updatedButtons
|
||||
@ -1343,8 +1343,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
let buttonSize = CGSize(width: button.buttonWidth, height: minimalInputHeight)
|
||||
button.updateLayout(size: buttonSize)
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: nextButtonTopRight.x - buttonSize.width, y: nextButtonTopRight.y + floor((minimalInputHeight - buttonSize.height) / 2.0)), size: buttonSize)
|
||||
if button.superview == nil {
|
||||
self.view.addSubview(button)
|
||||
if button.supernode == nil {
|
||||
self.addSubnode(button)
|
||||
button.frame = buttonFrame.offsetBy(dx: -additionalOffset, dy: 0.0)
|
||||
transition.updateFrame(layer: button.layer, frame: buttonFrame)
|
||||
if animatedTransition {
|
||||
@ -1364,7 +1364,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
transition.updateFrame(layer: button.layer, frame: buttonFrame)
|
||||
button.layer.animateScale(from: 1.0, to: 0.2, duration: 0.25, removeOnCompletion: false)
|
||||
button.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { [weak button] _ in
|
||||
button?.removeFromSuperview()
|
||||
button?.removeFromSupernode()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user