From 36c82642d67b1d8309b7ad8e1e30985ba03a5b41 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Sun, 6 Oct 2019 04:25:10 +0400 Subject: [PATCH] Fix ItemListController crash? --- Makefile | 8 +- .../Sources/BotCheckoutControllerNode.swift | 11 +- .../Sources/BotReceiptControllerNode.swift | 11 +- .../Sources/CreatePollController.swift | 9 +- .../Sources/ItemListController.swift | 66 ++++--- .../Sources/ItemListControllerNode.swift | 107 ++++++---- .../MergeLists/Sources/Identifiable.swift | 8 + .../MergeLists/Sources/MergeLists.swift | 184 ++++++++++++++++++ .../Sources/NotificationSoundSelection.swift | 5 +- .../Sources/ResetPasswordController.swift | 5 +- .../Sources/ChannelAdminController.swift | 5 +- .../Sources/ChannelAdminsController.swift | 5 +- .../ChannelBannedMemberController.swift | 5 +- .../Sources/ChannelBlacklistController.swift | 5 +- ...hannelDiscussionGroupSetupController.swift | 5 +- .../Sources/ChannelInfoController.swift | 5 +- .../Sources/ChannelMembersController.swift | 5 +- .../ChannelPermissionsController.swift | 5 +- .../Sources/ChannelVisibilityController.swift | 5 +- .../ConvertToSupergroupController.swift | 5 +- .../Sources/DeviceContactInfoController.swift | 7 +- .../Sources/GroupInfoController.swift | 5 +- .../GroupPreHistorySetupController.swift | 5 +- .../GroupStickerPackSetupController.swift | 5 +- .../Sources/GroupsInCommonController.swift | 5 +- .../Sources/PeerReportController.swift | 5 +- .../Sources/PhoneLabelController.swift | 5 +- .../Sources/UserInfoController.swift | 5 +- .../Sources/PeersNearbyController.swift | 5 +- .../ChangePhoneNumberCodeController.swift | 9 +- ...AutodownloadConnectionTypeController.swift | 5 +- .../AutodownloadMediaCategoryController.swift | 5 +- .../DataAndStorageSettingsController.swift | 5 +- .../NetworkUsageStatsController.swift | 5 +- .../ProxyListSettingsController.swift | 9 +- .../ProxyServerSettingsController.swift | 5 +- .../SaveIncomingMediaController.swift | 5 +- .../StorageUsageController.swift | 5 +- .../VoiceCallDataSavingController.swift | 5 +- .../Sources/DebugAccountsController.swift | 5 +- .../SettingsUI/Sources/DebugController.swift | 5 +- .../Sources/EditSettingsController.swift | 5 +- .../Sources/LogoutOptionsController.swift | 5 +- .../NotificationExceptionControllerNode.swift | 3 +- ...ificationExceptionSettingsController.swift | 5 +- .../NotificationsAndSounds.swift | 5 +- .../BlockedPeersController.swift | 5 +- .../ConfirmPhoneNumberController.swift | 9 +- .../CreatePasswordController.swift | 5 +- .../DataPrivacySettingsController.swift | 5 +- .../PasscodeOptionsController.swift | 5 +- .../PrivacyAndSecurityController.swift | 5 +- .../RecentSessionsController.swift | 5 +- .../SelectivePrivacySettingsController.swift | 5 +- ...ectivePrivacySettingsPeersController.swift | 5 +- ...pVerificationPasswordEntryController.swift | 5 +- .../TwoStepVerificationResetController.swift | 5 +- .../TwoStepVerificationUnlockController.swift | 5 +- .../Sources/SettingsController.swift | 81 +++++++- .../ArchivedStickerPacksController.swift | 5 +- .../FeaturedStickerPacksController.swift | 17 +- .../InstalledStickerPacksController.swift | 9 +- .../Sources/Themes/EditThemeController.swift | 5 +- .../ThemeAutoNightSettingsController.swift | 5 +- .../Themes/ThemeSettingsController.swift | 5 +- .../Sources/UsernameSetupController.swift | 5 +- .../Watch/WatchSettingsController.swift | 5 +- .../Sources/CallFeedbackController.swift | 5 +- .../ChatRecentActionsFilterController.swift | 5 +- .../TelegramUI/CreateChannelController.swift | 5 +- .../TelegramUI/CreateGroupController.swift | 5 +- .../Sources/UpdateInfoController.swift | 5 +- .../Sources/WalletCreateInvoiceScreen.swift | 7 +- .../Sources/WalletReceiveScreen.swift | 7 +- .../WalletUI/Sources/WalletSendScreen.swift | 7 +- .../Sources/WalletSettingsScreen.swift | 5 +- .../Sources/WalletTransactionInfoScreen.swift | 5 +- 77 files changed, 615 insertions(+), 244 deletions(-) diff --git a/Makefile b/Makefile index c754f8e17c..5bd0719094 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/submodules/BotPaymentsUI/Sources/BotCheckoutControllerNode.swift b/submodules/BotPaymentsUI/Sources/BotCheckoutControllerNode.swift index 50dbf9cfd9..554afe1041 100644 --- a/submodules/BotPaymentsUI/Sources/BotCheckoutControllerNode.swift +++ b/submodules/BotPaymentsUI/Sources/BotCheckoutControllerNode.swift @@ -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, 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, private var applePayAuthrorizationCompletion: ((PKPaymentAuthorizationStatus) -> Void)? private var applePayController: PKPaymentAuthorizationViewController? - init(controller: ItemListController?, 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, openShippingMethodImpl?() }) - let signal: Signal<(PresentationTheme, (ItemListNodeState, 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.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)) diff --git a/submodules/BotPaymentsUI/Sources/BotReceiptControllerNode.swift b/submodules/BotPaymentsUI/Sources/BotReceiptControllerNode.swift index b1acd3946a..af19356d93 100644 --- a/submodules/BotPaymentsUI/Sources/BotReceiptControllerNode.swift +++ b/submodules/BotPaymentsUI/Sources/BotReceiptControllerNode.swift @@ -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 { +final class BotReceiptControllerNode: ItemListControllerNode { private let context: AccountContext private let dismissAnimated: () -> Void @@ -264,7 +265,7 @@ final class BotReceiptControllerNode: ItemListControllerNode { private let actionButton: BotCheckoutActionButton - init(controller: ItemListController?, 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 { let arguments = BotReceiptControllerArguments(account: context.account) - let signal: Signal<(PresentationTheme, (ItemListNodeState, BotReceiptEntry.ItemGenerationArguments)), NoError> = combineLatest(context.sharedContext.presentationData, receiptData.get(), context.account.postbox.loadedPeerWithId(messageId.peerId)) - |> map { presentationData, receiptData, botPeer -> (PresentationTheme, (ItemListNodeState, 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)) diff --git a/submodules/ComposePollUI/Sources/CreatePollController.swift b/submodules/ComposePollUI/Sources/CreatePollController.swift index 59df335199..ff84146754 100644 --- a/submodules/ComposePollUI/Sources/CreatePollController.swift +++ b/submodules/ComposePollUI/Sources/CreatePollController.swift @@ -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.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 diff --git a/submodules/ItemListUI/Sources/ItemListController.swift b/submodules/ItemListUI/Sources/ItemListController.swift index 12f2d1dad0..b71842e2d4 100644 --- a/submodules/ItemListUI/Sources/ItemListController.swift +++ b/submodules/ItemListUI/Sources/ItemListController.swift @@ -103,8 +103,8 @@ public struct ItemListControllerState { } } -open class ItemListController: ViewController, KeyShortcutResponder, PresentableController { - private let state: Signal<(ItemListControllerState, (ItemListNodeState, 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: ViewController, KeyShor public var experimentalSnapScrollToItem: Bool = false { didSet { if self.isNodeLoaded { - (self.displayNode as! ItemListControllerNode).listNode.experimentalSnapScrollToItem = self.experimentalSnapScrollToItem + (self.displayNode as! ItemListControllerNode).listNode.experimentalSnapScrollToItem = self.experimentalSnapScrollToItem } } } @@ -143,7 +143,7 @@ open class ItemListController: ViewController, KeyShor public var enableInteractiveDismiss = false { didSet { if self.isNodeLoaded { - (self.displayNode as! ItemListControllerNode).enableInteractiveDismiss = self.enableInteractiveDismiss + (self.displayNode as! ItemListControllerNode).enableInteractiveDismiss = self.enableInteractiveDismiss } } } @@ -151,15 +151,15 @@ open class ItemListController: ViewController, KeyShor public var alwaysSynchronous = false { didSet { if self.isNodeLoaded { - (self.displayNode as! ItemListControllerNode).alwaysSynchronous = self.alwaysSynchronous + (self.displayNode as! ItemListControllerNode).alwaysSynchronous = self.alwaysSynchronous } } } - public var visibleEntriesUpdated: ((ItemListNodeVisibleEntries) -> Void)? { + public var visibleEntriesUpdated: ((ItemListNodeVisibleEntries) -> Void)? { didSet { if self.isNodeLoaded { - (self.displayNode as! ItemListControllerNode).visibleEntriesUpdated = self.visibleEntriesUpdated + (self.displayNode as! ItemListControllerNode).visibleEntriesUpdated = self.visibleEntriesUpdated } } } @@ -167,7 +167,7 @@ open class ItemListController: ViewController, KeyShor public var visibleBottomContentOffsetChanged: ((ListViewVisibleContentOffset) -> Void)? { didSet { if self.isNodeLoaded { - (self.displayNode as! ItemListControllerNode).visibleBottomContentOffsetChanged = self.visibleBottomContentOffsetChanged + (self.displayNode as! ItemListControllerNode).visibleBottomContentOffsetChanged = self.visibleBottomContentOffsetChanged } } } @@ -175,7 +175,7 @@ open class ItemListController: ViewController, KeyShor public var contentOffsetChanged: ((ListViewVisibleContentOffset, Bool) -> Void)? { didSet { if self.isNodeLoaded { - (self.displayNode as! ItemListControllerNode).contentOffsetChanged = self.contentOffsetChanged + (self.displayNode as! ItemListControllerNode).contentOffsetChanged = self.contentOffsetChanged } } } @@ -183,7 +183,7 @@ open class ItemListController: ViewController, KeyShor public var contentScrollingEnded: ((ListView) -> Bool)? { didSet { if self.isNodeLoaded { - (self.displayNode as! ItemListControllerNode).contentScrollingEnded = self.contentScrollingEnded + (self.displayNode as! ItemListControllerNode).contentScrollingEnded = self.contentScrollingEnded } } } @@ -191,17 +191,22 @@ open class ItemListController: ViewController, KeyShor public var searchActivated: ((Bool) -> Void)? { didSet { if self.isNodeLoaded { - (self.displayNode as! ItemListControllerNode).searchActivated = self.searchActivated + (self.displayNode as! ItemListControllerNode).searchActivated = self.searchActivated } } } public var willScrollToTop: (() -> Void)? - public var reorderEntry: ((Int, Int, [Entry]) -> Void)? { + public func setReorderEntry(_ 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).reorderEntry = self.reorderEntry + (self.displayNode as! ItemListControllerNode).reorderEntry = self.reorderEntry } } } @@ -212,17 +217,20 @@ open class ItemListController: ViewController, KeyShor public var willDisappear: ((Bool) -> Void)? public var didDisappear: ((Bool) -> Void)? - convenience public init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, Entry.ItemGenerationArguments)), NoError>, tabBarItem: Signal? = nil) { + convenience public init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, ItemGenerationArguments)), NoError>, tabBarItem: Signal? = nil) { self.init(sharedContext: context.sharedContext, state: state, tabBarItem: tabBarItem) } - convenience public init(sharedContext: SharedAccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, Entry.ItemGenerationArguments)), NoError>, tabBarItem: Signal? = nil) { + convenience public init(sharedContext: SharedAccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, ItemGenerationArguments)), NoError>, tabBarItem: Signal? = 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.ItemGenerationArguments)), NoError>, tabBarItem: Signal?) { + public init(theme: PresentationTheme, strings: PresentationStrings, updatedPresentationData: Signal<(theme: PresentationTheme, strings: PresentationStrings), NoError>, state: Signal<(ItemListControllerState, (ItemListNodeState, ItemGenerationArguments)), NoError>, tabBarItem: Signal?) { 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: ViewController, KeyShor self.scrollToTop = { [weak self] in self?.willScrollToTop?() - (self?.displayNode as! ItemListControllerNode).scrollToTop() + (self?.displayNode as! ItemListControllerNode).scrollToTop() } if let tabBarItem = tabBarItem { @@ -418,7 +426,7 @@ open class ItemListController: ViewController, KeyShor } } } |> map { ($0.theme, $1) } - let displayNode = ItemListControllerNode(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: ViewController, KeyShor } self.displayNode = displayNode super.displayNodeDidLoad() - self._ready.set((self.displayNode as! ItemListControllerNode).ready) + self._ready.set((self.displayNode as! ItemListControllerNode).ready) } override open func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { @@ -448,7 +456,7 @@ open class ItemListController: ViewController, KeyShor self.validLayout = layout - (self.displayNode as! ItemListControllerNode).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: ViewController, KeyShor } public func viewDidAppear(completion: @escaping () -> Void) { - (self.displayNode as! ItemListControllerNode).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).animateIn(completion: { + (self.displayNode as! ItemListControllerNode).animateIn(completion: { presentationArguments.completion?() completion() }) @@ -506,7 +514,7 @@ open class ItemListController: ViewController, KeyShor public func frameForItemNode(_ predicate: (ListViewItemNode) -> Bool) -> CGRect? { var result: CGRect? - (self.displayNode as! ItemListControllerNode).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: ViewController, KeyShor } public func forEachItemNode(_ f: (ListViewItemNode) -> Void) { - (self.displayNode as! ItemListControllerNode).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: ViewController, KeyShor } public func ensureItemNodeVisible(_ itemNode: ListViewItemNode, animated: Bool = true) { - (self.displayNode as! ItemListControllerNode).listNode.ensureItemNodeVisible(itemNode, animated: animated) + (self.displayNode as! ItemListControllerNode).listNode.ensureItemNodeVisible(itemNode, animated: animated) } public func afterLayout(_ f: @escaping () -> Void) { - (self.displayNode as! ItemListControllerNode).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: ViewController, KeyShor } var selectedNode: ItemListItemNode? - let listLocation = self.view.convert(location, to: (self.displayNode as! ItemListControllerNode).listNode.view) - (self.displayNode as! ItemListControllerNode).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: ViewController, KeyShor } public func clearItemNodesHighlight(animated: Bool = false) { - (self.displayNode as! ItemListControllerNode).listNode.clearHighlightAnimated(animated) + (self.displayNode as! ItemListControllerNode).listNode.clearHighlightAnimated(animated) } public func previewingCommit(_ viewControllerToCommit: UIViewController) { diff --git a/submodules/ItemListUI/Sources/ItemListControllerNode.swift b/submodules/ItemListUI/Sources/ItemListControllerNode.swift index 035597133f..3d31f6615e 100644 --- a/submodules/ItemListUI/Sources/ItemListControllerNode.swift +++ b/submodules/ItemListUI/Sources/ItemListControllerNode.swift @@ -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(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 { +private struct ItemListNodeTransition { let theme: PresentationTheme let entries: ItemListNodeEntryTransition let updateStyle: ItemListStyle? @@ -56,12 +79,12 @@ private struct ItemListNodeTransition { let animated: Bool let animateAlpha: Bool let crossfade: Bool - let mergedEntries: [Entry] + let mergedEntries: [ItemListNodeAnyEntry] let scrollEnabled: Bool } -public struct ItemListNodeState { - 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 { 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(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 { } } -private final class ItemListNodeOpaqueState { - let mergedEntries: [Entry] +private final class ItemListNodeOpaqueState { + let mergedEntries: [ItemListNodeAnyEntry] - init(mergedEntries: [Entry]) { + init(mergedEntries: [ItemListNodeAnyEntry]) { self.mergedEntries = mergedEntries } } -public final class ItemListNodeVisibleEntries: 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 { - return AnyIterator { () -> Entry? in + public func makeIterator() -> AnyIterator { + return AnyIterator { () -> ItemListNodeAnyEntry? in return self.iterate() } } } -public final class ItemListControllerNodeView: UITracingLayerView, PreviewingHostView { +public final class ItemListControllerNodeView: UITracingLayerView, PreviewingHostView { var onLayout: (() -> Void)? - init(controller: ItemListController?) { + init(controller: ItemListController?) { self.controller = controller super.init(frame: CGRect()) @@ -149,10 +172,10 @@ public final class ItemListControllerNodeView: UITraci }) } - weak var controller: ItemListController? + weak var controller: ItemListController? } -open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate { +open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate { private var _ready = ValuePromise() open var ready: Signal { return self._ready.get() @@ -172,7 +195,7 @@ open class ItemListControllerNode: ASDisplayNode, UISc private let transitionDisposable = MetaDisposable() - private var enqueuedTransitions: [ItemListNodeTransition] = [] + private var enqueuedTransitions: [ItemListNodeTransition] = [] private var validLayout: (ContainerViewLayout, CGFloat)? private var theme: PresentationTheme? @@ -186,12 +209,12 @@ open class ItemListControllerNode: ASDisplayNode, UISc public let updateNavigationOffset: (CGFloat) -> Void public var dismiss: (() -> Void)? - public var visibleEntriesUpdated: ((ItemListNodeVisibleEntries) -> 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: ASDisplayNode, UISc var alwaysSynchronous = false - public init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, state: Signal<(PresentationTheme, (ItemListNodeState, 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: ASDisplayNode, UISc super.init() self.setViewBlock({ [weak controller] in - return ItemListControllerNodeView(controller: controller) + return ItemListControllerNodeView(controller: controller) }) self.backgroundColor = nil @@ -221,13 +244,13 @@ open class ItemListControllerNode: 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)?.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(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: ASDisplayNode, UISc } self.listNode.reorderItem = { [weak self] fromIndex, toIndex, opaqueTransactionState in - if let strongSelf = self, let reorderEntry = strongSelf.reorderEntry, let mergedEntries = (opaqueTransactionState as? ItemListNodeOpaqueState)?.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: ASDisplayNode, UISc } } - let previousState = Atomic?>(value: nil) - self.transitionDisposable.set(((state |> map { theme, stateAndArguments -> ItemListNodeTransition in + let previousState = Atomic(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: ASDisplayNode, UISc override open func didLoad() { super.didLoad() - (self.view as? ItemListControllerNodeView)?.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: ASDisplayNode, UISc } } - (self.view as? ItemListControllerNodeView)?.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: ASDisplayNode, UISc } } - private func enqueueTransition(_ transition: ItemListNodeTransition) { + private func enqueueTransition(_ transition: ItemListNodeTransition) { self.enqueuedTransitions.append(transition) if self.validLayout != nil { self.dequeueTransitions() diff --git a/submodules/MergeLists/Sources/Identifiable.swift b/submodules/MergeLists/Sources/Identifiable.swift index 0ada7637ed..f45912c178 100644 --- a/submodules/MergeLists/Sources/Identifiable.swift +++ b/submodules/MergeLists/Sources/Identifiable.swift @@ -4,3 +4,11 @@ public protocol Identifiable { associatedtype T: Hashable var stableId: T { get } } + +public struct AnyIdentifiable { + var stableId: AnyHashable + + public init(_ value: T) where T : Identifiable { + self.stableId = value.stableId + } +} diff --git a/submodules/MergeLists/Sources/MergeLists.swift b/submodules/MergeLists/Sources/MergeLists.swift index f5f5c5bb8e..8b2780082e 100644 --- a/submodules/MergeLists/Sources/MergeLists.swift +++ b/submodules/MergeLists/Sources/MergeLists.swift @@ -181,6 +181,190 @@ public func mergeListsStableWithUpdates(leftList: [T], rightList: [T], allUpd return (removeIndices, insertItems, updatedIndices) } +@inlinable +public func mergeListsStableWithUpdates(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)\(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(leftList: [T], rightList: [T], allUpdated: Bool = false) -> ([Int], [(Int, T, Int?)], [(Int, T, Int)]) where T: Comparable, T: Identifiable { var removeIndices: [Int] = [] diff --git a/submodules/NotificationSoundSelectionUI/Sources/NotificationSoundSelection.swift b/submodules/NotificationSoundSelectionUI/Sources/NotificationSoundSelection.swift index 67474328ac..c80321a5b2 100644 --- a/submodules/NotificationSoundSelectionUI/Sources/NotificationSoundSelection.swift +++ b/submodules/NotificationSoundSelectionUI/Sources/NotificationSoundSelection.swift @@ -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.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() diff --git a/submodules/PasswordSetupUI/Sources/ResetPasswordController.swift b/submodules/PasswordSetupUI/Sources/ResetPasswordController.swift index 09050255eb..d120b4a566 100644 --- a/submodules/PasswordSetupUI/Sources/ResetPasswordController.swift +++ b/submodules/PasswordSetupUI/Sources/ResetPasswordController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { dismissImpl?() diff --git a/submodules/PeerInfoUI/Sources/ChannelAdminController.swift b/submodules/PeerInfoUI/Sources/ChannelAdminController.swift index ab55a0c503..3241670210 100644 --- a/submodules/PeerInfoUI/Sources/ChannelAdminController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelAdminController.swift @@ -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.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) diff --git a/submodules/PeerInfoUI/Sources/ChannelAdminsController.swift b/submodules/PeerInfoUI/Sources/ChannelAdminsController.swift index 5f6c4575d5..58225ba45d 100644 --- a/submodules/PeerInfoUI/Sources/ChannelAdminsController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelAdminsController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state, view, admins -> (ItemListControllerState, (ItemListNodeState, Any)) in var rightNavigationButton: ItemListNavigationButton? var secondaryRightNavigationButton: ItemListNavigationButton? if let admins = admins, admins.count > 1 { diff --git a/submodules/PeerInfoUI/Sources/ChannelBannedMemberController.swift b/submodules/PeerInfoUI/Sources/ChannelBannedMemberController.swift index 56d02aaf79..693f53f6f3 100644 --- a/submodules/PeerInfoUI/Sources/ChannelBannedMemberController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelBannedMemberController.swift @@ -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.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? diff --git a/submodules/PeerInfoUI/Sources/ChannelBlacklistController.swift b/submodules/PeerInfoUI/Sources/ChannelBlacklistController.swift index 0d5b25a228..58615df3d7 100644 --- a/submodules/PeerInfoUI/Sources/ChannelBlacklistController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelBlacklistController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state, view, participants -> (ItemListControllerState, (ItemListNodeState, Any)) in var rightNavigationButton: ItemListNavigationButton? var secondaryRightNavigationButton: ItemListNavigationButton? if let participants = participants, !participants.isEmpty { diff --git a/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift b/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift index c01f826dcf..c689f2e26c 100644 --- a/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift @@ -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.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 diff --git a/submodules/PeerInfoUI/Sources/ChannelInfoController.swift b/submodules/PeerInfoUI/Sources/ChannelInfoController.swift index cc40e51e79..fe29d31158 100644 --- a/submodules/PeerInfoUI/Sources/ChannelInfoController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelInfoController.swift @@ -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([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.ItemGenerationArguments)) in + |> map { presentationData, state, view, combinedView -> (ItemListControllerState, (ItemListNodeState, Any)) in let peer = peerViewMainPeer(view) var globalNotificationSettings: GlobalNotificationSettings = GlobalNotificationSettings.defaultSettings diff --git a/submodules/PeerInfoUI/Sources/ChannelMembersController.swift b/submodules/PeerInfoUI/Sources/ChannelMembersController.swift index 3a43d7629d..d06d845cf3 100644 --- a/submodules/PeerInfoUI/Sources/ChannelMembersController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelMembersController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state, view, peers -> (ItemListControllerState, (ItemListNodeState, Any)) in var rightNavigationButton: ItemListNavigationButton? var secondaryRightNavigationButton: ItemListNavigationButton? if let peers = peers, !peers.isEmpty { diff --git a/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift b/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift index 49982247a4..8e4f75ce64 100644 --- a/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state, viewAndParticipants -> (ItemListControllerState, (ItemListNodeState, Any)) in let (view, participants) = viewAndParticipants var rightNavigationButton: ItemListNavigationButton? diff --git a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift index 613a8e61a0..b681b522b0 100644 --- a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state, view, publicChannelsToRevoke -> (ItemListControllerState, (ItemListNodeState, Any)) in let peer = peerViewMainPeer(view) var rightNavigationButton: ItemListNavigationButton? diff --git a/submodules/PeerInfoUI/Sources/ConvertToSupergroupController.swift b/submodules/PeerInfoUI/Sources/ConvertToSupergroupController.swift index a8a274cf45..cd43aefc48 100644 --- a/submodules/PeerInfoUI/Sources/ConvertToSupergroupController.swift +++ b/submodules/PeerInfoUI/Sources/ConvertToSupergroupController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in var rightNavigationButton: ItemListNavigationButton? if state.isConverting { diff --git a/submodules/PeerInfoUI/Sources/DeviceContactInfoController.swift b/submodules/PeerInfoUI/Sources/DeviceContactInfoController.swift index 35d3a2d6fd..2eb94165da 100644 --- a/submodules/PeerInfoUI/Sources/DeviceContactInfoController.swift +++ b/submodules/PeerInfoUI/Sources/DeviceContactInfoController.swift @@ -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, 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?>(value: nil) let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), contactData) - |> map { presentationData, state, peerAndContactData -> (ItemListControllerState, (ItemListNodeState, DeviceContactInfoEntry.ItemGenerationArguments)) in + |> map { presentationData, state, peerAndContactData -> (ItemListControllerState, (ItemListNodeState, Any)) in var leftNavigationButton: ItemListNavigationButton? switch subject { case .vcard: diff --git a/submodules/PeerInfoUI/Sources/GroupInfoController.swift b/submodules/PeerInfoUI/Sources/GroupInfoController.swift index af05be151b..89d17fa041 100644 --- a/submodules/PeerInfoUI/Sources/GroupInfoController.swift +++ b/submodules/PeerInfoUI/Sources/GroupInfoController.swift @@ -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([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.ItemGenerationArguments)) in + |> map { presentationData, state, view, combinedView, channelMembers -> (ItemListControllerState, (ItemListNodeState, Any)) in let peer = peerViewMainPeer(view) var globalNotificationSettings: GlobalNotificationSettings = GlobalNotificationSettings.defaultSettings diff --git a/submodules/PeerInfoUI/Sources/GroupPreHistorySetupController.swift b/submodules/PeerInfoUI/Sources/GroupPreHistorySetupController.swift index 4e90bbc0d6..58cf27799f 100644 --- a/submodules/PeerInfoUI/Sources/GroupPreHistorySetupController.swift +++ b/submodules/PeerInfoUI/Sources/GroupPreHistorySetupController.swift @@ -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.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?() diff --git a/submodules/PeerInfoUI/Sources/GroupStickerPackSetupController.swift b/submodules/PeerInfoUI/Sources/GroupStickerPackSetupController.swift index 3fc8a425ee..6823f6ad42 100644 --- a/submodules/PeerInfoUI/Sources/GroupStickerPackSetupController.swift +++ b/submodules/PeerInfoUI/Sources/GroupStickerPackSetupController.swift @@ -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(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.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 diff --git a/submodules/PeerInfoUI/Sources/GroupsInCommonController.swift b/submodules/PeerInfoUI/Sources/GroupsInCommonController.swift index 07204dd178..fcf4760b38 100644 --- a/submodules/PeerInfoUI/Sources/GroupsInCommonController.swift +++ b/submodules/PeerInfoUI/Sources/GroupsInCommonController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state, peers -> (ItemListControllerState, (ItemListNodeState, Any)) in var emptyStateItem: ItemListControllerEmptyStateItem? if peers == nil { emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme) diff --git a/submodules/PeerInfoUI/Sources/PeerReportController.swift b/submodules/PeerInfoUI/Sources/PeerReportController.swift index 01261f203e..d898e41625 100644 --- a/submodules/PeerInfoUI/Sources/PeerReportController.swift +++ b/submodules/PeerInfoUI/Sources/PeerReportController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in let rightButton: ItemListNavigationButton if state.isReporting { rightButton = ItemListNavigationButton(content: .none, style: .activity, enabled: true, action: {}) diff --git a/submodules/PeerInfoUI/Sources/PhoneLabelController.swift b/submodules/PeerInfoUI/Sources/PhoneLabelController.swift index 93bf2c7df0..1a4a3cadba 100644 --- a/submodules/PeerInfoUI/Sources/PhoneLabelController.swift +++ b/submodules/PeerInfoUI/Sources/PhoneLabelController.swift @@ -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.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() diff --git a/submodules/PeerInfoUI/Sources/UserInfoController.swift b/submodules/PeerInfoUI/Sources/UserInfoController.swift index ed78567d10..1e5be89fb3 100644 --- a/submodules/PeerInfoUI/Sources/UserInfoController.swift +++ b/submodules/PeerInfoUI/Sources/UserInfoController.swift @@ -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([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.ItemGenerationArguments)) in + |> map { presentationData, state, view, deviceContacts, combinedView -> (ItemListControllerState, (ItemListNodeState, Any)) in let peer = peerViewMainPeer(view.0) var globalNotificationSettings: GlobalNotificationSettings = .defaultSettings diff --git a/submodules/PeersNearbyUI/Sources/PeersNearbyController.swift b/submodules/PeersNearbyUI/Sources/PeersNearbyController.swift index 2080e27999..ccb4759411 100644 --- a/submodules/PeersNearbyUI/Sources/PeersNearbyController.swift +++ b/submodules/PeersNearbyUI/Sources/PeersNearbyController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, data, displayLoading -> (ItemListControllerState, (ItemListNodeState, Any)) in let previous = previousData.swap(data) var crossfade = false diff --git a/submodules/SettingsUI/Sources/ChangePhoneNumberCodeController.swift b/submodules/SettingsUI/Sources/ChangePhoneNumberCodeController.swift index 6eff637800..94016770c4 100644 --- a/submodules/SettingsUI/Sources/ChangePhoneNumberCodeController.swift +++ b/submodules/SettingsUI/Sources/ChangePhoneNumberCodeController.swift @@ -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, ChangePhoneNumberCodeController { +private final class ChangePhoneNumberCodeControllerImpl: ItemListController, ChangePhoneNumberCodeController { private let applyCodeImpl: (Int) -> Void - init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, 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.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: {}) diff --git a/submodules/SettingsUI/Sources/Data and Storage/AutodownloadConnectionTypeController.swift b/submodules/SettingsUI/Sources/Data and Storage/AutodownloadConnectionTypeController.swift index 55de889ed6..c090fbfc20 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/AutodownloadConnectionTypeController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/AutodownloadConnectionTypeController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState, Any)) in var automaticMediaDownloadSettings: MediaAutoDownloadSettings if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings] as? MediaAutoDownloadSettings { automaticMediaDownloadSettings = value diff --git a/submodules/SettingsUI/Sources/Data and Storage/AutodownloadMediaCategoryController.swift b/submodules/SettingsUI/Sources/Data and Storage/AutodownloadMediaCategoryController.swift index bc7d4d64fe..4f1986aed4 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/AutodownloadMediaCategoryController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/AutodownloadMediaCategoryController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState, Any)) in var automaticMediaDownloadSettings: MediaAutoDownloadSettings if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings] as? MediaAutoDownloadSettings { automaticMediaDownloadSettings = value diff --git a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift index 24cd66d65d..e175018ab0 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift @@ -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.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) diff --git a/submodules/SettingsUI/Sources/Data and Storage/NetworkUsageStatsController.swift b/submodules/SettingsUI/Sources/Data and Storage/NetworkUsageStatsController.swift index a5411c50b9..1d84317953 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/NetworkUsageStatsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/NetworkUsageStatsController.swift @@ -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.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) diff --git a/submodules/SettingsUI/Sources/Data and Storage/ProxyListSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/ProxyListSettingsController.swift index 27b52d4783..bebd008b71 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/ProxyListSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/ProxyListSettingsController.swift @@ -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.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 { diff --git a/submodules/SettingsUI/Sources/Data and Storage/ProxyServerSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/ProxyServerSettingsController.swift index be49498b21..561dc3fabf 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/ProxyServerSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/ProxyServerSettingsController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { dismissImpl?() }) diff --git a/submodules/SettingsUI/Sources/Data and Storage/SaveIncomingMediaController.swift b/submodules/SettingsUI/Sources/Data and Storage/SaveIncomingMediaController.swift index ce3624239a..9f9757c921 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/SaveIncomingMediaController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/SaveIncomingMediaController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState, Any)) in let automaticMediaDownloadSettings: MediaAutoDownloadSettings if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings] as? MediaAutoDownloadSettings { automaticMediaDownloadSettings = value diff --git a/submodules/SettingsUI/Sources/Data and Storage/StorageUsageController.swift b/submodules/SettingsUI/Sources/Data and Storage/StorageUsageController.swift index 4587623003..462f10ec6a 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/StorageUsageController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/StorageUsageController.swift @@ -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.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 diff --git a/submodules/SettingsUI/Sources/Data and Storage/VoiceCallDataSavingController.swift b/submodules/SettingsUI/Sources/Data and Storage/VoiceCallDataSavingController.swift index 5acb97b20e..16598eb138 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/VoiceCallDataSavingController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/VoiceCallDataSavingController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, sharedSettings -> (ItemListControllerState, (ItemListNodeState, Any)) in let dataSaving = effectiveDataSaving(for: sharedSettings.0, autodownloadSettings: sharedSettings.1) diff --git a/submodules/SettingsUI/Sources/DebugAccountsController.swift b/submodules/SettingsUI/Sources/DebugAccountsController.swift index 511c5405c5..854d120840 100644 --- a/submodules/SettingsUI/Sources/DebugAccountsController.swift +++ b/submodules/SettingsUI/Sources/DebugAccountsController.swift @@ -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.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) diff --git a/submodules/SettingsUI/Sources/DebugController.swift b/submodules/SettingsUI/Sources/DebugController.swift index 481aa9112e..37a46d4f78 100644 --- a/submodules/SettingsUI/Sources/DebugController.swift +++ b/submodules/SettingsUI/Sources/DebugController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, sharedData, preferences -> (ItemListControllerState, (ItemListNodeState, Any)) in let loggingSettings: LoggingSettings if let value = sharedData.entries[SharedDataKeys.loggingSettings] as? LoggingSettings { loggingSettings = value diff --git a/submodules/SettingsUI/Sources/EditSettingsController.swift b/submodules/SettingsUI/Sources/EditSettingsController.swift index 05cecda448..a901ac805a 100644 --- a/submodules/SettingsUI/Sources/EditSettingsController.swift +++ b/submodules/SettingsUI/Sources/EditSettingsController.swift @@ -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.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: {}) diff --git a/submodules/SettingsUI/Sources/LogoutOptionsController.swift b/submodules/SettingsUI/Sources/LogoutOptionsController.swift index e4d88e7819..ee6837e224 100644 --- a/submodules/SettingsUI/Sources/LogoutOptionsController.swift +++ b/submodules/SettingsUI/Sources/LogoutOptionsController.swift @@ -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.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?() }) diff --git a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift index aedb943eeb..da68d00569 100644 --- a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift +++ b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift @@ -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: { diff --git a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionSettingsController.swift b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionSettingsController.swift index a0d223bf0c..df50cd7b2b 100644 --- a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionSettingsController.swift +++ b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionSettingsController.swift @@ -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.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() }) diff --git a/submodules/SettingsUI/Sources/Notifications/NotificationsAndSounds.swift b/submodules/SettingsUI/Sources/Notifications/NotificationsAndSounds.swift index 42b87d5796..78766952bb 100644 --- a/submodules/SettingsUI/Sources/Notifications/NotificationsAndSounds.swift +++ b/submodules/SettingsUI/Sources/Notifications/NotificationsAndSounds.swift @@ -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.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 { diff --git a/submodules/SettingsUI/Sources/Privacy and Security/BlockedPeersController.swift b/submodules/SettingsUI/Sources/Privacy and Security/BlockedPeersController.swift index c8454f1466..2dc0cc1eb3 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/BlockedPeersController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/BlockedPeersController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state, blockedPeersState -> (ItemListControllerState, (ItemListNodeState, Any)) in var rightNavigationButton: ItemListNavigationButton? if !blockedPeersState.peers.isEmpty { if state.editing { diff --git a/submodules/SettingsUI/Sources/Privacy and Security/ConfirmPhoneNumberController.swift b/submodules/SettingsUI/Sources/Privacy and Security/ConfirmPhoneNumberController.swift index aba918c2e4..9a95de25f4 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/ConfirmPhoneNumberController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/ConfirmPhoneNumberController.swift @@ -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, ConfirmPhoneNumberCodeController { +private final class ConfirmPhoneNumberCodeControllerImpl: ItemListController, ConfirmPhoneNumberCodeController { private let applyCodeImpl: (Int) -> Void - init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, 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.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?() }) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/CreatePasswordController.swift b/submodules/SettingsUI/Sources/Privacy and Security/CreatePasswordController.swift index 44c6af26fa..907cd2778c 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/CreatePasswordController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/CreatePasswordController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { dismissImpl?() }) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/DataPrivacySettingsController.swift b/submodules/SettingsUI/Sources/Privacy and Security/DataPrivacySettingsController.swift index 967275c080..a32c07e346 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/DataPrivacySettingsController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/DataPrivacySettingsController.swift @@ -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.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 diff --git a/submodules/SettingsUI/Sources/Privacy and Security/PasscodeOptionsController.swift b/submodules/SettingsUI/Sources/Privacy and Security/PasscodeOptionsController.swift index 0ee6f5e19d..f01063fc67 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/PasscodeOptionsController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/PasscodeOptionsController.swift @@ -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.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) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift index 9e11f0dcfc..36827a4bbd 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift @@ -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.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: {}) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsController.swift b/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsController.swift index 3698fc572e..4ac75f487d 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, mode, state, sessionsState, websitesAndPeers -> (ItemListControllerState, (ItemListNodeState, Any)) in var rightNavigationButton: ItemListNavigationButton? let websites = websitesAndPeers?.0 let peers = websitesAndPeers?.1 diff --git a/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift b/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift index 6d73f31413..91647f85da 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state, peerName -> (ItemListControllerState, (ItemListNodeState, Any)) in let title: String switch kind { diff --git a/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsPeersController.swift b/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsPeersController.swift index 9d21882e34..041e9c2531 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsPeersController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsPeersController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state, peers -> (ItemListControllerState, (ItemListNodeState, Any)) in var rightNavigationButton: ItemListNavigationButton? if !peers.isEmpty { if state.editing { diff --git a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationPasswordEntryController.swift b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationPasswordEntryController.swift index 73962fe325..cf1b880b31 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationPasswordEntryController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationPasswordEntryController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { dismissImpl?() diff --git a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationResetController.swift b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationResetController.swift index 0c254f2f28..5ba7bd68ed 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationResetController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationResetController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { dismissImpl?() diff --git a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationUnlockController.swift b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationUnlockController.swift index e3bb7edafd..97affadd28 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationUnlockController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationUnlockController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state, data -> (ItemListControllerState, (ItemListNodeState, Any)) in var rightNavigationButton: ItemListNavigationButton? var emptyStateItem: ItemListControllerEmptyStateItem? let title: String diff --git a/submodules/SettingsUI/Sources/SettingsController.swift b/submodules/SettingsUI/Sources/SettingsController.swift index 308dd154dc..73242cded6 100644 --- a/submodules/SettingsUI/Sources/SettingsController.swift +++ b/submodules/SettingsUI/Sources/SettingsController.swift @@ -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, SettingsController, TabBarContainedController { +private final class SettingsControllerImpl: ItemListController, SettingsController, TabBarContainedController { let sharedContext: SharedAccountContext let contextValue: Promise var accountsAndPeersValue: ((Account, Peer)?, [(Account, Peer, Int32)])? @@ -611,7 +678,7 @@ private final class SettingsControllerImpl: ItemListController, S return false } - init(currentContext: AccountContext, contextValue: Promise, state: Signal<(ItemListControllerState, (ItemListNodeState, SettingsEntry.ItemGenerationArguments)), NoError>, tabBarItem: Signal?, accountsAndPeers: Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError>) { + init(currentContext: AccountContext, contextValue: Promise, state: Signal<(ItemListControllerState, (ItemListNodeState, Any)), NoError>, tabBarItem: Signal?, 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.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 diff --git a/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift index c1bb994fba..381065879e 100644 --- a/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift @@ -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.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 diff --git a/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift index 11a6ab9ea3..0d1e66c198 100644 --- a/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift @@ -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.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 { diff --git a/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift index b134929169..7d460ea8b3 100644 --- a/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift @@ -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.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 { diff --git a/submodules/SettingsUI/Sources/Themes/EditThemeController.swift b/submodules/SettingsUI/Sources/Themes/EditThemeController.swift index c95ddb02c7..6ebc89cad5 100644 --- a/submodules/SettingsUI/Sources/Themes/EditThemeController.swift +++ b/submodules/SettingsUI/Sources/Themes/EditThemeController.swift @@ -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.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?() }) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift b/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift index 1562d28c92..d788b46374 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift @@ -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.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)] diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift index 8d04cb87b9..065cc7be1e 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift @@ -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.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 diff --git a/submodules/SettingsUI/Sources/UsernameSetupController.swift b/submodules/SettingsUI/Sources/UsernameSetupController.swift index af106ee1dc..36c43dd107 100644 --- a/submodules/SettingsUI/Sources/UsernameSetupController.swift +++ b/submodules/SettingsUI/Sources/UsernameSetupController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state, view -> (ItemListControllerState, (ItemListNodeState, Any)) in let peer = peerViewMainPeer(view) var rightNavigationButton: ItemListNavigationButton? diff --git a/submodules/SettingsUI/Sources/Watch/WatchSettingsController.swift b/submodules/SettingsUI/Sources/Watch/WatchSettingsController.swift index e353d538e8..fdaa7a5fdb 100644 --- a/submodules/SettingsUI/Sources/Watch/WatchSettingsController.swift +++ b/submodules/SettingsUI/Sources/Watch/WatchSettingsController.swift @@ -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.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)) diff --git a/submodules/TelegramCallsUI/Sources/CallFeedbackController.swift b/submodules/TelegramCallsUI/Sources/CallFeedbackController.swift index 7431144131..599a571163 100644 --- a/submodules/TelegramCallsUI/Sources/CallFeedbackController.swift +++ b/submodules/TelegramCallsUI/Sources/CallFeedbackController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { dismissImpl?() }) diff --git a/submodules/TelegramUI/TelegramUI/ChatRecentActionsFilterController.swift b/submodules/TelegramUI/TelegramUI/ChatRecentActionsFilterController.swift index dddb675b49..ae37f557f0 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRecentActionsFilterController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRecentActionsFilterController.swift @@ -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.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?() }) diff --git a/submodules/TelegramUI/TelegramUI/CreateChannelController.swift b/submodules/TelegramUI/TelegramUI/CreateChannelController.swift index e2b2f560e3..7d328d2a13 100644 --- a/submodules/TelegramUI/TelegramUI/CreateChannelController.swift +++ b/submodules/TelegramUI/TelegramUI/CreateChannelController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in let rightNavigationButton: ItemListNavigationButton if state.creating { diff --git a/submodules/TelegramUI/TelegramUI/CreateGroupController.swift b/submodules/TelegramUI/TelegramUI/CreateGroupController.swift index 2efc375f38..4d9f506eb3 100644 --- a/submodules/TelegramUI/TelegramUI/CreateGroupController.swift +++ b/submodules/TelegramUI/TelegramUI/CreateGroupController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData, state, view, address -> (ItemListControllerState, (ItemListNodeState, Any)) in let rightNavigationButton: ItemListNavigationButton if state.creating { diff --git a/submodules/TelegramUpdateUI/Sources/UpdateInfoController.swift b/submodules/TelegramUpdateUI/Sources/UpdateInfoController.swift index c6a380b6d7..0a3e963957 100644 --- a/submodules/TelegramUpdateUI/Sources/UpdateInfoController.swift +++ b/submodules/TelegramUpdateUI/Sources/UpdateInfoController.swift @@ -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.ItemGenerationArguments)) in + |> map { presentationData -> (ItemListControllerState, (ItemListNodeState, Any)) in let appIcon: PresentationAppIcon? let appIcons = context.sharedContext.applicationBindings.getAvailableAlternateIcons() if let alternateIconName = context.sharedContext.applicationBindings.getAlternateIconName() { diff --git a/submodules/WalletUI/Sources/WalletCreateInvoiceScreen.swift b/submodules/WalletUI/Sources/WalletCreateInvoiceScreen.swift index 5db03737d8..f044fdaae8 100644 --- a/submodules/WalletUI/Sources/WalletCreateInvoiceScreen.swift +++ b/submodules/WalletUI/Sources/WalletCreateInvoiceScreen.swift @@ -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, 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.ItemGenerationArguments)) in + |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in var ensureVisibleItemTag: ItemListItemTag? if let focusItemTag = state.focusItemTag { ensureVisibleItemTag = focusItemTag diff --git a/submodules/WalletUI/Sources/WalletReceiveScreen.swift b/submodules/WalletUI/Sources/WalletReceiveScreen.swift index 661df1af0e..c38de6db32 100644 --- a/submodules/WalletUI/Sources/WalletReceiveScreen.swift +++ b/submodules/WalletUI/Sources/WalletReceiveScreen.swift @@ -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, 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.ItemGenerationArguments)) in + |> map { presentationData -> (ItemListControllerState, (ItemListNodeState, Any)) in let rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: true, action: { dismissImpl?() }) diff --git a/submodules/WalletUI/Sources/WalletSendScreen.swift b/submodules/WalletUI/Sources/WalletSendScreen.swift index 6380f17c83..9b3e29c683 100644 --- a/submodules/WalletUI/Sources/WalletSendScreen.swift +++ b/submodules/WalletUI/Sources/WalletSendScreen.swift @@ -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, 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.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?() }) diff --git a/submodules/WalletUI/Sources/WalletSettingsScreen.swift b/submodules/WalletUI/Sources/WalletSettingsScreen.swift index c243df64f8..aac546e85c 100644 --- a/submodules/WalletUI/Sources/WalletSettingsScreen.swift +++ b/submodules/WalletUI/Sources/WalletSettingsScreen.swift @@ -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.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) diff --git a/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift b/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift index f5c347629a..1677f8ece3 100644 --- a/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift +++ b/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift @@ -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.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)