diff --git a/TelegramUI.xcodeproj/project.pbxproj b/TelegramUI.xcodeproj/project.pbxproj index cfda0017e7..8b8f3053af 100644 --- a/TelegramUI.xcodeproj/project.pbxproj +++ b/TelegramUI.xcodeproj/project.pbxproj @@ -193,6 +193,7 @@ D044A0F320BDA05800326FAC /* ThrottledValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D044A0F220BDA05800326FAC /* ThrottledValue.swift */; }; D044A0FB20BDC40C00326FAC /* CachedChannelAdmins.swift in Sources */ = {isa = PBXBuildFile; fileRef = D044A0FA20BDC40C00326FAC /* CachedChannelAdmins.swift */; }; D045549A21B2F173007A6DD9 /* libturbojpeg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D045549921B2F173007A6DD9 /* libturbojpeg.a */; }; + D04554A421B42982007A6DD9 /* ConfirmPhoneNumberController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04554A321B42982007A6DD9 /* ConfirmPhoneNumberController.swift */; }; D046142E2004DB3700EC0EF2 /* LiveLocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D046142D2004DB3700EC0EF2 /* LiveLocationManager.swift */; }; D04614372005094E00EC0EF2 /* DeviceLocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04614362005094E00EC0EF2 /* DeviceLocationManager.swift */; }; D0461439200514F000EC0EF2 /* LiveLocationSummaryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0461438200514F000EC0EF2 /* LiveLocationSummaryManager.swift */; }; @@ -1389,6 +1390,7 @@ D044A0F220BDA05800326FAC /* ThrottledValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThrottledValue.swift; sourceTree = ""; }; D044A0FA20BDC40C00326FAC /* CachedChannelAdmins.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CachedChannelAdmins.swift; sourceTree = ""; }; D045549921B2F173007A6DD9 /* libturbojpeg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libturbojpeg.a; path = "third-party/libjpeg-turbo/libturbojpeg.a"; sourceTree = ""; }; + D04554A321B42982007A6DD9 /* ConfirmPhoneNumberController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmPhoneNumberController.swift; sourceTree = ""; }; D046142D2004DB3700EC0EF2 /* LiveLocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveLocationManager.swift; sourceTree = ""; }; D04614362005094E00EC0EF2 /* DeviceLocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceLocationManager.swift; sourceTree = ""; }; D0461438200514F000EC0EF2 /* LiveLocationSummaryManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveLocationSummaryManager.swift; sourceTree = ""; }; @@ -4628,6 +4630,7 @@ D0760B231E9D015D00F1F3C4 /* PasscodeOptionsController.swift */, D0CE6F6F213EEE5000BCD44B /* CreatePasswordController.swift */, D0B3AC7F2142E2E900CD1374 /* ResetPasswordController.swift */, + D04554A321B42982007A6DD9 /* ConfirmPhoneNumberController.swift */, D05D8B792195E00C0064586F /* Setup Two Step Verification */, ); name = "Privacy and Security"; @@ -5617,6 +5620,7 @@ D0EC6E071EB9F58900EBF1C3 /* ChatExternalFileGalleryItem.swift in Sources */, D0EC6E081EB9F58900EBF1C3 /* ChatImageGalleryItem.swift in Sources */, D048EA891F4F297500188713 /* InstantPageSettingsFontFamilyItemNode.swift in Sources */, + D04554A421B42982007A6DD9 /* ConfirmPhoneNumberController.swift in Sources */, D0EC6E0A1EB9F58900EBF1C3 /* ChatVideoGalleryItemScrubberView.swift in Sources */, D0EC6E0B1EB9F58900EBF1C3 /* ZoomableContentGalleryItemNode.swift in Sources */, D07ABBA5202A14BC003671DE /* LegacyImagePicker.swift in Sources */, diff --git a/TelegramUI/AutodownloadSizeLimitItem.swift b/TelegramUI/AutodownloadSizeLimitItem.swift index 2fe66e3e45..874506d3d5 100644 --- a/TelegramUI/AutodownloadSizeLimitItem.swift +++ b/TelegramUI/AutodownloadSizeLimitItem.swift @@ -41,7 +41,7 @@ class AutodownloadSizeLimitItem: ListViewItem, ItemListItem { self.updated = updated } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = AutodownloadSizeLimitItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -51,13 +51,13 @@ class AutodownloadSizeLimitItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? AutodownloadSizeLimitItemNode { let makeLayout = nodeValue.asyncLayout() @@ -65,7 +65,7 @@ class AutodownloadSizeLimitItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/BotCheckoutHeaderItem.swift b/TelegramUI/BotCheckoutHeaderItem.swift index 08f6270969..45690225ca 100644 --- a/TelegramUI/BotCheckoutHeaderItem.swift +++ b/TelegramUI/BotCheckoutHeaderItem.swift @@ -19,7 +19,7 @@ class BotCheckoutHeaderItem: ListViewItem, ItemListItem { self.sectionId = sectionId } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = BotCheckoutHeaderItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -29,13 +29,13 @@ class BotCheckoutHeaderItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? BotCheckoutHeaderItemNode { let makeLayout = nodeValue.asyncLayout() @@ -43,7 +43,7 @@ class BotCheckoutHeaderItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/BotCheckoutPriceItem.swift b/TelegramUI/BotCheckoutPriceItem.swift index 476ee6411f..a720997e07 100644 --- a/TelegramUI/BotCheckoutPriceItem.swift +++ b/TelegramUI/BotCheckoutPriceItem.swift @@ -20,7 +20,7 @@ class BotCheckoutPriceItem: ListViewItem, ItemListItem { self.sectionId = sectionId } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = BotCheckoutPriceItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -30,13 +30,13 @@ class BotCheckoutPriceItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? BotCheckoutPriceItemNode { let makeLayout = nodeValue.asyncLayout() @@ -44,7 +44,7 @@ class BotCheckoutPriceItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/CalculatingCacheSizeItem.swift b/TelegramUI/CalculatingCacheSizeItem.swift index bd9cbdf892..750dc2cb33 100644 --- a/TelegramUI/CalculatingCacheSizeItem.swift +++ b/TelegramUI/CalculatingCacheSizeItem.swift @@ -16,7 +16,7 @@ class CalculatingCacheSizeItem: ListViewItem, ItemListItem { self.style = style } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = CalculatingCacheSizeItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -26,13 +26,13 @@ class CalculatingCacheSizeItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? CalculatingCacheSizeItemNode { let makeLayout = nodeValue.asyncLayout() @@ -40,7 +40,7 @@ class CalculatingCacheSizeItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/CallListCallItem.swift b/TelegramUI/CallListCallItem.swift index 126ee2467d..e513c49855 100644 --- a/TelegramUI/CallListCallItem.swift +++ b/TelegramUI/CallListCallItem.swift @@ -92,7 +92,7 @@ class CallListCallItem: ListViewItem { self.header = nil } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = CallListCallItemNode() let makeLayout = node.asyncLayout() @@ -103,7 +103,7 @@ class CallListCallItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { + return (nil, { _ in nodeApply().1(false) }) }) @@ -111,7 +111,7 @@ class CallListCallItem: ListViewItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? CallListCallItemNode { let layout = nodeValue.asyncLayout() @@ -123,7 +123,7 @@ class CallListCallItem: ListViewItem { animated = false } Queue.mainQueue().async { - completion(nodeLayout, { + completion(nodeLayout, { _ in apply().1(animated) }) } diff --git a/TelegramUI/ChangePhoneNumberCodeController.swift b/TelegramUI/ChangePhoneNumberCodeController.swift index 0d67bf9c16..3af34a4b30 100644 --- a/TelegramUI/ChangePhoneNumberCodeController.swift +++ b/TelegramUI/ChangePhoneNumberCodeController.swift @@ -38,7 +38,7 @@ private enum ChangePhoneNumberCodeTag: ItemListItemTag { } private enum ChangePhoneNumberCodeEntry: ItemListNodeEntry { - case codeEntry(PresentationTheme, String) + case codeEntry(PresentationTheme, String, String) case codeInfo(PresentationTheme, String) var section: ItemListSectionId { @@ -56,8 +56,8 @@ private enum ChangePhoneNumberCodeEntry: ItemListNodeEntry { static func ==(lhs: ChangePhoneNumberCodeEntry, rhs: ChangePhoneNumberCodeEntry) -> Bool { switch lhs { - case let .codeEntry(lhsTheme, lhsText): - if case let .codeEntry(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText { + case let .codeEntry(lhsTheme, lhsTitle, lhsText): + if case let .codeEntry(rhsTheme, rhsTitle, rhsText) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle, lhsText == rhsText { return true } else { return false @@ -77,8 +77,8 @@ private enum ChangePhoneNumberCodeEntry: ItemListNodeEntry { func item(_ arguments: ChangePhoneNumberCodeControllerArguments) -> ListViewItem { switch self { - case let .codeEntry(theme, text): - return ItemListSingleLineInputItem(theme: theme, title: NSAttributedString(string: "Code", textColor: .black), text: text, placeholder: "", type: .number, spacing: 10.0, tag: ChangePhoneNumberCodeTag.input, sectionId: self.section, textUpdated: { updatedText in + case let .codeEntry(theme, title, text): + return ItemListSingleLineInputItem(theme: theme, title: NSAttributedString(string: title, textColor: .black), text: text, placeholder: "", type: .number, spacing: 10.0, tag: ChangePhoneNumberCodeTag.input, sectionId: self.section, textUpdated: { updatedText in arguments.updateEntryText(updatedText) }, action: { arguments.next() @@ -129,7 +129,7 @@ private struct ChangePhoneNumberCodeControllerState: Equatable { private func changePhoneNumberCodeControllerEntries(presentationData: PresentationData, state: ChangePhoneNumberCodeControllerState, codeData: ChangeAccountPhoneNumberData, timeout: Int32?, strings: PresentationStrings, theme: AuthorizationTheme) -> [ChangePhoneNumberCodeEntry] { var entries: [ChangePhoneNumberCodeEntry] = [] - entries.append(.codeEntry(presentationData.theme, state.codeText)) + entries.append(.codeEntry(presentationData.theme, presentationData.strings.ChangePhoneNumberCode_CodePlaceholder, state.codeText)) var text = authorizationCurrentOptionText(codeData.type, strings: presentationData.strings, primaryColor: presentationData.theme.list.itemPrimaryTextColor, accentColor: presentationData.theme.list.itemAccentColor).string if let nextType = codeData.nextType { text += "\n\n" + authorizationNextOptionText(currentType: codeData.type, nextType: nextType, timeout: timeout, strings: presentationData.strings, primaryColor: .black, accentColor: .black).0.string @@ -194,7 +194,7 @@ func changePhoneNumberCodeController(account: Account, phoneNumber: String, code } var dismissImpl: (() -> Void)? - var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments) -> Void)? + var presentControllerImpl: ((ViewController, Any?) -> Void)? let actionsDisposable = DisposableSet() @@ -264,7 +264,7 @@ func changePhoneNumberCodeController(account: Account, phoneNumber: String, code return $0.withUpdatedChecking(false) } let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } - presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: nil, text: "You have changed your phone number to \(formatPhoneNumber(phoneNumber)).", actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) + presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .success), nil) dismissImpl?() })) } diff --git a/TelegramUI/ChatBotInfoItem.swift b/TelegramUI/ChatBotInfoItem.swift index 6bf0eb7f1b..9fb2dc3b34 100644 --- a/TelegramUI/ChatBotInfoItem.swift +++ b/TelegramUI/ChatBotInfoItem.swift @@ -21,7 +21,7 @@ final class ChatBotInfoItem: ListViewItem { self.presentationData = presentationData } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { let configure = { let node = ChatBotInfoItemNode() @@ -33,7 +33,7 @@ final class ChatBotInfoItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(.None) }) + return (nil, { _ in apply(.None) }) }) } } @@ -46,7 +46,7 @@ final class ChatBotInfoItem: ListViewItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ChatBotInfoItemNode { let nodeLayout = nodeValue.asyncLayout() @@ -54,7 +54,7 @@ final class ChatBotInfoItem: ListViewItem { async { let (layout, apply) = nodeLayout(self, params) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation) }) } diff --git a/TelegramUI/ChatButtonKeyboardInputNode.swift b/TelegramUI/ChatButtonKeyboardInputNode.swift index 4a2714fb60..f35e83c748 100644 --- a/TelegramUI/ChatButtonKeyboardInputNode.swift +++ b/TelegramUI/ChatButtonKeyboardInputNode.swift @@ -66,7 +66,7 @@ final class ChatButtonKeyboardInputNode: ChatInputNode { } } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> (CGFloat, CGFloat) { + override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, isVisible: Bool) -> (CGFloat, CGFloat) { transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: UIScreenPixel))) if self.theme !== interfaceState.theme { diff --git a/TelegramUI/ChatController.swift b/TelegramUI/ChatController.swift index cf6dacca0d..a8cb99cc03 100644 --- a/TelegramUI/ChatController.swift +++ b/TelegramUI/ChatController.swift @@ -2188,6 +2188,11 @@ public final class ChatController: TelegramController, KeyShortcutResponder, UID return $0.updatedInputMode({ _ in return updatedInputMode }).updatedInterfaceState({ $0.withUpdatedMessageActionsState({ $0.withUpdatedClosedButtonKeyboardMessageId(updatedClosedButtonKeyboardMessageId) }) }) }) } + }, openStickers: { [weak self] in + guard let strongSelf = self else { + return + } + strongSelf.chatDisplayNode.openStickers() }, editMessage: { [weak self] in if let strongSelf = self, let editMessage = strongSelf.presentationInterfaceState.interfaceState.editMessage { var disableUrlPreview = false @@ -4224,7 +4229,7 @@ public final class ChatController: TelegramController, KeyShortcutResponder, UID private func sendMediaRecording() { if let recordedMediaPreview = self.presentationInterfaceState.recordedMediaPreview { - let waveformBuffer = MemoryBuffer(data: recordedMediaPreview.waveform.samples) + let waveformBuffer = MemoryBuffer(data: recordedMediaPreview.waveform.makeBitstream()) self.chatDisplayNode.setupSendActionOnViewUpdate({ [weak self] in if let strongSelf = self { diff --git a/TelegramUI/ChatControllerNode.swift b/TelegramUI/ChatControllerNode.swift index 5ba653d8a8..4bc60300b3 100644 --- a/TelegramUI/ChatControllerNode.swift +++ b/TelegramUI/ChatControllerNode.swift @@ -169,6 +169,8 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } } + private var openStickersDisposable: Disposable? + init(account: Account, chatLocation: ChatLocation, messageId: MessageId?, controllerInteraction: ChatControllerInteraction, chatPresentationInterfaceState: ChatPresentationInterfaceState, automaticMediaDownloadSettings: AutomaticMediaDownloadSettings, navigationBar: NavigationBar?, controller: ChatController?) { self.account = account self.chatLocation = chatLocation @@ -339,6 +341,10 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } } + deinit { + self.openStickersDisposable?.dispose() + } + override func didLoad() { super.didLoad() @@ -601,7 +607,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { self.insertSubnode(inputNode, aboveSubnode: self.inputPanelBackgroundNode) } } - inputNodeHeightAndOverflow = inputNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: cleanInsets.bottom, standardInputHeight: layout.standardInputHeight, inputHeight: layout.inputHeight ?? 0.0, maximumHeight: maximumInputNodeHeight, inputPanelHeight: inputPanelNodeBaseHeight, transition: immediatelyLayoutInputNodeAndAnimateAppearance ? .immediate : transition, interfaceState: self.chatPresentationInterfaceState) + inputNodeHeightAndOverflow = inputNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: cleanInsets.bottom, standardInputHeight: layout.standardInputHeight, inputHeight: layout.inputHeight ?? 0.0, maximumHeight: maximumInputNodeHeight, inputPanelHeight: inputPanelNodeBaseHeight, transition: immediatelyLayoutInputNodeAndAnimateAppearance ? .immediate : transition, interfaceState: self.chatPresentationInterfaceState, isVisible: true) } else if let inputNode = self.inputNode { dismissedInputNode = inputNode self.inputNode = nil @@ -679,7 +685,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } if let inputMediaNode = self.inputMediaNode, inputMediaNode != self.inputNode { - let _ = inputMediaNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: cleanInsets.bottom, standardInputHeight: layout.standardInputHeight, inputHeight: layout.inputHeight ?? 0.0, maximumHeight: maximumInputNodeHeight, inputPanelHeight: inputPanelSize?.height ?? 0.0, transition: .immediate, interfaceState: self.chatPresentationInterfaceState) + let _ = inputMediaNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: cleanInsets.bottom, standardInputHeight: layout.standardInputHeight, inputHeight: layout.inputHeight ?? 0.0, maximumHeight: maximumInputNodeHeight, inputPanelHeight: inputPanelSize?.height ?? 0.0, transition: .immediate, interfaceState: self.chatPresentationInterfaceState, isVisible: false) } transition.updateFrame(node: self.titleAccessoryPanelContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: 56.0))) @@ -1367,6 +1373,14 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { self.emptyNode?.isHidden = false } + if let openStickersDisposable = self.openStickersDisposable { + if case .media = chatPresentationInterfaceState.inputMode { + } else { + openStickersDisposable.dispose() + self.openStickersDisposable = nil + } + } + let layoutTransition: ContainedViewLayoutTransition = transition if updatedInputFocus { @@ -1494,7 +1508,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { inputNode.interfaceInteraction = interfaceInteraction self.inputMediaNode = inputNode if let (validLayout, _) = self.validLayout { - let _ = inputNode.updateLayout(width: validLayout.size.width, leftInset: validLayout.safeInsets.left, rightInset: validLayout.safeInsets.right, bottomInset: validLayout.intrinsicInsets.bottom, standardInputHeight: validLayout.standardInputHeight, inputHeight: validLayout.inputHeight ?? 0.0, maximumHeight: validLayout.standardInputHeight, inputPanelHeight: 44.0, transition: .immediate, interfaceState: self.chatPresentationInterfaceState) + let _ = inputNode.updateLayout(width: validLayout.size.width, leftInset: validLayout.safeInsets.left, rightInset: validLayout.safeInsets.right, bottomInset: validLayout.intrinsicInsets.bottom, standardInputHeight: validLayout.standardInputHeight, inputHeight: validLayout.inputHeight ?? 0.0, maximumHeight: validLayout.standardInputHeight, inputPanelHeight: 44.0, transition: .immediate, interfaceState: self.chatPresentationInterfaceState, isVisible: false) } } } @@ -1921,4 +1935,17 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { self.keyboardGestureBeginLocation = nil } } + + func openStickers() { + if let inputMediaNode = self.inputMediaNode, self.openStickersDisposable == nil { + self.openStickersDisposable = (inputMediaNode.ready + |> take(1) + |> deliverOnMainQueue).start(next: { [weak self] in + self?.openStickersDisposable = nil + self?.interfaceInteraction?.updateInputModeAndDismissedButtonKeyboardMessageId({ state in + return (.media(mode: .other, expanded: nil), state.interfaceState.messageActionsState.closedButtonKeyboardMessageId) + }) + }) + } + } } diff --git a/TelegramUI/ChatHoleItem.swift b/TelegramUI/ChatHoleItem.swift index 838c71e665..5cc04def5b 100644 --- a/TelegramUI/ChatHoleItem.swift +++ b/TelegramUI/ChatHoleItem.swift @@ -18,21 +18,21 @@ class ChatHoleItem: ListViewItem { //self.header = ChatMessageDateHeader(timestamp: index.timestamp, theme: theme, strings: strings) } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatHoleItemNode() node.layoutForParams(params, item: self, previousItem: previousItem, nextItem: nextItem) Queue.mainQueue().async { completion(node, { - return (nil, {}) + return (nil, { _ in }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { - completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: node().insets), { + completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: node().insets), { _ in }) } } diff --git a/TelegramUI/ChatInputNode.swift b/TelegramUI/ChatInputNode.swift index c3db7a0cf1..ab36507362 100644 --- a/TelegramUI/ChatInputNode.swift +++ b/TelegramUI/ChatInputNode.swift @@ -1,11 +1,15 @@ import Foundation import Display import AsyncDisplayKit +import SwiftSignalKit class ChatInputNode: ASDisplayNode { var interfaceInteraction: ChatPanelInterfaceInteraction? + var ready: Signal { + return .single(Void()) + } - func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> (CGFloat, CGFloat) { + func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, isVisible: Bool) -> (CGFloat, CGFloat) { return (0.0, 0.0) } } diff --git a/TelegramUI/ChatListHoleItem.swift b/TelegramUI/ChatListHoleItem.swift index 91d5d7a349..ba8de93444 100644 --- a/TelegramUI/ChatListHoleItem.swift +++ b/TelegramUI/ChatListHoleItem.swift @@ -16,7 +16,7 @@ class ChatListHoleItem: ListViewItem { self.theme = theme } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatListHoleItemNode() node.relativePosition = (first: previousItem == nil, last: nextItem == nil) @@ -24,13 +24,13 @@ class ChatListHoleItem: ListViewItem { node.layoutForParams(params, item: self, previousItem: previousItem, nextItem: nextItem) Queue.mainQueue().async { completion(node, { - return (nil, {}) + return (nil, { _ in }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { assert(node() is ChatListHoleItemNode) if let nodeValue = node() as? ChatListHoleItemNode { @@ -42,7 +42,7 @@ class ChatListHoleItem: ListViewItem { let (nodeLayout, apply) = layout(self, params, first, last) Queue.mainQueue().async { - completion(nodeLayout, { + completion(nodeLayout, { _ in apply() if let nodeValue = node() as? ChatListHoleItemNode { nodeValue.updateBackgroundAndSeparatorsLayout() diff --git a/TelegramUI/ChatListItem.swift b/TelegramUI/ChatListItem.swift index 9cb181fa3e..fcaf9b90a9 100644 --- a/TelegramUI/ChatListItem.swift +++ b/TelegramUI/ChatListItem.swift @@ -50,7 +50,7 @@ class ChatListItem: ListViewItem { self.interaction = interaction } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatListItemNode() let (first, last, firstWithHeader, nextIsPinned) = ChatListItem.mergeType(item: self, previousItem: previousItem, nextItem: nextItem) @@ -63,7 +63,7 @@ class ChatListItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { + return (nil, { _ in node.setupItem(item: self) apply(false) node.updateIsHighlighted(transition: .immediate) @@ -73,7 +73,7 @@ class ChatListItem: ListViewItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { assert(node() is ChatListItemNode) if let nodeValue = node() as? ChatListItemNode { @@ -88,7 +88,7 @@ class ChatListItem: ListViewItem { let (nodeLayout, apply) = layout(self, params, first, last, firstWithHeader, nextIsPinned) Queue.mainQueue().async { - completion(nodeLayout, { + completion(nodeLayout, { _ in apply(animated) }) } diff --git a/TelegramUI/ChatListNode.swift b/TelegramUI/ChatListNode.swift index b087853529..1c8c796df7 100644 --- a/TelegramUI/ChatListNode.swift +++ b/TelegramUI/ChatListNode.swift @@ -582,7 +582,7 @@ final class ChatListNode: ListView { } var searchMode = false - if case .chatList = mode { + if case .peers = mode { searchMode = true } diff --git a/TelegramUI/ChatListRecentPeersListItem.swift b/TelegramUI/ChatListRecentPeersListItem.swift index ffc7bee5fe..046dcd117b 100644 --- a/TelegramUI/ChatListRecentPeersListItem.swift +++ b/TelegramUI/ChatListRecentPeersListItem.swift @@ -26,7 +26,7 @@ class ChatListRecentPeersListItem: ListViewItem { self.header = nil } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatListRecentPeersListItemNode() let makeLayout = node.asyncLayout() @@ -38,15 +38,15 @@ class ChatListRecentPeersListItem: ListViewItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ChatListRecentPeersListItemNode { let layout = nodeValue.asyncLayout() async { let (nodeLayout, apply) = layout(self, params, nextItem != nil) Queue.mainQueue().async { - completion(nodeLayout, { - apply().1() + completion(nodeLayout, { info in + apply().1(info) }) } } @@ -87,7 +87,7 @@ class ChatListRecentPeersListItemNode: ListViewItemNode { } } - func asyncLayout() -> (_ item: ChatListRecentPeersListItem, _ params: ListViewItemLayoutParams, _ last: Bool) -> (ListViewItemNodeLayout, () -> (Signal?, () -> Void)) { + func asyncLayout() -> (_ item: ChatListRecentPeersListItem, _ params: ListViewItemLayoutParams, _ last: Bool) -> (ListViewItemNodeLayout, () -> (Signal?, (ListViewItemApply) -> Void)) { let currentItem = self.item return { [weak self] item, params, last in @@ -99,7 +99,7 @@ class ChatListRecentPeersListItemNode: ListViewItemNode { updatedTheme = item.theme } - return (nil, { + return (nil, { _ in if let strongSelf = self { strongSelf.item = item diff --git a/TelegramUI/ChatListSearchItem.swift b/TelegramUI/ChatListSearchItem.swift index f0c5f12e44..59295fc96d 100644 --- a/TelegramUI/ChatListSearchItem.swift +++ b/TelegramUI/ChatListSearchItem.swift @@ -22,7 +22,7 @@ class ChatListSearchItem: ListViewItem { self.activate = activate } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatListSearchItemNode() node.placeholder = self.placeholder @@ -40,7 +40,7 @@ class ChatListSearchItem: ListViewItem { node.activate = self.activate Queue.mainQueue().async { completion(node, { - return (nil, { + return (nil, { _ in apply(false) }) }) @@ -48,7 +48,7 @@ class ChatListSearchItem: ListViewItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ChatListSearchItemNode { nodeValue.placeholder = self.placeholder @@ -60,7 +60,7 @@ class ChatListSearchItem: ListViewItem { } let (nodeLayout, apply) = layout(self, params, nextIsPinned, self.isEnabled) Queue.mainQueue().async { - completion(nodeLayout, { + completion(nodeLayout, { _ in apply(animation.isAnimated) }) } diff --git a/TelegramUI/ChatMediaInputGifPane.swift b/TelegramUI/ChatMediaInputGifPane.swift index ba8e2e5fa0..4228ab9e7b 100644 --- a/TelegramUI/ChatMediaInputGifPane.swift +++ b/TelegramUI/ChatMediaInputGifPane.swift @@ -44,7 +44,7 @@ final class ChatMediaInputGifPane: ChatMediaInputPane, UIScrollViewDelegate { self.disposable.dispose() } - override func updateLayout(size: CGSize, topInset: CGFloat, bottomInset: CGFloat, isExpanded: Bool, transition: ContainedViewLayoutTransition) { + override func updateLayout(size: CGSize, topInset: CGFloat, bottomInset: CGFloat, isExpanded: Bool, isVisible: Bool, transition: ContainedViewLayoutTransition) { self.validLayout = size let emptySize = self.emptyNode.updateLayout(size) transition.updateFrame(node: self.emptyNode, frame: CGRect(origin: CGPoint(x: floor(size.width - emptySize.width) / 2.0, y: topInset + floor(size.height - topInset - emptySize.height) / 2.0), size: emptySize)) diff --git a/TelegramUI/ChatMediaInputMetaSectionItemNode.swift b/TelegramUI/ChatMediaInputMetaSectionItemNode.swift index 962ad8910d..d57e108fae 100644 --- a/TelegramUI/ChatMediaInputMetaSectionItemNode.swift +++ b/TelegramUI/ChatMediaInputMetaSectionItemNode.swift @@ -27,7 +27,7 @@ final class ChatMediaInputMetaSectionItem: ListViewItem { self.theme = theme } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatMediaInputMetaSectionItemNode() node.contentSize = CGSize(width: 41.0, height: 41.0) @@ -39,7 +39,7 @@ final class ChatMediaInputMetaSectionItem: ListViewItem { node.updateAppearanceTransition(transition: .immediate) Queue.mainQueue().async { completion(node, { - return (nil, { + return (nil, { _ in }) }) @@ -47,9 +47,9 @@ final class ChatMediaInputMetaSectionItem: ListViewItem { } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { - completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: node().insets), { + completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: node().insets), { _ in (node() as? ChatMediaInputMetaSectionItemNode)?.setItem(item: self) (node() as? ChatMediaInputMetaSectionItemNode)?.updateTheme(theme: self.theme) }) diff --git a/TelegramUI/ChatMediaInputNode.swift b/TelegramUI/ChatMediaInputNode.swift index 8ef26f2f9c..fa1a417670 100644 --- a/TelegramUI/ChatMediaInputNode.swift +++ b/TelegramUI/ChatMediaInputNode.swift @@ -54,7 +54,7 @@ private func preparedChatMediaInputGridEntryTransition(account: Account, view: I case .search, .peerSpecificSetup: break case .sticker: - scrollToItem = GridNodeScrollToItem(index: i, position: .top, transition: .animated(duration: 0.0, curve: .easeInOut), directionHint: .down, adjustForSection: true, adjustForTopInset: true) + scrollToItem = GridNodeScrollToItem(index: i, position: .top, transition: .immediate, directionHint: .down, adjustForSection: true, adjustForTopInset: true) } } case .generic: @@ -394,6 +394,7 @@ final class ChatMediaInputNode: ChatInputNode { private let listView: ListView private var stickerSearchContainerNode: StickerPaneSearchContainerNode? + private let stickerSearchContainerNodeLoadedDisposable = MetaDisposable() private let stickerPane: ChatMediaInputStickerPane private var animatingStickerPaneOut = false @@ -409,7 +410,7 @@ final class ChatMediaInputNode: ChatInputNode { private var currentView: ItemCollectionsView? private let dismissedPeerSpecificStickerPack = Promise() - private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, ChatPresentationInterfaceState)? + private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, ChatPresentationInterfaceState, Bool)? private var paneArrangement: ChatMediaInputPaneArrangement private var initializedArrangement = false @@ -417,6 +418,12 @@ final class ChatMediaInputNode: ChatInputNode { private var strings: PresentationStrings private let themeAndStringsPromise: Promise<(PresentationTheme, PresentationStrings)> + private let _ready = Promise() + private var didSetReady = false + override var ready: Signal { + return self._ready.get() + } + init(account: Account, peerId: PeerId?, controllerInteraction: ChatControllerInteraction, theme: PresentationTheme, strings: PresentationStrings, gifPaneIsActiveUpdated: @escaping (Bool) -> Void) { self.account = account self.peerId = peerId @@ -504,16 +511,38 @@ final class ChatMediaInputNode: ChatInputNode { } }, toggleSearch: { [weak self] value in if let strongSelf = self { - strongSelf.controllerInteraction.updateInputMode { current in - switch current { - case let .media(mode, _): - if value { - return .media(mode: mode, expanded: .search) - } else { - return .media(mode: mode, expanded: nil) + if value { + let stickerSearchContainerNode: StickerPaneSearchContainerNode + if let current = strongSelf.stickerSearchContainerNode { + stickerSearchContainerNode = current + } else { + stickerSearchContainerNode = StickerPaneSearchContainerNode(account: strongSelf.account, theme: strongSelf.theme, strings: strongSelf.strings, controllerInteraction: strongSelf.controllerInteraction, inputNodeInteraction: strongSelf.inputNodeInteraction, cancel: { + self?.stickerSearchContainerNode?.deactivate() + self?.inputNodeInteraction.toggleSearch(false) + }) + strongSelf.stickerSearchContainerNode = stickerSearchContainerNode + } + strongSelf.stickerSearchContainerNodeLoadedDisposable.set((stickerSearchContainerNode.ready + |> deliverOnMainQueue).start(next: { + if let strongSelf = self { + strongSelf.controllerInteraction.updateInputMode { current in + switch current { + case let .media(mode, _): + return .media(mode: mode, expanded: .search) + default: + return current + } } - default: - return current + } + })) + } else { + strongSelf.controllerInteraction.updateInputMode { current in + switch current { + case let .media(mode, _): + return .media(mode: mode, expanded: nil) + default: + return current + } } } } @@ -728,6 +757,7 @@ final class ChatMediaInputNode: ChatInputNode { deinit { self.disposable.dispose() + self.stickerSearchContainerNodeLoadedDisposable.dispose() } private func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) { @@ -920,8 +950,8 @@ final class ChatMediaInputNode: ChatInputNode { if let index = self.paneArrangement.panes.index(of: pane), index != self.paneArrangement.currentIndex { let previousGifPanelWasActive = self.paneArrangement.panes[self.paneArrangement.currentIndex] == .gifs self.paneArrangement = self.paneArrangement.withIndexTransition(0.0).withCurrentIndex(index) - if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState) = self.validLayout { - let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .animated(duration: 0.25, curve: .spring), interfaceState: interfaceState) + if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, isVisible) = self.validLayout { + let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .animated(duration: 0.25, curve: .spring), interfaceState: interfaceState, isVisible: isVisible) self.updateAppearanceTransition(transition: transition) } let updatedGifPanelWasActive = self.paneArrangement.panes[self.paneArrangement.currentIndex] == .gifs @@ -941,8 +971,8 @@ final class ChatMediaInputNode: ChatInputNode { self.setHighlightedItemCollectionId(ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.trending.rawValue, id: 0)) } } else { - if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState) = self.validLayout { - let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .animated(duration: 0.25, curve: .spring), interfaceState: interfaceState) + if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, isVisible) = self.validLayout { + let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .animated(duration: 0.25, curve: .spring), interfaceState: interfaceState, isVisible: isVisible) } } } @@ -1070,8 +1100,8 @@ final class ChatMediaInputNode: ChatInputNode { } } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> (CGFloat, CGFloat) { - self.validLayout = (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState) + override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, isVisible: Bool) -> (CGFloat, CGFloat) { + self.validLayout = (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, isVisible) if self.theme !== interfaceState.theme || self.strings !== interfaceState.strings { self.updateThemeAndStrings(theme: interfaceState.theme, strings: interfaceState.strings) @@ -1100,27 +1130,25 @@ final class ChatMediaInputNode: ChatInputNode { } if displaySearch { - let containerFrame = CGRect(origin: CGPoint(x: 0.0, y: -inputPanelHeight), size: CGSize(width: width, height: panelHeight + inputPanelHeight)) if let stickerSearchContainerNode = self.stickerSearchContainerNode { - transition.updateFrame(node: stickerSearchContainerNode, frame: containerFrame) - stickerSearchContainerNode.updateLayout(size: containerFrame.size, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, inputHeight: inputHeight, transition: transition) - } else { - let stickerSearchContainerNode = StickerPaneSearchContainerNode(account: self.account, theme: self.theme, strings: self.strings, controllerInteraction: self.controllerInteraction, inputNodeInteraction: self.inputNodeInteraction, cancel: { [weak self] in - self?.stickerSearchContainerNode?.deactivate() - self?.inputNodeInteraction.toggleSearch(false) - }) - self.stickerSearchContainerNode = stickerSearchContainerNode - self.insertSubnode(stickerSearchContainerNode, belowSubnode: self.collectionListContainer) - stickerSearchContainerNode.frame = containerFrame - stickerSearchContainerNode.updateLayout(size: containerFrame.size, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, inputHeight: inputHeight, transition: .immediate) - var placeholderNode: StickerPaneSearchBarPlaceholderNode? - self.stickerPane.gridNode.forEachItemNode { itemNode in - if let itemNode = itemNode as? StickerPaneSearchBarPlaceholderNode { - placeholderNode = itemNode + let containerFrame = CGRect(origin: CGPoint(x: 0.0, y: -inputPanelHeight), size: CGSize(width: width, height: panelHeight + inputPanelHeight)) + if stickerSearchContainerNode.supernode != nil { + transition.updateFrame(node: stickerSearchContainerNode, frame: containerFrame) + stickerSearchContainerNode.updateLayout(size: containerFrame.size, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, inputHeight: inputHeight, transition: transition) + } else { + self.stickerSearchContainerNode = stickerSearchContainerNode + self.insertSubnode(stickerSearchContainerNode, belowSubnode: self.collectionListContainer) + stickerSearchContainerNode.frame = containerFrame + stickerSearchContainerNode.updateLayout(size: containerFrame.size, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, inputHeight: inputHeight, transition: .immediate) + var placeholderNode: StickerPaneSearchBarPlaceholderNode? + self.stickerPane.gridNode.forEachItemNode { itemNode in + if let itemNode = itemNode as? StickerPaneSearchBarPlaceholderNode { + placeholderNode = itemNode + } + } + if let placeholderNode = placeholderNode { + stickerSearchContainerNode.animateIn(from: placeholderNode, transition: transition) } - } - if let placeholderNode = placeholderNode { - stickerSearchContainerNode.animateIn(from: placeholderNode, transition: transition) } } } @@ -1206,10 +1234,10 @@ final class ChatMediaInputNode: ChatInputNode { } } - self.gifPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, transition: transition) + self.gifPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, isVisible: isVisible, transition: transition) - self.stickerPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, transition: transition) - self.trendingPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, transition: transition) + self.stickerPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, isVisible: isVisible, transition: transition) + self.trendingPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, isVisible: isVisible, transition: transition) if self.gifPane.supernode != nil { if !visiblePanes.contains(where: { $0.0 == .gifs }) { @@ -1288,6 +1316,7 @@ final class ChatMediaInputNode: ChatInputNode { if !displaySearch, let stickerSearchContainerNode = self.stickerSearchContainerNode { self.stickerSearchContainerNode = nil + self.stickerSearchContainerNodeLoadedDisposable.set(nil) var placeholderNode: StickerPaneSearchBarPlaceholderNode? self.stickerPane.gridNode.forEachItemNode { itemNode in @@ -1322,6 +1351,10 @@ final class ChatMediaInputNode: ChatInputNode { self.listView.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, updateOpaqueState: nil, completion: { [weak self] _ in if let strongSelf = self { strongSelf.enqueueGridTransition(gridTransition, firstTime: gridFirstTime) + if !strongSelf.didSetReady { + strongSelf.didSetReady = true + strongSelf._ready.set(.single(Void())) + } } }) } @@ -1368,7 +1401,7 @@ final class ChatMediaInputNode: ChatInputNode { self.trendingPane.removeFromSupernode() } case .changed: - if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState) = self.validLayout { + if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, isVisible) = self.validLayout { let translationX = -recognizer.translation(in: self.view).x var indexTransition = translationX / width if self.paneArrangement.currentIndex == 0 { @@ -1377,10 +1410,10 @@ final class ChatMediaInputNode: ChatInputNode { indexTransition = min(0.0, indexTransition) } self.paneArrangement = self.paneArrangement.withIndexTransition(indexTransition) - let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState) + let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, isVisible: isVisible) } case .ended: - if let (width, _, _, _, _, _, _, _, _) = self.validLayout { + if let (width, _, _, _, _, _, _, _, _, _) = self.validLayout { var updatedIndex = self.paneArrangement.currentIndex if abs(self.paneArrangement.indexTransition * width) > 30.0 { if self.paneArrangement.indexTransition < 0.0 { @@ -1393,9 +1426,9 @@ final class ChatMediaInputNode: ChatInputNode { self.setCurrentPane(self.paneArrangement.panes[updatedIndex], transition: .animated(duration: 0.25, curve: .spring)) } case .cancelled: - if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState) = self.validLayout { + if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, isVisible) = self.validLayout { self.paneArrangement = self.paneArrangement.withIndexTransition(0.0) - let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .animated(duration: 0.25, curve: .spring), interfaceState: interfaceState) + let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .animated(duration: 0.25, curve: .spring), interfaceState: interfaceState, isVisible: isVisible) } default: break diff --git a/TelegramUI/ChatMediaInputPane.swift b/TelegramUI/ChatMediaInputPane.swift index 6fe5c6cf74..e45b0e7ce3 100644 --- a/TelegramUI/ChatMediaInputPane.swift +++ b/TelegramUI/ChatMediaInputPane.swift @@ -10,6 +10,6 @@ struct ChatMediaInputPaneScrollState { class ChatMediaInputPane: ASDisplayNode { var collectionListPanelOffset: CGFloat = 0.0 - func updateLayout(size: CGSize, topInset: CGFloat, bottomInset: CGFloat, isExpanded: Bool, transition: ContainedViewLayoutTransition) { + func updateLayout(size: CGSize, topInset: CGFloat, bottomInset: CGFloat, isExpanded: Bool, isVisible: Bool, transition: ContainedViewLayoutTransition) { } } diff --git a/TelegramUI/ChatMediaInputPeerSpecificItem.swift b/TelegramUI/ChatMediaInputPeerSpecificItem.swift index aa055998d9..cc8e9730d1 100644 --- a/TelegramUI/ChatMediaInputPeerSpecificItem.swift +++ b/TelegramUI/ChatMediaInputPeerSpecificItem.swift @@ -26,7 +26,7 @@ final class ChatMediaInputPeerSpecificItem: ListViewItem { self.theme = theme } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatMediaInputPeerSpecificItemNode() node.contentSize = boundingSize @@ -34,7 +34,7 @@ final class ChatMediaInputPeerSpecificItem: ListViewItem { node.inputNodeInteraction = self.inputNodeInteraction Queue.mainQueue().async { completion(node, { - return (nil, { + return (nil, { _ in node.updateItem(account: self.account, peer: self.peer, collectionId: self.collectionId, theme: self.theme) node.updateAppearanceTransition(transition: .immediate) }) @@ -43,9 +43,9 @@ final class ChatMediaInputPeerSpecificItem: ListViewItem { } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { - completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { + completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { _ in (node() as? ChatMediaInputPeerSpecificItemNode)?.updateItem(account: self.account, peer: self.peer, collectionId: self.collectionId, theme: self.theme) }) } diff --git a/TelegramUI/ChatMediaInputRecentGifsItem.swift b/TelegramUI/ChatMediaInputRecentGifsItem.swift index 06e0e46ecb..e6c7d35b18 100644 --- a/TelegramUI/ChatMediaInputRecentGifsItem.swift +++ b/TelegramUI/ChatMediaInputRecentGifsItem.swift @@ -20,7 +20,7 @@ final class ChatMediaInputRecentGifsItem: ListViewItem { self.theme = theme } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatMediaInputRecentGifsItemNode() node.contentSize = CGSize(width: 41.0, height: 41.0) @@ -31,15 +31,15 @@ final class ChatMediaInputRecentGifsItem: ListViewItem { node.updateAppearanceTransition(transition: .immediate) Queue.mainQueue().async { completion(node, { - return (nil, {}) + return (nil, { _ in }) }) } } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { - completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { + completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { _ in (node() as? ChatMediaInputRecentGifsItemNode)?.updateTheme(theme: self.theme) }) } diff --git a/TelegramUI/ChatMediaInputSettingsItem.swift b/TelegramUI/ChatMediaInputSettingsItem.swift index 1eaaa108f3..f7b1fb3a00 100644 --- a/TelegramUI/ChatMediaInputSettingsItem.swift +++ b/TelegramUI/ChatMediaInputSettingsItem.swift @@ -20,7 +20,7 @@ final class ChatMediaInputSettingsItem: ListViewItem { self.theme = theme } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatMediaInputSettingsItemNode() node.contentSize = CGSize(width: 41.0, height: 41.0) @@ -30,15 +30,15 @@ final class ChatMediaInputSettingsItem: ListViewItem { node.updateAppearanceTransition(transition: .immediate) Queue.mainQueue().async { completion(node, { - return (nil, {}) + return (nil, { _ in }) }) } } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { - completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { + completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { _ in (node() as? ChatMediaInputSettingsItemNode)?.updateTheme(theme: self.theme) }) } diff --git a/TelegramUI/ChatMediaInputStickerGridItem.swift b/TelegramUI/ChatMediaInputStickerGridItem.swift index 82e452a79e..a5d54411c0 100644 --- a/TelegramUI/ChatMediaInputStickerGridItem.swift +++ b/TelegramUI/ChatMediaInputStickerGridItem.swift @@ -134,6 +134,7 @@ final class ChatMediaInputStickerGridItem: GridItem { final class ChatMediaInputStickerGridItemNode: GridItemNode { private var currentState: (Account, StickerPackItem, CGSize)? + private var currentSize: CGSize? private let imageNode: TransformImageNode private let stickerFetchedDisposable = MetaDisposable() @@ -167,31 +168,35 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode { } func setup(account: Account, stickerItem: StickerPackItem) { - if self.currentState == nil || self.currentState!.0 !== account || self.currentState!.1 != stickerItem { - if let dimensions = stickerItem.file.dimensions { - self.imageNode.setSignal(chatMessageSticker(account: account, file: stickerItem.file, small: true)) - self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, fileReference: stickerPackFileReference(stickerItem.file), resource: chatMessageStickerResource(file: stickerItem.file, small: true)).start()) - - self.currentState = (account, stickerItem, dimensions) - self.setNeedsLayout() - } - } - //self.updateSelectionState(animated: false) //self.updateHiddenMedia() } - override func layout() { - super.layout() + override func updateLayout(item: GridItem, size: CGSize, isVisible: Bool, synchronousLoads: Bool) { + guard let item = item as? ChatMediaInputStickerGridItem else { + return + } + if self.currentState == nil || self.currentState!.0 !== item.account || self.currentState!.1 != item.stickerItem { + if let dimensions = item.stickerItem.file.dimensions { + self.imageNode.setSignal(chatMessageSticker(account: item.account, file: item.stickerItem.file, small: true, synchronousLoad: synchronousLoads && isVisible)) + self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.account, fileReference: stickerPackFileReference(item.stickerItem.file), resource: chatMessageStickerResource(file: item.stickerItem.file, small: true)).start()) + + self.currentState = (item.account, item.stickerItem, dimensions) + self.setNeedsLayout() + } + } - let bounds = self.bounds - let sideSize: CGFloat = min(75.0 - 10.0, bounds.width) - let boundingSize = CGSize(width: sideSize, height: sideSize) - - if let (_, _, mediaDimensions) = self.currentState { - let imageSize = mediaDimensions.aspectFitted(boundingSize) - self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets()))() - self.imageNode.frame = CGRect(origin: CGPoint(x: floor((bounds.size.width - imageSize.width) / 2.0), y: (bounds.size.height - imageSize.height) / 2.0), size: imageSize) + if self.currentSize != size { + self.currentSize = size + + let sideSize: CGFloat = min(75.0 - 10.0, size.width) + let boundingSize = CGSize(width: sideSize, height: sideSize) + + if let (_, _, mediaDimensions) = self.currentState { + let imageSize = mediaDimensions.aspectFitted(boundingSize) + self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets()))() + self.imageNode.frame = CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: (size.height - imageSize.height) / 2.0), size: imageSize) + } } } diff --git a/TelegramUI/ChatMediaInputStickerPackItem.swift b/TelegramUI/ChatMediaInputStickerPackItem.swift index a3bec90ce6..4b73a92ad4 100644 --- a/TelegramUI/ChatMediaInputStickerPackItem.swift +++ b/TelegramUI/ChatMediaInputStickerPackItem.swift @@ -28,7 +28,7 @@ final class ChatMediaInputStickerPackItem: ListViewItem { self.theme = theme } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatMediaInputStickerPackItemNode() node.contentSize = boundingSize @@ -36,7 +36,7 @@ final class ChatMediaInputStickerPackItem: ListViewItem { node.inputNodeInteraction = self.inputNodeInteraction Queue.mainQueue().async { completion(node, { - return (nil, { + return (nil, { _ in node.updateStickerPackItem(account: self.account, item: self.stickerPackItem, collectionId: self.collectionId, theme: self.theme) node.updateAppearanceTransition(transition: .immediate) }) @@ -45,9 +45,9 @@ final class ChatMediaInputStickerPackItem: ListViewItem { } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { - completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { + completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { _ in (node() as? ChatMediaInputStickerPackItemNode)?.updateStickerPackItem(account: self.account, item: self.stickerPackItem, collectionId: self.collectionId, theme: self.theme) }) } diff --git a/TelegramUI/ChatMediaInputStickerPane.swift b/TelegramUI/ChatMediaInputStickerPane.swift index 309bfb75a8..4d300b2e42 100644 --- a/TelegramUI/ChatMediaInputStickerPane.swift +++ b/TelegramUI/ChatMediaInputStickerPane.swift @@ -15,6 +15,7 @@ final class ChatMediaInputStickerPaneOpaqueState { final class ChatMediaInputStickerPane: ChatMediaInputPane { private var isExpanded: Bool? + private var isPaneVisible = false let gridNode: GridNode private let paneDidScroll: (ChatMediaInputPane, ChatMediaInputPaneScrollState, ContainedViewLayoutTransition) -> Void private let fixPaneScroll: (ChatMediaInputPane, ChatMediaInputPaneScrollState) -> Void @@ -58,7 +59,7 @@ final class ChatMediaInputStickerPane: ChatMediaInputPane { self.gridNode.scrollView.alwaysBounceVertical = true } - override func updateLayout(size: CGSize, topInset: CGFloat, bottomInset: CGFloat, isExpanded: Bool, transition: ContainedViewLayoutTransition) { + override func updateLayout(size: CGSize, topInset: CGFloat, bottomInset: CGFloat, isExpanded: Bool, isVisible: Bool, transition: ContainedViewLayoutTransition) { var changedIsExpanded = false if let previousIsExpanded = self.isExpanded { if previousIsExpanded != isExpanded { @@ -70,7 +71,7 @@ final class ChatMediaInputStickerPane: ChatMediaInputPane { let sideInset: CGFloat = 2.0 var itemSide: CGFloat = floor((size.width - sideInset * 2.0) / 5.0) itemSide = min(itemSide, 75.0) - let itemSize = CGSize(width: itemSide, height: itemSide) + let itemSize = CGSize(width: itemSide, height: max(itemSide, 80.0)) var scrollToItem: GridNodeScrollToItem? if changedIsExpanded { @@ -98,13 +99,23 @@ final class ChatMediaInputStickerPane: ChatMediaInputPane { } } } - self.gridNode.transaction(GridNodeTransaction(deleteItems: [], insertItems: [], updateItems: [], scrollToItem: scrollToItem, updateLayout: GridNodeUpdateLayout(layout: GridNodeLayout(size: size, insets: UIEdgeInsets(top: topInset, left: sideInset, bottom: bottomInset, right: sideInset), preloadSize: 300.0, type: .fixed(itemSize: itemSize, lineSpacing: 0.0)), transition: transition), itemTransition: .immediate, stationaryItems: .none, updateFirstIndexInSectionOffset: nil), completion: { _ in }) + self.gridNode.transaction(GridNodeTransaction(deleteItems: [], insertItems: [], updateItems: [], scrollToItem: scrollToItem, updateLayout: GridNodeUpdateLayout(layout: GridNodeLayout(size: size, insets: UIEdgeInsets(top: topInset, left: sideInset, bottom: bottomInset, right: sideInset), preloadSize: isVisible ? 300.0 : 0.0, type: .fixed(itemSize: itemSize, lineSpacing: 0.0)), transition: transition), itemTransition: .immediate, stationaryItems: .none, updateFirstIndexInSectionOffset: nil), completion: { _ in }) if false, let scrollToItem = scrollToItem { self.gridNode.transaction(GridNodeTransaction(deleteItems: [], insertItems: [], updateItems: [], scrollToItem: scrollToItem, updateLayout: nil, itemTransition: .immediate, stationaryItems: .none, updateFirstIndexInSectionOffset: nil), completion: { _ in }) } transition.updateFrame(node: self.gridNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: size.height))) + + if self.isPaneVisible != isVisible { + self.isPaneVisible = isVisible + if isVisible { + self.gridNode.forEachItemNode { itemNode in + if let _ = itemNode as? ChatMediaInputStickerGridItemNode { + } + } + } + } } func itemAt(point: CGPoint) -> (ASDisplayNode, StickerPackItem)? { diff --git a/TelegramUI/ChatMediaInputTrendingItem.swift b/TelegramUI/ChatMediaInputTrendingItem.swift index b3f9d1e217..70e1186c6e 100644 --- a/TelegramUI/ChatMediaInputTrendingItem.swift +++ b/TelegramUI/ChatMediaInputTrendingItem.swift @@ -20,7 +20,7 @@ final class ChatMediaInputTrendingItem: ListViewItem { self.theme = theme } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatMediaInputTrendingItemNode() node.contentSize = CGSize(width: 41.0, height: 41.0) @@ -31,15 +31,15 @@ final class ChatMediaInputTrendingItem: ListViewItem { node.updateAppearanceTransition(transition: .immediate) Queue.mainQueue().async { completion(node, { - return (nil, {}) + return (nil, { _ in }) }) } } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { - completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { + completion(ListViewItemNodeLayout(contentSize: node().contentSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { _ in (node() as? ChatMediaInputTrendingItemNode)?.updateTheme(theme: self.theme) }) } diff --git a/TelegramUI/ChatMediaInputTrendingPane.swift b/TelegramUI/ChatMediaInputTrendingPane.swift index 2f0ec5e611..fe2c043d21 100644 --- a/TelegramUI/ChatMediaInputTrendingPane.swift +++ b/TelegramUI/ChatMediaInputTrendingPane.swift @@ -103,6 +103,12 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane { private var disposable: Disposable? private var isActivated = false + private let _ready = Promise() + private var didSetReady = false + var ready: Signal { + return self._ready.get() + } + var scrollingInitiated: (() -> Void)? init(account: Account, controllerInteraction: ChatControllerInteraction, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool) { @@ -189,11 +195,18 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane { return preparedTransition(from: previous ?? [], to: entries, account: account, theme: presentationData.theme, strings: presentationData.strings, interaction: interaction, initial: previous == nil) } |> deliverOnMainQueue).start(next: { [weak self] transition in - self?.enqueueTransition(transition) + guard let strongSelf = self else { + return + } + strongSelf.enqueueTransition(transition) + if !strongSelf.didSetReady { + strongSelf.didSetReady = true + strongSelf._ready.set(.single(Void())) + } }) } - override func updateLayout(size: CGSize, topInset: CGFloat, bottomInset: CGFloat, isExpanded: Bool, transition: ContainedViewLayoutTransition) { + override func updateLayout(size: CGSize, topInset: CGFloat, bottomInset: CGFloat, isExpanded: Bool, isVisible: Bool, transition: ContainedViewLayoutTransition) { let hadValidLayout = self.validLayout != nil self.validLayout = (size, bottomInset) @@ -224,7 +237,7 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane { } private func enqueueTransition(_ transition: TrendingPaneTransition) { - enqueuedTransitions.append(transition) + self.enqueuedTransitions.append(transition) if self.validLayout != nil { while !self.enqueuedTransitions.isEmpty { @@ -245,8 +258,9 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane { var options = ListViewDeleteAndInsertOptions() if transition.initial { - //options.insert(.Synchronous) - //options.insert(.LowLatency) + options.insert(.Synchronous) + options.insert(.LowLatency) + options.insert(.PreferSynchronousResourceLoading) } else { options.insert(.AnimateInsertion) } diff --git a/TelegramUI/ChatMessageInteractiveMediaNode.swift b/TelegramUI/ChatMessageInteractiveMediaNode.swift index 51fb14fa9c..42cf1f00ca 100644 --- a/TelegramUI/ChatMessageInteractiveMediaNode.swift +++ b/TelegramUI/ChatMessageInteractiveMediaNode.swift @@ -439,6 +439,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode { var statusFrame = statusNode.frame statusFrame.origin.x = floor(imageFrame.midX - statusFrame.width / 2.0) statusFrame.origin.y = floor(imageFrame.midY - statusFrame.height / 2.0) + statusNode.frame = statusFrame } if let replaceVideoNode = replaceVideoNode { diff --git a/TelegramUI/ChatMessageItem.swift b/TelegramUI/ChatMessageItem.swift index c82e63dadd..28f9dfee33 100644 --- a/TelegramUI/ChatMessageItem.swift +++ b/TelegramUI/ChatMessageItem.swift @@ -314,7 +314,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible { self.accessoryItem = accessoryItem } - public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { var viewClassName: AnyClass = ChatMessageBubbleItemNode.self loop: for media in message.media { @@ -356,7 +356,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible { Queue.mainQueue().async { completion(node, { - return (nil, { apply(.None, synchronousLoads) }) + return (nil, { _ in apply(.None, synchronousLoads) }) }) } } @@ -400,7 +400,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible { return (mergedTop, mergedBottom, dateAtBottom) } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ChatMessageItemView { nodeValue.setupItem(self) @@ -412,7 +412,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible { let (layout, apply) = nodeLayout(self, params, top, bottom, dateAtBottom && !self.disableDate) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation, false) if let nodeValue = node() as? ChatMessageItemView { nodeValue.updateSelectionState(animated: false) diff --git a/TelegramUI/ChatPanelInterfaceInteraction.swift b/TelegramUI/ChatPanelInterfaceInteraction.swift index ca81ae50b9..bea6418dc1 100644 --- a/TelegramUI/ChatPanelInterfaceInteraction.swift +++ b/TelegramUI/ChatPanelInterfaceInteraction.swift @@ -49,6 +49,7 @@ final class ChatPanelInterfaceInteraction { let shareSelectedMessages: () -> Void let updateTextInputStateAndMode: (@escaping (ChatTextInputState, ChatInputMode) -> (ChatTextInputState, ChatInputMode)) -> Void let updateInputModeAndDismissedButtonKeyboardMessageId: ((ChatPresentationInterfaceState) -> (ChatInputMode, MessageId?)) -> Void + let openStickers: () -> Void let editMessage: () -> Void let beginMessageSearch: (ChatSearchDomain, String) -> Void let dismissMessageSearch: () -> Void @@ -90,7 +91,7 @@ final class ChatPanelInterfaceInteraction { let toggleSilentPost: () -> Void let statuses: ChatPanelInterfaceInteractionStatuses? - init(setupReplyMessage: @escaping (MessageId) -> Void, setupEditMessage: @escaping (MessageId?) -> Void, beginMessageSelection: @escaping ([MessageId]) -> Void, deleteSelectedMessages: @escaping () -> Void, reportSelectedMessages: @escaping () -> Void, reportMessages: @escaping ([Message]) -> Void, deleteMessages: @escaping ([Message]) -> Void, forwardSelectedMessages: @escaping () -> Void, forwardMessages: @escaping ([Message]) -> Void, shareSelectedMessages: @escaping () -> Void, updateTextInputStateAndMode: @escaping ((ChatTextInputState, ChatInputMode) -> (ChatTextInputState, ChatInputMode)) -> Void, updateInputModeAndDismissedButtonKeyboardMessageId: @escaping ((ChatPresentationInterfaceState) -> (ChatInputMode, MessageId?)) -> Void, editMessage: @escaping () -> Void, beginMessageSearch: @escaping (ChatSearchDomain, String) -> Void, dismissMessageSearch: @escaping () -> Void, updateMessageSearch: @escaping (String) -> Void, navigateMessageSearch: @escaping (ChatPanelSearchNavigationAction) -> Void, openCalendarSearch: @escaping () -> Void, toggleMembersSearch: @escaping (Bool) -> Void, navigateToMessage: @escaping (MessageId) -> Void, openPeerInfo: @escaping () -> Void, togglePeerNotifications: @escaping () -> Void, sendContextResult: @escaping (ChatContextResultCollection, ChatContextResult) -> Void, sendBotCommand: @escaping (Peer, String) -> Void, sendBotStart: @escaping (String?) -> Void, botSwitchChatWithPayload: @escaping (PeerId, String) -> Void, beginMediaRecording: @escaping (Bool) -> Void, finishMediaRecording: @escaping (ChatFinishMediaRecordingAction) -> Void, stopMediaRecording: @escaping () -> Void, lockMediaRecording: @escaping () -> Void, deleteRecordedMedia: @escaping () -> Void, sendRecordedMedia: @escaping () -> Void, displayRestrictedInfo: @escaping (ChatPanelRestrictionInfoSubject) -> Void, switchMediaRecordingMode: @escaping () -> Void, setupMessageAutoremoveTimeout: @escaping () -> Void, sendSticker: @escaping (FileMediaReference) -> Void, unblockPeer: @escaping () -> Void, pinMessage: @escaping (MessageId) -> Void, unpinMessage: @escaping () -> Void, reportPeer: @escaping () -> Void, presentPeerContact: @escaping () -> Void, dismissReportPeer: @escaping () -> Void, deleteChat: @escaping () -> Void, beginCall: @escaping () -> Void, toggleMessageStickerStarred: @escaping (MessageId) -> Void, presentController: @escaping (ViewController, Any?) -> Void, getNavigationController: @escaping () -> NavigationController?, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, navigateFeed: @escaping () -> Void, openGrouping: @escaping () -> Void, toggleSilentPost: @escaping () -> Void, statuses: ChatPanelInterfaceInteractionStatuses?) { + init(setupReplyMessage: @escaping (MessageId) -> Void, setupEditMessage: @escaping (MessageId?) -> Void, beginMessageSelection: @escaping ([MessageId]) -> Void, deleteSelectedMessages: @escaping () -> Void, reportSelectedMessages: @escaping () -> Void, reportMessages: @escaping ([Message]) -> Void, deleteMessages: @escaping ([Message]) -> Void, forwardSelectedMessages: @escaping () -> Void, forwardMessages: @escaping ([Message]) -> Void, shareSelectedMessages: @escaping () -> Void, updateTextInputStateAndMode: @escaping ((ChatTextInputState, ChatInputMode) -> (ChatTextInputState, ChatInputMode)) -> Void, updateInputModeAndDismissedButtonKeyboardMessageId: @escaping ((ChatPresentationInterfaceState) -> (ChatInputMode, MessageId?)) -> Void, openStickers: @escaping () -> Void, editMessage: @escaping () -> Void, beginMessageSearch: @escaping (ChatSearchDomain, String) -> Void, dismissMessageSearch: @escaping () -> Void, updateMessageSearch: @escaping (String) -> Void, navigateMessageSearch: @escaping (ChatPanelSearchNavigationAction) -> Void, openCalendarSearch: @escaping () -> Void, toggleMembersSearch: @escaping (Bool) -> Void, navigateToMessage: @escaping (MessageId) -> Void, openPeerInfo: @escaping () -> Void, togglePeerNotifications: @escaping () -> Void, sendContextResult: @escaping (ChatContextResultCollection, ChatContextResult) -> Void, sendBotCommand: @escaping (Peer, String) -> Void, sendBotStart: @escaping (String?) -> Void, botSwitchChatWithPayload: @escaping (PeerId, String) -> Void, beginMediaRecording: @escaping (Bool) -> Void, finishMediaRecording: @escaping (ChatFinishMediaRecordingAction) -> Void, stopMediaRecording: @escaping () -> Void, lockMediaRecording: @escaping () -> Void, deleteRecordedMedia: @escaping () -> Void, sendRecordedMedia: @escaping () -> Void, displayRestrictedInfo: @escaping (ChatPanelRestrictionInfoSubject) -> Void, switchMediaRecordingMode: @escaping () -> Void, setupMessageAutoremoveTimeout: @escaping () -> Void, sendSticker: @escaping (FileMediaReference) -> Void, unblockPeer: @escaping () -> Void, pinMessage: @escaping (MessageId) -> Void, unpinMessage: @escaping () -> Void, reportPeer: @escaping () -> Void, presentPeerContact: @escaping () -> Void, dismissReportPeer: @escaping () -> Void, deleteChat: @escaping () -> Void, beginCall: @escaping () -> Void, toggleMessageStickerStarred: @escaping (MessageId) -> Void, presentController: @escaping (ViewController, Any?) -> Void, getNavigationController: @escaping () -> NavigationController?, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, navigateFeed: @escaping () -> Void, openGrouping: @escaping () -> Void, toggleSilentPost: @escaping () -> Void, statuses: ChatPanelInterfaceInteractionStatuses?) { self.setupReplyMessage = setupReplyMessage self.setupEditMessage = setupEditMessage self.beginMessageSelection = beginMessageSelection @@ -103,6 +104,7 @@ final class ChatPanelInterfaceInteraction { self.shareSelectedMessages = shareSelectedMessages self.updateTextInputStateAndMode = updateTextInputStateAndMode self.updateInputModeAndDismissedButtonKeyboardMessageId = updateInputModeAndDismissedButtonKeyboardMessageId + self.openStickers = openStickers self.editMessage = editMessage self.beginMessageSearch = beginMessageSearch self.dismissMessageSearch = dismissMessageSearch diff --git a/TelegramUI/ChatRecentActionsController.swift b/TelegramUI/ChatRecentActionsController.swift index 073fcedb02..82dfea5df8 100644 --- a/TelegramUI/ChatRecentActionsController.swift +++ b/TelegramUI/ChatRecentActionsController.swift @@ -48,6 +48,7 @@ final class ChatRecentActionsController: TelegramController { }, shareSelectedMessages: { }, updateTextInputStateAndMode: { _ in }, updateInputModeAndDismissedButtonKeyboardMessageId: { _ in + }, openStickers: { }, editMessage: { }, beginMessageSearch: { _, _ in }, dismissMessageSearch: { diff --git a/TelegramUI/ChatRecentActionsControllerNode.swift b/TelegramUI/ChatRecentActionsControllerNode.swift index fbe4076e11..d74218a9c1 100644 --- a/TelegramUI/ChatRecentActionsControllerNode.swift +++ b/TelegramUI/ChatRecentActionsControllerNode.swift @@ -734,7 +734,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { }), nil) case let .localization(identifier): strongSelf.presentController(LanguageLinkPreviewController(account: strongSelf.account, identifier: identifier), nil) - case .proxy, .confirmationCode: + case .proxy, .confirmationCode, .cancelAccountReset, .share: openResolvedUrl(result, account: strongSelf.account, navigationController: strongSelf.getNavigationController(), openPeer: { peerId, _ in if let strongSelf = self { strongSelf.openPeer(peerId: peerId, peer: nil) diff --git a/TelegramUI/ChatTextInputPanelNode.swift b/TelegramUI/ChatTextInputPanelNode.swift index 3a85cd2e9c..c5ddcc9b58 100644 --- a/TelegramUI/ChatTextInputPanelNode.swift +++ b/TelegramUI/ChatTextInputPanelNode.swift @@ -1425,9 +1425,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { switch item { case let .stickers(enabled): if enabled { - self.interfaceInteraction?.updateInputModeAndDismissedButtonKeyboardMessageId({ state in - return (.media(mode: .other, expanded: nil), state.interfaceState.messageActionsState.closedButtonKeyboardMessageId) - }) + self.interfaceInteraction?.openStickers() } else { self.interfaceInteraction?.displayRestrictedInfo(.stickers) } diff --git a/TelegramUI/ChatUnreadItem.swift b/TelegramUI/ChatUnreadItem.swift index 4bdf4de685..25fd8fe719 100644 --- a/TelegramUI/ChatUnreadItem.swift +++ b/TelegramUI/ChatUnreadItem.swift @@ -18,19 +18,19 @@ class ChatUnreadItem: ListViewItem { self.header = ChatMessageDateHeader(timestamp: index.timestamp, presentationData: presentationData) } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatUnreadItemNode() node.layoutForParams(params, item: self, previousItem: previousItem, nextItem: nextItem) Queue.mainQueue().async { completion(node, { - return (nil, {}) + return (nil, { _ in }) }) } } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ChatUnreadItemNode { let nodeLayout = nodeValue.asyncLayout() @@ -40,7 +40,7 @@ class ChatUnreadItem: ListViewItem { let (layout, apply) = nodeLayout(self, params, dateAtBottom) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/CommandChatInputPanelItem.swift b/TelegramUI/CommandChatInputPanelItem.swift index 44e897a764..cb410f59ce 100644 --- a/TelegramUI/CommandChatInputPanelItem.swift +++ b/TelegramUI/CommandChatInputPanelItem.swift @@ -20,7 +20,7 @@ final class CommandChatInputPanelItem: ListViewItem { self.commandSelected = commandSelected } - public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { let configure = { () -> Void in let node = CommandChatInputPanelItemNode() @@ -33,7 +33,7 @@ final class CommandChatInputPanelItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(.None) }) + return (nil, { _ in apply(.None) }) }) } } @@ -46,7 +46,7 @@ final class CommandChatInputPanelItem: ListViewItem { } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? CommandChatInputPanelItemNode { let nodeLayout = nodeValue.asyncLayout() @@ -56,7 +56,7 @@ final class CommandChatInputPanelItem: ListViewItem { let (layout, apply) = nodeLayout(self, params, top, bottom) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation) }) } diff --git a/TelegramUI/ConfirmPhoneNumberController.swift b/TelegramUI/ConfirmPhoneNumberController.swift new file mode 100644 index 0000000000..811ccfa9ba --- /dev/null +++ b/TelegramUI/ConfirmPhoneNumberController.swift @@ -0,0 +1,331 @@ +import Foundation +import Display +import SwiftSignalKit +import Postbox +import TelegramCore + +private final class ConfirmPhoneNumberCodeControllerArguments { + let updateEntryText: (String) -> Void + let next: () -> Void + + init(updateEntryText: @escaping (String) -> Void, next: @escaping () -> Void) { + self.updateEntryText = updateEntryText + self.next = next + } +} + +private enum ConfirmPhoneNumberCodeSection: Int32 { + case code +} + +private enum ConfirmPhoneNumberCodeTag: ItemListItemTag { + case input + + func isEqual(to other: ItemListItemTag) -> Bool { + if let other = other as? ConfirmPhoneNumberCodeTag { + switch self { + case .input: + if case .input = other { + return true + } else { + return false + } + } + } else { + return false + } + } +} + +private enum ConfirmPhoneNumberCodeEntry: ItemListNodeEntry { + case codeEntry(PresentationTheme, String, String) + case codeInfo(PresentationTheme, PresentationStrings, String, String) + + var section: ItemListSectionId { + return ConfirmPhoneNumberCodeSection.code.rawValue + } + + var stableId: Int32 { + switch self { + case .codeEntry: + return 1 + case .codeInfo: + return 2 + } + } + + static func ==(lhs: ConfirmPhoneNumberCodeEntry, rhs: ConfirmPhoneNumberCodeEntry) -> Bool { + switch lhs { + case let .codeEntry(lhsTheme, lhsTitle, lhsText): + if case let .codeEntry(rhsTheme, rhsTitle, rhsText) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle, lhsText == rhsText { + return true + } else { + return false + } + case let .codeInfo(lhsTheme, lhsStrings, lhsPhoneNumber, lhsText): + if case let .codeInfo(rhsTheme, rhsStrings, rhsPhoneNumber, rhsText) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsPhoneNumber == rhsPhoneNumber, lhsText == rhsText { + return true + } else { + return false + } + } + } + + static func <(lhs: ConfirmPhoneNumberCodeEntry, rhs: ConfirmPhoneNumberCodeEntry) -> Bool { + return lhs.stableId < rhs.stableId + } + + func item(_ arguments: ConfirmPhoneNumberCodeControllerArguments) -> ListViewItem { + switch self { + case let .codeEntry(theme, title, text): + return ItemListSingleLineInputItem(theme: theme, title: NSAttributedString(string: title, textColor: .black), text: text, placeholder: "", type: .number, spacing: 10.0, tag: ConfirmPhoneNumberCodeTag.input, sectionId: self.section, textUpdated: { updatedText in + arguments.updateEntryText(updatedText) + }, action: { + arguments.next() + }) + case let .codeInfo(theme, strings, phoneNumber, nextOptionText): + let formattedNumber = formatPhoneNumber(phoneNumber) + let stringAndRanges = strings.CancelResetAccount_TextSMS(formattedNumber) + var result = "" + result += stringAndRanges.0 + if let range = result.range(of: formattedNumber) { + result.insert("*", at: range.upperBound) + result.insert("*", at: range.upperBound) + result.insert("*", at: range.lowerBound) + result.insert("*", at: range.lowerBound) + } + if !nextOptionText.isEmpty { + result += "\n\n" + nextOptionText + } + return ItemListTextItem(theme: theme, text: .markdown(result), sectionId: self.section) + } + } +} + +private struct ConfirmPhoneNumberCodeControllerState: Equatable { + var codeText: String + var checking: Bool + + init(codeText: String, checking: Bool) { + self.codeText = codeText + self.checking = checking + } +} + +private func confirmPhoneNumberCodeControllerEntries(presentationData: PresentationData, state: ConfirmPhoneNumberCodeControllerState, phoneNumber: String, codeData: CancelAccountResetData, timeout: Int32?, strings: PresentationStrings, theme: AuthorizationTheme) -> [ConfirmPhoneNumberCodeEntry] { + var entries: [ConfirmPhoneNumberCodeEntry] = [] + + entries.append(.codeEntry(presentationData.theme, presentationData.strings.ChangePhoneNumberCode_CodePlaceholder, state.codeText)) + var text = "" + if let nextType = codeData.nextType { + text += authorizationNextOptionText(currentType: codeData.type, nextType: nextType, timeout: timeout, strings: presentationData.strings, primaryColor: .black, accentColor: .black).0.string + } + entries.append(.codeInfo(presentationData.theme, presentationData.strings, phoneNumber, text)) + + return entries +} + +private func timeoutSignal(codeData: CancelAccountResetData) -> Signal { + if let _ = codeData.nextType, let timeout = codeData.timeout { + return Signal { subscriber in + let value = Atomic(value: timeout) + subscriber.putNext(timeout) + + let timer = SwiftSignalKit.Timer(timeout: 1.0, repeat: true, completion: { + subscriber.putNext(value.modify { value in + return max(0, value - 1) + }) + }, queue: Queue.mainQueue()) + timer.start() + + return ActionDisposable { + timer.invalidate() + } + } + } else { + return .single(nil) + } +} + +protocol ConfirmPhoneNumberCodeController: class { + func applyCode(_ code: Int) +} + +private final class ConfirmPhoneNumberCodeControllerImpl: ItemListController, ConfirmPhoneNumberCodeController { + private let applyCodeImpl: (Int) -> Void + + init(account: Account, state: Signal<(ItemListControllerState, (ItemListNodeState, ConfirmPhoneNumberCodeEntry.ItemGenerationArguments)), NoError>, applyCodeImpl: @escaping (Int) -> Void) { + self.applyCodeImpl = applyCodeImpl + + let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } + super.init(theme: presentationData.theme, strings: presentationData.strings, updatedPresentationData: account.telegramApplicationContext.presentationData |> map { ($0.theme, $0.strings) }, state: state, tabBarItem: nil) + } + + required init(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func applyCode(_ code: Int) { + self.applyCodeImpl(code) + } +} + +func confirmPhoneNumberCodeController(account: Account, phoneNumber: String, codeData: CancelAccountResetData) -> ViewController { + let initialState = ConfirmPhoneNumberCodeControllerState(codeText: "", checking: false) + + let statePromise = ValuePromise(initialState, ignoreRepeated: true) + let stateValue = Atomic(value: initialState) + let updateState: ((ConfirmPhoneNumberCodeControllerState) -> ConfirmPhoneNumberCodeControllerState) -> Void = { f in + statePromise.set(stateValue.modify { f($0) }) + } + + var dismissImpl: (() -> Void)? + var presentControllerImpl: ((ViewController, Any?) -> Void)? + + let actionsDisposable = DisposableSet() + + let confirmPhoneDisposable = MetaDisposable() + actionsDisposable.add(confirmPhoneDisposable) + + let nextTypeDisposable = MetaDisposable() + actionsDisposable.add(nextTypeDisposable) + + let currentDataPromise = Promise() + currentDataPromise.set(.single(codeData)) + + let timeout = Promise() + timeout.set(currentDataPromise.get() + |> mapToSignal(timeoutSignal)) + + let resendCode = currentDataPromise.get() + |> mapToSignal { [weak currentDataPromise] data -> Signal in + if let _ = data.nextType { + return timeout.get() + |> filter { $0 == 0 } + |> take(1) + |> mapToSignal { _ -> Signal in + return Signal { subscriber in + return requestNextCancelAccountResetOption(network: account.network, phoneNumber: phoneNumber, phoneCodeHash: data.hash).start(next: { next in + currentDataPromise?.set(.single(next)) + }, error: { error in + + }) + } + } + } else { + return .complete() + } + } + nextTypeDisposable.set(resendCode.start()) + + let checkCode: () -> Void = { + var code: String? + updateState { state in + var state = state + if state.checking || state.codeText.isEmpty { + return state + } else { + code = state.codeText + state.checking = true + return state + } + } + if let code = code { + confirmPhoneDisposable.set((requestCancelAccountReset(network: account.network, phoneCodeHash: codeData.hash, phoneCode: code) + |> deliverOnMainQueue).start(error: { error in + updateState { state in + var state = state + state.checking = false + return state + } + let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } + let alertText: String + switch error { + case .generic: + alertText = presentationData.strings.Login_UnknownError + case .invalidCode: + alertText = presentationData.strings.Login_InvalidCodeError + case .codeExpired: + alertText = presentationData.strings.Login_CodeExpiredError + case .limitExceeded: + alertText = presentationData.strings.Login_CodeFloodError + } + presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: nil, text: alertText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) + }, completed: { + updateState { state in + var state = state + state.checking = false + return state + } + let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } + presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: nil, text: presentationData.strings.CancelResetAccount_Success(formatPhoneNumber(phoneNumber)).0, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) + dismissImpl?() + })) + } + } + + let arguments = ConfirmPhoneNumberCodeControllerArguments(updateEntryText: { updatedText in + var initiateCheck = false + updateState { state in + var state = state + if state.codeText.count < 5 && updatedText.count == 5 { + initiateCheck = true + } + state.codeText = updatedText + return state + } + if initiateCheck { + checkCode() + } + }, next: { + checkCode() + }) + + let signal = combineLatest((account.applicationContext as! TelegramApplicationContext).presentationData, statePromise.get() |> deliverOnMainQueue, currentDataPromise.get() |> deliverOnMainQueue, timeout.get() |> deliverOnMainQueue) + |> deliverOnMainQueue + |> map { presentationData, state, data, timeout -> (ItemListControllerState, (ItemListNodeState, ConfirmPhoneNumberCodeEntry.ItemGenerationArguments)) in + let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { + dismissImpl?() + }) + var rightNavigationButton: ItemListNavigationButton? + if state.checking { + rightNavigationButton = ItemListNavigationButton(content: .none, style: .activity, enabled: true, action: {}) + } else { + var nextEnabled = true + if state.codeText.isEmpty { + nextEnabled = false + } + rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Next), style: .bold, enabled: nextEnabled, action: { + checkCode() + }) + } + + let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.CancelResetAccount_Title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false) + let listState = ItemListNodeState(entries: confirmPhoneNumberCodeControllerEntries(presentationData: presentationData, state: state, phoneNumber: phoneNumber, codeData: data, timeout: timeout, strings: presentationData.strings, theme: defaultLightAuthorizationTheme), style: .blocks, focusItemTag: ConfirmPhoneNumberCodeTag.input, emptyStateItem: nil, animateChanges: false) + + return (controllerState, (listState, arguments)) + } + |> afterDisposed { + actionsDisposable.dispose() + } + + let controller = ConfirmPhoneNumberCodeControllerImpl(account: account, state: signal, applyCodeImpl: { code in + updateState { state in + var state = state + state.codeText = "\(code)" + return state + } + checkCode() + }) + + presentControllerImpl = { [weak controller] c, p in + if let controller = controller { + controller.present(c, in: .window(.root), with: p) + } + } + dismissImpl = { [weak controller] in + controller?.dismiss() + } + + return controller +} diff --git a/TelegramUI/ContactAddItem.swift b/TelegramUI/ContactAddItem.swift index 72eb2ded4f..bf10ae93cd 100644 --- a/TelegramUI/ContactAddItem.swift +++ b/TelegramUI/ContactAddItem.swift @@ -24,7 +24,7 @@ class ContactsAddItem: ListViewItem { self.header = header } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ContactsAddItemNode() let makeLayout = node.asyncLayout() @@ -34,12 +34,12 @@ class ContactsAddItem: ListViewItem { node.insets = nodeLayout.insets completion(node, { - return (nil, { nodeApply(false) }) + return (nil, { _ in nodeApply(false) }) }) } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ContactsAddItemNode { let layout = nodeValue.asyncLayout() @@ -47,7 +47,7 @@ class ContactsAddItem: ListViewItem { let (first, last, firstWithHeader) = ContactsAddItem.mergeType(item: self, previousItem: previousItem, nextItem: nextItem) let (nodeLayout, apply) = layout(self, params, first, last, firstWithHeader) Queue.mainQueue().async { - completion(nodeLayout, { + completion(nodeLayout, { _ in apply(animation.isAnimated) }) } diff --git a/TelegramUI/ContactListActionItem.swift b/TelegramUI/ContactListActionItem.swift index 03735892ed..31bfa6923f 100644 --- a/TelegramUI/ContactListActionItem.swift +++ b/TelegramUI/ContactListActionItem.swift @@ -18,7 +18,7 @@ class ContactListActionItem: ListViewItem { self.action = action } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ContactListActionItemNode() let (_, _, firstWithHeader) = ContactListActionItem.mergeType(item: self, previousItem: previousItem, nextItem: nextItem) @@ -29,13 +29,13 @@ class ContactListActionItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ContactListActionItemNode { let makeLayout = nodeValue.asyncLayout() @@ -44,7 +44,7 @@ class ContactListActionItem: ListViewItem { let (_, _, firstWithHeader) = ContactListActionItem.mergeType(item: self, previousItem: previousItem, nextItem: nextItem) let (layout, apply) = makeLayout(self, params, firstWithHeader) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ContactsPeerItem.swift b/TelegramUI/ContactsPeerItem.swift index 5279de07df..f1e4acff77 100644 --- a/TelegramUI/ContactsPeerItem.swift +++ b/TelegramUI/ContactsPeerItem.swift @@ -195,7 +195,7 @@ class ContactsPeerItem: ListViewItem { } } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ContactsPeerItemNode() let makeLayout = node.asyncLayout() @@ -207,7 +207,7 @@ class ContactsPeerItem: ListViewItem { Queue.mainQueue().async { completion(node, { let (signal, apply) = nodeApply() - return (signal, { + return (signal, { _ in apply(false, synchronousLoads) }) }) @@ -215,7 +215,7 @@ class ContactsPeerItem: ListViewItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ContactsPeerItemNode { let layout = nodeValue.asyncLayout() @@ -223,7 +223,7 @@ class ContactsPeerItem: ListViewItem { let (first, last, firstWithHeader) = ContactsPeerItem.mergeType(item: self, previousItem: previousItem, nextItem: nextItem) let (nodeLayout, apply) = layout(self, params, first, last, firstWithHeader) Queue.mainQueue().async { - completion(nodeLayout, { + completion(nodeLayout, { _ in apply().1(animation.isAnimated, false) }) } diff --git a/TelegramUI/EmojisChatInputPanelItem.swift b/TelegramUI/EmojisChatInputPanelItem.swift index 8cee508e0f..0550463d26 100644 --- a/TelegramUI/EmojisChatInputPanelItem.swift +++ b/TelegramUI/EmojisChatInputPanelItem.swift @@ -20,7 +20,7 @@ final class EmojisChatInputPanelItem: ListViewItem { self.hashtagSelected = hashtagSelected } - public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { let configure = { () -> Void in let node = EmojisChatInputPanelItemNode() @@ -33,7 +33,7 @@ final class EmojisChatInputPanelItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(.None) }) + return (nil, { _ in apply(.None) }) }) } } @@ -46,7 +46,7 @@ final class EmojisChatInputPanelItem: ListViewItem { } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? EmojisChatInputPanelItemNode { let nodeLayout = nodeValue.asyncLayout() @@ -56,7 +56,7 @@ final class EmojisChatInputPanelItem: ListViewItem { let (layout, apply) = nodeLayout(self, params, top, bottom) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation) }) } diff --git a/TelegramUI/ExternalMusicAlbumArtResources.swift b/TelegramUI/ExternalMusicAlbumArtResources.swift index 122d13037b..9a78302558 100644 --- a/TelegramUI/ExternalMusicAlbumArtResources.swift +++ b/TelegramUI/ExternalMusicAlbumArtResources.swift @@ -61,7 +61,7 @@ public class ExternalMusicAlbumArtResource: TelegramMediaResource { } } -private func urlEncodedStringFromString(_ string: String) -> String { +func urlEncodedStringFromString(_ string: String) -> String { var nsString: NSString = string as NSString if let value = nsString.replacingPercentEscapes(using: String.Encoding.utf8.rawValue) { nsString = value as NSString diff --git a/TelegramUI/GroupInfoController.swift b/TelegramUI/GroupInfoController.swift index 9de2b8657e..c68a6e4371 100644 --- a/TelegramUI/GroupInfoController.swift +++ b/TelegramUI/GroupInfoController.swift @@ -1096,11 +1096,7 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa } } else if let channel = view.peers[view.peerId] as? TelegramChannel { if case .member = channel.participationStatus, let cachedChannelData = view.cachedData as? CachedChannelData, let memberCount = cachedChannelData.participantsSummary.memberCount, memberCount <= 200 { - if channel.flags.contains(.isCreator) { - entries.append(.leave(presentationData.theme, presentationData.strings.GroupInfo_DeleteAndExit)) - } else { - entries.append(.leave(presentationData.theme, presentationData.strings.Group_LeaveGroup)) - } + entries.append(.leave(presentationData.theme, presentationData.strings.Group_LeaveGroup)) } } diff --git a/TelegramUI/GroupStickerPackCurrentItem.swift b/TelegramUI/GroupStickerPackCurrentItem.swift index cfffb7b949..a6d0ddec17 100644 --- a/TelegramUI/GroupStickerPackCurrentItem.swift +++ b/TelegramUI/GroupStickerPackCurrentItem.swift @@ -28,7 +28,7 @@ final class GroupStickerPackCurrentItem: ListViewItem, ItemListItem { self.action = action } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = GroupStickerPackCurrentItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -38,13 +38,13 @@ final class GroupStickerPackCurrentItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(false) }) + return (nil, { _ in apply(false) }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? GroupStickerPackCurrentItemNode { let makeLayout = nodeValue.asyncLayout() @@ -57,7 +57,7 @@ final class GroupStickerPackCurrentItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animated) }) } diff --git a/TelegramUI/HashtagChatInputPanelItem.swift b/TelegramUI/HashtagChatInputPanelItem.swift index f9c525a48c..e9b1a08c1e 100644 --- a/TelegramUI/HashtagChatInputPanelItem.swift +++ b/TelegramUI/HashtagChatInputPanelItem.swift @@ -18,7 +18,7 @@ final class HashtagChatInputPanelItem: ListViewItem { self.hashtagSelected = hashtagSelected } - public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { let configure = { () -> Void in let node = HashtagChatInputPanelItemNode() @@ -31,7 +31,7 @@ final class HashtagChatInputPanelItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(.None) }) + return (nil, { _ in apply(.None) }) }) } } @@ -44,7 +44,7 @@ final class HashtagChatInputPanelItem: ListViewItem { } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? HashtagChatInputPanelItemNode { let nodeLayout = nodeValue.asyncLayout() @@ -54,7 +54,7 @@ final class HashtagChatInputPanelItem: ListViewItem { let (layout, apply) = nodeLayout(self, params, top, bottom) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation) }) } diff --git a/TelegramUI/HorizontalListContextResultsChatInputPanelItem.swift b/TelegramUI/HorizontalListContextResultsChatInputPanelItem.swift index 1a646c4a17..a4be920a85 100644 --- a/TelegramUI/HorizontalListContextResultsChatInputPanelItem.swift +++ b/TelegramUI/HorizontalListContextResultsChatInputPanelItem.swift @@ -19,7 +19,7 @@ final class HorizontalListContextResultsChatInputPanelItem: ListViewItem { self.resultSelected = resultSelected } - public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { let configure = { () -> Void in let node = HorizontalListContextResultsChatInputPanelItemNode() @@ -32,7 +32,7 @@ final class HorizontalListContextResultsChatInputPanelItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(.None) }) + return (nil, { _ in apply(.None) }) }) } } @@ -45,7 +45,7 @@ final class HorizontalListContextResultsChatInputPanelItem: ListViewItem { } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? HorizontalListContextResultsChatInputPanelItemNode { let nodeLayout = nodeValue.asyncLayout() @@ -55,7 +55,7 @@ final class HorizontalListContextResultsChatInputPanelItem: ListViewItem { let (layout, apply) = nodeLayout(self, params, top, bottom) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation) }) } diff --git a/TelegramUI/HorizontalPeerItem.swift b/TelegramUI/HorizontalPeerItem.swift index c3c6f50c32..92fc5c223a 100644 --- a/TelegramUI/HorizontalPeerItem.swift +++ b/TelegramUI/HorizontalPeerItem.swift @@ -36,7 +36,7 @@ final class HorizontalPeerItem: ListViewItem { self.unreadBadge = unreadBadge } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = HorizontalPeerItemNode() @@ -47,7 +47,7 @@ final class HorizontalPeerItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { + return (nil, { _ in apply(false) }) }) @@ -55,7 +55,7 @@ final class HorizontalPeerItem: ListViewItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { assert(node() is HorizontalPeerItemNode) if let nodeValue = node() as? HorizontalPeerItemNode { @@ -63,7 +63,7 @@ final class HorizontalPeerItem: ListViewItem { async { let (nodeLayout, apply) = layout(self, params) Queue.mainQueue().async { - completion(nodeLayout, { + completion(nodeLayout, { _ in apply(animation.isAnimated) }) } diff --git a/TelegramUI/ItemListActionItem.swift b/TelegramUI/ItemListActionItem.swift index 1177fdefbb..68c325e81c 100644 --- a/TelegramUI/ItemListActionItem.swift +++ b/TelegramUI/ItemListActionItem.swift @@ -38,7 +38,7 @@ class ItemListActionItem: ListViewItem, ItemListItem { self.tag = tag } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListActionItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -48,13 +48,13 @@ class ItemListActionItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListActionItemNode { let makeLayout = nodeValue.asyncLayout() @@ -62,7 +62,7 @@ class ItemListActionItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ItemListActivityTextItem.swift b/TelegramUI/ItemListActivityTextItem.swift index 6c04c1ca89..3b58544f7b 100644 --- a/TelegramUI/ItemListActivityTextItem.swift +++ b/TelegramUI/ItemListActivityTextItem.swift @@ -18,7 +18,7 @@ class ItemListActivityTextItem: ListViewItem, ItemListItem { self.sectionId = sectionId } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListActivityTextItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -28,13 +28,13 @@ class ItemListActivityTextItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { guard let nodeValue = node() as? ItemListActivityTextItemNode else { assertionFailure() @@ -46,7 +46,7 @@ class ItemListActivityTextItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ItemListAvatarAndNameItem.swift b/TelegramUI/ItemListAvatarAndNameItem.swift index 9d65d33f11..8baee9f1da 100644 --- a/TelegramUI/ItemListAvatarAndNameItem.swift +++ b/TelegramUI/ItemListAvatarAndNameItem.swift @@ -201,7 +201,7 @@ class ItemListAvatarAndNameInfoItem: ListViewItem, ItemListItem { } } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListAvatarAndNameInfoItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -210,12 +210,12 @@ class ItemListAvatarAndNameInfoItem: ListViewItem, ItemListItem { node.insets = layout.insets completion(node, { - return (nil, { apply(false) }) + return (nil, { _ in apply(false) }) }) } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListAvatarAndNameInfoItemNode { var animated = true @@ -227,7 +227,7 @@ class ItemListAvatarAndNameInfoItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animated) }) } diff --git a/TelegramUI/ItemListCallListItem.swift b/TelegramUI/ItemListCallListItem.swift index 4038b39e04..4a30f0bcae 100644 --- a/TelegramUI/ItemListCallListItem.swift +++ b/TelegramUI/ItemListCallListItem.swift @@ -22,7 +22,7 @@ class ItemListCallListItem: ListViewItem, ItemListItem { self.style = style } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListCallListItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -32,13 +32,13 @@ class ItemListCallListItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListCallListItemNode { let makeLayout = nodeValue.asyncLayout() @@ -46,7 +46,7 @@ class ItemListCallListItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ItemListCheckboxItem.swift b/TelegramUI/ItemListCheckboxItem.swift index e1fd12d891..cf955d0046 100644 --- a/TelegramUI/ItemListCheckboxItem.swift +++ b/TelegramUI/ItemListCheckboxItem.swift @@ -34,7 +34,7 @@ class ItemListCheckboxItem: ListViewItem, ItemListItem { self.action = action } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListCheckboxItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -44,13 +44,13 @@ class ItemListCheckboxItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListCheckboxItemNode { let makeLayout = nodeValue.asyncLayout() @@ -58,7 +58,7 @@ class ItemListCheckboxItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ItemListDisclosureItem.swift b/TelegramUI/ItemListDisclosureItem.swift index 29fed9b6c2..999cd3b25e 100644 --- a/TelegramUI/ItemListDisclosureItem.swift +++ b/TelegramUI/ItemListDisclosureItem.swift @@ -51,7 +51,7 @@ class ItemListDisclosureItem: ListViewItem, ItemListItem { self.action = action } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListDisclosureItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -61,13 +61,13 @@ class ItemListDisclosureItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListDisclosureItemNode { let makeLayout = nodeValue.asyncLayout() @@ -75,7 +75,7 @@ class ItemListDisclosureItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ItemListMultilineInputItem.swift b/TelegramUI/ItemListMultilineInputItem.swift index 291662c5bf..c3eabb2292 100644 --- a/TelegramUI/ItemListMultilineInputItem.swift +++ b/TelegramUI/ItemListMultilineInputItem.swift @@ -26,7 +26,7 @@ class ItemListMultilineInputItem: ListViewItem, ItemListItem { self.action = action } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListMultilineInputItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -36,13 +36,13 @@ class ItemListMultilineInputItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListMultilineInputItemNode { let makeLayout = nodeValue.asyncLayout() @@ -50,7 +50,7 @@ class ItemListMultilineInputItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ItemListMultilineTextItem.swift b/TelegramUI/ItemListMultilineTextItem.swift index 6f1b9ec295..409af195b0 100644 --- a/TelegramUI/ItemListMultilineTextItem.swift +++ b/TelegramUI/ItemListMultilineTextItem.swift @@ -42,7 +42,7 @@ class ItemListMultilineTextItem: ListViewItem, ItemListItem { self.selectable = action != nil } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListMultilineTextItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -52,13 +52,13 @@ class ItemListMultilineTextItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListMultilineTextItemNode { let makeLayout = nodeValue.asyncLayout() @@ -66,7 +66,7 @@ class ItemListMultilineTextItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ItemListPeerActionItem.swift b/TelegramUI/ItemListPeerActionItem.swift index 4e2da9b0ae..9d4c32f9e4 100644 --- a/TelegramUI/ItemListPeerActionItem.swift +++ b/TelegramUI/ItemListPeerActionItem.swift @@ -20,7 +20,7 @@ class ItemListPeerActionItem: ListViewItem, ItemListItem { self.action = action } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListPeerActionItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -30,13 +30,13 @@ class ItemListPeerActionItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(false) }) + return (nil, { _ in apply(false) }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListPeerActionItemNode { let makeLayout = nodeValue.asyncLayout() @@ -49,7 +49,7 @@ class ItemListPeerActionItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animated) }) } diff --git a/TelegramUI/ItemListPeerItem.swift b/TelegramUI/ItemListPeerItem.swift index 1b65e2e302..764edb88a0 100644 --- a/TelegramUI/ItemListPeerItem.swift +++ b/TelegramUI/ItemListPeerItem.swift @@ -105,7 +105,7 @@ final class ItemListPeerItem: ListViewItem, ItemListItem { self.hasTopGroupInset = hasTopGroupInset } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListPeerItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -115,13 +115,13 @@ final class ItemListPeerItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (node.avatarNode.ready, { apply(false) }) + return (node.avatarNode.ready, { _ in apply(false) }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListPeerItemNode { let makeLayout = nodeValue.asyncLayout() @@ -134,7 +134,7 @@ final class ItemListPeerItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animated) }) } diff --git a/TelegramUI/ItemListRecentSessionItem.swift b/TelegramUI/ItemListRecentSessionItem.swift index a043339915..b0268beb60 100644 --- a/TelegramUI/ItemListRecentSessionItem.swift +++ b/TelegramUI/ItemListRecentSessionItem.swift @@ -57,7 +57,7 @@ final class ItemListRecentSessionItem: ListViewItem, ItemListItem { self.removeSession = removeSession } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListRecentSessionItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -67,13 +67,13 @@ final class ItemListRecentSessionItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(false) }) + return (nil, { _ in apply(false) }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListRecentSessionItemNode { let makeLayout = nodeValue.asyncLayout() @@ -86,7 +86,7 @@ final class ItemListRecentSessionItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animated) }) } diff --git a/TelegramUI/ItemListSecretChatKeyItem.swift b/TelegramUI/ItemListSecretChatKeyItem.swift index 1543dc33ce..c0ca0e36f5 100644 --- a/TelegramUI/ItemListSecretChatKeyItem.swift +++ b/TelegramUI/ItemListSecretChatKeyItem.swift @@ -25,7 +25,7 @@ class ItemListSecretChatKeyItem: ListViewItem, ItemListItem { self.action = action } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListSecretChatKeyItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -35,13 +35,13 @@ class ItemListSecretChatKeyItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListSecretChatKeyItemNode { let makeLayout = nodeValue.asyncLayout() @@ -49,7 +49,7 @@ class ItemListSecretChatKeyItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ItemListSectionHeaderItem.swift b/TelegramUI/ItemListSectionHeaderItem.swift index fef5dce77f..451f747466 100644 --- a/TelegramUI/ItemListSectionHeaderItem.swift +++ b/TelegramUI/ItemListSectionHeaderItem.swift @@ -16,7 +16,7 @@ class ItemListSectionHeaderItem: ListViewItem, ItemListItem { self.sectionId = sectionId } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListSectionHeaderItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -26,13 +26,13 @@ class ItemListSectionHeaderItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { guard let nodeValue = node() as? ItemListSectionHeaderItemNode else { assertionFailure() @@ -44,7 +44,7 @@ class ItemListSectionHeaderItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ItemListSingleLineInputItem.swift b/TelegramUI/ItemListSingleLineInputItem.swift index 9aca4b1381..a9bc815045 100644 --- a/TelegramUI/ItemListSingleLineInputItem.swift +++ b/TelegramUI/ItemListSingleLineInputItem.swift @@ -42,7 +42,7 @@ class ItemListSingleLineInputItem: ListViewItem, ItemListItem { self.action = action } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListSingleLineInputItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -52,13 +52,13 @@ class ItemListSingleLineInputItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListSingleLineInputItemNode { @@ -67,7 +67,7 @@ class ItemListSingleLineInputItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ItemListStickerPackItem.swift b/TelegramUI/ItemListStickerPackItem.swift index 5d641fcf32..fa42039250 100644 --- a/TelegramUI/ItemListStickerPackItem.swift +++ b/TelegramUI/ItemListStickerPackItem.swift @@ -69,7 +69,7 @@ final class ItemListStickerPackItem: ListViewItem, ItemListItem { self.removePack = removePack } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListStickerPackItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -79,13 +79,13 @@ final class ItemListStickerPackItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(false) }) + return (nil, { _ in apply(false) }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListStickerPackItemNode { let makeLayout = nodeValue.asyncLayout() @@ -98,7 +98,7 @@ final class ItemListStickerPackItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animated) }) } diff --git a/TelegramUI/ItemListSwitchItem.swift b/TelegramUI/ItemListSwitchItem.swift index 4351a3290f..8ff7d9a13c 100644 --- a/TelegramUI/ItemListSwitchItem.swift +++ b/TelegramUI/ItemListSwitchItem.swift @@ -31,7 +31,7 @@ class ItemListSwitchItem: ListViewItem, ItemListItem { self.updated = updated } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListSwitchItemNode(type: self.type) let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -41,13 +41,13 @@ class ItemListSwitchItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(false) }) + return (nil, { _ in apply(false) }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListSwitchItemNode { let makeLayout = nodeValue.asyncLayout() @@ -55,7 +55,7 @@ class ItemListSwitchItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in var animated = true if case .None = animation { animated = false diff --git a/TelegramUI/ItemListTextItem.swift b/TelegramUI/ItemListTextItem.swift index 385e623766..4e5c6fe2f3 100644 --- a/TelegramUI/ItemListTextItem.swift +++ b/TelegramUI/ItemListTextItem.swift @@ -28,7 +28,7 @@ class ItemListTextItem: ListViewItem, ItemListItem { self.style = style } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListTextItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -38,13 +38,13 @@ class ItemListTextItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { guard let nodeValue = node() as? ItemListTextItemNode else { assertionFailure() @@ -56,7 +56,7 @@ class ItemListTextItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ItemListTextWithLabelItem.swift b/TelegramUI/ItemListTextWithLabelItem.swift index faebcaa0ea..00c150c667 100644 --- a/TelegramUI/ItemListTextWithLabelItem.swift +++ b/TelegramUI/ItemListTextWithLabelItem.swift @@ -41,7 +41,7 @@ final class ItemListTextWithLabelItem: ListViewItem, ItemListItem { self.tag = tag } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListTextWithLabelItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -51,13 +51,13 @@ final class ItemListTextWithLabelItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(.None) }) + return (nil, { _ in apply(.None) }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListTextWithLabelItemNode { let makeLayout = nodeValue.asyncLayout() @@ -65,7 +65,7 @@ final class ItemListTextWithLabelItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation) }) } diff --git a/TelegramUI/ItemListWebsiteItem.swift b/TelegramUI/ItemListWebsiteItem.swift index 475bf6e310..d59c38a476 100644 --- a/TelegramUI/ItemListWebsiteItem.swift +++ b/TelegramUI/ItemListWebsiteItem.swift @@ -47,7 +47,7 @@ final class ItemListWebsiteItem: ListViewItem, ItemListItem { self.removeSession = removeSession } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListWebsiteItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -57,13 +57,13 @@ final class ItemListWebsiteItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(false) }) + return (nil, { _ in apply(false) }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListWebsiteItemNode { let makeLayout = nodeValue.asyncLayout() @@ -76,7 +76,7 @@ final class ItemListWebsiteItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animated) }) } diff --git a/TelegramUI/LegacyCamera.swift b/TelegramUI/LegacyCamera.swift index 6e4ed54f4f..f63da3863b 100644 --- a/TelegramUI/LegacyCamera.swift +++ b/TelegramUI/LegacyCamera.swift @@ -26,8 +26,8 @@ func presentedLegacyCamera(account: Account, peer: Peer, cameraView: TGAttachmen if #available(iOSApplicationExtension 11.0, *) { } else { - controller.customPresentOverlayController = { [weak legacyController] overlayController in - guard let legacyController = legacyController, let overlayController = overlayController else { + controller.customPresentOverlayController = { [weak legacyController] generateController in + guard let legacyController = legacyController, let generateController = generateController else { return } @@ -35,6 +35,9 @@ func presentedLegacyCamera(account: Account, peer: Peer, cameraView: TGAttachmen let overlayLegacyController = LegacyController(presentation: .custom, theme: presentationData.theme) overlayLegacyController.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .portrait, compactSize: .portrait) overlayLegacyController.statusBar.statusBarStyle = .Hide + + let overlayController = generateController(overlayLegacyController.context)! + overlayLegacyController.bind(controller: overlayController) overlayController.customDismissSelf = { [weak overlayLegacyController] in overlayLegacyController?.dismiss() diff --git a/TelegramUI/LegacyController.swift b/TelegramUI/LegacyController.swift index b9bb54d0a7..cd99c1235a 100644 --- a/TelegramUI/LegacyController.swift +++ b/TelegramUI/LegacyController.swift @@ -339,6 +339,9 @@ public class LegacyController: ViewController { self.contextImpl = contextImpl } + deinit { + } + required public init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } diff --git a/TelegramUI/ListMessageHoleItem.swift b/TelegramUI/ListMessageHoleItem.swift index f8a97bd7ba..9d1a6cf67c 100644 --- a/TelegramUI/ListMessageHoleItem.swift +++ b/TelegramUI/ListMessageHoleItem.swift @@ -9,7 +9,7 @@ final class ListMessageHoleItem: ListViewItem { public init() { } - public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { let configure = { () -> Void in let node = ListMessageHoleItemNode() @@ -24,7 +24,7 @@ final class ListMessageHoleItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(.None) }) + return (nil, { _ in apply(.None) }) }) } } @@ -37,7 +37,7 @@ final class ListMessageHoleItem: ListViewItem { } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ListMessageHoleItemNode { nodeValue.updateSelectionState(animated: false) @@ -49,7 +49,7 @@ final class ListMessageHoleItem: ListViewItem { let (layout, apply) = nodeLayout(self, params, top, bottom, dateAtBottom) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation) }) } diff --git a/TelegramUI/ListMessageItem.swift b/TelegramUI/ListMessageItem.swift index e7c9fb1888..4b3b1f3efe 100644 --- a/TelegramUI/ListMessageItem.swift +++ b/TelegramUI/ListMessageItem.swift @@ -35,7 +35,7 @@ final class ListMessageItem: ListViewItem { self.selection = selection } - public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { var viewClassName: AnyClass = ListMessageSnippetItemNode.self for media in message.media { @@ -61,7 +61,7 @@ final class ListMessageItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(.None) }) + return (nil, { _ in apply(.None) }) }) } } @@ -74,7 +74,7 @@ final class ListMessageItem: ListViewItem { } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ListMessageNode { nodeValue.setupItem(self) @@ -88,7 +88,7 @@ final class ListMessageItem: ListViewItem { let (layout, apply) = nodeLayout(self, params, top, bottom, dateAtBottom) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation) }) } diff --git a/TelegramUI/LocalizationListItem.swift b/TelegramUI/LocalizationListItem.swift index 26abd42081..2a3e5c7841 100644 --- a/TelegramUI/LocalizationListItem.swift +++ b/TelegramUI/LocalizationListItem.swift @@ -41,7 +41,7 @@ class LocalizationListItem: ListViewItem, ItemListItem { self.removeItem = removeItem } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = LocalizationListItemNode() var neighbors = itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem) @@ -55,13 +55,13 @@ class LocalizationListItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(false) }) + return (nil, { _ in apply(false) }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? LocalizationListItemNode { let makeLayout = nodeValue.asyncLayout() @@ -73,7 +73,7 @@ class LocalizationListItem: ListViewItem, ItemListItem { } let (layout, apply) = makeLayout(self, params, neighbors) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation.isAnimated) }) } diff --git a/TelegramUI/ManagedAudioRecorder.swift b/TelegramUI/ManagedAudioRecorder.swift index c1b4e72497..7ffac34d92 100644 --- a/TelegramUI/ManagedAudioRecorder.swift +++ b/TelegramUI/ManagedAudioRecorder.swift @@ -161,9 +161,10 @@ final class ManagedAudioRecorderContext { private let audioUnit = Atomic(value: nil) - private var waveformSamples = Data() - private var waveformPeak: Int16 = 0 - private var waveformPeakCount: Int = 0 + private var compressedWaveformSamples = Data() + private var currentPeak: Int64 = 0 + private var currentPeakCount: Int = 0 + private var peakCompressionFactor: Int = 1 private var micLevelPeak: Int16 = 0 private var micLevelPeakCount: Int = 0 @@ -527,8 +528,6 @@ final class ManagedAudioRecorderContext { self.audioBuffer.append(currentEncoderPacket.assumingMemoryBound(to: UInt8.self), count: currentEncoderPacketSize) break } else { - let previousBytesWritten = self.oggWriter.encodedBytes() - self.processWaveformPreview(samples: currentEncoderPacket.assumingMemoryBound(to: Int16.self), count: currentEncoderPacketSize / 2) self.oggWriter.writeFrame(currentEncoderPacket.assumingMemoryBound(to: UInt8.self), frameByteCount: UInt(currentEncoderPacketSize)) @@ -538,16 +537,6 @@ final class ManagedAudioRecorderContext { self.recordingStateUpdateTimestamp = timestamp self.recordingState.set(.recording(duration: oggWriter.encodedDuration(), durationMediaTimestamp: timestamp)) } - - /*NSUInteger currentBytesWritten = [_oggWriter encodedBytes]; - if (currentBytesWritten != previousBytesWritten) - { - [ActionStageInstance() dispatchOnStageQueue:^ - { - TGLiveUploadActor *actor = (TGLiveUploadActor *)[ActionStageInstance() executingActorWithPath:_liveUploadPath]; - [actor updateSize:currentBytesWritten]; - }]; - }*/ } } } @@ -562,19 +551,28 @@ final class ManagedAudioRecorderContext { sample = -sample } } - if self.waveformPeak < sample { - self.waveformPeak = sample - } - self.waveformPeakCount += 1 - if self.waveformPeakCount >= 100 { - self.waveformSamples.count += 2 - var waveformPeak = self.waveformPeak - withUnsafeBytes(of: &waveformPeak, { bytes -> Void in - self.waveformSamples.append(bytes.baseAddress!.assumingMemoryBound(to: UInt8.self), count: 2) + self.currentPeak = max(Int64(sample), self.currentPeak) + self.currentPeakCount += 1 + if self.currentPeakCount == self.peakCompressionFactor { + var compressedPeak = self.currentPeak//Int16(Float(self.currentPeak) / Float(self.peakCompressionFactor)) + withUnsafeBytes(of: &compressedPeak, { buffer in + self.compressedWaveformSamples.append(buffer.bindMemory(to: UInt8.self)) }) - self.waveformPeak = 0 - self.waveformPeakCount = 0 + self.currentPeak = 0 + self.currentPeakCount = 0 + + let compressedSampleCount = self.compressedWaveformSamples.count / 2 + if compressedSampleCount == 200 { + self.compressedWaveformSamples.withUnsafeMutableBytes { (compressedSamples: UnsafeMutablePointer) -> Void in + for i in 0 ..< 100 { + let maxSample = Int64(max(compressedSamples[i * 2 + 0], compressedSamples[i * 2 + 1])) + compressedSamples[i] = Int16(maxSample) + } + } + self.compressedWaveformSamples.count = 100 * 2 + self.peakCompressionFactor *= 2 + } } if self.micLevelPeak < sample { @@ -601,8 +599,8 @@ final class ManagedAudioRecorderContext { memset(scaledSamples, 0, 100 * 2); var waveform: Data? - let count = self.waveformSamples.count / 2 - self.waveformSamples.withUnsafeMutableBytes { (samples: UnsafeMutablePointer) -> Void in + let count = self.compressedWaveformSamples.count / 2 + self.compressedWaveformSamples.withUnsafeMutableBytes { (samples: UnsafeMutablePointer) -> Void in for i in 0 ..< count { let sample = samples[i] let index = i * 100 / count @@ -618,7 +616,7 @@ final class ManagedAudioRecorderContext { if peak < sample { peak = sample } - sumSamples += Int64(peak) + sumSamples += Int64(sample) } var calculatedPeak: UInt16 = 0 calculatedPeak = UInt16((Double(sumSamples) * 1.8 / 100.0)) @@ -629,12 +627,12 @@ final class ManagedAudioRecorderContext { for i in 0 ..< 100 { let sample: UInt16 = UInt16(Int64(scaledSamples[i])) - if sample > calculatedPeak { - scaledSamples[i] = Int16(calculatedPeak) - } + let minPeak = min(Int64(sample), Int64(calculatedPeak)) + let resultPeak = minPeak * 31 / Int64(calculatedPeak) + scaledSamples[i] = Int16(clamping: min(31, resultPeak)) } - let resultWaveform = AudioWaveform(samples: Data(bytes: scaledSamplesMemory, count: 100 * 2), peak: Int32(calculatedPeak)) + let resultWaveform = AudioWaveform(samples: Data(bytes: scaledSamplesMemory, count: 100 * 2), peak: 31) let bitstream = resultWaveform.makeBitstream() waveform = AudioWaveform(bitstream: bitstream, bitsPerSample: 5).makeBitstream() } diff --git a/TelegramUI/MediaInputPaneTrendingItem.swift b/TelegramUI/MediaInputPaneTrendingItem.swift index d1bcf0a8b8..b4d7c7a97a 100644 --- a/TelegramUI/MediaInputPaneTrendingItem.swift +++ b/TelegramUI/MediaInputPaneTrendingItem.swift @@ -26,7 +26,7 @@ class MediaInputPaneTrendingItem: ListViewItem { self.unread = unread } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = MediaInputPaneTrendingItemNode() let (layout, apply) = node.asyncLayout()(self, params) @@ -36,13 +36,13 @@ class MediaInputPaneTrendingItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { info in apply(synchronousLoads && info.isOnScreen) }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? MediaInputPaneTrendingItemNode { let makeLayout = nodeValue.asyncLayout() @@ -50,8 +50,8 @@ class MediaInputPaneTrendingItem: ListViewItem { async { let (layout, apply) = makeLayout(self, params) Queue.mainQueue().async { - completion(layout, { - apply() + completion(layout, { _ in + apply(false) }) } } @@ -168,7 +168,7 @@ class MediaInputPaneTrendingItemNode: ListViewItemNode { self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) } - func asyncLayout() -> (_ item: MediaInputPaneTrendingItem, _ params: ListViewItemLayoutParams) -> (ListViewItemNodeLayout, () -> Void) { + func asyncLayout() -> (_ item: MediaInputPaneTrendingItem, _ params: ListViewItemLayoutParams) -> (ListViewItemNodeLayout, (Bool) -> Void) { let makeInstallLayout = TextNode.asyncLayout(self.installTextNode) let makeTitleLayout = TextNode.asyncLayout(self.titleNode) let makeDescriptionLayout = TextNode.asyncLayout(self.descriptionNode) @@ -201,7 +201,7 @@ class MediaInputPaneTrendingItemNode: ListViewItemNode { topItems.removeSubrange(5 ..< topItems.count) } - return (layout, { [weak self] in + return (layout, { [weak self] synchronousLoads in if let strongSelf = self { if item.topItems.count < Int(item.info.count) && item.topItems.count < 5 && strongSelf.item?.info.id != item.info.id { strongSelf.preloadDisposable.set(preloadedFeaturedStickerSet(network: item.account.network, postbox: item.account.postbox, id: item.info.id).start()) @@ -267,7 +267,7 @@ class MediaInputPaneTrendingItemNode: ListViewItemNode { } if file.fileId != node.file?.fileId { node.file = file - node.setSignal(chatMessageSticker(account: item.account, file: file, small: true)) + node.setSignal(chatMessageSticker(account: item.account, file: file, small: true, synchronousLoad: synchronousLoads), attemptSynchronously: synchronousLoads) node.loadDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.account, fileReference: stickerPackFileReference(file), resource: chatMessageStickerResource(file: file, small: true)).start()) } if let dimensions = file.dimensions { diff --git a/TelegramUI/MentionChatInputPanelItem.swift b/TelegramUI/MentionChatInputPanelItem.swift index f1c2bd28dd..164ec888b0 100644 --- a/TelegramUI/MentionChatInputPanelItem.swift +++ b/TelegramUI/MentionChatInputPanelItem.swift @@ -22,7 +22,7 @@ final class MentionChatInputPanelItem: ListViewItem { self.peerSelected = peerSelected } - public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { let configure = { () -> Void in let node = MentionChatInputPanelItemNode() @@ -35,7 +35,7 @@ final class MentionChatInputPanelItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(.None) }) + return (nil, { _ in apply(.None) }) }) } } @@ -48,7 +48,7 @@ final class MentionChatInputPanelItem: ListViewItem { } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? MentionChatInputPanelItemNode { let nodeLayout = nodeValue.asyncLayout() @@ -58,7 +58,7 @@ final class MentionChatInputPanelItem: ListViewItem { let (layout, apply) = nodeLayout(self, params, top, bottom) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation) }) } diff --git a/TelegramUI/NotificationSearchItem.swift b/TelegramUI/NotificationSearchItem.swift index ae94ef9968..7f8475bd6c 100644 --- a/TelegramUI/NotificationSearchItem.swift +++ b/TelegramUI/NotificationSearchItem.swift @@ -30,7 +30,7 @@ class NotificationSearchItem: ListViewItem, ItemListItem { self.activate = activate } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = NotificationSearchItemNode() node.placeholder = self.placeholder @@ -44,7 +44,7 @@ class NotificationSearchItem: ListViewItem, ItemListItem { node.activate = self.activate Queue.mainQueue().async { completion(node, { - return (nil, { + return (nil, { _ in apply(false) }) }) @@ -52,14 +52,14 @@ class NotificationSearchItem: ListViewItem, ItemListItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? NotificationSearchItemNode { let layout = nodeValue.asyncLayout() async { let (nodeLayout, apply) = layout(self, params) Queue.mainQueue().async { - completion(nodeLayout, { + completion(nodeLayout, { _ in apply(animation.isAnimated) }) } diff --git a/TelegramUI/OpenResolvedUrl.swift b/TelegramUI/OpenResolvedUrl.swift index 1621c33e45..5430fd1192 100644 --- a/TelegramUI/OpenResolvedUrl.swift +++ b/TelegramUI/OpenResolvedUrl.swift @@ -20,7 +20,7 @@ private func defaultNavigationForPeerId(_ peerId: PeerId?, navigation: ChatContr } } -func openResolvedUrl(_ resolvedUrl: ResolvedUrl, account: Account, context: OpenURLContext = .generic, navigationController: NavigationController?, openPeer: @escaping (PeerId, ChatControllerInteractionNavigateToPeer) -> Void, sendFile: ((FileMediaReference) -> Void)? = nil, present: (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void) { +func openResolvedUrl(_ resolvedUrl: ResolvedUrl, account: Account, context: OpenURLContext = .generic, navigationController: NavigationController?, openPeer: @escaping (PeerId, ChatControllerInteractionNavigateToPeer) -> Void, sendFile: ((FileMediaReference) -> Void)? = nil, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void) { let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } switch resolvedUrl { case let .externalUrl(url): @@ -106,5 +106,62 @@ func openResolvedUrl(_ resolvedUrl: ResolvedUrl, account: Account, context: Open present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: nil, text: presentationData.strings.AuthCode_Alert(formattedConfirmationCode(code)).0, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) } } + case let .cancelAccountReset(phone, hash): + let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } + let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: nil)) + present(controller, nil) + let _ = (requestCancelAccountResetData(network: account.network, hash: hash) + |> deliverOnMainQueue).start(next: { [weak controller] data in + controller?.dismiss() + present(confirmPhoneNumberCodeController(account: account, phoneNumber: phone, codeData: data), ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) + }, error: { [weak controller] error in + controller?.dismiss() + + let text: String + switch error { + case .limitExceeded: + text = presentationData.strings.Login_CodeFloodError + case .generic: + text = presentationData.strings.Login_UnknownError + } + let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } + present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) + }) + dismissInput() + case let .share(url, text): + let controller = PeerSelectionController(account: account) + controller.peerSelected = { [weak controller] peerId in + if let strongController = controller { + strongController.dismiss() + + let textInputState: ChatTextInputState + if let text = text, !text.isEmpty { + let urlString = NSMutableAttributedString(string: "\(text)\n") + let textString = NSAttributedString(string: "\(text)") + let selectionRange: Range = urlString.length ..< (urlString.length + textString.length) + urlString.append(textString) + textInputState = ChatTextInputState(inputText: urlString, selectionRange: selectionRange) + } else { + textInputState = ChatTextInputState(inputText: NSAttributedString(string: "\(url)")) + } + + let _ = (account.postbox.transaction({ transaction -> Void in + transaction.updatePeerChatInterfaceState(peerId, update: { currentState in + if let currentState = currentState as? ChatInterfaceState { + return currentState.withUpdatedComposeInputState(textInputState) + } else { + return ChatInterfaceState().withUpdatedComposeInputState(textInputState) + } + }) + }) + |> deliverOnMainQueue).start(completed: { + navigationController?.pushViewController(ChatController(account: account, chatLocation: .peer(peerId), messageId: nil)) + }) + } + } + if let navigationController = navigationController { + account.telegramApplicationContext.applicationBindings.dismissNativeController() + (navigationController.viewControllers.last as? ViewController)?.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: ViewControllerPresentationAnimation.modalSheet)) + } } } diff --git a/TelegramUI/OpenUrl.swift b/TelegramUI/OpenUrl.swift index 9f1971236f..4c6259b5ce 100644 --- a/TelegramUI/OpenUrl.swift +++ b/TelegramUI/OpenUrl.swift @@ -187,10 +187,10 @@ public func openExternalUrl(account: Account, context: OpenURLContext = .generic navigationController?.pushViewController(infoController) } }) - case .chat: + case let .chat(_, messageId): if let navigationController = navigationController { navigationController.view.window?.rootViewController?.dismiss(animated: true, completion: nil) - navigateToChatController(navigationController: navigationController, account: account, chatLocation: .peer(peerId)) + navigateToChatController(navigationController: navigationController, account: account, chatLocation: .peer(peerId), messageId: messageId) } case let .withBotStartPayload(payload): if let navigationController = navigationController { @@ -296,40 +296,11 @@ public func openExternalUrl(account: Account, context: OpenURLContext = .generic } } if let shareUrl = shareUrl { - let controller = PeerSelectionController(account: account) - controller.peerSelected = { [weak controller] peerId in - if let strongController = controller { - strongController.dismiss() - - let textInputState: ChatTextInputState - if let shareText = shareText, !shareText.isEmpty { - let urlString = NSMutableAttributedString(string: "\(shareUrl)\n") - let textString = NSAttributedString(string: "\(shareText)") - let selectionRange: Range = urlString.length ..< (urlString.length + textString.length) - urlString.append(textString) - textInputState = ChatTextInputState(inputText: urlString, selectionRange: selectionRange) - } else { - textInputState = ChatTextInputState(inputText: NSAttributedString(string: "\(shareUrl)")) - } - - let _ = (account.postbox.transaction({ transaction -> Void in - transaction.updatePeerChatInterfaceState(peerId, update: { currentState in - if let currentState = currentState as? ChatInterfaceState { - return currentState.withUpdatedComposeInputState(textInputState) - } else { - return ChatInterfaceState().withUpdatedComposeInputState(textInputState) - } - }) - }) - |> deliverOnMainQueue).start(completed: { - navigationController?.pushViewController(ChatController(account: account, chatLocation: .peer(peerId), messageId: nil)) - }) - } - } - if let navigationController = navigationController { - account.telegramApplicationContext.applicationBindings.dismissNativeController() - (navigationController.viewControllers.last as? ViewController)?.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: ViewControllerPresentationAnimation.modalSheet)) + var resultUrl = "https://t.me/share/url?url=\(urlEncodedStringFromString(shareUrl))" + if let shareText = shareText { + resultUrl += "&text=\(urlEncodedStringFromString(shareText))" } + convertedUrl = resultUrl } } } else if parsedUrl.host == "socks" || parsedUrl.host == "proxy" { @@ -483,6 +454,25 @@ public func openExternalUrl(account: Account, context: OpenURLContext = .generic convertedUrl = "https://t.me/login/\(code)" } } + } else if parsedUrl.host == "confirmphone" { + if let components = URLComponents(string: "/?" + query) { + var phone: String? + var hash: String? + if let queryItems = components.queryItems { + for queryItem in queryItems { + if let value = queryItem.value { + if queryItem.name == "phone" { + phone = value + } else if queryItem.name == "hash" { + hash = value + } + } + } + } + if let phone = phone, let hash = hash { + convertedUrl = "https://t.me/confirmphone?phone=\(phone)&hash=\(hash)" + } + } } if parsedUrl.host == "resolve" { diff --git a/TelegramUI/PeerMediaCollectionController.swift b/TelegramUI/PeerMediaCollectionController.swift index 9cfb3df951..a49c844348 100644 --- a/TelegramUI/PeerMediaCollectionController.swift +++ b/TelegramUI/PeerMediaCollectionController.swift @@ -371,6 +371,7 @@ public class PeerMediaCollectionController: TelegramController { } }, updateTextInputStateAndMode: { _ in }, updateInputModeAndDismissedButtonKeyboardMessageId: { _ in + }, openStickers: { }, editMessage: { }, beginMessageSearch: { _, _ in }, dismissMessageSearch: { diff --git a/TelegramUI/PermissionInfoItem.swift b/TelegramUI/PermissionInfoItem.swift index 704857b216..e14f94e7d6 100644 --- a/TelegramUI/PermissionInfoItem.swift +++ b/TelegramUI/PermissionInfoItem.swift @@ -16,7 +16,7 @@ class PermissionInfoItem: ListViewItem { self.subject = subject } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = PermissionInfoItemNode() let (layout, apply) = node.asyncLayout()(self, params, nil) @@ -26,13 +26,13 @@ class PermissionInfoItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? PermissionInfoItemNode { let makeLayout = nodeValue.asyncLayout() @@ -40,7 +40,7 @@ class PermissionInfoItem: ListViewItem { async { let (layout, apply) = makeLayout(self, params, nil) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } @@ -58,7 +58,7 @@ class PermissionInfoItemListItem: PermissionInfoItem, ItemListItem { super.init(theme: theme, strings: strings, subject: subject) } - override func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + override func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = PermissionInfoItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -68,13 +68,13 @@ class PermissionInfoItemListItem: PermissionInfoItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - override func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + override func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? PermissionInfoItemNode { let makeLayout = nodeValue.asyncLayout() @@ -82,7 +82,7 @@ class PermissionInfoItemListItem: PermissionInfoItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ProxySettingsActionItem.swift b/TelegramUI/ProxySettingsActionItem.swift index bc821b1738..915af42e37 100644 --- a/TelegramUI/ProxySettingsActionItem.swift +++ b/TelegramUI/ProxySettingsActionItem.swift @@ -25,7 +25,7 @@ class ProxySettingsActionItem: ListViewItem, ItemListItem { self.action = action } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ProxySettingsActionItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -35,13 +35,13 @@ class ProxySettingsActionItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(false) }) + return (nil, { _ in apply(false) }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ProxySettingsActionItemNode { let makeLayout = nodeValue.asyncLayout() @@ -54,7 +54,7 @@ class ProxySettingsActionItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animated) }) } diff --git a/TelegramUI/ProxySettingsServerItem.swift b/TelegramUI/ProxySettingsServerItem.swift index 844e8a7961..ba4b403419 100644 --- a/TelegramUI/ProxySettingsServerItem.swift +++ b/TelegramUI/ProxySettingsServerItem.swift @@ -46,7 +46,7 @@ final class ProxySettingsServerItem: ListViewItem, ItemListItem { self.removeServer = removeServer } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ProxySettingsServerItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -56,13 +56,13 @@ final class ProxySettingsServerItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(false) }) + return (nil, { _ in apply(false) }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ProxySettingsServerItemNode { let makeLayout = nodeValue.asyncLayout() @@ -75,7 +75,7 @@ final class ProxySettingsServerItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animated) }) } diff --git a/TelegramUI/SecretChatKeyController.swift b/TelegramUI/SecretChatKeyController.swift index 338d90a44f..4c3f657daf 100644 --- a/TelegramUI/SecretChatKeyController.swift +++ b/TelegramUI/SecretChatKeyController.swift @@ -24,6 +24,7 @@ final class SecretChatKeyController: ViewController { super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData)) + self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBar.style.style self.title = self.presentationData.strings.EncryptionKey_Title } diff --git a/TelegramUI/StickerPaneSearchContainerNode.swift b/TelegramUI/StickerPaneSearchContainerNode.swift index 2f2d8cce58..f1b5a96fd4 100644 --- a/TelegramUI/StickerPaneSearchContainerNode.swift +++ b/TelegramUI/StickerPaneSearchContainerNode.swift @@ -153,6 +153,11 @@ final class StickerPaneSearchContainerNode: ASDisplayNode { private let searchDisposable = MetaDisposable() + private let _ready = Promise() + var ready: Signal { + return self._ready.get() + } + init(account: Account, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: ChatControllerInteraction, inputNodeInteraction: ChatMediaInputNodeInteraction, cancel: @escaping () -> Void) { self.account = account self.theme = theme @@ -218,21 +223,21 @@ final class StickerPaneSearchContainerNode: ASDisplayNode { }, install: { [weak self] info in if let strongSelf = self { let _ = (loadedStickerPack(postbox: strongSelf.account.postbox, network: strongSelf.account.network, reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false) - |> mapToSignal { result -> Signal in - switch result { - case let .result(info, items, installed): - if installed { - return .complete() - } else { - return addStickerPackInteractively(postbox: strongSelf.account.postbox, info: info, items: items) - } - case .fetching: - break - case .none: - break - } - return .complete() - }).start() + |> mapToSignal { result -> Signal in + switch result { + case let .result(info, items, installed): + if installed { + return .complete() + } else { + return addStickerPackInteractively(postbox: strongSelf.account.postbox, info: info, items: items) + } + case .fetching: + break + case .none: + break + } + return .complete() + }).start() } }, sendSticker: { [weak self] file in if let strongSelf = self { @@ -363,6 +368,9 @@ final class StickerPaneSearchContainerNode: ASDisplayNode { } })) } + + self._ready.set(self.trendingPane.ready) + self.trendingPane.activate() } deinit { @@ -392,7 +400,7 @@ final class StickerPaneSearchContainerNode: ASDisplayNode { self.gridNode.transaction(GridNodeTransaction(deleteItems: [], insertItems: [], updateItems: [], scrollToItem: nil, updateLayout: GridNodeUpdateLayout(layout: GridNodeLayout(size: contentFrame.size, insets: UIEdgeInsets(top: 4.0, left: 0.0, bottom: 4.0 + bottomInset, right: 0.0), preloadSize: 300.0, type: .fixed(itemSize: CGSize(width: 75.0, height: 75.0), lineSpacing: 0.0)), transition: transition), itemTransition: .immediate, stationaryItems: .none, updateFirstIndexInSectionOffset: nil), completion: { _ in }) transition.updateFrame(node: self.trendingPane, frame: contentFrame) - self.trendingPane.updateLayout(size: contentFrame.size, topInset: 0.0, bottomInset: bottomInset, isExpanded: false, transition: transition) + self.trendingPane.updateLayout(size: contentFrame.size, topInset: 0.0, bottomInset: bottomInset, isExpanded: false, isVisible: true, transition: transition) transition.updateFrame(node: self.gridNode, frame: contentFrame) if firstLayout { diff --git a/TelegramUI/StickerResources.swift b/TelegramUI/StickerResources.swift index 27dc9a278d..968b9c44be 100644 --- a/TelegramUI/StickerResources.swift +++ b/TelegramUI/StickerResources.swift @@ -44,11 +44,11 @@ func chatMessageStickerResource(file: TelegramMediaFile, small: Bool) -> MediaRe return resource } -private func chatMessageStickerDatas(postbox: Postbox, file: TelegramMediaFile, small: Bool, fetched: Bool, onlyFullSize: Bool) -> Signal<(Data?, Data?, Bool), NoError> { +private func chatMessageStickerDatas(postbox: Postbox, file: TelegramMediaFile, small: Bool, fetched: Bool, onlyFullSize: Bool, synchronousLoad: Bool) -> Signal<(Data?, Data?, Bool), NoError> { let thumbnailResource = chatMessageStickerResource(file: file, small: true) let resource = chatMessageStickerResource(file: file, small: small) - let maybeFetched = postbox.mediaBox.cachedResourceRepresentation(resource, representation: CachedStickerAJpegRepresentation(size: small ? CGSize(width: 160.0, height: 160.0) : nil), complete: false, fetch: false) + let maybeFetched = postbox.mediaBox.cachedResourceRepresentation(resource, representation: CachedStickerAJpegRepresentation(size: small ? CGSize(width: 160.0, height: 160.0) : nil), complete: false, fetch: false, attemptSynchronously: synchronousLoad) return maybeFetched |> take(1) @@ -96,7 +96,7 @@ private func chatMessageStickerDatas(postbox: Postbox, file: TelegramMediaFile, } func chatMessageLegacySticker(account: Account, file: TelegramMediaFile, small: Bool, fitSize: CGSize, fetched: Bool = false, onlyFullSize: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { - let signal = chatMessageStickerDatas(postbox: account.postbox, file: file, small: small, fetched: fetched, onlyFullSize: onlyFullSize) + let signal = chatMessageStickerDatas(postbox: account.postbox, file: file, small: small, fetched: fetched, onlyFullSize: onlyFullSize, synchronousLoad: false) return signal |> map { (thumbnailData, fullSizeData, fullSizeComplete) in return { preArguments in var fullSizeImage: (UIImage, UIImage)? @@ -159,12 +159,12 @@ func chatMessageLegacySticker(account: Account, file: TelegramMediaFile, small: } } -public func chatMessageSticker(account: Account, file: TelegramMediaFile, small: Bool, fetched: Bool = false, onlyFullSize: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { - return chatMessageSticker(postbox: account.postbox, file: file, small: small, fetched: fetched, onlyFullSize: onlyFullSize) +public func chatMessageSticker(account: Account, file: TelegramMediaFile, small: Bool, fetched: Bool = false, onlyFullSize: Bool = false, synchronousLoad: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { + return chatMessageSticker(postbox: account.postbox, file: file, small: small, fetched: fetched, onlyFullSize: onlyFullSize, synchronousLoad: synchronousLoad) } -public func chatMessageSticker(postbox: Postbox, file: TelegramMediaFile, small: Bool, fetched: Bool = false, onlyFullSize: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { - let signal = chatMessageStickerDatas(postbox: postbox, file: file, small: small, fetched: fetched, onlyFullSize: onlyFullSize) +public func chatMessageSticker(postbox: Postbox, file: TelegramMediaFile, small: Bool, fetched: Bool = false, onlyFullSize: Bool = false, synchronousLoad: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { + let signal = chatMessageStickerDatas(postbox: postbox, file: file, small: small, fetched: fetched, onlyFullSize: onlyFullSize, synchronousLoad: synchronousLoad) return signal |> map { (thumbnailData, fullSizeData, fullSizeComplete) in return { arguments in diff --git a/TelegramUI/ThemeSettingsBrightnessItem.swift b/TelegramUI/ThemeSettingsBrightnessItem.swift index 9d5ce82c7f..5dea635f87 100644 --- a/TelegramUI/ThemeSettingsBrightnessItem.swift +++ b/TelegramUI/ThemeSettingsBrightnessItem.swift @@ -19,7 +19,7 @@ class ThemeSettingsBrightnessItem: ListViewItem, ItemListItem { self.updated = updated } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ThemeSettingsBrightnessItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -29,13 +29,13 @@ class ThemeSettingsBrightnessItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ThemeSettingsBrightnessItemNode { let makeLayout = nodeValue.asyncLayout() @@ -43,7 +43,7 @@ class ThemeSettingsBrightnessItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/ThemeSettingsChatPreviewItem.swift b/TelegramUI/ThemeSettingsChatPreviewItem.swift index a563e6c47d..e51dbae6cc 100644 --- a/TelegramUI/ThemeSettingsChatPreviewItem.swift +++ b/TelegramUI/ThemeSettingsChatPreviewItem.swift @@ -26,7 +26,7 @@ class ThemeSettingsChatPreviewItem: ListViewItem, ItemListItem { self.dateTimeFormat = dateTimeFormat } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ThemeSettingsChatPreviewItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -36,13 +36,13 @@ class ThemeSettingsChatPreviewItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ThemeSettingsChatPreviewItemNode { let makeLayout = nodeValue.asyncLayout() @@ -50,7 +50,7 @@ class ThemeSettingsChatPreviewItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } @@ -166,12 +166,12 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { current.insets = layout.insets current.frame = nodeFrame - apply() + apply(ListViewItemApply(isOnScreen: true)) }) } else { item1.nodeConfiguredForParams(async: { $0() }, params: params, synchronousLoads: false, previousItem: nil, nextItem: nil, completion: { node, apply in node1 = node - apply().1() + apply().1(ListViewItemApply(isOnScreen: true)) }) } @@ -185,12 +185,12 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { current.insets = layout.insets current.frame = nodeFrame - apply() + apply(ListViewItemApply(isOnScreen: true)) }) } else { item2.nodeConfiguredForParams(async: { $0() }, params: params, synchronousLoads: false, previousItem: nil, nextItem: nil, completion: { node, apply in node2 = node - apply().1() + apply().1(ListViewItemApply(isOnScreen: true)) }) } diff --git a/TelegramUI/ThemeSettingsFontSizeItem.swift b/TelegramUI/ThemeSettingsFontSizeItem.swift index af902e49fb..a31ec581f2 100644 --- a/TelegramUI/ThemeSettingsFontSizeItem.swift +++ b/TelegramUI/ThemeSettingsFontSizeItem.swift @@ -19,7 +19,7 @@ class ThemeSettingsFontSizeItem: ListViewItem, ItemListItem { self.updated = updated } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ThemeSettingsFontSizeItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -29,13 +29,13 @@ class ThemeSettingsFontSizeItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ThemeSettingsFontSizeItemNode { let makeLayout = nodeValue.asyncLayout() @@ -43,7 +43,7 @@ class ThemeSettingsFontSizeItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/UrlHandling.swift b/TelegramUI/UrlHandling.swift index 30b3d2df82..be3881d21b 100644 --- a/TelegramUI/UrlHandling.swift +++ b/TelegramUI/UrlHandling.swift @@ -18,6 +18,8 @@ enum ParsedInternalUrl { case proxy(host: String, port: Int32, username: String?, password: String?, secret: Data?) case internalInstantView(url: String) case confirmationCode(Int) + case cancelAccountReset(phone: String, hash: String) + case share(url: String, text: String?) } private enum ParsedUrl { @@ -37,6 +39,8 @@ enum ResolvedUrl { case join(String) case localization(String) case confirmationCode(Int) + case cancelAccountReset(phone: String, hash: String) + case share(url: String, text: String?) } func parseInternalUrl(query: String) -> ParsedInternalUrl? { @@ -103,6 +107,21 @@ func parseInternalUrl(query: String) -> ParsedInternalUrl? { if let code = code, let codeValue = Int(code) { return .confirmationCode(codeValue) } + } else if peerName == "confirmphone" { + var phone: String? + var hash: String? + for queryItem in queryItems { + if let value = queryItem.value { + if queryItem.name == "phone" { + phone = value + } else if queryItem.name == "hash" { + hash = value + } + } + } + if let phone = phone, let hash = hash { + return .cancelAccountReset(phone: phone, hash: hash) + } } else { for queryItem in queryItems { if let value = queryItem.value { @@ -129,6 +148,25 @@ func parseInternalUrl(query: String) -> ParsedInternalUrl? { if let code = Int(pathComponents[1]) { return .confirmationCode(code) } + } else if pathComponents[0] == "share" && pathComponents[1] == "url" { + if let queryItems = components.queryItems { + var url: String? + var text: String? + for queryItem in queryItems { + if let value = queryItem.value { + if queryItem.name == "url" { + url = value + } else if queryItem.name == "text" { + text = value + } + } + } + + if let url = url { + return .share(url: url, text: text) + } + } + return nil } else if let value = Int(pathComponents[1]) { return .peerName(peerName, .channelMessage(Int32(value))) } else { @@ -191,6 +229,10 @@ private func resolveInternalUrl(account: Account, url: ParsedInternalUrl) -> Sig |> map(Optional.init) case let .confirmationCode(code): return .single(.confirmationCode(code)) + case let .cancelAccountReset(phone, hash): + return .single(.cancelAccountReset(phone: phone, hash: hash)) + case let .share(url, text): + return .single(.share(url: url, text: text)) } } @@ -289,19 +331,3 @@ func resolveInstantViewUrl(account: Account, url: String) -> Signal Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = UserInfoEditingPhoneActionItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -26,13 +26,13 @@ class UserInfoEditingPhoneActionItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? UserInfoEditingPhoneActionItemNode { let makeLayout = nodeValue.asyncLayout() @@ -40,7 +40,7 @@ class UserInfoEditingPhoneActionItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/UserInfoEditingPhoneItem.swift b/TelegramUI/UserInfoEditingPhoneItem.swift index 679682a63e..e009335e26 100644 --- a/TelegramUI/UserInfoEditingPhoneItem.swift +++ b/TelegramUI/UserInfoEditingPhoneItem.swift @@ -37,7 +37,7 @@ class UserInfoEditingPhoneItem: ListViewItem, ItemListItem { self.tag = tag } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = UserInfoEditingPhoneItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -47,13 +47,13 @@ class UserInfoEditingPhoneItem: ListViewItem, ItemListItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply() }) + return (nil, { _ in apply() }) }) } } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? UserInfoEditingPhoneItemNode { let makeLayout = nodeValue.asyncLayout() @@ -61,7 +61,7 @@ class UserInfoEditingPhoneItem: ListViewItem, ItemListItem { async { let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply() }) } diff --git a/TelegramUI/VerticalListContextResultsChatInputPanelButtonItem.swift b/TelegramUI/VerticalListContextResultsChatInputPanelButtonItem.swift index a06f354cc3..e1244121a2 100644 --- a/TelegramUI/VerticalListContextResultsChatInputPanelButtonItem.swift +++ b/TelegramUI/VerticalListContextResultsChatInputPanelButtonItem.swift @@ -16,7 +16,7 @@ final class VerticalListContextResultsChatInputPanelButtonItem: ListViewItem { self.pressed = pressed } - public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { let configure = { () -> Void in let node = VerticalListContextResultsChatInputPanelButtonItemNode() @@ -29,7 +29,7 @@ final class VerticalListContextResultsChatInputPanelButtonItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(.None) }) + return (nil, { _ in apply(.None) }) }) } } @@ -42,7 +42,7 @@ final class VerticalListContextResultsChatInputPanelButtonItem: ListViewItem { } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? VerticalListContextResultsChatInputPanelButtonItemNode { let nodeLayout = nodeValue.asyncLayout() @@ -52,7 +52,7 @@ final class VerticalListContextResultsChatInputPanelButtonItem: ListViewItem { let (layout, apply) = nodeLayout(self, params, top, bottom) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation) }) } diff --git a/TelegramUI/VerticalListContextResultsChatInputPanelItem.swift b/TelegramUI/VerticalListContextResultsChatInputPanelItem.swift index c27f10e946..3b77033124 100644 --- a/TelegramUI/VerticalListContextResultsChatInputPanelItem.swift +++ b/TelegramUI/VerticalListContextResultsChatInputPanelItem.swift @@ -20,7 +20,7 @@ final class VerticalListContextResultsChatInputPanelItem: ListViewItem { self.resultSelected = resultSelected } - public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, () -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { let configure = { () -> Void in let node = VerticalListContextResultsChatInputPanelItemNode() @@ -33,7 +33,7 @@ final class VerticalListContextResultsChatInputPanelItem: ListViewItem { Queue.mainQueue().async { completion(node, { - return (nil, { apply(.None) }) + return (nil, { _ in apply(.None) }) }) } } @@ -46,7 +46,7 @@ final class VerticalListContextResultsChatInputPanelItem: ListViewItem { } } - public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? VerticalListContextResultsChatInputPanelItemNode { let nodeLayout = nodeValue.asyncLayout() @@ -56,7 +56,7 @@ final class VerticalListContextResultsChatInputPanelItem: ListViewItem { let (layout, apply) = nodeLayout(self, params, top, bottom) Queue.mainQueue().async { - completion(layout, { + completion(layout, { _ in apply(animation) }) }