From c959e060c1500dec36a977c19852a9f92b7b20b6 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 2 Feb 2023 03:02:03 +0400 Subject: [PATCH 01/13] Fix handshake emoji display --- submodules/Display/Source/TextNode.swift | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/submodules/Display/Source/TextNode.swift b/submodules/Display/Source/TextNode.swift index b9621e5798..2ae7dc5339 100644 --- a/submodules/Display/Source/TextNode.swift +++ b/submodules/Display/Source/TextNode.swift @@ -1510,7 +1510,7 @@ open class TextNode: ASDisplayNode { continue } - var fixCoupleEmoji = false + var fixDoubleEmoji = false if glyphCount == 2, let font = attributes["NSFont"] as? UIFont, font.fontName.contains("ColorEmoji"), let string = layout.attributedString { let range = CTRunGetStringRange(run) let substring = string.attributedSubstring(from: NSMakeRange(range.location, range.length)).string @@ -1518,17 +1518,21 @@ open class TextNode: ASDisplayNode { let heart = Unicode.Scalar(0x2764)! let man = Unicode.Scalar(0x1F468)! let woman = Unicode.Scalar(0x1F469)! + let leftHand = Unicode.Scalar(0x1FAF1)! + let rightHand = Unicode.Scalar(0x1FAF2)! if substring.unicodeScalars.contains(heart) && (substring.unicodeScalars.contains(man) || substring.unicodeScalars.contains(woman)) { - fixCoupleEmoji = true + fixDoubleEmoji = true + } else if substring.unicodeScalars.contains(leftHand) && substring.unicodeScalars.contains(rightHand) { + fixDoubleEmoji = true } } - if fixCoupleEmoji { + if fixDoubleEmoji { context.setBlendMode(.normal) } CTRunDraw(run, context, CFRangeMake(0, glyphCount)) - if fixCoupleEmoji { + if fixDoubleEmoji { context.setBlendMode(blendMode) } } From b8f0bb1620d05e8c0208da7e0c62c3ed980672d1 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 2 Feb 2023 03:03:36 +0400 Subject: [PATCH 02/13] Fix entities keyboard bottom panel inset on iPad --- .../Sources/ChatEntityKeyboardInputNode.swift | 21 ++++++---- .../ChatInputNode/Sources/ChatInputNode.swift | 2 +- .../Sources/ChatButtonKeyboardInputNode.swift | 2 +- .../Sources/ChatControllerNode.swift | 8 ++-- .../Sources/ChatMediaInputNode.swift | 38 +++++++++---------- 5 files changed, 38 insertions(+), 33 deletions(-) diff --git a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift index 5534b909e0..304b90882b 100644 --- a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift +++ b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift @@ -302,7 +302,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { public var switchToTextInput: (() -> Void)? - private var currentState: (width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, interfaceState: ChatPresentationInterfaceState, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool)? + private var currentState: (width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, interfaceState: ChatPresentationInterfaceState, layoutMetrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool)? private var scheduledContentAnimationHint: EmojiPagerContentComponent.ContentAnimation? private var scheduledInnerTransition: Transition? @@ -1690,22 +1690,22 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { } private func performLayout(transition: Transition) { - guard let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded) = self.currentState else { + guard let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded) = self.currentState else { return } self.scheduledInnerTransition = transition - let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) + let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) } public func simulateUpdateLayout(isVisible: Bool) { - guard let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, _, isExpanded) = self.currentState else { + guard let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, _, isExpanded) = self.currentState else { return } - let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) + let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) } - public override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) { - self.currentState = (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded) + public override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, layoutMetrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) { + self.currentState = (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded) let innerTransition: Transition if let scheduledInnerTransition = self.scheduledInnerTransition { @@ -1774,13 +1774,17 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { let startTime = CFAbsoluteTimeGetCurrent() + var keyboardBottomInset = bottomInset + if case .regular = layoutMetrics.widthClass, inputHeight > 0.0 && inputHeight < 100.0 { + keyboardBottomInset = inputHeight + 15.0 + } let entityKeyboardSize = self.entityKeyboardView.update( transition: mappedTransition, component: AnyComponent(EntityKeyboardComponent( theme: interfaceState.theme, strings: interfaceState.strings, isContentInFocus: isVisible, - containerInsets: UIEdgeInsets(top: self.isEmojiSearchActive ? -34.0 : 0.0, left: leftInset, bottom: bottomInset, right: rightInset), + containerInsets: UIEdgeInsets(top: self.isEmojiSearchActive ? -34.0 : 0.0, left: leftInset, bottom: keyboardBottomInset, right: rightInset), topPanelInsets: UIEdgeInsets(), emojiContent: emojiContent, stickerContent: stickerContent, @@ -2427,6 +2431,7 @@ public final class EntityInputView: UIInputView, AttachmentTextInputPanelInputVi inputPanelHeight: 0.0, transition: .immediate, interfaceState: presentationInterfaceState, + layoutMetrics: LayoutMetrics(widthClass: .compact, heightClass: .compact), deviceMetrics: DeviceMetrics.iPhone12, isVisible: true, isExpanded: false diff --git a/submodules/TelegramUI/Components/ChatInputNode/Sources/ChatInputNode.swift b/submodules/TelegramUI/Components/ChatInputNode/Sources/ChatInputNode.swift index 95f9bf353a..aa19ddfdf0 100644 --- a/submodules/TelegramUI/Components/ChatInputNode/Sources/ChatInputNode.swift +++ b/submodules/TelegramUI/Components/ChatInputNode/Sources/ChatInputNode.swift @@ -28,7 +28,7 @@ open class ChatInputNode: ASDisplayNode { } - open func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) { + open func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, layoutMetrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) { return (0.0, 0.0) } } diff --git a/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift b/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift index aa18aab993..2921481394 100644 --- a/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift @@ -260,7 +260,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, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (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, layoutMetrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) { transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: UIScreenPixel))) if self.backgroundNode == nil { diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index fca3e1ac8f..1dbaa88c88 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -1398,7 +1398,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { let inputHeight = layout.standardInputHeight + self.inputPanelContainerNode.expansionFraction * (maximumInputNodeHeight - layout.standardInputHeight) - let heightAndOverflow = inputNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: cleanInsets.bottom, standardInputHeight: inputHeight, inputHeight: layout.inputHeight ?? 0.0, maximumHeight: maximumInputNodeHeight, inputPanelHeight: inputPanelNodeBaseHeight, transition: immediatelyLayoutInputNodeAndAnimateAppearance ? .immediate : transition, interfaceState: self.chatPresentationInterfaceState, deviceMetrics: layout.deviceMetrics, isVisible: self.isInFocus, isExpanded: self.inputPanelContainerNode.stableIsExpanded) + let heightAndOverflow = inputNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: cleanInsets.bottom, standardInputHeight: inputHeight, inputHeight: layout.inputHeight ?? 0.0, maximumHeight: maximumInputNodeHeight, inputPanelHeight: inputPanelNodeBaseHeight, transition: immediatelyLayoutInputNodeAndAnimateAppearance ? .immediate : transition, interfaceState: self.chatPresentationInterfaceState, layoutMetrics: layout.metrics, deviceMetrics: layout.deviceMetrics, isVisible: self.isInFocus, isExpanded: self.inputPanelContainerNode.stableIsExpanded) let boundedHeight = inputNode.followsDefaultHeight ? min(heightAndOverflow.0, layout.standardInputHeight) : heightAndOverflow.0 @@ -1449,10 +1449,10 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { self.historyNode.isSelectionGestureEnabled = isSelectionEnabled 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, deviceMetrics: layout.deviceMetrics, isVisible: false, isExpanded: self.inputPanelContainerNode.stableIsExpanded) + 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, layoutMetrics: layout.metrics, deviceMetrics: layout.deviceMetrics, isVisible: false, isExpanded: self.inputPanelContainerNode.stableIsExpanded) } - transition.updateFrame(node: self.titleAccessoryPanelContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: 116.0))) + transition.updateFrame(node: self.titleAccessoryPanelContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: 200.0))) transition.updateFrame(node: self.inputContextPanelContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: layout.size.height))) transition.updateFrame(node: self.inputContextOverTextPanelContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: layout.size.height))) @@ -2684,7 +2684,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } 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, deviceMetrics: validLayout.deviceMetrics, isVisible: false, isExpanded: self.inputPanelContainerNode.stableIsExpanded) + 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, layoutMetrics: validLayout.metrics, deviceMetrics: validLayout.deviceMetrics, isVisible: false, isExpanded: self.inputPanelContainerNode.stableIsExpanded) } } diff --git a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift index df7e5843f8..c4f9f8d95b 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift @@ -543,7 +543,7 @@ final class ChatMediaInputNode: ChatInputNode { var requestDisableStickerAnimations: ((Bool) -> Void)? - private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, ChatPresentationInterfaceState, DeviceMetrics, Bool, Bool)? + private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, ChatPresentationInterfaceState, LayoutMetrics, DeviceMetrics, Bool, Bool)? private var paneArrangement: ChatMediaInputPaneArrangement private var initializedArrangement = false @@ -1439,7 +1439,7 @@ final class ChatMediaInputNode: ChatInputNode { } }))) - if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _) = strongSelf.validLayout { + if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _, _) = strongSelf.validLayout { var isScheduledMessages = false if case .scheduledMessages = interfaceState.subject { isScheduledMessages = true @@ -1561,7 +1561,7 @@ final class ChatMediaInputNode: ChatInputNode { |> map { isStarred -> (UIView, CGRect, PeekControllerContent)? in if let strongSelf = self { var menuItems: [ContextMenuItem] = [] - if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _) = strongSelf.validLayout { + if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _, _) = strongSelf.validLayout { var isScheduledMessages = false if case .scheduledMessages = interfaceState.subject { isScheduledMessages = true @@ -1715,7 +1715,7 @@ final class ChatMediaInputNode: ChatInputNode { |> map { isStarred, hasPremium -> (UIView, CGRect, PeekControllerContent)? in if let strongSelf = self { var menuItems: [ContextMenuItem] = [] - if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _) = strongSelf.validLayout { + if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _, _) = strongSelf.validLayout { var isScheduledMessages = false if case .scheduledMessages = interfaceState.subject { isScheduledMessages = true @@ -1892,8 +1892,8 @@ final class ChatMediaInputNode: ChatInputNode { self.paneArrangement = self.paneArrangement.withIndexTransition(0.0).withCurrentIndex(index) let updatedGifPanelWasActive = self.paneArrangement.panes[self.paneArrangement.currentIndex] == .gifs - if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded) = self.validLayout { - let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: transition, interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) + if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded) = self.validLayout { + let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: transition, interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) self.updateAppearanceTransition(transition: transition) } if updatedGifPanelWasActive != previousGifPanelWasActive { @@ -1910,8 +1910,8 @@ final class ChatMediaInputNode: ChatInputNode { } } } else { - if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded) = 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, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) + if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded) = 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, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) } } } @@ -2149,20 +2149,20 @@ final class ChatMediaInputNode: ChatInputNode { } func simulateUpdateLayout(isVisible: Bool) { - if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, _, isExpanded) = self.validLayout { - let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) + if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, _, isExpanded) = self.validLayout { + let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) } } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (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, layoutMetrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) { var searchMode: ChatMediaInputSearchMode? - if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _) = self.validLayout, case let .media(_, maybeExpanded, _) = interfaceState.inputMode, let expanded = maybeExpanded, case let .search(mode) = expanded { + if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _, _) = self.validLayout, case let .media(_, maybeExpanded, _) = interfaceState.inputMode, let expanded = maybeExpanded, case let .search(mode) = expanded { searchMode = mode } - let wasVisible = self.validLayout?.10 ?? false + let wasVisible = self.validLayout?.11 ?? false - self.validLayout = (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded) + self.validLayout = (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded) if self.theme !== interfaceState.theme || self.strings !== interfaceState.strings { self.updateThemeAndStrings(chatWallpaper: interfaceState.chatWallpaper, theme: interfaceState.theme, strings: interfaceState.strings) @@ -2515,7 +2515,7 @@ final class ChatMediaInputNode: ChatInputNode { self.stickerPane.removeFromSupernode() } case .changed: - if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded) = self.validLayout { + if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded) = self.validLayout { let translationX = -recognizer.translation(in: self.view).x var indexTransition = translationX / width if self.paneArrangement.currentIndex == 0 { @@ -2524,10 +2524,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, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) + let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) } 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 { @@ -2540,9 +2540,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, deviceMetrics, isVisible, isExpanded) = self.validLayout { + if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded) = 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, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) + 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, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded) } default: break From 824e8872949c9768e79a195bb4d36c64d4a52eb9 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 2 Feb 2023 03:17:45 +0400 Subject: [PATCH 03/13] Fix haptic delay when sharing to saved messages --- .../Sources/ChatListSearchContainerNode.swift | 6 ++++ .../Sources/ShareControllerNode.swift | 9 +++++- .../Sources/VoiceChatController.swift | 4 ++- .../TelegramUI/Sources/ChatController.swift | 4 +++ .../Sources/ChatControllerNode.swift | 9 ++---- .../Sources/PeerInfo/PeerInfoScreen.swift | 30 +++++++------------ 6 files changed, 35 insertions(+), 27 deletions(-) diff --git a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift index 9d68e005f5..23a1cbf1ab 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift @@ -128,6 +128,8 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo private weak var copyProtectionTooltipController: TooltipController? + private lazy var hapticFeedback = { HapticFeedback() }() + private var didSetReady: Bool = false private let _ready = Promise() public override func ready() -> Signal { @@ -1392,6 +1394,10 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo let peerId = peer.id if let strongSelf = self, let _ = peerSelectionController { if peerId == strongSelf.context.account.peerId { + Queue.mainQueue().after(0.88) { + strongSelf.hapticFeedback.success() + } + let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } (strongSelf.navigationController?.topViewController as? ViewController)?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: true, text: messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .window(.root)) diff --git a/submodules/ShareController/Sources/ShareControllerNode.swift b/submodules/ShareController/Sources/ShareControllerNode.swift index baa67514a2..7ca7100b83 100644 --- a/submodules/ShareController/Sources/ShareControllerNode.swift +++ b/submodules/ShareController/Sources/ShareControllerNode.swift @@ -876,7 +876,14 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate }) self.completed?(peerIds) - Queue.mainQueue().after(0.44) { + let delay: Double + if let peerId = peerIds.first, peerIds.count == 1 && peerId == self.context?.account.peerId { + delay = 0.88 + } else { + delay = 0.44 + } + + Queue.mainQueue().after(delay) { if self.hapticFeedback == nil { self.hapticFeedback = HapticFeedback() } diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index 5f5f53e49e..10aa9a82f0 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -2658,6 +2658,9 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController if let strongSelf = self { strongSelf.call.setShouldBeRecording(false, title: nil, videoOrientation: nil) + Queue.mainQueue().after(0.88) { + strongSelf.hapticFeedback.success() + } let text: String if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info { @@ -2665,7 +2668,6 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController } else { text = strongSelf.presentationData.strings.VideoChat_RecordingSaved } - strongSelf.presentUndoOverlay(content: .forward(savedMessages: true, text: text), action: { [weak self] value in if case .info = value, let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController { let context = strongSelf.context diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 05743bd736..b7d1440d76 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -16072,6 +16072,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.searchResultsController = nil strongController.dismiss() } else if peerId == strongSelf.context.account.peerId { + Queue.mainQueue().after(0.88) { + strongSelf.chatDisplayNode.hapticFeedback.success() + } + let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: true, text: messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many), elevatedLayout: false, animateInAsReplacement: true, action: { [weak self] value in if case .info = value, let strongSelf = self { diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 1dbaa88c88..b98a3eab19 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -164,7 +164,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { private var scheduledAnimateInAsOverlayFromNode: ASDisplayNode? private var dismissAsOverlayLayout: ContainerViewLayout? - private var hapticFeedback: HapticFeedback? + lazy var hapticFeedback = { HapticFeedback() }() private var scrollViewDismissStatus = false var chatPresentationInterfaceState: ChatPresentationInterfaceState @@ -2904,10 +2904,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { if let scrollContainerNode = self.scrollContainerNode, scrollView === scrollContainerNode.view { - if self.hapticFeedback == nil { - self.hapticFeedback = HapticFeedback() - } - self.hapticFeedback?.prepareImpact() + self.hapticFeedback.prepareImpact() } } @@ -2917,7 +2914,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { if dismissStatus != self.scrollViewDismissStatus { self.scrollViewDismissStatus = dismissStatus if !self.dismissedAsOverlay { - self.hapticFeedback?.impact() + self.hapticFeedback.impact() } } } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index ad580036da..91aee0591f 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -1950,7 +1950,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate private var editingSections: [AnyHashable: PeerInfoScreenItemSectionContainerNode] = [:] private let paneContainerNode: PeerInfoPaneContainerNode private var ignoreScrolling: Bool = false - private var hapticFeedback: HapticFeedback? + private lazy var hapticFeedback = { HapticFeedback() }() private var customStatusData: (PeerInfoStatusData?, PeerInfoStatusData?, CGFloat?) private let customStatusPromise = Promise<(PeerInfoStatusData?, PeerInfoStatusData?, CGFloat?)>((nil, nil, nil)) @@ -3096,7 +3096,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate for (_, section) in strongSelf.editingSections { section.animateErrorIfNeeded() } - strongSelf.hapticFeedback?.error() + strongSelf.hapticFeedback.error() return } } @@ -3146,10 +3146,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate if (peer.firstName ?? "") != firstName || (peer.lastName ?? "") != lastName { if firstName.isEmpty && lastName.isEmpty { - if strongSelf.hapticFeedback == nil { - strongSelf.hapticFeedback = HapticFeedback() - } - strongSelf.hapticFeedback?.error() + strongSelf.hapticFeedback.error() strongSelf.headerNode.editingContentNode.shakeTextForKey(.firstName) } else { var dismissStatus: (() -> Void)? @@ -3212,10 +3209,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate let description = strongSelf.headerNode.editingContentNode.editingTextForKey(.description) ?? "" if title.isEmpty { - if strongSelf.hapticFeedback == nil { - strongSelf.hapticFeedback = HapticFeedback() - } - strongSelf.hapticFeedback?.error() + strongSelf.hapticFeedback.error() strongSelf.headerNode.editingContentNode.shakeTextForKey(.title) } else { @@ -8024,6 +8018,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate if let strongSelf = self, let _ = peerSelectionController { if peerId == strongSelf.context.account.peerId { + Queue.mainQueue().after(0.88) { + strongSelf.hapticFeedback.success() + } + let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: true, text: messageIds.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current) @@ -9055,10 +9053,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate shouldBeExpanded = true if self.canOpenAvatarByDragging && self.headerNode.isAvatarExpanded && offsetY <= -32.0 { - if self.hapticFeedback == nil { - self.hapticFeedback = HapticFeedback() - } - self.hapticFeedback?.impact() + self.hapticFeedback.impact() self.canOpenAvatarByDragging = false let contentOffset = scrollView.contentOffset.y @@ -9078,13 +9073,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate if let shouldBeExpanded = shouldBeExpanded, shouldBeExpanded != self.headerNode.isAvatarExpanded { let transition: ContainedViewLayoutTransition = .animated(duration: 0.35, curve: .spring) - if self.hapticFeedback == nil { - self.hapticFeedback = HapticFeedback() - } if shouldBeExpanded { - self.hapticFeedback?.impact() + self.hapticFeedback.impact() } else { - self.hapticFeedback?.tap() + self.hapticFeedback.tap() } self.headerNode.updateIsAvatarExpanded(shouldBeExpanded, transition: transition) From 275e1da4bb1e5231249599747326d123514a922d Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 2 Feb 2023 03:45:49 +0400 Subject: [PATCH 04/13] Add custom proximity sensor screen dimming since it's broken on iPhone 14 --- .../DeviceProximity/DeviceProximityManager.h | 2 ++ .../Sources/DeviceProximityManager.m | 9 ++++++++ submodules/Display/Source/WindowContent.swift | 22 ++++++++++++++----- .../TelegramUI/Sources/AppDelegate.swift | 8 +++++++ .../Sources/ApplicationContext.swift | 5 ----- 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/submodules/DeviceProximity/PublicHeaders/DeviceProximity/DeviceProximityManager.h b/submodules/DeviceProximity/PublicHeaders/DeviceProximity/DeviceProximityManager.h index b9b9f23535..2a6c4f4010 100644 --- a/submodules/DeviceProximity/PublicHeaders/DeviceProximity/DeviceProximityManager.h +++ b/submodules/DeviceProximity/PublicHeaders/DeviceProximity/DeviceProximityManager.h @@ -2,6 +2,8 @@ @interface DeviceProximityManager : NSObject +@property (nonatomic, copy) void(^ _Nullable proximityChanged)(bool); + + (DeviceProximityManager * _Nonnull)shared; - (bool)currentValue; diff --git a/submodules/DeviceProximity/Sources/DeviceProximityManager.m b/submodules/DeviceProximity/Sources/DeviceProximityManager.m index 94ef975a8d..3b14080244 100644 --- a/submodules/DeviceProximity/Sources/DeviceProximityManager.m +++ b/submodules/DeviceProximity/Sources/DeviceProximityManager.m @@ -46,6 +46,9 @@ for (void (^f)(bool) in [strongSelf->_subscribers copyItems]) { f(proximityState); } + if (strongSelf.proximityChanged != nil) { + strongSelf.proximityChanged(proximityState); + } } else if (!strongSelf->_proximityState && [strongSelf->_subscribers isEmpty]) { [UIDevice currentDevice].proximityMonitoringEnabled = false; } @@ -90,6 +93,9 @@ for (void (^f)(bool) in [_subscribers copyItems]) { f(_proximityState); } + if (self.proximityChanged != nil) { + self.proximityChanged(_proximityState); + } } } else { if (_proximityState) { @@ -97,6 +103,9 @@ for (void (^f)(bool) in [_subscribers copyItems]) { f(_proximityState); } + if (self.proximityChanged != nil) { + self.proximityChanged(_proximityState); + } } else { [UIDevice currentDevice].proximityMonitoringEnabled = false; } diff --git a/submodules/Display/Source/WindowContent.swift b/submodules/Display/Source/WindowContent.swift index 9981e42339..fbf0c016ab 100644 --- a/submodules/Display/Source/WindowContent.swift +++ b/submodules/Display/Source/WindowContent.swift @@ -241,6 +241,7 @@ public final class WindowKeyboardGestureRecognizerDelegate: NSObject, UIGestureR public class Window1 { public let hostView: WindowHostView public let badgeView: UIImageView + private let customProximityDimView: UIView private var deviceMetrics: DeviceMetrics @@ -257,8 +258,6 @@ public class Window1 { private var updatingLayout: UpdatingLayout? private var updatedContainerLayout: ContainerViewLayout? private var upperKeyboardInputPositionBound: CGFloat? - private var cachedWindowSubviewCount: Int = 0 - private var cachedHasPreview: Bool = false private let presentationContext: PresentationContext private let overlayPresentationContext: GlobalOverlayPresentationContext @@ -270,10 +269,7 @@ public class Window1 { private var shouldInvalidateSupportedOrientations = false private var statusBarHidden = false - - public var previewThemeAccentColor: UIColor = .blue - public var previewThemeDarkBlur: Bool = false - + private var shouldNotAnimateLikelyKeyboardAutocorrectionSwitch: Bool = false public private(set) var forceInCallStatusBarText: String? = nil @@ -333,6 +329,10 @@ public class Window1 { self.badgeView.image = UIImage(bundleImageName: "Components/AppBadge") self.badgeView.isHidden = true + self.customProximityDimView = UIView() + self.customProximityDimView.backgroundColor = .black + self.customProximityDimView.isHidden = true + self.systemUserInterfaceStyle = hostView.systemUserInterfaceStyle let boundsSize = self.hostView.eventView.bounds.size @@ -652,6 +652,7 @@ public class Window1 { self.windowPanRecognizer = recognizer self.hostView.containerView.addGestureRecognizer(recognizer) self.hostView.containerView.addSubview(self.badgeView) + self.hostView.containerView.addSubview(self.customProximityDimView) } public required init(coder aDecoder: NSCoder) { @@ -685,6 +686,13 @@ public class Window1 { self.updateBadgeVisibility() } + public func setProximityDimHidden(_ hidden: Bool) { + guard hidden != self.customProximityDimView.isHidden else { + return + } + self.customProximityDimView.isHidden = hidden + } + private func updateBadgeVisibility() { let badgeIsHidden = !self.deviceMetrics.showAppBadge || self.forceBadgeHidden || self.windowLayout.size.width > self.windowLayout.size.height if badgeIsHidden != self.badgeView.isHidden && !badgeIsHidden { @@ -1141,6 +1149,8 @@ public class Window1 { self.updateBadgeVisibility() self.badgeView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((self.windowLayout.size.width - image.size.width) / 2.0), y: 5.0), size: image.size) } + + self.customProximityDimView.frame = CGRect(origin: .zero, size: self.windowLayout.size) } } } diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index 9ae5443d09..9e064fa2cb 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -36,6 +36,7 @@ import UIKitRuntimeUtils import StoreKit import PhoneNumberFormat import AuthorizationUI +import DeviceProximity #if canImport(AppCenter) import AppCenter @@ -1316,6 +1317,13 @@ private func extractAccountManagerState(records: AccountRecordsView deliverOnMainQueue).start(next: { [weak self] presentationData in if let strongSelf = self { if previousTheme.swap(presentationData.theme) !== presentationData.theme { - strongSelf.mainWindow.previewThemeAccentColor = presentationData.theme.rootController.navigationBar.accentTextColor - strongSelf.mainWindow.previewThemeDarkBlur = presentationData.theme.rootController.keyboardColor == .dark strongSelf.lockedCoveringView.updateTheme(presentationData.theme) strongSelf.rootController.updateTheme(NavigationControllerTheme(presentationTheme: presentationData.theme)) } From 6b8a616e702736064b451495630dd522680ca783 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 2 Feb 2023 03:47:05 +0400 Subject: [PATCH 05/13] Fix forward info tapping for static stickers --- .../Sources/ChatMessageStickerItemNode.swift | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index 7e3b0dd9cd..a3f24aa215 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -1297,6 +1297,34 @@ class ChatMessageStickerItemNode: ChatMessageItemView { } } + if let forwardInfoNode = self.forwardInfoNode, forwardInfoNode.frame.contains(location) { + if let item = self.item, let forwardInfo = item.message.forwardInfo { + let performAction: () -> Void = { + if let sourceMessageId = forwardInfo.sourceMessageId { + if !item.message.id.peerId.isReplies, let channel = forwardInfo.author as? TelegramChannel, channel.addressName == nil { + if case let .broadcast(info) = channel.info, info.flags.contains(.hasDiscussionGroup) { + } else if case .member = channel.participationStatus { + } else { + item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, forwardInfoNode, nil) + return + } + } + item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId) + } else if let peer = forwardInfo.source ?? forwardInfo.author { + item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) + } else if let _ = forwardInfo.authorSignature { + item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil) + } + } + + if forwardInfoNode.hasAction(at: self.view.convert(location, to: forwardInfoNode.view)) { + return .action({}) + } else { + return .optionalAction(performAction) + } + } + } + if let item = self.item, self.imageNode.frame.contains(location) { return .optionalAction({ let _ = item.controllerInteraction.openMessage(item.message, .default) From 3242bfc50739d8a5c836b4a67a371df3d2046e97 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 2 Feb 2023 07:02:48 +0400 Subject: [PATCH 06/13] Various improvements --- .../Sources/AttachmentController.swift | 6 +++ .../Sources/AttachmentPanel.swift | 16 +++++- .../Sources/CreatePollController.swift | 39 +++++++++++++- .../Navigation/NavigationController.swift | 8 ++- .../Sources/LocationPickerController.swift | 34 +++++++++++++ .../Sources/MediaPickerScreen.swift | 51 ++++++++++++------- .../Sources/AttachmentFileController.swift | 42 +++++++++++++-- .../TelegramUI/Sources/ChatController.swift | 42 +++++++-------- .../Sources/PeerInfo/PeerInfoHeaderNode.swift | 10 ++-- .../Sources/WebSearchController.swift | 6 ++- 10 files changed, 195 insertions(+), 59 deletions(-) diff --git a/submodules/AttachmentUI/Sources/AttachmentController.swift b/submodules/AttachmentUI/Sources/AttachmentController.swift index af45bf6514..4d1533cb73 100644 --- a/submodules/AttachmentUI/Sources/AttachmentController.swift +++ b/submodules/AttachmentUI/Sources/AttachmentController.swift @@ -352,6 +352,12 @@ public class AttachmentController: ViewController { } } + self.panel.longPressed = { [weak self] _ in + if let strongSelf = self, let currentController = strongSelf.currentControllers.last { + currentController.longTapWithTabBar?() + } + } + self.panel.beganTextEditing = { [weak self] in if let strongSelf = self { strongSelf.container.update(isExpanded: true, transition: .animated(duration: 0.4, curve: .spring)) diff --git a/submodules/AttachmentUI/Sources/AttachmentPanel.swift b/submodules/AttachmentUI/Sources/AttachmentPanel.swift index c95c3b4079..1640c9d4de 100644 --- a/submodules/AttachmentUI/Sources/AttachmentPanel.swift +++ b/submodules/AttachmentUI/Sources/AttachmentPanel.swift @@ -124,6 +124,7 @@ private final class AttachButtonComponent: CombinedComponent { let strings: PresentationStrings let theme: PresentationTheme let action: () -> Void + let longPressAction: () -> Void init( context: AccountContext, @@ -131,7 +132,8 @@ private final class AttachButtonComponent: CombinedComponent { isSelected: Bool, strings: PresentationStrings, theme: PresentationTheme, - action: @escaping () -> Void + action: @escaping () -> Void, + longPressAction: @escaping () -> Void ) { self.context = context self.type = type @@ -139,6 +141,7 @@ private final class AttachButtonComponent: CombinedComponent { self.strings = strings self.theme = theme self.action = action + self.longPressAction = longPressAction } static func ==(lhs: AttachButtonComponent, rhs: AttachButtonComponent) -> Bool { @@ -293,6 +296,11 @@ private final class AttachButtonComponent: CombinedComponent { .gesture(.tap { component.action() }) + .gesture(.longPress({ state in + if case .began = state { + component.longPressAction() + } + })) ) return context.availableSize @@ -495,6 +503,8 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate { var isStandalone: Bool = false var selectionChanged: (AttachmentButtonType) -> Bool = { _ in return false } + var longPressed: (AttachmentButtonType) -> Void = { _ in } + var beganTextEditing: () -> Void = {} var textUpdated: (NSAttributedString) -> Void = { _ in } var sendMessagePressed: (AttachmentTextInputPanelSendMode) -> Void = { _ in } @@ -874,6 +884,10 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate { } } } + }, longPressAction: { [weak self] in + if let strongSelf = self, i == strongSelf.selectedIndex { + strongSelf.longPressed(type) + } }) ), environment: {}, diff --git a/submodules/ComposePollUI/Sources/CreatePollController.swift b/submodules/ComposePollUI/Sources/CreatePollController.swift index 8d8e493a9f..1f5ba3164b 100644 --- a/submodules/ComposePollUI/Sources/CreatePollController.swift +++ b/submodules/ComposePollUI/Sources/CreatePollController.swift @@ -516,16 +516,51 @@ public final class ComposedPoll { } } -private class CreatePollControllerImpl: ItemListController, AttachmentContainable { +private final class CreatePollContext: AttachmentMediaPickerContext { + var selectionCount: Signal { + return .single(0) + } + + var caption: Signal { + return .single(nil) + } + + public var loadingProgress: Signal { + return .single(nil) + } + + public var mainButtonState: Signal { + return .single(nil) + } + + func setCaption(_ caption: NSAttributedString) { + } + + func send(silently: Bool, mode: AttachmentMediaPickerSendMode) { + } + + func schedule() { + } + + func mainButtonAction() { + } +} + + +public class CreatePollControllerImpl: ItemListController, AttachmentContainable { public var requestAttachmentMenuExpansion: () -> Void = {} public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> ([AttachmentContainable], AttachmentMediaPickerContext?)) -> Void = { _ in } public var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in } public var cancelPanGesture: () -> Void = { } public var isContainerPanning: () -> Bool = { return false } public var isContainerExpanded: () -> Bool = { return false } + + public var mediaPickerContext: AttachmentMediaPickerContext? { + return CreatePollContext() + } } -public func createPollController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, peer: EnginePeer, isQuiz: Bool? = nil, completion: @escaping (ComposedPoll) -> Void) -> AttachmentContainable { +public func createPollController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, peer: EnginePeer, isQuiz: Bool? = nil, completion: @escaping (ComposedPoll) -> Void) -> CreatePollControllerImpl { var initialState = CreatePollControllerState() if let isQuiz = isQuiz { initialState.isQuiz = isQuiz diff --git a/submodules/Display/Source/Navigation/NavigationController.swift b/submodules/Display/Source/Navigation/NavigationController.swift index f73b13db5d..8bb2c46f06 100644 --- a/submodules/Display/Source/Navigation/NavigationController.swift +++ b/submodules/Display/Source/Navigation/NavigationController.swift @@ -433,8 +433,12 @@ open class NavigationController: UINavigationController, ContainableController, minHeight = 40.0 } var inCallStatusBarFrame = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: max(layout.statusBarHeight ?? 0.0, max(minHeight, layout.safeInsets.top)))) - if (layout.deviceMetrics.hasTopNotch || layout.deviceMetrics.hasDynamicIsland) && !isLandscape { - inCallStatusBarFrame.size.height += 12.0 + if !isLandscape { + if layout.deviceMetrics.hasTopNotch { + inCallStatusBarFrame.size.height += 12.0 + } else if layout.deviceMetrics.hasDynamicIsland { + inCallStatusBarFrame.size.height += 20.0 + } } if inCallStatusBar.frame.isEmpty { inCallStatusBar.frame = inCallStatusBarFrame diff --git a/submodules/LocationUI/Sources/LocationPickerController.swift b/submodules/LocationUI/Sources/LocationPickerController.swift index 912d1962b1..d70344413e 100644 --- a/submodules/LocationUI/Sources/LocationPickerController.swift +++ b/submodules/LocationUI/Sources/LocationPickerController.swift @@ -363,4 +363,38 @@ public final class LocationPickerController: ViewController, AttachmentContainab self.interaction?.dismissSearch() self.scrollToTop?() } + + public var mediaPickerContext: AttachmentMediaPickerContext? { + return LocationPickerContext() + } +} + +private final class LocationPickerContext: AttachmentMediaPickerContext { + var selectionCount: Signal { + return .single(0) + } + + var caption: Signal { + return .single(nil) + } + + public var loadingProgress: Signal { + return .single(nil) + } + + public var mainButtonState: Signal { + return .single(nil) + } + + func setCaption(_ caption: NSAttributedString) { + } + + func send(silently: Bool, mode: AttachmentMediaPickerSendMode) { + } + + func schedule() { + } + + func mainButtonAction() { + } } diff --git a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift index d9f4283c40..18f821da8a 100644 --- a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift +++ b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift @@ -154,7 +154,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable { public var openCamera: ((TGAttachmentCameraView?) -> Void)? public var presentSchedulePicker: (Bool, @escaping (Int32) -> Void) -> Void = { _, _ in } public var presentTimerPicker: (@escaping (Int32) -> Void) -> Void = { _ in } - public var presentWebSearch: (MediaGroupsScreen) -> Void = { _ in } + public var presentWebSearch: (MediaGroupsScreen, Bool) -> Void = { _, _ in } public var getCaptionPanelView: () -> TGCaptionPanelView? = { return nil } private var completed = false @@ -1350,6 +1350,12 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable { } self.updateSelectionState(count: Int32(selectionContext.count())) + + self.longTapWithTabBar = { [weak self] in + if let strongSelf = self { + strongSelf.presentSearch(activateOnDisplay: false) + } + } } required init(coder aDecoder: NSCoder) { @@ -1572,27 +1578,34 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable { self.controllerNode.updateNavigation(delayDisappear: true, transition: .immediate) } + private func presentSearch(activateOnDisplay: Bool) { + guard self.moreButtonNode.iconNode.iconState == .search else { + return + } + self.requestAttachmentMenuExpansion() + self.presentWebSearch(MediaGroupsScreen(context: self.context, updatedPresentationData: self.updatedPresentationData, mediaAssetsContext: self.controllerNode.mediaAssetsContext, openGroup: { [weak self] collection in + if let strongSelf = self { + let mediaPicker = MediaPickerScreen(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: strongSelf.peer, threadTitle: strongSelf.threadTitle, chatLocation: strongSelf.chatLocation, bannedSendPhotos: strongSelf.bannedSendPhotos, bannedSendVideos: strongSelf.bannedSendVideos, subject: .assets(collection), editingContext: strongSelf.interaction?.editingState, selectionContext: strongSelf.interaction?.selectionState) + + mediaPicker.presentSchedulePicker = strongSelf.presentSchedulePicker + mediaPicker.presentTimerPicker = strongSelf.presentTimerPicker + mediaPicker.getCaptionPanelView = strongSelf.getCaptionPanelView + mediaPicker.legacyCompletion = strongSelf.legacyCompletion + mediaPicker.dismissAll = { [weak self] in + self?.dismiss(animated: true, completion: nil) + } + + mediaPicker._presentedInModal = true + mediaPicker.updateNavigationStack = strongSelf.updateNavigationStack + strongSelf.updateNavigationStack({ _ in return ([strongSelf, mediaPicker], strongSelf.mediaPickerContext)}) + } + }), activateOnDisplay) + } + @objc private func searchOrMorePressed(node: ContextReferenceContentNode, gesture: ContextGesture?) { switch self.moreButtonNode.iconNode.iconState { case .search: - self.requestAttachmentMenuExpansion() - self.presentWebSearch(MediaGroupsScreen(context: self.context, updatedPresentationData: self.updatedPresentationData, mediaAssetsContext: self.controllerNode.mediaAssetsContext, openGroup: { [weak self] collection in - if let strongSelf = self { - let mediaPicker = MediaPickerScreen(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: strongSelf.peer, threadTitle: strongSelf.threadTitle, chatLocation: strongSelf.chatLocation, bannedSendPhotos: strongSelf.bannedSendPhotos, bannedSendVideos: strongSelf.bannedSendVideos, subject: .assets(collection), editingContext: strongSelf.interaction?.editingState, selectionContext: strongSelf.interaction?.selectionState) - - mediaPicker.presentSchedulePicker = strongSelf.presentSchedulePicker - mediaPicker.presentTimerPicker = strongSelf.presentTimerPicker - mediaPicker.getCaptionPanelView = strongSelf.getCaptionPanelView - mediaPicker.legacyCompletion = strongSelf.legacyCompletion - mediaPicker.dismissAll = { [weak self] in - self?.dismiss(animated: true, completion: nil) - } - - mediaPicker._presentedInModal = true - mediaPicker.updateNavigationStack = strongSelf.updateNavigationStack - strongSelf.updateNavigationStack({ _ in return ([strongSelf, mediaPicker], strongSelf.mediaPickerContext)}) - } - })) + self.presentSearch(activateOnDisplay: true) case .more: let strings = self.presentationData.strings let selectionCount = self.selectionCount diff --git a/submodules/TelegramUI/Sources/AttachmentFileController.swift b/submodules/TelegramUI/Sources/AttachmentFileController.swift index 0f383c5b5c..7550b1a2ae 100644 --- a/submodules/TelegramUI/Sources/AttachmentFileController.swift +++ b/submodules/TelegramUI/Sources/AttachmentFileController.swift @@ -163,7 +163,37 @@ private func attachmentFileControllerEntries(presentationData: PresentationData, return entries } -private class AttachmentFileControllerImpl: ItemListController, AttachmentContainable { +private final class AttachmentFileContext: AttachmentMediaPickerContext { + var selectionCount: Signal { + return .single(0) + } + + var caption: Signal { + return .single(nil) + } + + public var loadingProgress: Signal { + return .single(nil) + } + + public var mainButtonState: Signal { + return .single(nil) + } + + func setCaption(_ caption: NSAttributedString) { + } + + func send(silently: Bool, mode: AttachmentMediaPickerSendMode) { + } + + func schedule() { + } + + func mainButtonAction() { + } +} + +class AttachmentFileControllerImpl: ItemListController, AttachmentContainable { public var requestAttachmentMenuExpansion: () -> Void = {} public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> ([AttachmentContainable], AttachmentMediaPickerContext?)) -> Void = { _ in } public var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in } @@ -174,23 +204,27 @@ private class AttachmentFileControllerImpl: ItemListController, AttachmentContai var delayDisappear = false var resetForReuseImpl: () -> Void = {} - public func resetForReuse() { + func resetForReuse() { self.resetForReuseImpl() self.scrollToTop?() } - public func prepareForReuse() { + func prepareForReuse() { self.delayDisappear = true self.visibleBottomContentOffsetChanged?(self.visibleBottomContentOffset) self.delayDisappear = false } + + public var mediaPickerContext: AttachmentMediaPickerContext? { + return AttachmentFileContext() + } } private struct AttachmentFileControllerState: Equatable { var searching: Bool } -public func attachmentFileController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, bannedSendMedia: (Int32, Bool)?, presentGallery: @escaping () -> Void, presentFiles: @escaping () -> Void, send: @escaping (AnyMediaReference) -> Void) -> AttachmentContainable { +func attachmentFileController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, bannedSendMedia: (Int32, Bool)?, presentGallery: @escaping () -> Void, presentFiles: @escaping () -> Void, send: @escaping (AnyMediaReference) -> Void) -> AttachmentFileControllerImpl { let actionsDisposable = DisposableSet() let statePromise = ValuePromise(AttachmentFileControllerState(searching: false), ignoreRepeated: true) diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index b7d1440d76..4e74668a01 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -10653,6 +10653,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if case .standard(false) = self.presentationInterfaceState.mode, self.raiseToListen == nil { self.raiseToListen = RaiseToListenManager(shouldActivate: { [weak self] in if let strongSelf = self, strongSelf.isNodeLoaded && strongSelf.canReadHistoryValue, strongSelf.presentationInterfaceState.interfaceState.editMessage == nil, strongSelf.playlistStateAndType == nil { + if !strongSelf.context.sharedContext.currentMediaInputSettings.with({ $0.enableRaiseToSpeak }) { + return false + } + if strongSelf.presentationInterfaceState.inputTextPanelState.mediaRecordingState != nil { return false } @@ -10670,13 +10674,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return false } - if case let .media(_, expanded, _) = strongSelf.presentationInterfaceState.inputMode, expanded != nil { + if case .media = strongSelf.presentationInterfaceState.inputMode { return false } - if !strongSelf.context.sharedContext.currentMediaInputSettings.with({ $0.enableRaiseToSpeak }) { - return false - } + return true } @@ -10712,14 +10714,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } strongSelf.chatDisplayNode.historyNode.voicePlaylistItemChanged(previousItem, currentItem) -// if let currentItem = currentItem?.id as? PeerMessagesMediaPlaylistItemId { -// self.controllerInteraction?.currentlyPlayingMessageId = currentItem.messageId -// if let previousItem = previousItem?.id as? PeerMessagesMediaPlaylistItemId, previousItem.messageId.peerId == peerId, currentItem.messageId.peerId == peerId, currentItem.messageId != previousItem.messageId { -// if strongSelf.chatDisplayNode.historyNode.isMessageVisibleOnScreen(currentItem.messageId) { -// strongSelf.navigateToMessage(from: nil, to: .id(currentItem.messageId, nil), scrollPosition: .center(.bottom), rememberInStack: false, animated: true, completion: nil) -// } -// } -// } } } @@ -12630,8 +12624,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let inputText = strongSelf.presentationInterfaceState.interfaceState.effectiveInputState.inputText let currentMediaController = Atomic(value: nil) - let currentFilesController = Atomic(value: nil) - let currentLocationController = Atomic(value: nil) + let currentFilesController = Atomic(value: nil) + let currentLocationController = Atomic(value: nil) let attachmentController = AttachmentController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, chatLocation: strongSelf.chatLocation, buttons: buttons, initialButton: initialButton, makeEntityInputView: { [weak self] in guard let strongSelf = self else { @@ -12680,7 +12674,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.controllerNavigationDisposable.set(nil) let existingController = currentFilesController.with { $0 } if let controller = existingController { - completion(controller, nil) + completion(controller, controller.mediaPickerContext) controller.prepareForReuse() return } @@ -12703,12 +12697,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) }) let _ = currentFilesController.swap(controller) - completion(controller, nil) + completion(controller, controller.mediaPickerContext) case .location: strongSelf.controllerNavigationDisposable.set(nil) let existingController = currentLocationController.with { $0 } if let controller = existingController { - completion(controller, nil) + completion(controller, controller.mediaPickerContext) controller.prepareForReuse() return } @@ -12743,7 +12737,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }, nil) strongSelf.sendMessages([message]) }) - completion(controller, nil) + completion(controller, controller.mediaPickerContext) let _ = currentLocationController.swap(controller) }) @@ -12909,7 +12903,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G })) case .poll: let controller = strongSelf.configurePollCreation() - completion(controller, nil) + completion(controller, controller?.mediaPickerContext) strongSelf.controllerNavigationDisposable.set(nil) case let .app(bot, botName, _): let params = WebAppParameters(peerId: peer.id, botId: bot.id, botName: botName, url: nil, queryId: nil, payload: botPayload, buttonText: nil, keepAliveSignal: nil, fromMenu: false, isSimple: false) @@ -13398,8 +13392,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G controller.openCamera = { [weak self] cameraView in self?.openCamera(cameraView: cameraView) } - controller.presentWebSearch = { [weak self, weak controller] mediaGroups in - self?.presentWebSearch(editingMessage: false, attachment: true, present: { [weak controller] c, a in + controller.presentWebSearch = { [weak self, weak controller] mediaGroups, activateOnDisplay in + self?.presentWebSearch(editingMessage: false, attachment: true, activateOnDisplay: activateOnDisplay, present: { [weak controller] c, a in controller?.present(c, in: .current) if let webSearchController = c as? WebSearchController { webSearchController.searchingUpdated = { [weak mediaGroups] searching in @@ -13560,7 +13554,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) } - private func presentWebSearch(editingMessage: Bool, attachment: Bool, present: @escaping (ViewController, Any?) -> Void) { + private func presentWebSearch(editingMessage: Bool, attachment: Bool, activateOnDisplay: Bool = true, present: @escaping (ViewController, Any?) -> Void) { guard let peer = self.presentationInterfaceState.renderedPeer?.peer else { return } @@ -13583,7 +13577,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } }) - })) + }), activateOnDisplay: activateOnDisplay) controller.attemptItemSelection = { [weak strongSelf] item in guard let strongSelf, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else { return false @@ -14158,7 +14152,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.present(tooltipScreen, in: .current) } - private func configurePollCreation(isQuiz: Bool? = nil) -> AttachmentContainable? { + private func configurePollCreation(isQuiz: Bool? = nil) -> CreatePollControllerImpl? { guard let peer = self.presentationInterfaceState.renderedPeer?.peer else { return nil } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift index e5492db0f4..250f353d63 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift @@ -306,7 +306,7 @@ final class PeerInfoHeaderNavigationTransition { final class PeerInfoAvatarTransformContainerNode: ASDisplayNode { let context: AccountContext - private let containerNode: ContextControllerSourceNode + let containerNode: ContextControllerSourceNode let avatarNode: AvatarNode fileprivate var videoNode: UniversalVideoNode? @@ -2509,11 +2509,11 @@ final class PeerInfoHeaderNode: ASDisplayNode { func updateAvatarIsHidden(entry: AvatarGalleryEntry?) { if let entry = entry { - self.avatarListNode.avatarContainerNode.avatarNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first - self.editingContentNode.avatarNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first + self.avatarListNode.avatarContainerNode.containerNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first + self.editingContentNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first } else { - self.avatarListNode.avatarContainerNode.avatarNode.isHidden = false - self.editingContentNode.avatarNode.isHidden = false + self.avatarListNode.avatarContainerNode.containerNode.isHidden = false + self.editingContentNode.isHidden = false } self.avatarListNode.listContainerNode.updateEntryIsHidden(entry: entry) } diff --git a/submodules/WebSearchUI/Sources/WebSearchController.swift b/submodules/WebSearchUI/Sources/WebSearchController.swift index b8a63649ea..fb2b69a473 100644 --- a/submodules/WebSearchUI/Sources/WebSearchController.swift +++ b/submodules/WebSearchUI/Sources/WebSearchController.swift @@ -85,6 +85,7 @@ public final class WebSearchController: ViewController { private let peer: EnginePeer? private let chatLocation: ChatLocation? private let configuration: EngineConfiguration.SearchBots + private let activateOnDisplay: Bool private var controllerNode: WebSearchControllerNode { return self.displayNode as! WebSearchControllerNode @@ -121,12 +122,13 @@ public final class WebSearchController: ViewController { public var attemptItemSelection: (ChatContextResult) -> Bool = { _ in return true } - public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, peer: EnginePeer?, chatLocation: ChatLocation?, configuration: EngineConfiguration.SearchBots, mode: WebSearchControllerMode) { + public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, peer: EnginePeer?, chatLocation: ChatLocation?, configuration: EngineConfiguration.SearchBots, mode: WebSearchControllerMode, activateOnDisplay: Bool = true) { self.context = context self.mode = mode self.peer = peer self.chatLocation = chatLocation self.configuration = configuration + self.activateOnDisplay = activateOnDisplay let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 } self.interfaceState = WebSearchInterfaceState(presentationData: presentationData) @@ -329,7 +331,7 @@ public final class WebSearchController: ViewController { self.didPlayPresentationAnimation = true self.controllerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) } - if !self.didActivateSearch { + if !self.didActivateSearch && self.activateOnDisplay { self.didActivateSearch = true self.navigationContentNode?.activate(select: select) } From 6a5bead5bcef8d5d84dc7af54c3becb2379d64a4 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 2 Feb 2023 07:09:47 +0400 Subject: [PATCH 07/13] Fix gallery push animation --- submodules/GalleryUI/Sources/GalleryController.swift | 4 ++++ submodules/TelegramUI/Sources/ChatController.swift | 3 +++ 2 files changed, 7 insertions(+) diff --git a/submodules/GalleryUI/Sources/GalleryController.swift b/submodules/GalleryUI/Sources/GalleryController.swift index c48b278773..2d18e46444 100644 --- a/submodules/GalleryUI/Sources/GalleryController.swift +++ b/submodules/GalleryUI/Sources/GalleryController.swift @@ -1112,6 +1112,10 @@ public class GalleryController: ViewController, StandalonePresentableController, let animatedOutNode = !simpleAnimation + if let chatController = strongSelf.baseNavigationController?.topViewController as? ChatController { + chatController.updatePushedTransition(0.0, transition: .animated(duration: 0.45, curve: .customSpring(damping: 180.0, initialVelocity: 0.0))) + } + strongSelf.galleryNode.animateOut(animateContent: animatedOutNode, completion: { }) } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 4e74668a01..1fccb8b2b0 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -18216,6 +18216,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } public func updatePushedTransition(_ fraction: CGFloat, transition: ContainedViewLayoutTransition) { + if !transition.isAnimated { + self.chatDisplayNode.historyNodeContainer.layer.removeAllAnimations() + } let scale: CGFloat = 1.0 - 0.06 * fraction transition.updateTransformScale(node: self.chatDisplayNode.historyNodeContainer, scale: scale) } From 55ff4563f777513d4cc1f3488337b97211da0d4a Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 2 Feb 2023 17:17:06 +0400 Subject: [PATCH 08/13] Fix Chinese and Norwegian language detection --- .../TranslateUI/Sources/ChatTranslation.swift | 18 +++++++++++++---- .../TranslateUI/Sources/Translate.swift | 20 +++++++++++++------ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/submodules/TranslateUI/Sources/ChatTranslation.swift b/submodules/TranslateUI/Sources/ChatTranslation.swift index 1a869e8512..c43060353b 100644 --- a/submodules/TranslateUI/Sources/ChatTranslation.swift +++ b/submodules/TranslateUI/Sources/ChatTranslation.swift @@ -222,14 +222,24 @@ public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id) let hypotheses = languageRecognizer.languageHypotheses(withMaximum: 4) languageRecognizer.reset() - let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains($0.key.rawValue) }.sorted(by: { $0.value > $1.value }) - if let language = filteredLanguages.first(where: { supportedTranslationLanguages.contains($0.key.rawValue) }) { - let fromLang = language.key.rawValue + func normalize(_ code: String) -> String { + if code.contains("-") { + return code.components(separatedBy: "-").first ?? code + } else if code == "nb" { + return "no" + } else { + return code + } + } + + let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains(normalize($0.key.rawValue)) }.sorted(by: { $0.value > $1.value }) + if let language = filteredLanguages.first { + let fromLang = normalize(language.key.rawValue) fromLangs[fromLang] = (fromLangs[fromLang] ?? 0) + message.text.count count += 1 } } - if count >= 10 { + if count >= 16 { break } } diff --git a/submodules/TranslateUI/Sources/Translate.swift b/submodules/TranslateUI/Sources/Translate.swift index 80bdd32879..5a70f375ce 100644 --- a/submodules/TranslateUI/Sources/Translate.swift +++ b/submodules/TranslateUI/Sources/Translate.swift @@ -25,9 +25,6 @@ public var supportedTranslationLanguages = [ "ca", "ceb", "zh", -// "zh-Hant", -// "zh-CN", "zh" -// "zh-TW" "co", "hr", "cs", @@ -168,9 +165,20 @@ public func canTranslateText(context: AccountContext, text: String, showTranslat supportedTranslationLanguages = ["uk", "ru"] } - let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains($0.key.rawValue) }.sorted(by: { $0.value > $1.value }) - if let language = filteredLanguages.first(where: { supportedTranslationLanguages.contains($0.key.rawValue) }) { - return (!dontTranslateLanguages.contains(language.key.rawValue), language.key.rawValue) + func normalize(_ code: String) -> String { + if code.contains("-") { + return code.components(separatedBy: "-").first ?? code + } else if code == "nb" { + return "no" + } else { + return code + } + } + + let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains(normalize($0.key.rawValue)) }.sorted(by: { $0.value > $1.value }) + if let language = filteredLanguages.first { + let languageCode = normalize(language.key.rawValue) + return (!dontTranslateLanguages.contains(languageCode), languageCode) } else { return (false, nil) } From 927f7786a0c362f0adc4c3aec6993997cfdf8db1 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 2 Feb 2023 17:17:46 +0400 Subject: [PATCH 09/13] Various improvements --- submodules/Display/Source/GenerateImage.swift | 6 +++--- submodules/Display/Source/NavigationBar.swift | 1 + .../Sources/MediaGroupsAlbumGridItem.swift | 9 +++++---- .../MediaPickerUI/Sources/MediaGroupsScreen.swift | 2 +- .../LocalizationListControllerNode.swift | 11 +++++++++++ submodules/TelegramUI/Sources/AppDelegate.swift | 1 + .../TelegramUI/Sources/ChatTranslationPanelNode.swift | 2 +- .../WebSearchUI/Sources/WebSearchControllerNode.swift | 6 +++--- 8 files changed, 26 insertions(+), 12 deletions(-) diff --git a/submodules/Display/Source/GenerateImage.swift b/submodules/Display/Source/GenerateImage.swift index 97cd118f4d..59c4234b5c 100644 --- a/submodules/Display/Source/GenerateImage.swift +++ b/submodules/Display/Source/GenerateImage.swift @@ -351,7 +351,7 @@ public func generateGradientTintedImage(image: UIImage?, colors: [UIColor]) -> U let t = CGFloat(i) / CGFloat(colors.count - 1) locations.append(t) } - let colorSpace = CGColorSpaceCreateDeviceRGB() + let colorSpace = DeviceGraphicsContextSettings.shared.colorSpace let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)! context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: imageRect.height), end: CGPoint(x: 0.0, y: 0.0), options: CGGradientDrawingOptions()) @@ -381,7 +381,7 @@ public func generateGradientImage(size: CGSize, colors: [UIColor], locations: [C UIGraphicsBeginImageContextWithOptions(size, false, 0.0) if let context = UIGraphicsGetCurrentContext() { let gradientColors = colors.map { $0.cgColor } as CFArray - let colorSpace = CGColorSpaceCreateDeviceRGB() + let colorSpace = DeviceGraphicsContextSettings.shared.colorSpace var locations = locations let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)! @@ -403,7 +403,7 @@ public func generateGradientFilledCircleImage(diameter: CGFloat, colors: NSArray context.clip() var locations: [CGFloat] = [0.0, 1.0] - let colorSpace = CGColorSpaceCreateDeviceRGB() + let colorSpace = DeviceGraphicsContextSettings.shared.colorSpace let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: &locations)! context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: bounds.size.height), options: CGGradientDrawingOptions()) diff --git a/submodules/Display/Source/NavigationBar.swift b/submodules/Display/Source/NavigationBar.swift index c2ac67ea80..7752442d25 100644 --- a/submodules/Display/Source/NavigationBar.swift +++ b/submodules/Display/Source/NavigationBar.swift @@ -1190,6 +1190,7 @@ open class NavigationBar: ASDisplayNode { self.badgeNode.updateTheme(fillColor: self.presentationData.theme.buttonColor, strokeColor: self.presentationData.theme.buttonColor, textColor: self.presentationData.theme.badgeTextColor) + self.updateLeftButton(animated: false) self.requestLayout() } } diff --git a/submodules/MediaPickerUI/Sources/MediaGroupsAlbumGridItem.swift b/submodules/MediaPickerUI/Sources/MediaGroupsAlbumGridItem.swift index c6df8e16aa..7b1f98b574 100644 --- a/submodules/MediaPickerUI/Sources/MediaGroupsAlbumGridItem.swift +++ b/submodules/MediaPickerUI/Sources/MediaGroupsAlbumGridItem.swift @@ -140,7 +140,7 @@ private final class MediaGroupsGridAlbumItemNode : ListViewItemNode { override func didLoad() { super.didLoad() - self.imageNode.cornerRadius = 10.0 + self.imageNode.cornerRadius = 5.0 if #available(iOS 13.0, *) { self.imageNode.layer.cornerCurve = .continuous } @@ -221,11 +221,11 @@ private func preparedTransition(action: @escaping (PHAssetCollection) -> Void, f } final class MediaGroupsAlbumGridItem: ListViewItem { - let presentationData: ItemListPresentationData + let presentationData: PresentationData let collections: [PHAssetCollection] let action: (PHAssetCollection) -> Void - public init(presentationData: ItemListPresentationData, collections: [PHAssetCollection], action: @escaping (PHAssetCollection) -> Void) { + public init(presentationData: PresentationData, collections: [PHAssetCollection], action: @escaping (PHAssetCollection) -> Void) { self.presentationData = presentationData self.collections = collections self.action = action @@ -347,7 +347,8 @@ private class MediaGroupsAlbumGridItemNode: ListViewItemNode { firstItem = result.firstObject } if let firstItem = firstItem { - entries.append(MediaGroupsGridAlbumEntry(theme: item.presentationData.theme, index: index, collection: collection, firstItem: firstItem, count: presentationStringsFormattedNumber(Int32(result.count)))) + let count = presentationStringsFormattedNumber(Int32(result.count), item.presentationData.dateTimeFormat.groupingSeparator) + entries.append(MediaGroupsGridAlbumEntry(theme: item.presentationData.theme, index: index, collection: collection, firstItem: firstItem, count: count)) index += 1 } } diff --git a/submodules/MediaPickerUI/Sources/MediaGroupsScreen.swift b/submodules/MediaPickerUI/Sources/MediaGroupsScreen.swift index 0f9337ae58..bf94a0446c 100644 --- a/submodules/MediaPickerUI/Sources/MediaGroupsScreen.swift +++ b/submodules/MediaPickerUI/Sources/MediaGroupsScreen.swift @@ -91,7 +91,7 @@ private enum MediaGroupsEntry: Comparable, Identifiable { case let .albumsHeader(_, text), let .smartAlbumsHeader(_, text): return MediaGroupsHeaderItem(presentationData: ItemListPresentationData(presentationData), title: text) case let .albums(_, collections): - return MediaGroupsAlbumGridItem(presentationData: ItemListPresentationData(presentationData), collections: collections, action: { collection in + return MediaGroupsAlbumGridItem(presentationData: presentationData, collections: collections, action: { collection in openGroup(collection) }) case let .smartAlbum(_, _, collection, count): diff --git a/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift b/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift index c7adeb131a..92a77ffb9a 100644 --- a/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift +++ b/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift @@ -612,7 +612,18 @@ final class LocalizationListControllerNode: ViewControllerTracingNode { } func updatePresentationData(_ presentationData: PresentationData) { + let stringsUpdated = self.presentationData.strings !== presentationData.strings self.presentationData = presentationData + + if stringsUpdated { + if let snapshotView = self.view.snapshotView(afterScreenUpdates: false) { + self.view.addSubview(snapshotView) + snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak snapshotView] _ in + snapshotView?.removeFromSuperview() + }) + } + } + self.presentationDataValue.set(.single(presentationData)) self.backgroundColor = presentationData.theme.list.blocksBackgroundColor self.listNode.keepTopItemOverscrollBackground = ListViewKeepTopItemOverscrollBackground(color: presentationData.theme.list.blocksBackgroundColor, direction: true) diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index 9e064fa2cb..ab73b00203 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -319,6 +319,7 @@ private func extractAccountManagerState(records: AccountRecordsView (cleanSize: CGSize, apparentHeight: CGFloat) { - let constrainedSize = CGSize(width: min(260.0, constrainedWidth), height: min(604.0, maxHeight)) + let constrainedSize = CGSize(width: min(220.0, constrainedWidth), height: min(604.0, maxHeight)) var topContentHeight: CGFloat = 0.0 if let backButtonNode = self.backButtonNode { diff --git a/submodules/WebSearchUI/Sources/WebSearchControllerNode.swift b/submodules/WebSearchUI/Sources/WebSearchControllerNode.swift index fc840cb691..666a768400 100644 --- a/submodules/WebSearchUI/Sources/WebSearchControllerNode.swift +++ b/submodules/WebSearchUI/Sources/WebSearchControllerNode.swift @@ -245,9 +245,9 @@ class WebSearchControllerNode: ASDisplayNode { self.addSubnode(self.segmentedContainerNode) self.segmentedContainerNode.addSubnode(self.segmentedBackgroundNode) self.segmentedContainerNode.addSubnode(self.segmentedSeparatorNode) - if case .media = mode { - self.segmentedContainerNode.addSubnode(self.segmentedControlNode) - } +// if case .media = mode { +// self.segmentedContainerNode.addSubnode(self.segmentedControlNode) +// } if !attachment { self.addSubnode(self.toolbarBackgroundNode) self.addSubnode(self.toolbarSeparatorNode) From 1aff8f35406f8e1b0dcc7a83b3f215f901f49d91 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 2 Feb 2023 17:38:13 +0400 Subject: [PATCH 10/13] Use raise to listen instead instead of bare proximity sensor for ear speaker switching --- .../Sources/SharedMediaPlayer.swift | 64 ++++++++++++++----- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/submodules/TelegramUI/Sources/SharedMediaPlayer.swift b/submodules/TelegramUI/Sources/SharedMediaPlayer.swift index 0e20d9d467..5fd209ea2a 100644 --- a/submodules/TelegramUI/Sources/SharedMediaPlayer.swift +++ b/submodules/TelegramUI/Sources/SharedMediaPlayer.swift @@ -9,6 +9,7 @@ import TelegramAudio import AccountContext import TelegramUniversalVideoContent import DeviceProximity +import RaiseToListen private enum SharedMediaPlaybackItem: Equatable { case audio(MediaPlayer) @@ -120,7 +121,9 @@ final class SharedMediaPlayer { private var playbackRate: AudioPlaybackRate - private var proximityManagerIndex: Int? + //private var proximityManagerIndex: Int? + private var raiseToListen: RaiseToListenManager? + private let controlPlaybackWithProximity: Bool private var forceAudioToSpeaker = false @@ -346,9 +349,10 @@ final class SharedMediaPlayer { } else { strongSelf.playbackStateValue.set(.single(nil)) if !state.loading { - if let proximityManagerIndex = strongSelf.proximityManagerIndex { - DeviceProximityManager.shared().remove(proximityManagerIndex) - } + strongSelf.raiseToListen = nil +// if let proximityManagerIndex = strongSelf.proximityManagerIndex { +// DeviceProximityManager.shared().remove(proximityManagerIndex) +// } } } } @@ -362,18 +366,44 @@ final class SharedMediaPlayer { }) if controlPlaybackWithProximity { - self.proximityManagerIndex = DeviceProximityManager.shared().add { [weak self] value in - let forceAudioToSpeaker = !value - if let strongSelf = self, strongSelf.forceAudioToSpeaker != forceAudioToSpeaker { - strongSelf.forceAudioToSpeaker = forceAudioToSpeaker - strongSelf.playbackItem?.setForceAudioToSpeaker(forceAudioToSpeaker) - if !forceAudioToSpeaker { - strongSelf.control(.playback(.play)) - } else { - strongSelf.control(.playback(.pause)) + self.raiseToListen = RaiseToListenManager(shouldActivate: { + return true + }, activate: { [weak self] in + if let strongSelf = self { + let forceAudioToSpeaker = false + if strongSelf.forceAudioToSpeaker != forceAudioToSpeaker { + strongSelf.forceAudioToSpeaker = forceAudioToSpeaker + strongSelf.playbackItem?.setForceAudioToSpeaker(forceAudioToSpeaker) + if !forceAudioToSpeaker { + strongSelf.control(.playback(.play)) + } } } - } + }, deactivate: { [weak self] in + if let strongSelf = self { + let forceAudioToSpeaker = true + if strongSelf.forceAudioToSpeaker != forceAudioToSpeaker { + strongSelf.forceAudioToSpeaker = forceAudioToSpeaker + strongSelf.playbackItem?.setForceAudioToSpeaker(forceAudioToSpeaker) + if forceAudioToSpeaker { + strongSelf.control(.playback(.pause)) + } + } + } + }) + self.raiseToListen?.enabled = true +// self.proximityManagerIndex = DeviceProximityManager.shared().add { [weak self] value in +// let forceAudioToSpeaker = !value +// if let strongSelf = self, strongSelf.forceAudioToSpeaker != forceAudioToSpeaker { +// strongSelf.forceAudioToSpeaker = forceAudioToSpeaker +// strongSelf.playbackItem?.setForceAudioToSpeaker(forceAudioToSpeaker) +// if !forceAudioToSpeaker { +// strongSelf.control(.playback(.play)) +// } else { +// strongSelf.control(.playback(.pause)) +// } +// } +// } } } @@ -384,9 +414,9 @@ final class SharedMediaPlayer { self.playbackStateValueDisposable?.dispose() self.prefetchDisposable.dispose() - if let proximityManagerIndex = self.proximityManagerIndex { - DeviceProximityManager.shared().remove(proximityManagerIndex) - } +// if let proximityManagerIndex = self.proximityManagerIndex { +// DeviceProximityManager.shared().remove(proximityManagerIndex) +// } if let playbackItem = self.playbackItem { switch playbackItem { From 1e5381a6f23beb8f1e051ec4f5a335815325dd26 Mon Sep 17 00:00:00 2001 From: Mike Renoir <> Date: Fri, 3 Feb 2023 14:30:39 +0400 Subject: [PATCH 11/13] macos 10.12 crash fix --- .../Postbox/Sources/TimeBasedCleanup.swift | 26 ++++++++++++++----- .../Resources/CollectCacheUsageStats.swift | 26 ++++++++++++++----- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/submodules/Postbox/Sources/TimeBasedCleanup.swift b/submodules/Postbox/Sources/TimeBasedCleanup.swift index 0e14f9a194..6579b10911 100644 --- a/submodules/Postbox/Sources/TimeBasedCleanup.swift +++ b/submodules/Postbox/Sources/TimeBasedCleanup.swift @@ -272,17 +272,29 @@ private func scanFiles(at path: String, olderThan minTimestamp: Int32, includeSu }*/ private func statForDirectory(path: String) -> Int64 { - var s = darwin_dirstat() - var result = dirstat_np(path, 1, &s, MemoryLayout.size) - if result != -1 { - return Int64(s.total_size) - } else { - result = dirstat_np(path, 0, &s, MemoryLayout.size) + if #available(macOS 10.13, *) { + var s = darwin_dirstat() + var result = dirstat_np(path, 1, &s, MemoryLayout.size) if result != -1 { return Int64(s.total_size) } else { - return 0 + result = dirstat_np(path, 0, &s, MemoryLayout.size) + if result != -1 { + return Int64(s.total_size) + } else { + return 0 + } } + } else { + let fileManager = FileManager.default + let folderURL = URL(fileURLWithPath: path) + var folderSize: Int64 = 0 + if let files = try? fileManager.contentsOfDirectory(at: folderURL, includingPropertiesForKeys: nil, options: []) { + for file in files { + folderSize += (fileSize(file.path) ?? 0) + } + } + return folderSize } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Resources/CollectCacheUsageStats.swift b/submodules/TelegramCore/Sources/TelegramEngine/Resources/CollectCacheUsageStats.swift index 315393596d..2531804cf5 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Resources/CollectCacheUsageStats.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Resources/CollectCacheUsageStats.swift @@ -143,17 +143,29 @@ private extension StorageUsageStats { } private func statForDirectory(path: String) -> Int64 { - var s = darwin_dirstat() - var result = dirstat_np(path, 1, &s, MemoryLayout.size) - if result != -1 { - return Int64(s.total_size) - } else { - result = dirstat_np(path, 0, &s, MemoryLayout.size) + if #available(macOS 10.13, *) { + var s = darwin_dirstat() + var result = dirstat_np(path, 1, &s, MemoryLayout.size) if result != -1 { return Int64(s.total_size) } else { - return 0 + result = dirstat_np(path, 0, &s, MemoryLayout.size) + if result != -1 { + return Int64(s.total_size) + } else { + return 0 + } } + } else { + let fileManager = FileManager.default + let folderURL = URL(fileURLWithPath: path) + var folderSize: Int64 = 0 + if let files = try? fileManager.contentsOfDirectory(at: folderURL, includingPropertiesForKeys: nil, options: []) { + for file in files { + folderSize += (fileSize(file.path) ?? 0) + } + } + return folderSize } } From 21dba6e813bbba03a6abba19aef78f4dd36e5bab Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Fri, 3 Feb 2023 15:31:32 +0400 Subject: [PATCH 12/13] Fix typo --- .../EntityKeyboard/Sources/EmojiPagerContentComponent.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift index 0eff70c99f..9f0013fb96 100644 --- a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift +++ b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift @@ -7141,7 +7141,7 @@ public final class EmojiPagerContentComponent: Component { topReactions = orderedView } else if orderedView.collectionId == Namespaces.OrderedItemList.CloudFeaturedProfilePhotoEmoji { featuredAvatarEmoji = orderedView - } else if orderedView.collectionId == Namespaces.OrderedItemList.CloudFeaturedProfilePhotoEmoji { + } else if orderedView.collectionId == Namespaces.OrderedItemList.CloudFeaturedGroupPhotoEmoji { featuredAvatarEmoji = orderedView } } From d5b2d433635831d8b1e193dc6741b02810855f8b Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Fri, 3 Feb 2023 16:04:16 +0400 Subject: [PATCH 13/13] Fix another typo --- .../TelegramCore/Sources/State/ManagedRecentStickers.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/TelegramCore/Sources/State/ManagedRecentStickers.swift b/submodules/TelegramCore/Sources/State/ManagedRecentStickers.swift index 70e30d8ac9..48385da8c6 100644 --- a/submodules/TelegramCore/Sources/State/ManagedRecentStickers.swift +++ b/submodules/TelegramCore/Sources/State/ManagedRecentStickers.swift @@ -292,7 +292,7 @@ func managedProfilePhotoEmoji(postbox: Postbox, network: Network) -> Signal Signal { let poll = managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudFeaturedGroupPhotoEmoji, extractItemId: { RecentMediaItemId($0).mediaId.id }, reverseHashOrder: false, forceFetch: false, fetch: { hash in - return network.request(Api.functions.account.getDefaultProfilePhotoEmojis(hash: hash)) + return network.request(Api.functions.account.getDefaultGroupPhotoEmojis(hash: hash)) |> retryRequest |> mapToSignal { result -> Signal<[OrderedItemListEntry]?, NoError> in switch result {