diff --git a/submodules/CallListUI/BUILD b/submodules/CallListUI/BUILD index 20d6366802..21a966fc50 100644 --- a/submodules/CallListUI/BUILD +++ b/submodules/CallListUI/BUILD @@ -34,6 +34,9 @@ swift_library( "//submodules/InviteLinksUI", "//submodules/UndoUI", "//submodules/TelegramCallsUI", + "//submodules/TelegramUI/Components/EdgeEffect", + "//submodules/ComponentFlow", + "//submodules/Components/ComponentDisplayAdapters", ], visibility = [ "//visibility:public", diff --git a/submodules/CallListUI/Sources/CallListController.swift b/submodules/CallListUI/Sources/CallListController.swift index d2a2bc2b4c..fc8b3fac5e 100644 --- a/submodules/CallListUI/Sources/CallListController.swift +++ b/submodules/CallListUI/Sources/CallListController.swift @@ -361,10 +361,10 @@ public final class CallListController: TelegramBaseController { if empty { switch strongSelf.mode { case .tab: - strongSelf.navigationItem.setLeftBarButton(nil, animated: true) - strongSelf.navigationItem.setRightBarButton(nil, animated: true) + strongSelf.navigationItem.setLeftBarButton(nil, animated: strongSelf.controllerNode.didSetReady) + strongSelf.navigationItem.setRightBarButton(nil, animated: strongSelf.controllerNode.didSetReady) case .navigation: - strongSelf.navigationItem.setRightBarButton(nil, animated: true) + strongSelf.navigationItem.setRightBarButton(nil, animated: strongSelf.controllerNode.didSetReady) } } else { var pressedImpl: (() -> Void)? @@ -381,25 +381,24 @@ public final class CallListController: TelegramBaseController { switch strongSelf.mode { case .tab: if strongSelf.editingMode { - strongSelf.navigationItem.setLeftBarButton(UIBarButtonItem(title: strongSelf.presentationData.strings.Common_Done, style: .done, target: strongSelf, action: #selector(strongSelf.donePressed)), animated: true) - strongSelf.navigationItem.setRightBarButton(UIBarButtonItem(customDisplayNode: buttonNode), animated: true) + strongSelf.navigationItem.setLeftBarButton(UIBarButtonItem(title: strongSelf.presentationData.strings.Common_Done, style: .done, target: strongSelf, action: #selector(strongSelf.donePressed)), animated: strongSelf.controllerNode.didSetReady) + strongSelf.navigationItem.setRightBarButton(UIBarButtonItem(customDisplayNode: buttonNode), animated: strongSelf.controllerNode.didSetReady) strongSelf.navigationItem.rightBarButtonItem?.setCustomAction({ pressedImpl?() }) } else { - strongSelf.navigationItem.setLeftBarButton(UIBarButtonItem(title: strongSelf.presentationData.strings.Common_Edit, style: .plain, target: strongSelf, action: #selector(strongSelf.editPressed)), animated: true) - //strongSelf.navigationItem.setRightBarButton(UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(strongSelf.presentationData.theme), style: .plain, target: self, action: #selector(strongSelf.callPressed)), animated: true) - strongSelf.navigationItem.setRightBarButton(nil, animated: true) + strongSelf.navigationItem.setLeftBarButton(UIBarButtonItem(title: strongSelf.presentationData.strings.Common_Edit, style: .plain, target: strongSelf, action: #selector(strongSelf.editPressed)), animated: strongSelf.controllerNode.didSetReady) + strongSelf.navigationItem.setRightBarButton(nil, animated: strongSelf.controllerNode.didSetReady) } case .navigation: if strongSelf.editingMode { - strongSelf.navigationItem.setLeftBarButton(UIBarButtonItem(customDisplayNode: buttonNode), animated: true) + strongSelf.navigationItem.setLeftBarButton(UIBarButtonItem(customDisplayNode: buttonNode), animated: strongSelf.controllerNode.didSetReady) strongSelf.navigationItem.leftBarButtonItem?.setCustomAction({ pressedImpl?() }) - strongSelf.navigationItem.setRightBarButton(UIBarButtonItem(title: strongSelf.presentationData.strings.Common_Done, style: .done, target: strongSelf, action: #selector(strongSelf.donePressed)), animated: true) + strongSelf.navigationItem.setRightBarButton(UIBarButtonItem(title: strongSelf.presentationData.strings.Common_Done, style: .done, target: strongSelf, action: #selector(strongSelf.donePressed)), animated: strongSelf.controllerNode.didSetReady) } else { - strongSelf.navigationItem.setRightBarButton(UIBarButtonItem(title: strongSelf.presentationData.strings.Common_Edit, style: .plain, target: strongSelf, action: #selector(strongSelf.editPressed)), animated: true) + strongSelf.navigationItem.setRightBarButton(UIBarButtonItem(title: strongSelf.presentationData.strings.Common_Edit, style: .plain, target: strongSelf, action: #selector(strongSelf.editPressed)), animated: strongSelf.controllerNode.didSetReady) } } } diff --git a/submodules/CallListUI/Sources/CallListControllerNode.swift b/submodules/CallListUI/Sources/CallListControllerNode.swift index 9b248b7a84..014cf4c92a 100644 --- a/submodules/CallListUI/Sources/CallListControllerNode.swift +++ b/submodules/CallListUI/Sources/CallListControllerNode.swift @@ -15,6 +15,9 @@ import AnimatedStickerNode import TelegramAnimatedStickerNode import AppBundle import ItemListPeerActionItem +import EdgeEffect +import ComponentFlow +import ComponentDisplayAdapters private struct CallListNodeListViewTransition { let callListView: CallListNodeView @@ -185,7 +188,7 @@ final class CallListControllerNode: ASDisplayNode { private var containerLayout: (ContainerViewLayout, CGFloat)? private let _ready = ValuePromise() - private var didSetReady = false + private(set) var didSetReady = false var ready: Signal { return _ready.get() } @@ -220,6 +223,8 @@ final class CallListControllerNode: ASDisplayNode { private let emptyButtonIconNode: ASImageNode private let emptyButtonTextNode: ImmediateTextNode + private let edgeEffectView: EdgeEffectView + private let call: (EngineMessage) -> Void private let joinGroupCall: (EnginePeer.Id, EngineGroupCallDescription) -> Void private let openNewCall: () -> Void @@ -277,6 +282,8 @@ final class CallListControllerNode: ASDisplayNode { self.emptyButtonIconNode.displaysAsynchronously = false self.emptyButtonIconNode.isUserInteractionEnabled = false + self.edgeEffectView = EdgeEffectView() + super.init() self.setViewBlock({ @@ -289,6 +296,8 @@ final class CallListControllerNode: ASDisplayNode { self.addSubnode(self.emptyButtonTextNode) self.addSubnode(self.emptyButtonIconNode) self.addSubnode(self.emptyButtonNode) + + self.view.addSubview(self.edgeEffectView) switch self.mode { case .tab: @@ -945,5 +954,10 @@ final class CallListControllerNode: ASDisplayNode { self.dequeuedInitialTransitionOnLayout = true self.dequeueTransition() } + + let edgeEffectHeight: CGFloat = layout.intrinsicInsets.bottom + let edgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - edgeEffectHeight), size: CGSize(width: layout.size.width, height: edgeEffectHeight)) + transition.updateFrame(view: self.edgeEffectView, frame: edgeEffectFrame) + self.edgeEffectView.update(content: self.presentationData.theme.list.plainBackgroundColor, rect: edgeEffectFrame, edge: .bottom, edgeSize: edgeEffectFrame.height, transition: ComponentTransition(transition)) } } diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index aabf95b693..7072e9109a 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -2102,9 +2102,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { let effectiveBackgroundColor: UIColor if item.isPinned { onlineIcon = PresentationResourcesChatList.recentStatusOnlineIcon(item.presentationData.theme, state: .pinned, voiceChat: self.onlineIsVoiceChat) - //TODO:localize - effectiveBackgroundColor = item.presentationData.theme.chatList.itemBackgroundColor - //effectiveBackgroundColor = item.presentationData.theme.chatList.pinnedItemBackgroundColor + effectiveBackgroundColor = item.presentationData.theme.chatList.pinnedItemBackgroundColor } else { onlineIcon = PresentationResourcesChatList.recentStatusOnlineIcon(item.presentationData.theme, state: .regular, voiceChat: self.onlineIsVoiceChat) effectiveBackgroundColor = item.presentationData.theme.chatList.itemBackgroundColor @@ -2118,9 +2116,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { if let avatarLiveBadge = self.avatarLiveBadge { let effectiveBackgroundColor: UIColor if item.isPinned { - //TODO:localize - effectiveBackgroundColor = item.presentationData.theme.chatList.itemBackgroundColor - //effectiveBackgroundColor = item.presentationData.theme.chatList.pinnedItemBackgroundColor + effectiveBackgroundColor = item.presentationData.theme.chatList.pinnedItemBackgroundColor } else { effectiveBackgroundColor = item.presentationData.theme.chatList.itemBackgroundColor } @@ -4133,9 +4129,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { let effectiveBackgroundColor: UIColor if item.isPinned { - //TODO:localize - effectiveBackgroundColor = item.presentationData.theme.chatList.itemBackgroundColor - //effectiveBackgroundColor = item.presentationData.theme.chatList.pinnedItemBackgroundColor + effectiveBackgroundColor = item.presentationData.theme.chatList.pinnedItemBackgroundColor } else { effectiveBackgroundColor = item.presentationData.theme.chatList.itemBackgroundColor } @@ -4156,9 +4150,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { effectiveBackgroundColor = item.presentationData.theme.chatList.itemHighlightedBackgroundColor } else if case let .chatList(index) = item.index, index.pinningIndex != nil { onlineIcon = PresentationResourcesChatList.recentStatusOnlineIcon(item.presentationData.theme, state: .pinned, voiceChat: onlineIsVoiceChat) - //TODO:localize - effectiveBackgroundColor = item.presentationData.theme.chatList.itemBackgroundColor - //effectiveBackgroundColor = item.presentationData.theme.chatList.pinnedItemBackgroundColor + effectiveBackgroundColor = item.presentationData.theme.chatList.pinnedItemBackgroundColor } else { onlineIcon = PresentationResourcesChatList.recentStatusOnlineIcon(item.presentationData.theme, state: .regular, voiceChat: onlineIsVoiceChat) effectiveBackgroundColor = item.presentationData.theme.chatList.itemBackgroundColor @@ -5070,9 +5062,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { backgroundColor = theme.itemBackgroundColor highlightedBackgroundColor = theme.itemHighlightedBackgroundColor } else { - //TODO:localize - backgroundColor = item.presentationData.theme.chatList.itemBackgroundColor - //backgroundColor = theme.pinnedItemBackgroundColor + backgroundColor = theme.pinnedItemBackgroundColor highlightedBackgroundColor = theme.pinnedItemHighlightedBackgroundColor } } else { diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index 89e700e648..b8b2928332 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -3251,8 +3251,10 @@ public final class ChatListNode: ListView { if entryCount - 1 - i < 0 { continue } - if case .PeerEntry = transition.chatListView.filteredEntries[entryCount - 1 - i] { - } else { + switch transition.chatListView.filteredEntries[entryCount - 1 - i] { + case .PeerEntry, .GroupReferenceEntry: + break + default: continue } if case let .index(index) = transition.chatListView.filteredEntries[entryCount - 1 - i].sortIndex, case let .chatList(chatListIndex) = index, chatListIndex.pinningIndex != nil { diff --git a/submodules/CountrySelectionUI/Sources/AuthorizationSequenceCountrySelectionController.swift b/submodules/CountrySelectionUI/Sources/AuthorizationSequenceCountrySelectionController.swift index 65745ad6aa..f25be2945b 100644 --- a/submodules/CountrySelectionUI/Sources/AuthorizationSequenceCountrySelectionController.swift +++ b/submodules/CountrySelectionUI/Sources/AuthorizationSequenceCountrySelectionController.swift @@ -142,7 +142,7 @@ private final class AuthorizationSequenceCountrySelectionNavigationContentNode: self.cancel = cancel - self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme), strings: strings, fieldStyle: .modern) + self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme), presentationTheme: theme, strings: strings, fieldStyle: .modern) let placeholderText = strings.Common_Search let searchBarFont = Font.regular(17.0) diff --git a/submodules/FeaturedStickersScreen/Sources/FeaturedStickersScreen.swift b/submodules/FeaturedStickersScreen/Sources/FeaturedStickersScreen.swift index 31e1c17497..4ec29aad8f 100644 --- a/submodules/FeaturedStickersScreen/Sources/FeaturedStickersScreen.swift +++ b/submodules/FeaturedStickersScreen/Sources/FeaturedStickersScreen.swift @@ -980,7 +980,7 @@ private final class SearchNavigationContentNode: NavigationBarContentNode { self.cancel = cancel - self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme), strings: strings, fieldStyle: .modern, cancelText: strings.Common_Done) + self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme), presentationTheme: theme, strings: strings, fieldStyle: .modern, cancelText: strings.Common_Done) let placeholderText = placeholder?(strings) ?? strings.Common_Search let searchBarFont = Font.regular(17.0) @@ -1004,7 +1004,7 @@ private final class SearchNavigationContentNode: NavigationBarContentNode { self.theme = theme self.strings = strings - self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: theme), strings: strings) + self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: theme), presentationTheme: theme, strings: strings) } func setQueryUpdated(_ f: @escaping (String, String?) -> Void) { diff --git a/submodules/HashtagSearchUI/Sources/HashtagSearchController.swift b/submodules/HashtagSearchUI/Sources/HashtagSearchController.swift index c1710530ea..baca0d65aa 100644 --- a/submodules/HashtagSearchUI/Sources/HashtagSearchController.swift +++ b/submodules/HashtagSearchUI/Sources/HashtagSearchController.swift @@ -59,7 +59,7 @@ public final class HashtagSearchController: TelegramBaseController { } self.presentationData = presentationData - super.init(context: context, navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData), mediaAccessoryPanelVisibility: .specific(size: .compact), locationBroadcastPanelSource: .none, groupCallPanelSource: .none) + super.init(context: context, navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData, style: .glass), mediaAccessoryPanelVisibility: .specific(size: .compact), locationBroadcastPanelSource: .none, groupCallPanelSource: .none) self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style @@ -87,7 +87,7 @@ public final class HashtagSearchController: TelegramBaseController { if previousTheme !== presentationData.theme || previousStrings !== presentationData.strings { self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style - self.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationData: self.presentationData), transition: .immediate) + self.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationData: self.presentationData, style: .glass), transition: .immediate) self.controllerNode.updatePresentationData(self.presentationData) } } diff --git a/submodules/HashtagSearchUI/Sources/HashtagSearchNavigationContentNode.swift b/submodules/HashtagSearchUI/Sources/HashtagSearchNavigationContentNode.swift index 1a7d6f3e0a..1ecbfff335 100644 --- a/submodules/HashtagSearchUI/Sources/HashtagSearchNavigationContentNode.swift +++ b/submodules/HashtagSearchUI/Sources/HashtagSearchNavigationContentNode.swift @@ -79,7 +79,7 @@ final class HashtagSearchNavigationContentNode: NavigationBarContentNode { var initialQuery = initialQuery initialQuery.removeFirst() - self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme, hasSeparator: false), strings: strings, fieldStyle: .modern, icon: icon, displayBackground: false) + self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme, hasSeparator: false), presentationTheme: theme, strings: strings, fieldStyle: .modern, icon: icon, displayBackground: false) self.searchBar.text = initialQuery self.searchBar.placeholderString = NSAttributedString(string: strings.HashtagSearch_SearchPlaceholder, font: searchBarFont, textColor: theme.rootController.navigationSearchBar.inputPlaceholderTextColor) @@ -111,7 +111,7 @@ final class HashtagSearchNavigationContentNode: NavigationBarContentNode { func updateTheme(_ theme: PresentationTheme) { self.theme = theme - self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: theme, hasSeparator: false), strings: self.strings) + self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: theme, hasSeparator: false), presentationTheme: theme, strings: self.strings) } func setQueryUpdated(_ f: @escaping (String) -> Void) { diff --git a/submodules/InviteLinksUI/Sources/InviteRequestsSearchItem.swift b/submodules/InviteLinksUI/Sources/InviteRequestsSearchItem.swift index 60dd4a8abe..7202bd643c 100644 --- a/submodules/InviteLinksUI/Sources/InviteRequestsSearchItem.swift +++ b/submodules/InviteLinksUI/Sources/InviteRequestsSearchItem.swift @@ -38,7 +38,7 @@ final class SearchNavigationContentNode: NavigationBarContentNode, ItemListContr self.cancel = cancel - self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme, hasSeparator: false), strings: strings, fieldStyle: .modern, displayBackground: false) + self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme, hasSeparator: false), presentationTheme: theme, strings: strings, fieldStyle: .modern, displayBackground: false) super.init() @@ -66,7 +66,7 @@ final class SearchNavigationContentNode: NavigationBarContentNode, ItemListContr func updateTheme(_ theme: PresentationTheme) { self.theme = theme - self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: self.theme), strings: self.strings) + self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: self.theme), presentationTheme: self.theme, strings: self.strings) self.updatePlaceholder() } diff --git a/submodules/LocationUI/Sources/LocationSearchNavigationContentNode.swift b/submodules/LocationUI/Sources/LocationSearchNavigationContentNode.swift index 8d2baf3cf5..dc2acb4fa0 100644 --- a/submodules/LocationUI/Sources/LocationSearchNavigationContentNode.swift +++ b/submodules/LocationUI/Sources/LocationSearchNavigationContentNode.swift @@ -18,7 +18,7 @@ final class LocationSearchNavigationContentNode: NavigationBarContentNode { self.presentationData = presentationData self.interaction = interaction - self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: presentationData.theme, hasSeparator: false), strings: presentationData.strings, fieldStyle: .modern) + self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: presentationData.theme, hasSeparator: false), presentationTheme: presentationData.theme, strings: presentationData.strings, fieldStyle: .modern) self.searchBar.placeholderString = NSAttributedString(string: presentationData.strings.Map_Search, font: searchBarFont, textColor: presentationData.theme.rootController.navigationSearchBar.inputPlaceholderTextColor) super.init() @@ -58,6 +58,6 @@ final class LocationSearchNavigationContentNode: NavigationBarContentNode { func updatePresentationData(_ presentationData: PresentationData) { self.presentationData = presentationData - self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: presentationData.theme, hasSeparator: false), strings: presentationData.strings) + self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: presentationData.theme, hasSeparator: false), presentationTheme: presentationData.theme, strings: presentationData.strings) } } diff --git a/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupSearchItem.swift b/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupSearchItem.swift index dbe3d0ea69..bd45319a0c 100644 --- a/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupSearchItem.swift +++ b/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupSearchItem.swift @@ -168,6 +168,7 @@ private final class ChannelDiscussionSearchNavigationContentNode: NavigationBarC accent: theme.chat.inputPanel.panelControlAccentColor, keyboard: theme.rootController.keyboardColor ), + presentationTheme: theme, strings: strings, fieldStyle: .inlineNavigation, forceSeparator: false, diff --git a/submodules/PeerInfoUI/Sources/GroupInfoSearchNavigationContentNode.swift b/submodules/PeerInfoUI/Sources/GroupInfoSearchNavigationContentNode.swift index 132b8f876e..824182dcc2 100644 --- a/submodules/PeerInfoUI/Sources/GroupInfoSearchNavigationContentNode.swift +++ b/submodules/PeerInfoUI/Sources/GroupInfoSearchNavigationContentNode.swift @@ -83,6 +83,7 @@ final class GroupInfoSearchNavigationContentNode: NavigationBarContentNode, Item accent: theme.chat.inputPanel.panelControlAccentColor, keyboard: theme.rootController.keyboardColor ), + presentationTheme: theme, strings: strings, fieldStyle: .inlineNavigation, forceSeparator: false, diff --git a/submodules/SearchBarNode/Sources/SearchBarNode.swift b/submodules/SearchBarNode/Sources/SearchBarNode.swift index b9ad6cf7c6..5dbd9afb34 100644 --- a/submodules/SearchBarNode/Sources/SearchBarNode.swift +++ b/submodules/SearchBarNode/Sources/SearchBarNode.swift @@ -894,6 +894,9 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { public var tokensUpdated: (([SearchBarToken]) -> Void)? + private let inlineSearchPlaceholder: SearchBarPlaceholderNode + private var inlineSearchPlaceholderContentsView: SearchBarPlaceholderContentView? + private let backgroundNode: NavigationBackgroundNode private let separatorNode: ASDisplayNode private let textBackgroundNode: ASDisplayNode @@ -972,6 +975,9 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { if let takenSearchPlaceholderContentView = self.takenSearchPlaceholderContentView { takenSearchPlaceholderContentView.updateSearchIconVisibility(isVisible: !self.activity) } + if let inlineSearchPlaceholderContentsView = self.inlineSearchPlaceholderContentsView { + inlineSearchPlaceholderContentsView.updateSearchIconVisibility(isVisible: !self.activity) + } } } } @@ -999,14 +1005,21 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { public let fieldStyle: SearchBarStyle private let forceSeparator: Bool private var theme: SearchBarNodeTheme? + private var presentationTheme: PresentationTheme private var strings: PresentationStrings? private let cancelText: String? - public init(theme: SearchBarNodeTheme, strings: PresentationStrings, fieldStyle: SearchBarStyle = .legacy, icon: Icon = .loupe, forceSeparator: Bool = false, displayBackground: Bool = true, cancelText: String? = nil) { + private var isAnimatingOut: Bool = false + + public init(theme: SearchBarNodeTheme, presentationTheme: PresentationTheme, strings: PresentationStrings, fieldStyle: SearchBarStyle = .legacy, icon: Icon = .loupe, forceSeparator: Bool = false, displayBackground: Bool = true, cancelText: String? = nil) { + self.presentationTheme = presentationTheme + self.fieldStyle = fieldStyle self.forceSeparator = forceSeparator self.cancelText = cancelText self.icon = icon + + self.inlineSearchPlaceholder = SearchBarPlaceholderNode(fieldStyle: .glass) self.backgroundNode = NavigationBackgroundNode(color: theme.background) self.backgroundNode.isUserInteractionEnabled = false @@ -1043,7 +1056,9 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { super.init() switch self.fieldStyle { - case .glass, .inlineNavigation: + case .glass: + break + case .inlineNavigation: break case .legacy, .modern: self.addSubnode(self.backgroundNode) @@ -1085,11 +1100,11 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { self.cancelButton.addTarget(self, action: #selector(self.cancelPressed), forControlEvents: .touchUpInside) self.clearButton.addTarget(self, action: #selector(self.clearPressed), forControlEvents: .touchUpInside) - self.updateThemeAndStrings(theme: theme, strings: strings) + self.updateThemeAndStrings(theme: theme, presentationTheme: presentationTheme, strings: strings) self.updateIsEmpty(animated: false) } - public func updateThemeAndStrings(theme: SearchBarNodeTheme, strings: PresentationStrings) { + public func updateThemeAndStrings(theme: SearchBarNodeTheme, presentationTheme: PresentationTheme, strings: PresentationStrings) { if self.theme != theme || self.strings !== strings { self.clearButton.accessibilityLabel = strings.WebSearch_RecentSectionClear self.cancelButton.accessibilityLabel = self.cancelText ?? strings.Common_Cancel @@ -1122,6 +1137,7 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { } self.theme = theme + self.presentationTheme = presentationTheme self.strings = strings if let (boundingSize, leftInset, rightInset) = self.validLayout { self.updateLayout(boundingSize: boundingSize, leftInset: leftInset, rightInset: rightInset, transition: .immediate) @@ -1184,6 +1200,45 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { transition.updateFrame(node: self.clearButton, frame: CGRect(origin: CGPoint(x: textBackgroundFrame.maxX - 6.0 - clearSize.width, y: textBackgroundFrame.minY + floor((textBackgroundFrame.size.height - clearSize.height) / 2.0)), size: clearSize)) self.textField.frame = textFrame + + let searchPlaceholderFrame = CGRect(origin: CGPoint(x: 16.0, y: 0.0), size: CGSize(width: max(0.0, boundingSize.width - 16.0 * 2.0), height: 44.0)) + + if case .glass = self.fieldStyle, self.takenSearchPlaceholderContentView == nil { + transition.updateFrame(node: self.inlineSearchPlaceholder, frame: searchPlaceholderFrame) + if let theme = self.theme { + let _ = self.inlineSearchPlaceholder.updateLayout( + placeholderString: self.placeholderString, + compactPlaceholderString: self.placeholderString, + constrainedSize: searchPlaceholderFrame.size, + expansionProgress: 1.0, + iconColor: theme.inputIcon, + foregroundColor: self.presentationTheme.chat.inputPanel.panelControlColor, + backgroundColor: self.presentationTheme.rootController.navigationBar.opaqueBackgroundColor, + controlColor: self.presentationTheme.chat.inputPanel.panelControlColor, + transition: transition + ) + if self.inlineSearchPlaceholderContentsView == nil { + let inlineSearchPlaceholderContentsView = self.inlineSearchPlaceholder.takeContents() + inlineSearchPlaceholderContentsView.onCancel = { [weak self] in + guard let self else { + return + } + self.cancel?() + } + self.inlineSearchPlaceholderContentsView = inlineSearchPlaceholderContentsView + self.view.insertSubview(inlineSearchPlaceholderContentsView, at: 0) + } + } + if let inlineSearchPlaceholderContentsView = self.inlineSearchPlaceholderContentsView { + inlineSearchPlaceholderContentsView.update(size: searchPlaceholderFrame.size, isActive: true, transition: transition) + transition.updateFrame(view: inlineSearchPlaceholderContentsView, frame: searchPlaceholderFrame) + } + } + + if !self.isAnimatingOut, let takenSearchPlaceholderContentView = self.takenSearchPlaceholderContentView { + transition.updateFrame(view: takenSearchPlaceholderContentView, frame: searchPlaceholderFrame) + takenSearchPlaceholderContentView.update(size: searchPlaceholderFrame.size, isActive: true, transition: transition) + } } @objc private func tapGesture(_ recognizer: UITapGestureRecognizer) { @@ -1201,6 +1256,8 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { } public func animateIn(from node: SearchBarPlaceholderNode, duration: Double, timingFunction: String) { + self.inlineSearchPlaceholder.isHidden = true + let takenSearchPlaceholderContentView = node.takeContents() takenSearchPlaceholderContentView.onCancel = { [weak self] in guard let self else { @@ -1210,6 +1267,9 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { } self.takenSearchPlaceholderContentView = takenSearchPlaceholderContentView self.view.insertSubview(takenSearchPlaceholderContentView, at: 0) + if let inlineSearchPlaceholderContentsView = self.inlineSearchPlaceholderContentsView { + inlineSearchPlaceholderContentsView.removeFromSuperview() + } let sourceFrame = node.view.convert(node.bounds, to: self.view) let targetFrame = CGRect(origin: CGPoint(x: 16.0, y: 0.0), size: CGSize(width: max(0.0, self.bounds.width - 16.0 * 2.0), height: 44.0)) @@ -1271,6 +1331,8 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { } public func transitionOut(to node: SearchBarPlaceholderNode, transition: ContainedViewLayoutTransition, completion: @escaping () -> Void) { + self.isAnimatingOut = true + /*let targetTextBackgroundFrame = node.view.convert(node.backgroundView.frame, to: self.view) let duration: Double = transition.isAnimated ? 0.5 : 0.0 @@ -1531,6 +1593,7 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { if let takenSearchPlaceholderContentView = self.takenSearchPlaceholderContentView { takenSearchPlaceholderContentView.updatePlaceholderVisibility(isVisible: isEmpty) } + self.inlineSearchPlaceholderContentsView?.updatePlaceholderVisibility(isVisible: isEmpty) let clearIsHidden = (textIsEmpty && tokensEmpty) && self.prefixString == nil transition.updateAlpha(node: self.clearButton.imageNode, alpha: clearIsHidden ? 0.0 : 1.0) diff --git a/submodules/SearchBarNode/Sources/SearchBarPlaceholderNode.swift b/submodules/SearchBarNode/Sources/SearchBarPlaceholderNode.swift index f991663d6d..fdf652338b 100644 --- a/submodules/SearchBarNode/Sources/SearchBarPlaceholderNode.swift +++ b/submodules/SearchBarNode/Sources/SearchBarPlaceholderNode.swift @@ -49,13 +49,15 @@ public final class SearchBarPlaceholderContentView: UIView { } let fieldStyle: SearchBarStyle - let backgroundNode: ASDisplayNode? + let plainBackgroundView: UIImageView let glassBackgroundView: GlassBackgroundView? private var fillBackgroundColor: UIColor private var foregroundColor: UIColor private var iconColor: UIColor let iconNode: ASImageNode let labelNode: TextNode + let plainIconNode: ASImageNode + let plainLabelNode: TextNode private var close: (background: GlassBackgroundView, icon: UIImageView)? @@ -72,20 +74,13 @@ public final class SearchBarPlaceholderContentView: UIView { self.foregroundColor = UIColor(rgb: 0xededed) self.iconColor = UIColor(rgb: 0x000000, alpha: 0.0) + self.plainBackgroundView = UIImageView() + switch fieldStyle { case .legacy, .modern: - let backgroundNode = ASDisplayNode() - backgroundNode.isLayerBacked = false - backgroundNode.displaysAsynchronously = false - backgroundNode.backgroundColor = self.foregroundColor - backgroundNode.cornerRadius = self.fieldStyle.cornerDiameter / 2.0 - self.backgroundNode = backgroundNode - self.glassBackgroundView = nil case .inlineNavigation, .glass: self.glassBackgroundView = GlassBackgroundView() - - self.backgroundNode = nil } self.iconNode = ASImageNode() @@ -96,20 +91,27 @@ public final class SearchBarPlaceholderContentView: UIView { self.labelNode.isOpaque = false self.labelNode.isUserInteractionEnabled = false + self.plainIconNode = ASImageNode() + self.plainIconNode.displaysAsynchronously = false + self.plainIconNode.displayWithoutProcessing = true + + self.plainLabelNode = TextNode() + self.plainLabelNode.isOpaque = false + self.plainLabelNode.isUserInteractionEnabled = false + super.init(frame: CGRect()) - if let backgroundNode = self.backgroundNode { - backgroundNode.isUserInteractionEnabled = true - self.addSubview(backgroundNode.view) - } + self.plainBackgroundView.isUserInteractionEnabled = true + self.addSubview(self.plainBackgroundView) + + self.plainBackgroundView.addSubview(self.plainIconNode.view) + self.plainBackgroundView.addSubview(self.plainLabelNode.view) + if let glassBackgroundView = self.glassBackgroundView { self.addSubview(glassBackgroundView) glassBackgroundView.contentView.addSubview(self.iconNode.view) glassBackgroundView.contentView.addSubview(self.labelNode.view) - } else { - self.addSubview(self.iconNode.view) - self.addSubview(self.labelNode.view) } } @@ -161,6 +163,7 @@ public final class SearchBarPlaceholderContentView: UIView { private func updateLayout(params: Params, transition: ContainedViewLayoutTransition) -> CGFloat { let labelLayout = TextNode.asyncLayout(self.labelNode) + let plainLabelLayout = TextNode.asyncLayout(self.plainLabelNode) let currentForegroundColor = self.foregroundColor let currentIconColor = self.iconColor @@ -172,6 +175,7 @@ public final class SearchBarPlaceholderContentView: UIView { } let (labelLayoutResult, labelApply) = labelLayout(TextNodeLayoutArguments(attributedString: placeholderString, backgroundColor: .clear, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: params.constrainedSize, alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (_, plainLabelApply) = plainLabelLayout(TextNodeLayoutArguments(attributedString: placeholderString, backgroundColor: .clear, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: params.constrainedSize, alignment: .natural, cutout: nil, insets: UIEdgeInsets())) var updatedColor: UIColor? var updatedIconImage: UIImage? @@ -185,19 +189,19 @@ public final class SearchBarPlaceholderContentView: UIView { let height = params.constrainedSize.height * params.expansionProgress let _ = labelApply() + let _ = plainLabelApply() self.fillBackgroundColor = params.backgroundColor self.foregroundColor = params.foregroundColor self.iconColor = params.iconColor - if let backgroundNode = self.backgroundNode { - backgroundNode.isUserInteractionEnabled = params.expansionProgress > 0.9999 - } + self.plainBackgroundView.isUserInteractionEnabled = params.expansionProgress > 0.9999 - if let updatedColor, let backgroundNode = self.backgroundNode { - backgroundNode.backgroundColor = updatedColor + if let updatedColor { + self.plainBackgroundView.backgroundColor = updatedColor } if let updatedIconImage { self.iconNode.image = updatedIconImage + self.plainIconNode.image = updatedIconImage } self.placeholderString = placeholderString @@ -220,6 +224,7 @@ public final class SearchBarPlaceholderContentView: UIView { iconX = floor((params.constrainedSize.width - totalWidth) / 2.0) } transition.updateFrame(node: self.iconNode, frame: CGRect(origin: CGPoint(x: iconX, y: floorToScreenPixels((height - iconSize.height) / 2.0)), size: iconSize)) + transition.updateFrame(node: self.plainIconNode, frame: CGRect(origin: CGPoint(x: iconX, y: floorToScreenPixels((height - iconSize.height) / 2.0)), size: iconSize)) } else { iconX = 12.0 } @@ -230,6 +235,7 @@ public final class SearchBarPlaceholderContentView: UIView { let labelX: CGFloat = iconX + iconSize.width + spacing let labelFrame = CGRect(origin: CGPoint(x: labelX, y: floorToScreenPixels((height - labelLayoutResult.size.height) / 2.0) + textOffset), size: labelLayoutResult.size) transition.updateFrame(node: self.labelNode, frame: labelFrame) + transition.updateFrame(node: self.plainLabelNode, frame: labelFrame) var innerAlpha = max(0.0, params.expansionProgress - 0.77) / 0.23 if innerAlpha > 0.9999 { @@ -241,27 +247,36 @@ public final class SearchBarPlaceholderContentView: UIView { if !transition.isAnimated { self.labelNode.layer.removeAnimation(forKey: "opacity") self.iconNode.layer.removeAnimation(forKey: "opacity") + self.plainLabelNode.layer.removeAnimation(forKey: "opacity") + self.plainIconNode.layer.removeAnimation(forKey: "opacity") } transition.updateAlpha(node: self.labelNode, alpha: innerAlpha) transition.updateAlpha(node: self.iconNode, alpha: innerAlpha) + + transition.updateAlpha(node: self.plainLabelNode, alpha: innerAlpha) + transition.updateAlpha(node: self.plainIconNode, alpha: innerAlpha) } let outerAlpha = min(0.3, params.expansionProgress) / 0.3 - let cornerRadius = min(self.fieldStyle.cornerDiameter / 2.0, height / 2.0) + let cornerRadius = height * 0.5 - if let backgroundNode = self.backgroundNode, backgroundNode.cornerRadius != cornerRadius { + if self.plainBackgroundView.layer.cornerRadius != cornerRadius { if !transition.isAnimated { - backgroundNode.layer.removeAnimation(forKey: "cornerRadius") + self.plainBackgroundView.layer.removeAnimation(forKey: "cornerRadius") } - transition.updateCornerRadius(node: backgroundNode, cornerRadius: cornerRadius) + transition.updateCornerRadius(layer: self.plainBackgroundView.layer, cornerRadius: cornerRadius) } - if let backgroundNode = self.backgroundNode, backgroundNode.alpha != outerAlpha { + var plainBackgroundAlpha = outerAlpha + if params.isActive { + plainBackgroundAlpha = 0.0 + } + if self.plainBackgroundView.alpha != plainBackgroundAlpha { if !transition.isAnimated { - backgroundNode.layer.removeAnimation(forKey: "opacity") + self.plainBackgroundView.layer.removeAnimation(forKey: "opacity") } - transition.updateAlpha(node: backgroundNode, alpha: outerAlpha) + transition.updateAlpha(layer: self.plainBackgroundView.layer, alpha: plainBackgroundAlpha) } var backgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: params.constrainedSize.width, height: height)) @@ -269,12 +284,12 @@ public final class SearchBarPlaceholderContentView: UIView { backgroundFrame.size.width -= 44.0 + 8.0 } - if let backgroundNode = self.backgroundNode, backgroundNode.frame != backgroundFrame { + if self.plainBackgroundView.frame != backgroundFrame { if !transition.isAnimated { - backgroundNode.layer.removeAnimation(forKey: "position") - backgroundNode.layer.removeAnimation(forKey: "bounds") + self.plainBackgroundView.layer.removeAnimation(forKey: "position") + self.plainBackgroundView.layer.removeAnimation(forKey: "bounds") } - transition.updateFrame(node: backgroundNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: params.constrainedSize.width, height: height))) + transition.updateFrame(view: self.plainBackgroundView, frame: CGRect(origin: CGPoint(), size: CGSize(width: params.constrainedSize.width, height: height))) } if let glassBackgroundView = self.glassBackgroundView { @@ -284,6 +299,9 @@ public final class SearchBarPlaceholderContentView: UIView { if backgroundFrame.height < 16.0 { backgroundAlpha = max(0.0, min(1.0, backgroundFrame.height / 16.0)) } + if !params.isActive { + backgroundAlpha = 0.0 + } ComponentTransition(transition).setAlpha(view: glassBackgroundView, alpha: backgroundAlpha) let isDark = params.backgroundColor.hsb.b < 0.5 glassBackgroundView.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.height * 0.5, isDark: isDark, tintColor: .init(kind: .panel, color: UIColor(white: isDark ? 0.0 : 1.0, alpha: 0.6)), isInteractive: true, transition: ComponentTransition(transition)) @@ -372,10 +390,12 @@ public final class SearchBarPlaceholderContentView: UIView { public func updatePlaceholderVisibility(isVisible: Bool) { self.labelNode.isHidden = !isVisible + self.plainLabelNode.isHidden = !isVisible } public func updateSearchIconVisibility(isVisible: Bool) { self.iconNode.isHidden = !isVisible + self.plainIconNode.isHidden = !isVisible } } @@ -408,12 +428,10 @@ public class SearchBarPlaceholderNode: ASDisplayNode { private let contentView: SearchBarPlaceholderContentView public var backgroundView: UIView { - if let backgroundNode = self.contentView.backgroundNode { - return backgroundNode.view - } else if let glassBackgroundView = self.contentView.glassBackgroundView { + if let glassBackgroundView = self.contentView.glassBackgroundView { return glassBackgroundView } else { - preconditionFailure() + return self.contentView.plainBackgroundView } } diff --git a/submodules/SearchUI/Sources/SearchDisplayController.swift b/submodules/SearchUI/Sources/SearchDisplayController.swift index 7754741bbb..53cdd002ce 100644 --- a/submodules/SearchUI/Sources/SearchDisplayController.swift +++ b/submodules/SearchUI/Sources/SearchDisplayController.swift @@ -57,7 +57,7 @@ public final class SearchDisplayController { self.searchBarIsExternal = searchBarIsExternal if !searchBarIsExternal { - self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: presentationData.theme, hasBackground: hasBackground, hasSeparator: hasSeparator, inline: inline), strings: presentationData.strings, fieldStyle: fieldStyle, forceSeparator: hasSeparator, displayBackground: hasBackground) + self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: presentationData.theme, hasBackground: hasBackground, hasSeparator: hasSeparator, inline: inline), presentationTheme: presentationData.theme, strings: presentationData.strings, fieldStyle: fieldStyle, forceSeparator: hasSeparator, displayBackground: hasBackground) } self.backgroundNode = BackgroundNode() self.backgroundNode.allowsGroupOpacity = true @@ -143,7 +143,7 @@ public final class SearchDisplayController { public func updatePresentationData(_ presentationData: PresentationData) { if !self.searchBarIsExternal { - self.searchBar?.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: presentationData.theme, hasSeparator: self.hasSeparator, inline: self.inline), strings: presentationData.strings) + self.searchBar?.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: presentationData.theme, hasSeparator: self.hasSeparator, inline: self.inline), presentationTheme: presentationData.theme, strings: presentationData.strings) } self.contentNode.updatePresentationData(presentationData) diff --git a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift index f32fbbe7b9..0602a0fc39 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift @@ -988,7 +988,7 @@ extension StoreMessage { } } - if (flags & (1 << 17)) != 0 { + if (flags & (1 << 19)) != 0 { attributes.append(ContentRequiresValidationMessageAttribute()) } @@ -1174,7 +1174,7 @@ extension StoreMessage { threadId = 1 } - if (flags & (1 << 17)) != 0 { + if (flags & (1 << 19)) != 0 { attributes.append(ContentRequiresValidationMessageAttribute()) } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChatAdminRights.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChatAdminRights.swift index 733b5f926d..5d270bf553 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChatAdminRights.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChatAdminRights.swift @@ -62,7 +62,8 @@ public struct TelegramChatAdminRightsFlags: OptionSet, Hashable { .canPostStories, .canEditStories, .canDeleteStories, - .canManageDirect + .canManageDirect, + .canBanUsers ] public static func peerSpecific(peer: EnginePeer) -> TelegramChatAdminRightsFlags { diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift index 82018273d0..fe645502e6 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift @@ -504,7 +504,7 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati pinnedBadgeColor: UIColor(rgb: 0x767677), pinnedSearchBarColor: UIColor(rgb: 0x272728), regularSearchBarColor: UIColor(rgb: 0x272728), - sectionHeaderFillColor: UIColor(rgb: 0x1c1c1d), + sectionHeaderFillColor: .black, sectionHeaderTextColor: UIColor(rgb: 0xffffff), verifiedIconFillColor: UIColor(rgb: 0xffffff), verifiedIconForegroundColor: UIColor(rgb: 0x000000), diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift index 86c3dad638..f3c3552455 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift @@ -714,7 +714,7 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres pinnedBadgeColor: mainSecondaryTextColor.withAlphaComponent(0.5), pinnedSearchBarColor: accentColor.withMultiplied(hue: 1.029, saturation: 0.609, brightness: 0.12), regularSearchBarColor: accentColor.withMultiplied(hue: 1.029, saturation: 0.609, brightness: 0.12), - sectionHeaderFillColor: mainBackgroundColor, + sectionHeaderFillColor: .black, sectionHeaderTextColor: mainSecondaryTextColor.withAlphaComponent(0.5), verifiedIconFillColor: accentColor, verifiedIconForegroundColor: .white, diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift index aacb1f0111..6d6fb1a7cb 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift @@ -565,8 +565,8 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio pinnedBadgeColor: UIColor(rgb: 0xb6b6bb), pinnedSearchBarColor: UIColor(rgb: 0xe5e5e5), regularSearchBarColor: UIColor(rgb: 0xe9e9e9), - sectionHeaderFillColor: UIColor(rgb: 0xf7f7f7), - sectionHeaderTextColor: UIColor(rgb: 0x8e8e93), + sectionHeaderFillColor: .white, + sectionHeaderTextColor: .black, verifiedIconFillColor: defaultDayAccentColor, verifiedIconForegroundColor: UIColor(rgb: 0xffffff), secretIconColor: UIColor(rgb: 0x00b12c), diff --git a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsSearchNavigationContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsSearchNavigationContentNode.swift index 5c524bf3f9..63eb156744 100644 --- a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsSearchNavigationContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsSearchNavigationContentNode.swift @@ -25,7 +25,7 @@ final class ChatRecentActionsSearchNavigationContentNode: NavigationBarContentNo self.cancel = cancel - self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme, hasSeparator: false), strings: strings, fieldStyle: .modern, displayBackground: false) + self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme, hasSeparator: false), presentationTheme: theme, strings: strings, fieldStyle: .modern, displayBackground: false) let placeholderText = strings.Common_Search self.searchBar.placeholderString = NSAttributedString(string: placeholderText, font: searchBarFont, textColor: theme.rootController.navigationSearchBar.inputPlaceholderTextColor) diff --git a/submodules/TelegramUI/Components/Chat/ChatSearchNavigationContentNode/Sources/ChatSearchNavigationContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatSearchNavigationContentNode/Sources/ChatSearchNavigationContentNode.swift index 0571903449..b50857c895 100644 --- a/submodules/TelegramUI/Components/Chat/ChatSearchNavigationContentNode/Sources/ChatSearchNavigationContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatSearchNavigationContentNode/Sources/ChatSearchNavigationContentNode.swift @@ -64,6 +64,7 @@ public final class ChatSearchNavigationContentNode: NavigationBarContentNode { accent: theme.chat.inputPanel.panelControlAccentColor, keyboard: theme.rootController.keyboardColor ), + presentationTheme: theme, strings: strings, fieldStyle: .inlineNavigation, forceSeparator: false, @@ -246,6 +247,7 @@ public final class ChatSearchNavigationContentNode: NavigationBarContentNode { accent: presentationInterfaceState.theme.chat.inputPanel.panelControlAccentColor, keyboard: presentationInterfaceState.theme.rootController.keyboardColor ), + presentationTheme: presentationInterfaceState.theme, strings: presentationInterfaceState.strings ) diff --git a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift index d2255c3b1a..b13ccb5930 100644 --- a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift +++ b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift @@ -359,6 +359,9 @@ public final class ChatListNavigationBar: Component { let searchOffsetFraction = clippedSearchOffset / searchOffsetDistance searchContentNode.expansionProgress = 1.0 - searchOffsetFraction embeddedSearchBarExpansionHeight = 60.0 - floorToScreenPixels((1.0 - searchOffsetFraction) * searchSize.height) + if searchOffsetFraction > 0.0 { + searchFrame.origin.y -= (60.0 - 44.0) * 0.5 * searchOffsetFraction + } searchFrameValue = searchFrame transition.setFrameWithAdditivePosition(view: searchContentNode.view, frame: searchFrame) @@ -479,7 +482,7 @@ public final class ChatListNavigationBar: Component { if component.statusBarHeight < 1.0 { headerContentY = 0.0 } else { - headerContentY = component.statusBarHeight + 5.0 + headerContentY = component.statusBarHeight + 10.0 } } let headerContentFrame = CGRect(origin: CGPoint(x: 0.0, y: headerContentY), size: headerContentSize) @@ -683,7 +686,7 @@ public final class ChatListNavigationBar: Component { } } else { contentHeight += 44.0 - contentHeight += 8.0 + contentHeight += 7.0 if component.search != nil { contentHeight += navigationBarSearchContentHeight @@ -696,8 +699,6 @@ public final class ChatListNavigationBar: Component { transition.setFrame(view: disappearingHeaderPanelsView, frame: headerPanelsFrame) } if let headerPanels = component.headerPanels { - headersContentHeight += 4.0 - let headerPanelsView: ComponentView var headerPanelsTransition = transition if let current = self.headerPanelsView { diff --git a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/NavigationButtonComponent.swift b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/NavigationButtonComponent.swift index 8a99c1ac6d..5ebc820020 100644 --- a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/NavigationButtonComponent.swift +++ b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/NavigationButtonComponent.swift @@ -116,7 +116,7 @@ public final class NavigationButtonComponent: Component { switch component.content { case let .text(title, isBold): - textString = NSAttributedString(string: title, font: isBold ? Font.bold(17.0) : Font.regular(17.0), textColor: theme.chat.inputPanel.panelControlColor) + textString = NSAttributedString(string: title, font: isBold ? Font.bold(17.0) : Font.medium(17.0), textColor: theme.chat.inputPanel.panelControlColor) case .more: isMore = true case let .icon(imageNameValue): @@ -140,7 +140,7 @@ public final class NavigationButtonComponent: Component { textView.attributedText = textString let textSize = textView.updateLayout(availableSize) - let textInset: CGFloat = 10.0 + let textInset: CGFloat = 12.0 size.width = max(44.0, textSize.width + textInset * 2.0) textView.frame = CGRect(origin: CGPoint(x: floor((size.width - textSize.width) / 2.0), y: floor((availableSize.height - textSize.height) / 2.0)), size: textSize) diff --git a/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleComponent.swift b/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleComponent.swift index b17a89d9db..eda0606f24 100644 --- a/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleComponent.swift +++ b/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleComponent.swift @@ -1010,13 +1010,7 @@ public final class ChatTitleComponent: Component { let containerSize = CGSize(width: contentSize.width + containerSideInset * 2.0, height: 44.0) let containerFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - containerSize.width) * 0.5), y: floorToScreenPixels((availableSize.height - containerSize.height) * 0.5)), size: containerSize) - var titleFrame = CGRect(origin: CGPoint(x: floor((containerFrame.width - titleSize.width) * 0.5), y: floor((containerFrame.height - contentSize.height) * 0.5)), size: titleSize) - if titleFrame.origin.x + titleFrame.width + titleRightIconsWidth > containerFrame.width - containerSideInset { - titleFrame.origin.x = containerFrame.width - containerSideInset - titleFrame.width - titleRightIconsWidth - } - if titleFrame.origin.x - titleLeftIconsWidth < containerSideInset { - titleFrame.origin.x = containerSideInset + titleLeftIconsWidth - } + let titleFrame = CGRect(origin: CGPoint(x: titleLeftIconsWidth + floor((containerFrame.width - titleSize.width - titleLeftIconsWidth - titleRightIconsWidth) * 0.5), y: floor((containerFrame.height - contentSize.height) * 0.5)), size: titleSize) if let titleView = self.title.view { if titleView.superview == nil { titleView.isUserInteractionEnabled = false @@ -1130,6 +1124,8 @@ public final class ChatTitleComponent: Component { if let backgroundView = self.backgroundView { self.backgroundView = nil backgroundView.removeFromSuperview() + } + if self.contentContainer.superview !== self { self.addSubview(self.contentContainer) } transition.setFrame(view: self.contentContainer, frame: containerFrame) diff --git a/submodules/TelegramUI/Components/EdgeEffect/Sources/EdgeEffect.swift b/submodules/TelegramUI/Components/EdgeEffect/Sources/EdgeEffect.swift index 9a59cd4a10..0eaabdcaf7 100644 --- a/submodules/TelegramUI/Components/EdgeEffect/Sources/EdgeEffect.swift +++ b/submodules/TelegramUI/Components/EdgeEffect/Sources/EdgeEffect.swift @@ -77,33 +77,33 @@ public class EdgeEffectView: UIView { } if blur { - let gradientMaskLayer = SimpleGradientLayer() - let baseGradientAlpha: CGFloat = 1.0 - let numSteps = 8 - let firstStep = 1 - let firstLocation = 0.8 - gradientMaskLayer.colors = (0 ..< numSteps).map { i in - if i < firstStep { - return UIColor(white: 1.0, alpha: 1.0).cgColor - } else { - let step: CGFloat = CGFloat(i - firstStep) / CGFloat(numSteps - firstStep - 1) - let value: CGFloat = 1.0 - bezierPoint(0.42, 0.0, 0.58, 1.0, step) - return UIColor(white: 1.0, alpha: baseGradientAlpha * value).cgColor - } - } - gradientMaskLayer.locations = (0 ..< numSteps).map { i -> NSNumber in - if i < firstStep { - return 0.0 as NSNumber - } else { - let step: CGFloat = CGFloat(i - firstStep) / CGFloat(numSteps - firstStep - 1) - return (firstLocation + (1.0 - firstLocation) * step) as NSNumber - } - } - let blurView: VariableBlurView if let current = self.blurView { blurView = current } else { + let gradientMaskLayer = SimpleGradientLayer() + let baseGradientAlpha: CGFloat = 1.0 + let numSteps = 8 + let firstStep = 1 + let firstLocation = 0.8 + gradientMaskLayer.colors = (0 ..< numSteps).map { i in + if i < firstStep { + return UIColor(white: 1.0, alpha: 1.0).cgColor + } else { + let step: CGFloat = CGFloat(i - firstStep) / CGFloat(numSteps - firstStep - 1) + let value: CGFloat = 1.0 - bezierPoint(0.42, 0.0, 0.58, 1.0, step) + return UIColor(white: 1.0, alpha: baseGradientAlpha * value).cgColor + } + } + gradientMaskLayer.locations = (0 ..< numSteps).map { i -> NSNumber in + if i < firstStep { + return 0.0 as NSNumber + } else { + let step: CGFloat = CGFloat(i - firstStep) / CGFloat(numSteps - firstStep - 1) + return (firstLocation + (1.0 - firstLocation) * step) as NSNumber + } + } + blurView = VariableBlurView(gradientMask: self.contentMaskView.image ?? UIImage(), maxBlurRadius: 8.0) blurView.layer.mask = gradientMaskLayer self.insertSubview(blurView, at: 0) diff --git a/submodules/TelegramUI/Components/GlassBackgroundComponent/Sources/GlassBackgroundComponent.swift b/submodules/TelegramUI/Components/GlassBackgroundComponent/Sources/GlassBackgroundComponent.swift index c7a4f6efe7..45e7fa33e5 100644 --- a/submodules/TelegramUI/Components/GlassBackgroundComponent/Sources/GlassBackgroundComponent.swift +++ b/submodules/TelegramUI/Components/GlassBackgroundComponent/Sources/GlassBackgroundComponent.swift @@ -535,9 +535,12 @@ public class GlassBackgroundView: UIView { if transition.animation.isImmediate { nativeView.effect = glassEffect } else { - UIView.animate(withDuration: 0.2, animations: { - nativeView.effect = glassEffect - }) + if let glassEffect, let currentEffect = nativeView.effect as? UIGlassEffect, currentEffect.tintColor == glassEffect.tintColor, currentEffect.isInteractive == glassEffect.isInteractive { + } else { + UIView.animate(withDuration: 0.15, animations: { + nativeView.effect = glassEffect + }) + } } } diff --git a/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerSearchNavigationContentNode.swift b/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerSearchNavigationContentNode.swift index c8b4841084..d02a4154cf 100644 --- a/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerSearchNavigationContentNode.swift +++ b/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerSearchNavigationContentNode.swift @@ -81,6 +81,7 @@ final class GroupStickerSearchNavigationContentNode: NavigationBarContentNode, I accent: theme.chat.inputPanel.panelControlAccentColor, keyboard: theme.rootController.keyboardColor ), + presentationTheme: theme, strings: strings, fieldStyle: .inlineNavigation, forceSeparator: false, @@ -127,7 +128,7 @@ final class GroupStickerSearchNavigationContentNode: NavigationBarContentNode, I func updateTheme(_ theme: PresentationTheme) { self.theme = theme - self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: self.theme), strings: self.strings) + self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: self.theme), presentationTheme: self.theme, strings: self.strings) self.updatePlaceholder() } diff --git a/submodules/TelegramUI/Components/MiniAppListScreen/Sources/MiniAppListScreen.swift b/submodules/TelegramUI/Components/MiniAppListScreen/Sources/MiniAppListScreen.swift index ec57373b25..811661b633 100644 --- a/submodules/TelegramUI/Components/MiniAppListScreen/Sources/MiniAppListScreen.swift +++ b/submodules/TelegramUI/Components/MiniAppListScreen/Sources/MiniAppListScreen.swift @@ -460,6 +460,7 @@ final class MiniAppListScreenComponent: Component { let searchBarTheme = SearchBarNodeTheme(theme: environment.theme, hasSeparator: false) searchBarNode = SearchBarNode( theme: searchBarTheme, + presentationTheme: environment.theme, strings: environment.strings, fieldStyle: .modern, displayBackground: false diff --git a/submodules/TelegramUI/Components/NavigationBarImpl/Sources/NavigationButtonNode.swift b/submodules/TelegramUI/Components/NavigationBarImpl/Sources/NavigationButtonNode.swift index 2e46351ae0..0d4f353514 100644 --- a/submodules/TelegramUI/Components/NavigationBarImpl/Sources/NavigationButtonNode.swift +++ b/submodules/TelegramUI/Components/NavigationBarImpl/Sources/NavigationButtonNode.swift @@ -151,7 +151,7 @@ private final class ItemComponent: Component { if case let .item(item) = component.content, case .done = item.style { titleFont = Font.bold(17.0) } else { - titleFont = Font.regular(17.0) + titleFont = Font.medium(17.0) } let title: ComponentView @@ -204,7 +204,7 @@ private final class NavigationButtonItemNode: ImmediateTextNode { private let isGlass: Bool private func fontForCurrentState() -> UIFont { - return self.bold ? UIFont.boldSystemFont(ofSize: 17.0) : UIFont.systemFont(ofSize: 17.0) + return self.bold ? Font.semibold(17.0) : Font.medium(17.0) } private func attributesForCurrentState() -> [NSAttributedString.Key: AnyObject] { @@ -711,7 +711,7 @@ public final class NavigationButtonNodeImpl: ContextControllerSourceNode, Naviga var nodeInset: CGFloat = 0.0 if self.isGlass { if node.image == nil && node.node == nil { - nodeInset += 10.0 + nodeInset += 12.0 } if nodeSize.width + nodeInset * 2.0 < 44.0 { nodeInset = floorToScreenPixels((44.0 - nodeSize.width) * 0.5) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/BUILD b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/BUILD index a7d4c39c76..71742d960b 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/BUILD +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/BUILD @@ -168,6 +168,7 @@ swift_library( "//submodules/TelegramUI/Components/MediaManager/PeerMessagesMediaPlaylist", "//submodules/TelegramUI/Components/TextFieldComponent", "//submodules/TelegramUI/Components/EdgeEffect", + "//submodules/TelegramUI/Components/GlassBackgroundComponent", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNavigationButton.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNavigationButton.swift index f625dec007..f42fd8cfd0 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNavigationButton.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNavigationButton.swift @@ -13,6 +13,23 @@ private enum MoreIconNodeState: Equatable { case moreToSearch(Float) } +private let glassBackArrowImage: UIImage? = { + let imageSize = CGSize(width: 44.0, height: 44.0) + let topRightPoint = CGPoint(x: 24.6, y: 14.0) + let centerPoint = CGPoint(x: 17.0, y: imageSize.height * 0.5) + return generateImage(imageSize, rotatedContext: { size, context in + context.clear(CGRect(origin: CGPoint(), size: size)) + context.setStrokeColor(UIColor.white.cgColor) + context.setLineWidth(2.0) + context.setLineCap(.round) + context.setLineJoin(.round) + context.move(to: topRightPoint) + context.addLine(to: centerPoint) + context.addLine(to: CGPoint(x: topRightPoint.x, y: size.height - topRightPoint.y)) + context.strokePath() + })?.withRenderingMode(.alwaysTemplate) +}() + private final class MoreIconNode: ManagedAnimationNode { private let duration: Double = 0.21 private var iconState: MoreIconNodeState = .more @@ -124,14 +141,11 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode { let contextSourceNode: ContextReferenceContentNode private let textNode: ImmediateTextNode private let iconNode: ASImageNode - private let backIconLayer: SimpleShapeLayer private var animationNode: MoreIconNode? - private let backgroundNode: NavigationBackgroundNode private var key: PeerInfoHeaderNavigationButtonKey? private var contentsColor: UIColor = .white - private var canBeExpanded: Bool = false var action: ((ASDisplayNode, ContextGesture?) -> Void)? @@ -146,27 +160,14 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode { self.iconNode.displaysAsynchronously = false self.iconNode.displayWithoutProcessing = true - self.backIconLayer = SimpleShapeLayer() - self.backIconLayer.lineWidth = 3.0 - self.backIconLayer.lineCap = .round - self.backIconLayer.lineJoin = .round - self.backIconLayer.strokeColor = UIColor.white.cgColor - self.backIconLayer.fillColor = nil - self.backIconLayer.isHidden = true - self.backIconLayer.path = try? convertSvgPath("M10.5,2 L1.5,11 L10.5,20 ") - - self.backgroundNode = NavigationBackgroundNode(color: .clear, enableBlur: true) - - super.init(pointerStyle: .insetRectangle(-8.0, 2.0)) + super.init(pointerStyle: .insetRectangle(0.0, 0.0)) self.isAccessibilityElement = true self.accessibilityTraits = .button self.containerNode.addSubnode(self.contextSourceNode) - self.contextSourceNode.addSubnode(self.backgroundNode) self.contextSourceNode.addSubnode(self.textNode) self.contextSourceNode.addSubnode(self.iconNode) - self.contextSourceNode.layer.addSublayer(self.backIconLayer) self.addSubnode(self.containerNode) @@ -178,10 +179,6 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode { } self.addTarget(self, action: #selector(self.pressed), forControlEvents: .touchUpInside) - - if isReduceTransparencyEnabled() { - self.backgroundNode.isHidden = true - } } @objc private func pressed() { @@ -190,11 +187,7 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode { } override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - var boundingRect = self.bounds - if self.textNode.alpha != 0.0 { - boundingRect = boundingRect.union(self.textNode.frame) - } - boundingRect = boundingRect.insetBy(dx: -8.0, dy: -4.0) + let boundingRect = self.bounds if boundingRect.contains(point) { return super.hitTest(self.bounds.center, with: event) } else { @@ -202,31 +195,11 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode { } } - func updateContentsColor(backgroundColor: UIColor, contentsColor: UIColor, canBeExpanded: Bool, transition: ContainedViewLayoutTransition) { + func updateContentsColor(contentsColor: UIColor, transition: ContainedViewLayoutTransition) { self.contentsColor = contentsColor - self.canBeExpanded = canBeExpanded - - self.backgroundNode.updateColor(color: backgroundColor, transition: transition) transition.updateTintColor(layer: self.textNode.layer, color: self.contentsColor) transition.updateTintColor(view: self.iconNode.view, color: self.contentsColor) - transition.updateStrokeColor(layer: self.backIconLayer, strokeColor: self.contentsColor) - - switch self.key { - case .back: - transition.updateAlpha(layer: self.textNode.layer, alpha: canBeExpanded ? 1.0 : 0.0) - transition.updateTransformScale(node: self.textNode, scale: canBeExpanded ? 1.0 : 0.001) - - var iconTransform = CATransform3DIdentity - iconTransform = CATransform3DScale(iconTransform, canBeExpanded ? 1.0 : 0.8, canBeExpanded ? 1.0 : 0.8, 1.0) - iconTransform = CATransform3DTranslate(iconTransform, canBeExpanded ? -7.0 : 0.0, 0.0, 0.0) - transition.updateTransform(node: self.iconNode, transform: CATransform3DGetAffineTransform(iconTransform)) - - transition.updateTransform(layer: self.backIconLayer, transform: CATransform3DGetAffineTransform(iconTransform)) - transition.updateLineWidth(layer: self.backIconLayer, lineWidth: canBeExpanded ? 3.0 : 2.075) - default: - break - } if let animationNode = self.animationNode { transition.updateTintColor(layer: animationNode.imageNode.layer, color: self.contentsColor) @@ -239,7 +212,7 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode { var iconOffset = CGPoint() switch key { case .back: - iconOffset = CGPoint(x: -1.0, y: 0.0) + iconOffset = CGPoint(x: 0.0, y: 0.0) default: break } @@ -258,9 +231,9 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode { var animationState: MoreIconNodeState = .more switch key { case .back: - text = presentationData.strings.Common_Back + text = "" accessibilityText = presentationData.strings.Common_Back - icon = navigationBarBackArrowImage(color: .white) + icon = glassBackArrowImage case .edit: text = presentationData.strings.Common_Edit accessibilityText = text @@ -323,7 +296,7 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode { self.accessibilityLabel = accessibilityText self.containerNode.isGestureEnabled = isGestureEnabled - let font: UIFont = isBold ? Font.semibold(17.0) : Font.regular(17.0) + let font: UIFont = isBold ? Font.semibold(17.0) : Font.medium(17.0) self.textNode.attributedText = NSAttributedString(string: text, font: font, textColor: .white) transition.updateTintColor(layer: self.textNode.layer, color: self.contentsColor) @@ -357,70 +330,39 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode { textSize = self.textNode.bounds.size } - let inset: CGFloat = 0.0 - var textInset: CGFloat = 0.0 - switch key { - case .back: - textInset += 11.0 - default: - break - } + let textInset: CGFloat = 12.0 let resultSize: CGSize - let textFrame = CGRect(origin: CGPoint(x: inset + textInset, y: floor((height - textSize.height) / 2.0)), size: textSize) + let textFrame = CGRect(origin: CGPoint(x: textInset, y: floor((height - textSize.height) / 2.0)), size: textSize) self.textNode.position = textFrame.center self.textNode.bounds = CGRect(origin: CGPoint(), size: textFrame.size) if let animationNode = self.animationNode { let animationSize = CGSize(width: 30.0, height: 30.0) - animationNode.frame = CGRect(origin: CGPoint(x: inset, y: floor((height - animationSize.height) / 2.0)), size: animationSize).offsetBy(dx: iconOffset.x, dy: iconOffset.y) + animationNode.frame = CGRect(origin: CGPoint(x: floor((height - animationSize.width) * 0.5), y: floor((height - animationSize.height) / 2.0)), size: animationSize).offsetBy(dx: iconOffset.x, dy: iconOffset.y) - let size = CGSize(width: animationSize.width + inset * 2.0, height: height) + let size = CGSize(width: height, height: height) self.containerNode.frame = CGRect(origin: CGPoint(), size: size) self.contextSourceNode.frame = CGRect(origin: CGPoint(), size: size) resultSize = size } else if let image = self.iconNode.image { - let iconFrame = CGRect(origin: CGPoint(x: inset, y: floor((height - image.size.height) / 2.0)), size: image.size).offsetBy(dx: iconOffset.x, dy: iconOffset.y) + let iconFrame = CGRect(origin: CGPoint(x: floor((height - image.size.width) * 0.5), y: floor((height - image.size.height) / 2.0)), size: image.size).offsetBy(dx: iconOffset.x, dy: iconOffset.y) self.iconNode.position = iconFrame.center self.iconNode.bounds = CGRect(origin: CGPoint(), size: iconFrame.size) - if case .back = key { - self.backIconLayer.position = iconFrame.center - self.backIconLayer.bounds = CGRect(origin: CGPoint(), size: iconFrame.size) - - self.iconNode.isHidden = true - self.backIconLayer.isHidden = false - } else { - self.iconNode.isHidden = false - self.backIconLayer.isHidden = true - } - - let size = CGSize(width: image.size.width + inset * 2.0, height: height) + let size = CGSize(width: height, height: height) self.containerNode.frame = CGRect(origin: CGPoint(), size: size) self.contextSourceNode.frame = CGRect(origin: CGPoint(), size: size) resultSize = size } else { - let size = CGSize(width: textSize.width + inset * 2.0, height: height) + let size = CGSize(width: textSize.width + textInset * 2.0, height: height) self.containerNode.frame = CGRect(origin: CGPoint(), size: size) self.contextSourceNode.frame = CGRect(origin: CGPoint(), size: size) resultSize = size } - let diameter: CGFloat = 32.0 - let backgroundWidth: CGFloat - if self.iconNode.image != nil || self.animationNode != nil { - backgroundWidth = diameter - } else { - backgroundWidth = max(diameter, resultSize.width + 12.0 * 2.0) - } - let backgroundFrame = CGRect(origin: CGPoint(x: floor((resultSize.width - backgroundWidth) * 0.5), y: floor((resultSize.height - diameter) * 0.5)), size: CGSize(width: backgroundWidth, height: diameter)) - transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame) - self.backgroundNode.update(size: backgroundFrame.size, cornerRadius: diameter * 0.5, transition: transition) - - self.hitTestSlop = UIEdgeInsets(top: -2.0, left: -12.0, bottom: -2.0, right: -12.0) - return resultSize } } diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNavigationButtonContainerNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNavigationButtonContainerNode.swift index a40ab2c8e6..7b16328d7d 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNavigationButtonContainerNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNavigationButtonContainerNode.swift @@ -4,6 +4,9 @@ import AsyncDisplayKit import ContextUI import TelegramPresentationData import Display +import ComponentFlow +import ComponentDisplayAdapters +import GlassBackgroundComponent enum PeerInfoHeaderNavigationButtonKey { case back @@ -24,101 +27,125 @@ enum PeerInfoHeaderNavigationButtonKey { case postStory } -struct PeerInfoHeaderNavigationButtonSpec: Equatable { +struct PeerInfoHeaderNavigationButtonSpec: Hashable { let key: PeerInfoHeaderNavigationButtonKey let isForExpandedView: Bool } final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode { private var presentationData: PresentationData? - private(set) var leftButtonNodes: [PeerInfoHeaderNavigationButtonKey: PeerInfoHeaderNavigationButton] = [:] - private(set) var rightButtonNodes: [PeerInfoHeaderNavigationButtonKey: PeerInfoHeaderNavigationButton] = [:] + + private let backgroundContainer: GlassBackgroundContainerView + private let leftButtonsBackground: GlassBackgroundView + private let rightButtonsBackground: GlassBackgroundView + private let leftButtonsContainer: UIView + private let rightButtonsContainer: UIView + + private(set) var leftButtonNodes: [PeerInfoHeaderNavigationButtonSpec: PeerInfoHeaderNavigationButton] = [:] + private(set) var rightButtonNodes: [PeerInfoHeaderNavigationButtonSpec: PeerInfoHeaderNavigationButton] = [:] private var currentLeftButtons: [PeerInfoHeaderNavigationButtonSpec] = [] private var currentRightButtons: [PeerInfoHeaderNavigationButtonSpec] = [] private var backgroundContentColor: UIColor = .clear + private var isOverColoredContents: Bool = false private var contentsColor: UIColor = .white - private var canBeExpanded: Bool = false var performAction: ((PeerInfoHeaderNavigationButtonKey, ContextReferenceContentNode?, ContextGesture?) -> Void)? - func updateContentsColor(backgroundContentColor: UIColor, contentsColor: UIColor, canBeExpanded: Bool, transition: ContainedViewLayoutTransition) { - self.backgroundContentColor = backgroundContentColor - self.contentsColor = contentsColor - self.canBeExpanded = canBeExpanded + override init() { + self.backgroundContainer = GlassBackgroundContainerView() + self.leftButtonsBackground = GlassBackgroundView() + self.rightButtonsBackground = GlassBackgroundView() - for (_, button) in self.leftButtonNodes { - button.updateContentsColor(backgroundColor: self.backgroundContentColor, contentsColor: self.contentsColor, canBeExpanded: canBeExpanded, transition: transition) - transition.updateSublayerTransformOffset(layer: button.layer, offset: CGPoint(x: canBeExpanded ? -8.0 : 0.0, y: 0.0)) + self.leftButtonsContainer = UIView() + self.leftButtonsContainer.clipsToBounds = true + self.rightButtonsContainer = UIView() + self.rightButtonsContainer.clipsToBounds = true + + super.init() + + self.view.addSubview(self.backgroundContainer) + self.backgroundContainer.contentView.addSubview(self.leftButtonsBackground) + self.backgroundContainer.contentView.addSubview(self.rightButtonsBackground) + + self.leftButtonsBackground.contentView.addSubview(self.leftButtonsContainer) + self.rightButtonsBackground.contentView.addSubview(self.rightButtonsContainer) + } + + func updateContentsColor(backgroundContentColor: UIColor, contentsColor: UIColor, isOverColoredContents: Bool, transition: ContainedViewLayoutTransition) { + self.backgroundContentColor = backgroundContentColor + self.isOverColoredContents = isOverColoredContents + self.contentsColor = contentsColor + + guard let presentationData = self.presentationData else { + return + } + + let normalButtonContentsColor: UIColor = self.isOverColoredContents ? .white : presentationData.theme.chat.inputPanel.panelControlColor + let expandedButtonContentsColor: UIColor = presentationData.theme.chat.inputPanel.panelControlColor + + for (spec, button) in self.leftButtonNodes { + button.updateContentsColor(contentsColor: spec.isForExpandedView ? expandedButtonContentsColor : normalButtonContentsColor, transition: transition) } - var accumulatedRightButtonOffset: CGFloat = canBeExpanded ? 16.0 : 0.0 for spec in self.currentRightButtons.reversed() { - guard let button = self.rightButtonNodes[spec.key] else { + guard let button = self.rightButtonNodes[spec] else { continue } - button.updateContentsColor(backgroundColor: self.backgroundContentColor, contentsColor: self.contentsColor, canBeExpanded: canBeExpanded, transition: transition) - if !spec.isForExpandedView { - transition.updateSublayerTransformOffset(layer: button.layer, offset: CGPoint(x: accumulatedRightButtonOffset, y: 0.0)) - if self.backgroundContentColor.alpha != 0.0 { - accumulatedRightButtonOffset -= 6.0 - } - } - } - for (key, button) in self.rightButtonNodes { - if !self.currentRightButtons.contains(where: { $0.key == key }) { - button.updateContentsColor(backgroundColor: self.backgroundContentColor, contentsColor: self.contentsColor, canBeExpanded: canBeExpanded, transition: transition) - transition.updateSublayerTransformOffset(layer: button.layer, offset: CGPoint(x: 0.0, y: 0.0)) + button.updateContentsColor(contentsColor: spec.isForExpandedView ? expandedButtonContentsColor : normalButtonContentsColor, transition: transition) + } + for (spec, button) in self.rightButtonNodes { + if !self.currentRightButtons.contains(where: { $0 == spec }) { + button.updateContentsColor(contentsColor: spec.isForExpandedView ? expandedButtonContentsColor : normalButtonContentsColor, transition: transition) } } + + self.updateBackgroundColors(transition: ComponentTransition(transition)) } func update(size: CGSize, presentationData: PresentationData, leftButtons: [PeerInfoHeaderNavigationButtonSpec], rightButtons: [PeerInfoHeaderNavigationButtonSpec], expandFraction: CGFloat, shouldAnimateIn: Bool, transition: ContainedViewLayoutTransition) { - let sideInset: CGFloat = 24.0 - let expandedSideInset: CGFloat = 16.0 + transition.updateFrame(view: self.backgroundContainer, frame: CGRect(origin: CGPoint(), size: size)) - let maximumExpandOffset: CGFloat = 14.0 - let expandOffset: CGFloat = -expandFraction * maximumExpandOffset + let buttonHeight: CGFloat = 44.0 + + let sideInset: CGFloat = 16.0 + + var normalLeftButtonsWidth: CGFloat = 0.0 + var expandedLeftButtonsWidth: CGFloat = 0.0 + + let maxBlur: CGFloat = 5.0 + + let normalButtonContentsColor: UIColor = self.isOverColoredContents ? .white : presentationData.theme.chat.inputPanel.panelControlColor + let expandedButtonContentsColor: UIColor = presentationData.theme.chat.inputPanel.panelControlColor if self.currentLeftButtons != leftButtons || presentationData.strings !== self.presentationData?.strings { self.currentLeftButtons = leftButtons - var nextRegularButtonOrigin = sideInset - var nextExpandedButtonOrigin = sideInset for spec in leftButtons.reversed() { let buttonNode: PeerInfoHeaderNavigationButton var wasAdded = false - if let current = self.leftButtonNodes[spec.key] { + if let current = self.leftButtonNodes[spec] { buttonNode = current } else { wasAdded = true buttonNode = PeerInfoHeaderNavigationButton() - self.leftButtonNodes[spec.key] = buttonNode - self.addSubnode(buttonNode) + self.leftButtonNodes[spec] = buttonNode + self.leftButtonsContainer.addSubview(buttonNode.view) buttonNode.action = { [weak self] _, gesture in - guard let strongSelf = self, let buttonNode = strongSelf.leftButtonNodes[spec.key] else { + guard let strongSelf = self, let buttonNode = strongSelf.leftButtonNodes[spec] else { return } strongSelf.performAction?(spec.key, buttonNode.contextSourceNode, gesture) } } - let buttonSize = buttonNode.update(key: spec.key, presentationData: presentationData, height: size.height) - var nextButtonOrigin = spec.isForExpandedView ? nextExpandedButtonOrigin : nextRegularButtonOrigin + let buttonSize = buttonNode.update(key: spec.key, presentationData: presentationData, height: buttonHeight) + let buttonFrame = CGRect(origin: CGPoint(x: spec.isForExpandedView ? expandedLeftButtonsWidth : normalLeftButtonsWidth, y: 0.0), size: buttonSize) - let buttonY: CGFloat - if case .back = spec.key { - buttonY = 0.0 - } else { - buttonY = expandOffset + (spec.isForExpandedView ? maximumExpandOffset : 0.0) - } - let buttonFrame = CGRect(origin: CGPoint(x: nextButtonOrigin, y: buttonY), size: buttonSize) - - nextButtonOrigin += buttonSize.width + 4.0 if spec.isForExpandedView { - nextExpandedButtonOrigin = nextButtonOrigin + expandedLeftButtonsWidth += buttonSize.width } else { - nextRegularButtonOrigin = nextButtonOrigin + normalLeftButtonsWidth += buttonSize.width } let alphaFactor: CGFloat if case .back = spec.key { @@ -126,48 +153,40 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode { } else { alphaFactor = spec.isForExpandedView ? expandFraction : (1.0 - expandFraction) } + if wasAdded { buttonNode.frame = buttonFrame buttonNode.alpha = 0.0 + ComponentTransition.immediate.setBlur(layer: buttonNode.layer, radius: maxBlur) transition.updateAlpha(node: buttonNode, alpha: alphaFactor * alphaFactor) - buttonNode.updateContentsColor(backgroundColor: self.backgroundContentColor, contentsColor: self.contentsColor, canBeExpanded: self.canBeExpanded, transition: .immediate) - - transition.updateSublayerTransformOffset(layer: buttonNode.layer, offset: CGPoint(x: canBeExpanded ? -8.0 : 0.0, y: 0.0)) + ComponentTransition(transition).setBlur(layer: buttonNode.layer, radius: 0.0) + buttonNode.updateContentsColor(contentsColor: spec.isForExpandedView ? expandedButtonContentsColor : normalButtonContentsColor, transition: .immediate) } else { transition.updateFrameAdditiveToCenter(node: buttonNode, frame: buttonFrame) transition.updateAlpha(node: buttonNode, alpha: alphaFactor * alphaFactor) + ComponentTransition(transition).setBlur(layer: buttonNode.layer, radius: (1.0 - alphaFactor * alphaFactor) * maxBlur) } } - var removeKeys: [PeerInfoHeaderNavigationButtonKey] = [] - for (key, _) in self.leftButtonNodes { - if !leftButtons.contains(where: { $0.key == key }) { - removeKeys.append(key) + var removeKeys: [PeerInfoHeaderNavigationButtonSpec] = [] + for (spec, _) in self.leftButtonNodes { + if !leftButtons.contains(where: { $0 == spec }) { + removeKeys.append(spec) } } - for key in removeKeys { - if let buttonNode = self.leftButtonNodes.removeValue(forKey: key) { - buttonNode.removeFromSupernode() + for spec in removeKeys { + if let buttonNode = self.leftButtonNodes.removeValue(forKey: spec) { + buttonNode.view.removeFromSuperview() } } } else { - var nextRegularButtonOrigin = sideInset - var nextExpandedButtonOrigin = sideInset for spec in leftButtons.reversed() { - if let buttonNode = self.leftButtonNodes[spec.key] { + if let buttonNode = self.leftButtonNodes[spec] { let buttonSize = buttonNode.bounds.size - var nextButtonOrigin = spec.isForExpandedView ? nextExpandedButtonOrigin : nextRegularButtonOrigin - let buttonY: CGFloat - if case .back = spec.key { - buttonY = 0.0 - } else { - buttonY = expandOffset + (spec.isForExpandedView ? maximumExpandOffset : 0.0) - } - let buttonFrame = CGRect(origin: CGPoint(x: nextButtonOrigin, y: buttonY), size: buttonSize) - nextButtonOrigin += buttonSize.width + 4.0 + let buttonFrame = CGRect(origin: CGPoint(x: spec.isForExpandedView ? expandedLeftButtonsWidth : normalLeftButtonsWidth, y: 0.0), size: buttonSize) if spec.isForExpandedView { - nextExpandedButtonOrigin = nextButtonOrigin + expandedLeftButtonsWidth += buttonSize.width } else { - nextRegularButtonOrigin = nextButtonOrigin + normalLeftButtonsWidth += buttonSize.width } transition.updateFrameAdditiveToCenter(node: buttonNode, frame: buttonFrame) let alphaFactor: CGFloat @@ -182,16 +201,17 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode { buttonTransition = .animated(duration: duration * 0.25, curve: curve) } buttonTransition.updateAlpha(node: buttonNode, alpha: alphaFactor * alphaFactor) + ComponentTransition(buttonTransition).setBlur(layer: buttonNode.layer, radius: (1.0 - alphaFactor * alphaFactor) * maxBlur) } } } - var accumulatedRightButtonOffset: CGFloat = self.canBeExpanded ? 16.0 : 0.0 + var normalRightButtonsWidth: CGFloat = 0.0 + var expandedRightButtonsWidth: CGFloat = 0.0 + if self.currentRightButtons != rightButtons || presentationData.strings !== self.presentationData?.strings { self.currentRightButtons = rightButtons - var nextRegularButtonOrigin = size.width - sideInset - 8.0 - var nextExpandedButtonOrigin = size.width - expandedSideInset for spec in rightButtons.reversed() { let buttonNode: PeerInfoHeaderNavigationButton var wasAdded = false @@ -201,32 +221,30 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode { key = .moreSearchSort } - if let current = self.rightButtonNodes[key] { + if let current = self.rightButtonNodes[spec] { buttonNode = current } else { wasAdded = true buttonNode = PeerInfoHeaderNavigationButton() - self.rightButtonNodes[key] = buttonNode - self.addSubnode(buttonNode) + self.rightButtonNodes[spec] = buttonNode + self.rightButtonsContainer.addSubview(buttonNode.view) } buttonNode.action = { [weak self] _, gesture in - guard let strongSelf = self, let buttonNode = strongSelf.rightButtonNodes[key] else { + guard let strongSelf = self, let buttonNode = strongSelf.rightButtonNodes[spec] else { return } strongSelf.performAction?(spec.key, buttonNode.contextSourceNode, gesture) } - let buttonSize = buttonNode.update(key: spec.key, presentationData: presentationData, height: size.height) - var nextButtonOrigin = spec.isForExpandedView ? nextExpandedButtonOrigin : nextRegularButtonOrigin - let buttonFrame = CGRect(origin: CGPoint(x: nextButtonOrigin - buttonSize.width, y: expandOffset + (spec.isForExpandedView ? maximumExpandOffset : 0.0)), size: buttonSize) - nextButtonOrigin -= buttonSize.width + 15.0 + let buttonSize = buttonNode.update(key: spec.key, presentationData: presentationData, height: buttonHeight) + let buttonFrame = CGRect(origin: CGPoint(x: spec.isForExpandedView ? expandedRightButtonsWidth : normalRightButtonsWidth, y: 0.0), size: buttonSize) if spec.isForExpandedView { - nextExpandedButtonOrigin = nextButtonOrigin + expandedRightButtonsWidth += buttonSize.width } else { - nextRegularButtonOrigin = nextButtonOrigin + normalRightButtonsWidth += buttonSize.width } let alphaFactor: CGFloat = spec.isForExpandedView ? expandFraction : (1.0 - expandFraction) if wasAdded { - buttonNode.updateContentsColor(backgroundColor: self.backgroundContentColor, contentsColor: self.contentsColor, canBeExpanded: self.canBeExpanded, transition: .immediate) + buttonNode.updateContentsColor(contentsColor: spec.isForExpandedView ? expandedButtonContentsColor : normalButtonContentsColor, transition: .immediate) if shouldAnimateIn { if key == .moreSearchSort || key == .searchWithTags || key == .standaloneSearch { @@ -236,62 +254,51 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode { buttonNode.frame = buttonFrame buttonNode.alpha = 0.0 + ComponentTransition.immediate.setBlur(layer: buttonNode.layer, radius: maxBlur) transition.updateAlpha(node: buttonNode, alpha: alphaFactor * alphaFactor) - - if !spec.isForExpandedView { - transition.updateSublayerTransformOffset(layer: buttonNode.layer, offset: CGPoint(x: accumulatedRightButtonOffset, y: 0.0)) - if self.backgroundContentColor.alpha != 0.0 { - accumulatedRightButtonOffset -= 6.0 - } - } else { - transition.updateSublayerTransformOffset(layer: buttonNode.layer, offset: .zero) - } + ComponentTransition(transition).setBlur(layer: buttonNode.layer, radius: (1.0 - alphaFactor * alphaFactor) * maxBlur) } else { transition.updateFrameAdditiveToCenter(node: buttonNode, frame: buttonFrame) transition.updateAlpha(node: buttonNode, alpha: alphaFactor * alphaFactor) + ComponentTransition(transition).setBlur(layer: buttonNode.layer, radius: (1.0 - alphaFactor * alphaFactor) * maxBlur) } } - var removeKeys: [PeerInfoHeaderNavigationButtonKey] = [] - for (key, _) in self.rightButtonNodes { - if key == .moreSearchSort { + var removeKeys: [PeerInfoHeaderNavigationButtonSpec] = [] + for (spec, _) in self.rightButtonNodes { + if spec.key == .moreSearchSort { if !rightButtons.contains(where: { $0.key == .more || $0.key == .search || $0.key == .sort }) { - removeKeys.append(key) + removeKeys.append(spec) } - } else if !rightButtons.contains(where: { $0.key == key }) { - removeKeys.append(key) + } else if !rightButtons.contains(where: { $0 == spec }) { + removeKeys.append(spec) } } - for key in removeKeys { - if let buttonNode = self.rightButtonNodes.removeValue(forKey: key) { - if key == .moreSearchSort || key == .searchWithTags || key == .standaloneSearch { + for spec in removeKeys { + if let buttonNode = self.rightButtonNodes.removeValue(forKey: spec) { + if spec.key == .moreSearchSort || spec.key == .searchWithTags || spec.key == .standaloneSearch { buttonNode.layer.animateAlpha(from: buttonNode.alpha, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak buttonNode] _ in - buttonNode?.removeFromSupernode() + buttonNode?.view.removeFromSuperview() }) buttonNode.layer.animateScale(from: 1.0, to: 0.001, duration: 0.2, removeOnCompletion: false) } else { - buttonNode.removeFromSupernode() + buttonNode.view.removeFromSuperview() } } } } else { - var nextRegularButtonOrigin = size.width - sideInset - 8.0 - var nextExpandedButtonOrigin = size.width - expandedSideInset - for spec in rightButtons.reversed() { var key = spec.key if key == .more || key == .search || key == .sort { key = .moreSearchSort } - if let buttonNode = self.rightButtonNodes[key] { + if let buttonNode = self.rightButtonNodes[spec] { let buttonSize = buttonNode.bounds.size - var nextButtonOrigin = spec.isForExpandedView ? nextExpandedButtonOrigin : nextRegularButtonOrigin - let buttonFrame = CGRect(origin: CGPoint(x: nextButtonOrigin - buttonSize.width, y: expandOffset + (spec.isForExpandedView ? maximumExpandOffset : 0.0)), size: buttonSize) - nextButtonOrigin -= buttonSize.width + 15.0 + let buttonFrame = CGRect(origin: CGPoint(x: spec.isForExpandedView ? expandedRightButtonsWidth : normalRightButtonsWidth, y: 0.0), size: buttonSize) if spec.isForExpandedView { - nextExpandedButtonOrigin = nextButtonOrigin + expandedRightButtonsWidth += buttonSize.width } else { - nextRegularButtonOrigin = nextButtonOrigin + normalRightButtonsWidth += buttonSize.width } transition.updateFrameAdditiveToCenter(node: buttonNode, frame: buttonFrame) let alphaFactor: CGFloat = spec.isForExpandedView ? expandFraction : (1.0 - expandFraction) @@ -301,9 +308,60 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode { buttonTransition = .animated(duration: duration * 0.25, curve: curve) } buttonTransition.updateAlpha(node: buttonNode, alpha: alphaFactor * alphaFactor) + ComponentTransition(transition).setBlur(layer: buttonNode.layer, radius: (1.0 - alphaFactor * alphaFactor) * maxBlur) } } } self.presentationData = presentationData + + let buttonsY: CGFloat = floor((size.height - buttonHeight) * 0.5) + 2.0 + + let leftButtonsWidth = (1.0 - expandFraction) * normalLeftButtonsWidth + expandFraction * expandedLeftButtonsWidth + let rightButtonsWidth = (1.0 - expandFraction) * normalRightButtonsWidth + expandFraction * expandedRightButtonsWidth + + var leftButtonsFrame = CGRect(origin: CGPoint(x: sideInset, y: buttonsY), size: CGSize(width: max(44.0, leftButtonsWidth), height: buttonHeight)) + if leftButtonsWidth < 44.0 { + let leftFraction = leftButtonsWidth / 44.0 + leftButtonsFrame.origin.x = floorToScreenPixels(leftFraction * sideInset + (1.0 - leftFraction) * (-44.0)) + } + var rightButtonsFrame = CGRect(origin: CGPoint(x: size.width - sideInset - rightButtonsWidth, y: buttonsY), size: CGSize(width: max(44.0, rightButtonsWidth), height: buttonHeight)) + if rightButtonsWidth < 44.0 { + let rightFraction = rightButtonsWidth / 44.0 + rightButtonsFrame.origin.x = floorToScreenPixels(rightFraction * (size.width - sideInset - 44.0) + (1.0 - rightFraction) * size.width) + } + + transition.updateFrame(view: self.leftButtonsBackground, frame: leftButtonsFrame) + transition.updateFrame(view: self.leftButtonsContainer, frame: CGRect(origin: CGPoint(), size: leftButtonsFrame.size)) + self.leftButtonsContainer.layer.cornerRadius = leftButtonsFrame.height * 0.5 + + transition.updateFrame(view: self.rightButtonsBackground, frame: rightButtonsFrame) + transition.updateFrame(view: self.rightButtonsContainer, frame: CGRect(origin: CGPoint(), size: rightButtonsFrame.size)) + self.rightButtonsContainer.layer.cornerRadius = rightButtonsFrame.height * 0.5 + + self.updateBackgroundColors(transition: ComponentTransition(transition)) + } + + private func updateBackgroundColors(transition: ComponentTransition) { + guard let presentationData = self.presentationData else { + return + } + + let leftButtonsSize = self.leftButtonsBackground.bounds.size + let rightButtonsSize = self.rightButtonsBackground.bounds.size + + let tintColor: GlassBackgroundView.TintColor + let tintIsDark: Bool + if self.isOverColoredContents { + tintColor = .init(kind: .custom, color: self.backgroundContentColor) + tintIsDark = presentationData.theme.overallDarkAppearance + } else { + tintColor = .init(kind: .panel, color: UIColor(white: presentationData.theme.overallDarkAppearance ? 0.0 : 1.0, alpha: 0.6)) + tintIsDark = presentationData.theme.overallDarkAppearance + } + + self.backgroundContainer.update(size: self.backgroundContainer.bounds.size, isDark: tintIsDark, transition: transition) + + self.rightButtonsBackground.update(size: rightButtonsSize, cornerRadius: rightButtonsSize.height * 0.5, isDark: tintIsDark, tintColor: tintColor, isInteractive: true, transition: transition) + self.leftButtonsBackground.update(size: leftButtonsSize, cornerRadius: leftButtonsSize.height * 0.5, isDark: tintIsDark, tintColor: tintColor, isInteractive: true, transition: transition) } } diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift index 9618ed73c8..ad1170c8ec 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift @@ -44,6 +44,7 @@ import ProfileLevelInfoScreen import PlainButtonComponent import BundleIconComponent import MarqueeComponent +import EdgeEffect final class PeerInfoHeaderNavigationTransition { let sourceNavigationBar: NavigationBar @@ -63,7 +64,7 @@ final class PeerInfoHeaderNavigationTransition { } } -final class PeerInfoHeaderRegularContentNode: ASDisplayNode { +final class PeerInfoHeaderRegularContentNode: SparseNode { } enum PeerInfoHeaderTextFieldNodeKey: Equatable { @@ -90,6 +91,7 @@ final class PeerInfoHeaderNode: ASDisplayNode { private var state: PeerInfoState? private var peer: Peer? private var threadData: MessageHistoryThreadData? + private var isSearching: Bool = false private var avatarSize: CGFloat? private let isOpenedFromChat: Bool @@ -151,17 +153,13 @@ final class PeerInfoHeaderNode: ASDisplayNode { let usernameNode: MultiScaleTextNode var actionButtonNodes: [PeerInfoHeaderButtonKey: PeerInfoHeaderActionButtonNode] = [:] var buttonNodes: [PeerInfoHeaderButtonKey: PeerInfoHeaderButtonNode] = [:] - let backgroundNode: NavigationBackgroundNode - let expandedBackgroundNode: NavigationBackgroundNode - let separatorNode: ASDisplayNode - let navigationBackgroundNode: ASDisplayNode - let navigationBackgroundBackgroundNode: ASDisplayNode + let panelsExpansionBackgroundView: UIView + let headerEdgeEffectView: EdgeEffectView var navigationTitle: String? - let navigationTitleNode: ImmediateTextNode - let navigationSeparatorNode: ASDisplayNode let navigationButtonContainer: PeerInfoHeaderNavigationButtonContainerNode - let editingNavigationBackgroundNode: NavigationBackgroundNode - let editingNavigationBackgroundSeparator: ASDisplayNode + let searchContainer: ASDisplayNode + let searchBarContainer: SparseNode + let editingEdgeEffectView: EdgeEffectView var musicBackground: UIView? var music: ComponentView? @@ -286,30 +284,16 @@ final class PeerInfoHeaderNode: ASDisplayNode { self.avatarOverlayNode = PeerInfoEditingAvatarOverlayNode(context: context) self.avatarOverlayNode.isUserInteractionEnabled = false - self.navigationBackgroundNode = ASDisplayNode() - self.navigationBackgroundNode.isHidden = true - self.navigationBackgroundNode.isUserInteractionEnabled = false - - self.navigationBackgroundBackgroundNode = ASDisplayNode() - self.navigationBackgroundBackgroundNode.isUserInteractionEnabled = false - - self.navigationTitleNode = ImmediateTextNode() - - self.navigationSeparatorNode = ASDisplayNode() - self.navigationButtonContainer = PeerInfoHeaderNavigationButtonContainerNode() - self.editingNavigationBackgroundNode = NavigationBackgroundNode(color: .clear, enableBlur: true) - self.editingNavigationBackgroundSeparator = ASDisplayNode() + self.searchBarContainer = SparseNode() + self.searchContainer = ASDisplayNode() - self.backgroundNode = NavigationBackgroundNode(color: .clear) - self.backgroundNode.isHidden = true - self.backgroundNode.isUserInteractionEnabled = false - self.expandedBackgroundNode = NavigationBackgroundNode(color: .clear) - self.expandedBackgroundNode.isHidden = false - self.expandedBackgroundNode.isUserInteractionEnabled = false + self.panelsExpansionBackgroundView = UIView() + self.headerEdgeEffectView = EdgeEffectView() + self.headerEdgeEffectView.isUserInteractionEnabled = false - self.separatorNode = ASDisplayNode() - self.separatorNode.isLayerBacked = true + self.editingEdgeEffectView = EdgeEffectView() + self.editingEdgeEffectView.isUserInteractionEnabled = false self.animationCache = context.animationCache self.animationRenderer = context.animationRenderer @@ -320,8 +304,9 @@ final class PeerInfoHeaderNode: ASDisplayNode { self?.requestUpdateLayout?(false) } - self.addSubnode(self.backgroundNode) - self.addSubnode(self.expandedBackgroundNode) + self.view.addSubview(self.panelsExpansionBackgroundView) + self.addSubnode(self.searchContainer) + self.view.addSubview(self.headerEdgeEffectView) self.view.addSubview(self.backgroundBannerView) self.titleNodeContainer.addSubnode(self.titleNode) self.subtitleNodeContainer.addSubnode(self.subtitleNode) @@ -346,14 +331,9 @@ final class PeerInfoHeaderNode: ASDisplayNode { self.addSubnode(self.editingContentNode) self.addSubnode(self.avatarOverlayNode) - self.addSubnode(self.navigationBackgroundNode) - self.navigationBackgroundNode.addSubnode(self.navigationBackgroundBackgroundNode) - self.navigationBackgroundNode.addSubnode(self.navigationTitleNode) - self.navigationBackgroundNode.addSubnode(self.navigationSeparatorNode) - self.addSubnode(self.editingNavigationBackgroundNode) - self.addSubnode(self.editingNavigationBackgroundSeparator) + self.view.addSubview(self.editingEdgeEffectView) self.addSubnode(self.navigationButtonContainer) - self.addSubnode(self.separatorNode) + self.addSubnode(self.searchBarContainer) self.avatarListNode.avatarContainerNode.tapped = { [weak self] in self?.initiateAvatarExpansion(gallery: false, first: false) @@ -509,7 +489,7 @@ final class PeerInfoHeaderNode: ASDisplayNode { private var currentStatusIcon: CredibilityIcon? private var currentPanelStatusData: PeerInfoStatusData? - func update(width: CGFloat, containerHeight: CGFloat, containerInset: CGFloat, statusBarHeight: CGFloat, navigationHeight: CGFloat, isModalOverlay: Bool, isMediaOnly: Bool, contentOffset: CGFloat, paneContainerY: CGFloat, presentationData: PresentationData, peer: Peer?, cachedData: CachedPeerData?, threadData: MessageHistoryThreadData?, peerNotificationSettings: TelegramPeerNotificationSettings?, threadNotificationSettings: TelegramPeerNotificationSettings?, globalNotificationSettings: EngineGlobalNotificationSettings?, statusData: PeerInfoStatusData?, panelStatusData: (PeerInfoStatusData?, PeerInfoStatusData?, CGFloat?), isSecretChat: Bool, isContact: Bool, isSettings: Bool, state: PeerInfoState, profileGiftsContext: ProfileGiftsContext?, screenData: PeerInfoScreenData?, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, transition: ContainedViewLayoutTransition, additive: Bool, animateHeader: Bool) -> CGFloat { + func update(width: CGFloat, containerHeight: CGFloat, containerInset: CGFloat, statusBarHeight: CGFloat, navigationHeight: CGFloat, isModalOverlay: Bool, isMediaOnly: Bool, contentOffset: CGFloat, paneContainerY: CGFloat, presentationData: PresentationData, peer: Peer?, cachedData: CachedPeerData?, threadData: MessageHistoryThreadData?, peerNotificationSettings: TelegramPeerNotificationSettings?, threadNotificationSettings: TelegramPeerNotificationSettings?, globalNotificationSettings: EngineGlobalNotificationSettings?, statusData: PeerInfoStatusData?, panelStatusData: (PeerInfoStatusData?, PeerInfoStatusData?, CGFloat?), isSecretChat: Bool, isContact: Bool, isSettings: Bool, state: PeerInfoState, profileGiftsContext: ProfileGiftsContext?, screenData: PeerInfoScreenData?, isSearching: Bool, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, transition: ContainedViewLayoutTransition, additive: Bool, animateHeader: Bool) -> CGFloat { if self.appliedCustomNavigationContentNode !== self.customNavigationContentNode { if let previous = self.appliedCustomNavigationContentNode { transition.updateAlpha(node: previous, alpha: 0.0, completion: { [weak previous] _ in @@ -536,11 +516,15 @@ final class PeerInfoHeaderNode: ASDisplayNode { self.state = state self.peer = peer self.threadData = threadData + self.isSearching = isSearching self.avatarListNode.listContainerNode.peer = peer.flatMap(EnginePeer.init) let isFirstTime = self.validLayout == nil self.validLayout = (width, statusBarHeight, deviceMetrics) + self.searchBarContainer.isUserInteractionEnabled = isSearching + self.searchContainer.isUserInteractionEnabled = isSearching + let previousPanelStatusData = self.currentPanelStatusData self.currentPanelStatusData = panelStatusData.0 @@ -637,7 +621,7 @@ final class PeerInfoHeaderNode: ASDisplayNode { transition.updateAlpha(node: self.regularContentNode, alpha: (state.isEditing || self.customNavigationContentNode != nil) ? 0.0 : 1.0) if self.navigationTransition == nil { - transition.updateAlpha(node: self.navigationButtonContainer, alpha: self.customNavigationContentNode != nil ? 0.0 : 1.0) + transition.updateAlpha(node: self.navigationButtonContainer, alpha: (self.customNavigationContentNode != nil || isSearching) ? 0.0 : 1.0) } self.editingContentNode.alpha = state.isEditing ? 1.0 : 0.0 @@ -656,10 +640,6 @@ final class PeerInfoHeaderNode: ASDisplayNode { let avatarFrame = CGRect(origin: CGPoint(x: floor((width - avatarSize) / 2.0), y: statusBarHeight + 22.0), size: CGSize(width: avatarSize, height: avatarSize)) - self.backgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.blurredBackgroundColor, transition: .immediate) - - let headerBackgroundColor: UIColor = presentationData.theme.list.blocksBackgroundColor - let regularNavigationContentsAccentColor: UIColor = peer?.effectiveProfileColor != nil ? .white : presentationData.theme.list.itemAccentColor let collapsedHeaderNavigationContentsAccentColor = presentationData.theme.list.itemAccentColor let expandedAvatarNavigationContentsAccentColor: UIColor = .white @@ -674,7 +654,7 @@ final class PeerInfoHeaderNode: ASDisplayNode { let regularHeaderButtonBackgroundColor: UIColor let collapsedHeaderButtonBackgroundColor: UIColor = .clear - let expandedAvatarHeaderButtonBackgroundColor: UIColor = UIColor(white: 1.0, alpha: 0.1) + let expandedAvatarHeaderButtonBackgroundColor: UIColor = UIColor(white: 0.0, alpha: 0.5) let regularContentButtonForegroundColor: UIColor = peer?.effectiveProfileColor != nil ? UIColor.white : presentationData.theme.list.itemAccentColor let collapsedHeaderContentButtonForegroundColor = presentationData.theme.list.itemAccentColor @@ -745,61 +725,21 @@ final class PeerInfoHeaderNode: ASDisplayNode { navigationTransition = animateHeader ? .animated(duration: 0.2, curve: .easeInOut) : .immediate } + let editingEdgeEffectHeight: CGFloat = 40.0 + let editingEdgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: width, height: navigationHeight + 10.0)) + transition.updateFrame(view: self.editingEdgeEffectView, frame: editingEdgeEffectFrame) + self.editingEdgeEffectView.update(content: presentationData.theme.list.blocksBackgroundColor, blur: true, rect: editingEdgeEffectFrame, edge: .top, edgeSize: editingEdgeEffectHeight, transition: ComponentTransition(transition)) let editingBackgroundAlpha: CGFloat if state.isEditing { editingBackgroundAlpha = max(0.0, min(1.0, contentOffset / 20.0)) } else { editingBackgroundAlpha = 0.0 } - - self.editingNavigationBackgroundSeparator.backgroundColor = presentationData.theme.rootController.navigationBar.separatorColor - self.editingNavigationBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.blurredBackgroundColor, transition: .immediate) - - let editingNavigationBackgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: width, height: navigationHeight)) - transition.updateFrame(node: self.editingNavigationBackgroundNode, frame: editingNavigationBackgroundFrame) - self.editingNavigationBackgroundNode.update(size: editingNavigationBackgroundFrame.size, transition: transition) - transition.updateFrame(node: self.editingNavigationBackgroundSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: editingNavigationBackgroundFrame.maxY), size: CGSize(width: width, height: UIScreenPixel))) - - transition.updateAlpha(node: self.editingNavigationBackgroundNode, alpha: editingBackgroundAlpha) - transition.updateAlpha(node: self.editingNavigationBackgroundSeparator, alpha: editingBackgroundAlpha) + ComponentTransition(transition).setAlpha(view: self.editingEdgeEffectView, alpha: editingBackgroundAlpha) let backgroundBannerAlpha: CGFloat - var effectiveSeparatorAlpha: CGFloat - /*if let navigationTransition = self.navigationTransition { - transitionSourceHeight = navigationTransition.sourceNavigationBar.backgroundNode.bounds.height - transitionFraction = navigationTransition.fraction - - innerBackgroundTransitionFraction = 0.0 - backgroundBannerAlpha = 1.0 - - if let avatarNavigationNode = navigationTransition.sourceNavigationBar.rightButtonNode.singleCustomNode as? ChatAvatarNavigationNode { - if let statusView = avatarNavigationNode.statusView.view { - transitionSourceAvatarFrame = statusView.convert(statusView.bounds, to: navigationTransition.sourceNavigationBar.view) - } else { - transitionSourceAvatarFrame = avatarNavigationNode.avatarNode.view.convert(avatarNavigationNode.avatarNode.view.bounds, to: navigationTransition.sourceNavigationBar.view) - } - transition.updateAlpha(node: self.avatarListNode.avatarContainerNode.avatarNode, alpha: 1.0 - transitionFraction) - } else { - if deviceMetrics.hasDynamicIsland && statusBarHeight > 0.0 && !isLandscape { - transitionSourceAvatarFrame = CGRect(origin: CGPoint(x: avatarFrame.minX, y: -20.0), size: avatarFrame.size).insetBy(dx: avatarSize * 0.4, dy: avatarSize * 0.4) - } else { - transitionSourceAvatarFrame = avatarFrame.offsetBy(dx: 0.0, dy: -avatarFrame.maxY).insetBy(dx: avatarSize * 0.4, dy: avatarSize * 0.4) - } - } - transitionSourceTitleFrame = navigationTransition.sourceTitleFrame - transitionSourceSubtitleFrame = navigationTransition.sourceSubtitleFrame - - transition.updateAlpha(layer: self.backgroundBannerView.layer, alpha: 1.0 - transitionFraction) - - self.expandedBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.blurredBackgroundColor.mixedWith(headerBackgroundColor, alpha: 1.0 - transitionFraction), forceKeepBlur: true, transition: transition) - effectiveSeparatorAlpha = transitionFraction - - if self.isAvatarExpanded, case .animated = transition, transitionFraction == 1.0 { - self.avatarListNode.animateAvatarCollapse(transition: transition) - } - self.avatarClippingNode.clipsToBounds = false - } else*/ do { + do { let backgroundTransitionStepDistance: CGFloat = 50.0 var backgroundTransitionDistance: CGFloat = navigationHeight + panelWithAvatarHeight - backgroundTransitionStepDistance if self.isSettings || self.isMyProfile { @@ -812,9 +752,6 @@ final class PeerInfoHeaderNode: ASDisplayNode { innerBackgroundTransitionFraction = max(0.0, min(1.0, contentOffset / backgroundTransitionStepDistance)) } - self.expandedBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.opaqueBackgroundColor.mixedWith(headerBackgroundColor, alpha: 1.0 - innerBackgroundTransitionFraction), forceKeepBlur: true, transition: transition) - navigationTransition.updateAlpha(node: self.expandedBackgroundNode, alpha: state.isEditing ? 0.0 : 1.0) - if state.isEditing { backgroundBannerAlpha = 0.0 } else { @@ -826,8 +763,6 @@ final class PeerInfoHeaderNode: ASDisplayNode { } navigationTransition.updateAlpha(layer: self.backgroundBannerView.layer, alpha: backgroundBannerAlpha) - effectiveSeparatorAlpha = innerBackgroundTransitionFraction - self.avatarClippingNode.clipsToBounds = true } @@ -1161,7 +1096,10 @@ final class PeerInfoHeaderNode: ASDisplayNode { self.titleExpandedVerifiedIconSize = expandedIconSize } - self.navigationButtonContainer.updateContentsColor(backgroundContentColor: headerButtonBackgroundColor, contentsColor: navigationContentsAccentColor, canBeExpanded: navigationContentsCanBeExpanded, transition: navigationTransition) + var actualNavigationContentsColor = navigationContentsAccentColor + actualNavigationContentsColor = presentationData.theme.chat.inputPanel.panelControlColor + + self.navigationButtonContainer.updateContentsColor(backgroundContentColor: headerButtonBackgroundColor, contentsColor: actualNavigationContentsColor, isOverColoredContents: !navigationContentsCanBeExpanded, transition: navigationTransition) self.titleNode.updateTintColor(color: navigationContentsPrimaryColor, transition: navigationTransition) self.subtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: navigationTransition) @@ -1189,25 +1127,6 @@ final class PeerInfoHeaderNode: ASDisplayNode { self.avatarListNode.listContainerNode.currentItemNode?.updateTransitionFraction(transitionFraction, transition: transition) self.avatarOverlayNode.updateTransitionFraction(transitionFraction, transition: transition) - if self.navigationTitle != presentationData.strings.EditProfile_Title || themeUpdated { - self.navigationTitleNode.attributedText = NSAttributedString(string: presentationData.strings.EditProfile_Title, font: Font.semibold(17.0), textColor: .white) - } - - let navigationTitleSize = self.navigationTitleNode.updateLayout(CGSize(width: width, height: navigationHeight)) - self.navigationTitleNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((width - navigationTitleSize.width) / 2.0), y: navigationHeight - 44.0 + floorToScreenPixels((44.0 - navigationTitleSize.height) / 2.0)), size: navigationTitleSize) - - self.navigationBackgroundNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: width, height: navigationHeight)) - self.navigationBackgroundBackgroundNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: width, height: navigationHeight)) - self.navigationSeparatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: navigationHeight), size: CGSize(width: width, height: UIScreenPixel)) - self.navigationBackgroundBackgroundNode.backgroundColor = presentationData.theme.rootController.navigationBar.opaqueBackgroundColor - self.navigationSeparatorNode.backgroundColor = presentationData.theme.rootController.navigationBar.separatorColor - - let navigationSeparatorAlpha: CGFloat = 0.0 - transition.updateAlpha(node: self.navigationBackgroundBackgroundNode, alpha: 1.0 - navigationSeparatorAlpha) - transition.updateAlpha(node: self.navigationSeparatorNode, alpha: navigationSeparatorAlpha) - - self.separatorNode.backgroundColor = presentationData.theme.list.itemBlocksSeparatorColor - let expandedAvatarControlsHeight: CGFloat = 61.0 var expandedAvatarListHeight = min(width, containerHeight - expandedAvatarControlsHeight) if self.isSettings || self.isMyProfile { @@ -1638,7 +1557,7 @@ final class PeerInfoHeaderNode: ASDisplayNode { let singleTitleLockOffset: CGFloat = ((peer?.id == self.context.account.peerId && !self.isMyProfile) || subtitleSize.height.isZero) ? 8.0 : 0.0 - let titleLockOffset: CGFloat = 7.0 + singleTitleLockOffset + let titleLockOffset: CGFloat = 16.0 + singleTitleLockOffset let titleMaxLockOffset: CGFloat = 7.0 let titleOffset: CGFloat let titleCollapseFraction: CGFloat @@ -1697,38 +1616,37 @@ final class PeerInfoHeaderNode: ASDisplayNode { let paneAreaExpansionDistance: CGFloat = 32.0 let effectiveAreaExpansionFraction: CGFloat + let realAreaExpansionFraction: CGFloat if state.isEditing { effectiveAreaExpansionFraction = 0.0 + realAreaExpansionFraction = effectiveAreaExpansionFraction } else if isSettings || isMyProfile { var paneAreaExpansionDelta = (self.frame.maxY - navigationHeight) - contentOffset paneAreaExpansionDelta = max(0.0, min(paneAreaExpansionDelta, paneAreaExpansionDistance)) effectiveAreaExpansionFraction = 1.0 - paneAreaExpansionDelta / paneAreaExpansionDistance + + do { + var paneAreaExpansionDelta = (paneContainerY - navigationHeight) - contentOffset + paneAreaExpansionDelta = max(0.0, min(paneAreaExpansionDelta, paneAreaExpansionDistance)) + realAreaExpansionFraction = 1.0 - paneAreaExpansionDelta / paneAreaExpansionDistance + } } else { var paneAreaExpansionDelta = (paneContainerY - navigationHeight) - contentOffset paneAreaExpansionDelta = max(0.0, min(paneAreaExpansionDelta, paneAreaExpansionDistance)) effectiveAreaExpansionFraction = 1.0 - paneAreaExpansionDelta / paneAreaExpansionDistance + realAreaExpansionFraction = effectiveAreaExpansionFraction } - let secondarySeparatorAlpha = 1.0 - effectiveAreaExpansionFraction - if self.navigationTransition == nil && !self.isSettings && effectiveSeparatorAlpha == 1.0 && secondarySeparatorAlpha < 1.0 { - effectiveSeparatorAlpha = secondarySeparatorAlpha - } - if self.customNavigationContentNode != nil { - effectiveSeparatorAlpha = 0.0 - } - if state.isEditing { - effectiveSeparatorAlpha = 0.0 - } - transition.updateAlpha(node: self.separatorNode, alpha: effectiveSeparatorAlpha) - self.titleNode.update(stateFractions: [ TitleNodeStateRegular: self.isAvatarExpanded ? 0.0 : 1.0, TitleNodeStateExpanded: self.isAvatarExpanded ? 1.0 : 0.0 ], transition: transition) - let subtitleAlpha: CGFloat + transition.updateAlpha(node: self.titleNode, alpha: isSearching ? 0.0 : 1.0) + + var subtitleAlpha: CGFloat var subtitleOffset: CGFloat = 0.0 - let panelSubtitleAlpha: CGFloat + var panelSubtitleAlpha: CGFloat var panelSubtitleOffset: CGFloat = 0.0 if self.isSettings { subtitleAlpha = 1.0 - titleCollapseFraction @@ -1755,6 +1673,12 @@ final class PeerInfoHeaderNode: ASDisplayNode { } } } + + if isSearching { + subtitleAlpha = 0.0 + panelSubtitleAlpha = 0.0 + } + self.subtitleNode.update(stateFractions: [ TitleNodeStateRegular: self.isAvatarExpanded ? 0.0 : 1.0, TitleNodeStateExpanded: self.isAvatarExpanded ? 1.0 : 0.0 @@ -2465,18 +2389,15 @@ final class PeerInfoHeaderNode: ASDisplayNode { } let backgroundFrame: CGRect - let separatorFrame: CGRect var resolvedHeight: CGFloat if state.isEditing { resolvedHeight = editingContentHeight backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: -2000.0 + max(navigationHeight, resolvedHeight - contentOffset)), size: CGSize(width: width, height: 2000.0)) - separatorFrame = CGRect(origin: CGPoint(x: 0.0, y: max(navigationHeight, resolvedHeight - contentOffset)), size: CGSize(width: width, height: UIScreenPixel)) } else { resolvedHeight = resolvedRegularHeight backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: -2000.0 + apparentHeight), size: CGSize(width: width, height: 2000.0)) - separatorFrame = CGRect(origin: CGPoint(x: 0.0, y: apparentHeight), size: CGSize(width: width, height: UIScreenPixel)) } transition.updateFrame(node: self.regularContentNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: resolvedHeight))) @@ -2582,20 +2503,29 @@ final class PeerInfoHeaderNode: ASDisplayNode { } } + let edgeEffectHeight: CGFloat = 40.0 + let edgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: backgroundFrame.width, height: navigationHeight + 10.0)) + + let panelsExpansionBackgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: -2000.0 + paneContainerY - contentOffset), size: CGSize(width: width, height: 2000.0)) + if additive { - transition.updateFrameAdditive(node: self.backgroundNode, frame: backgroundFrame) - self.backgroundNode.update(size: self.backgroundNode.bounds.size, transition: transition) - transition.updateFrameAdditive(node: self.expandedBackgroundNode, frame: backgroundFrame) - self.expandedBackgroundNode.update(size: self.expandedBackgroundNode.bounds.size, transition: transition) - transition.updateFrameAdditive(node: self.separatorNode, frame: separatorFrame) + transition.updateFrameAdditive(layer: self.headerEdgeEffectView.layer, frame: edgeEffectFrame) + transition.updateFrameAdditive(view: self.panelsExpansionBackgroundView, frame: panelsExpansionBackgroundFrame) } else { - transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame) - self.backgroundNode.update(size: self.backgroundNode.bounds.size, transition: transition) - transition.updateFrame(node: self.expandedBackgroundNode, frame: backgroundFrame) - self.expandedBackgroundNode.update(size: self.expandedBackgroundNode.bounds.size, transition: transition) - transition.updateFrame(node: self.separatorNode, frame: separatorFrame) + transition.updateFrame(view: self.headerEdgeEffectView, frame: edgeEffectFrame) + transition.updateFrame(view: self.panelsExpansionBackgroundView, frame: panelsExpansionBackgroundFrame) } + self.panelsExpansionBackgroundView.backgroundColor = presentationData.theme.rootController.navigationBar.opaqueBackgroundColor + transition.updateAlpha(layer: self.panelsExpansionBackgroundView.layer, alpha: realAreaExpansionFraction) + if isSettings { + self.panelsExpansionBackgroundView.isHidden = true + } + + self.headerEdgeEffectView.update(content: presentationData.theme.rootController.navigationBar.opaqueBackgroundColor, blur: true, rect: edgeEffectFrame, edge: .top, edgeSize: edgeEffectHeight, transition: ComponentTransition(transition)) + + navigationTransition.updateAlpha(layer: self.headerEdgeEffectView.layer, alpha: state.isEditing ? 0.0 : 1.0) + if !state.isEditing { if !isSettings && !isMyProfile { if self.isAvatarExpanded { @@ -2775,8 +2705,13 @@ final class PeerInfoHeaderNode: ASDisplayNode { guard let result = super.hitTest(point, with: event) else { return nil } - if !self.backgroundNode.frame.contains(point) { - return nil + + if self.isSearching { + if !result.isDescendant(of: self.searchBarContainer.view) && !result.isDescendant(of: self.searchContainer.view) { + return self.view + } + + return result } if let customNavigationContentNode = self.customNavigationContentNode { diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index c4f721618c..9fbf86eb3e 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -10622,7 +10622,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro switch status { case .available: var cameraTransitionIn: StoryCameraTransitionIn? - if let rightButton = self.headerNode.navigationButtonContainer.rightButtonNodes[.postStory] { + if let rightButton = self.headerNode.navigationButtonContainer.rightButtonNodes.first(where: { $0.key.key == .postStory })?.value { cameraTransitionIn = StoryCameraTransitionIn( sourceView: rightButton.view, sourceRect: rightButton.view.bounds, @@ -11452,7 +11452,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if self.isSettings { if let settings = self.data?.globalSettings { - self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, mode: .list, placeholder: self.presentationData.strings.Settings_Search, hasBackground: true, hasSeparator: true, contentNode: SettingsSearchContainerNode(context: self.context, openResult: { [weak self] result in + self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, mode: .navigation, placeholder: self.presentationData.strings.Settings_Search, hasBackground: true, hasSeparator: true, contentNode: SettingsSearchContainerNode(context: self.context, openResult: { [weak self] result in if let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController { result.present(strongSelf.context, navigationController, { [weak self] mode, controller in if let strongSelf = self { @@ -11482,7 +11482,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro }, searchBarIsExternal: true) } } else if let currentPaneKey = self.paneContainerNode.currentPaneKey, case .members = currentPaneKey { - self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, mode: .list, placeholder: self.presentationData.strings.Common_Search, hasBackground: true, hasSeparator: true, contentNode: ChannelMembersSearchContainerNode(context: self.context, forceTheme: nil, peerId: self.peerId, mode: .searchMembers, filters: [], searchContext: self.groupMembersSearchContext, openPeer: { [weak self] peer, participant in + self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, mode: .navigation, placeholder: self.presentationData.strings.Common_Search, hasBackground: true, hasSeparator: true, contentNode: ChannelMembersSearchContainerNode(context: self.context, forceTheme: nil, peerId: self.peerId, mode: .searchMembers, filters: [], searchContext: self.groupMembersSearchContext, openPeer: { [weak self] peer, participant in self?.openPeer(peerId: peer.id, navigation: .info(nil)) }, updateActivity: { _ in }, pushController: { [weak self] c in @@ -11583,9 +11583,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } } - self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, mode: .list, placeholder: self.presentationData.strings.Common_Search, hasBackground: true, contentNode: ChatHistorySearchContainerNode(context: self.context, peerId: self.peerId, threadId: self.chatLocation.threadId, tagMask: tagMask, interfaceInteraction: self.chatInterfaceInteraction), cancel: { [weak self] in + self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, mode: .navigation, placeholder: self.presentationData.strings.Common_Search, hasBackground: false, contentNode: ChatHistorySearchContainerNode(context: self.context, peerId: self.peerId, threadId: self.chatLocation.threadId, tagMask: tagMask, interfaceInteraction: self.chatInterfaceInteraction), cancel: { [weak self] in self?.deactivateSearch() - }) + }, fieldStyle: .glass) } let transition: ContainedViewLayoutTransition = .animated(duration: 0.2, curve: .easeInOut) @@ -11595,8 +11595,13 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro self.searchDisplayController?.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate) self.searchDisplayController?.activate(insertSubnode: { [weak self] subnode, isSearchBar in - if let strongSelf = self, let navigationBar = strongSelf.controller?.navigationBar { - strongSelf.insertSubnode(subnode, belowSubnode: navigationBar) + guard let self else { + return + } + if isSearchBar { + self.headerNode.searchBarContainer.addSubnode(subnode) + } else { + self.headerNode.searchContainer.addSubnode(subnode) } }, placeholder: nil) @@ -11627,12 +11632,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if let navigationBar = self.controller?.navigationBar { transition.updateAlpha(node: navigationBar, alpha: 1.0) } + if let (layout, navigationHeight) = self.validLayout { + self.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .animated(duration: 0.4, curve: .spring), additive: false) + } } private weak var mediaGalleryContextMenu: ContextController? func displaySharedMediaFastScrollingTooltip() { - guard let buttonNode = self.headerNode.navigationButtonContainer.rightButtonNodes[.more] else { + guard let buttonNode = self.headerNode.navigationButtonContainer.rightButtonNodes.first(where: { $0.key.key == .more })?.value else { return } guard let controller = self.controller else { @@ -12582,8 +12590,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } let headerInset = sectionInset - let headerHeight = self.headerNode.update(width: layout.size.width, containerHeight: layout.size.height, containerInset: headerInset, statusBarHeight: layout.statusBarHeight ?? 0.0, navigationHeight: navigationHeight, isModalOverlay: layout.isModalOverlay, isMediaOnly: self.isMediaOnly, contentOffset: self.isMediaOnly ? 212.0 : self.scrollNode.view.contentOffset.y, paneContainerY: self.paneContainerNode.frame.minY, presentationData: self.presentationData, peer: self.data?.savedMessagesPeer ?? self.data?.peer, cachedData: self.data?.cachedData, threadData: self.data?.threadData, peerNotificationSettings: self.data?.peerNotificationSettings, threadNotificationSettings: self.data?.threadNotificationSettings, globalNotificationSettings: self.data?.globalNotificationSettings, statusData: self.data?.status, panelStatusData: self.customStatusData, isSecretChat: self.peerId.namespace == Namespaces.Peer.SecretChat, isContact: self.data?.isContact ?? false, isSettings: self.isSettings, state: self.state, profileGiftsContext: self.data?.profileGiftsContext, screenData: self.data, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, transition: self.headerNode.navigationTransition == nil ? transition : .immediate, additive: additive, animateHeader: transition.isAnimated && self.headerNode.navigationTransition == nil) - let headerFrame = CGRect(origin: CGPoint(x: 0.0, y: contentHeight), size: CGSize(width: layout.size.width, height: headerHeight)) + let headerHeight = self.headerNode.update(width: layout.size.width, containerHeight: layout.size.height, containerInset: headerInset, statusBarHeight: layout.statusBarHeight ?? 0.0, navigationHeight: navigationHeight, isModalOverlay: layout.isModalOverlay, isMediaOnly: self.isMediaOnly, contentOffset: self.isMediaOnly ? 212.0 : self.scrollNode.view.contentOffset.y, paneContainerY: self.paneContainerNode.frame.minY, presentationData: self.presentationData, peer: self.data?.savedMessagesPeer ?? self.data?.peer, cachedData: self.data?.cachedData, threadData: self.data?.threadData, peerNotificationSettings: self.data?.peerNotificationSettings, threadNotificationSettings: self.data?.threadNotificationSettings, globalNotificationSettings: self.data?.globalNotificationSettings, statusData: self.data?.status, panelStatusData: self.customStatusData, isSecretChat: self.peerId.namespace == Namespaces.Peer.SecretChat, isContact: self.data?.isContact ?? false, isSettings: self.isSettings, state: self.state, profileGiftsContext: self.data?.profileGiftsContext, screenData: self.data, isSearching: self.searchDisplayController != nil, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, transition: self.headerNode.navigationTransition == nil ? transition : .immediate, additive: additive, animateHeader: transition.isAnimated && self.headerNode.navigationTransition == nil) + let headerFrame = CGRect(origin: CGPoint(x: 0.0, y: contentHeight), size: CGSize(width: layout.size.width, height: layout.size.height)) if additive { transition.updateFrameAdditive(node: self.headerNode, frame: headerFrame) } else { @@ -12967,7 +12975,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } let headerInset = sectionInset - let _ = self.headerNode.update(width: layout.size.width, containerHeight: layout.size.height, containerInset: headerInset, statusBarHeight: layout.statusBarHeight ?? 0.0, navigationHeight: navigationHeight, isModalOverlay: layout.isModalOverlay, isMediaOnly: self.isMediaOnly, contentOffset: self.isMediaOnly ? 212.0 : offsetY, paneContainerY: self.paneContainerNode.frame.minY, presentationData: self.presentationData, peer: self.data?.savedMessagesPeer ?? self.data?.peer, cachedData: self.data?.cachedData, threadData: self.data?.threadData, peerNotificationSettings: self.data?.peerNotificationSettings, threadNotificationSettings: self.data?.threadNotificationSettings, globalNotificationSettings: self.data?.globalNotificationSettings, statusData: self.data?.status, panelStatusData: self.customStatusData, isSecretChat: self.peerId.namespace == Namespaces.Peer.SecretChat, isContact: self.data?.isContact ?? false, isSettings: self.isSettings, state: self.state, profileGiftsContext: self.data?.profileGiftsContext, screenData: self.data, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, transition: self.headerNode.navigationTransition == nil ? transition : .immediate, additive: additive, animateHeader: animateHeader && self.headerNode.navigationTransition == nil) + let _ = self.headerNode.update(width: layout.size.width, containerHeight: layout.size.height, containerInset: headerInset, statusBarHeight: layout.statusBarHeight ?? 0.0, navigationHeight: navigationHeight, isModalOverlay: layout.isModalOverlay, isMediaOnly: self.isMediaOnly, contentOffset: self.isMediaOnly ? 212.0 : offsetY, paneContainerY: self.paneContainerNode.frame.minY, presentationData: self.presentationData, peer: self.data?.savedMessagesPeer ?? self.data?.peer, cachedData: self.data?.cachedData, threadData: self.data?.threadData, peerNotificationSettings: self.data?.peerNotificationSettings, threadNotificationSettings: self.data?.threadNotificationSettings, globalNotificationSettings: self.data?.globalNotificationSettings, statusData: self.data?.status, panelStatusData: self.customStatusData, isSecretChat: self.peerId.namespace == Namespaces.Peer.SecretChat, isContact: self.data?.isContact ?? false, isSettings: self.isSettings, state: self.state, profileGiftsContext: self.data?.profileGiftsContext, screenData: self.data, isSearching: self.searchDisplayController != nil, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, transition: self.headerNode.navigationTransition == nil ? transition : .immediate, additive: additive, animateHeader: animateHeader && self.headerNode.navigationTransition == nil) } let paneAreaExpansionDistance: CGFloat = 32.0 @@ -12996,11 +13004,14 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro disableTabSwitching = true } - let navigationBarHeight: CGFloat = !self.isSettings && layout.isModalOverlay ? 56.0 : 44.0 + let navigationBarHeight: CGFloat = !self.isSettings && layout.isModalOverlay ? 68.0 : 60.0 self.paneContainerNode.update(size: self.paneContainerNode.bounds.size, sideInset: layout.safeInsets.left, bottomInset: bottomInset, deviceMetrics: layout.deviceMetrics, visibleHeight: visibleHeight, expansionFraction: effectiveAreaExpansionFraction, presentationData: self.presentationData, data: self.data, areTabsHidden: self.headerNode.customNavigationContentNode != nil, disableTabSwitching: disableTabSwitching, navigationHeight: navigationHeight, transition: transition) transition.updateFrame(node: self.headerNode.navigationButtonContainer, frame: CGRect(origin: CGPoint(x: layout.safeInsets.left, y: layout.statusBarHeight ?? 0.0), size: CGSize(width: layout.size.width - layout.safeInsets.left * 2.0, height: navigationBarHeight))) - + var searchBarContainerY: CGFloat = layout.statusBarHeight ?? 0.0 + searchBarContainerY += floor((navigationBarHeight - 44.0) * 0.5) + 2.0 + transition.updateFrame(node: self.headerNode.searchBarContainer, frame: CGRect(origin: CGPoint(x: layout.safeInsets.left, y: searchBarContainerY), size: CGSize(width: layout.size.width - layout.safeInsets.left * 2.0, height: navigationBarHeight))) + transition.updateFrame(node: self.headerNode.searchContainer, frame: CGRect(origin: CGPoint(), size: layout.size)) var leftNavigationButtons: [PeerInfoHeaderNavigationButtonSpec] = [] var rightNavigationButtons: [PeerInfoHeaderNavigationButtonSpec] = [] @@ -13074,6 +13085,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro switch previousItem { case .close, .item: leftNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .back, isForExpandedView: false)) + leftNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .back, isForExpandedView: true)) } } self.headerNode.navigationButtonContainer.update(size: CGSize(width: layout.size.width - layout.safeInsets.left * 2.0, height: navigationBarHeight), presentationData: self.presentationData, leftButtons: leftNavigationButtons, rightButtons: rightNavigationButtons, expandFraction: effectiveAreaExpansionFraction, shouldAnimateIn: animateHeader, transition: transition) @@ -14597,7 +14609,7 @@ private final class PeerInfoNavigationTransitionNode: ASDisplayNode, CustomNavig } let headerInset = sectionInset - topHeight = self.headerNode.update(width: layout.size.width, containerHeight: layout.size.height, containerInset: headerInset, statusBarHeight: layout.statusBarHeight ?? 0.0, navigationHeight: topNavigationBar.bounds.height, isModalOverlay: layout.isModalOverlay, isMediaOnly: false, contentOffset: 0.0, paneContainerY: 0.0, presentationData: self.presentationData, peer: self.screenNode.data?.savedMessagesPeer ?? self.screenNode.data?.peer, cachedData: self.screenNode.data?.cachedData, threadData: self.screenNode.data?.threadData, peerNotificationSettings: self.screenNode.data?.peerNotificationSettings, threadNotificationSettings: self.screenNode.data?.threadNotificationSettings, globalNotificationSettings: self.screenNode.data?.globalNotificationSettings, statusData: self.screenNode.data?.status, panelStatusData: (nil, nil, nil), isSecretChat: self.screenNode.peerId.namespace == Namespaces.Peer.SecretChat, isContact: self.screenNode.data?.isContact ?? false, isSettings: self.screenNode.isSettings, state: self.screenNode.state, profileGiftsContext: self.screenNode.data?.profileGiftsContext, screenData: self.screenNode.data, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, transition: transition, additive: false, animateHeader: false) + topHeight = self.headerNode.update(width: layout.size.width, containerHeight: layout.size.height, containerInset: headerInset, statusBarHeight: layout.statusBarHeight ?? 0.0, navigationHeight: topNavigationBar.bounds.height, isModalOverlay: layout.isModalOverlay, isMediaOnly: false, contentOffset: 0.0, paneContainerY: 0.0, presentationData: self.presentationData, peer: self.screenNode.data?.savedMessagesPeer ?? self.screenNode.data?.peer, cachedData: self.screenNode.data?.cachedData, threadData: self.screenNode.data?.threadData, peerNotificationSettings: self.screenNode.data?.peerNotificationSettings, threadNotificationSettings: self.screenNode.data?.threadNotificationSettings, globalNotificationSettings: self.screenNode.data?.globalNotificationSettings, statusData: self.screenNode.data?.status, panelStatusData: (nil, nil, nil), isSecretChat: self.screenNode.peerId.namespace == Namespaces.Peer.SecretChat, isContact: self.screenNode.data?.isContact ?? false, isSettings: self.screenNode.isSettings, state: self.screenNode.state, profileGiftsContext: self.screenNode.data?.profileGiftsContext, screenData: self.screenNode.data, isSearching: false, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, transition: transition, additive: false, animateHeader: false) } let titleScale = (fraction * previousTitleNode.view.bounds.height + (1.0 - fraction) * self.headerNode.titleNodeRawContainer.bounds.height) / previousTitleNode.view.bounds.height diff --git a/submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen/Sources/QuickReplySetupScreen.swift b/submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen/Sources/QuickReplySetupScreen.swift index 4f50681179..8dceebcb26 100644 --- a/submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen/Sources/QuickReplySetupScreen.swift +++ b/submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen/Sources/QuickReplySetupScreen.swift @@ -1020,6 +1020,7 @@ final class QuickReplySetupScreenComponent: Component { let searchBarTheme = SearchBarNodeTheme(theme: environment.theme, hasSeparator: false) searchBarNode = SearchBarNode( theme: searchBarTheme, + presentationTheme: environment.theme, strings: environment.strings, fieldStyle: .modern, displayBackground: false diff --git a/submodules/TelegramUI/Components/Settings/PeerSelectionScreen/Sources/PeerSelectionScreen.swift b/submodules/TelegramUI/Components/Settings/PeerSelectionScreen/Sources/PeerSelectionScreen.swift index d6e6aa77fe..fa1afbf7d6 100644 --- a/submodules/TelegramUI/Components/Settings/PeerSelectionScreen/Sources/PeerSelectionScreen.swift +++ b/submodules/TelegramUI/Components/Settings/PeerSelectionScreen/Sources/PeerSelectionScreen.swift @@ -478,6 +478,7 @@ final class PeerSelectionScreenComponent: Component { let searchBarTheme = SearchBarNodeTheme(theme: environment.theme, hasSeparator: false) searchBarNode = SearchBarNode( theme: searchBarTheme, + presentationTheme: environment.theme, strings: environment.strings, fieldStyle: .modern, displayBackground: false diff --git a/submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift b/submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift index 1396f9babb..5a03f510eb 100644 --- a/submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift +++ b/submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift @@ -206,6 +206,7 @@ public final class NavigationSearchView: UIView { accent: params.theme.chat.inputPanel.panelControlAccentColor, keyboard: params.theme.rootController.keyboardColor ), + presentationTheme: params.theme, strings: params.strings, fieldStyle: .inlineNavigation, icon: .loupe, diff --git a/submodules/TelegramUI/Sources/ContactSelectionController.swift b/submodules/TelegramUI/Sources/ContactSelectionController.swift index 4a2cca1f72..f8c979464d 100644 --- a/submodules/TelegramUI/Sources/ContactSelectionController.swift +++ b/submodules/TelegramUI/Sources/ContactSelectionController.swift @@ -573,7 +573,7 @@ final class ContactsSearchNavigationContentNode: NavigationBarContentNode { init(presentationData: PresentationData, dismissSearch: @escaping () -> Void, updateSearchQuery: @escaping (String) -> Void) { self.presentationData = presentationData - self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: presentationData.theme, hasSeparator: false), strings: presentationData.strings, fieldStyle: .modern) + self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: presentationData.theme, hasSeparator: false), presentationTheme: presentationData.theme, strings: presentationData.strings, fieldStyle: .modern) self.searchBar.placeholderString = NSAttributedString(string: presentationData.strings.Common_Search, font: searchBarFont, textColor: presentationData.theme.rootController.navigationSearchBar.inputPlaceholderTextColor) super.init() @@ -617,7 +617,7 @@ final class ContactsSearchNavigationContentNode: NavigationBarContentNode { func updatePresentationData(_ presentationData: PresentationData) { self.presentationData = presentationData - self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: presentationData.theme, hasSeparator: false), strings: presentationData.strings) + self.searchBar.updateThemeAndStrings(theme: SearchBarNodeTheme(theme: presentationData.theme, hasSeparator: false), presentationTheme: presentationData.theme, strings: presentationData.strings) } } diff --git a/submodules/WebSearchUI/Sources/WebSearchNavigationContentNode.swift b/submodules/WebSearchUI/Sources/WebSearchNavigationContentNode.swift index 16649aa33e..e1316cd736 100644 --- a/submodules/WebSearchUI/Sources/WebSearchNavigationContentNode.swift +++ b/submodules/WebSearchUI/Sources/WebSearchNavigationContentNode.swift @@ -22,7 +22,7 @@ final class WebSearchNavigationContentNode: NavigationBarContentNode { self.theme = theme self.strings = strings - self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme, hasSeparator: false), strings: strings, fieldStyle: .modern, displayBackground: !attachment) + self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme, hasSeparator: false), presentationTheme: theme, strings: strings, fieldStyle: .modern, displayBackground: !attachment) self.searchBar.hasCancelButton = attachment self.searchBar.placeholderString = NSAttributedString(string: attachment ? strings.Attachment_SearchWeb : strings.Common_Search, font: searchBarFont, textColor: theme.rootController.navigationSearchBar.inputPlaceholderTextColor)