Fix ItemListController crash?

This commit is contained in:
Peter 2019-10-06 04:25:10 +04:00
parent 3ddbeea591
commit 36c82642d6
77 changed files with 615 additions and 244 deletions

View File

@ -146,7 +146,7 @@ build_debug_armv7: check_env
//:NotificationContentExtension#dwarf-and-dsym,iphoneos-armv7 \
//:NotificationServiceExtension#dwarf-and-dsym,iphoneos-armv7 \
//:IntentsExtension#dwarf-and-dsym,iphoneos-armv7 \
--verbose 7 ${BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS} ${BUCK_THREADS_OPTIONS} ${BUCK_CACHE_OPTIONS}
${BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS} ${BUCK_THREADS_OPTIONS} ${BUCK_CACHE_OPTIONS}
build: check_env
$(BUCK) build \
@ -284,7 +284,7 @@ app_arm64: build_arm64 package_arm64
app_debug_arm64: build_debug_arm64 package_debug_arm64
app_debug_armv7: build_debug_armv7 package_armv7
app_debug_armv7: build_debug_armv7 package_debug_armv7
build_buckdebug: check_env
BUCK_DEBUG_MODE=1 $(BUCK) build \
@ -374,6 +374,10 @@ project: check_env kill_xcode
$(BUCK) project //:workspace --config custom.mode=project ${BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS}
open Telegram_Buck.xcworkspace
project_opt: check_env kill_xcode
$(BUCK) project //:workspace --config custom.mode=project ${BUCK_OPTIONS} ${BUCK_RELEASE_OPTIONS}
open Telegram_Buck.xcworkspace
project_buckdebug: check_env kill_xcode
BUCK_DEBUG_MODE=1 $(BUCK) project //:workspace --config custom.mode=project ${BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS}
open Telegram_Buck.xcworkspace

View File

@ -159,7 +159,8 @@ enum BotCheckoutEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: BotCheckoutControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! BotCheckoutControllerArguments
switch self {
case let .header(theme, invoice, botName):
return BotCheckoutHeaderItem(account: arguments.account, theme: theme, invoice: invoice, botName: botName, sectionId: self.section)
@ -366,7 +367,7 @@ private func availablePaymentMethods(form: BotPaymentForm, current: BotCheckoutP
return methods
}
final class BotCheckoutControllerNode: ItemListControllerNode<BotCheckoutEntry>, PKPaymentAuthorizationViewControllerDelegate {
final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthorizationViewControllerDelegate {
private let context: AccountContext
private let messageId: MessageId
private let present: (ViewController, Any?) -> Void
@ -394,7 +395,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode<BotCheckoutEntry>,
private var applePayAuthrorizationCompletion: ((PKPaymentAuthorizationStatus) -> Void)?
private var applePayController: PKPaymentAuthorizationViewController?
init(controller: ItemListController<BotCheckoutEntry>?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContext, invoice: TelegramMediaInvoice, messageId: MessageId, present: @escaping (ViewController, Any?) -> Void, dismissAnimated: @escaping () -> Void) {
init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContext, invoice: TelegramMediaInvoice, messageId: MessageId, present: @escaping (ViewController, Any?) -> Void, dismissAnimated: @escaping () -> Void) {
self.context = context
self.messageId = messageId
self.present = present
@ -414,8 +415,8 @@ final class BotCheckoutControllerNode: ItemListControllerNode<BotCheckoutEntry>,
openShippingMethodImpl?()
})
let signal: Signal<(PresentationTheme, (ItemListNodeState<BotCheckoutEntry>, BotCheckoutEntry.ItemGenerationArguments)), NoError> = combineLatest(context.sharedContext.presentationData, self.state.get(), paymentFormAndInfo.get(), context.account.postbox.loadedPeerWithId(messageId.peerId))
|> map { presentationData, state, paymentFormAndInfo, botPeer -> (PresentationTheme, (ItemListNodeState<BotCheckoutEntry>, BotCheckoutEntry.ItemGenerationArguments)) in
let signal: Signal<(PresentationTheme, (ItemListNodeState, Any)), NoError> = combineLatest(context.sharedContext.presentationData, self.state.get(), paymentFormAndInfo.get(), context.account.postbox.loadedPeerWithId(messageId.peerId))
|> map { presentationData, state, paymentFormAndInfo, botPeer -> (PresentationTheme, (ItemListNodeState, Any)) in
let nodeState = ItemListNodeState(entries: botCheckoutControllerEntries(presentationData: presentationData, state: state, invoice: invoice, paymentForm: paymentFormAndInfo?.0, formInfo: paymentFormAndInfo?.1, validatedFormInfo: paymentFormAndInfo?.2, currentShippingOptionId: paymentFormAndInfo?.3, currentPaymentMethod: paymentFormAndInfo?.4, botPeer: botPeer), style: .plain, focusItemTag: nil, emptyStateItem: nil, animateChanges: false)
return (presentationData.theme, (nodeState, arguments))

View File

@ -147,7 +147,8 @@ enum BotReceiptEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: BotReceiptControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! BotReceiptControllerArguments
switch self {
case let .header(theme, invoice, botName):
return BotCheckoutHeaderItem(account: arguments.account, theme: theme, invoice: invoice, botName: botName, sectionId: self.section)
@ -253,7 +254,7 @@ private func availablePaymentMethods(current: BotCheckoutPaymentMethod?) -> [Bot
return []
}
final class BotReceiptControllerNode: ItemListControllerNode<BotReceiptEntry> {
final class BotReceiptControllerNode: ItemListControllerNode {
private let context: AccountContext
private let dismissAnimated: () -> Void
@ -264,7 +265,7 @@ final class BotReceiptControllerNode: ItemListControllerNode<BotReceiptEntry> {
private let actionButton: BotCheckoutActionButton
init(controller: ItemListController<BotReceiptEntry>?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContext, invoice: TelegramMediaInvoice, messageId: MessageId, dismissAnimated: @escaping () -> Void) {
init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContext, invoice: TelegramMediaInvoice, messageId: MessageId, dismissAnimated: @escaping () -> Void) {
self.context = context
self.dismissAnimated = dismissAnimated
@ -272,8 +273,8 @@ final class BotReceiptControllerNode: ItemListControllerNode<BotReceiptEntry> {
let arguments = BotReceiptControllerArguments(account: context.account)
let signal: Signal<(PresentationTheme, (ItemListNodeState<BotReceiptEntry>, BotReceiptEntry.ItemGenerationArguments)), NoError> = combineLatest(context.sharedContext.presentationData, receiptData.get(), context.account.postbox.loadedPeerWithId(messageId.peerId))
|> map { presentationData, receiptData, botPeer -> (PresentationTheme, (ItemListNodeState<BotReceiptEntry>, BotReceiptEntry.ItemGenerationArguments)) in
let signal: Signal<(PresentationTheme, (ItemListNodeState, Any)), NoError> = combineLatest(context.sharedContext.presentationData, receiptData.get(), context.account.postbox.loadedPeerWithId(messageId.peerId))
|> map { presentationData, receiptData, botPeer -> (PresentationTheme, (ItemListNodeState, Any)) in
let nodeState = ItemListNodeState(entries: botReceiptControllerEntries(presentationData: presentationData, invoice: invoice, formInvoice: receiptData?.0, formInfo: receiptData?.1, shippingOption: receiptData?.2, paymentMethodTitle: receiptData?.3, botPeer: botPeer), style: .plain, focusItemTag: nil, emptyStateItem: nil, animateChanges: false)
return (presentationData.theme, (nodeState, arguments))

View File

@ -128,7 +128,8 @@ private enum CreatePollEntry: ItemListNodeEntry {
return lhs.sortId < rhs.sortId
}
func item(_ arguments: CreatePollControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! CreatePollControllerArguments
switch self {
case let .textHeader(theme, text, accessoryText):
return ItemListSectionHeaderItem(theme: theme, text: text, accessoryText: accessoryText, sectionId: self.section)
@ -305,7 +306,7 @@ public func createPollController(context: AccountContext, peerId: PeerId, comple
let limitsKey = PostboxViewKey.preferences(keys: Set([PreferencesKeys.limitsConfiguration]))
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get() |> deliverOnMainQueue, context.account.postbox.combinedView(keys: [limitsKey]))
|> map { presentationData, state, combinedView -> (ItemListControllerState, (ItemListNodeState<CreatePollEntry>, CreatePollEntry.ItemGenerationArguments)) in
|> map { presentationData, state, combinedView -> (ItemListControllerState, (ItemListNodeState, Any)) in
let limitsConfiguration: LimitsConfiguration = (combinedView.views[limitsKey] as? PreferencesView)?.values[PreferencesKeys.limitsConfiguration] as? LimitsConfiguration ?? LimitsConfiguration.defaultValue
var enabled = true
@ -453,7 +454,7 @@ public func createPollController(context: AccountContext, peerId: PeerId, comple
})
}
controller.reorderEntry = { fromIndex, toIndex, entries in
controller.setReorderEntry({ (fromIndex: Int, toIndex: Int, entries: [CreatePollEntry]) -> Void in
let fromEntry = entries[fromIndex]
guard case let .option(_, _, id, _, _, _, _, _) = fromEntry else {
return
@ -512,7 +513,7 @@ public func createPollController(context: AccountContext, peerId: PeerId, comple
}
return state
}
}
})
controller.isOpaqueWhenInOverlay = true
controller.blocksBackgroundWhenInOverlay = true
controller.experimentalSnapScrollToItem = true

View File

@ -103,8 +103,8 @@ public struct ItemListControllerState {
}
}
open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShortcutResponder, PresentableController {
private let state: Signal<(ItemListControllerState, (ItemListNodeState<Entry>, Entry.ItemGenerationArguments)), NoError>
open class ItemListController: ViewController, KeyShortcutResponder, PresentableController {
private let state: Signal<(ItemListControllerState, (ItemListNodeState, Any)), NoError>
private var leftNavigationButtonTitleAndStyle: (ItemListNavigationButtonContent, ItemListNavigationButtonStyle)?
private var rightNavigationButtonTitleAndStyle: [(ItemListNavigationButtonContent, ItemListNavigationButtonStyle)] = []
@ -135,7 +135,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
public var experimentalSnapScrollToItem: Bool = false {
didSet {
if self.isNodeLoaded {
(self.displayNode as! ItemListControllerNode<Entry>).listNode.experimentalSnapScrollToItem = self.experimentalSnapScrollToItem
(self.displayNode as! ItemListControllerNode).listNode.experimentalSnapScrollToItem = self.experimentalSnapScrollToItem
}
}
}
@ -143,7 +143,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
public var enableInteractiveDismiss = false {
didSet {
if self.isNodeLoaded {
(self.displayNode as! ItemListControllerNode<Entry>).enableInteractiveDismiss = self.enableInteractiveDismiss
(self.displayNode as! ItemListControllerNode).enableInteractiveDismiss = self.enableInteractiveDismiss
}
}
}
@ -151,15 +151,15 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
public var alwaysSynchronous = false {
didSet {
if self.isNodeLoaded {
(self.displayNode as! ItemListControllerNode<Entry>).alwaysSynchronous = self.alwaysSynchronous
(self.displayNode as! ItemListControllerNode).alwaysSynchronous = self.alwaysSynchronous
}
}
}
public var visibleEntriesUpdated: ((ItemListNodeVisibleEntries<Entry>) -> Void)? {
public var visibleEntriesUpdated: ((ItemListNodeVisibleEntries) -> Void)? {
didSet {
if self.isNodeLoaded {
(self.displayNode as! ItemListControllerNode<Entry>).visibleEntriesUpdated = self.visibleEntriesUpdated
(self.displayNode as! ItemListControllerNode).visibleEntriesUpdated = self.visibleEntriesUpdated
}
}
}
@ -167,7 +167,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
public var visibleBottomContentOffsetChanged: ((ListViewVisibleContentOffset) -> Void)? {
didSet {
if self.isNodeLoaded {
(self.displayNode as! ItemListControllerNode<Entry>).visibleBottomContentOffsetChanged = self.visibleBottomContentOffsetChanged
(self.displayNode as! ItemListControllerNode).visibleBottomContentOffsetChanged = self.visibleBottomContentOffsetChanged
}
}
}
@ -175,7 +175,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
public var contentOffsetChanged: ((ListViewVisibleContentOffset, Bool) -> Void)? {
didSet {
if self.isNodeLoaded {
(self.displayNode as! ItemListControllerNode<Entry>).contentOffsetChanged = self.contentOffsetChanged
(self.displayNode as! ItemListControllerNode).contentOffsetChanged = self.contentOffsetChanged
}
}
}
@ -183,7 +183,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
public var contentScrollingEnded: ((ListView) -> Bool)? {
didSet {
if self.isNodeLoaded {
(self.displayNode as! ItemListControllerNode<Entry>).contentScrollingEnded = self.contentScrollingEnded
(self.displayNode as! ItemListControllerNode).contentScrollingEnded = self.contentScrollingEnded
}
}
}
@ -191,17 +191,22 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
public var searchActivated: ((Bool) -> Void)? {
didSet {
if self.isNodeLoaded {
(self.displayNode as! ItemListControllerNode<Entry>).searchActivated = self.searchActivated
(self.displayNode as! ItemListControllerNode).searchActivated = self.searchActivated
}
}
}
public var willScrollToTop: (() -> Void)?
public var reorderEntry: ((Int, Int, [Entry]) -> Void)? {
public func setReorderEntry<T: ItemListNodeEntry>(_ f: @escaping (Int, Int, [T]) -> Void) {
self.reorderEntry = { a, b, list in
f(a, b, list.map { $0 as! T })
}
}
private var reorderEntry: ((Int, Int, [ItemListNodeAnyEntry]) -> Void)? {
didSet {
if self.isNodeLoaded {
(self.displayNode as! ItemListControllerNode<Entry>).reorderEntry = self.reorderEntry
(self.displayNode as! ItemListControllerNode).reorderEntry = self.reorderEntry
}
}
}
@ -212,17 +217,20 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
public var willDisappear: ((Bool) -> Void)?
public var didDisappear: ((Bool) -> Void)?
convenience public init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState<Entry>, Entry.ItemGenerationArguments)), NoError>, tabBarItem: Signal<ItemListControllerTabBarItem, NoError>? = nil) {
convenience public init<ItemGenerationArguments>(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, ItemGenerationArguments)), NoError>, tabBarItem: Signal<ItemListControllerTabBarItem, NoError>? = nil) {
self.init(sharedContext: context.sharedContext, state: state, tabBarItem: tabBarItem)
}
convenience public init(sharedContext: SharedAccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState<Entry>, Entry.ItemGenerationArguments)), NoError>, tabBarItem: Signal<ItemListControllerTabBarItem, NoError>? = nil) {
convenience public init<ItemGenerationArguments>(sharedContext: SharedAccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, ItemGenerationArguments)), NoError>, tabBarItem: Signal<ItemListControllerTabBarItem, NoError>? = nil) {
let presentationData = sharedContext.currentPresentationData.with { $0 }
self.init(theme: presentationData.theme, strings: presentationData.strings, updatedPresentationData: sharedContext.presentationData |> map { ($0.theme, $0.strings) }, state: state, tabBarItem: tabBarItem)
}
public init(theme: PresentationTheme, strings: PresentationStrings, updatedPresentationData: Signal<(theme: PresentationTheme, strings: PresentationStrings), NoError>, state: Signal<(ItemListControllerState, (ItemListNodeState<Entry>, Entry.ItemGenerationArguments)), NoError>, tabBarItem: Signal<ItemListControllerTabBarItem, NoError>?) {
public init<ItemGenerationArguments>(theme: PresentationTheme, strings: PresentationStrings, updatedPresentationData: Signal<(theme: PresentationTheme, strings: PresentationStrings), NoError>, state: Signal<(ItemListControllerState, (ItemListNodeState, ItemGenerationArguments)), NoError>, tabBarItem: Signal<ItemListControllerTabBarItem, NoError>?) {
self.state = state
|> map { controllerState, nodeStateAndArgument -> (ItemListControllerState, (ItemListNodeState, Any)) in
return (controllerState, (nodeStateAndArgument.0, nodeStateAndArgument.1))
}
self.theme = theme
self.strings = strings
@ -236,7 +244,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
self.scrollToTop = { [weak self] in
self?.willScrollToTop?()
(self?.displayNode as! ItemListControllerNode<Entry>).scrollToTop()
(self?.displayNode as! ItemListControllerNode).scrollToTop()
}
if let tabBarItem = tabBarItem {
@ -418,7 +426,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
}
}
} |> map { ($0.theme, $1) }
let displayNode = ItemListControllerNode<Entry>(controller: self, navigationBar: self.navigationBar!, updateNavigationOffset: { [weak self] offset in
let displayNode = ItemListControllerNode(controller: self, navigationBar: self.navigationBar!, updateNavigationOffset: { [weak self] offset in
if let strongSelf = self {
strongSelf.navigationOffset = offset
}
@ -440,7 +448,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
}
self.displayNode = displayNode
super.displayNodeDidLoad()
self._ready.set((self.displayNode as! ItemListControllerNode<Entry>).ready)
self._ready.set((self.displayNode as! ItemListControllerNode).ready)
}
override open func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
@ -448,7 +456,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
self.validLayout = layout
(self.displayNode as! ItemListControllerNode<Entry>).containerLayoutUpdated(layout, navigationBarHeight: self.navigationInsetHeight, transition: transition)
(self.displayNode as! ItemListControllerNode).containerLayoutUpdated(layout, navigationBarHeight: self.navigationInsetHeight, transition: transition)
}
@objc func leftNavigationButtonPressed() {
@ -470,12 +478,12 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
}
public func viewDidAppear(completion: @escaping () -> Void) {
(self.displayNode as! ItemListControllerNode<Entry>).listNode.preloadPages = true
(self.displayNode as! ItemListControllerNode).listNode.preloadPages = true
if let presentationArguments = self.presentationArguments as? ViewControllerPresentationArguments, !self.didPlayPresentationAnimation {
self.didPlayPresentationAnimation = true
if case .modalSheet = presentationArguments.presentationAnimation {
(self.displayNode as! ItemListControllerNode<Entry>).animateIn(completion: {
(self.displayNode as! ItemListControllerNode).animateIn(completion: {
presentationArguments.completion?()
completion()
})
@ -506,7 +514,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
public func frameForItemNode(_ predicate: (ListViewItemNode) -> Bool) -> CGRect? {
var result: CGRect?
(self.displayNode as! ItemListControllerNode<Entry>).listNode.forEachItemNode { itemNode in
(self.displayNode as! ItemListControllerNode).listNode.forEachItemNode { itemNode in
if let itemNode = itemNode as? ListViewItemNode {
if predicate(itemNode) {
result = itemNode.convert(itemNode.bounds, to: self.displayNode)
@ -517,7 +525,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
}
public func forEachItemNode(_ f: (ListViewItemNode) -> Void) {
(self.displayNode as! ItemListControllerNode<Entry>).listNode.forEachItemNode { itemNode in
(self.displayNode as! ItemListControllerNode).listNode.forEachItemNode { itemNode in
if let itemNode = itemNode as? ListViewItemNode {
f(itemNode)
}
@ -525,11 +533,11 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
}
public func ensureItemNodeVisible(_ itemNode: ListViewItemNode, animated: Bool = true) {
(self.displayNode as! ItemListControllerNode<Entry>).listNode.ensureItemNodeVisible(itemNode, animated: animated)
(self.displayNode as! ItemListControllerNode).listNode.ensureItemNodeVisible(itemNode, animated: animated)
}
public func afterLayout(_ f: @escaping () -> Void) {
(self.displayNode as! ItemListControllerNode<Entry>).afterLayout(f)
(self.displayNode as! ItemListControllerNode).afterLayout(f)
}
public func previewingController(from sourceView: UIView, for location: CGPoint) -> (UIViewController, CGRect)? {
@ -546,8 +554,8 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
}
var selectedNode: ItemListItemNode?
let listLocation = self.view.convert(location, to: (self.displayNode as! ItemListControllerNode<Entry>).listNode.view)
(self.displayNode as! ItemListControllerNode<Entry>).listNode.forEachItemNode { itemNode in
let listLocation = self.view.convert(location, to: (self.displayNode as! ItemListControllerNode).listNode.view)
(self.displayNode as! ItemListControllerNode).listNode.forEachItemNode { itemNode in
if itemNode.frame.contains(listLocation), let itemNode = itemNode as? ItemListItemNode {
selectedNode = itemNode
}
@ -570,7 +578,7 @@ open class ItemListController<Entry: ItemListNodeEntry>: ViewController, KeyShor
}
public func clearItemNodesHighlight(animated: Bool = false) {
(self.displayNode as! ItemListControllerNode<Entry>).listNode.clearHighlightAnimated(animated)
(self.displayNode as! ItemListControllerNode).listNode.clearHighlightAnimated(animated)
}
public func previewingCommit(_ viewControllerToCommit: UIViewController) {

View File

@ -9,13 +9,30 @@ import MergeLists
public typealias ItemListSectionId = Int32
public protocol ItemListNodeEntry: Comparable, Identifiable {
associatedtype ItemGenerationArguments
var section: ItemListSectionId { get }
public protocol ItemListNodeAnyEntry {
var anyId: AnyHashable { get }
var tag: ItemListItemTag? { get }
func isLessThan(_ rhs: ItemListNodeAnyEntry) -> Bool
func isEqual(_ rhs: ItemListNodeAnyEntry) -> Bool
func item(_ arguments: Any) -> ListViewItem
}
public protocol ItemListNodeEntry: Comparable, Identifiable, ItemListNodeAnyEntry {
var section: ItemListSectionId { get }
}
public extension ItemListNodeEntry {
var anyId: AnyHashable {
return self.stableId
}
func item(_ arguments: ItemGenerationArguments) -> ListViewItem
func isLessThan(_ rhs: ItemListNodeAnyEntry) -> Bool {
return self < (rhs as! Self)
}
func isEqual(_ rhs: ItemListNodeAnyEntry) -> Bool {
return self == (rhs as! Self)
}
}
public extension ItemListNodeEntry {
@ -28,8 +45,14 @@ private struct ItemListNodeEntryTransition {
let updates: [ListViewUpdateItem]
}
private func preparedItemListNodeEntryTransition<Entry: ItemListNodeEntry>(from fromEntries: [Entry], to toEntries: [Entry], arguments: Entry.ItemGenerationArguments) -> ItemListNodeEntryTransition {
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
private func preparedItemListNodeEntryTransition(from fromEntries: [ItemListNodeAnyEntry], to toEntries: [ItemListNodeAnyEntry], arguments: Any) -> ItemListNodeEntryTransition {
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries, isLess: { lhs, rhs in
return lhs.isLessThan(rhs)
}, isEqual: { lhs, rhs in
return lhs.isEqual(rhs)
}, getId: { value in
return value.anyId
})
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(arguments), directionHint: nil) }
@ -43,7 +66,7 @@ public enum ItemListStyle {
case blocks
}
private struct ItemListNodeTransition<Entry: ItemListNodeEntry> {
private struct ItemListNodeTransition {
let theme: PresentationTheme
let entries: ItemListNodeEntryTransition
let updateStyle: ItemListStyle?
@ -56,12 +79,12 @@ private struct ItemListNodeTransition<Entry: ItemListNodeEntry> {
let animated: Bool
let animateAlpha: Bool
let crossfade: Bool
let mergedEntries: [Entry]
let mergedEntries: [ItemListNodeAnyEntry]
let scrollEnabled: Bool
}
public struct ItemListNodeState<Entry: ItemListNodeEntry> {
let entries: [Entry]
public final class ItemListNodeState {
let entries: [ItemListNodeAnyEntry]
let style: ItemListStyle
let emptyStateItem: ItemListControllerEmptyStateItem?
let searchItem: ItemListControllerSearch?
@ -72,8 +95,8 @@ public struct ItemListNodeState<Entry: ItemListNodeEntry> {
let ensureVisibleItemTag: ItemListItemTag?
let initialScrollToItem: ListViewScrollToItem?
public init(entries: [Entry], 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) {
self.entries = entries
public init<T: ItemListNodeEntry>(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) {
self.entries = entries.map { $0 }
self.style = style
self.emptyStateItem = emptyStateItem
self.searchItem = searchItem
@ -86,32 +109,32 @@ public struct ItemListNodeState<Entry: ItemListNodeEntry> {
}
}
private final class ItemListNodeOpaqueState<Entry: ItemListNodeEntry> {
let mergedEntries: [Entry]
private final class ItemListNodeOpaqueState {
let mergedEntries: [ItemListNodeAnyEntry]
init(mergedEntries: [Entry]) {
init(mergedEntries: [ItemListNodeAnyEntry]) {
self.mergedEntries = mergedEntries
}
}
public final class ItemListNodeVisibleEntries<Entry: ItemListNodeEntry>: Sequence {
let iterate: () -> Entry?
public final class ItemListNodeVisibleEntries: Sequence {
let iterate: () -> ItemListNodeAnyEntry?
init(iterate: @escaping () -> Entry?) {
init(iterate: @escaping () -> ItemListNodeAnyEntry?) {
self.iterate = iterate
}
public func makeIterator() -> AnyIterator<Entry> {
return AnyIterator { () -> Entry? in
public func makeIterator() -> AnyIterator<ItemListNodeAnyEntry> {
return AnyIterator { () -> ItemListNodeAnyEntry? in
return self.iterate()
}
}
}
public final class ItemListControllerNodeView<Entry: ItemListNodeEntry>: UITracingLayerView, PreviewingHostView {
public final class ItemListControllerNodeView: UITracingLayerView, PreviewingHostView {
var onLayout: (() -> Void)?
init(controller: ItemListController<Entry>?) {
init(controller: ItemListController?) {
self.controller = controller
super.init(frame: CGRect())
@ -149,10 +172,10 @@ public final class ItemListControllerNodeView<Entry: ItemListNodeEntry>: UITraci
})
}
weak var controller: ItemListController<Entry>?
weak var controller: ItemListController?
}
open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UIScrollViewDelegate {
open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate {
private var _ready = ValuePromise<Bool>()
open var ready: Signal<Bool, NoError> {
return self._ready.get()
@ -172,7 +195,7 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UISc
private let transitionDisposable = MetaDisposable()
private var enqueuedTransitions: [ItemListNodeTransition<Entry>] = []
private var enqueuedTransitions: [ItemListNodeTransition] = []
private var validLayout: (ContainerViewLayout, CGFloat)?
private var theme: PresentationTheme?
@ -186,12 +209,12 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UISc
public let updateNavigationOffset: (CGFloat) -> Void
public var dismiss: (() -> Void)?
public var visibleEntriesUpdated: ((ItemListNodeVisibleEntries<Entry>) -> Void)?
public var visibleEntriesUpdated: ((ItemListNodeVisibleEntries) -> Void)?
public var visibleBottomContentOffsetChanged: ((ListViewVisibleContentOffset) -> Void)?
public var contentOffsetChanged: ((ListViewVisibleContentOffset, Bool) -> Void)?
public var contentScrollingEnded: ((ListView) -> Bool)?
public var searchActivated: ((Bool) -> Void)?
public var reorderEntry: ((Int, Int, [Entry]) -> Void)?
public var reorderEntry: ((Int, Int, [ItemListNodeAnyEntry]) -> Void)?
public var requestLayout: ((ContainedViewLayoutTransition) -> Void)?
public var enableInteractiveDismiss = false {
@ -201,7 +224,7 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UISc
var alwaysSynchronous = false
public init(controller: ItemListController<Entry>?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, state: Signal<(PresentationTheme, (ItemListNodeState<Entry>, Entry.ItemGenerationArguments)), NoError>) {
public init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, state: Signal<(PresentationTheme, (ItemListNodeState, Any)), NoError>) {
self.navigationBar = navigationBar
self.updateNavigationOffset = updateNavigationOffset
@ -212,7 +235,7 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UISc
super.init()
self.setViewBlock({ [weak controller] in
return ItemListControllerNodeView<Entry>(controller: controller)
return ItemListControllerNodeView(controller: controller)
})
self.backgroundColor = nil
@ -221,13 +244,13 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UISc
self.addSubnode(self.listNode)
self.listNode.displayedItemRangeChanged = { [weak self] displayedRange, opaqueTransactionState in
if let strongSelf = self, let visibleEntriesUpdated = strongSelf.visibleEntriesUpdated, let mergedEntries = (opaqueTransactionState as? ItemListNodeOpaqueState<Entry>)?.mergedEntries {
if let strongSelf = self, let visibleEntriesUpdated = strongSelf.visibleEntriesUpdated, let mergedEntries = (opaqueTransactionState as? ItemListNodeOpaqueState)?.mergedEntries {
if let visible = displayedRange.visibleRange {
let indexRange = (visible.firstIndex, visible.lastIndex)
var index = indexRange.0
let iterator = ItemListNodeVisibleEntries<Entry>(iterate: {
var item: Entry?
let iterator = ItemListNodeVisibleEntries(iterate: {
var item: ItemListNodeAnyEntry?
if index <= indexRange.1 {
item = mergedEntries[index]
}
@ -240,7 +263,7 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UISc
}
self.listNode.reorderItem = { [weak self] fromIndex, toIndex, opaqueTransactionState in
if let strongSelf = self, let reorderEntry = strongSelf.reorderEntry, let mergedEntries = (opaqueTransactionState as? ItemListNodeOpaqueState<Entry>)?.mergedEntries {
if let strongSelf = self, let reorderEntry = strongSelf.reorderEntry, let mergedEntries = (opaqueTransactionState as? ItemListNodeOpaqueState)?.mergedEntries {
if fromIndex >= 0 && fromIndex < mergedEntries.count && toIndex >= 0 && toIndex < mergedEntries.count {
reorderEntry(fromIndex, toIndex, mergedEntries)
}
@ -266,10 +289,14 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UISc
}
}
let previousState = Atomic<ItemListNodeState<Entry>?>(value: nil)
self.transitionDisposable.set(((state |> map { theme, stateAndArguments -> ItemListNodeTransition<Entry> in
let previousState = Atomic<ItemListNodeState?>(value: nil)
self.transitionDisposable.set(((state |> map { theme, stateAndArguments -> ItemListNodeTransition in
let (state, arguments) = stateAndArguments
assert(state.entries == state.entries.sorted())
if state.entries.count > 1 {
for i in 1 ..< state.entries.count {
assert(state.entries[i - 1].isLessThan(state.entries[i]))
}
}
let previous = previousState.swap(state)
let transition = preparedItemListNodeEntryTransition(from: previous?.entries ?? [], to: state.entries, arguments: arguments)
var updatedStyle: ItemListStyle?
@ -297,7 +324,7 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UISc
override open func didLoad() {
super.didLoad()
(self.view as? ItemListControllerNodeView<Entry>)?.onLayout = { [weak self] in
(self.view as? ItemListControllerNodeView)?.onLayout = { [weak self] in
guard let strongSelf = self else {
return
}
@ -310,7 +337,7 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UISc
}
}
(self.view as? ItemListControllerNodeView<Entry>)?.hitTestImpl = { [weak self] point, event in
(self.view as? ItemListControllerNodeView)?.hitTestImpl = { [weak self] point, event in
return self?.hitTest(point, with: event)
}
}
@ -416,7 +443,7 @@ open class ItemListControllerNode<Entry: ItemListNodeEntry>: ASDisplayNode, UISc
}
}
private func enqueueTransition(_ transition: ItemListNodeTransition<Entry>) {
private func enqueueTransition(_ transition: ItemListNodeTransition) {
self.enqueuedTransitions.append(transition)
if self.validLayout != nil {
self.dequeueTransitions()

View File

@ -4,3 +4,11 @@ public protocol Identifiable {
associatedtype T: Hashable
var stableId: T { get }
}
public struct AnyIdentifiable {
var stableId: AnyHashable
public init<T>(_ value: T) where T : Identifiable {
self.stableId = value.stableId
}
}

View File

@ -181,6 +181,190 @@ public func mergeListsStableWithUpdates<T>(leftList: [T], rightList: [T], allUpd
return (removeIndices, insertItems, updatedIndices)
}
@inlinable
public func mergeListsStableWithUpdates<T>(leftList: [T], rightList: [T], isLess: (T, T) -> Bool, isEqual: (T, T) -> Bool, getId: (T) -> AnyHashable, allUpdated: Bool = false) -> ([Int], [(Int, T, Int?)], [(Int, T, Int)]) {
var removeIndices: [Int] = []
var insertItems: [(Int, T, Int?)] = []
var updatedIndices: [(Int, T, Int)] = []
#if DEBUG
var existingStableIds: [AnyHashable: T] = [:]
for item in leftList {
if let _ = existingStableIds[getId(item)] {
assertionFailure()
} else {
existingStableIds[getId(item)] = item
}
}
existingStableIds.removeAll()
for item in rightList {
if let other = existingStableIds[getId(item)] {
print("\(other) has the same stableId as \(item): \(getId(item))")
assertionFailure()
} else {
existingStableIds[getId(item)] = item
}
}
#endif
var currentList = leftList
var i = 0
var previousIndices: [AnyHashable: Int] = [:]
for left in leftList {
previousIndices[getId(left)] = i
i += 1
}
i = 0
var j = 0
while true {
let left: T? = i < currentList.count ? currentList[i] : nil
let right: T? = j < rightList.count ? rightList[j] : nil
if let left = left, let right = right {
if getId(left) == getId(right) && (!isEqual(left, right) || allUpdated) {
updatedIndices.append((i, right, previousIndices[getId(left)]!))
i += 1
j += 1
} else {
if isEqual(left, right) && !allUpdated {
i += 1
j += 1
} else if isLess(left, right) {
removeIndices.append(i)
i += 1
} else {
j += 1
}
}
} else if let _ = left {
removeIndices.append(i)
i += 1
} else if let _ = right {
j += 1
} else {
break
}
}
//print("remove:\n\(removeIndices)")
for index in removeIndices.reversed() {
currentList.remove(at: index)
for i in 0 ..< updatedIndices.count {
if updatedIndices[i].0 >= index {
updatedIndices[i].0 -= 1
}
}
}
/*print("\n current after removes:\n")
m = 0
for right in currentList {
print("\(m): \(right.stableId)")
m += 1
}
print("update:\n\(updatedIndices.map({ "\($0.0), \($0.1.stableId) (was \($0.2)))" }))")*/
i = 0
j = 0
var k = 0
while true {
let left: T?
//print("i=\(i), j=\(j), k=\(k)")
if k < updatedIndices.count && updatedIndices[k].0 < i {
//print("updated[k=\(k)]=\(updatedIndices[k].0)<i=\(i), k++")
k += 1
}
if k < updatedIndices.count {
if updatedIndices[k].0 == i {
left = updatedIndices[k].1
//print("override left = \(updatedIndices[k].1.stableId)")
} else {
left = i < currentList.count ? currentList[i] : nil
}
} else {
left = i < currentList.count ? currentList[i] : nil
}
let right: T? = j < rightList.count ? rightList[j] : nil
if let left = left, let right = right {
if isEqual(left, right) {
//print("\(left.stableId)==\(right.stableId)")
//print("i++, j++")
i += 1
j += 1
} else if !isLess(left, right) {
//print("\(left.stableId)>\(right.stableId)")
//print("insert \(right.stableId) at \(i)")
//print("i++, j++")
let previousIndex = previousIndices[getId(right)]
insertItems.append((i, right, previousIndex))
currentList.insert(right, at: i)
if k < updatedIndices.count {
for l in k ..< updatedIndices.count {
updatedIndices[l] = (updatedIndices[l].0 + 1, updatedIndices[l].1, updatedIndices[l].2)
}
}
i += 1
j += 1
} else {
//print("\(left.stableId)<\(right.stableId)")
//print("i++")
i += 1
}
} else if let _ = left {
//print("\(left!.stableId)>nil")
//print("i++")
i += 1
} else if let right = right {
//print("nil<\(right.stableId)")
//print("insert \(right.stableId) at \(i)")
//print("i++")
//print("j++")
let previousIndex = previousIndices[getId(right)]
insertItems.append((i, right, previousIndex))
currentList.insert(right, at: i)
if k < updatedIndices.count {
for l in k ..< updatedIndices.count {
updatedIndices[l] = (updatedIndices[l].0 + 1, updatedIndices[l].1, updatedIndices[l].2)
}
}
i += 1
j += 1
} else {
break
}
}
for (index, item, _) in updatedIndices {
currentList[index] = item
}
#if DEBUG
if currentList.count != rightList.count {
precondition(false)
} else {
for i in 0 ..< currentList.count {
if !isEqual(currentList[i], rightList[i]) {
precondition(false)
}
}
}
#endif
return (removeIndices, insertItems, updatedIndices)
}
@inlinable
public func mergeListsStableWithUpdatesReversed<T>(leftList: [T], rightList: [T], allUpdated: Bool = false) -> ([Int], [(Int, T, Int?)], [(Int, T, Int)]) where T: Comparable, T: Identifiable {
var removeIndices: [Int] = []

View File

@ -123,7 +123,8 @@ private enum NotificationSoundSelectionEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: NotificationSoundSelectionArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! NotificationSoundSelectionArguments
switch self {
case let.modernHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -281,7 +282,7 @@ public func notificationSoundSelectionController(context: AccountContext, isModa
})
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get())
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<NotificationSoundSelectionEntry>, NotificationSoundSelectionEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
arguments.cancel()

View File

@ -65,7 +65,8 @@ private enum ResetPasswordEntry: ItemListNodeEntry, Equatable {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: ResetPasswordControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ResetPasswordControllerArguments
switch self {
case let .code(theme, strings, text, value):
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: text, textColor: theme.list.itemPrimaryTextColor), text: value, placeholder: "", type: .number, spacing: 10.0, tag: ResetPasswordEntryTag.code, sectionId: self.section, textUpdated: { updatedText in
@ -141,7 +142,7 @@ public func resetPasswordController(context: AccountContext, emailPattern: Strin
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get())
|> deliverOnMainQueue
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<ResetPasswordEntry>, ResetPasswordEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()

View File

@ -359,7 +359,8 @@ private enum ChannelAdminEntry: ItemListNodeEntry {
}
}
func item(_ arguments: ChannelAdminControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ChannelAdminControllerArguments
switch self {
case let .info(theme, strings, dateTimeFormat, peer, presence):
return ItemListAvatarAndNameInfoItem(account: arguments.account, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, mode: .generic, peer: peer, presence: presence, cachedData: nil, state: ItemListAvatarAndNameInfoItemState(), sectionId: self.section, style: .blocks(withTopInset: true, withExtendedBottomInset: false), editingNameUpdated: { _ in
@ -861,7 +862,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), combinedView)
|> deliverOnMainQueue
|> map { presentationData, state, combinedView -> (ItemListControllerState, (ItemListNodeState<ChannelAdminEntry>, ChannelAdminEntry.ItemGenerationArguments)) in
|> map { presentationData, state, combinedView -> (ItemListControllerState, (ItemListNodeState, Any)) in
let channelView = combinedView.views[.peer(peerId: peerId, components: .all)] as! PeerView
let adminView = combinedView.views[.peer(peerId: adminId, components: .all)] as! PeerView
let canEdit = canEditAdminRights(accountPeerId: context.account.peerId, channelView: channelView, initialParticipant: initialParticipant)

View File

@ -198,7 +198,8 @@ private enum ChannelAdminsEntry: ItemListNodeEntry {
}
}
func item(_ arguments: ChannelAdminsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ChannelAdminsControllerArguments
switch self {
case let .recentActions(theme, text):
return ItemListDisclosureItem(theme: theme, title: text, label: "", sectionId: self.section, style: .blocks, action: {
@ -681,7 +682,7 @@ public func channelAdminsController(context: AccountContext, peerId: PeerId, loa
let signal = combineLatest(queue: .mainQueue(), presentationDataSignal, statePromise.get(), peerView.get(), adminsPromise.get() |> deliverOnMainQueue)
|> deliverOnMainQueue
|> map { presentationData, state, view, admins -> (ItemListControllerState, (ItemListNodeState<ChannelAdminsEntry>, ChannelAdminsEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view, admins -> (ItemListControllerState, (ItemListNodeState, Any)) in
var rightNavigationButton: ItemListNavigationButton?
var secondaryRightNavigationButton: ItemListNavigationButton?
if let admins = admins, admins.count > 1 {

View File

@ -218,7 +218,8 @@ private enum ChannelBannedMemberEntry: ItemListNodeEntry {
}
}
func item(_ arguments: ChannelBannedMemberControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ChannelBannedMemberControllerArguments
switch self {
case let .info(theme, strings, dateTimeFormat, peer, presence):
return ItemListAvatarAndNameInfoItem(account: arguments.account, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, mode: .generic, peer: peer, presence: presence, cachedData: nil, state: ItemListAvatarAndNameInfoItemState(), sectionId: self.section, style: .blocks(withTopInset: true, withExtendedBottomInset: false), editingNameUpdated: { _ in
@ -512,7 +513,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), combinedView)
|> deliverOnMainQueue
|> map { presentationData, state, combinedView -> (ItemListControllerState, (ItemListNodeState<ChannelBannedMemberEntry>, ChannelBannedMemberEntry.ItemGenerationArguments)) in
|> map { presentationData, state, combinedView -> (ItemListControllerState, (ItemListNodeState, Any)) in
let channelView = combinedView.views[.peer(peerId: peerId, components: .all)] as! PeerView
let memberView = combinedView.views[.peer(peerId: memberId, components: .all)] as! PeerView
var initialBannedByPeer: Peer?

View File

@ -145,7 +145,8 @@ private enum ChannelBlacklistEntry: ItemListNodeEntry {
}
}
func item(_ arguments: ChannelBlacklistControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ChannelBlacklistControllerArguments
switch self {
case let .add(theme, text):
return ItemListActionItem(theme: theme, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
@ -434,7 +435,7 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), peerView.get(), blacklistPromise.get())
|> deliverOnMainQueue
|> map { presentationData, state, view, participants -> (ItemListControllerState, (ItemListNodeState<ChannelBlacklistEntry>, ChannelBlacklistEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view, participants -> (ItemListControllerState, (ItemListNodeState, Any)) in
var rightNavigationButton: ItemListNavigationButton?
var secondaryRightNavigationButton: ItemListNavigationButton?
if let participants = participants, !participants.isEmpty {

View File

@ -125,7 +125,8 @@ private enum ChannelDiscussionGroupSetupControllerEntry: ItemListNodeEntry {
return lhs.sortIndex < rhs.sortIndex
}
func item(_ arguments: ChannelDiscussionGroupSetupControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ChannelDiscussionGroupSetupControllerArguments
switch self {
case let .header(theme, strings, title, isGroup, label):
return ChannelDiscussionGroupSetupHeaderItem(theme: theme, strings: strings, title: title, isGroup: isGroup, label: label, sectionId: self.section)
@ -525,7 +526,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), peerView, groupPeers.get())
|> deliverOnMainQueue
|> map { presentationData, state, view, groups -> (ItemListControllerState, (ItemListNodeState<ChannelDiscussionGroupSetupControllerEntry>, ChannelDiscussionGroupSetupControllerEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view, groups -> (ItemListControllerState, (ItemListNodeState, Any)) in
let title: String
if let peer = view.peers[view.peerId] as? TelegramChannel, case .broadcast = peer.info {
title = presentationData.strings.Channel_DiscussionGroup

View File

@ -318,7 +318,8 @@ private enum ChannelInfoEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: ChannelInfoControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ChannelInfoControllerArguments
switch self {
case let .info(theme, strings, dateTimeFormat, peer, cachedData, state, updatingAvatar):
return ItemListAvatarAndNameInfoItem(account: arguments.account, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, mode: .generic, peer: peer, presence: nil, cachedData: cachedData, state: state, sectionId: self.section, style: .plain, editingNameUpdated: { editingName in
@ -953,7 +954,7 @@ public func channelInfoController(context: AccountContext, peerId: PeerId) -> Vi
let globalNotificationsKey: PostboxViewKey = .preferences(keys: Set<ValueBoxKey>([PreferencesKeys.globalNotifications]))
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), context.account.viewTracker.peerView(peerId, updateData: true), context.account.postbox.combinedView(keys: [globalNotificationsKey]))
|> map { presentationData, state, view, combinedView -> (ItemListControllerState, (ItemListNodeState<ChannelInfoEntry>, ChannelInfoEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view, combinedView -> (ItemListControllerState, (ItemListNodeState, Any)) in
let peer = peerViewMainPeer(view)
var globalNotificationSettings: GlobalNotificationSettings = GlobalNotificationSettings.defaultSettings

View File

@ -175,7 +175,8 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
}
}
func item(_ arguments: ChannelMembersControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ChannelMembersControllerArguments
switch self {
case let .addMember(theme, text):
return ItemListActionItem(theme: theme, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
@ -463,7 +464,7 @@ public func channelMembersController(context: AccountContext, peerId: PeerId) ->
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), peerView, peersPromise.get())
|> deliverOnMainQueue
|> map { presentationData, state, view, peers -> (ItemListControllerState, (ItemListNodeState<ChannelMembersEntry>, ChannelMembersEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view, peers -> (ItemListControllerState, (ItemListNodeState, Any)) in
var rightNavigationButton: ItemListNavigationButton?
var secondaryRightNavigationButton: ItemListNavigationButton?
if let peers = peers, !peers.isEmpty {

View File

@ -213,7 +213,8 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
}
}
func item(_ arguments: ChannelPermissionsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ChannelPermissionsControllerArguments
switch self {
case let .permissionsHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -756,7 +757,7 @@ public func channelPermissionsController(context: AccountContext, peerId origina
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), viewAndParticipants)
|> deliverOnMainQueue
|> map { presentationData, state, viewAndParticipants -> (ItemListControllerState, (ItemListNodeState<ChannelPermissionsEntry>, ChannelPermissionsEntry.ItemGenerationArguments)) in
|> map { presentationData, state, viewAndParticipants -> (ItemListControllerState, (ItemListNodeState, Any)) in
let (view, participants) = viewAndParticipants
var rightNavigationButton: ItemListNavigationButton?

View File

@ -260,7 +260,8 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: ChannelVisibilityControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ChannelVisibilityControllerArguments
switch self {
case let .typeHeader(theme, title):
return ItemListSectionHeaderItem(theme: theme, text: title, sectionId: self.section)
@ -974,7 +975,7 @@ public func channelVisibilityController(context: AccountContext, peerId: PeerId,
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get() |> deliverOnMainQueue, peerView, peersDisablingAddressNameAssignment.get() |> deliverOnMainQueue)
|> deliverOnMainQueue
|> map { presentationData, state, view, publicChannelsToRevoke -> (ItemListControllerState, (ItemListNodeState<ChannelVisibilityEntry>, ChannelVisibilityEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view, publicChannelsToRevoke -> (ItemListControllerState, (ItemListNodeState, Any)) in
let peer = peerViewMainPeer(view)
var rightNavigationButton: ItemListNavigationButton?

View File

@ -74,7 +74,8 @@ private enum ConvertToSupergroupEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: ConvertToSupergroupArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ConvertToSupergroupArguments
switch self {
case let .info(theme, text):
return ItemListTextItem(theme: theme, text: .markdown(text), sectionId: self.section)
@ -155,7 +156,7 @@ public func convertToSupergroupController(context: AccountContext, peerId: PeerI
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get())
|> deliverOnMainQueue
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<ConvertToSupergroupEntry>, ConvertToSupergroupEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
var rightNavigationButton: ItemListNavigationButton?
if state.isConverting {

View File

@ -372,7 +372,8 @@ private enum DeviceContactInfoEntry: ItemListNodeEntry {
return lhs.sortIndex < rhs.sortIndex
}
func item(_ arguments: DeviceContactInfoControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! DeviceContactInfoControllerArguments
switch self {
case let .info(_, theme, strings, dateTimeFormat, peer, state, jobSummary, isPlain):
return ItemListAvatarAndNameInfoItem(account: arguments.account, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, mode: .contact, peer: peer, presence: nil, label: jobSummary, cachedData: nil, state: state, sectionId: self.section, style: arguments.isPlain ? .plain : .blocks(withTopInset: false, withExtendedBottomInset: true), editingNameUpdated: { editingName in
@ -750,7 +751,7 @@ private func deviceContactInfoEntries(account: Account, presentationData: Presen
return entries
}
private final class DeviceContactInfoController: ItemListController<DeviceContactInfoEntry>, MFMessageComposeViewControllerDelegate, UINavigationControllerDelegate {
private final class DeviceContactInfoController: ItemListController, MFMessageComposeViewControllerDelegate, UINavigationControllerDelegate {
private var composer: MFMessageComposeViewController?
func inviteContact(presentationData: PresentationData, numbers: [String]) {
if MFMessageComposeViewController.canSendText() {
@ -1020,7 +1021,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
let previousEditingPhoneIds = Atomic<Set<Int64>?>(value: nil)
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), contactData)
|> map { presentationData, state, peerAndContactData -> (ItemListControllerState, (ItemListNodeState<DeviceContactInfoEntry>, DeviceContactInfoEntry.ItemGenerationArguments)) in
|> map { presentationData, state, peerAndContactData -> (ItemListControllerState, (ItemListNodeState, Any)) in
var leftNavigationButton: ItemListNavigationButton?
switch subject {
case .vcard:

View File

@ -473,7 +473,8 @@ private enum GroupInfoEntry: ItemListNodeEntry {
return lhs.sortIndex < rhs.sortIndex
}
func item(_ arguments: GroupInfoArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! GroupInfoArguments
switch self {
case let .info(theme, strings, dateTimeFormat, peer, cachedData, state, updatingAvatar):
return ItemListAvatarAndNameInfoItem(account: arguments.context.account, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, mode: .generic, peer: peer, presence: nil, cachedData: cachedData, state: state, sectionId: self.section, style: .blocks(withTopInset: false, withExtendedBottomInset: false), editingNameUpdated: { editingName in
@ -2115,7 +2116,7 @@ public func groupInfoController(context: AccountContext, peerId originalPeerId:
let globalNotificationsKey: PostboxViewKey = .preferences(keys: Set<ValueBoxKey>([PreferencesKeys.globalNotifications]))
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), peerView.get(), context.account.postbox.combinedView(keys: [globalNotificationsKey]), channelMembersPromise.get())
|> map { presentationData, state, view, combinedView, channelMembers -> (ItemListControllerState, (ItemListNodeState<GroupInfoEntry>, GroupInfoEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view, combinedView, channelMembers -> (ItemListControllerState, (ItemListNodeState, Any)) in
let peer = peerViewMainPeer(view)
var globalNotificationSettings: GlobalNotificationSettings = GlobalNotificationSettings.defaultSettings

View File

@ -76,7 +76,8 @@ private enum GroupPreHistorySetupEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: GroupPreHistorySetupArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! GroupPreHistorySetupArguments
switch self {
case let .header(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -138,7 +139,7 @@ public func groupPreHistorySetupController(context: AccountContext, peerId: Peer
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), context.account.viewTracker.peerView(peerId))
|> deliverOnMainQueue
|> map { presentationData, state, view -> (ItemListControllerState, (ItemListNodeState<GroupPreHistorySetupEntry>, GroupPreHistorySetupEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view -> (ItemListControllerState, (ItemListNodeState, Any)) in
let defaultValue: Bool = (view.cachedData as? CachedChannelData)?.flags.contains(.preHistoryEnabled) ?? false
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()

View File

@ -206,7 +206,8 @@ private enum GroupStickerPackEntry: ItemListNodeEntry {
}
}
func item(_ arguments: GroupStickerPackSetupControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! GroupStickerPackSetupControllerArguments
switch self {
case let .search(theme, strings, prefix, placeholder, value):
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: prefix, textColor: theme.list.itemPrimaryTextColor), text: value, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: false), spacing: 0.0, clearType: .always, tag: nil, sectionId: self.section, textUpdated: { value in
@ -409,7 +410,7 @@ public func groupStickerPackSetupController(context: AccountContext, peerId: Pee
let previousHadData = Atomic<Bool>(value: false)
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get() |> deliverOnMainQueue, initialData.get() |> deliverOnMainQueue, stickerPacks.get() |> deliverOnMainQueue, searchState.get() |> deliverOnMainQueue, context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.stickerSettings]) |> deliverOnMainQueue)
|> map { presentationData, state, initialData, view, searchState, sharedData -> (ItemListControllerState, (ItemListNodeState<GroupStickerPackEntry>, GroupStickerPackEntry.ItemGenerationArguments)) in
|> map { presentationData, state, initialData, view, searchState, sharedData -> (ItemListControllerState, (ItemListNodeState, Any)) in
var stickerSettings = StickerSettings.defaultSettings
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.stickerSettings] as? StickerSettings {
stickerSettings = value

View File

@ -85,7 +85,8 @@ private enum GroupsInCommonEntry: ItemListNodeEntry {
}
}
func item(_ arguments: GroupsInCommonControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! GroupsInCommonControllerArguments
switch self {
case let .peerItem(_, theme, strings, dateTimeFormat, nameDisplayOrder, peer):
return ItemListPeerItem(theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, account: arguments.account, peer: peer, presence: nil, text: .none, label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), switchValue: nil, enabled: true, selectable: true, sectionId: self.section, action: {
@ -157,7 +158,7 @@ public func groupsInCommonController(context: AccountContext, peerId: PeerId) ->
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), peersPromise.get())
|> deliverOnMainQueue
|> map { presentationData, state, peers -> (ItemListControllerState, (ItemListNodeState<GroupsInCommonEntry>, GroupsInCommonEntry.ItemGenerationArguments)) in
|> map { presentationData, state, peers -> (ItemListControllerState, (ItemListNodeState, Any)) in
var emptyStateItem: ItemListControllerEmptyStateItem?
if peers == nil {
emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme)

View File

@ -249,7 +249,8 @@ private enum PeerReportControllerEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: PeerReportControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! PeerReportControllerArguments
switch self {
case let .text(theme, title, value):
return ItemListMultilineInputItem(theme: theme, text: value, placeholder: title, maxLength: nil, sectionId: self.section, style: .blocks, textUpdated: { text in
@ -293,7 +294,7 @@ private func peerReportController(context: AccountContext, subject: PeerReportSu
let reportDisposable = MetaDisposable()
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get())
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<PeerReportControllerEntry>, PeerReportControllerEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let rightButton: ItemListNavigationButton
if state.isReporting {
rightButton = ItemListNavigationButton(content: .none, style: .activity, enabled: true, action: {})

View File

@ -55,7 +55,8 @@ private enum PhoneLabelEntry: ItemListNodeEntry {
return lhs.index < rhs.index
}
func item(_ arguments: PhoneLabelArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! PhoneLabelArguments
switch self {
case let .label(_, theme, value, text, selected):
return ItemListCheckboxItem(theme: theme, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
@ -107,7 +108,7 @@ public func phoneLabelController(context: AccountContext, currentLabel: String,
})
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get())
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<PhoneLabelEntry>, PhoneLabelEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
arguments.cancel()

View File

@ -387,7 +387,8 @@ private enum UserInfoEntry: ItemListNodeEntry {
return lhs.sortIndex < rhs.sortIndex
}
func item(_ arguments: UserInfoControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! UserInfoControllerArguments
switch self {
case let .info(theme, strings, dateTimeFormat, peer, presence, cachedData, state, displayCall):
return ItemListAvatarAndNameInfoItem(account: arguments.account, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, mode: .generic, peer: peer, presence: presence, cachedData: cachedData, state: state, sectionId: self.section, style: .plain, editingNameUpdated: { editingName in
@ -1195,7 +1196,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Pe
let globalNotificationsKey: PostboxViewKey = .preferences(keys: Set<ValueBoxKey>([PreferencesKeys.globalNotifications]))
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), peerView.get(), deviceContacts, context.account.postbox.combinedView(keys: [.peerChatState(peerId: peerId), globalNotificationsKey]))
|> map { presentationData, state, view, deviceContacts, combinedView -> (ItemListControllerState, (ItemListNodeState<UserInfoEntry>, UserInfoEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view, deviceContacts, combinedView -> (ItemListControllerState, (ItemListNodeState, Any)) in
let peer = peerViewMainPeer(view.0)
var globalNotificationSettings: GlobalNotificationSettings = .defaultSettings

View File

@ -187,7 +187,8 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
return result
}
func item(_ arguments: PeersNearbyControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! PeersNearbyControllerArguments
switch self {
case let .header(theme, text):
return PeersNearbyHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -410,7 +411,7 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
let signal = combineLatest(context.sharedContext.presentationData, dataPromise.get(), displayLoading)
|> deliverOnMainQueue
|> map { presentationData, data, displayLoading -> (ItemListControllerState, (ItemListNodeState<PeersNearbyEntry>, PeersNearbyEntry.ItemGenerationArguments)) in
|> map { presentationData, data, displayLoading -> (ItemListControllerState, (ItemListNodeState, Any)) in
let previous = previousData.swap(data)
var crossfade = false

View File

@ -82,7 +82,8 @@ private enum ChangePhoneNumberCodeEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: ChangePhoneNumberCodeControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ChangePhoneNumberCodeControllerArguments
switch self {
case let .codeEntry(theme, strings, title, text):
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: title, textColor: .black), text: text, placeholder: "", type: .number, spacing: 10.0, tag: ChangePhoneNumberCodeTag.input, sectionId: self.section, textUpdated: { updatedText in
@ -172,10 +173,10 @@ public protocol ChangePhoneNumberCodeController: class {
func applyCode(_ code: Int)
}
private final class ChangePhoneNumberCodeControllerImpl: ItemListController<ChangePhoneNumberCodeEntry>, ChangePhoneNumberCodeController {
private final class ChangePhoneNumberCodeControllerImpl: ItemListController, ChangePhoneNumberCodeController {
private let applyCodeImpl: (Int) -> Void
init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState<ChangePhoneNumberCodeEntry>, ChangePhoneNumberCodeEntry.ItemGenerationArguments)), NoError>, applyCodeImpl: @escaping (Int) -> Void) {
init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, Any)), NoError>, applyCodeImpl: @escaping (Int) -> Void) {
self.applyCodeImpl = applyCodeImpl
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
@ -294,7 +295,7 @@ func changePhoneNumberCodeController(context: AccountContext, phoneNumber: Strin
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get() |> deliverOnMainQueue, currentDataPromise.get() |> deliverOnMainQueue, timeout.get() |> deliverOnMainQueue)
|> deliverOnMainQueue
|> map { presentationData, state, data, timeout -> (ItemListControllerState, (ItemListNodeState<ChangePhoneNumberCodeEntry>, ChangePhoneNumberCodeEntry.ItemGenerationArguments)) in
|> map { presentationData, state, data, timeout -> (ItemListControllerState, (ItemListNodeState, Any)) in
var rightNavigationButton: ItemListNavigationButton?
if state.checking {
rightNavigationButton = ItemListNavigationButton(content: .none, style: .activity, enabled: true, action: {})

View File

@ -140,7 +140,8 @@ private enum AutodownloadMediaCategoryEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: AutodownloadMediaConnectionTypeControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! AutodownloadMediaConnectionTypeControllerArguments
switch self {
case let .master(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in
@ -318,7 +319,7 @@ func autodownloadMediaConnectionTypeController(context: AccountContext, connecti
let signal = combineLatest(context.sharedContext.presentationData, context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.autodownloadSettings, ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings]))
|> deliverOnMainQueue
|> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState<AutodownloadMediaCategoryEntry>, AutodownloadMediaCategoryEntry.ItemGenerationArguments)) in
|> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState, Any)) in
var automaticMediaDownloadSettings: MediaAutoDownloadSettings
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings] as? MediaAutoDownloadSettings {
automaticMediaDownloadSettings = value

View File

@ -168,7 +168,8 @@ private enum AutodownloadMediaCategoryEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: AutodownloadMediaCategoryControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! AutodownloadMediaCategoryControllerArguments
switch self {
case let .peerHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -398,7 +399,7 @@ func autodownloadMediaCategoryController(context: AccountContext, connectionType
initialValuePromise.set(currentAutodownloadSettings())
let signal = combineLatest(context.sharedContext.presentationData, context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.autodownloadSettings, ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings])) |> deliverOnMainQueue
|> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState<AutodownloadMediaCategoryEntry>, AutodownloadMediaCategoryEntry.ItemGenerationArguments)) in
|> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState, Any)) in
var automaticMediaDownloadSettings: MediaAutoDownloadSettings
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings] as? MediaAutoDownloadSettings {
automaticMediaDownloadSettings = value

View File

@ -258,7 +258,8 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: DataAndStorageControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! DataAndStorageControllerArguments
switch self {
case let .storageUsage(theme, text):
return ItemListDisclosureItem(theme: theme, title: text, label: "", sectionId: self.section, style: .blocks, action: {
@ -564,7 +565,7 @@ func dataAndStorageController(context: AccountContext, focusOnItemTag: DataAndSt
})
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), dataAndStorageDataPromise.get()) |> deliverOnMainQueue
|> map { presentationData, state, dataAndStorageData -> (ItemListControllerState, (ItemListNodeState<DataAndStorageEntry>, DataAndStorageEntry.ItemGenerationArguments)) in
|> map { presentationData, state, dataAndStorageData -> (ItemListControllerState, (ItemListNodeState, Any)) in
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.ChatSettings_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
let listState = ItemListNodeState(entries: dataAndStorageControllerEntries(state: state, data: dataAndStorageData, presentationData: presentationData), style: .blocks, ensureVisibleItemTag: focusOnItemTag, emptyStateItem: nil, animateChanges: false)

View File

@ -253,7 +253,8 @@ private enum NetworkUsageStatsEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: NetworkUsageStatsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! NetworkUsageStatsControllerArguments
switch self {
case let .messagesHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -411,7 +412,7 @@ func networkUsageStatsController(context: AccountContext) -> ViewController {
})
let signal = combineLatest(context.sharedContext.presentationData, section.get(), stats.get()) |> deliverOnMainQueue
|> map { presentationData, section, stats -> (ItemListControllerState, (ItemListNodeState<NetworkUsageStatsEntry>, NetworkUsageStatsEntry.ItemGenerationArguments)) in
|> map { presentationData, section, stats -> (ItemListControllerState, (ItemListNodeState, Any)) in
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .sectionControl([presentationData.strings.NetworkUsageSettings_Cellular, presentationData.strings.NetworkUsageSettings_Wifi], 0), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
let listState = ItemListNodeState(entries: networkUsageStatsControllerEntries(presentationData: presentationData, section: section, stats: stats), style: .blocks, emptyStateItem: nil, animateChanges: false)

View File

@ -200,7 +200,8 @@ private enum ProxySettingsControllerEntry: ItemListNodeEntry {
}
}
func item(_ arguments: ProxySettingsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ProxySettingsControllerArguments
switch self {
case let .enabled(theme, text, value, createsNew):
return ItemListSwitchItem(theme: theme, title: text, value: value, enableInteractiveChanges: !createsNew, enabled: true, sectionId: self.section, style: .blocks, updated: { value in
@ -404,7 +405,7 @@ public func proxySettingsController(accountManager: AccountManager, context: Acc
})
let signal = combineLatest(updatedPresentationData, statePromise.get(), proxySettings.get(), statusesContext.statuses(), network.connectionStatus)
|> map { themeAndStrings, state, proxySettings, statuses, connectionStatus -> (ItemListControllerState, (ItemListNodeState<ProxySettingsControllerEntry>, ProxySettingsControllerEntry.ItemGenerationArguments)) in
|> map { themeAndStrings, state, proxySettings, statuses, connectionStatus -> (ItemListControllerState, (ItemListNodeState, Any)) in
var leftNavigationButton: ItemListNavigationButton?
if case .modal = mode {
leftNavigationButton = ItemListNavigationButton(content: .text(themeAndStrings.strings.Common_Cancel), style: .regular, enabled: true, action: {
@ -450,7 +451,7 @@ public func proxySettingsController(accountManager: AccountManager, context: Acc
dismissImpl = { [weak controller] in
controller?.dismiss()
}
controller.reorderEntry = { fromIndex, toIndex, entries in
controller.setReorderEntry({ (fromIndex: Int, toIndex: Int, entries: [ProxySettingsControllerEntry]) -> Void in
let fromEntry = entries[fromIndex]
guard case let .server(_, _, _, fromServer, _, _, _, _) = fromEntry else {
return
@ -501,7 +502,7 @@ public func proxySettingsController(accountManager: AccountManager, context: Acc
}
return current
}).start()
}
})
shareProxyListImpl = { [weak controller] in
guard let context = context, let strongController = controller else {

View File

@ -116,7 +116,8 @@ private enum ProxySettingsEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: proxyServerSettingsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! proxyServerSettingsControllerArguments
switch self {
case let .usePasteboardSettings(theme, title):
return ItemListActionItem(theme: theme, title: title, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
@ -335,7 +336,7 @@ func proxyServerSettingsController(context: AccountContext? = nil, theme: Presen
let signal = combineLatest(updatedPresentationData, statePromise.get())
|> deliverOnMainQueue
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<ProxySettingsEntry>, ProxySettingsEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()
})

View File

@ -58,7 +58,8 @@ private enum SaveIncomingMediaEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: SaveIncomingMediaControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! SaveIncomingMediaControllerArguments
switch self {
case let .header(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -114,7 +115,7 @@ func saveIncomingMediaController(context: AccountContext) -> ViewController {
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings]))
|> deliverOnMainQueue
|> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState<SaveIncomingMediaEntry>, SaveIncomingMediaEntry.ItemGenerationArguments)) in
|> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState, Any)) in
let automaticMediaDownloadSettings: MediaAutoDownloadSettings
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings] as? MediaAutoDownloadSettings {
automaticMediaDownloadSettings = value

View File

@ -152,7 +152,8 @@ private enum StorageUsageEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: StorageUsageControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! StorageUsageControllerArguments
switch self {
case let .keepMedia(theme, text, value):
return ItemListDisclosureItem(theme: theme, title: text, label: value, sectionId: self.section, style: .blocks, action: {
@ -722,7 +723,7 @@ public func storageUsageController(context: AccountContext, isModal: Bool = fals
var dismissImpl: (() -> Void)?
let signal = combineLatest(context.sharedContext.presentationData, cacheSettingsPromise.get(), statsPromise.get()) |> deliverOnMainQueue
|> map { presentationData, cacheSettings, cacheStats -> (ItemListControllerState, (ItemListNodeState<StorageUsageEntry>, StorageUsageEntry.ItemGenerationArguments)) in
|> map { presentationData, cacheSettings, cacheStats -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = isModal ? ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()
}) : nil

View File

@ -77,7 +77,8 @@ private enum VoiceCallDataSavingEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: VoiceCallDataSavingControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! VoiceCallDataSavingControllerArguments
switch self {
case let .never(theme, text, value):
return ItemListCheckboxItem(theme: theme, title: text, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: {
@ -148,7 +149,7 @@ func voiceCallDataSavingController(context: AccountContext) -> ViewController {
})
let signal = combineLatest(context.sharedContext.presentationData, sharedSettings) |> deliverOnMainQueue
|> map { presentationData, sharedSettings -> (ItemListControllerState, (ItemListNodeState<VoiceCallDataSavingEntry>, VoiceCallDataSavingEntry.ItemGenerationArguments)) in
|> map { presentationData, sharedSettings -> (ItemListControllerState, (ItemListNodeState, Any)) in
let dataSaving = effectiveDataSaving(for: sharedSettings.0, autodownloadSettings: sharedSettings.1)

View File

@ -71,7 +71,8 @@ private enum DebugAccountsControllerEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: DebugAccountsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! DebugAccountsControllerArguments
switch self {
case let .record(theme, record, current):
return ItemListCheckboxItem(theme: theme, title: "\(UInt64(bitPattern: record.id.int64))", style: .left, checked: current, zeroSeparatorInsets: false, sectionId: self.section, action: {
@ -131,7 +132,7 @@ public func debugAccountsController(context: AccountContext, accountManager: Acc
})
let signal = combineLatest(context.sharedContext.presentationData, accountManager.accountRecords())
|> map { presentationData, view -> (ItemListControllerState, (ItemListNodeState<DebugAccountsControllerEntry>, DebugAccountsControllerEntry.ItemGenerationArguments)) in
|> map { presentationData, view -> (ItemListControllerState, (ItemListNodeState, Any)) in
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text("Accounts"), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
let listState = ItemListNodeState(entries: debugAccountsControllerEntries(view: view, presentationData: presentationData), style: .blocks)

View File

@ -148,7 +148,8 @@ private enum DebugControllerEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: DebugControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! DebugControllerArguments
switch self {
case let .sendLogs(theme):
return ItemListDisclosureItem(theme: theme, title: "Send Logs", label: "", sectionId: self.section, style: .blocks, action: {
@ -597,7 +598,7 @@ public func debugController(sharedContext: SharedAccountContext, context: Accoun
}
let signal = combineLatest(sharedContext.presentationData, sharedContext.accountManager.sharedData(keys: Set([SharedDataKeys.loggingSettings, ApplicationSpecificSharedDataKeys.mediaInputSettings, ApplicationSpecificSharedDataKeys.experimentalUISettings])), preferencesSignal)
|> map { presentationData, sharedData, preferences -> (ItemListControllerState, (ItemListNodeState<DebugControllerEntry>, DebugControllerEntry.ItemGenerationArguments)) in
|> map { presentationData, sharedData, preferences -> (ItemListControllerState, (ItemListNodeState, Any)) in
let loggingSettings: LoggingSettings
if let value = sharedData.entries[SharedDataKeys.loggingSettings] as? LoggingSettings {
loggingSettings = value

View File

@ -188,7 +188,8 @@ private enum SettingsEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: EditSettingsItemArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! EditSettingsItemArguments
switch self {
case let .userInfo(theme, strings, dateTimeFormat, peer, cachedData, state, updatingImage):
return ItemListAvatarAndNameInfoItem(account: arguments.context.account, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, mode: .editSettings, peer: peer, presence: TelegramUserPresence(status: .present(until: Int32.max), lastActivity: 0), cachedData: cachedData, state: state, sectionId: ItemListSectionId(self.section), style: .blocks(withTopInset: false, withExtendedBottomInset: false), editingNameUpdated: { editingName in
@ -424,7 +425,7 @@ func editSettingsController(context: AccountContext, currentName: ItemListAvatar
let peerView = context.account.viewTracker.peerView(context.account.peerId)
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), peerView)
|> map { presentationData, state, view -> (ItemListControllerState, (ItemListNodeState<SettingsEntry>, SettingsEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view -> (ItemListControllerState, (ItemListNodeState, Any)) in
let rightNavigationButton: ItemListNavigationButton
if state.updatingName != nil || state.updatingBioText {
rightNavigationButton = ItemListNavigationButton(content: .none, style: .activity, enabled: true, action: {})

View File

@ -70,7 +70,8 @@ private enum LogoutOptionsEntry: ItemListNodeEntry, Equatable {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: LogoutOptionsItemArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! LogoutOptionsItemArguments
switch self {
case let .alternativeHeader(theme, title):
return ItemListSectionHeaderItem(theme: theme, text: title, sectionId: self.section)
@ -225,7 +226,7 @@ func logoutOptionsController(context: AccountContext, navigationController: Navi
context.sharedContext.accountManager.accessChallengeData(),
hasWallets
)
|> map { presentationData, accessChallengeData, hasWallets -> (ItemListControllerState, (ItemListNodeState<LogoutOptionsEntry>, LogoutOptionsEntry.ItemGenerationArguments)) in
|> map { presentationData, accessChallengeData, hasWallets -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()
})

View File

@ -508,7 +508,8 @@ private enum NotificationExceptionEntry : ItemListNodeEntry {
case addException(PresentationTheme, PresentationStrings, NotificationExceptionMode.Mode, Bool)
case removeAll(PresentationTheme, PresentationStrings)
func item(_ arguments: NotificationExceptionArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! NotificationExceptionArguments
switch self {
case let .search(theme, strings):
return NotificationSearchItem(theme: theme, placeholder: strings.Common_Search, activate: {

View File

@ -154,7 +154,8 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
return lhs.index < rhs.index
}
func item(_ arguments: NotificationPeerExceptionArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! NotificationPeerExceptionArguments
switch self {
case let .remove(_, theme, strings):
return ItemListActionItem(theme: theme, title: strings.Notification_Exceptions_RemoveFromExceptions, kind: .generic, alignment: .center, sectionId: self.section, style: .blocks, action: {
@ -362,7 +363,7 @@ func notificationPeerExceptionController(context: AccountContext, peer: Peer, mo
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get() |> distinctUntilChanged)
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<NotificationPeerExceptionEntry>, NotificationPeerExceptionEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
arguments.cancel()
})

View File

@ -569,7 +569,8 @@ private enum NotificationsAndSoundsEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: NotificationsAndSoundsArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! NotificationsAndSoundsArguments
switch self {
case let .accountsHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -1066,7 +1067,7 @@ public func notificationsAndSoundsController(context: AccountContext, exceptions
|> distinctUntilChanged
let signal = combineLatest(context.sharedContext.presentationData, sharedData, preferences, notificationExceptions.get(), DeviceAccess.authorizationStatus(applicationInForeground: context.sharedContext.applicationBindings.applicationInForeground, subject: .notifications), notificationsWarningSuppressed.get(), hasMoreThanOneAccount)
|> map { presentationData, sharedData, view, exceptions, authorizationStatus, warningSuppressed, hasMoreThanOneAccount -> (ItemListControllerState, (ItemListNodeState<NotificationsAndSoundsEntry>, NotificationsAndSoundsEntry.ItemGenerationArguments)) in
|> map { presentationData, sharedData, view, exceptions, authorizationStatus, warningSuppressed, hasMoreThanOneAccount -> (ItemListControllerState, (ItemListNodeState, Any)) in
let viewSettings: GlobalNotificationSettingsSet
if let settings = view.values[PreferencesKeys.globalNotifications] as? GlobalNotificationSettings {

View File

@ -119,7 +119,8 @@ private enum BlockedPeersEntry: ItemListNodeEntry {
}
}
func item(_ arguments: BlockedPeersControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! BlockedPeersControllerArguments
switch self {
case let .add(theme, text):
return ItemListPeerActionItem(theme: theme, icon: PresentationResourcesItemList.addPersonIcon(theme), title: text, sectionId: self.section, editing: false, action: {
@ -265,7 +266,7 @@ public func blockedPeersController(context: AccountContext, blockedPeersContext:
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), blockedPeersContext.state)
|> deliverOnMainQueue
|> map { presentationData, state, blockedPeersState -> (ItemListControllerState, (ItemListNodeState<BlockedPeersEntry>, BlockedPeersEntry.ItemGenerationArguments)) in
|> map { presentationData, state, blockedPeersState -> (ItemListControllerState, (ItemListNodeState, Any)) in
var rightNavigationButton: ItemListNavigationButton?
if !blockedPeersState.peers.isEmpty {
if state.editing {

View File

@ -81,7 +81,8 @@ private enum ConfirmPhoneNumberCodeEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: ConfirmPhoneNumberCodeControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ConfirmPhoneNumberCodeControllerArguments
switch self {
case let .codeEntry(theme, strings, title, text):
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: title, textColor: .black), text: text, placeholder: "", type: .number, spacing: 10.0, tag: ConfirmPhoneNumberCodeTag.input, sectionId: self.section, textUpdated: { updatedText in
@ -157,10 +158,10 @@ protocol ConfirmPhoneNumberCodeController: class {
func applyCode(_ code: Int)
}
private final class ConfirmPhoneNumberCodeControllerImpl: ItemListController<ConfirmPhoneNumberCodeEntry>, ConfirmPhoneNumberCodeController {
private final class ConfirmPhoneNumberCodeControllerImpl: ItemListController, ConfirmPhoneNumberCodeController {
private let applyCodeImpl: (Int) -> Void
init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState<ConfirmPhoneNumberCodeEntry>, ConfirmPhoneNumberCodeEntry.ItemGenerationArguments)), NoError>, applyCodeImpl: @escaping (Int) -> Void) {
init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, Any)), NoError>, applyCodeImpl: @escaping (Int) -> Void) {
self.applyCodeImpl = applyCodeImpl
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
@ -289,7 +290,7 @@ public func confirmPhoneNumberCodeController(context: AccountContext, phoneNumbe
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get() |> deliverOnMainQueue, currentDataPromise.get() |> deliverOnMainQueue, timeout.get() |> deliverOnMainQueue)
|> deliverOnMainQueue
|> map { presentationData, state, data, timeout -> (ItemListControllerState, (ItemListNodeState<ConfirmPhoneNumberCodeEntry>, ConfirmPhoneNumberCodeEntry.ItemGenerationArguments)) in
|> map { presentationData, state, data, timeout -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()
})

View File

@ -115,7 +115,8 @@ private enum CreatePasswordEntry: ItemListNodeEntry, Equatable {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: CreatePasswordControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! CreatePasswordControllerArguments
switch self {
case let .passwordHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -372,7 +373,7 @@ func createPasswordController(context: AccountContext, createPasswordContext: Cr
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get())
|> deliverOnMainQueue
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<CreatePasswordEntry>, CreatePasswordEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()
})

View File

@ -206,7 +206,8 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: DataPrivacyControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! DataPrivacyControllerArguments
switch self {
case let .contactsHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -490,7 +491,7 @@ public func dataPrivacyController(context: AccountContext) -> ViewController {
actionsDisposable.add(managedUpdatedRecentPeers(accountPeerId: context.account.peerId, postbox: context.account.postbox, network: context.account.network).start())
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.secretChatLinkPreviewsKey()), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.contactSynchronizationSettings]), context.account.postbox.preferencesView(keys: [PreferencesKeys.contactsSettings]), recentPeers(account: context.account))
|> map { presentationData, state, noticeView, sharedData, preferences, recentPeers -> (ItemListControllerState, (ItemListNodeState<PrivacyAndSecurityEntry>, PrivacyAndSecurityEntry.ItemGenerationArguments)) in
|> map { presentationData, state, noticeView, sharedData, preferences, recentPeers -> (ItemListControllerState, (ItemListNodeState, Any)) in
let secretChatLinkPreviews = noticeView.value.flatMap({ ApplicationSpecificNotice.getSecretChatLinkPreviews($0) })
let settings: ContactsSettings = preferences.values[PreferencesKeys.contactsSettings] as? ContactsSettings ?? ContactsSettings.defaultSettings

View File

@ -104,7 +104,8 @@ private enum PasscodeOptionsEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: PasscodeOptionsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! PasscodeOptionsControllerArguments
switch self {
case let .togglePasscode(theme, title, value):
return ItemListActionItem(theme: theme, title: title, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
@ -358,7 +359,7 @@ func passcodeOptionsController(context: AccountContext) -> ViewController {
})
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), passcodeOptionsDataPromise.get()) |> deliverOnMainQueue
|> map { presentationData, state, passcodeOptionsData -> (ItemListControllerState, (ItemListNodeState<PasscodeOptionsEntry>, PasscodeOptionsEntry.ItemGenerationArguments)) in
|> map { presentationData, state, passcodeOptionsData -> (ItemListControllerState, (ItemListNodeState, Any)) in
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.PasscodeSettings_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
let listState = ItemListNodeState(entries: passcodeOptionsControllerEntries(presentationData: presentationData, state: state, passcodeOptionsData: passcodeOptionsData), style: .blocks, emptyStateItem: nil, animateChanges: false)

View File

@ -246,7 +246,8 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: PrivacyAndSecurityControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! PrivacyAndSecurityControllerArguments
switch self {
case let .privacyHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -729,7 +730,7 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
}))
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), privacySettingsPromise.get(), context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.secretChatLinkPreviewsKey()), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.contactSynchronizationSettings]), recentPeers(account: context.account), blockedPeersContext.state, activeSessionsContext.state, context.sharedContext.accountManager.accessChallengeData(), twoStepAuthDataValue.get())
|> map { presentationData, state, privacySettings, noticeView, sharedData, recentPeers, blockedPeersState, activeSessionsState, accessChallengeData, twoStepAuthData -> (ItemListControllerState, (ItemListNodeState<PrivacyAndSecurityEntry>, PrivacyAndSecurityEntry.ItemGenerationArguments)) in
|> map { presentationData, state, privacySettings, noticeView, sharedData, recentPeers, blockedPeersState, activeSessionsState, accessChallengeData, twoStepAuthData -> (ItemListControllerState, (ItemListNodeState, Any)) in
var rightNavigationButton: ItemListNavigationButton?
if privacySettings == nil || state.updatingAccountTimeoutValue != nil {
rightNavigationButton = ItemListNavigationButton(content: .none, style: .activity, enabled: true, action: {})

View File

@ -238,7 +238,8 @@ private enum RecentSessionsEntry: ItemListNodeEntry {
}
}
func item(_ arguments: RecentSessionsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! RecentSessionsControllerArguments
switch self {
case let .currentSessionHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -581,7 +582,7 @@ public func recentSessionsController(context: AccountContext, activeSessionsCont
let signal = combineLatest(context.sharedContext.presentationData, mode.get(), statePromise.get(), activeSessionsContext.state, websitesPromise.get())
|> deliverOnMainQueue
|> map { presentationData, mode, state, sessionsState, websitesAndPeers -> (ItemListControllerState, (ItemListNodeState<RecentSessionsEntry>, RecentSessionsEntry.ItemGenerationArguments)) in
|> map { presentationData, mode, state, sessionsState, websitesAndPeers -> (ItemListControllerState, (ItemListNodeState, Any)) in
var rightNavigationButton: ItemListNavigationButton?
let websites = websitesAndPeers?.0
let peers = websitesAndPeers?.1

View File

@ -343,7 +343,8 @@ private enum SelectivePrivacySettingsEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: SelectivePrivacySettingsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! SelectivePrivacySettingsControllerArguments
switch self {
case let .forwardsPreviewHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, multiline: true, sectionId: self.section)
@ -932,7 +933,7 @@ func selectivePrivacySettingsController(context: AccountContext, kind: Selective
}
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), peerName) |> deliverOnMainQueue
|> map { presentationData, state, peerName -> (ItemListControllerState, (ItemListNodeState<SelectivePrivacySettingsEntry>, SelectivePrivacySettingsEntry.ItemGenerationArguments)) in
|> map { presentationData, state, peerName -> (ItemListControllerState, (ItemListNodeState, Any)) in
let title: String
switch kind {

View File

@ -146,7 +146,8 @@ private enum SelectivePrivacyPeersEntry: ItemListNodeEntry {
}
}
func item(_ arguments: SelectivePrivacyPeersControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! SelectivePrivacyPeersControllerArguments
switch self {
case let .peerItem(_, theme, strings, dateTimeFormat, nameDisplayOrder, peer, editing, enabled):
var text: ItemListPeerItemText = .none
@ -349,7 +350,7 @@ public func selectivePrivacyPeersController(context: AccountContext, title: Stri
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), peersPromise.get())
|> deliverOnMainQueue
|> map { presentationData, state, peers -> (ItemListControllerState, (ItemListNodeState<SelectivePrivacyPeersEntry>, SelectivePrivacyPeersEntry.ItemGenerationArguments)) in
|> map { presentationData, state, peers -> (ItemListControllerState, (ItemListNodeState, Any)) in
var rightNavigationButton: ItemListNavigationButton?
if !peers.isEmpty {
if state.editing {

View File

@ -118,7 +118,8 @@ private enum TwoStepVerificationPasswordEntryEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: TwoStepVerificationPasswordEntryControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! TwoStepVerificationPasswordEntryControllerArguments
switch self {
case let .passwordEntryTitle(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -393,7 +394,7 @@ func twoStepVerificationPasswordEntryController(context: AccountContext, mode: T
})
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get()) |> deliverOnMainQueue
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<TwoStepVerificationPasswordEntryEntry>, TwoStepVerificationPasswordEntryEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()

View File

@ -83,7 +83,8 @@ private enum TwoStepVerificationResetEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: TwoStepVerificationResetControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! TwoStepVerificationResetControllerArguments
switch self {
case let .codeEntry(theme, strings, placeholder, text):
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: placeholder, textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: "", type: .password, spacing: 10.0, tag: TwoStepVerificationResetTag.input, sectionId: self.section, textUpdated: { updatedText in
@ -201,7 +202,7 @@ func twoStepVerificationResetController(context: AccountContext, emailPattern: S
})
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get()) |> deliverOnMainQueue
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<TwoStepVerificationResetEntry>, TwoStepVerificationResetEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()

View File

@ -119,7 +119,8 @@ private enum TwoStepVerificationUnlockSettingsEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: TwoStepVerificationUnlockSettingsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! TwoStepVerificationUnlockSettingsControllerArguments
switch self {
case let .passwordEntry(theme, strings, text, value):
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: text, textColor: theme.list.itemPrimaryTextColor), text: value, placeholder: "", type: .password, spacing: 10.0, tag: TwoStepVerificationUnlockSettingsEntryTag.password, sectionId: self.section, textUpdated: { updatedText in
@ -759,7 +760,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode:
var didAppear = false
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), dataPromise.get() |> deliverOnMainQueue) |> deliverOnMainQueue
|> map { presentationData, state, data -> (ItemListControllerState, (ItemListNodeState<TwoStepVerificationUnlockSettingsEntry>, TwoStepVerificationUnlockSettingsEntry.ItemGenerationArguments)) in
|> map { presentationData, state, data -> (ItemListControllerState, (ItemListNodeState, Any)) in
var rightNavigationButton: ItemListNavigationButton?
var emptyStateItem: ItemListControllerEmptyStateItem?
let title: String

View File

@ -61,7 +61,7 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
}
}
private enum SettingsEntryTag: Equatable, ItemListItemTag {
private indirect enum SettingsEntryTag: Equatable, ItemListItemTag {
case account(AccountRecordId)
func isEqual(to other: ItemListItemTag) -> Bool {
@ -73,7 +73,7 @@ private enum SettingsEntryTag: Equatable, ItemListItemTag {
}
}
private struct SettingsItemArguments {
private final class SettingsItemArguments {
let accountManager: AccountManager
let avatarAndNameInfoContext: ItemListAvatarAndNameInfoItemContext
@ -105,6 +105,72 @@ private struct SettingsItemArguments {
let keepPhone: () -> Void
let openPhoneNumberChange: () -> Void
let accountContextAction: (AccountRecordId, ASDisplayNode, ContextGesture?) -> Void
init(
accountManager: AccountManager,
avatarAndNameInfoContext: ItemListAvatarAndNameInfoItemContext,
avatarTapAction: @escaping () -> Void,
changeProfilePhoto: @escaping () -> Void,
openUsername: @escaping () -> Void,
openProxy: @escaping () -> Void,
openSavedMessages: @escaping () -> Void,
openRecentCalls: @escaping () -> Void,
openPrivacyAndSecurity: @escaping (AccountPrivacySettings?) -> Void,
openDataAndStorage: @escaping () -> Void,
openStickerPacks: @escaping ([ArchivedStickerPackItem]?) -> Void,
openNotificationsAndSounds: @escaping (NotificationExceptionsList?) -> Void,
openThemes: @escaping () -> Void,
pushController: @escaping (ViewController) -> Void,
openLanguage: @escaping () -> Void,
openPassport: @escaping () -> Void,
openWallet: @escaping () -> Void,
openWatch: @escaping () -> Void,
openSupport: @escaping () -> Void,
openFaq: @escaping (String?) -> Void,
openEditing: @escaping () -> Void,
displayCopyContextMenu: @escaping () -> Void,
switchToAccount: @escaping (AccountRecordId) -> Void,
addAccount: @escaping () -> Void,
setAccountIdWithRevealedOptions: @escaping (AccountRecordId?, AccountRecordId?) -> Void,
removeAccount: @escaping (AccountRecordId) -> Void,
keepPhone: @escaping () -> Void,
openPhoneNumberChange: @escaping () -> Void,
accountContextAction: @escaping (AccountRecordId, ASDisplayNode, ContextGesture?) -> Void
) {
self.accountManager = accountManager
self.avatarAndNameInfoContext = avatarAndNameInfoContext
self.avatarTapAction = avatarTapAction
self.changeProfilePhoto = changeProfilePhoto
self.openUsername = openUsername
self.openProxy = openProxy
self.openSavedMessages = openSavedMessages
self.openRecentCalls = openRecentCalls
self.openPrivacyAndSecurity = openPrivacyAndSecurity
self.openDataAndStorage = openDataAndStorage
self.openStickerPacks = openStickerPacks
self.openNotificationsAndSounds = openNotificationsAndSounds
self.openThemes = openThemes
self.pushController = pushController
self.openLanguage = openLanguage
self.openPassport = openPassport
self.openWallet = openWallet
self.openWatch = openWatch
self.openSupport = openSupport
self.openFaq = openFaq
self.openEditing = openEditing
self.displayCopyContextMenu = displayCopyContextMenu
self.switchToAccount = switchToAccount
self.addAccount = addAccount
self.setAccountIdWithRevealedOptions = setAccountIdWithRevealedOptions
self.removeAccount = removeAccount
self.keepPhone = keepPhone
self.openPhoneNumberChange = openPhoneNumberChange
self.accountContextAction = accountContextAction
}
}
private enum SettingsSection: Int32 {
@ -118,7 +184,7 @@ private enum SettingsSection: Int32 {
case help
}
private enum SettingsEntry: ItemListNodeEntry {
private indirect enum SettingsEntry: ItemListNodeEntry {
case userInfo(Account, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer?, CachedPeerData?, ItemListAvatarAndNameInfoItemState, ItemListAvatarAndNameInfoItemUpdatingAvatar?)
case setProfilePhoto(PresentationTheme, String)
case setUsername(PresentationTheme, String)
@ -391,7 +457,8 @@ private enum SettingsEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: SettingsItemArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! SettingsItemArguments
switch self {
case let .userInfo(account, theme, strings, dateTimeFormat, peer, cachedData, state, updatingImage):
return ItemListAvatarAndNameInfoItem(account: account, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, mode: .settings, peer: peer, presence: TelegramUserPresence(status: .present(until: Int32.max), lastActivity: 0), cachedData: cachedData, state: state, sectionId: ItemListSectionId(self.section), style: .blocks(withTopInset: false, withExtendedBottomInset: false), editingNameUpdated: { _ in
@ -596,7 +663,7 @@ public protocol SettingsController: class {
func updateContext(context: AccountContext)
}
private final class SettingsControllerImpl: ItemListController<SettingsEntry>, SettingsController, TabBarContainedController {
private final class SettingsControllerImpl: ItemListController, SettingsController, TabBarContainedController {
let sharedContext: SharedAccountContext
let contextValue: Promise<AccountContext>
var accountsAndPeersValue: ((Account, Peer)?, [(Account, Peer, Int32)])?
@ -611,7 +678,7 @@ private final class SettingsControllerImpl: ItemListController<SettingsEntry>, S
return false
}
init(currentContext: AccountContext, contextValue: Promise<AccountContext>, state: Signal<(ItemListControllerState, (ItemListNodeState<SettingsEntry>, SettingsEntry.ItemGenerationArguments)), NoError>, tabBarItem: Signal<ItemListControllerTabBarItem, NoError>?, accountsAndPeers: Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError>) {
init(currentContext: AccountContext, contextValue: Promise<AccountContext>, state: Signal<(ItemListControllerState, (ItemListNodeState, Any)), NoError>, tabBarItem: Signal<ItemListControllerTabBarItem, NoError>?, accountsAndPeers: Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError>) {
self.sharedContext = currentContext.sharedContext
self.contextValue = contextValue
let presentationData = currentContext.sharedContext.currentPresentationData.with { $0 }
@ -1221,7 +1288,7 @@ public func settingsController(context: AccountContext, accountManager: AccountM
}
let signal = combineLatest(queue: Queue.mainQueue(), contextValue.get(), updatedPresentationData, statePromise.get(), peerView, combineLatest(queue: Queue.mainQueue(), preferences, notifyExceptions.get(), notificationsAuthorizationStatus.get(), notificationsWarningSuppressed.get(), privacySettings.get(), displayPhoneNumberConfirmation.get()), combineLatest(featuredStickerPacks, archivedPacks.get()), combineLatest(hasWallet, hasPassport.get(), hasWatchApp.get()), accountsAndPeers.get())
|> map { context, presentationData, state, view, preferencesAndExceptions, featuredAndArchived, hasWalletPassportAndWatch, accountsAndPeers -> (ItemListControllerState, (ItemListNodeState<SettingsEntry>, SettingsEntry.ItemGenerationArguments)) in
|> map { context, presentationData, state, view, preferencesAndExceptions, featuredAndArchived, hasWalletPassportAndWatch, accountsAndPeers -> (ItemListControllerState, (ItemListNodeState, Any)) in
let proxySettings: ProxySettings = preferencesAndExceptions.0.entries[SharedDataKeys.proxySettings] as? ProxySettings ?? ProxySettings.defaultSettings
let inAppNotificationSettings: InAppNotificationSettings = preferencesAndExceptions.0.entries[ApplicationSpecificSharedDataKeys.inAppNotificationSettings] as? InAppNotificationSettings ?? InAppNotificationSettings.defaultSettings
let experimentalUISettings: ExperimentalUISettings = preferencesAndExceptions.0.entries[ApplicationSpecificSharedDataKeys.experimentalUISettings] as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings

View File

@ -152,7 +152,8 @@ private enum ArchivedStickerPacksEntry: ItemListNodeEntry {
}
}
func item(_ arguments: ArchivedStickerPacksControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ArchivedStickerPacksControllerArguments
switch self {
case let .info(theme, text):
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
@ -380,7 +381,7 @@ public func archivedStickerPacksController(context: AccountContext, mode: Archiv
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get() |> deliverOnMainQueue, stickerPacks.get() |> deliverOnMainQueue, installedStickerPacks.get() |> deliverOnMainQueue, context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.stickerSettings]) |> deliverOnMainQueue)
|> deliverOnMainQueue
|> map { presentationData, state, packs, installedView, sharedData -> (ItemListControllerState, (ItemListNodeState<ArchivedStickerPacksEntry>, ArchivedStickerPacksEntry.ItemGenerationArguments)) in
|> map { presentationData, state, packs, installedView, sharedData -> (ItemListControllerState, (ItemListNodeState, Any)) in
var stickerSettings = StickerSettings.defaultSettings
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.stickerSettings] as? StickerSettings {
stickerSettings = value

View File

@ -115,7 +115,8 @@ private enum FeaturedStickerPacksEntry: ItemListNodeEntry {
}
}
func item(_ arguments: FeaturedStickerPacksControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! FeaturedStickerPacksControllerArguments
switch self {
case let .pack(_, theme, strings, info, unread, topItem, count, playAnimatedStickers, installed):
return ItemListStickerPackItem(theme: theme, strings: strings, account: arguments.account, packInfo: info, itemCount: count, topItem: topItem, unread: unread, control: .installation(installed: installed), editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: {
@ -205,7 +206,7 @@ public func featuredStickerPacksController(context: AccountContext) -> ViewContr
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get() |> deliverOnMainQueue, stickerPacks.get() |> deliverOnMainQueue, featured.get() |> deliverOnMainQueue, context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.stickerSettings]) |> deliverOnMainQueue)
|> deliverOnMainQueue
|> map { presentationData, state, view, featured, sharedData -> (ItemListControllerState, (ItemListNodeState<FeaturedStickerPacksEntry>, FeaturedStickerPacksEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view, featured, sharedData -> (ItemListControllerState, (ItemListNodeState, Any)) in
var stickerSettings = StickerSettings.defaultSettings
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.stickerSettings] as? StickerSettings {
stickerSettings = value
@ -238,11 +239,13 @@ public func featuredStickerPacksController(context: AccountContext) -> ViewContr
controller.visibleEntriesUpdated = { entries in
var unreadIds: [ItemCollectionId] = []
for entry in entries {
switch entry {
case let .pack(_, _, _, info, unread, _, _, _, _):
if unread && !alreadyReadIds.contains(info.id) {
unreadIds.append(info.id)
}
if let entry = entry as? FeaturedStickerPacksEntry {
switch entry {
case let .pack(_, _, _, info, unread, _, _, _, _):
if unread && !alreadyReadIds.contains(info.id) {
unreadIds.append(info.id)
}
}
}
}
if !unreadIds.isEmpty {

View File

@ -287,7 +287,8 @@ private enum InstalledStickerPacksEntry: ItemListNodeEntry {
}
}
func item(_ arguments: InstalledStickerPacksControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! InstalledStickerPacksControllerArguments
switch self {
case let .suggestOptions(theme, text, value):
return ItemListDisclosureItem(theme: theme, title: text, label: value, sectionId: self.section, style: .blocks, action: {
@ -580,7 +581,7 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
var previousPackCount: Int?
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), stickerPacks.get(), combineLatest(queue: .mainQueue(), featured.get(), archivedPromise.get()), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.stickerSettings]))
|> deliverOnMainQueue
|> map { presentationData, state, view, featuredAndArchived, sharedData -> (ItemListControllerState, (ItemListNodeState<InstalledStickerPacksEntry>, InstalledStickerPacksEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view, featuredAndArchived, sharedData -> (ItemListControllerState, (ItemListNodeState, Any)) in
var stickerSettings = StickerSettings.defaultSettings
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.stickerSettings] as? StickerSettings {
stickerSettings = value
@ -640,7 +641,7 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
if case .modal = mode {
controller.navigationPresentation = .modal
}
controller.reorderEntry = { fromIndex, toIndex, entries in
controller.setReorderEntry({ (fromIndex: Int, toIndex: Int, entries: [InstalledStickerPacksEntry]) -> Void in
let fromEntry = entries[fromIndex]
guard case let .pack(_, _, _, fromPackInfo, _, _, _, _, _) = fromEntry else {
return
@ -699,7 +700,7 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
transaction.replaceItemCollectionInfos(namespace: namespaceForMode(mode), itemCollectionInfos: infos)
}
}).start()
}
})
presentControllerImpl = { [weak controller] c, p in
if let controller = controller {

View File

@ -130,7 +130,8 @@ private enum EditThemeControllerEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: EditThemeControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! EditThemeControllerArguments
switch self {
case let .title(theme, strings, title, text, _):
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(), text: text, placeholder: title, type: .regular(capitalization: true, autocorrection: false), returnKeyType: .default, clearType: .onFocus, tag: EditThemeEntryTag.title, sectionId: self.section, textUpdated: { value in
@ -331,7 +332,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
})
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), previewThemePromise.get())
|> map { presentationData, state, previewTheme -> (ItemListControllerState, (ItemListNodeState<EditThemeControllerEntry>, EditThemeControllerEntry.ItemGenerationArguments)) in
|> map { presentationData, state, previewTheme -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()
})

View File

@ -187,7 +187,8 @@ private enum ThemeAutoNightSettingsControllerEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: ThemeAutoNightSettingsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ThemeAutoNightSettingsControllerArguments
switch self {
case let .modeDisabled(theme, title, value):
return ItemListCheckboxItem(theme: theme, title: title, style: .left, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: {
@ -533,7 +534,7 @@ public func themeAutoNightSettingsController(context: AccountContext) -> ViewCon
cloudThemes.set(updatedCloudThemes)
let signal = combineLatest(context.sharedContext.presentationData |> deliverOnMainQueue, sharedData |> deliverOnMainQueue, cloudThemes.get() |> deliverOnMainQueue, stagingSettingsPromise.get() |> deliverOnMainQueue)
|> map { presentationData, sharedData, cloudThemes, stagingSettings -> (ItemListControllerState, (ItemListNodeState<ThemeAutoNightSettingsControllerEntry>, ThemeAutoNightSettingsControllerEntry.ItemGenerationArguments)) in
|> map { presentationData, sharedData, cloudThemes, stagingSettings -> (ItemListControllerState, (ItemListNodeState, Any)) in
let settings = (sharedData.entries[ApplicationSpecificSharedDataKeys.presentationThemeSettings] as? PresentationThemeSettings) ?? PresentationThemeSettings.defaultSettings
let defaultThemes: [PresentationThemeReference] = [.builtin(.night), .builtin(.nightAccent)]

View File

@ -269,7 +269,8 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: ThemeSettingsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ThemeSettingsControllerArguments
switch self {
case let .fontSizeHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -543,7 +544,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
})
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationThemeSettings]), cloudThemes.get(), availableAppIcons, currentAppIconName.get())
|> map { presentationData, sharedData, cloudThemes, availableAppIcons, currentAppIconName -> (ItemListControllerState, (ItemListNodeState<ThemeSettingsControllerEntry>, ThemeSettingsControllerEntry.ItemGenerationArguments)) in
|> map { presentationData, sharedData, cloudThemes, availableAppIcons, currentAppIconName -> (ItemListControllerState, (ItemListNodeState, Any)) in
let settings = (sharedData.entries[ApplicationSpecificSharedDataKeys.presentationThemeSettings] as? PresentationThemeSettings) ?? PresentationThemeSettings.defaultSettings
let fontSize = settings.fontSize

View File

@ -89,7 +89,8 @@ private enum UsernameSetupEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: UsernameSetupControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! UsernameSetupControllerArguments
switch self {
case let .editablePublicLink(theme, strings, prefix, currentText, text):
return ItemListSingleLineInputItem(theme: theme, strings: strings, title: NSAttributedString(string: prefix, textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: "", type: .username, spacing: 10.0, clearType: .always, tag: UsernameEntryTag.username, sectionId: self.section, textUpdated: { updatedText in
@ -283,7 +284,7 @@ public func usernameSetupController(context: AccountContext) -> ViewController {
|> deliverOnMainQueue
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get() |> deliverOnMainQueue, peerView)
|> map { presentationData, state, view -> (ItemListControllerState, (ItemListNodeState<UsernameSetupEntry>, UsernameSetupEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view -> (ItemListControllerState, (ItemListNodeState, Any)) in
let peer = peerViewMainPeer(view)
var rightNavigationButton: ItemListNavigationButton?

View File

@ -73,7 +73,8 @@ private enum WatchSettingsControllerEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: WatchSettingsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! WatchSettingsControllerArguments
switch self {
case let .replyPresetsHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -129,7 +130,7 @@ public func watchSettingsController(context: AccountContext) -> ViewController {
let signal = combineLatest(context.sharedContext.presentationData, context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.watchPresetSettings]))
|> deliverOnMainQueue
|> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState<WatchSettingsControllerEntry>, WatchSettingsControllerEntry.ItemGenerationArguments)) in
|> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState, Any)) in
let settings = (sharedData.entries[ApplicationSpecificSharedDataKeys.watchPresetSettings] as? WatchPresetSettings) ?? WatchPresetSettings.defaultSettings
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.AppleWatch_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))

View File

@ -147,7 +147,8 @@ private enum CallFeedbackControllerEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: CallFeedbackControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! CallFeedbackControllerArguments
switch self {
case let .reasonsHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -238,7 +239,7 @@ public func callFeedbackController(sharedContext: SharedAccountContext, account:
let signal = combineLatest(sharedContext.presentationData, statePromise.get())
|> deliverOnMainQueue
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<CallFeedbackControllerEntry>, CallFeedbackControllerEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()
})

View File

@ -204,7 +204,8 @@ private enum ChatRecentActionsFilterEntry: ItemListNodeEntry {
}
}
func item(_ arguments: ChatRecentActionsFilterControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! ChatRecentActionsFilterControllerArguments
switch self {
case let .actionsTitle(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -454,7 +455,7 @@ public func channelRecentActionsFilterController(context: AccountContext, peer:
let signal = combineLatest(presentationDataSignal, statePromise.get(), adminsPromise.get() |> deliverOnMainQueue)
|> deliverOnMainQueue
|> map { presentationData, state, admins -> (ItemListControllerState, (ItemListNodeState<ChatRecentActionsFilterEntry>, ChatRecentActionsFilterEntry.ItemGenerationArguments)) in
|> map { presentationData, state, admins -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()
})

View File

@ -132,7 +132,8 @@ private enum CreateChannelEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: CreateChannelArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! CreateChannelArguments
switch self {
case let .channelInfo(theme, strings, dateTimeFormat, peer, state, avatar):
return ItemListAvatarAndNameInfoItem(account: arguments.account, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, mode: .generic, peer: peer, presence: nil, cachedData: nil, state: state, sectionId: ItemListSectionId(self.section), style: .blocks(withTopInset: false, withExtendedBottomInset: false), editingNameUpdated: { editingName in
@ -357,7 +358,7 @@ public func createChannelController(context: AccountContext) -> ViewController {
})
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get())
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<CreateChannelEntry>, CreateChannelEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let rightNavigationButton: ItemListNavigationButton
if state.creating {

View File

@ -193,7 +193,8 @@ private enum CreateGroupEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: CreateGroupArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! CreateGroupArguments
switch self {
case let .groupInfo(theme, strings, dateTimeFormat, peer, state, avatar):
return ItemListAvatarAndNameInfoItem(account: arguments.account, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, mode: .generic, peer: peer, presence: nil, cachedData: nil, state: state, sectionId: ItemListSectionId(self.section), style: .blocks(withTopInset: false, withExtendedBottomInset: false), editingNameUpdated: { editingName in
@ -584,7 +585,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
})
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), context.account.postbox.multiplePeersView(peerIds), .single(nil) |> then(addressPromise.get()))
|> map { presentationData, state, view, address -> (ItemListControllerState, (ItemListNodeState<CreateGroupEntry>, CreateGroupEntry.ItemGenerationArguments)) in
|> map { presentationData, state, view, address -> (ItemListControllerState, (ItemListNodeState, Any)) in
let rightNavigationButton: ItemListNavigationButton
if state.creating {

View File

@ -66,7 +66,8 @@ private enum UpdateInfoControllerEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: UpdateInfoControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! UpdateInfoControllerArguments
switch self {
case let .info(theme, icon, title, text, entities):
return UpdateInfoItem(theme: theme, appIcon: icon, title: title, text: text, entities: entities, sectionId: self.section, style: .blocks, linkItemAction: { action, itemLink in
@ -106,7 +107,7 @@ public func updateInfoController(context: AccountContext, appUpdateInfo: AppUpda
let signal = context.sharedContext.presentationData
|> deliverOnMainQueue
|> map { presentationData -> (ItemListControllerState, (ItemListNodeState<UpdateInfoControllerEntry>, UpdateInfoControllerEntry.ItemGenerationArguments)) in
|> map { presentationData -> (ItemListControllerState, (ItemListNodeState, Any)) in
let appIcon: PresentationAppIcon?
let appIcons = context.sharedContext.applicationBindings.getAvailableAlternateIcons()
if let alternateIconName = context.sharedContext.applicationBindings.getAlternateIconName() {

View File

@ -174,7 +174,8 @@ private enum WalletCreateInvoiceScreenEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: WalletCreateInvoiceScreenArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! WalletCreateInvoiceScreenArguments
switch self {
case let .amountHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -291,7 +292,7 @@ protocol WalletCreateInvoiceScreen {
}
private final class WalletCreateInvoiceScreenImpl: ItemListController<WalletCreateInvoiceScreenEntry>, WalletCreateInvoiceScreen {
private final class WalletCreateInvoiceScreenImpl: ItemListController, WalletCreateInvoiceScreen {
}
@ -360,7 +361,7 @@ func walletCreateInvoiceScreen(context: AccountContext, address: String) -> View
})
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get())
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<WalletCreateInvoiceScreenEntry>, WalletCreateInvoiceScreenEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
var ensureVisibleItemTag: ItemListItemTag?
if let focusItemTag = state.focusItemTag {
ensureVisibleItemTag = focusItemTag

View File

@ -132,7 +132,8 @@ private enum WalletReceiveScreenEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: WalletReceiveScreenArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! WalletReceiveScreenArguments
switch self {
case let .addressCode(theme, text):
return WalletQrCodeItem(theme: theme, address: text, sectionId: self.section, style: .blocks, action: {
@ -184,7 +185,7 @@ protocol WalletReceiveScreen {
}
private final class WalletReceiveScreenImpl: ItemListController<WalletReceiveScreenEntry>, WalletReceiveScreen {
private final class WalletReceiveScreenImpl: ItemListController, WalletReceiveScreen {
}
@ -220,7 +221,7 @@ func walletReceiveScreen(context: AccountContext, address: String) -> ViewContro
let signal = context.sharedContext.presentationData
|> deliverOnMainQueue
|> map { presentationData -> (ItemListControllerState, (ItemListNodeState<WalletReceiveScreenEntry>, WalletReceiveScreenEntry.ItemGenerationArguments)) in
|> map { presentationData -> (ItemListControllerState, (ItemListNodeState, Any)) in
let rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: true, action: {
dismissImpl?()
})

View File

@ -150,7 +150,8 @@ private enum WalletSendScreenEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: WalletSendScreenArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! WalletSendScreenArguments
switch self {
case let .addressHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
@ -270,7 +271,7 @@ protocol WalletSendScreen {
}
private final class WalletSendScreenImpl: ItemListController<WalletSendScreenEntry>, WalletSendScreen {
private final class WalletSendScreenImpl: ItemListController, WalletSendScreen {
}
@ -468,7 +469,7 @@ public func walletSendScreen(context: AccountContext, tonContext: TonContext, ra
}
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, walletState, statePromise.get())
|> map { presentationData, walletState, state -> (ItemListControllerState, (ItemListNodeState<WalletSendScreenEntry>, WalletSendScreenEntry.ItemGenerationArguments)) in
|> map { presentationData, walletState, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()
})

View File

@ -57,7 +57,8 @@ private enum WalletSettingsEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: WalletSettingsControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! WalletSettingsControllerArguments
switch self {
case let .exportWallet(theme, text):
return ItemListActionItem(theme: theme, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
@ -147,7 +148,7 @@ public func walletSettingsController(context: AccountContext, tonContext: TonCon
})
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get())
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<WalletSettingsEntry>, WalletSettingsEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.Wallet_Settings_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
let listState = ItemListNodeState(entries: walletSettingsControllerEntries(presentationData: presentationData, state: state), style: .blocks, animateChanges: false)

View File

@ -114,7 +114,8 @@ private enum WalletTransactionInfoEntry: ItemListNodeEntry {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: WalletTransactionInfoControllerArguments) -> ListViewItem {
func item(_ arguments: Any) -> ListViewItem {
let arguments = arguments as! WalletTransactionInfoControllerArguments
switch self {
case let .amount(theme, strings, dateTimeFormat, walletTransaction):
return WalletTransactionHeaderItem(theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, walletTransaction: walletTransaction, sectionId: self.section)
@ -325,7 +326,7 @@ func walletTransactionInfoController(context: AccountContext, tonContext: TonCon
})
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get())
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<WalletTransactionInfoEntry>, WalletTransactionInfoEntry.ItemGenerationArguments)) in
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.Wallet_TransactionInfo_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
let listState = ItemListNodeState(entries: walletTransactionInfoControllerEntries(presentationData: presentationData, walletTransaction: walletTransaction, state: state, walletInfo: walletInfo), style: .blocks, animateChanges: false)