mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
2ef1de9a8c
commit
f800936080
@ -8906,3 +8906,5 @@ Sorry for the inconvenience.";
|
||||
"Gallery.VoiceOver.Edit" = "Edit";
|
||||
"Gallery.VoiceOver.Stickers" = "Stickers";
|
||||
"Gallery.VoiceOver.PictureInPicture" = "Picture-in-Picture";
|
||||
|
||||
"Appearance.VoiceOver.Theme" = "%@ Theme";
|
||||
|
@ -757,6 +757,8 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.scrollNode.view.delegate = self
|
||||
self.scrollNode.view.showsHorizontalScrollIndicator = false
|
||||
self.scrollNode.view.showsVerticalScrollIndicator = false
|
||||
|
||||
self.view.accessibilityTraits = .tabBar
|
||||
}
|
||||
|
||||
@objc private func buttonPressed() {
|
||||
|
@ -76,9 +76,7 @@ private final class ItemNode: ASDisplayNode {
|
||||
|
||||
private var deleteButtonNode: ItemNodeDeleteButtonNode?
|
||||
private let buttonNode: HighlightTrackingButtonNode
|
||||
|
||||
private let activateArea: AccessibilityAreaNode
|
||||
|
||||
|
||||
private var selectionFraction: CGFloat = 0.0
|
||||
private(set) var unreadCount: Int = 0
|
||||
|
||||
@ -140,13 +138,9 @@ private final class ItemNode: ASDisplayNode {
|
||||
self.badgeBackgroundInactiveNode.displayWithoutProcessing = true
|
||||
|
||||
self.buttonNode = HighlightTrackingButtonNode()
|
||||
|
||||
self.activateArea = AccessibilityAreaNode()
|
||||
|
||||
|
||||
super.init()
|
||||
|
||||
self.isAccessibilityElement = true
|
||||
|
||||
|
||||
self.extractedContainerNode.contentNode.addSubnode(self.extractedBackgroundNode)
|
||||
self.extractedContainerNode.contentNode.addSubnode(self.titleContainer)
|
||||
self.titleContainer.addSubnode(self.titleNode)
|
||||
@ -163,9 +157,7 @@ private final class ItemNode: ASDisplayNode {
|
||||
self.containerNode.addSubnode(self.extractedContainerNode)
|
||||
self.containerNode.targetNodeForActivationProgress = self.extractedContainerNode.contentNode
|
||||
self.addSubnode(self.containerNode)
|
||||
|
||||
self.addSubnode(self.activateArea)
|
||||
|
||||
|
||||
self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
||||
|
||||
self.containerNode.activated = { [weak self] gesture, _ in
|
||||
@ -212,11 +204,16 @@ private final class ItemNode: ASDisplayNode {
|
||||
self.badgeBackgroundInactiveNode.image = generateStretchableFilledCircleImage(diameter: 18.0, color: presentationData.theme.chatList.unreadBadgeInactiveBackgroundColor)
|
||||
}
|
||||
|
||||
self.activateArea.accessibilityLabel = title
|
||||
self.buttonNode.accessibilityLabel = title
|
||||
if unreadCount > 0 {
|
||||
self.activateArea.accessibilityValue = strings.VoiceOver_Chat_UnreadMessages(Int32(unreadCount))
|
||||
self.buttonNode.accessibilityValue = strings.VoiceOver_Chat_UnreadMessages(Int32(unreadCount))
|
||||
} else {
|
||||
self.activateArea.accessibilityValue = ""
|
||||
self.buttonNode.accessibilityValue = ""
|
||||
}
|
||||
if selectionFraction == 1.0 {
|
||||
self.buttonNode.accessibilityTraits = [.button, .selected]
|
||||
} else {
|
||||
self.buttonNode.accessibilityTraits = [.button]
|
||||
}
|
||||
|
||||
self.containerNode.isGestureEnabled = !isEditing && !isReordering
|
||||
@ -338,7 +335,6 @@ private final class ItemNode: ASDisplayNode {
|
||||
self.extractedContainerNode.contentNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
self.extractedContainerNode.contentRect = CGRect(origin: CGPoint(x: self.extractedBackgroundNode.frame.minX, y: 0.0), size: CGSize(width:self.extractedBackgroundNode.frame.width, height: size.height))
|
||||
self.containerNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
self.activateArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
self.hitTestSlop = UIEdgeInsets(top: 0.0, left: -sideInset, bottom: 0.0, right: -sideInset)
|
||||
self.extractedContainerNode.hitTestSlop = self.hitTestSlop
|
||||
|
@ -126,6 +126,13 @@ private final class ItemNode: ASDisplayNode {
|
||||
transition.updateAlpha(node: self.titleNode, alpha: deselectionAlpha)
|
||||
transition.updateAlpha(node: self.titleActiveNode, alpha: selectionAlpha)
|
||||
|
||||
self.buttonNode.accessibilityLabel = title
|
||||
if selectionFraction == 1.0 {
|
||||
self.buttonNode.accessibilityTraits = [.button, .selected]
|
||||
} else {
|
||||
self.buttonNode.accessibilityTraits = [.button]
|
||||
}
|
||||
|
||||
if self.theme !== presentationData.theme {
|
||||
self.theme = presentationData.theme
|
||||
self.iconNode.image = icon
|
||||
|
@ -1861,6 +1861,9 @@ public final class ChatListNode: ListView {
|
||||
return false
|
||||
}
|
||||
}
|
||||
case .GroupReferenceEntry:
|
||||
isEmpty = false
|
||||
return true
|
||||
default:
|
||||
return true
|
||||
}
|
||||
|
@ -686,9 +686,9 @@ func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState
|
||||
} else if case let .peerType(type) = mode, !result.isEmpty {
|
||||
switch type {
|
||||
case .group:
|
||||
result.append(.AdditionalCategory(index: 0, id: 0, title: "Create a New Group for This", image: PresentationResourcesItemList.createGroupIcon(state.presentationData.theme), appearance: .action, selected: false, presentationData: state.presentationData))
|
||||
result.append(.AdditionalCategory(index: 0, id: 0, title: state.presentationData.strings.RequestPeer_CreateNewGroup, image: PresentationResourcesItemList.createGroupIcon(state.presentationData.theme), appearance: .action, selected: false, presentationData: state.presentationData))
|
||||
case .channel:
|
||||
result.append(.AdditionalCategory(index: 0, id: 0, title: "Create a New Channel for This", image: PresentationResourcesItemList.createGroupIcon(state.presentationData.theme), appearance: .action, selected: false, presentationData: state.presentationData))
|
||||
result.append(.AdditionalCategory(index: 0, id: 0, title: state.presentationData.strings.RequestPeer_CreateNewChannel, image: PresentationResourcesItemList.createGroupIcon(state.presentationData.theme), appearance: .action, selected: false, presentationData: state.presentationData))
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
@ -103,7 +103,6 @@ public enum ChatInputMode: Equatable {
|
||||
|
||||
public enum ChatTitlePanelContext: Equatable, Comparable {
|
||||
case pinnedMessage
|
||||
case chatInfo
|
||||
case requestInProgress
|
||||
case toastAlert(String)
|
||||
case inviteRequests([EnginePeer], Int32)
|
||||
@ -112,8 +111,6 @@ public enum ChatTitlePanelContext: Equatable, Comparable {
|
||||
switch self {
|
||||
case .pinnedMessage:
|
||||
return 0
|
||||
case .chatInfo:
|
||||
return 1
|
||||
case .requestInProgress:
|
||||
return 2
|
||||
case .toastAlert:
|
||||
|
@ -101,6 +101,7 @@ private final class ContextControllerActionsListActionItemNode: HighlightTrackin
|
||||
|
||||
self.isAccessibilityElement = true
|
||||
self.accessibilityLabel = item.text
|
||||
self.accessibilityTraits = [.button]
|
||||
|
||||
self.addSubnode(self.highlightBackgroundNode)
|
||||
self.addSubnode(self.titleLabelNode)
|
||||
|
@ -8,6 +8,8 @@ public protocol AccessibilityFocusableNode {
|
||||
|
||||
public final class AccessibilityAreaNode: ASDisplayNode {
|
||||
public var activate: (() -> Bool)?
|
||||
public var increment: (() -> Void)?
|
||||
public var decrement: (() -> Void)?
|
||||
public var focused: (() -> Void)?
|
||||
|
||||
override public init() {
|
||||
@ -43,4 +45,12 @@ public final class AccessibilityAreaNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public func accessibilityIncrement() {
|
||||
self.increment?()
|
||||
}
|
||||
|
||||
override public func accessibilityDecrement() {
|
||||
self.decrement?()
|
||||
}
|
||||
}
|
||||
|
@ -697,9 +697,16 @@ open class NavigationBar: ASDisplayNode {
|
||||
if self.rightButtonNode.supernode != nil {
|
||||
addAccessibilityChildren(of: self.rightButtonNode, container: self, to: &accessibilityElements)
|
||||
}
|
||||
if let customHeaderContentView = self.customHeaderContentView, customHeaderContentView.superview != nil {
|
||||
customHeaderContentView.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(customHeaderContentView.bounds, in: customHeaderContentView)
|
||||
accessibilityElements.append(customHeaderContentView)
|
||||
}
|
||||
if let contentNode = self.contentNode {
|
||||
addAccessibilityChildren(of: contentNode, container: self, to: &accessibilityElements)
|
||||
}
|
||||
if let secondaryContentNode = self.secondaryContentNode {
|
||||
addAccessibilityChildren(of: secondaryContentNode, container: self, to: &accessibilityElements)
|
||||
}
|
||||
return accessibilityElements
|
||||
} set(value) {
|
||||
}
|
||||
|
@ -528,4 +528,12 @@ open class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGesture
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
open override func accessibilityPerformEscape() -> Bool {
|
||||
if let controller = self.galleryController() {
|
||||
controller.dismiss(animated: true)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,12 @@
|
||||
|
||||
- (void)setValue:(CGFloat)value animated:(BOOL)animated;
|
||||
|
||||
- (void)increase;
|
||||
- (void)increaseBy:(CGFloat)delta;
|
||||
|
||||
- (void)decrease;
|
||||
- (void)decreaseBy:(CGFloat)delta;
|
||||
|
||||
@end
|
||||
|
||||
extern const CGFloat TGPhotoEditorSliderViewMargin;
|
||||
|
@ -668,4 +668,32 @@ const CGFloat TGPhotoEditorSliderViewInternalMargin = 7.0f;
|
||||
self.interactionEnded();
|
||||
}
|
||||
|
||||
- (void)increase {
|
||||
self.value = MIN(self.maximumValue, self.value + 1);
|
||||
|
||||
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)increaseBy:(CGFloat)delta {
|
||||
self.value = MIN(self.maximumValue, self.value + delta);
|
||||
|
||||
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)decrease {
|
||||
self.value = MAX(self.minimumValue, self.value - 1);
|
||||
|
||||
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)decreaseBy:(CGFloat)delta {
|
||||
self.value = MAX(self.minimumValue, self.value - delta);
|
||||
|
||||
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -55,7 +55,7 @@ final class HelloView: UIView, PhoneDemoDecorationView {
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
func setupAnimations() {
|
||||
guard self.activePhrases.isEmpty else {
|
||||
return
|
||||
@ -121,11 +121,13 @@ final class HelloView: UIView, PhoneDemoDecorationView {
|
||||
self.activePositions.insert(positionIndex)
|
||||
|
||||
let duration: Double = Double.random(in: 1.75...2.25)
|
||||
view.layer.animateKeyframes(values: [0.0, 1.0, 0.0] as [NSNumber], duration: duration, keyPath: "opacity", removeOnCompletion: false, completion: { [weak view] _ in
|
||||
self.activePhrases.remove(index)
|
||||
self.activePositions.remove(positionIndex)
|
||||
view?.removeFromSuperview()
|
||||
self.spawnNextPhrase()
|
||||
view.layer.animateKeyframes(values: [0.0, 1.0, 0.0] as [NSNumber], duration: duration, keyPath: "opacity", removeOnCompletion: false, completion: { [weak view, weak self] _ in
|
||||
if let self {
|
||||
self.activePhrases.remove(index)
|
||||
self.activePositions.remove(positionIndex)
|
||||
view?.removeFromSuperview()
|
||||
self.spawnNextPhrase()
|
||||
}
|
||||
})
|
||||
view.layer.animateScale(from: CGFloat.random(in: 0.4 ..< 0.6), to: CGFloat.random(in: 0.9 ..< 1.2), duration: duration, removeOnCompletion: false)
|
||||
|
||||
|
@ -429,6 +429,9 @@ private final class BubbleSettingsToolbarNode: ASDisplayNode {
|
||||
|
||||
super.init()
|
||||
|
||||
self.cancelButton.accessibilityTraits = [.button]
|
||||
self.doneButton.accessibilityTraits = [.button]
|
||||
|
||||
self.addSubnode(self.switchItemNode)
|
||||
self.addSubnode(self.cornerRadiusItemNode)
|
||||
self.addSubnode(self.cancelButton)
|
||||
@ -482,6 +485,9 @@ private final class BubbleSettingsToolbarNode: ASDisplayNode {
|
||||
|
||||
self.cancelButton.setTitle(presentationData.strings.Common_Cancel, with: Font.regular(17.0), with: presentationData.theme.list.itemPrimaryTextColor, for: [])
|
||||
self.doneButton.setTitle(presentationData.strings.Wallpaper_Set, with: Font.regular(17.0), with: presentationData.theme.list.itemPrimaryTextColor, for: [])
|
||||
|
||||
self.cancelButton.accessibilityLabel = presentationData.strings.Common_Cancel
|
||||
self.doneButton.accessibilityLabel = presentationData.strings.Wallpaper_Set
|
||||
}
|
||||
|
||||
func updatePresentationThemeSettings(presentationThemeSettings: PresentationThemeSettings) {
|
||||
|
@ -95,6 +95,8 @@ private final class AutodownloadDataUsagePickerItemNode: ListViewItemNode {
|
||||
private let customTextNode: TextNode
|
||||
private var sliderView: TGPhotoEditorSliderView?
|
||||
|
||||
private let activateArea: AccessibilityAreaNode
|
||||
|
||||
private var item: AutodownloadDataUsagePickerItem?
|
||||
private var layoutParams: ListViewItemLayoutParams?
|
||||
|
||||
@ -126,12 +128,27 @@ private final class AutodownloadDataUsagePickerItemNode: ListViewItemNode {
|
||||
self.customTextNode.isUserInteractionEnabled = false
|
||||
self.customTextNode.displaysAsynchronously = false
|
||||
|
||||
self.activateArea = AccessibilityAreaNode()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
|
||||
self.addSubnode(self.lowTextNode)
|
||||
self.addSubnode(self.mediumTextNode)
|
||||
self.addSubnode(self.highTextNode)
|
||||
self.addSubnode(self.customTextNode)
|
||||
self.addSubnode(self.activateArea)
|
||||
|
||||
self.activateArea.increment = { [weak self] in
|
||||
if let self {
|
||||
self.sliderView?.increase()
|
||||
}
|
||||
}
|
||||
|
||||
self.activateArea.decrement = { [weak self] in
|
||||
if let self {
|
||||
self.sliderView?.decrease()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateSliderView() {
|
||||
@ -154,6 +171,8 @@ private final class AutodownloadDataUsagePickerItemNode: ListViewItemNode {
|
||||
sliderView.isUserInteractionEnabled = item.enabled
|
||||
sliderView.alpha = item.enabled ? 1.0 : 0.4
|
||||
sliderView.layer.allowsGroupOpacity = !item.enabled
|
||||
|
||||
self.updateAccessibilityLabels()
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,11 +342,33 @@ private final class AutodownloadDataUsagePickerItemNode: ListViewItemNode {
|
||||
|
||||
strongSelf.updateSliderView()
|
||||
}
|
||||
strongSelf.activateArea.accessibilityLabel = item.strings.AutoDownloadSettings_DataUsage
|
||||
|
||||
strongSelf.activateArea.frame = CGRect(origin: CGPoint(x: params.leftInset, y: 0.0), size: CGSize(width: params.width - params.leftInset - params.rightInset, height: layout.contentSize.height))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private func updateAccessibilityLabels() {
|
||||
guard let item = self.item else {
|
||||
return
|
||||
}
|
||||
var textNodes: [TextNode] = [self.lowTextNode, self.mediumTextNode, self.highTextNode]
|
||||
if let customPosition = item.customPosition {
|
||||
textNodes.insert(self.customTextNode, at: customPosition)
|
||||
}
|
||||
if let value = self.sliderView?.value {
|
||||
self.activateArea.accessibilityValue = textNodes[Int(value)].cachedLayout?.attributedString?.string ?? ""
|
||||
}
|
||||
var accessibilityTraits: UIAccessibilityTraits = [.adjustable]
|
||||
if item.enabled {
|
||||
} else {
|
||||
accessibilityTraits.insert(.notEnabled)
|
||||
}
|
||||
self.activateArea.accessibilityTraits = accessibilityTraits
|
||||
}
|
||||
|
||||
override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
|
||||
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4)
|
||||
}
|
||||
|
@ -135,6 +135,8 @@ class ItemListWebsiteItemNode: ItemListRevealOptionsItemNode {
|
||||
return self.containerNode
|
||||
}
|
||||
|
||||
private let activateArea: AccessibilityAreaNode
|
||||
|
||||
private var layoutParams: (ItemListWebsiteItem, ListViewItemLayoutParams, ItemListNeighbors)?
|
||||
|
||||
private var editableControlNode: ItemListEditableControlNode?
|
||||
@ -184,6 +186,8 @@ class ItemListWebsiteItemNode: ItemListRevealOptionsItemNode {
|
||||
self.highlightedBackgroundNode = ASDisplayNode()
|
||||
self.highlightedBackgroundNode.isLayerBacked = true
|
||||
|
||||
self.activateArea = AccessibilityAreaNode()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false)
|
||||
|
||||
self.addSubnode(self.containerNode)
|
||||
@ -191,6 +195,8 @@ class ItemListWebsiteItemNode: ItemListRevealOptionsItemNode {
|
||||
self.containerNode.addSubnode(self.titleNode)
|
||||
self.containerNode.addSubnode(self.appNode)
|
||||
self.containerNode.addSubnode(self.locationNode)
|
||||
|
||||
self.addSubnode(self.activateArea)
|
||||
}
|
||||
|
||||
func asyncLayout() -> (_ item: ItemListWebsiteItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, (Bool) -> Void) {
|
||||
@ -288,6 +294,28 @@ class ItemListWebsiteItemNode: ItemListRevealOptionsItemNode {
|
||||
if let strongSelf = self {
|
||||
strongSelf.layoutParams = (item, params, neighbors)
|
||||
|
||||
strongSelf.activateArea.frame = CGRect(origin: CGPoint(x: params.leftInset, y: 0.0), size: CGSize(width: params.width - params.leftInset - params.rightInset, height: layout.contentSize.height))
|
||||
|
||||
strongSelf.activateArea.accessibilityLabel = titleAttributedString?.string ?? ""
|
||||
|
||||
var value = ""
|
||||
if let string = appAttributedString?.string {
|
||||
value += string
|
||||
}
|
||||
if let string = locationAttributedString?.string {
|
||||
if !value.isEmpty {
|
||||
value += "\n"
|
||||
}
|
||||
value += string
|
||||
}
|
||||
strongSelf.activateArea.accessibilityValue = value
|
||||
|
||||
if item.enabled {
|
||||
strongSelf.activateArea.accessibilityTraits = []
|
||||
} else {
|
||||
strongSelf.activateArea.accessibilityTraits = .notEnabled
|
||||
}
|
||||
|
||||
if let _ = updatedTheme {
|
||||
strongSelf.topStripeNode.backgroundColor = item.presentationData.theme.list.itemBlocksSeparatorColor
|
||||
strongSelf.bottomStripeNode.backgroundColor = item.presentationData.theme.list.itemBlocksSeparatorColor
|
||||
|
@ -716,6 +716,9 @@ private final class TextSelectionToolbarNode: ASDisplayNode {
|
||||
|
||||
super.init()
|
||||
|
||||
self.cancelButton.accessibilityTraits = [.button]
|
||||
self.doneButton.accessibilityTraits = [.button]
|
||||
|
||||
self.addSubnode(self.switchItemNode)
|
||||
self.addSubnode(self.fontSizeItemNode)
|
||||
self.addSubnode(self.cancelButton)
|
||||
@ -769,6 +772,9 @@ private final class TextSelectionToolbarNode: ASDisplayNode {
|
||||
|
||||
self.cancelButton.setTitle(presentationData.strings.Common_Cancel, with: Font.regular(17.0), with: presentationData.theme.list.itemPrimaryTextColor, for: [])
|
||||
self.doneButton.setTitle(presentationData.strings.Wallpaper_Set, with: Font.regular(17.0), with: presentationData.theme.list.itemPrimaryTextColor, for: [])
|
||||
|
||||
self.cancelButton.accessibilityLabel = presentationData.strings.Common_Cancel
|
||||
self.doneButton.accessibilityLabel = presentationData.strings.Wallpaper_Set
|
||||
}
|
||||
|
||||
func updatePresentationThemeSettings(presentationThemeSettings: PresentationThemeSettings) {
|
||||
|
@ -203,6 +203,8 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode {
|
||||
private var placeholderNode: StickerShimmerEffectNode
|
||||
var snapshotView: UIView?
|
||||
|
||||
private let activateAreaNode: AccessibilityAreaNode
|
||||
|
||||
var item: ThemeCarouselThemeIconItem?
|
||||
|
||||
override var visibility: ListViewItemNodeVisibility {
|
||||
@ -246,6 +248,8 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode {
|
||||
self.emojiImageNode = TransformImageNode()
|
||||
|
||||
self.placeholderNode = StickerShimmerEffectNode()
|
||||
|
||||
self.activateAreaNode = AccessibilityAreaNode()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false)
|
||||
|
||||
@ -272,6 +276,8 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode {
|
||||
}
|
||||
firstTime = false
|
||||
}
|
||||
|
||||
self.addSubnode(self.activateAreaNode)
|
||||
}
|
||||
|
||||
deinit {
|
||||
@ -442,6 +448,16 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode {
|
||||
animatedStickerNode.frame = emojiFrame
|
||||
animatedStickerNode.updateLayout(size: emojiFrame.size)
|
||||
}
|
||||
|
||||
let presentationData = item.context.sharedContext.currentPresentationData.with { $0 }
|
||||
strongSelf.activateAreaNode.accessibilityLabel = item.themeReference.emoticon.flatMap { presentationData.strings.Appearance_VoiceOver_Theme($0).string }
|
||||
if item.selected {
|
||||
strongSelf.activateAreaNode.accessibilityTraits = [.button, .selected]
|
||||
} else {
|
||||
strongSelf.activateAreaNode.accessibilityTraits = [.button]
|
||||
}
|
||||
|
||||
strongSelf.activateAreaNode.frame = CGRect(origin: .zero, size: itemLayout.size)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -102,6 +102,8 @@ private final class ThemeSettingsAppIconNode : ASDisplayNode {
|
||||
private let textNode: ImmediateTextNode
|
||||
private var action: (() -> Void)?
|
||||
|
||||
private let activateAreaNode: AccessibilityAreaNode
|
||||
|
||||
private var locked = false
|
||||
|
||||
override init() {
|
||||
@ -122,12 +124,16 @@ private final class ThemeSettingsAppIconNode : ASDisplayNode {
|
||||
self.textNode.isUserInteractionEnabled = false
|
||||
self.textNode.displaysAsynchronously = false
|
||||
|
||||
self.activateAreaNode = AccessibilityAreaNode()
|
||||
self.activateAreaNode.accessibilityTraits = [.button]
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.iconNode)
|
||||
self.addSubnode(self.overlayNode)
|
||||
self.addSubnode(self.textNode)
|
||||
self.addSubnode(self.lockNode)
|
||||
self.addSubnode(self.activateAreaNode)
|
||||
}
|
||||
|
||||
func setup(theme: PresentationTheme, icon: UIImage, title: NSAttributedString, locked: Bool, color: UIColor, bordered: Bool, selected: Bool, action: @escaping () -> Void) {
|
||||
@ -140,6 +146,13 @@ private final class ThemeSettingsAppIconNode : ASDisplayNode {
|
||||
action()
|
||||
}
|
||||
|
||||
self.activateAreaNode.accessibilityLabel = title.string
|
||||
if locked {
|
||||
self.activateAreaNode.accessibilityTraits = [.button, .notEnabled]
|
||||
} else {
|
||||
self.activateAreaNode.accessibilityTraits = [.button]
|
||||
}
|
||||
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
@ -171,6 +184,8 @@ private final class ThemeSettingsAppIconNode : ASDisplayNode {
|
||||
self.textNode.frame = textFrame
|
||||
|
||||
self.lockNode.frame = CGRect(x: self.textNode.frame.minX - 10.0, y: 90.0, width: 6.0, height: 8.0)
|
||||
|
||||
self.activateAreaNode.frame = self.bounds
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,7 +201,7 @@ class ThemeSettingsAppIconItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
private let scrollNode: ASScrollNode
|
||||
private var nodes: [ThemeSettingsAppIconNode] = []
|
||||
|
||||
|
||||
private var item: ThemeSettingsAppIconItem?
|
||||
private var layoutParams: ListViewItemLayoutParams?
|
||||
|
||||
|
@ -207,6 +207,8 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
private let titleNode: TextNode
|
||||
var snapshotView: UIView?
|
||||
|
||||
private let activateAreaNode: AccessibilityAreaNode
|
||||
|
||||
var item: ThemeSettingsThemeIconItem?
|
||||
|
||||
init() {
|
||||
@ -222,13 +224,17 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
|
||||
self.titleNode = TextNode()
|
||||
self.titleNode.isUserInteractionEnabled = false
|
||||
|
||||
|
||||
self.activateAreaNode = AccessibilityAreaNode()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false)
|
||||
|
||||
self.addSubnode(self.containerNode)
|
||||
self.containerNode.addSubnode(self.imageNode)
|
||||
self.containerNode.addSubnode(self.overlayNode)
|
||||
self.containerNode.addSubnode(self.titleNode)
|
||||
|
||||
self.addSubnode(self.activateAreaNode)
|
||||
|
||||
self.containerNode.activated = { [weak self] gesture, _ in
|
||||
guard let strongSelf = self, let item = strongSelf.item else {
|
||||
@ -308,6 +314,15 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
|
||||
strongSelf.overlayNode.frame = CGRect(origin: CGPoint(x: 9.0, y: 13.0), size: CGSize(width: 100.0, height: 64.0))
|
||||
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 88.0), size: CGSize(width: itemLayout.contentSize.width, height: 16.0))
|
||||
|
||||
strongSelf.activateAreaNode.accessibilityLabel = item.title
|
||||
if item.selected {
|
||||
strongSelf.activateAreaNode.accessibilityTraits = [.button, .selected]
|
||||
} else {
|
||||
strongSelf.activateAreaNode.accessibilityTraits = [.button]
|
||||
}
|
||||
|
||||
strongSelf.activateAreaNode.frame = CGRect(origin: .zero, size: itemLayout.size)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -237,6 +237,9 @@ public final class ChatListHeaderComponent: Component {
|
||||
self.titleView.attributedText = NSAttributedString(string: title, font: Font.regular(17.0), textColor: theme.rootController.navigationBar.accentTextColor)
|
||||
let titleSize = self.titleView.updateLayout(CGSize(width: 100.0, height: 44.0))
|
||||
|
||||
self.accessibilityLabel = title
|
||||
self.accessibilityTraits = [.button]
|
||||
|
||||
if self.currentColor != theme.rootController.navigationBar.accentTextColor {
|
||||
self.currentColor = theme.rootController.navigationBar.accentTextColor
|
||||
self.arrowView.image = NavigationBarTheme.generateBackArrowImage(color: theme.rootController.navigationBar.accentTextColor)
|
||||
|
@ -4304,36 +4304,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
self.chatTitleView = ChatTitleView(context: self.context, theme: self.presentationData.theme, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameDisplayOrder: self.presentationData.nameDisplayOrder, animationCache: controllerInteraction.presentationContext.animationCache, animationRenderer: controllerInteraction.presentationContext.animationRenderer)
|
||||
self.navigationItem.titleView = self.chatTitleView
|
||||
self.chatTitleView?.pressed = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
if strongSelf.chatLocation == .peer(id: strongSelf.context.account.peerId) {
|
||||
if let peer = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer, let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: true, requestsContext: nil) {
|
||||
strongSelf.effectiveNavigationController?.pushViewController(infoController)
|
||||
}
|
||||
} else {
|
||||
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
||||
return $0.updatedTitlePanelContext {
|
||||
if let index = $0.firstIndex(where: {
|
||||
switch $0 {
|
||||
case .chatInfo:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}) {
|
||||
var updatedContexts = $0
|
||||
updatedContexts.remove(at: index)
|
||||
return updatedContexts
|
||||
} else {
|
||||
var updatedContexts = $0
|
||||
updatedContexts.append(.chatInfo)
|
||||
return updatedContexts.sorted()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
self.chatTitleView?.longPressed = { [weak self] in
|
||||
if let strongSelf = self, let peerView = strongSelf.peerView, let peer = peerView.peers[peerView.peerId], peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil && !strongSelf.presentationInterfaceState.isNotAccessible {
|
||||
strongSelf.interfaceInteraction?.beginMessageSearch(.everything, "")
|
||||
@ -8317,22 +8287,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: interactive, { current in
|
||||
return current.updatedTitlePanelContext {
|
||||
if let index = $0.firstIndex(where: {
|
||||
switch $0 {
|
||||
case .chatInfo:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}) {
|
||||
var updatedContexts = $0
|
||||
updatedContexts.remove(at: index)
|
||||
return updatedContexts
|
||||
} else {
|
||||
return $0
|
||||
}
|
||||
}.updatedSearch(current.search == nil ? ChatSearchData(domain: domain).withUpdatedQuery(query) : current.search?.withUpdatedDomain(domain).withUpdatedQuery(query))
|
||||
return current.updatedSearch(current.search == nil ? ChatSearchData(domain: domain).withUpdatedQuery(query) : current.search?.withUpdatedDomain(domain).withUpdatedQuery(query))
|
||||
})
|
||||
strongSelf.updateItemNodesSearchTextHighlightStates()
|
||||
})
|
||||
@ -9613,17 +9568,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
guard let strongSelf = self, case let .peer(peerId) = strongSelf.chatLocation else {
|
||||
return
|
||||
}
|
||||
strongSelf.updateChatPresentationInterfaceState(interactive: true, { state in
|
||||
return state.updatedTitlePanelContext({
|
||||
$0.filter({ item in
|
||||
if case .chatInfo = item {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
let _ = (strongSelf.context.engine.peers.updatePeersGroupIdInteractively(peerIds: [peerId], groupId: .root)
|
||||
|> deliverOnMainQueue).start()
|
||||
}, openLinkEditing: { [weak self] in
|
||||
@ -11070,30 +11014,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return interfaceState
|
||||
}).start()
|
||||
}
|
||||
|
||||
override public func viewDidDisappear(_ animated: Bool) {
|
||||
super.viewDidDisappear(animated)
|
||||
|
||||
self.updateChatPresentationInterfaceState(animated: false, interactive: false, {
|
||||
$0.updatedTitlePanelContext {
|
||||
if let index = $0.firstIndex(where: {
|
||||
switch $0 {
|
||||
case .chatInfo:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}) {
|
||||
var updatedContexts = $0
|
||||
updatedContexts.remove(at: index)
|
||||
return updatedContexts
|
||||
} else {
|
||||
return $0
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override public func viewWillLeaveNavigation() {
|
||||
self.chatDisplayNode.willNavigateAway()
|
||||
}
|
||||
@ -11719,7 +11640,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
private func navigationButtonAction(_ action: ChatNavigationButtonAction) {
|
||||
switch action {
|
||||
case .spacer:
|
||||
case .spacer, .toggleInfoPanel:
|
||||
break
|
||||
case .cancelMessageSelection:
|
||||
self.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } })
|
||||
@ -12204,27 +12125,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
case .feed:
|
||||
break
|
||||
}
|
||||
case .toggleInfoPanel:
|
||||
self.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
||||
return $0.updatedTitlePanelContext {
|
||||
if let index = $0.firstIndex(where: {
|
||||
switch $0 {
|
||||
case .chatInfo:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}) {
|
||||
var updatedContexts = $0
|
||||
updatedContexts.remove(at: index)
|
||||
return updatedContexts
|
||||
} else {
|
||||
var updatedContexts = $0
|
||||
updatedContexts.append(.chatInfo)
|
||||
return updatedContexts.sorted()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,230 +0,0 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import ChatPresentationInterfaceState
|
||||
|
||||
private enum ChatInfoTitleButton {
|
||||
case search
|
||||
case info
|
||||
case mute
|
||||
case unmute
|
||||
case call
|
||||
case report
|
||||
case unarchive
|
||||
|
||||
func title(_ strings: PresentationStrings) -> String {
|
||||
switch self {
|
||||
case .search:
|
||||
return strings.Common_Search
|
||||
case .info:
|
||||
return strings.Conversation_Info
|
||||
case .mute:
|
||||
return strings.Conversation_TitleMute
|
||||
case .unmute:
|
||||
return strings.Conversation_TitleUnmute
|
||||
case .call:
|
||||
return strings.Conversation_Call
|
||||
case .report:
|
||||
return strings.ReportPeer_Report
|
||||
case .unarchive:
|
||||
return strings.ChatList_UnarchiveAction
|
||||
}
|
||||
}
|
||||
|
||||
func icon(_ theme: PresentationTheme) -> UIImage? {
|
||||
switch self {
|
||||
case .search:
|
||||
return PresentationResourcesChat.chatTitlePanelSearchImage(theme)
|
||||
case .info:
|
||||
return PresentationResourcesChat.chatTitlePanelInfoImage(theme)
|
||||
case .mute:
|
||||
return PresentationResourcesChat.chatTitlePanelMuteImage(theme)
|
||||
case .unmute:
|
||||
return PresentationResourcesChat.chatTitlePanelUnmuteImage(theme)
|
||||
case .call:
|
||||
return PresentationResourcesChat.chatTitlePanelCallImage(theme)
|
||||
case .report:
|
||||
return PresentationResourcesChat.chatTitlePanelReportImage(theme)
|
||||
case .unarchive:
|
||||
return PresentationResourcesChat.chatTitlePanelUnarchiveImage(theme)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func peerButtons(_ peer: Peer, interfaceState: ChatPresentationInterfaceState) -> [ChatInfoTitleButton] {
|
||||
let muteAction: ChatInfoTitleButton
|
||||
if interfaceState.peerIsMuted {
|
||||
muteAction = .unmute
|
||||
} else {
|
||||
muteAction = .mute
|
||||
}
|
||||
|
||||
let infoButton: ChatInfoTitleButton
|
||||
if interfaceState.isArchived {
|
||||
infoButton = .unarchive
|
||||
} else {
|
||||
infoButton = .info
|
||||
}
|
||||
|
||||
if let peer = peer as? TelegramUser {
|
||||
var buttons: [ChatInfoTitleButton] = [.search, muteAction]
|
||||
if peer.botInfo == nil && interfaceState.callsAvailable {
|
||||
buttons.append(.call)
|
||||
}
|
||||
|
||||
buttons.append(infoButton)
|
||||
return buttons
|
||||
} else if let _ = peer as? TelegramSecretChat {
|
||||
var buttons: [ChatInfoTitleButton] = [.search, muteAction]
|
||||
buttons.append(.call)
|
||||
buttons.append(.info)
|
||||
return buttons
|
||||
} else if let channel = peer as? TelegramChannel {
|
||||
if channel.flags.contains(.isCreator) || channel.addressName == nil {
|
||||
return [.search, muteAction, infoButton]
|
||||
} else {
|
||||
return [.search, .report, muteAction, infoButton]
|
||||
}
|
||||
} else if let group = peer as? TelegramGroup {
|
||||
if case .creator = group.role {
|
||||
return [.search, muteAction, infoButton]
|
||||
} else {
|
||||
return [.search, muteAction, infoButton]
|
||||
}
|
||||
} else {
|
||||
return [.search, muteAction, infoButton]
|
||||
}
|
||||
}
|
||||
|
||||
private let buttonFont = Font.medium(10.0)
|
||||
|
||||
private final class ChatInfoTitlePanelButtonNode: HighlightableButtonNode {
|
||||
init() {
|
||||
super.init()
|
||||
|
||||
self.displaysAsynchronously = false
|
||||
self.imageNode.displayWithoutProcessing = true
|
||||
self.imageNode.displaysAsynchronously = false
|
||||
|
||||
self.titleNode.displaysAsynchronously = false
|
||||
|
||||
self.laysOutHorizontally = false
|
||||
}
|
||||
|
||||
func setup(text: String, color: UIColor, icon: UIImage?) {
|
||||
self.setTitle(text, with: buttonFont, with: color, for: [])
|
||||
self.setImage(icon, for: [])
|
||||
if let icon = icon {
|
||||
self.contentSpacing = max(0.0, 32.0 - icon.size.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class ChatInfoTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
private var theme: PresentationTheme?
|
||||
|
||||
private let separatorNode: ASDisplayNode
|
||||
private var buttons: [(ChatInfoTitleButton, ChatInfoTitlePanelButtonNode)] = []
|
||||
|
||||
override init() {
|
||||
self.separatorNode = ASDisplayNode()
|
||||
self.separatorNode.isLayerBacked = true
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.separatorNode)
|
||||
}
|
||||
|
||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> LayoutResult {
|
||||
let themeUpdated = self.theme !== interfaceState.theme
|
||||
self.theme = interfaceState.theme
|
||||
|
||||
let panelHeight: CGFloat = 55.0
|
||||
|
||||
if themeUpdated {
|
||||
self.separatorNode.backgroundColor = interfaceState.theme.rootController.navigationBar.separatorColor
|
||||
}
|
||||
|
||||
let updatedButtons: [ChatInfoTitleButton]
|
||||
switch interfaceState.chatLocation {
|
||||
case .peer:
|
||||
if let peer = interfaceState.renderedPeer?.peer {
|
||||
updatedButtons = peerButtons(peer, interfaceState: interfaceState)
|
||||
} else {
|
||||
updatedButtons = []
|
||||
}
|
||||
case .replyThread, .feed:
|
||||
updatedButtons = []
|
||||
}
|
||||
|
||||
var buttonsUpdated = false
|
||||
if self.buttons.count != updatedButtons.count {
|
||||
buttonsUpdated = true
|
||||
} else {
|
||||
for i in 0 ..< updatedButtons.count {
|
||||
if self.buttons[i].0 != updatedButtons[i] {
|
||||
buttonsUpdated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if buttonsUpdated || themeUpdated {
|
||||
for (_, buttonNode) in self.buttons {
|
||||
buttonNode.removeFromSupernode()
|
||||
}
|
||||
self.buttons.removeAll()
|
||||
for button in updatedButtons {
|
||||
let buttonNode = ChatInfoTitlePanelButtonNode()
|
||||
buttonNode.laysOutHorizontally = false
|
||||
|
||||
buttonNode.setup(text: button.title(interfaceState.strings), color: interfaceState.theme.chat.inputPanel.panelControlAccentColor, icon: button.icon(interfaceState.theme))
|
||||
|
||||
buttonNode.addTarget(self, action: #selector(self.buttonPressed(_:)), forControlEvents: [.touchUpInside])
|
||||
self.addSubnode(buttonNode)
|
||||
self.buttons.append((button, buttonNode))
|
||||
}
|
||||
}
|
||||
|
||||
if !self.buttons.isEmpty {
|
||||
let buttonWidth = floor((width - leftInset - rightInset) / CGFloat(self.buttons.count))
|
||||
var nextButtonOrigin: CGFloat = leftInset
|
||||
for (_, buttonNode) in self.buttons {
|
||||
buttonNode.frame = CGRect(origin: CGPoint(x: nextButtonOrigin, y: 0.0), size: CGSize(width: buttonWidth, height: panelHeight))
|
||||
nextButtonOrigin += buttonWidth
|
||||
}
|
||||
}
|
||||
|
||||
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: width, height: UIScreenPixel)))
|
||||
|
||||
return LayoutResult(backgroundHeight: panelHeight, insetHeight: panelHeight)
|
||||
}
|
||||
|
||||
@objc func buttonPressed(_ node: HighlightableButtonNode) {
|
||||
for (button, buttonNode) in self.buttons {
|
||||
if buttonNode === node {
|
||||
switch button {
|
||||
case .info:
|
||||
self.interfaceInteraction?.openPeerInfo()
|
||||
case .mute:
|
||||
self.interfaceInteraction?.togglePeerNotifications()
|
||||
case .unmute:
|
||||
self.interfaceInteraction?.togglePeerNotifications()
|
||||
case .search:
|
||||
self.interfaceInteraction?.beginMessageSearch(.everything, "")
|
||||
case .call:
|
||||
self.interfaceInteraction?.beginCall(false)
|
||||
case .report:
|
||||
self.interfaceInteraction?.reportPeer()
|
||||
case .unarchive:
|
||||
self.interfaceInteraction?.unarchiveChat()
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceStat
|
||||
break loop
|
||||
}
|
||||
}
|
||||
case .chatInfo, .requestInProgress, .toastAlert, .inviteRequests:
|
||||
case .requestInProgress, .toastAlert, .inviteRequests:
|
||||
selectedContext = context
|
||||
break loop
|
||||
}
|
||||
@ -120,14 +120,6 @@ func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceStat
|
||||
panel.interfaceInteraction = interfaceInteraction
|
||||
return panel
|
||||
}
|
||||
case .chatInfo:
|
||||
if let currentPanel = currentPanel as? ChatInfoTitlePanelNode {
|
||||
return currentPanel
|
||||
} else {
|
||||
let panel = ChatInfoTitlePanelNode()
|
||||
panel.interfaceInteraction = interfaceInteraction
|
||||
return panel
|
||||
}
|
||||
case .requestInProgress:
|
||||
if let currentPanel = currentPanel as? ChatRequestInProgressTitlePanelNode {
|
||||
return currentPanel
|
||||
|
@ -119,6 +119,8 @@ final class ChatInviteRequestsTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
private var avatarsContent: AnimatedAvatarSetContext.Content?
|
||||
private let avatarsNode: AnimatedAvatarSetNode
|
||||
|
||||
private let activateAreaNode: AccessibilityAreaNode
|
||||
|
||||
private var theme: PresentationTheme?
|
||||
|
||||
private var peerId: PeerId?
|
||||
@ -138,6 +140,9 @@ final class ChatInviteRequestsTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
self.avatarsContext = AnimatedAvatarSetContext()
|
||||
self.avatarsNode = AnimatedAvatarSetNode()
|
||||
|
||||
self.activateAreaNode = AccessibilityAreaNode()
|
||||
self.activateAreaNode.accessibilityTraits = .button
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.separatorNode)
|
||||
@ -146,6 +151,8 @@ final class ChatInviteRequestsTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
self.addSubnode(self.closeButton)
|
||||
|
||||
self.addSubnode(self.avatarsNode)
|
||||
|
||||
self.addSubnode(self.activateAreaNode)
|
||||
}
|
||||
|
||||
|
||||
@ -198,6 +205,9 @@ final class ChatInviteRequestsTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
transition.updateFrame(node: self.avatarsNode, frame: CGRect(origin: CGPoint(x: leftInset + 8.0, y: floor((panelHeight - avatarsSize.height) / 2.0)), size: avatarsSize))
|
||||
}
|
||||
|
||||
self.activateAreaNode.frame = CGRect(origin: .zero, size: CGSize(width: width, height: panelHeight))
|
||||
self.activateAreaNode.accessibilityLabel = interfaceState.strings.Conversation_RequestsToJoin(self.count)
|
||||
|
||||
return LayoutResult(backgroundHeight: initialPanelHeight, insetHeight: panelHeight)
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@ final class ChatRequestInProgressTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
private let separatorNode: ASDisplayNode
|
||||
private let titleNode: ImmediateTextNode
|
||||
|
||||
private let activateAreaNode: AccessibilityAreaNode
|
||||
|
||||
private var theme: PresentationTheme?
|
||||
private var strings: PresentationStrings?
|
||||
|
||||
@ -19,10 +21,15 @@ final class ChatRequestInProgressTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
self.titleNode = ImmediateTextNode()
|
||||
self.titleNode.maximumNumberOfLines = 1
|
||||
|
||||
self.activateAreaNode = AccessibilityAreaNode()
|
||||
self.activateAreaNode.accessibilityTraits = .staticText
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.titleNode)
|
||||
self.addSubnode(self.separatorNode)
|
||||
|
||||
self.addSubnode(self.activateAreaNode)
|
||||
}
|
||||
|
||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> LayoutResult {
|
||||
@ -46,6 +53,9 @@ final class ChatRequestInProgressTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
|
||||
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: width, height: UIScreenPixel)))
|
||||
|
||||
self.activateAreaNode.frame = CGRect(origin: .zero, size: CGSize(width: width, height: panelHeight))
|
||||
self.activateAreaNode.accessibilityLabel = interfaceState.strings.Channel_NotificationLoading
|
||||
|
||||
return LayoutResult(backgroundHeight: panelHeight, insetHeight: panelHeight)
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ final class ChatToastAlertPanelNode: ChatTitleAccessoryPanelNode {
|
||||
private let separatorNode: ASDisplayNode
|
||||
private let titleNode: ImmediateTextNode
|
||||
|
||||
private let activateAreaNode: AccessibilityAreaNode
|
||||
|
||||
private var textColor: UIColor = .black {
|
||||
didSet {
|
||||
if !self.textColor.isEqual(oldValue) {
|
||||
@ -34,6 +36,9 @@ final class ChatToastAlertPanelNode: ChatTitleAccessoryPanelNode {
|
||||
self.titleNode.maximumNumberOfLines = 1
|
||||
self.titleNode.insets = UIEdgeInsets(top: 2.0, left: 2.0, bottom: 2.0, right: 2.0)
|
||||
|
||||
self.activateAreaNode = AccessibilityAreaNode()
|
||||
self.activateAreaNode.accessibilityTraits = [.staticText]
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.titleNode)
|
||||
@ -51,6 +56,9 @@ final class ChatToastAlertPanelNode: ChatTitleAccessoryPanelNode {
|
||||
let titleSize = self.titleNode.updateLayout(CGSize(width: width - leftInset - rightInset - 20.0, height: 100.0))
|
||||
self.titleNode.frame = CGRect(origin: CGPoint(x: floor((width - titleSize.width) / 2.0), y: floor((panelHeight - titleSize.height) / 2.0)), size: titleSize)
|
||||
|
||||
self.activateAreaNode.frame = CGRect(origin: .zero, size: CGSize(width: width, height: panelHeight))
|
||||
self.activateAreaNode.accessibilityLabel = self.titleNode.attributedText?.string ?? ""
|
||||
|
||||
return LayoutResult(backgroundHeight: panelHeight, insetHeight: panelHeight)
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +155,12 @@ public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id)
|
||||
return .single(nil)
|
||||
}
|
||||
if #available(iOS 12.0, *) {
|
||||
let baseLang = context.sharedContext.currentPresentationData.with { $0 }.strings.baseLanguageCode
|
||||
var baseLang = context.sharedContext.currentPresentationData.with { $0 }.strings.baseLanguageCode
|
||||
let rawSuffix = "-raw"
|
||||
if baseLang.hasSuffix(rawSuffix) {
|
||||
baseLang = String(baseLang.dropLast(rawSuffix.count))
|
||||
}
|
||||
|
||||
return context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.translationSettings])
|
||||
|> mapToSignal { sharedData in
|
||||
let settings = sharedData.entries[ApplicationSpecificSharedDataKeys.translationSettings]?.get(TranslationSettings.self) ?? TranslationSettings.defaultSettings
|
||||
|
Loading…
x
Reference in New Issue
Block a user