mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-08 01:40:09 +00:00
Merge commit '8213fdaee36cf426edf15efe93ad146a09bbdc79'
This commit is contained in:
commit
a03b3766d6
@ -6147,3 +6147,5 @@ Sorry for the inconvenience.";
|
|||||||
|
|
||||||
"Channel.Setup.LinkTypePublic" = "Public";
|
"Channel.Setup.LinkTypePublic" = "Public";
|
||||||
"Channel.Setup.LinkTypePrivate" = "Private";
|
"Channel.Setup.LinkTypePrivate" = "Private";
|
||||||
|
|
||||||
|
"VoiceOver.ScrollStatus" = "Row %1$@ of %2$@";
|
||||||
|
|||||||
@ -220,6 +220,10 @@ final class CallListControllerNode: ASDisplayNode {
|
|||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
self.listNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.leftOverlayNode = ASDisplayNode()
|
self.leftOverlayNode = ASDisplayNode()
|
||||||
self.leftOverlayNode.backgroundColor = self.presentationData.theme.list.blocksBackgroundColor
|
self.leftOverlayNode.backgroundColor = self.presentationData.theme.list.blocksBackgroundColor
|
||||||
self.rightOverlayNode = ASDisplayNode()
|
self.rightOverlayNode = ASDisplayNode()
|
||||||
|
|||||||
@ -140,6 +140,9 @@ public final class ChatListSearchRecentPeersNode: ASDisplayNode {
|
|||||||
|
|
||||||
self.listView = ListView()
|
self.listView = ListView()
|
||||||
self.listView.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
|
self.listView.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
|
||||||
|
self.listView.accessibilityPageScrolledString = { row, count in
|
||||||
|
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -735,7 +735,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
}
|
}
|
||||||
self.tagMask = tagMask
|
self.tagMask = tagMask
|
||||||
|
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
self.presentationDataPromise.set(.single(ChatListPresentationData(theme: self.presentationData.theme, fontSize: self.presentationData.listsFontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameSortOrder: self.presentationData.nameSortOrder, nameDisplayOrder: self.presentationData.nameDisplayOrder, disableAnimations: self.presentationData.disableAnimations)))
|
self.presentationDataPromise.set(.single(ChatListPresentationData(theme: self.presentationData.theme, fontSize: self.presentationData.listsFontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameSortOrder: self.presentationData.nameSortOrder, nameDisplayOrder: self.presentationData.nameDisplayOrder, disableAnimations: self.presentationData.disableAnimations)))
|
||||||
|
|
||||||
self.searchStatePromise.set(self.searchStateValue)
|
self.searchStatePromise.set(self.searchStateValue)
|
||||||
@ -744,6 +745,9 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
|
|
||||||
self.recentListNode = ListView()
|
self.recentListNode = ListView()
|
||||||
self.recentListNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
self.recentListNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
||||||
|
self.recentListNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.shimmerNode = ChatListSearchShimmerNode(key: key)
|
self.shimmerNode = ChatListSearchShimmerNode(key: key)
|
||||||
self.shimmerNode.isUserInteractionEnabled = false
|
self.shimmerNode.isUserInteractionEnabled = false
|
||||||
@ -751,6 +755,9 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
self.listNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
var openMediaMessageImpl: ((Message, ChatControllerInteractionOpenMessageMode) -> Void)?
|
var openMediaMessageImpl: ((Message, ChatControllerInteractionOpenMessageMode) -> Void)?
|
||||||
var transitionNodeImpl: ((MessageId, Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?)?
|
var transitionNodeImpl: ((MessageId, Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?)?
|
||||||
|
|||||||
@ -805,10 +805,14 @@ public final class ContactListNode: ASDisplayNode {
|
|||||||
self.displayPermissionPlaceholder = displayPermissionPlaceholder
|
self.displayPermissionPlaceholder = displayPermissionPlaceholder
|
||||||
self.contextAction = contextAction
|
self.contextAction = contextAction
|
||||||
|
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.dynamicBounceEnabled = !self.presentationData.disableAnimations
|
self.listNode.dynamicBounceEnabled = !self.presentationData.disableAnimations
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.indexNode = CollectionIndexNode()
|
self.indexNode = CollectionIndexNode()
|
||||||
|
|
||||||
|
|||||||
@ -228,7 +228,8 @@ public final class ContactsSearchContainerNode: SearchDisplayControllerContentNo
|
|||||||
self.openPeer = openPeer
|
self.openPeer = openPeer
|
||||||
self.contextAction = contextAction
|
self.contextAction = contextAction
|
||||||
|
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
|
|
||||||
self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings))
|
self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings))
|
||||||
|
|
||||||
@ -237,6 +238,9 @@ public final class ContactsSearchContainerNode: SearchDisplayControllerContentNo
|
|||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
||||||
self.listNode.isHidden = true
|
self.listNode.isHidden = true
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -287,11 +287,15 @@ final class InviteContactsControllerNode: ASDisplayNode {
|
|||||||
init(context: AccountContext) {
|
init(context: AccountContext) {
|
||||||
self.context = context
|
self.context = context
|
||||||
|
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
|
|
||||||
self.presentationDataPromise = Promise(self.presentationData)
|
self.presentationDataPromise = Promise(self.presentationData)
|
||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
var shareImpl: (() -> Void)?
|
var shareImpl: (() -> Void)?
|
||||||
self.countPanelNode = InviteContactsCountPanelNode(theme: self.presentationData.theme, strings: self.presentationData.strings, action: {
|
self.countPanelNode = InviteContactsCountPanelNode(theme: self.presentationData.theme, strings: self.presentationData.strings, action: {
|
||||||
|
|||||||
@ -4249,6 +4249,8 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var accessibilityPageScrolledString: ((String, String) -> String)?
|
||||||
|
|
||||||
public func scrollWithDirection(_ direction: ListViewScrollDirection, distance: CGFloat) -> Bool {
|
public func scrollWithDirection(_ direction: ListViewScrollDirection, distance: CGFloat) -> Bool {
|
||||||
var accessibilityFocusedNode: (ASDisplayNode, CGRect)?
|
var accessibilityFocusedNode: (ASDisplayNode, CGRect)?
|
||||||
for itemNode in self.itemNodes {
|
for itemNode in self.itemNodes {
|
||||||
@ -4289,7 +4291,12 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
|||||||
if frame.intersects(itemNode.frame) {
|
if frame.intersects(itemNode.frame) {
|
||||||
UIAccessibility.post(notification: UIAccessibility.Notification.layoutChanged, argument: itemNode.view)
|
UIAccessibility.post(notification: UIAccessibility.Notification.layoutChanged, argument: itemNode.view)
|
||||||
if let index = itemNode.index {
|
if let index = itemNode.index {
|
||||||
let scrollStatus = "Row \(index + 1) of \(self.items.count)"
|
let scrollStatus: String
|
||||||
|
if let accessibilityPageScrolledString = self.accessibilityPageScrolledString {
|
||||||
|
scrollStatus = accessibilityPageScrolledString("\(index + 1)", "\(self.items.count)")
|
||||||
|
} else {
|
||||||
|
scrollStatus = "Row \(index + 1) of \(self.items.count)"
|
||||||
|
}
|
||||||
UIAccessibility.post(notification: UIAccessibility.Notification.pageScrolled, argument: scrollStatus)
|
UIAccessibility.post(notification: UIAccessibility.Notification.pageScrolled, argument: scrollStatus)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|||||||
@ -30,6 +30,9 @@ final class HashtagSearchControllerNode: ASDisplayNode {
|
|||||||
self.context = context
|
self.context = context
|
||||||
self.query = query
|
self.query = query
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.toolbarBackgroundNode = ASDisplayNode()
|
self.toolbarBackgroundNode = ASDisplayNode()
|
||||||
self.toolbarBackgroundNode.backgroundColor = theme.rootController.navigationBar.backgroundColor
|
self.toolbarBackgroundNode.backgroundColor = theme.rootController.navigationBar.backgroundColor
|
||||||
|
|||||||
@ -279,7 +279,9 @@ public final class InviteLinkInviteController: ViewController {
|
|||||||
init(context: AccountContext, peerId: PeerId, controller: InviteLinkInviteController) {
|
init(context: AccountContext, peerId: PeerId, controller: InviteLinkInviteController) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.peerId = peerId
|
self.peerId = peerId
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
self.presentationDataPromise = Promise(self.presentationData)
|
self.presentationDataPromise = Promise(self.presentationData)
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
|
|
||||||
@ -317,6 +319,9 @@ public final class InviteLinkInviteController: ViewController {
|
|||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
|
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
|
||||||
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
|
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -416,6 +416,9 @@ public final class InviteLinkViewController: ViewController {
|
|||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
|
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
|
||||||
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
|
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -71,12 +71,23 @@ public enum ItemListStyle {
|
|||||||
case blocks
|
case blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct ItemListToolbarItem {
|
||||||
|
public struct Action {
|
||||||
|
public let title: String
|
||||||
|
public let isEnabled: Bool
|
||||||
|
public let action: () -> Void
|
||||||
|
}
|
||||||
|
|
||||||
|
let actions: [Action]
|
||||||
|
}
|
||||||
|
|
||||||
private struct ItemListNodeTransition {
|
private struct ItemListNodeTransition {
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let entries: ItemListNodeEntryTransition
|
let entries: ItemListNodeEntryTransition
|
||||||
let updateStyle: ItemListStyle?
|
let updateStyle: ItemListStyle?
|
||||||
let emptyStateItem: ItemListControllerEmptyStateItem?
|
let emptyStateItem: ItemListControllerEmptyStateItem?
|
||||||
let searchItem: ItemListControllerSearch?
|
let searchItem: ItemListControllerSearch?
|
||||||
|
let toolbarItem: ItemListToolbarItem?
|
||||||
let focusItemTag: ItemListItemTag?
|
let focusItemTag: ItemListItemTag?
|
||||||
let ensureVisibleItemTag: ItemListItemTag?
|
let ensureVisibleItemTag: ItemListItemTag?
|
||||||
let scrollToItem: ListViewScrollToItem?
|
let scrollToItem: ListViewScrollToItem?
|
||||||
@ -94,6 +105,7 @@ public final class ItemListNodeState {
|
|||||||
let style: ItemListStyle
|
let style: ItemListStyle
|
||||||
let emptyStateItem: ItemListControllerEmptyStateItem?
|
let emptyStateItem: ItemListControllerEmptyStateItem?
|
||||||
let searchItem: ItemListControllerSearch?
|
let searchItem: ItemListControllerSearch?
|
||||||
|
let toolbarItem: ItemListToolbarItem?
|
||||||
let animateChanges: Bool
|
let animateChanges: Bool
|
||||||
let crossfadeState: Bool
|
let crossfadeState: Bool
|
||||||
let scrollEnabled: Bool
|
let scrollEnabled: Bool
|
||||||
@ -101,12 +113,13 @@ public final class ItemListNodeState {
|
|||||||
let ensureVisibleItemTag: ItemListItemTag?
|
let ensureVisibleItemTag: ItemListItemTag?
|
||||||
let initialScrollToItem: ListViewScrollToItem?
|
let initialScrollToItem: ListViewScrollToItem?
|
||||||
|
|
||||||
public init<T: ItemListNodeEntry>(presentationData: ItemListPresentationData, entries: [T], style: ItemListStyle, focusItemTag: ItemListItemTag? = nil, ensureVisibleItemTag: ItemListItemTag? = nil, emptyStateItem: ItemListControllerEmptyStateItem? = nil, searchItem: ItemListControllerSearch? = nil, initialScrollToItem: ListViewScrollToItem? = nil, crossfadeState: Bool = false, animateChanges: Bool = true, scrollEnabled: Bool = true) {
|
public init<T: ItemListNodeEntry>(presentationData: ItemListPresentationData, entries: [T], style: ItemListStyle, focusItemTag: ItemListItemTag? = nil, ensureVisibleItemTag: ItemListItemTag? = nil, emptyStateItem: ItemListControllerEmptyStateItem? = nil, searchItem: ItemListControllerSearch? = nil, toolbarItem: ItemListToolbarItem? = nil, initialScrollToItem: ListViewScrollToItem? = nil, crossfadeState: Bool = false, animateChanges: Bool = true, scrollEnabled: Bool = true) {
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
self.entries = entries.map { $0 }
|
self.entries = entries.map { $0 }
|
||||||
self.style = style
|
self.style = style
|
||||||
self.emptyStateItem = emptyStateItem
|
self.emptyStateItem = emptyStateItem
|
||||||
self.searchItem = searchItem
|
self.searchItem = searchItem
|
||||||
|
self.toolbarItem = toolbarItem
|
||||||
self.crossfadeState = crossfadeState
|
self.crossfadeState = crossfadeState
|
||||||
self.animateChanges = animateChanges
|
self.animateChanges = animateChanges
|
||||||
self.focusItemTag = focusItemTag
|
self.focusItemTag = focusItemTag
|
||||||
@ -189,6 +202,8 @@ open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
private var emptyStateItem: ItemListControllerEmptyStateItem?
|
private var emptyStateItem: ItemListControllerEmptyStateItem?
|
||||||
private var emptyStateNode: ItemListControllerEmptyStateItemNode?
|
private var emptyStateNode: ItemListControllerEmptyStateItemNode?
|
||||||
|
|
||||||
|
private var toolbarNode: ToolbarNode?
|
||||||
|
|
||||||
private var searchItem: ItemListControllerSearch?
|
private var searchItem: ItemListControllerSearch?
|
||||||
private var searchNode: ItemListControllerSearchNode?
|
private var searchNode: ItemListControllerSearchNode?
|
||||||
|
|
||||||
@ -333,7 +348,7 @@ open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
scrollToItem = state.initialScrollToItem
|
scrollToItem = state.initialScrollToItem
|
||||||
}
|
}
|
||||||
|
|
||||||
return ItemListNodeTransition(theme: presentationData.theme, entries: transition, updateStyle: updatedStyle, emptyStateItem: state.emptyStateItem, searchItem: state.searchItem, focusItemTag: state.focusItemTag, ensureVisibleItemTag: state.ensureVisibleItemTag, scrollToItem: scrollToItem, firstTime: previous == nil, animated: previous != nil && state.animateChanges, animateAlpha: previous != nil && state.animateChanges, crossfade: state.crossfadeState, mergedEntries: state.entries, scrollEnabled: state.scrollEnabled)
|
return ItemListNodeTransition(theme: presentationData.theme, entries: transition, updateStyle: updatedStyle, emptyStateItem: state.emptyStateItem, searchItem: state.searchItem, toolbarItem: state.toolbarItem, focusItemTag: state.focusItemTag, ensureVisibleItemTag: state.ensureVisibleItemTag, scrollToItem: scrollToItem, firstTime: previous == nil, animated: previous != nil && state.animateChanges, animateAlpha: previous != nil && state.animateChanges, crossfade: state.crossfadeState, mergedEntries: state.entries, scrollEnabled: state.scrollEnabled)
|
||||||
})
|
})
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] transition in
|
|> deliverOnMainQueue).start(next: { [weak self] transition in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
|
|||||||
@ -287,6 +287,9 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM
|
|||||||
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
||||||
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
|
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
|
||||||
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
|
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.emptyResultsTextNode = ImmediateTextNode()
|
self.emptyResultsTextNode = ImmediateTextNode()
|
||||||
self.emptyResultsTextNode.maximumNumberOfLines = 0
|
self.emptyResultsTextNode.maximumNumberOfLines = 0
|
||||||
|
|||||||
@ -114,7 +114,8 @@ final class LocationSearchContainerNode: ASDisplayNode {
|
|||||||
self.context = context
|
self.context = context
|
||||||
self.interaction = interaction
|
self.interaction = interaction
|
||||||
|
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings))
|
self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings))
|
||||||
|
|
||||||
self.dimNode = ASDisplayNode()
|
self.dimNode = ASDisplayNode()
|
||||||
@ -122,6 +123,9 @@ final class LocationSearchContainerNode: ASDisplayNode {
|
|||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
||||||
self.listNode.isHidden = true
|
self.listNode.isHidden = true
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.emptyResultsTitleNode = ImmediateTextNode()
|
self.emptyResultsTitleNode = ImmediateTextNode()
|
||||||
self.emptyResultsTitleNode.attributedText = NSAttributedString(string: self.presentationData.strings.SharedMedia_SearchNoResults, font: Font.semibold(17.0), textColor: self.presentationData.theme.list.freeTextColor)
|
self.emptyResultsTitleNode.attributedText = NSAttributedString(string: self.presentationData.strings.SharedMedia_SearchNoResults, font: Font.semibold(17.0), textColor: self.presentationData.theme.list.freeTextColor)
|
||||||
|
|||||||
@ -234,6 +234,9 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
|
|||||||
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
||||||
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
|
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
|
||||||
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
|
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
var setupProximityNotificationImpl: ((Bool) -> Void)?
|
var setupProximityNotificationImpl: ((Bool) -> Void)?
|
||||||
self.headerNode = LocationMapHeaderNode(presentationData: presentationData, toggleMapModeSelection: interaction.toggleMapModeSelection, goToUserLocation: interaction.toggleTrackingMode, setupProximityNotification: { reset in
|
self.headerNode = LocationMapHeaderNode(presentationData: presentationData, toggleMapModeSelection: interaction.toggleMapModeSelection, goToUserLocation: interaction.toggleTrackingMode, setupProximityNotification: { reset in
|
||||||
|
|||||||
@ -182,6 +182,9 @@ private final class MessageReactionListControllerNode: ViewControllerTracingNode
|
|||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.limitHitTestToNodes = true
|
self.listNode.limitHitTestToNodes = true
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.placeholderNode = MessageReactionListLoadingPlaceholder(theme: presentationData.theme, itemHeight: itemHeight)
|
self.placeholderNode = MessageReactionListLoadingPlaceholder(theme: presentationData.theme, itemHeight: itemHeight)
|
||||||
self.placeholderNode?.isUserInteractionEnabled = false
|
self.placeholderNode?.isUserInteractionEnabled = false
|
||||||
|
|||||||
@ -125,11 +125,15 @@ final class ChannelDiscussionGroupSearchContainerNode: SearchDisplayControllerCo
|
|||||||
self.context = context
|
self.context = context
|
||||||
self.openPeer = openPeer
|
self.openPeer = openPeer
|
||||||
|
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
self.presentationDataPromise = Promise(self.presentationData)
|
self.presentationDataPromise = Promise(self.presentationData)
|
||||||
|
|
||||||
self.dimNode = ASDisplayNode()
|
self.dimNode = ASDisplayNode()
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -321,7 +321,9 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
|||||||
self.openPeer = openPeer
|
self.openPeer = openPeer
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
|
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
|
|
||||||
self.forceTheme = forceTheme
|
self.forceTheme = forceTheme
|
||||||
if let forceTheme = self.forceTheme {
|
if let forceTheme = self.forceTheme {
|
||||||
self.presentationData = self.presentationData.withUpdated(theme: forceTheme)
|
self.presentationData = self.presentationData.withUpdated(theme: forceTheme)
|
||||||
@ -329,7 +331,14 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
|||||||
self.presentationDataPromise = Promise(self.presentationData)
|
self.presentationDataPromise = Promise(self.presentationData)
|
||||||
|
|
||||||
self.emptyQueryListNode = ListView()
|
self.emptyQueryListNode = ListView()
|
||||||
|
self.emptyQueryListNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -212,6 +212,10 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
|
|||||||
self.presentationData = self.presentationData.withUpdated(theme: forceTheme)
|
self.presentationData = self.presentationData.withUpdated(theme: forceTheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.setViewBlock({
|
self.setViewBlock({
|
||||||
|
|||||||
@ -182,12 +182,16 @@ private final class OldChannelsSearchContainerNode: SearchDisplayControllerConte
|
|||||||
private let presentationDataPromise: Promise<PresentationData>
|
private let presentationDataPromise: Promise<PresentationData>
|
||||||
|
|
||||||
init(context: AccountContext, peers: Signal<[InactiveChannel], NoError>, selectedPeerIds: Signal<Set<PeerId>, NoError>, togglePeer: @escaping (PeerId) -> Void) {
|
init(context: AccountContext, peers: Signal<[InactiveChannel], NoError>, selectedPeerIds: Signal<Set<PeerId>, NoError>, togglePeer: @escaping (PeerId) -> Void) {
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
self.presentationDataPromise = Promise(self.presentationData)
|
self.presentationDataPromise = Promise(self.presentationData)
|
||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
|
self.listNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
|
||||||
self.listNode.isHidden = true
|
self.listNode.isHidden = true
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -99,7 +99,8 @@ private final class LocalizationListSearchContainerNode: SearchDisplayController
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(context: AccountContext, listState: LocalizationListState, selectLocalization: @escaping (LocalizationInfo) -> Void, applyingCode: Signal<String?, NoError>) {
|
init(context: AccountContext, listState: LocalizationListState, selectLocalization: @escaping (LocalizationInfo) -> Void, applyingCode: Signal<String?, NoError>) {
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
|
|
||||||
self.presentationDataPromise = Promise(self.presentationData)
|
self.presentationDataPromise = Promise(self.presentationData)
|
||||||
|
|
||||||
@ -107,6 +108,9 @@ private final class LocalizationListSearchContainerNode: SearchDisplayController
|
|||||||
self.dimNode.backgroundColor = UIColor.black.withAlphaComponent(0.5)
|
self.dimNode.backgroundColor = UIColor.black.withAlphaComponent(0.5)
|
||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
@ -308,6 +312,9 @@ final class LocalizationListControllerNode: ViewControllerTracingNode {
|
|||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.keepTopItemOverscrollBackground = ListViewKeepTopItemOverscrollBackground(color: presentationData.theme.chatList.backgroundColor, direction: true)
|
self.listNode.keepTopItemOverscrollBackground = ListViewKeepTopItemOverscrollBackground(color: presentationData.theme.chatList.backgroundColor, direction: true)
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -716,7 +716,10 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
|||||||
self.stateValue = Atomic(value: NotificationExceptionState(mode: mode))
|
self.stateValue = Atomic(value: NotificationExceptionState(mode: mode))
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.keepTopItemOverscrollBackground = ListViewKeepTopItemOverscrollBackground(color: presentationData.theme.chatList.backgroundColor, direction: true)
|
self.listNode.keepTopItemOverscrollBackground = ListViewKeepTopItemOverscrollBackground(color: presentationData.theme.chatList.backgroundColor, direction: true)
|
||||||
//self.listNode.keepBottomItemOverscrollBackground = presentationData.theme.chatList.backgroundColor
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
let stateValue = self.stateValue
|
let stateValue = self.stateValue
|
||||||
@ -1164,7 +1167,8 @@ private final class NotificationExceptionsSearchContainerNode: SearchDisplayCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(context: AccountContext, mode: NotificationExceptionMode, arguments: NotificationExceptionArguments) {
|
init(context: AccountContext, mode: NotificationExceptionMode, arguments: NotificationExceptionArguments) {
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
|
|
||||||
self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings))
|
self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings))
|
||||||
|
|
||||||
@ -1172,6 +1176,9 @@ private final class NotificationExceptionsSearchContainerNode: SearchDisplayCont
|
|||||||
self.dimNode.backgroundColor = UIColor.black.withAlphaComponent(0.5)
|
self.dimNode.backgroundColor = UIColor.black.withAlphaComponent(0.5)
|
||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -363,16 +363,23 @@ public final class SettingsSearchContainerNode: SearchDisplayControllerContentNo
|
|||||||
private let presentationDataPromise: Promise<PresentationData>
|
private let presentationDataPromise: Promise<PresentationData>
|
||||||
|
|
||||||
public init(context: AccountContext, openResult: @escaping (SettingsSearchableItem) -> Void, resolvedFaqUrl: Signal<ResolvedUrl?, NoError>, exceptionsList: Signal<NotificationExceptionsList?, NoError>, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, privacySettings: Signal<AccountPrivacySettings?, NoError>, hasTwoStepAuth: Signal<Bool?, NoError>, activeSessionsContext: Signal<ActiveSessionsContext?, NoError>, webSessionsContext: Signal<WebSessionsContext?, NoError>) {
|
public init(context: AccountContext, openResult: @escaping (SettingsSearchableItem) -> Void, resolvedFaqUrl: Signal<ResolvedUrl?, NoError>, exceptionsList: Signal<NotificationExceptionsList?, NoError>, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, privacySettings: Signal<AccountPrivacySettings?, NoError>, hasTwoStepAuth: Signal<Bool?, NoError>, activeSessionsContext: Signal<ActiveSessionsContext?, NoError>, webSessionsContext: Signal<WebSessionsContext?, NoError>) {
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
self.presentationDataPromise = Promise(self.presentationData)
|
self.presentationDataPromise = Promise(self.presentationData)
|
||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
|
self.listNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
|
||||||
self.listNode.isHidden = true
|
self.listNode.isHidden = true
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.recentListNode = ListView()
|
self.recentListNode = ListView()
|
||||||
self.recentListNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
|
self.recentListNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
|
||||||
self.recentListNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
self.recentListNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
||||||
|
self.recentListNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -376,12 +376,17 @@ final class ThemeGridSearchContentNode: SearchDisplayControllerContentNode {
|
|||||||
self.context = context
|
self.context = context
|
||||||
self.queryPromise = Promise<WallpaperSearchQuery>(self.queryValue)
|
self.queryPromise = Promise<WallpaperSearchQuery>(self.queryValue)
|
||||||
|
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
self.presentationDataPromise = Promise(self.presentationData)
|
self.presentationDataPromise = Promise(self.presentationData)
|
||||||
|
|
||||||
self.dimNode = ASDisplayNode()
|
self.dimNode = ASDisplayNode()
|
||||||
self.recentListNode = ListView()
|
self.recentListNode = ListView()
|
||||||
self.recentListNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
self.recentListNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
||||||
|
self.recentListNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.gridNode = GridNode()
|
self.gridNode = GridNode()
|
||||||
|
|
||||||
self.emptyResultsTitleNode = ImmediateTextNode()
|
self.emptyResultsTitleNode = ImmediateTextNode()
|
||||||
|
|||||||
@ -365,31 +365,34 @@ public func preparedShareItems(account: Account, to peerId: PeerId, dataItems: [
|
|||||||
public func sentShareItems(account: Account, to peerIds: [PeerId], items: [PreparedShareItemContent]) -> Signal<Float, Void> {
|
public func sentShareItems(account: Account, to peerIds: [PeerId], items: [PreparedShareItemContent]) -> Signal<Float, Void> {
|
||||||
var messages: [EnqueueMessage] = []
|
var messages: [EnqueueMessage] = []
|
||||||
var groupingKey: Int64?
|
var groupingKey: Int64?
|
||||||
var mediaTypes: (photo: Bool, video: Bool, music: Bool, other: Bool) = (false, false, false, false)
|
var mediaTypes: (photo: Int, video: Int, music: Int, other: Int) = (0, 0, 0, 0)
|
||||||
if items.count > 1 {
|
if items.count > 1 {
|
||||||
for item in items {
|
for item in items {
|
||||||
if case let .media(result) = item, case let .media(media) = result {
|
if case let .media(result) = item, case let .media(media) = result {
|
||||||
if media.media is TelegramMediaImage {
|
if media.media is TelegramMediaImage {
|
||||||
mediaTypes.photo = true
|
mediaTypes.photo += 1
|
||||||
} else if let media = media.media as? TelegramMediaFile {
|
} else if let media = media.media as? TelegramMediaFile {
|
||||||
if media.isVideo {
|
if media.isVideo {
|
||||||
mediaTypes.video = true
|
mediaTypes.video += 1
|
||||||
} else if let fileName = media.fileName, fileName.hasPrefix("mp3") || fileName.hasPrefix("m4a") {
|
} else if media.isVoice || media.isAnimated || media.isSticker {
|
||||||
mediaTypes.music = true
|
mediaTypes = (0, 0, 0, 0)
|
||||||
|
break
|
||||||
|
} else if let fileName = media.fileName?.lowercased(), fileName.hasPrefix(".mp3") || fileName.hasPrefix("m4a") {
|
||||||
|
mediaTypes.music += 1
|
||||||
} else {
|
} else {
|
||||||
mediaTypes.other = true
|
mediaTypes.other += 1
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mediaTypes = (false, false, false, false)
|
mediaTypes = (0, 0, 0, 0)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mediaTypes.photo || mediaTypes.video) && !(mediaTypes.music || mediaTypes.other) {
|
if ((mediaTypes.photo + mediaTypes.video) > 1) && (mediaTypes.music == 0 && mediaTypes.other == 0) {
|
||||||
groupingKey = arc4random64()
|
groupingKey = arc4random64()
|
||||||
} else if !(mediaTypes.photo || mediaTypes.video) && (mediaTypes.music != mediaTypes.other) {
|
} else if ((mediaTypes.photo + mediaTypes.video) == 0) && ((mediaTypes.music > 1 && mediaTypes.other == 0) || (mediaTypes.music == 0 && mediaTypes.other > 1)) {
|
||||||
groupingKey = arc4random64()
|
groupingKey = arc4random64()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,7 @@ swift_library(
|
|||||||
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
|
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
|
||||||
"//submodules/ItemListPeerItem:ItemListPeerItem",
|
"//submodules/ItemListPeerItem:ItemListPeerItem",
|
||||||
"//submodules/ItemListPeerActionItem:ItemListPeerActionItem",
|
"//submodules/ItemListPeerActionItem:ItemListPeerActionItem",
|
||||||
|
"//submodules/ContextUI:ContextUI",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
import Display
|
import Display
|
||||||
|
import AsyncDisplayKit
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
import Postbox
|
import Postbox
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
@ -14,16 +15,19 @@ import AccountContext
|
|||||||
import PresentationDataUtils
|
import PresentationDataUtils
|
||||||
import AppBundle
|
import AppBundle
|
||||||
import GraphUI
|
import GraphUI
|
||||||
|
import ContextUI
|
||||||
|
|
||||||
private final class ChannelStatsControllerArguments {
|
private final class ChannelStatsControllerArguments {
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
let loadDetailedGraph: (StatsGraph, Int64) -> Signal<StatsGraph?, NoError>
|
let loadDetailedGraph: (StatsGraph, Int64) -> Signal<StatsGraph?, NoError>
|
||||||
let openMessageStats: (MessageId) -> Void
|
let openMessageStats: (MessageId) -> Void
|
||||||
|
let contextAction: (MessageId, ASDisplayNode, ContextGesture?) -> Void
|
||||||
|
|
||||||
init(context: AccountContext, loadDetailedGraph: @escaping (StatsGraph, Int64) -> Signal<StatsGraph?, NoError>, openMessage: @escaping (MessageId) -> Void) {
|
init(context: AccountContext, loadDetailedGraph: @escaping (StatsGraph, Int64) -> Signal<StatsGraph?, NoError>, openMessage: @escaping (MessageId) -> Void, contextAction: @escaping (MessageId, ASDisplayNode, ContextGesture?) -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.loadDetailedGraph = loadDetailedGraph
|
self.loadDetailedGraph = loadDetailedGraph
|
||||||
self.openMessageStats = openMessage
|
self.openMessageStats = openMessage
|
||||||
|
self.contextAction = contextAction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,6 +334,8 @@ private enum StatsEntry: ItemListNodeEntry {
|
|||||||
case let .post(_, _, _, _, message, interactions):
|
case let .post(_, _, _, _, message, interactions):
|
||||||
return StatsMessageItem(context: arguments.context, presentationData: presentationData, message: message, views: interactions.views, forwards: interactions.forwards, sectionId: self.section, style: .blocks, action: {
|
return StatsMessageItem(context: arguments.context, presentationData: presentationData, message: message, views: interactions.views, forwards: interactions.forwards, sectionId: self.section, style: .blocks, action: {
|
||||||
arguments.openMessageStats(message.id)
|
arguments.openMessageStats(message.id)
|
||||||
|
}, contextAction: { node, gesture in
|
||||||
|
arguments.contextAction(message.id, node, gesture)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,6 +413,7 @@ private func channelStatsControllerEntries(data: ChannelStats?, messages: [Messa
|
|||||||
|
|
||||||
public func channelStatsController(context: AccountContext, peerId: PeerId, cachedPeerData: CachedPeerData) -> ViewController {
|
public func channelStatsController(context: AccountContext, peerId: PeerId, cachedPeerData: CachedPeerData) -> ViewController {
|
||||||
var openMessageStatsImpl: ((MessageId) -> Void)?
|
var openMessageStatsImpl: ((MessageId) -> Void)?
|
||||||
|
var contextActionImpl: ((MessageId, ASDisplayNode, ContextGesture?) -> Void)?
|
||||||
|
|
||||||
let actionsDisposable = DisposableSet()
|
let actionsDisposable = DisposableSet()
|
||||||
let dataPromise = Promise<ChannelStats?>(nil)
|
let dataPromise = Promise<ChannelStats?>(nil)
|
||||||
@ -440,6 +447,8 @@ public func channelStatsController(context: AccountContext, peerId: PeerId, cach
|
|||||||
return statsContext.loadDetailedGraph(graph, x: x)
|
return statsContext.loadDetailedGraph(graph, x: x)
|
||||||
}, openMessage: { messageId in
|
}, openMessage: { messageId in
|
||||||
openMessageStatsImpl?(messageId)
|
openMessageStatsImpl?(messageId)
|
||||||
|
}, contextAction: { messageId, node, gesture in
|
||||||
|
contextActionImpl?(messageId, node, gesture)
|
||||||
})
|
})
|
||||||
|
|
||||||
let messageView = context.account.viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId), index: .upperBound, anchorIndex: .upperBound, count: 100, fixedCombinedReadStates: nil)
|
let messageView = context.account.viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId), index: .upperBound, anchorIndex: .upperBound, count: 100, fixedCombinedReadStates: nil)
|
||||||
@ -496,9 +505,49 @@ public func channelStatsController(context: AccountContext, peerId: PeerId, cach
|
|||||||
controller?.clearItemNodesHighlight(animated: true)
|
controller?.clearItemNodesHighlight(animated: true)
|
||||||
}
|
}
|
||||||
openMessageStatsImpl = { [weak controller] messageId in
|
openMessageStatsImpl = { [weak controller] messageId in
|
||||||
if let navigationController = controller?.navigationController as? NavigationController {
|
|
||||||
controller?.push(messageStatsController(context: context, messageId: messageId, cachedPeerData: cachedPeerData))
|
controller?.push(messageStatsController(context: context, messageId: messageId, cachedPeerData: cachedPeerData))
|
||||||
}
|
}
|
||||||
|
contextActionImpl = { [weak controller] messageId, sourceNode, gesture in
|
||||||
|
guard let controller = controller, let sourceNode = sourceNode as? ContextExtractedContentContainingNode else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
|
var items: [ContextMenuItem] = []
|
||||||
|
items.append(.action(ContextMenuActionItem(text: presentationData.strings.SharedMedia_ViewInChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/GoToMessage"), color: theme.contextMenu.primaryColor) }, action: { [weak controller] c, _ in
|
||||||
|
c.dismiss(completion: {
|
||||||
|
if let navigationController = controller?.navigationController as? NavigationController {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), subject: .message(id: messageId, highlight: true)))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})))
|
||||||
|
|
||||||
|
let contextController = ContextController(account: context.account, presentationData: presentationData, source: .extracted(ChannelStatsContextExtractedContentSource(controller: controller, sourceNode: sourceNode, keepInPlace: false)), items: .single(items), reactionItems: [], gesture: gesture)
|
||||||
|
controller.presentInGlobalOverlay(contextController)
|
||||||
}
|
}
|
||||||
return controller
|
return controller
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class ChannelStatsContextExtractedContentSource: ContextExtractedContentSource {
|
||||||
|
var keepInPlace: Bool
|
||||||
|
let ignoreContentTouches: Bool = true
|
||||||
|
let blurBackground: Bool = true
|
||||||
|
|
||||||
|
private let controller: ViewController
|
||||||
|
private let sourceNode: ContextExtractedContentContainingNode
|
||||||
|
|
||||||
|
init(controller: ViewController, sourceNode: ContextExtractedContentContainingNode, keepInPlace: Bool) {
|
||||||
|
self.controller = controller
|
||||||
|
self.sourceNode = sourceNode
|
||||||
|
self.keepInPlace = keepInPlace
|
||||||
|
}
|
||||||
|
|
||||||
|
func takeView() -> ContextControllerTakeViewInfo? {
|
||||||
|
return ContextControllerTakeViewInfo(contentContainingNode: self.sourceNode, contentAreaInScreenSpace: UIScreen.main.bounds)
|
||||||
|
}
|
||||||
|
|
||||||
|
func putBack() -> ContextControllerPutBackViewInfo? {
|
||||||
|
return ContextControllerPutBackViewInfo(contentAreaInScreenSpace: UIScreen.main.bounds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -22,8 +22,9 @@ public class StatsMessageItem: ListViewItem, ItemListItem {
|
|||||||
public let sectionId: ItemListSectionId
|
public let sectionId: ItemListSectionId
|
||||||
let style: ItemListStyle
|
let style: ItemListStyle
|
||||||
let action: (() -> Void)?
|
let action: (() -> Void)?
|
||||||
|
let contextAction: ((ASDisplayNode, ContextGesture?) -> Void)?
|
||||||
|
|
||||||
init(context: AccountContext, presentationData: ItemListPresentationData, message: Message, views: Int32, forwards: Int32, sectionId: ItemListSectionId, style: ItemListStyle, action: (() -> Void)?) {
|
init(context: AccountContext, presentationData: ItemListPresentationData, message: Message, views: Int32, forwards: Int32, sectionId: ItemListSectionId, style: ItemListStyle, action: (() -> Void)?, contextAction: ((ASDisplayNode, ContextGesture?) -> Void)?) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
self.message = message
|
self.message = message
|
||||||
@ -32,6 +33,7 @@ public class StatsMessageItem: ListViewItem, ItemListItem {
|
|||||||
self.sectionId = sectionId
|
self.sectionId = sectionId
|
||||||
self.style = style
|
self.style = style
|
||||||
self.action = action
|
self.action = action
|
||||||
|
self.contextAction = contextAction
|
||||||
}
|
}
|
||||||
|
|
||||||
public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
||||||
@ -88,6 +90,8 @@ public class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
let contextSourceNode: ContextExtractedContentContainingNode
|
let contextSourceNode: ContextExtractedContentContainingNode
|
||||||
private let containerNode: ContextControllerSourceNode
|
private let containerNode: ContextControllerSourceNode
|
||||||
private let extractedBackgroundImageNode: ASImageNode
|
private let extractedBackgroundImageNode: ASImageNode
|
||||||
|
private let offsetContainerNode: ASDisplayNode
|
||||||
|
private let countersContainerNode: ASDisplayNode
|
||||||
|
|
||||||
private var extractedRect: CGRect?
|
private var extractedRect: CGRect?
|
||||||
private var nonExtractedRect: CGRect?
|
private var nonExtractedRect: CGRect?
|
||||||
@ -134,6 +138,9 @@ public class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
self.contentImageNode = TransformImageNode()
|
self.contentImageNode = TransformImageNode()
|
||||||
self.contentImageNode.isLayerBacked = true
|
self.contentImageNode.isLayerBacked = true
|
||||||
|
|
||||||
|
self.offsetContainerNode = ASDisplayNode()
|
||||||
|
self.countersContainerNode = ASDisplayNode()
|
||||||
|
|
||||||
self.titleNode = TextNode()
|
self.titleNode = TextNode()
|
||||||
self.titleNode.isUserInteractionEnabled = false
|
self.titleNode.isUserInteractionEnabled = false
|
||||||
|
|
||||||
@ -153,13 +160,56 @@ public class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
|
|
||||||
super.init(layerBacked: false, dynamicBounce: false)
|
super.init(layerBacked: false, dynamicBounce: false)
|
||||||
|
|
||||||
self.addSubnode(self.contentImageNode)
|
self.containerNode.addSubnode(self.contextSourceNode)
|
||||||
self.addSubnode(self.titleNode)
|
self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode
|
||||||
self.addSubnode(self.labelNode)
|
self.addSubnode(self.containerNode)
|
||||||
self.addSubnode(self.viewsNode)
|
|
||||||
self.addSubnode(self.forwardsNode)
|
self.contextSourceNode.contentNode.addSubnode(self.extractedBackgroundImageNode)
|
||||||
|
self.contextSourceNode.contentNode.addSubnode(self.offsetContainerNode)
|
||||||
|
self.contextSourceNode.contentNode.addSubnode(self.countersContainerNode)
|
||||||
|
|
||||||
|
self.offsetContainerNode.addSubnode(self.contentImageNode)
|
||||||
|
self.offsetContainerNode.addSubnode(self.titleNode)
|
||||||
|
self.offsetContainerNode.addSubnode(self.labelNode)
|
||||||
|
self.countersContainerNode.addSubnode(self.viewsNode)
|
||||||
|
self.countersContainerNode.addSubnode(self.forwardsNode)
|
||||||
|
self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode
|
||||||
|
|
||||||
self.addSubnode(self.activateArea)
|
self.addSubnode(self.activateArea)
|
||||||
|
|
||||||
|
self.containerNode.activated = { [weak self] gesture, _ in
|
||||||
|
guard let strongSelf = self, let item = strongSelf.item, let contextAction = item.contextAction else {
|
||||||
|
gesture.cancel()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
contextAction(strongSelf.contextSourceNode, gesture)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.contextSourceNode.willUpdateIsExtractedToContextPreview = { [weak self] isExtracted, transition in
|
||||||
|
guard let strongSelf = self, let item = strongSelf.item else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if isExtracted {
|
||||||
|
strongSelf.extractedBackgroundImageNode.image = generateStretchableFilledCircleImage(diameter: 28.0, color: item.presentationData.theme.list.itemBlocksBackgroundColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let extractedRect = strongSelf.extractedRect, let nonExtractedRect = strongSelf.nonExtractedRect {
|
||||||
|
let rect = isExtracted ? extractedRect : nonExtractedRect
|
||||||
|
transition.updateFrame(node: strongSelf.extractedBackgroundImageNode, frame: rect)
|
||||||
|
}
|
||||||
|
|
||||||
|
transition.updateAlpha(node: strongSelf.countersContainerNode, alpha: isExtracted ? 0.0 : 1.0)
|
||||||
|
|
||||||
|
transition.updateSublayerTransformOffset(layer: strongSelf.countersContainerNode.layer, offset: CGPoint(x: isExtracted ? -24.0 : 0.0, y: 0.0))
|
||||||
|
transition.updateSublayerTransformOffset(layer: strongSelf.offsetContainerNode.layer, offset: CGPoint(x: isExtracted ? 12.0 : 0.0, y: 0.0))
|
||||||
|
|
||||||
|
transition.updateAlpha(node: strongSelf.extractedBackgroundImageNode, alpha: isExtracted ? 1.0 : 0.0, completion: { _ in
|
||||||
|
if !isExtracted {
|
||||||
|
self?.extractedBackgroundImageNode.image = nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func asyncLayout() -> (_ item: StatsMessageItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
|
public func asyncLayout() -> (_ item: StatsMessageItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
|
||||||
@ -271,6 +321,25 @@ public class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.item = item
|
strongSelf.item = item
|
||||||
|
|
||||||
|
let nonExtractedRect = CGRect(origin: CGPoint(), size: CGSize(width: layout.contentSize.width - 16.0, height: layout.contentSize.height))
|
||||||
|
let extractedRect = CGRect(origin: CGPoint(), size: layout.contentSize).insetBy(dx: 16.0 + params.leftInset, dy: 0.0)
|
||||||
|
strongSelf.extractedRect = extractedRect
|
||||||
|
strongSelf.nonExtractedRect = nonExtractedRect
|
||||||
|
|
||||||
|
if strongSelf.contextSourceNode.isExtractedToContextPreview {
|
||||||
|
strongSelf.extractedBackgroundImageNode.frame = extractedRect
|
||||||
|
} else {
|
||||||
|
strongSelf.extractedBackgroundImageNode.frame = nonExtractedRect
|
||||||
|
}
|
||||||
|
strongSelf.contextSourceNode.contentRect = extractedRect
|
||||||
|
|
||||||
|
strongSelf.containerNode.frame = CGRect(origin: CGPoint(), size: layout.contentSize)
|
||||||
|
strongSelf.contextSourceNode.frame = CGRect(origin: CGPoint(), size: layout.contentSize)
|
||||||
|
strongSelf.offsetContainerNode.frame = CGRect(origin: CGPoint(), size: layout.contentSize)
|
||||||
|
strongSelf.countersContainerNode.frame = CGRect(origin: CGPoint(), size: layout.contentSize)
|
||||||
|
strongSelf.contextSourceNode.contentNode.frame = CGRect(origin: CGPoint(), size: layout.contentSize)
|
||||||
|
strongSelf.containerNode.isGestureEnabled = item.contextAction != nil
|
||||||
|
|
||||||
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.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 = text
|
strongSelf.activateArea.accessibilityLabel = text
|
||||||
strongSelf.activateArea.accessibilityValue = label
|
strongSelf.activateArea.accessibilityValue = label
|
||||||
|
|||||||
@ -659,7 +659,9 @@ public final class VoiceChatController: ViewController {
|
|||||||
self.context = call.accountContext
|
self.context = call.accountContext
|
||||||
self.call = call
|
self.call = call
|
||||||
|
|
||||||
self.presentationData = sharedContext.currentPresentationData.with { $0 }
|
let presentationData = sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
|
|
||||||
self.darkTheme = defaultDarkColorPresentationTheme
|
self.darkTheme = defaultDarkColorPresentationTheme
|
||||||
self.currentSubtitle = self.presentationData.strings.SocksProxySetup_ProxyStatusConnecting
|
self.currentSubtitle = self.presentationData.strings.SocksProxySetup_ProxyStatusConnecting
|
||||||
|
|
||||||
@ -681,6 +683,9 @@ public final class VoiceChatController: ViewController {
|
|||||||
self.listNode.verticalScrollIndicatorColor = UIColor(white: 1.0, alpha: 0.3)
|
self.listNode.verticalScrollIndicatorColor = UIColor(white: 1.0, alpha: 0.3)
|
||||||
self.listNode.clipsToBounds = true
|
self.listNode.clipsToBounds = true
|
||||||
self.listNode.scroller.bounces = false
|
self.listNode.scroller.bounces = false
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.topPanelNode = ASDisplayNode()
|
self.topPanelNode = ASDisplayNode()
|
||||||
self.topPanelNode.clipsToBounds = false
|
self.topPanelNode.clipsToBounds = false
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -150,13 +150,17 @@ final class ChatHistorySearchContainerNode: SearchDisplayControllerContentNode {
|
|||||||
init(context: AccountContext, peerId: PeerId, tagMask: MessageTags, interfaceInteraction: ChatControllerInteraction) {
|
init(context: AccountContext, peerId: PeerId, tagMask: MessageTags, interfaceInteraction: ChatControllerInteraction) {
|
||||||
self.context = context
|
self.context = context
|
||||||
|
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
|
|
||||||
self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings, self.presentationData.dateTimeFormat, self.presentationData.listsFontSize))
|
self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings, self.presentationData.dateTimeFormat, self.presentationData.listsFontSize))
|
||||||
|
|
||||||
self.dimNode = ASDisplayNode()
|
self.dimNode = ASDisplayNode()
|
||||||
self.dimNode.backgroundColor = UIColor.black.withAlphaComponent(0.5)
|
self.dimNode.backgroundColor = UIColor.black.withAlphaComponent(0.5)
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.emptyResultsTitleNode = ImmediateTextNode()
|
self.emptyResultsTitleNode = ImmediateTextNode()
|
||||||
self.emptyResultsTitleNode.attributedText = NSAttributedString(string: self.presentationData.strings.SharedMedia_SearchNoResults, font: Font.semibold(17.0), textColor: self.presentationData.theme.list.freeTextColor)
|
self.emptyResultsTitleNode.attributedText = NSAttributedString(string: self.presentationData.strings.SharedMedia_SearchNoResults, font: Font.semibold(17.0), textColor: self.presentationData.theme.list.freeTextColor)
|
||||||
|
|||||||
@ -493,10 +493,16 @@ final class ChatMediaInputNode: ChatInputNode {
|
|||||||
self.listView = ListView()
|
self.listView = ListView()
|
||||||
self.listView.transform = CATransform3DMakeRotation(-CGFloat(Double.pi / 2.0), 0.0, 0.0, 1.0)
|
self.listView.transform = CATransform3DMakeRotation(-CGFloat(Double.pi / 2.0), 0.0, 0.0, 1.0)
|
||||||
self.listView.scroller.panGestureRecognizer.cancelsTouchesInView = false
|
self.listView.scroller.panGestureRecognizer.cancelsTouchesInView = false
|
||||||
|
self.listView.accessibilityPageScrolledString = { row, count in
|
||||||
|
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.gifListView = ListView()
|
self.gifListView = ListView()
|
||||||
self.gifListView.transform = CATransform3DMakeRotation(-CGFloat(Double.pi / 2.0), 0.0, 0.0, 1.0)
|
self.gifListView.transform = CATransform3DMakeRotation(-CGFloat(Double.pi / 2.0), 0.0, 0.0, 1.0)
|
||||||
self.gifListView.scroller.panGestureRecognizer.cancelsTouchesInView = false
|
self.gifListView.scroller.panGestureRecognizer.cancelsTouchesInView = false
|
||||||
|
self.gifListView.accessibilityPageScrolledString = { row, count in
|
||||||
|
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
var paneDidScrollImpl: ((ChatMediaInputPane, ChatMediaInputPaneScrollState, ContainedViewLayoutTransition) -> Void)?
|
var paneDidScrollImpl: ((ChatMediaInputPane, ChatMediaInputPaneScrollState, ContainedViewLayoutTransition) -> Void)?
|
||||||
var fixPaneScrollImpl: ((ChatMediaInputPane, ChatMediaInputPaneScrollState) -> Void)?
|
var fixPaneScrollImpl: ((ChatMediaInputPane, ChatMediaInputPaneScrollState) -> Void)?
|
||||||
|
|||||||
@ -110,6 +110,10 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
|||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.dynamicBounceEnabled = !self.presentationData.disableAnimations
|
self.listNode.dynamicBounceEnabled = !self.presentationData.disableAnimations
|
||||||
self.listNode.transform = CATransform3DMakeRotation(CGFloat(Double.pi), 0.0, 0.0, 1.0)
|
self.listNode.transform = CATransform3DMakeRotation(CGFloat(Double.pi), 0.0, 0.0, 1.0)
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.loadingNode = ChatLoadingNode(theme: self.presentationData.theme, chatWallpaper: self.presentationData.chatWallpaper, bubbleCorners: self.presentationData.chatBubbleCorners)
|
self.loadingNode = ChatLoadingNode(theme: self.presentationData.theme, chatWallpaper: self.presentationData.chatWallpaper, bubbleCorners: self.presentationData.chatBubbleCorners)
|
||||||
self.emptyNode = ChatRecentActionsEmptyNode(theme: self.presentationData.theme, chatWallpaper: self.presentationData.chatWallpaper, chatBubbleCorners: self.presentationData.chatBubbleCorners)
|
self.emptyNode = ChatRecentActionsEmptyNode(theme: self.presentationData.theme, chatWallpaper: self.presentationData.chatWallpaper, chatBubbleCorners: self.presentationData.chatBubbleCorners)
|
||||||
self.emptyNode.alpha = 0.0
|
self.emptyNode.alpha = 0.0
|
||||||
|
|||||||
@ -137,11 +137,16 @@ class ChatSearchResultsControllerNode: ViewControllerTracingNode, UIScrollViewDe
|
|||||||
self.searchQuery = searchQuery
|
self.searchQuery = searchQuery
|
||||||
self.searchResult = searchResult
|
self.searchResult = searchResult
|
||||||
self.searchState = searchState
|
self.searchState = searchState
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
self.presentationDataPromise = Promise(ChatListPresentationData(theme: self.presentationData.theme, fontSize: self.presentationData.listsFontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameSortOrder: self.presentationData.nameSortOrder, nameDisplayOrder: self.presentationData.nameDisplayOrder, disableAnimations: self.presentationData.disableAnimations))
|
self.presentationDataPromise = Promise(ChatListPresentationData(theme: self.presentationData.theme, fontSize: self.presentationData.listsFontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameSortOrder: self.presentationData.nameSortOrder, nameDisplayOrder: self.presentationData.nameDisplayOrder, disableAnimations: self.presentationData.disableAnimations))
|
||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.listNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
self.listNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -70,6 +70,9 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode {
|
|||||||
self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor
|
self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor
|
||||||
self.listView.limitHitTestToNodes = true
|
self.listView.limitHitTestToNodes = true
|
||||||
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
||||||
|
self.listView.accessibilityPageScrolledString = { row, count in
|
||||||
|
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize)
|
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize)
|
||||||
|
|
||||||
|
|||||||
@ -100,7 +100,8 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
|
|||||||
|
|
||||||
init(context: AccountContext, selectSticker: ((FileMediaReference, ASDisplayNode, CGRect) -> Bool)?) {
|
init(context: AccountContext, selectSticker: ((FileMediaReference, ASDisplayNode, CGRect) -> Bool)?) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
self.presentationData = presentationData
|
||||||
self.selectSticker = selectSticker
|
self.selectSticker = selectSticker
|
||||||
|
|
||||||
self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings))
|
self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings))
|
||||||
@ -179,9 +180,15 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
|
|||||||
|
|
||||||
self.stickerListView = ListView()
|
self.stickerListView = ListView()
|
||||||
self.stickerListView.transform = CATransform3DMakeRotation(-CGFloat(Double.pi / 2.0), 0.0, 0.0, 1.0)
|
self.stickerListView.transform = CATransform3DMakeRotation(-CGFloat(Double.pi / 2.0), 0.0, 0.0, 1.0)
|
||||||
|
self.stickerListView.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.maskListView = ListView()
|
self.maskListView = ListView()
|
||||||
self.maskListView.transform = CATransform3DMakeRotation(-CGFloat(Double.pi / 2.0), 0.0, 0.0, 1.0)
|
self.maskListView.transform = CATransform3DMakeRotation(-CGFloat(Double.pi / 2.0), 0.0, 0.0, 1.0)
|
||||||
|
self.maskListView.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.topSeparatorNode = ASDisplayNode()
|
self.topSeparatorNode = ASDisplayNode()
|
||||||
self.topSeparatorNode.backgroundColor = UIColor(rgb: 0x2c2d2d)
|
self.topSeparatorNode.backgroundColor = UIColor(rgb: 0x2c2d2d)
|
||||||
|
|||||||
@ -130,6 +130,9 @@ final class EmojisChatInputContextPanelNode: ChatInputContextPanelNode {
|
|||||||
self.listView.isOpaque = false
|
self.listView.isOpaque = false
|
||||||
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
||||||
self.listView.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
|
self.listView.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
|
||||||
|
self.listView.accessibilityPageScrolledString = { row, count in
|
||||||
|
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize)
|
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize)
|
||||||
|
|
||||||
|
|||||||
@ -76,6 +76,9 @@ final class HashtagChatInputContextPanelNode: ChatInputContextPanelNode {
|
|||||||
self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor
|
self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor
|
||||||
self.listView.limitHitTestToNodes = true
|
self.listView.limitHitTestToNodes = true
|
||||||
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
||||||
|
self.listView.accessibilityPageScrolledString = { row, count in
|
||||||
|
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize)
|
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize)
|
||||||
|
|
||||||
|
|||||||
@ -101,6 +101,9 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
|
|||||||
self.listView.backgroundColor = theme.list.plainBackgroundColor
|
self.listView.backgroundColor = theme.list.plainBackgroundColor
|
||||||
self.listView.transform = CATransform3DMakeRotation(-CGFloat(CGFloat.pi / 2.0), 0.0, 0.0, 1.0)
|
self.listView.transform = CATransform3DMakeRotation(-CGFloat(CGFloat.pi / 2.0), 0.0, 0.0, 1.0)
|
||||||
self.listView.isHidden = true
|
self.listView.isHidden = true
|
||||||
|
self.listView.accessibilityPageScrolledString = { row, count in
|
||||||
|
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize)
|
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize)
|
||||||
|
|
||||||
|
|||||||
@ -77,6 +77,9 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
|
|||||||
self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor
|
self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor
|
||||||
self.listView.limitHitTestToNodes = true
|
self.listView.limitHitTestToNodes = true
|
||||||
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
||||||
|
self.listView.accessibilityPageScrolledString = { row, count in
|
||||||
|
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize)
|
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize)
|
||||||
|
|
||||||
|
|||||||
@ -88,7 +88,11 @@ final class PeerInfoGroupsInCommonPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
|||||||
self.openPeerContextAction = openPeerContextAction
|
self.openPeerContextAction = openPeerContextAction
|
||||||
self.groupsInCommonContext = groupsInCommonContext
|
self.groupsInCommonContext = groupsInCommonContext
|
||||||
|
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -129,7 +129,11 @@ final class PeerInfoMembersPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
|||||||
self.membersContext = membersContext
|
self.membersContext = membersContext
|
||||||
self.action = action
|
self.action = action
|
||||||
|
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
|
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@ -90,6 +90,9 @@ final class StickersChatInputContextPanelNode: ChatInputContextPanelNode {
|
|||||||
self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor
|
self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor
|
||||||
self.listView.limitHitTestToNodes = true
|
self.listView.limitHitTestToNodes = true
|
||||||
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
||||||
|
self.listView.accessibilityPageScrolledString = { row, count in
|
||||||
|
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
self.stickersInteraction = StickersChatInputContextPanelInteraction()
|
self.stickersInteraction = StickersChatInputContextPanelInteraction()
|
||||||
|
|
||||||
|
|||||||
@ -141,6 +141,9 @@ final class VerticalListContextResultsChatInputContextPanelNode: ChatInputContex
|
|||||||
self.listView.limitHitTestToNodes = true
|
self.listView.limitHitTestToNodes = true
|
||||||
self.listView.isHidden = true
|
self.listView.isHidden = true
|
||||||
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
||||||
|
self.listView.accessibilityPageScrolledString = { row, count in
|
||||||
|
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize)
|
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize)
|
||||||
|
|
||||||
|
|||||||
@ -218,6 +218,9 @@ class WebSearchControllerNode: ASDisplayNode {
|
|||||||
|
|
||||||
self.recentQueriesNode = ListView()
|
self.recentQueriesNode = ListView()
|
||||||
self.recentQueriesNode.backgroundColor = theme.list.plainBackgroundColor
|
self.recentQueriesNode.backgroundColor = theme.list.plainBackgroundColor
|
||||||
|
self.recentQueriesNode.accessibilityPageScrolledString = { row, count in
|
||||||
|
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||||
|
}
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user