mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit '8213fdaee36cf426edf15efe93ad146a09bbdc79'
This commit is contained in:
commit
a03b3766d6
Telegram/Telegram-iOS/en.lproj
submodules
CallListUI/Sources
ChatListSearchRecentPeersNode/Sources
ChatListUI/Sources
ContactListUI/Sources
Display/Source
HashtagSearchUI/Sources
InviteLinksUI/Sources
ItemListUI/Sources
LocationUI/Sources
MessageReactionListUI/Sources
PeerInfoUI/Sources
ChannelDiscussionGroupSearchContainerNode.swiftChannelMembersSearchContainerNode.swiftChannelMembersSearchControllerNode.swiftOldChannelsSearch.swift
SettingsUI/Sources
Language Selection
Notifications/Exceptions
Search
Themes
ShareItems/Sources
StatisticsUI
TelegramCallsUI/Sources
TelegramPresentationData/Sources
TelegramUI
Resources
Sources
ChatHistorySearchContainerNode.swiftChatMediaInputNode.swiftChatRecentActionsControllerNode.swiftChatSearchResultsContollerNode.swiftCommandChatInputContextPanelNode.swiftDrawingStickersScreen.swiftEmojisChatInputContextPanelNode.swiftHashtagChatInputContextPanelNode.swiftHorizontalListContextResultsChatInputContextPanelNode.swiftMentionChatInputContextPanelNode.swift
PeerInfo/Panes
StickersChatInputContextPanelNode.swiftVerticalListContextResultsChatInputContextPanelNode.swiftWebSearchUI/Sources
@ -6147,3 +6147,5 @@ Sorry for the inconvenience.";
|
||||
|
||||
"Channel.Setup.LinkTypePublic" = "Public";
|
||||
"Channel.Setup.LinkTypePrivate" = "Private";
|
||||
|
||||
"VoiceOver.ScrollStatus" = "Row %1$@ of %2$@";
|
||||
|
@ -220,6 +220,10 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
|
||||
self.listNode = ListView()
|
||||
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.backgroundColor = self.presentationData.theme.list.blocksBackgroundColor
|
||||
self.rightOverlayNode = ASDisplayNode()
|
||||
|
@ -140,6 +140,9 @@ public final class ChatListSearchRecentPeersNode: ASDisplayNode {
|
||||
|
||||
self.listView = ListView()
|
||||
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()
|
||||
|
||||
|
@ -735,7 +735,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
}
|
||||
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.searchStatePromise.set(self.searchStateValue)
|
||||
@ -744,6 +745,9 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
|
||||
self.recentListNode = ListView()
|
||||
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.isUserInteractionEnabled = false
|
||||
@ -751,7 +755,10 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
|
||||
self.listNode = ListView()
|
||||
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 transitionNodeImpl: ((MessageId, Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?)?
|
||||
var addToTransitionSurfaceImpl: ((UIView) -> Void)?
|
||||
|
@ -805,10 +805,14 @@ public final class ContactListNode: ASDisplayNode {
|
||||
self.displayPermissionPlaceholder = displayPermissionPlaceholder
|
||||
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.dynamicBounceEnabled = !self.presentationData.disableAnimations
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
self.indexNode = CollectionIndexNode()
|
||||
|
||||
|
@ -228,7 +228,8 @@ public final class ContactsSearchContainerNode: SearchDisplayControllerContentNo
|
||||
self.openPeer = openPeer
|
||||
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))
|
||||
|
||||
@ -237,6 +238,9 @@ public final class ContactsSearchContainerNode: SearchDisplayControllerContentNo
|
||||
self.listNode = ListView()
|
||||
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
||||
self.listNode.isHidden = true
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -287,11 +287,15 @@ final class InviteContactsControllerNode: ASDisplayNode {
|
||||
init(context: AccountContext) {
|
||||
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.listNode = ListView()
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
var shareImpl: (() -> Void)?
|
||||
self.countPanelNode = InviteContactsCountPanelNode(theme: self.presentationData.theme, strings: self.presentationData.strings, action: {
|
||||
|
@ -4249,6 +4249,8 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
return false
|
||||
}
|
||||
|
||||
public var accessibilityPageScrolledString: ((String, String) -> String)?
|
||||
|
||||
public func scrollWithDirection(_ direction: ListViewScrollDirection, distance: CGFloat) -> Bool {
|
||||
var accessibilityFocusedNode: (ASDisplayNode, CGRect)?
|
||||
for itemNode in self.itemNodes {
|
||||
@ -4289,7 +4291,12 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
if frame.intersects(itemNode.frame) {
|
||||
UIAccessibility.post(notification: UIAccessibility.Notification.layoutChanged, argument: itemNode.view)
|
||||
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)
|
||||
}
|
||||
break
|
||||
|
@ -30,6 +30,9 @@ final class HashtagSearchControllerNode: ASDisplayNode {
|
||||
self.context = context
|
||||
self.query = query
|
||||
self.listNode = ListView()
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
self.toolbarBackgroundNode = ASDisplayNode()
|
||||
self.toolbarBackgroundNode.backgroundColor = theme.rootController.navigationBar.backgroundColor
|
||||
|
@ -279,7 +279,9 @@ public final class InviteLinkInviteController: ViewController {
|
||||
init(context: AccountContext, peerId: PeerId, controller: InviteLinkInviteController) {
|
||||
self.context = context
|
||||
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.controller = controller
|
||||
|
||||
@ -317,6 +319,9 @@ public final class InviteLinkInviteController: ViewController {
|
||||
self.listNode = ListView()
|
||||
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
|
||||
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -416,6 +416,9 @@ public final class InviteLinkViewController: ViewController {
|
||||
self.listNode = ListView()
|
||||
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
|
||||
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -71,12 +71,23 @@ public enum ItemListStyle {
|
||||
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 {
|
||||
let theme: PresentationTheme
|
||||
let entries: ItemListNodeEntryTransition
|
||||
let updateStyle: ItemListStyle?
|
||||
let emptyStateItem: ItemListControllerEmptyStateItem?
|
||||
let searchItem: ItemListControllerSearch?
|
||||
let toolbarItem: ItemListToolbarItem?
|
||||
let focusItemTag: ItemListItemTag?
|
||||
let ensureVisibleItemTag: ItemListItemTag?
|
||||
let scrollToItem: ListViewScrollToItem?
|
||||
@ -94,6 +105,7 @@ public final class ItemListNodeState {
|
||||
let style: ItemListStyle
|
||||
let emptyStateItem: ItemListControllerEmptyStateItem?
|
||||
let searchItem: ItemListControllerSearch?
|
||||
let toolbarItem: ItemListToolbarItem?
|
||||
let animateChanges: Bool
|
||||
let crossfadeState: Bool
|
||||
let scrollEnabled: Bool
|
||||
@ -101,12 +113,13 @@ public final class ItemListNodeState {
|
||||
let ensureVisibleItemTag: ItemListItemTag?
|
||||
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.entries = entries.map { $0 }
|
||||
self.style = style
|
||||
self.emptyStateItem = emptyStateItem
|
||||
self.searchItem = searchItem
|
||||
self.toolbarItem = toolbarItem
|
||||
self.crossfadeState = crossfadeState
|
||||
self.animateChanges = animateChanges
|
||||
self.focusItemTag = focusItemTag
|
||||
@ -189,6 +202,8 @@ open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
private var emptyStateItem: ItemListControllerEmptyStateItem?
|
||||
private var emptyStateNode: ItemListControllerEmptyStateItemNode?
|
||||
|
||||
private var toolbarNode: ToolbarNode?
|
||||
|
||||
private var searchItem: ItemListControllerSearch?
|
||||
private var searchNode: ItemListControllerSearchNode?
|
||||
|
||||
@ -333,7 +348,7 @@ open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
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
|
||||
if let strongSelf = self {
|
||||
|
@ -287,6 +287,9 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM
|
||||
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
||||
self.listNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
|
||||
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
self.emptyResultsTextNode = ImmediateTextNode()
|
||||
self.emptyResultsTextNode.maximumNumberOfLines = 0
|
||||
|
@ -114,7 +114,8 @@ final class LocationSearchContainerNode: ASDisplayNode {
|
||||
self.context = context
|
||||
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.dimNode = ASDisplayNode()
|
||||
@ -122,6 +123,9 @@ final class LocationSearchContainerNode: ASDisplayNode {
|
||||
self.listNode = ListView()
|
||||
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
||||
self.listNode.isHidden = true
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
self.emptyResultsTitleNode = ImmediateTextNode()
|
||||
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.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3)
|
||||
self.listNode.verticalScrollIndicatorFollowsOverscroll = true
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
var setupProximityNotificationImpl: ((Bool) -> Void)?
|
||||
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.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?.isUserInteractionEnabled = false
|
||||
|
@ -125,11 +125,15 @@ final class ChannelDiscussionGroupSearchContainerNode: SearchDisplayControllerCo
|
||||
self.context = context
|
||||
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.dimNode = ASDisplayNode()
|
||||
self.listNode = ListView()
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -321,7 +321,9 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
||||
self.openPeer = openPeer
|
||||
self.mode = mode
|
||||
|
||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.presentationData = presentationData
|
||||
|
||||
self.forceTheme = forceTheme
|
||||
if let forceTheme = self.forceTheme {
|
||||
self.presentationData = self.presentationData.withUpdated(theme: forceTheme)
|
||||
@ -329,7 +331,14 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
||||
self.presentationDataPromise = Promise(self.presentationData)
|
||||
|
||||
self.emptyQueryListNode = ListView()
|
||||
self.emptyQueryListNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
self.listNode = ListView()
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -212,6 +212,10 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
|
||||
self.presentationData = self.presentationData.withUpdated(theme: forceTheme)
|
||||
}
|
||||
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
self.setViewBlock({
|
||||
|
@ -182,12 +182,16 @@ private final class OldChannelsSearchContainerNode: SearchDisplayControllerConte
|
||||
private let presentationDataPromise: Promise<PresentationData>
|
||||
|
||||
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.listNode = ListView()
|
||||
self.listNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
|
||||
self.listNode.isHidden = true
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -99,7 +99,8 @@ private final class LocalizationListSearchContainerNode: SearchDisplayController
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@ -107,6 +108,9 @@ private final class LocalizationListSearchContainerNode: SearchDisplayController
|
||||
self.dimNode.backgroundColor = UIColor.black.withAlphaComponent(0.5)
|
||||
|
||||
self.listNode = ListView()
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
@ -308,6 +312,9 @@ final class LocalizationListControllerNode: ViewControllerTracingNode {
|
||||
|
||||
self.listNode = ListView()
|
||||
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()
|
||||
|
||||
|
@ -716,7 +716,10 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
||||
self.stateValue = Atomic(value: NotificationExceptionState(mode: mode))
|
||||
self.listNode = ListView()
|
||||
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()
|
||||
|
||||
let stateValue = self.stateValue
|
||||
@ -1164,7 +1167,8 @@ private final class NotificationExceptionsSearchContainerNode: SearchDisplayCont
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
@ -1172,6 +1176,9 @@ private final class NotificationExceptionsSearchContainerNode: SearchDisplayCont
|
||||
self.dimNode.backgroundColor = UIColor.black.withAlphaComponent(0.5)
|
||||
|
||||
self.listNode = ListView()
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -363,16 +363,23 @@ public final class SettingsSearchContainerNode: SearchDisplayControllerContentNo
|
||||
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>) {
|
||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.presentationData = presentationData
|
||||
self.presentationDataPromise = Promise(self.presentationData)
|
||||
|
||||
self.listNode = ListView()
|
||||
self.listNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
|
||||
self.listNode.isHidden = true
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
self.recentListNode = ListView()
|
||||
self.recentListNode.backgroundColor = self.presentationData.theme.chatList.backgroundColor
|
||||
self.recentListNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
||||
self.recentListNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -376,12 +376,17 @@ final class ThemeGridSearchContentNode: SearchDisplayControllerContentNode {
|
||||
self.context = context
|
||||
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.dimNode = ASDisplayNode()
|
||||
self.recentListNode = ListView()
|
||||
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.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> {
|
||||
var messages: [EnqueueMessage] = []
|
||||
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 {
|
||||
for item in items {
|
||||
if case let .media(result) = item, case let .media(media) = result {
|
||||
if media.media is TelegramMediaImage {
|
||||
mediaTypes.photo = true
|
||||
mediaTypes.photo += 1
|
||||
} else if let media = media.media as? TelegramMediaFile {
|
||||
if media.isVideo {
|
||||
mediaTypes.video = true
|
||||
} else if let fileName = media.fileName, fileName.hasPrefix("mp3") || fileName.hasPrefix("m4a") {
|
||||
mediaTypes.music = true
|
||||
mediaTypes.video += 1
|
||||
} else if media.isVoice || media.isAnimated || media.isSticker {
|
||||
mediaTypes = (0, 0, 0, 0)
|
||||
break
|
||||
} else if let fileName = media.fileName?.lowercased(), fileName.hasPrefix(".mp3") || fileName.hasPrefix("m4a") {
|
||||
mediaTypes.music += 1
|
||||
} else {
|
||||
mediaTypes.other = true
|
||||
mediaTypes.other += 1
|
||||
}
|
||||
} else {
|
||||
mediaTypes = (false, false, false, false)
|
||||
mediaTypes = (0, 0, 0, 0)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mediaTypes.photo || mediaTypes.video) && !(mediaTypes.music || mediaTypes.other) {
|
||||
if ((mediaTypes.photo + mediaTypes.video) > 1) && (mediaTypes.music == 0 && mediaTypes.other == 0) {
|
||||
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()
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ swift_library(
|
||||
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
|
||||
"//submodules/ItemListPeerItem:ItemListPeerItem",
|
||||
"//submodules/ItemListPeerActionItem:ItemListPeerActionItem",
|
||||
"//submodules/ContextUI:ContextUI",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -1,6 +1,7 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
@ -14,16 +15,19 @@ import AccountContext
|
||||
import PresentationDataUtils
|
||||
import AppBundle
|
||||
import GraphUI
|
||||
import ContextUI
|
||||
|
||||
private final class ChannelStatsControllerArguments {
|
||||
let context: AccountContext
|
||||
let loadDetailedGraph: (StatsGraph, Int64) -> Signal<StatsGraph?, NoError>
|
||||
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.loadDetailedGraph = loadDetailedGraph
|
||||
self.openMessageStats = openMessage
|
||||
self.contextAction = contextAction
|
||||
}
|
||||
}
|
||||
|
||||
@ -330,6 +334,8 @@ private enum StatsEntry: ItemListNodeEntry {
|
||||
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: {
|
||||
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 {
|
||||
var openMessageStatsImpl: ((MessageId) -> Void)?
|
||||
var contextActionImpl: ((MessageId, ASDisplayNode, ContextGesture?) -> Void)?
|
||||
|
||||
let actionsDisposable = DisposableSet()
|
||||
let dataPromise = Promise<ChannelStats?>(nil)
|
||||
@ -440,6 +447,8 @@ public func channelStatsController(context: AccountContext, peerId: PeerId, cach
|
||||
return statsContext.loadDetailedGraph(graph, x: x)
|
||||
}, openMessage: { messageId in
|
||||
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)
|
||||
@ -496,9 +505,49 @@ public func channelStatsController(context: AccountContext, peerId: PeerId, cach
|
||||
controller?.clearItemNodesHighlight(animated: true)
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
let style: ItemListStyle
|
||||
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.presentationData = presentationData
|
||||
self.message = message
|
||||
@ -32,6 +33,7 @@ public class StatsMessageItem: ListViewItem, ItemListItem {
|
||||
self.sectionId = sectionId
|
||||
self.style = style
|
||||
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) {
|
||||
@ -88,6 +90,8 @@ public class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
|
||||
let contextSourceNode: ContextExtractedContentContainingNode
|
||||
private let containerNode: ContextControllerSourceNode
|
||||
private let extractedBackgroundImageNode: ASImageNode
|
||||
private let offsetContainerNode: ASDisplayNode
|
||||
private let countersContainerNode: ASDisplayNode
|
||||
|
||||
private var extractedRect: CGRect?
|
||||
private var nonExtractedRect: CGRect?
|
||||
@ -134,6 +138,9 @@ public class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
|
||||
self.contentImageNode = TransformImageNode()
|
||||
self.contentImageNode.isLayerBacked = true
|
||||
|
||||
self.offsetContainerNode = ASDisplayNode()
|
||||
self.countersContainerNode = ASDisplayNode()
|
||||
|
||||
self.titleNode = TextNode()
|
||||
self.titleNode.isUserInteractionEnabled = false
|
||||
|
||||
@ -153,13 +160,56 @@ public class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
|
||||
self.addSubnode(self.contentImageNode)
|
||||
self.addSubnode(self.titleNode)
|
||||
self.addSubnode(self.labelNode)
|
||||
self.addSubnode(self.viewsNode)
|
||||
self.addSubnode(self.forwardsNode)
|
||||
self.containerNode.addSubnode(self.contextSourceNode)
|
||||
self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode
|
||||
self.addSubnode(self.containerNode)
|
||||
|
||||
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.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) {
|
||||
@ -271,6 +321,25 @@ public class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
|
||||
if let strongSelf = self {
|
||||
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.accessibilityLabel = text
|
||||
strongSelf.activateArea.accessibilityValue = label
|
||||
|
@ -659,7 +659,9 @@ public final class VoiceChatController: ViewController {
|
||||
self.context = call.accountContext
|
||||
self.call = call
|
||||
|
||||
self.presentationData = sharedContext.currentPresentationData.with { $0 }
|
||||
let presentationData = sharedContext.currentPresentationData.with { $0 }
|
||||
self.presentationData = presentationData
|
||||
|
||||
self.darkTheme = defaultDarkColorPresentationTheme
|
||||
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.clipsToBounds = true
|
||||
self.listNode.scroller.bounces = false
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
self.topPanelNode = ASDisplayNode()
|
||||
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) {
|
||||
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.dimNode = ASDisplayNode()
|
||||
self.dimNode.backgroundColor = UIColor.black.withAlphaComponent(0.5)
|
||||
self.listNode = ListView()
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
self.emptyResultsTitleNode = ImmediateTextNode()
|
||||
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.transform = CATransform3DMakeRotation(-CGFloat(Double.pi / 2.0), 0.0, 0.0, 1.0)
|
||||
self.listView.scroller.panGestureRecognizer.cancelsTouchesInView = false
|
||||
self.listView.accessibilityPageScrolledString = { row, count in
|
||||
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
self.gifListView = ListView()
|
||||
self.gifListView.transform = CATransform3DMakeRotation(-CGFloat(Double.pi / 2.0), 0.0, 0.0, 1.0)
|
||||
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 fixPaneScrollImpl: ((ChatMediaInputPane, ChatMediaInputPaneScrollState) -> Void)?
|
||||
|
@ -110,6 +110,10 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
self.listNode = ListView()
|
||||
self.listNode.dynamicBounceEnabled = !self.presentationData.disableAnimations
|
||||
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.emptyNode = ChatRecentActionsEmptyNode(theme: self.presentationData.theme, chatWallpaper: self.presentationData.chatWallpaper, chatBubbleCorners: self.presentationData.chatBubbleCorners)
|
||||
self.emptyNode.alpha = 0.0
|
||||
|
@ -137,11 +137,16 @@ class ChatSearchResultsControllerNode: ViewControllerTracingNode, UIScrollViewDe
|
||||
self.searchQuery = searchQuery
|
||||
self.searchResult = searchResult
|
||||
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.listNode = ListView()
|
||||
self.listNode.verticalScrollIndicatorColor = self.presentationData.theme.list.scrollIndicatorColor
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -70,6 +70,9 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode {
|
||||
self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor
|
||||
self.listView.limitHitTestToNodes = 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)
|
||||
|
||||
|
@ -100,7 +100,8 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
|
||||
|
||||
init(context: AccountContext, selectSticker: ((FileMediaReference, ASDisplayNode, CGRect) -> Bool)?) {
|
||||
self.context = context
|
||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.presentationData = presentationData
|
||||
self.selectSticker = selectSticker
|
||||
|
||||
self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings))
|
||||
@ -179,9 +180,15 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
|
||||
|
||||
self.stickerListView = ListView()
|
||||
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.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.backgroundColor = UIColor(rgb: 0x2c2d2d)
|
||||
|
@ -130,6 +130,9 @@ final class EmojisChatInputContextPanelNode: ChatInputContextPanelNode {
|
||||
self.listView.isOpaque = false
|
||||
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
||||
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)
|
||||
|
||||
|
@ -76,6 +76,9 @@ final class HashtagChatInputContextPanelNode: ChatInputContextPanelNode {
|
||||
self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor
|
||||
self.listView.limitHitTestToNodes = 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)
|
||||
|
||||
|
@ -101,6 +101,9 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
|
||||
self.listView.backgroundColor = theme.list.plainBackgroundColor
|
||||
self.listView.transform = CATransform3DMakeRotation(-CGFloat(CGFloat.pi / 2.0), 0.0, 0.0, 1.0)
|
||||
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)
|
||||
|
||||
|
@ -77,6 +77,9 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
|
||||
self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor
|
||||
self.listView.limitHitTestToNodes = 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)
|
||||
|
||||
|
@ -88,7 +88,11 @@ final class PeerInfoGroupsInCommonPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
self.openPeerContextAction = openPeerContextAction
|
||||
self.groupsInCommonContext = groupsInCommonContext
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.listNode = ListView()
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -129,7 +129,11 @@ final class PeerInfoMembersPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
self.membersContext = membersContext
|
||||
self.action = action
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.listNode = ListView()
|
||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -90,6 +90,9 @@ final class StickersChatInputContextPanelNode: ChatInputContextPanelNode {
|
||||
self.listView.keepBottomItemOverscrollBackground = theme.list.plainBackgroundColor
|
||||
self.listView.limitHitTestToNodes = true
|
||||
self.listView.view.disablesInteractiveTransitionGestureRecognizer = true
|
||||
self.listView.accessibilityPageScrolledString = { row, count in
|
||||
return strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
self.stickersInteraction = StickersChatInputContextPanelInteraction()
|
||||
|
||||
|
@ -141,6 +141,9 @@ final class VerticalListContextResultsChatInputContextPanelNode: ChatInputContex
|
||||
self.listView.limitHitTestToNodes = true
|
||||
self.listView.isHidden = 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)
|
||||
|
||||
|
@ -218,6 +218,9 @@ class WebSearchControllerNode: ASDisplayNode {
|
||||
|
||||
self.recentQueriesNode = ListView()
|
||||
self.recentQueriesNode.backgroundColor = theme.list.plainBackgroundColor
|
||||
self.recentQueriesNode.accessibilityPageScrolledString = { row, count in
|
||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user