UI bug fixes

This commit is contained in:
Ali 2021-05-15 01:20:26 +04:00
parent 6854173dae
commit 918b069431
134 changed files with 4372 additions and 3913 deletions

View File

@ -6468,3 +6468,5 @@ Sorry for the inconvenience.";
"VoiceChat.TapToViewCameraVideo" = "Tap to view camera video";
"VoiceChat.TapToViewScreenVideo" = "Tap to view screen sharing";
"WallpaperPreview.WallpaperColors" = "Colors";

View File

@ -30,7 +30,7 @@ public final class AuthDataTransferSplashScreen: ViewController {
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
let defaultTheme = NavigationBarTheme(rootControllerTheme: self.presentationData.theme)
let navigationBarTheme = NavigationBarTheme(buttonColor: defaultTheme.buttonColor, disabledButtonColor: defaultTheme.disabledButtonColor, primaryTextColor: defaultTheme.primaryTextColor, backgroundColor: .clear, separatorColor: .clear, badgeBackgroundColor: defaultTheme.badgeBackgroundColor, badgeStrokeColor: defaultTheme.badgeStrokeColor, badgeTextColor: defaultTheme.badgeTextColor)
let navigationBarTheme = NavigationBarTheme(buttonColor: defaultTheme.buttonColor, disabledButtonColor: defaultTheme.disabledButtonColor, primaryTextColor: defaultTheme.primaryTextColor, backgroundColor: .clear, enableBackgroundBlur: false, separatorColor: .clear, badgeBackgroundColor: defaultTheme.badgeBackgroundColor, badgeStrokeColor: defaultTheme.badgeStrokeColor, badgeTextColor: defaultTheme.badgeTextColor)
super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: navigationBarTheme, strings: NavigationBarStrings(back: self.presentationData.strings.Common_Back, close: self.presentationData.strings.Common_Close)))
@ -80,7 +80,7 @@ public final class AuthDataTransferSplashScreen: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
(self.displayNode as! AuthDataTransferSplashScreenNode).containerLayoutUpdated(layout: layout, navigationHeight: self.navigationHeight, transition: transition)
(self.displayNode as! AuthDataTransferSplashScreenNode).containerLayoutUpdated(layout: layout, navigationHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -90,7 +90,7 @@ public final class AuthTransferScanScreen: ViewController {
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
let navigationBarTheme = NavigationBarTheme(buttonColor: .white, disabledButtonColor: .white, primaryTextColor: .white, backgroundColor: .clear, separatorColor: .clear, badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear)
let navigationBarTheme = NavigationBarTheme(buttonColor: .white, disabledButtonColor: .white, primaryTextColor: .white, backgroundColor: .clear, enableBackgroundBlur: false, separatorColor: .clear, badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear)
super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: navigationBarTheme, strings: NavigationBarStrings(back: self.presentationData.strings.Common_Back, close: self.presentationData.strings.Common_Close)))
@ -205,7 +205,7 @@ public final class AuthTransferScanScreen: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
(self.displayNode as! AuthTransferScanScreenNode).containerLayoutUpdated(layout: layout, navigationHeight: self.navigationHeight, transition: transition)
(self.displayNode as! AuthTransferScanScreenNode).containerLayoutUpdated(layout: layout, navigationHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -115,11 +115,7 @@ public final class BotCheckoutController: ViewController {
}
override public func loadDisplayNode() {
let displayNode = BotCheckoutControllerNode(controller: self, navigationBar: self.navigationBar!, updateNavigationOffset: { [weak self] offset in
if let strongSelf = self {
strongSelf.navigationOffset = offset
}
}, context: self.context, invoice: self.invoice, messageId: self.messageId, inputData: self.inputData, present: { [weak self] c, a in
let displayNode = BotCheckoutControllerNode(controller: self, navigationBar: self.navigationBar!, context: self.context, invoice: self.invoice, messageId: self.messageId, inputData: self.inputData, present: { [weak self] c, a in
self?.present(c, in: .window(.root), with: a)
}, dismissAnimated: { [weak self] in
self?.dismiss()
@ -150,7 +146,7 @@ public final class BotCheckoutController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition, additionalInsets: UIEdgeInsets())
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition, additionalInsets: UIEdgeInsets())
}
@objc private func cancelPressed() {

View File

@ -538,7 +538,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
private var passwordTip: String?
private var passwordTipDisposable: Disposable?
init(controller: BotCheckoutController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContext, invoice: TelegramMediaInvoice, messageId: MessageId, inputData: Promise<BotCheckoutController.InputData?>, present: @escaping (ViewController, Any?) -> Void, dismissAnimated: @escaping () -> Void, completed: @escaping (String, MessageId?) -> Void) {
init(controller: BotCheckoutController?, navigationBar: NavigationBar, context: AccountContext, invoice: TelegramMediaInvoice, messageId: MessageId, inputData: Promise<BotCheckoutController.InputData?>, present: @escaping (ViewController, Any?) -> Void, dismissAnimated: @escaping () -> Void, completed: @escaping (String, MessageId?) -> Void) {
self.controller = controller
self.context = context
self.messageId = messageId
@ -598,7 +598,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
self.inProgressDimNode.isUserInteractionEnabled = false
self.inProgressDimNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor.withAlphaComponent(0.5)
super.init(controller: nil, navigationBar: navigationBar, updateNavigationOffset: updateNavigationOffset, state: signal)
super.init(controller: nil, navigationBar: navigationBar, state: signal)
self.arguments = arguments

View File

@ -144,7 +144,7 @@ final class BotCheckoutInfoController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc func cancelPressed() {

View File

@ -142,7 +142,7 @@ final class BotCheckoutNativeCardEntryController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc func cancelPressed() {

View File

@ -75,7 +75,7 @@ final class BotCheckoutWebInteractionController: ViewController {
override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
override var presentationController: UIPresentationController? {

View File

@ -48,11 +48,7 @@ public final class BotReceiptController: ViewController {
}
override public func loadDisplayNode() {
let displayNode = BotReceiptControllerNode(controller: nil, navigationBar: self.navigationBar!, updateNavigationOffset: { [weak self] offset in
if let strongSelf = self {
strongSelf.navigationOffset = offset
}
}, context: self.context, messageId: self.messageId, dismissAnimated: { [weak self] in
let displayNode = BotReceiptControllerNode(controller: nil, navigationBar: self.navigationBar!, context: self.context, messageId: self.messageId, dismissAnimated: { [weak self] in
self?.dismiss()
})
@ -79,7 +75,7 @@ public final class BotReceiptController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition, additionalInsets: UIEdgeInsets())
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition, additionalInsets: UIEdgeInsets())
}
@objc private func cancelPressed() {

View File

@ -280,7 +280,7 @@ final class BotReceiptControllerNode: ItemListControllerNode {
private let actionButtonPanelSeparator: ASDisplayNode
private let actionButton: BotCheckoutActionButton
init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContext, messageId: MessageId, dismissAnimated: @escaping () -> Void) {
init(controller: ItemListController?, navigationBar: NavigationBar, context: AccountContext, messageId: MessageId, dismissAnimated: @escaping () -> Void) {
self.context = context
self.dismissAnimated = dismissAnimated
@ -304,7 +304,7 @@ final class BotReceiptControllerNode: ItemListControllerNode {
self.actionButton = BotCheckoutActionButton(activeFillColor: self.presentationData.theme.list.itemAccentColor, foregroundColor: self.presentationData.theme.list.plainBackgroundColor)
self.actionButton.setState(.active(self.presentationData.strings.Common_Done))
super.init(controller: controller, navigationBar: navigationBar, updateNavigationOffset: updateNavigationOffset, state: signal)
super.init(controller: controller, navigationBar: navigationBar, state: signal)
self.dataRequestDisposable = (context.engine.payments.requestBotPaymentReceipt(messageId: messageId) |> deliverOnMainQueue).start(next: { [weak self] receipt in
if let strongSelf = self {

View File

@ -273,7 +273,7 @@ public final class CallListController: TelegramBaseController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc func callPressed() {

View File

@ -814,7 +814,7 @@ public final class ChatImportActivityScreen: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
private func beginImport() {

View File

@ -1134,7 +1134,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return
}
let count = ChatControllerCount.with({ $0 })
if count != 0 {
if count > 1 {
strongSelf.present(textAlertController(context: strongSelf.context, title: "", text: "ChatControllerCount \(count)", actions: [TextAlertAction(type: .defaultAction, title: "OK", action: {})]), in: .window(.root))
}
})
@ -1400,8 +1400,10 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
tabContainerOffset += layout.statusBarHeight ?? 0.0
tabContainerOffset += 44.0 + 20.0
}
let navigationBarHeight = self.navigationBar?.frame.maxY ?? 0.0
transition.updateFrame(node: self.tabContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: self.visualNavigationInsetHeight - self.additionalHeight - 46.0 + tabContainerOffset), size: CGSize(width: layout.size.width, height: 46.0)))
transition.updateFrame(node: self.tabContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: navigationBarHeight - self.additionalNavigationBarHeight - 46.0 + tabContainerOffset), size: CGSize(width: layout.size.width, height: 46.0)))
self.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || (self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !self.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .animated(duration: 0.4, curve: .spring))
if let tabContainerData = self.tabContainerData {
self.chatListDisplayNode.inlineTabContainerNode.isHidden = !tabContainerData.1 || tabContainerData.0.count <= 1
@ -1410,7 +1412,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
self.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || (self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !self.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .animated(duration: 0.4, curve: .spring))
self.chatListDisplayNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationInsetHeight, visualNavigationHeight: self.visualNavigationInsetHeight, cleanNavigationBarHeight: self.cleanNavigationHeight, transition: transition)
self.chatListDisplayNode.containerLayoutUpdated(layout, navigationBarHeight: self.cleanNavigationHeight, visualNavigationHeight: navigationBarHeight, cleanNavigationBarHeight: self.cleanNavigationHeight, transition: transition)
}
override public func navigationStackConfigurationUpdated(next: [ViewController]) {

View File

@ -515,7 +515,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
let header = ChatListSearchItemHeader(type: .messages, theme: presentationData.theme, strings: presentationData.strings, actionTitle: nil, action: nil)
let selection: ChatHistoryMessageSelection = selected.flatMap { .selectable(selected: $0) } ?? .none
if let tagMask = tagMask, tagMask != .photoOrVideo {
return ListMessageItem(presentationData: ChatPresentationData(theme: ChatPresentationThemeData(theme: presentationData.theme, wallpaper: .builtin(WallpaperSettings())), fontSize: presentationData.fontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: presentationData.disableAnimations, largeEmoji: false, chatBubbleCorners: PresentationChatBubbleCorners(mainRadius: 0.0, auxiliaryRadius: 0.0, mergeBubbleCorners: false)), context: context, chatLocation: .peer(peer.peerId), interaction: listInteraction, message: message, selection: selection, displayHeader: enableHeaders && !displayCustomHeader, customHeader: nil, hintIsLink: tagMask == .webPage, isGlobalSearchResult: true)
return ListMessageItem(presentationData: ChatPresentationData(theme: ChatPresentationThemeData(theme: presentationData.theme, wallpaper: .builtin(nil, WallpaperSettings())), fontSize: presentationData.fontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: presentationData.disableAnimations, largeEmoji: false, chatBubbleCorners: PresentationChatBubbleCorners(mainRadius: 0.0, auxiliaryRadius: 0.0, mergeBubbleCorners: false)), context: context, chatLocation: .peer(peer.peerId), interaction: listInteraction, message: message, selection: selection, displayHeader: enableHeaders && !displayCustomHeader, customHeader: nil, hintIsLink: tagMask == .webPage, isGlobalSearchResult: true)
} else {
return ChatListItem(presentationData: presentationData, context: context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: message.index), content: .peer(messages: [message], peer: peer, combinedReadState: readState, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(), embeddedState: nil, inputActivities: nil, promoInfo: nil, ignoreUnreadBadge: true, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: tagMask == nil ? header : nil, enableContextActions: false, hiddenOffset: false, interaction: interaction)
}

View File

@ -419,7 +419,7 @@ public class ContactsController: ViewController {
self.validLayout = layout
self.contactsNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationInsetHeight, actualNavigationBarHeight: self.navigationHeight, transition: transition)
self.contactsNode.containerLayoutUpdated(layout, navigationBarHeight: self.cleanNavigationHeight, actualNavigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
private func activateSearch() {

View File

@ -199,7 +199,7 @@ public class InviteContactsController: ViewController, MFMessageComposeViewContr
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.contactsNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationInsetHeight, actualNavigationBarHeight: self.navigationHeight, transition: transition)
self.contactsNode.containerLayoutUpdated(layout, navigationBarHeight: self.cleanNavigationHeight, actualNavigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
private func activateSearch() {

View File

@ -339,7 +339,7 @@ public final class AuthorizationSequenceCountrySelectionController: ViewControll
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
private func cancelPressed() {

View File

@ -122,7 +122,7 @@ open class LegacyPresentedController: ViewController {
override open func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
override open func dismiss(completion: (() -> Void)? = nil) {

View File

@ -5,8 +5,8 @@ private let titleFont = Font.with(size: 17.0, design: .regular, weight: .semibol
private var backArrowImageCache: [Int32: UIImage] = [:]
class SparseNode: ASDisplayNode {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
public final class SparseNode: ASDisplayNode {
override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let result = super.hitTest(point, with: event)
if result != self.view {
return result
@ -32,16 +32,18 @@ public final class NavigationBarTheme {
public let disabledButtonColor: UIColor
public let primaryTextColor: UIColor
public let backgroundColor: UIColor
public let enableBackgroundBlur: Bool
public let separatorColor: UIColor
public let badgeBackgroundColor: UIColor
public let badgeStrokeColor: UIColor
public let badgeTextColor: UIColor
public init(buttonColor: UIColor, disabledButtonColor: UIColor, primaryTextColor: UIColor, backgroundColor: UIColor, separatorColor: UIColor, badgeBackgroundColor: UIColor, badgeStrokeColor: UIColor, badgeTextColor: UIColor) {
public init(buttonColor: UIColor, disabledButtonColor: UIColor, primaryTextColor: UIColor, backgroundColor: UIColor, enableBackgroundBlur: Bool, separatorColor: UIColor, badgeBackgroundColor: UIColor, badgeStrokeColor: UIColor, badgeTextColor: UIColor) {
self.buttonColor = buttonColor
self.disabledButtonColor = disabledButtonColor
self.primaryTextColor = primaryTextColor
self.backgroundColor = backgroundColor
self.enableBackgroundBlur = enableBackgroundBlur
self.separatorColor = separatorColor
self.badgeBackgroundColor = badgeBackgroundColor
self.badgeStrokeColor = badgeStrokeColor
@ -49,7 +51,7 @@ public final class NavigationBarTheme {
}
public func withUpdatedSeparatorColor(_ color: UIColor) -> NavigationBarTheme {
return NavigationBarTheme(buttonColor: self.buttonColor, disabledButtonColor: self.disabledButtonColor, primaryTextColor: self.primaryTextColor, backgroundColor: self.backgroundColor, separatorColor: color, badgeBackgroundColor: self.badgeBackgroundColor, badgeStrokeColor: self.badgeStrokeColor, badgeTextColor: self.badgeTextColor)
return NavigationBarTheme(buttonColor: self.buttonColor, disabledButtonColor: self.disabledButtonColor, primaryTextColor: self.primaryTextColor, backgroundColor: self.backgroundColor, enableBackgroundBlur: self.enableBackgroundBlur, separatorColor: color, badgeBackgroundColor: self.badgeBackgroundColor, badgeStrokeColor: self.badgeStrokeColor, badgeTextColor: self.badgeTextColor)
}
}
@ -116,63 +118,73 @@ enum NavigationPreviousAction: Equatable {
}
public final class NavigationBackgroundNode: ASDisplayNode {
private var _color: UIColor
public var color: UIColor {
didSet {
if !self.color.isEqual(oldValue) {
self.backgroundNode.backgroundColor = self.color
self.updateBackgroundBlur()
}
get {
return self._color
} set(value) {
self.updateColor(color: value, transition: .immediate)
}
}
private let enableBlur: Bool
private var effectView: UIVisualEffectView?
private let backgroundNode: ASDisplayNode
public init(color: UIColor) {
self.color = color
public init(color: UIColor, enableBlur: Bool = true) {
self._color = .clear
self.enableBlur = enableBlur
self.backgroundNode = ASDisplayNode()
self.backgroundNode.backgroundColor = self.color
super.init()
self.addSubnode(self.backgroundNode)
self.updateBackgroundBlur()
self.updateColor(color: color, transition: .immediate)
}
private func updateBackgroundBlur() {
if self.color.alpha > 0.1 && self.color.alpha < 0.95 {
self.effectView?.removeFromSuperview()
self.effectView = nil
if self.color.lightness > 0.6 {
if #available(iOS 13.0, *) {
self.effectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterialLight))
private func updateBackgroundBlur(forceKeepBlur: Bool) {
if self.enableBlur && ((self.color.alpha > 0.1 && self.color.alpha < 0.95) || forceKeepBlur) {
if self.effectView == nil {
let effectView: UIVisualEffectView
if self.color.lightness > 0.6 {
effectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
} else {
self.effectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
effectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
}
for subview in effectView.subviews {
if subview.description.contains("_UIVisualEffectSubview") {
subview.isHidden = true
}
}
} else {
if #available(iOS 13.0, *) {
self.effectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterialDark))
} else {
self.effectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
}
}
if let effectView = self.effectView {
if let sublayer = effectView.layer.sublayers?[0], let filters = sublayer.filters {
let allowedKeys: [String] = [
"colorSaturate",
"gaussianBlur"
]
sublayer.filters = filters.filter { filter in
guard let filter = filter as? NSObject else {
return true
}
if String(describing: filter) != "gaussianBlur" {
let filterName = String(describing: filter)
if !allowedKeys.contains(filterName) {
return false
}
/*if filterName == "colorSaturate" {
filter.setValue(2.8 as NSNumber, forKey: "inputAmount")
} else if filterName == "gaussianBlur" {
filter.setValue(5.0 as NSNumber, forKey: "inputRadius")
}*/
return true
}
}
effectView.frame = self.bounds
self.effectView = effectView
self.view.insertSubview(effectView, at: 0)
}
} else if let effectView = self.effectView {
@ -181,6 +193,17 @@ public final class NavigationBackgroundNode: ASDisplayNode {
}
}
public func updateColor(color: UIColor, forceKeepBlur: Bool = false, transition: ContainedViewLayoutTransition) {
if self._color.isEqual(color) {
return
}
self._color = color
transition.updateBackgroundColor(node: self.backgroundNode, color: self.color)
self.updateBackgroundBlur(forceKeepBlur: forceKeepBlur)
}
public func update(size: CGSize, transition: ContainedViewLayoutTransition) {
let contentFrame = CGRect(origin: CGPoint(), size: size)
transition.updateFrame(node: self.backgroundNode, frame: contentFrame)
@ -202,7 +225,7 @@ open class NavigationBar: ASDisplayNode {
var presentationData: NavigationBarPresentationData
private var validLayout: (CGSize, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, Bool)?
private var validLayout: (size: CGSize, defaultHeight: CGFloat, additionalTopHeight: CGFloat, additionalContentHeight: CGFloat, additionalBackgroundHeight: CGFloat, leftInset: CGFloat, rightInset: CGFloat, appearsHidden: Bool)?
private var requestedLayout: Bool = false
var requestContainerLayout: (ContainedViewLayoutTransition) -> Void = { _ in }
@ -389,40 +412,6 @@ open class NavigationBar: ASDisplayNode {
var previousItemBackListenerKey: Int?
private func updateAccessibilityElements() {
/*if !self.isNodeLoaded {
return
}
var accessibilityElements: [AnyObject] = []
if self.leftButtonNode.supernode != nil {
accessibilityElements.append(self.leftButtonNode)
}
if self.titleNode.supernode != nil {
accessibilityElements.append(self.titleNode)
}
if let titleView = self.titleView, titleView.superview != nil {
accessibilityElements.append(titleView)
}
if self.rightButtonNode.supernode != nil {
accessibilityElements.append(self.rightButtonNode)
}
var updated = false
if let currentAccessibilityElements = self.accessibilityElements {
if currentAccessibilityElements.count != accessibilityElements.count {
updated = true
} else {
for i in 0 ..< accessibilityElements.count {
let element = currentAccessibilityElements[i] as AnyObject
if element !== accessibilityElements[i] {
updated = true
}
}
}
}
if updated {
self.accessibilityElements = accessibilityElements
}*/
}
override open var accessibilityElements: [Any]? {
@ -716,12 +705,19 @@ open class NavigationBar: ASDisplayNode {
self.updateAccessibilityElements()
}
private let backgroundNode: NavigationBackgroundNode
public let backgroundNode: NavigationBackgroundNode
public let backButtonNode: NavigationButtonNode
public let badgeNode: NavigationBarBadgeNode
public let backButtonArrow: ASImageNode
public let leftButtonNode: NavigationButtonNode
public let rightButtonNode: NavigationButtonNode
public let additionalContentNode: SparseNode
public func reattachAdditionalContentNode() {
if self.additionalContentNode.supernode !== self {
self.insertSubnode(self.additionalContentNode, aboveSubnode: self.clippingNode)
}
}
private var _transitionState: NavigationBarTransitionState?
var transitionState: NavigationBarTransitionState? {
@ -833,12 +829,14 @@ open class NavigationBar: ASDisplayNode {
self.stripeNode.backgroundColor = self.presentationData.theme.separatorColor
self.backgroundNode = NavigationBackgroundNode(color: self.presentationData.theme.backgroundColor)
self.additionalContentNode = SparseNode()
super.init()
self.addSubnode(self.backgroundNode)
self.addSubnode(self.buttonsContainerNode)
self.addSubnode(self.clippingNode)
self.addSubnode(self.additionalContentNode)
self.backgroundColor = nil
self.isOpaque = false
@ -928,16 +926,16 @@ open class NavigationBar: ASDisplayNode {
if let validLayout = self.validLayout, self.requestedLayout {
self.requestedLayout = false
self.updateLayout(size: validLayout.0, defaultHeight: validLayout.1, additionalHeight: validLayout.2, additionalBackgroundHeight: validLayout.3, leftInset: validLayout.4, rightInset: validLayout.5, appearsHidden: validLayout.6, transition: .immediate)
self.updateLayout(size: validLayout.size, defaultHeight: validLayout.defaultHeight, additionalTopHeight: validLayout.additionalTopHeight, additionalContentHeight: validLayout.additionalContentHeight, additionalBackgroundHeight: validLayout.additionalBackgroundHeight, leftInset: validLayout.leftInset, rightInset: validLayout.rightInset, appearsHidden: validLayout.appearsHidden, transition: .immediate)
}
}
func updateLayout(size: CGSize, defaultHeight: CGFloat, additionalHeight: CGFloat, additionalBackgroundHeight: CGFloat, leftInset: CGFloat, rightInset: CGFloat, appearsHidden: Bool, transition: ContainedViewLayoutTransition) {
func updateLayout(size: CGSize, defaultHeight: CGFloat, additionalTopHeight: CGFloat, additionalContentHeight: CGFloat, additionalBackgroundHeight: CGFloat, leftInset: CGFloat, rightInset: CGFloat, appearsHidden: Bool, transition: ContainedViewLayoutTransition) {
if self.layoutSuspended {
return
}
self.validLayout = (size, defaultHeight, additionalHeight, additionalBackgroundHeight, leftInset, rightInset, appearsHidden)
self.validLayout = (size, defaultHeight, additionalTopHeight, additionalContentHeight, additionalBackgroundHeight, leftInset, rightInset, appearsHidden)
let backgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: size.height + additionalBackgroundHeight))
if self.backgroundNode.frame != backgroundFrame {
@ -951,6 +949,7 @@ open class NavigationBar: ASDisplayNode {
let backButtonInset: CGFloat = leftInset + 27.0
transition.updateFrame(node: self.clippingNode, frame: CGRect(origin: CGPoint(), size: size))
transition.updateFrame(node: self.additionalContentNode, frame: CGRect(origin: CGPoint(), size: size))
transition.updateFrame(node: self.buttonsContainerNode, frame: CGRect(origin: CGPoint(), size: size))
var expansionHeight: CGFloat = 0.0
if let contentNode = self.contentNode {
@ -958,12 +957,12 @@ open class NavigationBar: ASDisplayNode {
switch contentNode.mode {
case .replacement:
expansionHeight = contentNode.height - defaultHeight
contentNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height))
contentNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height - additionalContentHeight))
case .expansion:
expansionHeight = contentNode.height
let additionalExpansionHeight: CGFloat = self.secondaryContentNode != nil && appearsHidden ? NavigationBar.defaultSecondaryContentHeight : 0.0
contentNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: size.height - expansionHeight - apparentAdditionalHeight - additionalExpansionHeight), size: CGSize(width: size.width, height: expansionHeight))
contentNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: size.height - additionalContentHeight - expansionHeight - apparentAdditionalHeight - additionalExpansionHeight), size: CGSize(width: size.width, height: expansionHeight))
if appearsHidden {
if self.secondaryContentNode != nil {
contentNodeFrame.origin.y += NavigationBar.defaultSecondaryContentHeight
@ -974,10 +973,10 @@ open class NavigationBar: ASDisplayNode {
contentNode.updateLayout(size: contentNodeFrame.size, leftInset: leftInset, rightInset: rightInset, transition: transition)
}
transition.updateFrame(node: self.stripeNode, frame: CGRect(x: 0.0, y: size.height, width: size.width, height: UIScreenPixel))
transition.updateFrame(node: self.stripeNode, frame: CGRect(x: 0.0, y: size.height + additionalBackgroundHeight, width: size.width, height: UIScreenPixel))
let nominalHeight: CGFloat = defaultHeight - additionalHeight
let contentVerticalOrigin = size.height - nominalHeight - expansionHeight - additionalHeight - apparentAdditionalHeight
let nominalHeight: CGFloat = defaultHeight
let contentVerticalOrigin = additionalTopHeight
var leftTitleInset: CGFloat = leftInset + 1.0
var rightTitleInset: CGFloat = rightInset + 1.0
@ -1184,8 +1183,8 @@ open class NavigationBar: ASDisplayNode {
let node = NavigationButtonNode()
node.updateManualText(self.backButtonNode.manualText)
node.color = accentColor
if let (size, defaultHeight, _, _, _, _, _) = self.validLayout {
let _ = node.updateLayout(constrainedSize: CGSize(width: size.width, height: defaultHeight))
if let validLayout = self.validLayout {
let _ = node.updateLayout(constrainedSize: CGSize(width: validLayout.size.width, height: validLayout.defaultHeight))
node.frame = self.backButtonNode.frame
}
return node
@ -1207,8 +1206,8 @@ open class NavigationBar: ASDisplayNode {
}
node.updateItems(items)
node.color = accentColor
if let (size, defaultHeight, _, _, _, _, _) = self.validLayout {
let _ = node.updateLayout(constrainedSize: CGSize(width: size.width, height: defaultHeight))
if let validLayout = self.validLayout {
let _ = node.updateLayout(constrainedSize: CGSize(width: validLayout.size.width, height: validLayout.defaultHeight))
node.frame = self.backButtonNode.frame
}
return node

View File

@ -12,7 +12,6 @@ final class TabBarControllerNode: ASDisplayNode {
private var theme: TabBarControllerTheme
let tabBarNode: TabBarNode
private let disabledOverlayNode: ASDisplayNode
private let navigationBar: NavigationBar?
private var toolbarNode: ToolbarNode?
private let toolbarActionSelected: (ToolbarActionOption) -> Void
private let disabledPressed: () -> Void
@ -27,9 +26,8 @@ final class TabBarControllerNode: ASDisplayNode {
}
}
init(theme: TabBarControllerTheme, navigationBar: NavigationBar?, itemSelected: @escaping (Int, Bool, [ASDisplayNode]) -> Void, contextAction: @escaping (Int, ContextExtractedContentContainingNode, ContextGesture) -> Void, swipeAction: @escaping (Int, TabBarItemSwipeDirection) -> Void, toolbarActionSelected: @escaping (ToolbarActionOption) -> Void, disabledPressed: @escaping () -> Void) {
init(theme: TabBarControllerTheme, itemSelected: @escaping (Int, Bool, [ASDisplayNode]) -> Void, contextAction: @escaping (Int, ContextExtractedContentContainingNode, ContextGesture) -> Void, swipeAction: @escaping (Int, TabBarItemSwipeDirection) -> Void, toolbarActionSelected: @escaping (ToolbarActionOption) -> Void, disabledPressed: @escaping () -> Void) {
self.theme = theme
self.navigationBar = navigationBar
self.tabBarNode = TabBarNode(theme: theme, itemSelected: itemSelected, contextAction: contextAction, swipeAction: swipeAction)
self.disabledOverlayNode = ASDisplayNode()
self.disabledOverlayNode.backgroundColor = theme.backgroundColor.withAlphaComponent(0.5)

View File

@ -87,7 +87,6 @@ open class TabBarController: ViewController {
}
}
public private(set) var controllers: [ViewController] = []
private let _ready = Promise<Bool>()
@ -115,14 +114,6 @@ open class TabBarController: ViewController {
var currentController: ViewController?
open override var navigationBarRequiresEntireLayoutUpdate: Bool {
if let currentController = currentController {
return currentController.navigationBarRequiresEntireLayoutUpdate
} else {
return false
}
}
private let pendingControllerDisposable = MetaDisposable()
private var theme: TabBarControllerTheme
@ -130,7 +121,7 @@ open class TabBarController: ViewController {
public init(navigationBarPresentationData: NavigationBarPresentationData, theme: TabBarControllerTheme) {
self.theme = theme
super.init(navigationBarPresentationData: navigationBarPresentationData)
super.init(navigationBarPresentationData: nil)
self.scrollToTop = { [weak self] in
guard let strongSelf = self else {
@ -151,7 +142,6 @@ open class TabBarController: ViewController {
}
public func updateTheme(navigationBarPresentationData: NavigationBarPresentationData, theme: TabBarControllerTheme) {
self.navigationBar?.updatePresentationData(navigationBarPresentationData)
if self.theme !== theme {
self.theme = theme
if self.isNodeLoaded {
@ -193,7 +183,7 @@ open class TabBarController: ViewController {
}
override open func loadDisplayNode() {
self.displayNode = TabBarControllerNode(theme: self.theme, navigationBar: self.navigationBar, itemSelected: { [weak self] index, longTap, itemNodes in
self.displayNode = TabBarControllerNode(theme: self.theme, itemSelected: { [weak self] index, longTap, itemNodes in
if let strongSelf = self {
if longTap, let controller = strongSelf.controllers[index] as? TabBarContainedController {
controller.presentTabBarPreviewingController(sourceNodes: itemNodes)
@ -302,37 +292,16 @@ open class TabBarController: ViewController {
if let _selectedIndex = self._selectedIndex, _selectedIndex < self.controllers.count {
self.currentController = self.controllers[_selectedIndex]
}
var displayNavigationBar = false
if let currentController = self.currentController {
currentController.willMove(toParent: self)
self.tabBarControllerNode.currentControllerNode = currentController.displayNode
currentController.navigationBar?.isHidden = true
self.addChild(currentController)
currentController.didMove(toParent: self)
currentController.navigationBar?.layoutSuspended = true
currentController.navigationItem.setTarget(self.navigationItem)
displayNavigationBar = currentController.displayNavigationBar
self.navigationBar?.setContentNode(currentController.navigationBar?.contentNode, animated: false)
self.navigationBar?.setSecondaryContentNode(currentController.navigationBar?.secondaryContentNode)
currentController.displayNode.recursivelyEnsureDisplaySynchronously(true)
self.statusBar.statusBarStyle = currentController.statusBar.statusBarStyle
if let navigationBarPresentationData = currentController.navigationBar?.presentationData {
self.navigationBar?.updatePresentationData(navigationBarPresentationData)
}
} else {
self.navigationItem.title = nil
self.navigationItem.leftBarButtonItem = nil
self.navigationItem.rightBarButtonItem = nil
self.navigationItem.titleView = nil
self.navigationItem.backBarButtonItem = nil
self.navigationBar?.setContentNode(nil, animated: false)
self.navigationBar?.setSecondaryContentNode(nil)
displayNavigationBar = false
}
if self.displayNavigationBar != displayNavigationBar {
self.setDisplayNavigationBar(displayNavigationBar)
}
if let layout = self.validLayout {

View File

@ -74,6 +74,16 @@ public enum TabBarItemContextActionType {
}
@objc open class ViewController: UIViewController, ContainableController {
public struct NavigationLayout {
public var navigationFrame: CGRect
public var defaultContentHeight: CGFloat
public init(navigationFrame: CGRect, defaultContentHeight: CGFloat) {
self.navigationFrame = navigationFrame
self.defaultContentHeight = defaultContentHeight
}
}
private var validLayout: ContainerViewLayout?
public var currentlyAppliedLayout: ContainerViewLayout? {
return self.validLayout
@ -194,35 +204,28 @@ public enum TabBarItemContextActionType {
open var hasActiveInput: Bool = false
private var navigationBarOrigin: CGFloat = 0.0
public var navigationOffset: CGFloat = 0.0 {
didSet {
if let navigationBar = self.navigationBar {
var navigationBarFrame = navigationBar.frame
navigationBarFrame.origin.y = self.navigationBarOrigin + self.navigationOffset
navigationBar.frame = navigationBarFrame
}
}
}
open var navigationHeight: CGFloat {
if let navigationBar = self.navigationBar {
return navigationBar.frame.maxY
open func navigationLayout(layout: ContainerViewLayout) -> NavigationLayout {
let statusBarHeight: CGFloat = layout.statusBarHeight ?? 0.0
var defaultNavigationBarHeight: CGFloat
if self._presentedInModal {
defaultNavigationBarHeight = 56.0
} else {
return 0.0
defaultNavigationBarHeight = 44.0
}
}
open var navigationInsetHeight: CGFloat {
if let navigationBar = self.navigationBar {
var height = navigationBar.frame.maxY
if let contentNode = navigationBar.contentNode, case .expansion = contentNode.mode {
height += contentNode.nominalHeight - contentNode.height
}
return height
} else {
return 0.0
let navigationBarHeight: CGFloat = statusBarHeight + (self.navigationBar?.contentHeight(defaultHeight: defaultNavigationBarHeight) ?? defaultNavigationBarHeight)
var navigationBarFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: navigationBarHeight))
navigationBarFrame.size.height += self.additionalNavigationBarHeight
if !self.displayNavigationBar {
navigationBarFrame.origin.y = -navigationBarFrame.size.height
}
self.navigationBarOrigin = navigationBarFrame.origin.y
return NavigationLayout(navigationFrame: navigationBarFrame, defaultContentHeight: defaultNavigationBarHeight)
}
open var cleanNavigationHeight: CGFloat {
@ -236,21 +239,11 @@ public enum TabBarItemContextActionType {
return 0.0
}
}
open var visualNavigationInsetHeight: CGFloat {
if let navigationBar = self.navigationBar {
let height = navigationBar.frame.maxY
if let contentNode = navigationBar.contentNode, case .expansion = contentNode.mode {
//height += contentNode.height
}
return height
} else {
return 0.0
}
open var additionalNavigationBarHeight: CGFloat {
return 0.0
}
public var additionalNavigationBarHeight: CGFloat = 0.0
public var additionalSideInsets: UIEdgeInsets = UIEdgeInsets()
private let _ready = Promise<Bool>(true)
@ -375,42 +368,31 @@ public enum TabBarItemContextActionType {
}
open func updateNavigationBarLayout(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
self.applyNavigationBarLayout(layout, additionalBackgroundHeight: 0.0, transition: transition)
self.applyNavigationBarLayout(layout, navigationLayout: self.navigationLayout(layout: layout), additionalBackgroundHeight: 0.0, transition: transition)
}
public func applyNavigationBarLayout(_ layout: ContainerViewLayout, additionalBackgroundHeight: CGFloat, transition: ContainedViewLayoutTransition) {
public func applyNavigationBarLayout(_ layout: ContainerViewLayout, navigationLayout: NavigationLayout, additionalBackgroundHeight: CGFloat, transition: ContainedViewLayoutTransition) {
let statusBarHeight: CGFloat = layout.statusBarHeight ?? 0.0
var defaultNavigationBarHeight: CGFloat
if self._presentedInModal {
defaultNavigationBarHeight = 56.0
} else {
defaultNavigationBarHeight = 44.0
}
let navigationBarHeight: CGFloat = statusBarHeight + (self.navigationBar?.contentHeight(defaultHeight: defaultNavigationBarHeight) ?? defaultNavigationBarHeight)
let navigationBarOffset: CGFloat
if statusBarHeight.isZero {
navigationBarOffset = 0.0
} else {
navigationBarOffset = 0.0
}
var navigationBarFrame = CGRect(origin: CGPoint(x: 0.0, y: navigationBarOffset), size: CGSize(width: layout.size.width, height: navigationBarHeight))
var navigationBarFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: navigationLayout.navigationFrame.maxY))
if !self.displayNavigationBar {
navigationBarFrame.origin.y = -navigationBarFrame.size.height
}
self.navigationBarOrigin = navigationBarFrame.origin.y
navigationBarFrame.origin.y += self.navigationOffset
if let navigationBar = self.navigationBar {
if let contentNode = navigationBar.contentNode, case .expansion = contentNode.mode, !self.displayNavigationBar {
navigationBarFrame.origin.y += contentNode.height + statusBarHeight
navigationBarFrame.origin.y -= navigationLayout.defaultContentHeight
navigationBarFrame.size.height += contentNode.height + navigationLayout.defaultContentHeight + statusBarHeight
//navigationBarFrame.origin.y += contentNode.height + statusBarHeight
}
if let _ = navigationBar.contentNode, let _ = navigationBar.secondaryContentNode, !self.displayNavigationBar {
navigationBarFrame.origin.y += NavigationBar.defaultSecondaryContentHeight
navigationBarFrame.size.height += NavigationBar.defaultSecondaryContentHeight
//navigationBarFrame.origin.y += NavigationBar.defaultSecondaryContentHeight
}
navigationBar.updateLayout(size: navigationBarFrame.size, defaultHeight: defaultNavigationBarHeight, additionalHeight: 0.0, additionalBackgroundHeight: additionalBackgroundHeight, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, appearsHidden: !self.displayNavigationBar, transition: transition)
navigationBar.updateLayout(size: navigationBarFrame.size, defaultHeight: navigationLayout.defaultContentHeight, additionalTopHeight: statusBarHeight, additionalContentHeight: self.additionalNavigationBarHeight, additionalBackgroundHeight: additionalBackgroundHeight, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, appearsHidden: !self.displayNavigationBar, transition: transition)
if !transition.isAnimated {
navigationBar.layer.cancelAnimationsRecursive(key: "bounds")
navigationBar.layer.cancelAnimationsRecursive(key: "position")

View File

@ -323,8 +323,8 @@ public struct GalleryConfiguration {
}
public class GalleryController: ViewController, StandalonePresentableController {
public static let darkNavigationTheme = NavigationBarTheme(buttonColor: .white, disabledButtonColor: UIColor(rgb: 0x525252), primaryTextColor: .white, backgroundColor: UIColor(white: 0.0, alpha: 0.6), separatorColor: UIColor(white: 0.0, alpha: 0.8), badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear)
public static let lightNavigationTheme = NavigationBarTheme(buttonColor: UIColor(rgb: 0x007ee5), disabledButtonColor: UIColor(rgb: 0xd0d0d0), primaryTextColor: .black, backgroundColor: UIColor(red: 0.968626451, green: 0.968626451, blue: 0.968626451, alpha: 1.0), separatorColor: UIColor(red: 0.6953125, green: 0.6953125, blue: 0.6953125, alpha: 1.0), badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear)
public static let darkNavigationTheme = NavigationBarTheme(buttonColor: .white, disabledButtonColor: UIColor(rgb: 0x525252), primaryTextColor: .white, backgroundColor: UIColor(white: 0.0, alpha: 0.6), enableBackgroundBlur: false, separatorColor: UIColor(white: 0.0, alpha: 0.8), badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear)
public static let lightNavigationTheme = NavigationBarTheme(buttonColor: UIColor(rgb: 0x007ee5), disabledButtonColor: UIColor(rgb: 0xd0d0d0), primaryTextColor: .black, backgroundColor: UIColor(red: 0.968626451, green: 0.968626451, blue: 0.968626451, alpha: 1.0), enableBackgroundBlur: false, separatorColor: UIColor(red: 0.6953125, green: 0.6953125, blue: 0.6953125, alpha: 1.0), badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear)
private var galleryNode: GalleryControllerNode {
return self.displayNode as! GalleryControllerNode
@ -1291,7 +1291,7 @@ public class GalleryController: ViewController, StandalonePresentableController
super.containerLayoutUpdated(layout, transition: transition)
self.galleryNode.frame = CGRect(origin: CGPoint(), size: layout.size)
self.galleryNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.galleryNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
if !self.adjustedForInitialPreviewingLayout && self.isPresentedInPreviewingContext() {
self.adjustedForInitialPreviewingLayout = true

View File

@ -497,7 +497,7 @@ public final class SecretMediaPreviewController: ViewController {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.frame = CGRect(origin: CGPoint(), size: layout.size)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
override public func dismiss(completion: (() -> Void)? = nil) {

View File

@ -79,7 +79,7 @@ public final class GameController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
override public var presentationController: UIPresentationController? {

View File

@ -4,6 +4,7 @@ import Display
import AsyncDisplayKit
public protocol GradientBackgroundNode: ASDisplayNode {
func updateColors(colors: [UIColor])
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition)
func animateEvent(transition: ContainedViewLayoutTransition)
}

View File

@ -121,10 +121,16 @@ final class SoftwareGradientBackgroundNode: ASDisplayNode, GradientBackgroundNod
private let contentView: UIImageView
private var validPhase: Int?
private var invalidated: Bool = false
private var validLayout: CGSize?
private var timer: Timer?
private var colors: [UIColor] = [
UIColor(rgb: 0x7FA381),
UIColor(rgb: 0xFFF5C5),
UIColor(rgb: 0x336F55),
UIColor(rgb: 0xFBE37D)
]
private struct PhaseTransitionKey: Hashable {
var width: Int
@ -144,73 +150,9 @@ final class SoftwareGradientBackgroundNode: ASDisplayNode, GradientBackgroundNod
self.view.addSubview(self.contentView)
self.phase = 0
self.backgroundColor = .white
/*if #available(iOS 10.0, *) {
let timer = Timer(timeInterval: 1.0, repeats: true, block: { [weak self] _ in
guard let strongSelf = self else {
return
}
strongSelf.phase += 1
if let size = strongSelf.validLayout {
strongSelf.updateLayout(size: size, transition: .animated(duration: 0.5, curve: .spring))
}
})
self.timer = timer
RunLoop.main.add(timer, forMode: .common)
}*/
}
deinit {
self.timer?.invalidate()
}
private func generateAndCachePhaseTransition(key: PhaseTransitionKey) {
DispatchQueue.global().async { [weak self] in
let basePositions: [CGPoint] = [
CGPoint(x: 0.80, y: 0.10),
CGPoint(x: 0.60, y: 0.20),
CGPoint(x: 0.35, y: 0.25),
CGPoint(x: 0.25, y: 0.60),
CGPoint(x: 0.20, y: 0.90),
CGPoint(x: 0.40, y: 0.80),
CGPoint(x: 0.65, y: 0.75),
CGPoint(x: 0.75, y: 0.40)
]
let colors: [UIColor] = [
UIColor(rgb: 0x7FA381),
UIColor(rgb: 0xFFF5C5),
UIColor(rgb: 0x336F55),
UIColor(rgb: 0xFBE37D)
]
var images: [UIImage] = []
let previousPositions = gatherPositions(shiftArray(array: basePositions, offset: key.fromPhase % 8))
let positions = gatherPositions(shiftArray(array: basePositions, offset: key.toPhase % 8))
let startTime = CFAbsoluteTimeGetCurrent()
for i in 0 ..< key.numberOfFrames {
let t = key.curve.solve(at: CGFloat(i) / CGFloat(key.numberOfFrames - 1))
let morphedPositions = Array(zip(previousPositions, positions).map { previous, current -> CGPoint in
return interpolatePoints(previous, current, at: t)
})
images.append(generateGradient(size: CGSize(width: key.width, height: key.height), colors: colors, positions: morphedPositions))
}
print("Animation cached in \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
DispatchQueue.main.async {
guard let strongSelf = self else {
return
}
strongSelf.cachedPhaseTransition.removeAll()
strongSelf.cachedPhaseTransition[key] = images
}
}
}
public func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) {
@ -230,40 +172,27 @@ final class SoftwareGradientBackgroundNode: ASDisplayNode, GradientBackgroundNod
CGPoint(x: 0.75, y: 0.40)
]
let colors: [UIColor] = [
UIColor(rgb: 0x7FA381),
UIColor(rgb: 0xFFF5C5),
UIColor(rgb: 0x336F55),
UIColor(rgb: 0xFBE37D)
]
let positions = gatherPositions(shiftArray(array: basePositions, offset: self.phase % 8))
if let validPhase = self.validPhase {
if validPhase != self.phase {
if validPhase != self.phase || self.invalidated {
self.validPhase = self.phase
self.invalidated = false
let previousPositions = gatherPositions(shiftArray(array: basePositions, offset: validPhase % 8))
if case let .animated(duration, curve) = transition {
var images: [UIImage] = []
let cacheKey = PhaseTransitionKey(width: Int(imageSize.width), height: Int(imageSize.height), fromPhase: validPhase, toPhase: self.phase, numberOfFrames: Int(duration * 60), curve: curve)
if let current = self.cachedPhaseTransition[cacheKey] {
images = current
} else {
let startTime = CFAbsoluteTimeGetCurrent()
let maxFrame = Int(duration * 30)
for i in 0 ..< maxFrame {
let t = curve.solve(at: CGFloat(i) / CGFloat(maxFrame - 1))
let maxFrame = Int(duration * 30)
for i in 0 ..< maxFrame {
let t = curve.solve(at: CGFloat(i) / CGFloat(maxFrame - 1))
let morphedPositions = Array(zip(previousPositions, positions).map { previous, current -> CGPoint in
return interpolatePoints(previous, current, at: t)
})
let morphedPositions = Array(zip(previousPositions, positions).map { previous, current -> CGPoint in
return interpolatePoints(previous, current, at: t)
})
images.append(generateGradient(size: imageSize, colors: colors, positions: morphedPositions))
}
print("Animation generated in \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
images.append(generateGradient(size: imageSize, colors: self.colors, positions: morphedPositions))
}
self.contentView.image = images.last
@ -284,6 +213,14 @@ final class SoftwareGradientBackgroundNode: ASDisplayNode, GradientBackgroundNod
transition.updateFrame(view: self.contentView, frame: CGRect(origin: CGPoint(), size: size))
}
public func updateColors(colors: [UIColor]) {
self.colors = colors
self.invalidated = true
if let size = self.validLayout {
self.updateLayout(size: size, transition: .immediate)
}
}
public func animateEvent(transition: ContainedViewLayoutTransition) {
if self.phase == 0 {
self.phase = 7

View File

@ -126,6 +126,6 @@ public final class HashtagSearchController: TelegramBaseController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -101,7 +101,7 @@ public final class ImportStickerPackController: ViewController, StandalonePresen
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -182,6 +182,6 @@ public final class InstantPageController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -462,6 +462,6 @@ public class InstantPageGalleryController: ViewController, StandalonePresentable
super.containerLayoutUpdated(layout, transition: transition)
self.galleryNode.frame = CGRect(origin: CGPoint(), size: layout.size)
self.galleryNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.galleryNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -74,6 +74,6 @@ final class InstantPageReferenceController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -143,7 +143,7 @@ public final class InviteLinkQRCodeController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
class Node: ViewControllerTracingNode, UIScrollViewDelegate {

View File

@ -444,11 +444,7 @@ open class ItemListController: ViewController, KeyShortcutResponder, Presentable
}
|> map { ($0.presentationData, $1) }
let displayNode = ItemListControllerNode(controller: self, navigationBar: self.navigationBar!, updateNavigationOffset: { [weak self] offset in
if let strongSelf = self {
strongSelf.navigationOffset = offset
}
}, state: nodeState)
let displayNode = ItemListControllerNode(controller: self, navigationBar: self.navigationBar!, state: nodeState)
displayNode.dismiss = { [weak self] in
self?.presentingViewController?.dismiss(animated: true, completion: nil)
}
@ -476,7 +472,7 @@ open class ItemListController: ViewController, KeyShortcutResponder, Presentable
self.validLayout = layout
(self.displayNode as! ItemListControllerNode).containerLayoutUpdated(layout, navigationBarHeight: self.navigationInsetHeight, transition: transition, additionalInsets: self.additionalInsets)
(self.displayNode as! ItemListControllerNode).containerLayoutUpdated(layout, navigationBarHeight: self.cleanNavigationHeight, transition: transition, additionalInsets: self.additionalInsets)
}
@objc func leftNavigationButtonPressed() {

View File

@ -227,7 +227,7 @@ public final class ItemListControllerNodeView: UITracingLayerView {
weak var controller: ItemListController?
}
open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate {
open class ItemListControllerNode: ASDisplayNode {
private var _ready = ValuePromise<Bool>()
open var ready: Signal<Bool, NoError> {
return self._ready.get()
@ -261,8 +261,7 @@ open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate {
private var appliedEnsureVisibleItemTag: ItemListItemTag?
private var afterLayoutActions: [() -> Void] = []
public let updateNavigationOffset: (CGFloat) -> Void
public var dismiss: (() -> Void)?
public var visibleEntriesUpdated: ((ItemListNodeVisibleEntries) -> Void)?
@ -282,9 +281,8 @@ open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate {
var alwaysSynchronous = false
public init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, state: Signal<(ItemListPresentationData, (ItemListNodeState, Any)), NoError>) {
public init(controller: ItemListController?, navigationBar: NavigationBar, state: Signal<(ItemListPresentationData, (ItemListNodeState, Any)), NoError>) {
self.navigationBar = navigationBar
self.updateNavigationOffset = updateNavigationOffset
self.listNode = ListView()
self.leftOverlayNode = ASDisplayNode()
@ -820,11 +818,6 @@ open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate {
self.searchNode?.scrollToTop()
}
open func scrollViewDidScroll(_ scrollView: UIScrollView) {
let distanceFromEquilibrium = scrollView.contentOffset.y - scrollView.contentSize.height / 3.0
self.updateNavigationOffset(-distanceFromEquilibrium)
}
open func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
targetContentOffset.pointee = scrollView.contentOffset

View File

@ -117,7 +117,7 @@ public final class JoinLinkPreviewController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
private func join() {

View File

@ -107,7 +107,7 @@ public final class LanguageLinkPreviewController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
private func activate() {

View File

@ -478,7 +478,7 @@ open class LegacyController: ViewController, PresentableController {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
if let legacyTelegramController = self.legacyController as? TGViewController {
var duration: TimeInterval = 0.0
if case let .animated(transitionDuration, _) = transition {

View File

@ -115,7 +115,7 @@ final class LocationDistancePickerScreen: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -319,7 +319,7 @@ public final class LocationPickerController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc private func cancelPressed() {

View File

@ -495,7 +495,7 @@ public final class LocationViewController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc private func cancelPressed() {

View File

@ -267,7 +267,7 @@ public final class PasscodeEntryController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
public override func dismiss(completion: (() -> Void)? = nil) {

View File

@ -143,7 +143,7 @@ public final class PasscodeSetupController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc private func nextPressed() {

View File

@ -45,6 +45,6 @@ public class FormController<InnerState, InitParams, Node: FormControllerNode<Ini
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -366,7 +366,7 @@ public final class SecureIdAuthController: ViewController, StandalonePresentable
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
override public func dismiss(completion: (() -> Void)? = nil) {

View File

@ -254,7 +254,7 @@ class SecureIdDocumentGalleryController: ViewController, StandalonePresentableCo
super.containerLayoutUpdated(layout, transition: transition)
self.galleryNode.frame = CGRect(origin: CGPoint(), size: layout.size)
self.galleryNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.galleryNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
if firstLayout {
firstLayout = false

View File

@ -39,7 +39,7 @@ public class SetupTwoStepVerificationController: ViewController {
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: NavigationBarTheme(buttonColor: self.presentationData.theme.rootController.navigationBar.accentTextColor, disabledButtonColor: self.presentationData.theme.rootController.navigationBar.disabledButtonColor, primaryTextColor: self.presentationData.theme.rootController.navigationBar.primaryTextColor, backgroundColor: .clear, separatorColor: .clear, badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear), strings: NavigationBarStrings(presentationStrings: self.presentationData.strings)))
super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: NavigationBarTheme(buttonColor: self.presentationData.theme.rootController.navigationBar.accentTextColor, disabledButtonColor: self.presentationData.theme.rootController.navigationBar.disabledButtonColor, primaryTextColor: self.presentationData.theme.rootController.navigationBar.primaryTextColor, backgroundColor: .clear, enableBackgroundBlur: false, separatorColor: .clear, badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear), strings: NavigationBarStrings(presentationStrings: self.presentationData.strings)))
self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
@ -151,7 +151,7 @@ public class SetupTwoStepVerificationController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc private func nextPressed() {

View File

@ -34,7 +34,7 @@ public final class TwoFactorDataInputScreen: ViewController {
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
let defaultTheme = NavigationBarTheme(rootControllerTheme: self.presentationData.theme)
let navigationBarTheme = NavigationBarTheme(buttonColor: defaultTheme.buttonColor, disabledButtonColor: defaultTheme.disabledButtonColor, primaryTextColor: defaultTheme.primaryTextColor, backgroundColor: .clear, separatorColor: .clear, badgeBackgroundColor: defaultTheme.badgeBackgroundColor, badgeStrokeColor: defaultTheme.badgeStrokeColor, badgeTextColor: defaultTheme.badgeTextColor)
let navigationBarTheme = NavigationBarTheme(buttonColor: defaultTheme.buttonColor, disabledButtonColor: defaultTheme.disabledButtonColor, primaryTextColor: defaultTheme.primaryTextColor, backgroundColor: .clear, enableBackgroundBlur: false, separatorColor: .clear, badgeBackgroundColor: defaultTheme.badgeBackgroundColor, badgeStrokeColor: defaultTheme.badgeStrokeColor, badgeTextColor: defaultTheme.badgeTextColor)
super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: navigationBarTheme, strings: NavigationBarStrings(back: self.presentationData.strings.Common_Back, close: self.presentationData.strings.Common_Close)))
@ -410,7 +410,7 @@ public final class TwoFactorDataInputScreen: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
(self.displayNode as! TwoFactorDataInputScreenNode).containerLayoutUpdated(layout: layout, navigationHeight: self.navigationHeight, transition: transition)
(self.displayNode as! TwoFactorDataInputScreenNode).containerLayoutUpdated(layout: layout, navigationHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -28,7 +28,7 @@ public final class TwoFactorAuthSplashScreen: ViewController {
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
let defaultTheme = NavigationBarTheme(rootControllerTheme: self.presentationData.theme)
let navigationBarTheme = NavigationBarTheme(buttonColor: defaultTheme.buttonColor, disabledButtonColor: defaultTheme.disabledButtonColor, primaryTextColor: defaultTheme.primaryTextColor, backgroundColor: .clear, separatorColor: .clear, badgeBackgroundColor: defaultTheme.badgeBackgroundColor, badgeStrokeColor: defaultTheme.badgeStrokeColor, badgeTextColor: defaultTheme.badgeTextColor)
let navigationBarTheme = NavigationBarTheme(buttonColor: defaultTheme.buttonColor, disabledButtonColor: defaultTheme.disabledButtonColor, primaryTextColor: defaultTheme.primaryTextColor, backgroundColor: .clear, enableBackgroundBlur: false, separatorColor: .clear, badgeBackgroundColor: defaultTheme.badgeBackgroundColor, badgeStrokeColor: defaultTheme.badgeStrokeColor, badgeTextColor: defaultTheme.badgeTextColor)
super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: navigationBarTheme, strings: NavigationBarStrings(back: self.presentationData.strings.Common_Back, close: self.presentationData.strings.Common_Close)))
@ -70,7 +70,7 @@ public final class TwoFactorAuthSplashScreen: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
(self.displayNode as! TwoFactorAuthSplashScreenNode).containerLayoutUpdated(layout: layout, navigationHeight: self.navigationHeight, transition: transition)
(self.displayNode as! TwoFactorAuthSplashScreenNode).containerLayoutUpdated(layout: layout, navigationHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -689,7 +689,7 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
super.containerLayoutUpdated(layout, transition: transition)
self.galleryNode.frame = CGRect(origin: CGPoint(), size: layout.size)
self.galleryNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.galleryNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
if !self.adjustedForInitialPreviewingLayout && self.isPresentedInPreviewingContext() {
self.adjustedForInitialPreviewingLayout = true

View File

@ -132,7 +132,7 @@ public final class ChannelMembersSearchController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationInsetHeight, actualNavigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.cleanNavigationHeight, actualNavigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
private func activateSearch() {

View File

@ -48,6 +48,6 @@ public final class SecretChatKeyController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -26,7 +26,6 @@ private func generateBackground(foregroundColor: UIColor, diameter: CGFloat) ->
}, opaque: false)?.stretchableImage(withLeftCapWidth: Int(diameter / 2.0), topCapHeight: Int(diameter / 2.0))
}
public struct SearchBarToken {
public struct Style {
public let backgroundColor: UIColor
@ -620,8 +619,8 @@ public final class SearchBarNodeTheme: Equatable {
self.keyboard = keyboard
}
public init(theme: PresentationTheme, hasSeparator: Bool = true) {
self.background = theme.rootController.navigationBar.backgroundColor
public init(theme: PresentationTheme, hasBackground: Bool = true, hasSeparator: Bool = true) {
self.background = hasBackground ? theme.rootController.navigationBar.backgroundColor : .clear
self.separator = hasSeparator ? theme.rootController.navigationBar.separatorColor : theme.rootController.navigationBar.backgroundColor
self.inputFill = theme.rootController.navigationSearchBar.inputFillColor
self.placeholder = theme.rootController.navigationSearchBar.inputPlaceholderTextColor
@ -714,7 +713,7 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
public var tokensUpdated: (([SearchBarToken]) -> Void)?
private let backgroundNode: ASDisplayNode
private let backgroundNode: NavigationBackgroundNode
private let separatorNode: ASDisplayNode
private let textBackgroundNode: ASDisplayNode
private var activityIndicator: ActivityIndicator?
@ -813,8 +812,9 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
self.forceSeparator = forceSeparator
self.cancelText = cancelText
self.backgroundNode = ASDisplayNode()
self.backgroundNode.isLayerBacked = true
self.backgroundNode = NavigationBackgroundNode(color: theme.background)
self.backgroundNode.isUserInteractionEnabled = false
//self.backgroundNode.isHidden = true
self.separatorNode = ASDisplayNode()
self.separatorNode.isLayerBacked = true
@ -887,7 +887,7 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
self.cancelButton.setAttributedTitle(NSAttributedString(string: self.cancelText ?? strings.Common_Cancel, font: self.cancelText != nil ? Font.semibold(17.0) : Font.regular(17.0), textColor: theme.accent), for: [])
}
if self.theme != theme {
self.backgroundNode.backgroundColor = theme.background
self.backgroundNode.color = theme.background
if self.fieldStyle != .modern || self.forceSeparator {
self.separatorNode.backgroundColor = theme.separator
}
@ -914,6 +914,7 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
self.validLayout = (boundingSize, leftInset, rightInset)
self.backgroundNode.frame = self.bounds
self.backgroundNode.update(size: self.backgroundNode.bounds.size, transition: .immediate)
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: self.bounds.size.height), size: CGSize(width: self.bounds.size.width, height: UIScreenPixel)))
let verticalOffset: CGFloat = boundingSize.height - 82.0

View File

@ -37,8 +37,8 @@ public final class SearchDisplayController {
private var isSearchingDisposable: Disposable?
public init(presentationData: PresentationData, mode: SearchDisplayControllerMode = .navigation, placeholder: String? = nil, hasSeparator: Bool = false, contentNode: SearchDisplayControllerContentNode, cancel: @escaping () -> Void) {
self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: presentationData.theme, hasSeparator: hasSeparator), strings: presentationData.strings, fieldStyle: .modern, forceSeparator: hasSeparator)
public init(presentationData: PresentationData, mode: SearchDisplayControllerMode = .navigation, placeholder: String? = nil, hasBackground: Bool = false, hasSeparator: Bool = false, contentNode: SearchDisplayControllerContentNode, cancel: @escaping () -> Void) {
self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: presentationData.theme, hasBackground: hasBackground, hasSeparator: hasSeparator), strings: presentationData.strings, fieldStyle: .modern, forceSeparator: hasSeparator)
self.backgroundNode = BackgroundNode()
self.backgroundNode.backgroundColor = presentationData.theme.chatList.backgroundColor
self.backgroundNode.allowsGroupOpacity = true

View File

@ -392,7 +392,7 @@ final class BubbleSettingsController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -133,7 +133,7 @@ public final class ChangePhoneNumberIntroController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
(self.displayNode as! ChangePhoneNumberIntroControllerNode).containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
(self.displayNode as! ChangePhoneNumberIntroControllerNode).containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc func cancelPressed() {

View File

@ -145,7 +145,7 @@ public class LocalizationListController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationInsetHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.cleanNavigationHeight, transition: transition)
}
@objc private func editPressed() {

View File

@ -157,7 +157,7 @@ public class NotificationExceptionsController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationInsetHeight, actualNavigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.cleanNavigationHeight, actualNavigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc private func removeAllPressed() {

View File

@ -178,6 +178,6 @@ final class PrivacyIntroController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -145,7 +145,7 @@ public class TermsOfServiceController: ViewController, StandalonePresentableCont
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
override public func viewDidAppear(_ animated: Bool) {

View File

@ -567,7 +567,7 @@ final class TextSizeSelectionController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -74,9 +74,12 @@ final class SettingsThemeWallpaperNode: ASDisplayNode {
self.backgroundNode.frame = CGRect(origin: CGPoint(), size: size)
self.imageNode.frame = CGRect(origin: CGPoint(), size: size)
if case .builtin = wallpaper {
if case let .builtin(gradient, _) = wallpaper {
if self.gradientNode == nil {
let gradientNode = createGradientBackgroundNode()
if let gradient = gradient {
gradientNode.updateColors(colors: gradient.colors.map { UIColor(rgb: $0) })
}
self.gradientNode = gradientNode
self.addSubnode(gradientNode)
}

View File

@ -439,7 +439,7 @@ final class ThemeAccentColorController: ViewController {
var wallpaper: TelegramWallpaper
func extractBuiltinWallpaper(_ currentWallpaper: TelegramWallpaper) {
if case let .builtin(settings) = currentWallpaper {
if case let .builtin(_, settings) = currentWallpaper {
var defaultPatternWallpaper: TelegramWallpaper?
for wallpaper in wallpapers {
@ -617,6 +617,6 @@ final class ThemeAccentColorController: ViewController {
override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -479,11 +479,11 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
suggestedWallpaper = .color(color.argb)
backgroundColors = (color, nil)
default:
suggestedWallpaper = .builtin(WallpaperSettings())
suggestedWallpaper = .builtin(nil, WallpaperSettings())
}
wallpaper = suggestedWallpaper
} else {
wallpaper = state.initialWallpaper ?? .builtin(WallpaperSettings())
wallpaper = state.initialWallpaper ?? .builtin(nil, WallpaperSettings())
wallpaperImage = chatControllerBackgroundImage(theme: nil, wallpaper: wallpaper, mediaBox: context.sharedContext.accountManager.mediaBox, knockoutMode: false)
}
@ -701,7 +701,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
}
self.colorPanelNode.updateState({ _ in
return WallpaperColorPanelNodeState(selection: colorPanelCollapsed ? .none : .first, firstColor: firstColor, defaultColor: defaultColor, secondColor: secondColor, secondColorAvailable: self.state.section != .accent, rotateAvailable: self.state.section == .background, rotation: self.state.rotation ?? 0, preview: false, simpleGradientGeneration: self.state.section == .messages)
return WallpaperColorPanelNodeState(selection: colorPanelCollapsed ? .none : .index(0), firstColor: firstColor, defaultColor: defaultColor, secondColor: secondColor, secondColorAvailable: self.state.section != .accent, rotateAvailable: self.state.section == .background, rotation: self.state.rotation, preview: false, simpleGradientGeneration: self.state.section == .messages, multiColors: [])
}, animated: animated)
needsLayout = true
@ -714,7 +714,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
self.colorPanelNode.updateState({ current in
var updated = current
updated.selection = colorPanelCollapsed ? .none : .first
updated.selection = colorPanelCollapsed ? .none : .index(0)
return updated
}, animated: animated)
}

View File

@ -177,6 +177,6 @@ final class ThemeColorsGridController: ViewController {
override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -339,7 +339,7 @@ final class ThemeGridController: ViewController {
override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationInsetHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.cleanNavigationHeight, transition: transition)
}
func activateSearch() {

View File

@ -56,6 +56,14 @@ final class ThemeGridControllerInteraction {
}
private struct ThemeGridControllerEntry: Comparable, Identifiable {
enum StableId: Hashable {
case builtin([UInt32])
case color(UInt32)
case gradient(UInt32, UInt32)
case file(Int64, UInt32, Int32)
case image(String)
}
let index: Int
let wallpaper: TelegramWallpaper
let isEditable: Bool
@ -69,26 +77,21 @@ private struct ThemeGridControllerEntry: Comparable, Identifiable {
return lhs.index < rhs.index
}
var stableId: Int64 {
var stableId: StableId {
switch self.wallpaper {
case .builtin:
return 0
case let .builtin(gradient, _):
return .builtin(gradient?.colors ?? [])
case let .color(color):
return (Int64(1) << 32) | Int64(bitPattern: UInt64(color))
return .color(color)
case let .gradient(topColor, bottomColor, _):
var hash: UInt32 = topColor
hash = hash &* 31 &+ bottomColor
return (Int64(2) << 32) | Int64(hash)
return .gradient(topColor, bottomColor)
case let .file(id, _, _, _, _, _, _, _, settings):
var hash: Int = id.hashValue
hash = hash &* 31 &+ (settings.color?.hashValue ?? 0)
hash = hash &* 31 &+ (settings.intensity?.hashValue ?? 0)
return (Int64(3) << 32) | Int64(hash)
return .file(id, settings.color ?? 0, settings.intensity ?? 0)
case let .image(representations, _):
if let largest = largestImageRepresentation(representations) {
return (Int64(4) << 32) | Int64(largest.resource.id.hashValue)
return .image(largest.resource.id.uniqueId)
} else {
return 0
return .image("")
}
}
}
@ -260,9 +263,20 @@ final class ThemeGridControllerNode: ASDisplayNode {
self.currentState = ThemeGridControllerNodeState(editing: false, selectedIndices: Set())
self.statePromise = ValuePromise(self.currentState, ignoreRepeated: true)
let defaultWallpaper = presentationData.theme.chat.defaultWallpaper
let wallpapersPromise = Promise<[TelegramWallpaper]>()
wallpapersPromise.set(telegramWallpapers(postbox: context.account.postbox, network: context.account.network))
wallpapersPromise.set(telegramWallpapers(postbox: context.account.postbox, network: context.account.network)
|> map { wallpapers in
var wallpapers = wallpapers
if !wallpapers.contains(where: {
$0.isBasicallyEqual(to: defaultWallpaper)
}) {
wallpapers.insert(defaultWallpaper, at: 0)
}
return wallpapers
})
self.wallpapersPromise = wallpapersPromise
let deletedWallpaperSlugsValue = Atomic<Set<String>>(value: Set())
@ -350,8 +364,10 @@ final class ThemeGridControllerNode: ASDisplayNode {
var index = 1
var isSelectedEditable = true
if case .builtin = presentationData.chatWallpaper {
isSelectedEditable = false
if case let .builtin(gradient, _) = presentationData.chatWallpaper {
if gradient == nil {
isSelectedEditable = false
}
} else if presentationData.chatWallpaper.isBasicallyEqual(to: presentationData.theme.chat.defaultWallpaper) {
isSelectedEditable = false
}
@ -359,10 +375,24 @@ final class ThemeGridControllerNode: ASDisplayNode {
var defaultWallpaper: TelegramWallpaper?
if !presentationData.chatWallpaper.isBasicallyEqual(to: presentationData.theme.chat.defaultWallpaper) {
if case .builtin = presentationData.theme.chat.defaultWallpaper {
} else {
let entry = ThemeGridControllerEntry(index: 1, wallpaper: presentationData.theme.chat.defaultWallpaper, isEditable: false, isSelected: false)
if !entries.contains(where: { $0.stableId == entry.stableId }) {
defaultWallpaper = presentationData.theme.chat.defaultWallpaper
entries.insert(ThemeGridControllerEntry(index: 1, wallpaper: presentationData.theme.chat.defaultWallpaper, isEditable: false, isSelected: false), at: 1)
entries.insert(entry, at: index)
index += 1
}
}
if !entries.contains(where: { entry in
if case .builtin = entry.wallpaper {
return true
} else {
return false
}
}) {
let entry = ThemeGridControllerEntry(index: 1, wallpaper: .builtin(nil, WallpaperSettings(motion: true)), isEditable: false, isSelected: false)
if !entries.contains(where: { $0.stableId == entry.stableId }) {
entries.insert(entry, at: index)
index += 1
}
}
@ -392,13 +422,18 @@ final class ThemeGridControllerNode: ASDisplayNode {
isDefault = true
}
var isEditable = true
if case .builtin = wallpaper {
isEditable = false
if case let .builtin(gradient, _) = wallpaper {
if gradient == nil {
isEditable = false
}
}
if !selected && !isDefault {
entries.append(ThemeGridControllerEntry(index: index, wallpaper: wallpaper, isEditable: isEditable, isSelected: false))
let entry = ThemeGridControllerEntry(index: index, wallpaper: wallpaper, isEditable: isEditable, isSelected: false)
if !entries.contains(where: { $0.stableId == entry.stableId }) {
entries.append(entry)
index += 1
}
}
index += 1
}
let previous = previousEntries.swap(entries)

View File

@ -479,7 +479,7 @@ public final class ThemePreviewController: ViewController {
self.validLayout = layout
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc private func actionPressed() {

View File

@ -632,7 +632,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
effectiveWallpaper = wallpaper
} else {
let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: reference, accentColor: accentColor?.color, bubbleColors: accentColor?.customBubbleColors, wallpaper: accentColor?.wallpaper)
effectiveWallpaper = theme?.chat.defaultWallpaper ?? .builtin(WallpaperSettings())
effectiveWallpaper = theme?.chat.defaultWallpaper ?? .builtin(nil, WallpaperSettings())
}
return (accentColor, effectiveWallpaper)
}
@ -643,7 +643,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
if let wallpaper = cachedWallpaper?.wallpaper, case let .file(file) = wallpaper {
return (accentColor, wallpaper)
} else {
return (accentColor, .builtin(WallpaperSettings()))
return (accentColor, .builtin(nil, WallpaperSettings()))
}
}
} else {
@ -833,7 +833,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
} else {
theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.accentColor, bubbleColors: accentColor?.customBubbleColors, wallpaper: accentColor?.wallpaper)
}
effectiveWallpaper = theme?.chat.defaultWallpaper ?? .builtin(WallpaperSettings())
effectiveWallpaper = theme?.chat.defaultWallpaper ?? .builtin(nil, WallpaperSettings())
}
let wallpaperSignal: Signal<TelegramWallpaper, NoError>

View File

@ -89,9 +89,13 @@ private class ColorInputFieldNode: ASDisplayNode, UITextFieldDelegate {
private var validLayout: (CGSize, Bool)?
private var skipEndEditing = false
private let displaySwatch: Bool
init(theme: PresentationTheme) {
init(theme: PresentationTheme, displaySwatch: Bool = true) {
self.theme = theme
self.displaySwatch = displaySwatch
self.textBackgroundNode = ASImageNode()
self.textBackgroundNode.image = textInputBackgroundImage(fieldColor: theme.chat.inputPanel.inputBackgroundColor, strokeColor: theme.chat.inputPanel.inputStrokeColor, diameter: 33.0)
@ -303,8 +307,15 @@ private class ColorInputFieldNode: ASDisplayNode, UITextFieldDelegate {
let swatchFrame = CGRect(origin: CGPoint(x: 6.0, y: 6.0), size: CGSize(width: 21.0, height: 21.0))
transition.updateFrame(node: self.swatchNode, frame: swatchFrame)
transition.updateFrame(node: self.borderNode, frame: swatchFrame)
self.swatchNode.isHidden = !self.displaySwatch
let textPadding: CGFloat = condensed ? 31.0 : 37.0
let textPadding: CGFloat
if self.displaySwatch {
textPadding = condensed ? 31.0 : 37.0
} else {
textPadding = 6.0
}
transition.updateFrame(node: self.textBackgroundNode, frame: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
transition.updateFrame(node: self.textFieldNode, frame: CGRect(x: textPadding + 10.0, y: 1.0, width: size.width - (21.0 + textPadding), height: size.height - 2.0))
@ -321,10 +332,9 @@ private class ColorInputFieldNode: ASDisplayNode, UITextFieldDelegate {
}
}
enum WallpaperColorPanelNodeSelectionState {
enum WallpaperColorPanelNodeSelectionState: Equatable {
case none
case first
case second
case index(Int)
}
struct WallpaperColorPanelNodeState {
@ -337,6 +347,53 @@ struct WallpaperColorPanelNodeState {
var rotation: Int32
var preview: Bool
var simpleGradientGeneration: Bool
var multiColors: [UIColor]
}
private final class ColorSampleItemNode: ASImageNode {
private struct State: Equatable {
var color: UInt32
var size: CGSize
}
private var action: () -> Void
private var validState: State?
private let selectionNode: ASImageNode
init(action: @escaping () -> Void) {
self.action = action
self.selectionNode = ASImageNode()
self.selectionNode.isUserInteractionEnabled = false
super.init()
self.addSubnode(self.selectionNode)
self.isUserInteractionEnabled = true
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
}
@objc private func tapGesture(_ recognizer: UITapGestureRecognizer) {
if case .ended = recognizer.state {
self.action()
}
}
func update(size: CGSize, color: UIColor, isSelected: Bool) {
self.selectionNode.frame = CGRect(origin: CGPoint(), size: size).insetBy(dx: 2.0, dy: 2.0)
self.selectionNode.isHidden = !isSelected
let state = State(color: color.rgb, size: size)
if self.validState != state {
self.validState = state
self.image = generateFilledCircleImage(diameter: size.width, color: color, strokeColor: UIColor(white: 0.0, alpha: 0.1), strokeWidth: UIScreenPixel, backgroundColor: nil)
self.selectionNode.image = generateFilledCircleImage(diameter: self.selectionNode.frame.width, color: color, strokeColor: .white, strokeWidth: 2.0, backgroundColor: nil)
}
}
}
final class WallpaperColorPanelNode: ASDisplayNode {
@ -344,7 +401,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
private var state: WallpaperColorPanelNodeState
private let backgroundNode: ASDisplayNode
private let backgroundNode: NavigationBackgroundNode
private let topSeparatorNode: ASDisplayNode
private let bottomSeparatorNode: ASDisplayNode
private let firstColorFieldNode: ColorInputFieldNode
@ -355,7 +412,11 @@ final class WallpaperColorPanelNode: ASDisplayNode {
private let doneButton: HighlightableButtonNode
private let colorPickerNode: WallpaperColorPickerNode
private var sampleItemNodes: [ColorSampleItemNode] = []
private let multiColorFieldNode: ColorInputFieldNode
var colorsChanged: ((UIColor?, UIColor?, Bool) -> Void)?
var multiColorsChanged: (([UIColor]) -> Void)?
var colorSelected: (() -> Void)?
var rotate: (() -> Void)?
@ -367,8 +428,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
init(theme: PresentationTheme, strings: PresentationStrings) {
self.theme = theme
self.backgroundNode = ASDisplayNode()
self.backgroundNode.backgroundColor = theme.chat.inputPanel.panelBackgroundColor
self.backgroundNode = NavigationBackgroundNode(color: theme.chat.inputPanel.panelBackgroundColor)
self.topSeparatorNode = ASDisplayNode()
self.topSeparatorNode.backgroundColor = theme.chat.inputPanel.panelSeparatorColor
@ -389,8 +449,9 @@ final class WallpaperColorPanelNode: ASDisplayNode {
self.firstColorFieldNode = ColorInputFieldNode(theme: theme)
self.secondColorFieldNode = ColorInputFieldNode(theme: theme)
self.multiColorFieldNode = ColorInputFieldNode(theme: theme, displaySwatch: false)
self.state = WallpaperColorPanelNodeState(selection: .first, firstColor: nil, secondColor: nil, secondColorAvailable: false, rotateAvailable: false, rotation: 0, preview: false, simpleGradientGeneration: false)
self.state = WallpaperColorPanelNodeState(selection: .index(0), firstColor: nil, secondColor: nil, secondColorAvailable: false, rotateAvailable: false, rotation: 0, preview: false, simpleGradientGeneration: false, multiColors: [])
super.init()
@ -398,6 +459,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
self.addSubnode(self.topSeparatorNode)
self.addSubnode(self.bottomSeparatorNode)
self.addSubnode(self.firstColorFieldNode)
self.addSubnode(self.multiColorFieldNode)
self.addSubnode(self.secondColorFieldNode)
self.addSubnode(self.doneButton)
self.addSubnode(self.colorPickerNode)
@ -424,7 +486,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
strongSelf.colorRemoved?()
strongSelf.updateState({ current in
var updated = current
updated.selection = .first
updated.selection = .index(0)
if let defaultColor = current.defaultColor, updated.secondColor == nil {
updated.firstColor = nil
} else {
@ -441,7 +503,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
strongSelf.updateState({ current in
var updated = current
if updated.selection != .none {
updated.selection = .first
updated.selection = .index(0)
}
return updated
})
@ -465,7 +527,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
strongSelf.updateState({ current in
var updated = current
if updated.selection != .none {
updated.selection = .first
updated.selection = .index(0)
}
updated.secondColor = nil
return updated
@ -477,7 +539,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
strongSelf.firstColorFieldNode.setSkipEndEditingIfNeeded()
strongSelf.updateState({ current in
var updated = current
updated.selection = .second
updated.selection = .index(1)
return updated
})
@ -491,12 +553,20 @@ final class WallpaperColorPanelNode: ASDisplayNode {
var updated = current
updated.preview = true
switch strongSelf.state.selection {
case .first:
updated.firstColor = color
case .second:
updated.secondColor = color
default:
break
case .index(0):
updated.firstColor = color
case .index(1):
updated.secondColor = color
default:
break
}
switch strongSelf.state.selection {
case let .index(index):
if updated.multiColors.count > index {
updated.multiColors[index] = color
}
default:
break
}
return updated
}, updateLayout: false)
@ -508,12 +578,20 @@ final class WallpaperColorPanelNode: ASDisplayNode {
var updated = current
updated.preview = false
switch strongSelf.state.selection {
case .first:
updated.firstColor = color
case .second:
updated.secondColor = color
default:
break
case .index(0):
updated.firstColor = color
case .index(1):
updated.secondColor = color
default:
break
}
switch strongSelf.state.selection {
case let .index(index):
if updated.multiColors.count > index {
updated.multiColors[index] = color
}
default:
break
}
return updated
}, updateLayout: false)
@ -523,7 +601,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
func updateTheme(_ theme: PresentationTheme) {
self.theme = theme
self.backgroundNode.backgroundColor = self.theme.chat.inputPanel.panelBackgroundColor
self.backgroundNode.color = self.theme.chat.inputPanel.panelBackgroundColor
self.topSeparatorNode.backgroundColor = self.theme.chat.inputPanel.panelSeparatorColor
self.bottomSeparatorNode.backgroundColor = self.theme.chat.inputPanel.panelSeparatorColor
self.firstColorFieldNode.updateTheme(theme)
@ -534,8 +612,8 @@ final class WallpaperColorPanelNode: ASDisplayNode {
var updateLayout = updateLayout
let previousFirstColor = self.state.firstColor
let previousSecondColor = self.state.secondColor
let previousMultiColors = self.state.multiColors
let previousPreview = self.state.preview
let previousRotation = self.state.rotation
self.state = f(self.state)
let firstColor: UIColor
@ -559,29 +637,67 @@ final class WallpaperColorPanelNode: ASDisplayNode {
self.secondColorFieldNode.setColor(secondColor, update: false)
}
var firstColorWasRemovable = self.firstColorFieldNode.isRemovable
let firstColorWasRemovable = self.firstColorFieldNode.isRemovable
self.firstColorFieldNode.isRemovable = self.state.secondColor != nil || (self.state.defaultColor != nil && self.state.firstColor != nil)
if firstColorWasRemovable != self.firstColorFieldNode.isRemovable {
updateLayout = true
}
if updateLayout, let size = self.validLayout {
switch self.state.selection {
case .first:
if self.state.multiColors.isEmpty {
switch self.state.selection {
case .index(0):
self.colorPickerNode.color = firstColor
case .second:
case .index(1):
if let secondColor = secondColor {
self.colorPickerNode.color = secondColor
}
default:
break
}
} else {
switch self.state.selection {
case let .index(index):
self.colorPickerNode.color = self.state.multiColors[index]
default:
break
}
}
self.updateLayout(size: size, transition: animated ? .animated(duration: 0.3, curve: .easeInOut) : .immediate)
}
if self.state.firstColor?.argb != previousFirstColor?.argb || self.state.secondColor?.argb != previousSecondColor?.argb || self.state.preview != previousPreview {
self.colorsChanged?(firstColorIsDefault ? nil : firstColor, secondColor, !self.state.preview)
if self.state.multiColors.isEmpty {
if self.state.firstColor?.argb != previousFirstColor?.argb || self.state.secondColor?.argb != previousSecondColor?.argb || self.state.preview != previousPreview {
self.colorsChanged?(firstColorIsDefault ? nil : firstColor, secondColor, !self.state.preview)
}
} else {
switch state.selection {
case let .index(index):
self.multiColorFieldNode.setColor(self.state.multiColors[index], update: false)
default:
break
}
for i in 0 ..< state.multiColors.count {
if i < self.sampleItemNodes.count {
self.sampleItemNodes[i].update(size: self.sampleItemNodes[i].bounds.size, color: state.multiColors[i], isSelected: state.selection == .index(i))
}
}
var updated = false
if self.state.multiColors.count != previousMultiColors.count {
updated = true
} else {
for i in 0 ..< self.state.multiColors.count {
if !self.state.multiColors[i].isEqual(previousMultiColors[i]) {
updated = true
}
}
}
if updated {
self.multiColorsChanged?(self.state.multiColors)
}
}
}
@ -630,8 +746,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
self.rotateButton.alpha = 0.0
self.swapButton.alpha = 0.0
let buttonOffset: CGFloat = (rightInsetWithButton - 13.0) / 2.0
var buttonFrame = self.addButton.frame
buttonFrame.origin.x = size.width
self.addButton.frame = buttonFrame
@ -651,6 +766,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
let separatorHeight = UIScreenPixel
let topPanelHeight: CGFloat = 47.0
transition.updateFrame(node: self.backgroundNode, frame: CGRect(x: 0.0, y: 0.0, width: size.width, height: topPanelHeight))
self.backgroundNode.update(size: self.backgroundNode.bounds.size, transition: transition)
transition.updateFrame(node: self.topSeparatorNode, frame: CGRect(x: 0.0, y: 0.0, width: size.width, height: separatorHeight))
transition.updateFrame(node: self.bottomSeparatorNode, frame: CGRect(x: 0.0, y: topPanelHeight, width: size.width, height: separatorHeight))
@ -712,20 +828,78 @@ final class WallpaperColorPanelNode: ASDisplayNode {
}
transition.updateTransformRotation(node: self.rotateButton, angle: degreesToRadians(CGFloat(self.state.rotation)), beginWithCurrentState: true, completion: nil)
self.firstColorFieldNode.isRemovable = self.state.secondColor != nil || (self.state.defaultColor != nil && self.state.firstColor != nil)
self.secondColorFieldNode.isRemovable = true
self.firstColorFieldNode.isSelected = self.state.selection == .first
self.secondColorFieldNode.isSelected = self.state.selection == .second
let firstFieldFrame = CGRect(x: leftInset, y: (topPanelHeight - fieldHeight) / 2.0, width: self.state.secondColor != nil ? floorToScreenPixels((size.width - fieldSpacing) / 2.0) - leftInset : size.width - leftInset - (self.state.secondColorAvailable ? rightInsetWithButton : rightInset), height: fieldHeight)
transition.updateFrame(node: self.firstColorFieldNode, frame: firstFieldFrame)
self.firstColorFieldNode.updateLayout(size: firstFieldFrame.size, condensed: condensedLayout, transition: transition)
let secondFieldFrame = CGRect(x: firstFieldFrame.maxX + fieldSpacing, y: (topPanelHeight - fieldHeight) / 2.0, width: firstFieldFrame.width, height: fieldHeight)
transition.updateFrame(node: self.secondColorFieldNode, frame: secondFieldFrame)
self.secondColorFieldNode.updateLayout(size: secondFieldFrame.size, condensed: condensedLayout, transition: transition)
if self.state.multiColors.isEmpty {
self.firstColorFieldNode.isHidden = false
self.secondColorFieldNode.isHidden = false
self.rotateButton.isHidden = false
self.swapButton.isHidden = false
self.multiColorFieldNode.isHidden = true
self.firstColorFieldNode.isRemovable = self.state.secondColor != nil || (self.state.defaultColor != nil && self.state.firstColor != nil)
self.secondColorFieldNode.isRemovable = true
self.firstColorFieldNode.isSelected = self.state.selection == .index(0)
self.secondColorFieldNode.isSelected = self.state.selection == .index(1)
let firstFieldFrame = CGRect(x: leftInset, y: (topPanelHeight - fieldHeight) / 2.0, width: self.state.secondColor != nil ? floorToScreenPixels((size.width - fieldSpacing) / 2.0) - leftInset : size.width - leftInset - (self.state.secondColorAvailable ? rightInsetWithButton : rightInset), height: fieldHeight)
transition.updateFrame(node: self.firstColorFieldNode, frame: firstFieldFrame)
self.firstColorFieldNode.updateLayout(size: firstFieldFrame.size, condensed: condensedLayout, transition: transition)
let secondFieldFrame = CGRect(x: firstFieldFrame.maxX + fieldSpacing, y: (topPanelHeight - fieldHeight) / 2.0, width: firstFieldFrame.width, height: fieldHeight)
transition.updateFrame(node: self.secondColorFieldNode, frame: secondFieldFrame)
self.secondColorFieldNode.updateLayout(size: secondFieldFrame.size, condensed: condensedLayout, transition: transition)
for itemNode in self.sampleItemNodes {
itemNode.removeFromSupernode()
}
self.sampleItemNodes.removeAll()
} else {
self.firstColorFieldNode.isHidden = true
self.secondColorFieldNode.isHidden = true
self.rotateButton.isHidden = true
self.swapButton.isHidden = true
self.multiColorFieldNode.isHidden = false
let sampleItemSize: CGFloat = 32.0
let sampleItemSpacing: CGFloat = 15.0
var nextSampleX = leftInset
for i in 0 ..< self.state.multiColors.count {
let itemNode: ColorSampleItemNode
if self.sampleItemNodes.count < i {
itemNode = self.sampleItemNodes[i]
} else {
itemNode = ColorSampleItemNode(action: { [weak self] in
guard let strongSelf = self else {
return
}
let index = i
strongSelf.updateState({ state in
var state = state
state.selection = .index(index)
return state
})
})
self.sampleItemNodes.append(itemNode)
self.insertSubnode(itemNode, aboveSubnode: self.multiColorFieldNode)
}
if i != 0 {
nextSampleX += sampleItemSpacing
}
itemNode.frame = CGRect(origin: CGPoint(x: nextSampleX, y: (topPanelHeight - sampleItemSize) / 2.0), size: CGSize(width: sampleItemSize, height: sampleItemSize))
nextSampleX += sampleItemSize
itemNode.update(size: itemNode.bounds.size, color: self.state.multiColors[i], isSelected: self.state.selection == .index(i))
}
let fieldX = nextSampleX + sampleItemSpacing
let fieldFrame = CGRect(x: fieldX, y: (topPanelHeight - fieldHeight) / 2.0, width: size.width - fieldX - leftInset, height: fieldHeight)
transition.updateFrame(node: self.multiColorFieldNode, frame: fieldFrame)
self.multiColorFieldNode.updateLayout(size: fieldFrame.size, condensed: false, transition: transition)
}
let colorPickerSize = CGSize(width: size.width, height: size.height - topPanelHeight - separatorHeight)
transition.updateFrame(node: self.colorPickerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: topPanelHeight + separatorHeight), size: colorPickerSize))
@ -764,7 +938,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
self.updateState({ current in
var updated = current
updated.selection = .second
updated.selection = .index(1)
let firstColor = current.firstColor ?? current.defaultColor
if let color = firstColor {

View File

@ -165,8 +165,10 @@ public class WallpaperGalleryController: ViewController {
private var overlayNode: WallpaperGalleryOverlayNode?
private var toolbarNode: WallpaperGalleryToolbarNode?
private var patternPanelNode: WallpaperPatternPanelNode?
private var colorsPanelNode: WallpaperColorPanelNode?
private var patternPanelEnabled = false
private var colorsPanelEnabled = false
public init(context: AccountContext, source: WallpaperListSource) {
self.context = context
@ -284,6 +286,8 @@ public class WallpaperGalleryController: ViewController {
self.toolbarNode?.updateThemeAndStrings(theme: self.presentationData.theme, strings: self.presentationData.strings)
self.patternPanelNode?.updateTheme(self.presentationData.theme)
self.patternPanelNode?.backgroundColors = self.presentationData.theme.overallDarkAppearance ? (self.presentationData.theme.list.blocksBackgroundColor, nil, nil) : nil
self.colorsPanelNode?.updateTheme(self.presentationData.theme)
}
func dismiss(forceAway: Bool) {
@ -374,6 +378,7 @@ public class WallpaperGalleryController: ViewController {
dismissed = true
if let centralItemNode = strongSelf.galleryNode.pager.centralItemNode() as? WallpaperGalleryItemNode {
let options = centralItemNode.options
let gradientColors = centralItemNode.colors
if !strongSelf.entries.isEmpty {
let entry = strongSelf.entries[centralItemNode.index]
switch entry {
@ -398,7 +403,7 @@ public class WallpaperGalleryController: ViewController {
let autoNightModeTriggered = strongSelf.presentationData.autoNightModeTriggered
let _ = (updatePresentationThemeSettingsInteractively(accountManager: strongSelf.context.sharedContext.accountManager, { current in
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
var wallpaper = wallpaper.isBasicallyEqual(to: strongSelf.presentationData.theme.chat.defaultWallpaper) ? nil : wallpaper
let wallpaper = wallpaper.isBasicallyEqual(to: strongSelf.presentationData.theme.chat.defaultWallpaper) ? nil : wallpaper
let themeReference: PresentationThemeReference
if autoNightModeTriggered {
themeReference = current.automaticThemeSwitchSetting.theme
@ -505,6 +510,15 @@ public class WallpaperGalleryController: ViewController {
settings.motion = options.contains(.motion)
updatedWallpaper = updatedWallpaper.withUpdatedSettings(settings)
}
if case let .builtin(_, settings) = updatedWallpaper {
var gradient: TelegramWallpaper.Gradient?
if let gradientColors = gradientColors {
if gradientColors != defaultBuiltinWallpaperGradientColors.map({ $0.rgb }) {
gradient = TelegramWallpaper.Gradient(colors: gradientColors)
}
}
updatedWallpaper = .builtin(gradient, settings)
}
applyWallpaper(updatedWallpaper)
}
default:
@ -560,6 +574,32 @@ public class WallpaperGalleryController: ViewController {
strongSelf.containerLayoutUpdated(layout, transition: .animated(duration: 0.3, curve: .spring))
}
}
node.requestColorsPanel = { [weak self] colors in
if let strongSelf = self, let (layout, _) = strongSelf.validLayout {
strongSelf.colorsPanelEnabled = colors != nil
strongSelf.galleryNode.scrollView.isScrollEnabled = colors == nil
if let colors = colors {
strongSelf.colorsPanelNode?.updateState({ _ in
return WallpaperColorPanelNodeState(
selection: .index(0),
firstColor: colors[0],
defaultColor: colors[0],
secondColor: colors[1],
secondColorAvailable: true,
rotateAvailable: false,
rotation: 0,
preview: false,
simpleGradientGeneration: false,
multiColors: colors
)
}, animated: false)
} else {
//strongSelf.updateEntries(pattern: .color(0), preview: false)
}
strongSelf.containerLayoutUpdated(layout, transition: .animated(duration: 0.3, curve: .spring))
}
}
if let entry = self.currentEntry(), case let .wallpaper(wallpaper, _) = entry, case let .file(_, _, _, _, true, _, _, _ , settings) = wallpaper, let color = settings.color {
if self.patternPanelNode?.backgroundColors != nil, let snapshotView = self.patternPanelNode?.scrollNode.view.snapshotContentTree() {
@ -633,7 +673,7 @@ public class WallpaperGalleryController: ViewController {
super.containerLayoutUpdated(layout, transition: transition)
self.galleryNode.frame = CGRect(origin: CGPoint(), size: layout.size)
self.galleryNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.galleryNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
self.overlayNode?.frame = self.galleryNode.bounds
transition.updateFrame(node: self.toolbarNode!, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - 49.0 - layout.intrinsicInsets.bottom), size: CGSize(width: layout.size.width, height: 49.0 + layout.intrinsicInsets.bottom)))
@ -658,17 +698,48 @@ public class WallpaperGalleryController: ViewController {
currentPatternPanelNode = patternPanelNode
self.overlayNode?.insertSubnode(patternPanelNode, belowSubnode: self.toolbarNode!)
}
let currentColorsPanelNode: WallpaperColorPanelNode
if let current = self.colorsPanelNode {
currentColorsPanelNode = current
} else {
let colorsPanelNode = WallpaperColorPanelNode(theme: self.presentationData.theme, strings: self.presentationData.strings)
self.colorsPanelNode = colorsPanelNode
currentColorsPanelNode = colorsPanelNode
self.overlayNode?.insertSubnode(colorsPanelNode, belowSubnode: self.toolbarNode!)
colorsPanelNode.multiColorsChanged = { [weak self] colors in
guard let strongSelf = self else {
return
}
guard let centralItemNode = strongSelf.galleryNode.pager.centralItemNode() as? WallpaperGalleryItemNode else {
return
}
centralItemNode.updateColors(colors: colors)
}
}
let panelHeight: CGFloat = 235.0
var patternPanelFrame = CGRect(x: 0.0, y: layout.size.height, width: layout.size.width, height: panelHeight)
if self.patternPanelEnabled {
patternPanelFrame.origin = CGPoint(x: 0.0, y: layout.size.height - bottomInset - panelHeight)
bottomInset += panelHeight
}
bottomInset += 66.0
transition.updateFrame(node: currentPatternPanelNode, frame: patternPanelFrame)
currentPatternPanelNode.updateLayout(size: patternPanelFrame.size, transition: transition)
var colorsPanelFrame = CGRect(x: 0.0, y: layout.size.height, width: layout.size.width, height: panelHeight)
if self.colorsPanelEnabled {
colorsPanelFrame.origin = CGPoint(x: 0.0, y: layout.size.height - bottomInset - panelHeight)
bottomInset += panelHeight
}
transition.updateFrame(node: currentColorsPanelNode, frame: colorsPanelFrame)
currentColorsPanelNode.updateLayout(size: colorsPanelFrame.size, transition: transition)
bottomInset += 66.0
self.validLayout = (layout, bottomInset)
if !hadLayout {

View File

@ -99,6 +99,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
private var blurButtonNode: WallpaperOptionButtonNode
private var motionButtonNode: WallpaperOptionButtonNode
private var patternButtonNode: WallpaperOptionButtonNode
private var colorsButtonNode: WallpaperOptionButtonNode
private var playButtonNode: HighlightableButtonNode
private let messagesContainerNode: ASDisplayNode
private var messageNodes: [ListViewItemNode]?
@ -113,9 +115,12 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
let actionButton = Promise<UIBarButtonItem?>(nil)
var action: (() -> Void)?
var requestPatternPanel: ((Bool) -> Void)?
var requestColorsPanel: (([UIColor]?) -> Void)?
private var validLayout: ContainerViewLayout?
private var validLayout: (ContainerViewLayout, CGFloat)?
private var validOffset: CGFloat?
private var gradientColors: [UIColor]?
init(context: AccountContext) {
self.context = context
@ -142,6 +147,34 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.motionButtonNode.setEnabled(false)
self.patternButtonNode = WallpaperOptionButtonNode(title: self.presentationData.strings.WallpaperPreview_Pattern, value: .check(false))
self.patternButtonNode.setEnabled(false)
self.colorsButtonNode = WallpaperOptionButtonNode(title: self.presentationData.strings.WallpaperPreview_WallpaperColors, value: .colors(false, [.clear]))
self.playButtonNode = HighlightableButtonNode()
self.playButtonNode.setImage(generateImage(CGSize(width: 48.0, height: 48.0), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.setFillColor(UIColor.white.cgColor)
let diameter = size.width
let factor = diameter / 50.0
let size = CGSize(width: 15.0, height: 18.0)
context.translateBy(x: (diameter - size.width) / 2.0 + 1.5, y: (diameter - size.height) / 2.0)
if (diameter < 40.0) {
context.translateBy(x: size.width / 2.0, y: size.height / 2.0)
context.scaleBy(x: factor, y: factor)
context.translateBy(x: -size.width / 2.0, y: -size.height / 2.0)
}
let _ = try? drawSvgPath(context, path: "M1.71891969,0.209353049 C0.769586558,-0.350676705 0,0.0908839327 0,1.18800046 L0,16.8564753 C0,17.9569971 0.750549162,18.357187 1.67393713,17.7519379 L14.1073836,9.60224049 C15.0318735,8.99626906 15.0094718,8.04970371 14.062401,7.49100858 L1.71891969,0.209353049 ")
context.fillPath()
if (diameter < 40.0) {
context.translateBy(x: size.width / 2.0, y: size.height / 2.0)
context.scaleBy(x: 1.0 / 0.8, y: 1.0 / 0.8)
context.translateBy(x: -size.width / 2.0, y: -size.height / 2.0)
}
context.translateBy(x: -(diameter - size.width) / 2.0 - 1.5, y: -(diameter - size.height) / 2.0)
}), for: [])
super.init()
@ -162,10 +195,14 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.addSubnode(self.blurButtonNode)
self.addSubnode(self.motionButtonNode)
self.addSubnode(self.patternButtonNode)
self.addSubnode(self.colorsButtonNode)
self.addSubnode(self.playButtonNode)
self.blurButtonNode.addTarget(self, action: #selector(self.toggleBlur), forControlEvents: .touchUpInside)
self.motionButtonNode.addTarget(self, action: #selector(self.toggleMotion), forControlEvents: .touchUpInside)
self.patternButtonNode.addTarget(self, action: #selector(self.togglePattern), forControlEvents: .touchUpInside)
self.colorsButtonNode.addTarget(self, action: #selector(self.toggleColors), forControlEvents: .touchUpInside)
self.playButtonNode.addTarget(self, action: #selector(self.togglePlay), forControlEvents: .touchUpInside)
}
deinit {
@ -185,6 +222,18 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
return nil
}
}
func updateColors(colors: [UIColor]) {
if self.gradientColors == nil {
return
}
self.gradientColors = colors
self.nativeNode.update(wallpaper: .builtin(TelegramWallpaper.Gradient(colors: colors.map {
$0.rgb
}), WallpaperSettings(blur: false, motion: false, color: nil, bottomColor: nil, intensity: nil, rotation: nil)))
self.colorsButtonNode.colors = colors
}
override func ready() -> Signal<Void, NoError> {
return self._ready.get()
@ -238,7 +287,12 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
switch entry {
case let .wallpaper(wallpaper, message):
switch wallpaper {
case .builtin:
case let .builtin(gradient, _):
if self.gradientColors == nil {
self.gradientColors = gradient?.colors.map({ color in
return UIColor(rgb: color)
}) ?? defaultBuiltinWallpaperGradientColors
}
displaySize = CGSize(width: 1308.0, height: 2688.0).fitted(CGSize(width: 1280.0, height: 1280.0)).dividedByScreenScale().integralFloor
contentSize = displaySize
signal = settingsBuiltinWallpaperImage(account: self.context.account)
@ -538,19 +592,21 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.colorDisposable.set((colorSignal
|> deliverOnMainQueue).start(next: { [weak self] color in
self?.statusNode.backgroundNodeColor = color
self?.patternButtonNode.buttonColor = color
self?.blurButtonNode.buttonColor = color
self?.motionButtonNode.buttonColor = color
guard let strongSelf = self else {
return
}
strongSelf.statusNode.backgroundNodeColor = color
strongSelf.patternButtonNode.buttonColor = color
strongSelf.blurButtonNode.buttonColor = color
strongSelf.motionButtonNode.buttonColor = color
strongSelf.colorsButtonNode.buttonColor = color
strongSelf.playButtonNode.setBackgroundImage(generateFilledCircleImage(diameter: 48.0, color: color), for: [])
}))
if let layout = self.validLayout {
//self.updateButtonsLayout(layout: layout, offset: CGPoint(), transition: animated ? .animated(duration: 0.2, curve: .easeInOut) : .immediate)
}
} else if self.arguments.patternEnabled != previousArguments.patternEnabled {
self.patternButtonNode.isSelected = self.arguments.patternEnabled
if let layout = self.validLayout {
if let (layout, _) = self.validLayout {
self.updateButtonsLayout(layout: layout, offset: CGPoint(), transition: .immediate)
self.updateMessagesLayout(layout: layout, offset: CGPoint(), transition: .immediate)
}
@ -563,7 +619,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
return
}
self.validOffset = offset
if let layout = self.validLayout {
if let (layout, _) = self.validLayout {
self.updateWrapperLayout(layout: layout, offset: offset, transition: .immediate)
self.updateButtonsLayout(layout: layout, offset: CGPoint(x: offset, y: 0.0), transition: .immediate)
self.updateMessagesLayout(layout: layout, offset: CGPoint(x: offset, y: 0.0), transition:.immediate)
@ -571,7 +627,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
}
func updateDismissTransition(_ value: CGFloat) {
if let layout = self.validLayout {
if let (layout, _) = self.validLayout {
self.updateButtonsLayout(layout: layout, offset: CGPoint(x: 0.0, y: value), transition: .immediate)
self.updateMessagesLayout(layout: layout, offset: CGPoint(x: 0.0, y: value), transition: .immediate)
}
@ -594,8 +650,16 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.setMotionEnabled(newValue.contains(.motion), animated: false)
self.motionButtonNode.isSelected = newValue.contains(.motion)
if let (layout, _) = self.validLayout {
self.updateButtonsLayout(layout: layout, offset: CGPoint(), transition: .immediate)
}
}
}
var colors: [UInt32]? {
return self.gradientColors?.map({ $0.rgb })
}
@objc func toggleBlur() {
let value = !self.blurButtonNode.isSelected
@ -607,7 +671,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
let blurRadius: CGFloat = 45.0
var animated = animated
if animated, let layout = self.validLayout {
if animated, let (layout, _) = self.validLayout {
animated = min(layout.size.width, layout.size.height) > 321.0
} else {
animated = false
@ -653,6 +717,10 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
let value = !self.motionButtonNode.isSelected
self.motionButtonNode.setSelected(value, animated: true)
self.setMotionEnabled(value, animated: true)
if let (layout, navigationBarHeight) = self.validLayout {
self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .animated(duration: 0.2, curve: .easeInOut))
}
}
var isPatternEnabled: Bool {
@ -665,6 +733,20 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.requestPatternPanel?(value)
}
@objc private func toggleColors() {
guard let currentGradientColors = self.gradientColors else {
return
}
let value = !self.colorsButtonNode.isSelected
self.colorsButtonNode.setSelected(value, animated: false)
self.requestColorsPanel?(value ? currentGradientColors : nil)
}
@objc private func togglePlay() {
self.nativeNode.animateEvent(transition: .animated(duration: 0.5, curve: .spring))
}
private func preparePatternEditing() {
if let entry = self.entry, case let .wallpaper(wallpaper, _) = entry, case let .file(file) = wallpaper {
@ -730,6 +812,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
let patternButtonSize = self.patternButtonNode.measure(layout.size)
let blurButtonSize = self.blurButtonNode.measure(layout.size)
let motionButtonSize = self.motionButtonNode.measure(layout.size)
let colorsButtonSize = self.colorsButtonNode.measure(layout.size)
let playButtonSize = CGSize(width: 48.0, height: 48.0)
let maxButtonWidth = max(patternButtonSize.width, max(blurButtonSize.width, motionButtonSize.width))
let buttonSize = CGSize(width: maxButtonWidth, height: 30.0)
@ -738,6 +822,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
var additionalYOffset: CGFloat = 0.0
if self.patternButtonNode.isSelected {
additionalYOffset = -235.0
} else if self.colorsButtonNode.isSelected {
additionalYOffset = -235.0
}
let leftButtonFrame = CGRect(origin: CGPoint(x: floor(layout.size.width / 2.0 - buttonSize.width - 10.0) + offset.x, y: layout.size.height - 49.0 - layout.intrinsicInsets.bottom - 54.0 + offset.y + additionalYOffset), size: buttonSize)
@ -752,6 +838,14 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
var motionFrame = centerButtonFrame
var motionAlpha: CGFloat = 0.0
var colorsFrame = CGRect(origin: CGPoint(x: rightButtonFrame.maxX - colorsButtonSize.width, y: rightButtonFrame.minY), size: colorsButtonSize)
var colorsAlpha: CGFloat = 0.0
let playFrame = CGRect(origin: CGPoint(x: centerButtonFrame.midX - playButtonSize.width / 2.0, y: centerButtonFrame.midY - playButtonSize.height / 2.0), size: playButtonSize)
var playAlpha: CGFloat = 0.0
let centerOffset: CGFloat = 32.0
if let entry = self.entry {
switch entry {
@ -767,8 +861,19 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
motionFrame = rightButtonFrame
case let .wallpaper(wallpaper, _):
switch wallpaper {
case .builtin:
case let .builtin(gradient, _):
self.colorsButtonNode.colors = self.gradientColors
motionAlpha = 1.0
if self.motionButtonNode.isSelected {
motionFrame = leftButtonFrame.offsetBy(dx: -centerOffset, dy: 0.0)
colorsFrame = colorsFrame.offsetBy(dx: centerOffset, dy: 0.0)
playAlpha = 1.0
} else {
motionFrame = leftButtonFrame
playAlpha = 0.0
}
colorsAlpha = 1.0
case .color:
patternAlpha = 1.0
if self.patternButtonNode.isSelected {
@ -811,11 +916,18 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
transition.updateFrame(node: self.motionButtonNode, frame: motionFrame)
transition.updateAlpha(node: self.motionButtonNode, alpha: motionAlpha * alpha)
transition.updateFrame(node: self.colorsButtonNode, frame: colorsFrame)
transition.updateAlpha(node: self.colorsButtonNode, alpha: colorsAlpha * alpha)
transition.updateFrame(node: self.playButtonNode, frame: playFrame)
transition.updateAlpha(node: self.playButtonNode, alpha: playAlpha * alpha)
transition.updateSublayerTransformScale(node: self.playButtonNode, scale: max(0.1, playAlpha))
}
private func updateMessagesLayout(layout: ContainerViewLayout, offset: CGPoint, transition: ContainedViewLayoutTransition) {
var bottomInset: CGFloat = 115.0
if self.patternButtonNode.isSelected {
if self.patternButtonNode.isSelected || self.colorsButtonNode.isSelected {
bottomInset = 350.0
}
@ -926,7 +1038,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
}
var additionalYOffset: CGFloat = 0.0
if self.patternButtonNode.isSelected {
if self.patternButtonNode.isSelected || self.colorsButtonNode.isSelected {
additionalYOffset = -190.0
}
@ -935,7 +1047,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.updateButtonsLayout(layout: layout, offset: CGPoint(x: offset, y: 0.0), transition: transition)
self.updateMessagesLayout(layout: layout, offset: CGPoint(x: offset, y: 0.0), transition: transition)
self.validLayout = layout
self.validLayout = (layout, navigationBarHeight)
}
override func visibilityUpdated(isVisible: Bool) {

View File

@ -9,6 +9,21 @@ import CheckNode
enum WallpaperOptionButtonValue {
case check(Bool)
case color(Bool, UIColor)
case colors(Bool, [UIColor])
}
private func generateColorsImage(diameter: CGFloat, colors: [UIColor]) -> UIImage? {
return generateImage(CGSize(width: diameter, height: diameter), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.addEllipse(in: CGRect(origin: CGPoint(), size: size))
context.clip()
for i in 0 ..< min(colors.count, 4) {
let x = i % 2
let y = i / 2
context.setFillColor(colors[i].cgColor)
context.fill(CGRect(origin: CGPoint(x: CGFloat(x) * size.width / 2.0, y: CGFloat(y) * size.height / 2.0), size: CGSize(width: size.width / 2.0, height: size.height / 2.0)))
}
})
}
final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
@ -23,16 +38,18 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
override var isSelected: Bool {
get {
switch self._value {
case let .check(selected), let .color(selected, _):
return selected
case let .check(selected), let .color(selected, _), let .colors(selected, _):
return selected
}
}
set {
switch self._value {
case .check:
self._value = .check(newValue)
case let .color(_, color):
self._value = .color(newValue, color)
case .check:
self._value = .check(newValue)
case let .color(_, color):
self._value = .color(newValue, color)
case let .colors(_, colors):
self._value = .colors(newValue, colors)
}
self.checkNode.setSelected(newValue, animated: false)
}
@ -56,14 +73,18 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
super.init()
switch value {
case let .check(selected):
self.checkNode.isHidden = false
self.colorNode.isHidden = true
self.checkNode.selected = selected
case let .color(_, color):
self.checkNode.isHidden = true
self.colorNode.isHidden = false
self.colorNode.image = generateFilledCircleImage(diameter: 18.0, color: color)
case let .check(selected):
self.checkNode.isHidden = false
self.colorNode.isHidden = true
self.checkNode.selected = selected
case let .color(_, color):
self.checkNode.isHidden = true
self.colorNode.isHidden = false
self.colorNode.image = generateFilledCircleImage(diameter: 18.0, color: color)
case let .colors(_, colors):
self.checkNode.isHidden = true
self.colorNode.isHidden = false
self.colorNode.image = generateColorsImage(diameter: 18.0, colors: colors)
}
self.addSubnode(self.backgroundNode)
@ -129,9 +150,50 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
}
}
}
var colors: [UIColor]? {
get {
switch self._value {
case let .colors(_, colors):
return colors
default:
return nil
}
}
set {
if let colors = newValue {
switch self._value {
case let .colors(selected, current):
if current.count == colors.count {
var updated = false
for i in 0 ..< current.count {
if !current[i].isEqual(colors[i]) {
updated = true
break
}
}
if !updated {
return
}
}
self._value = .colors(selected, colors)
self.colorNode.image = generateColorsImage(diameter: 18.0, colors: colors)
default:
break
}
}
}
}
func setSelected(_ selected: Bool, animated: Bool = false) {
self._value = .check(selected)
switch self._value {
case .check:
self._value = .check(selected)
case let .color(_, color):
self._value = .color(selected, color)
case let .colors(_, colors):
self._value = .colors(selected, colors)
}
self.checkNode.setSelected(selected, animated: animated)
}

View File

@ -165,7 +165,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
private let context: AccountContext
private var theme: PresentationTheme
private let backgroundNode: ASDisplayNode
private let backgroundNode: NavigationBackgroundNode
private let topSeparatorNode: ASDisplayNode
let scrollNode: ASScrollNode
@ -206,8 +206,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
self.context = context
self.theme = theme
self.backgroundNode = ASDisplayNode()
self.backgroundNode.backgroundColor = self.theme.chat.inputPanel.panelBackgroundColor
self.backgroundNode = NavigationBackgroundNode(color: theme.chat.inputPanel.panelBackgroundColor)
self.topSeparatorNode = ASDisplayNode()
self.topSeparatorNode.backgroundColor = self.theme.chat.inputPanel.panelSeparatorColor
@ -337,7 +336,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
func updateTheme(_ theme: PresentationTheme) {
self.theme = theme
self.backgroundNode.backgroundColor = self.theme.chat.inputPanel.panelBackgroundColor
self.backgroundNode.color = self.theme.chat.inputPanel.panelBackgroundColor
self.topSeparatorNode.backgroundColor = self.theme.chat.inputPanel.panelSeparatorColor
self.sliderView?.backColor = self.theme.list.disclosureArrowColor
@ -418,6 +417,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
self.validLayout = size
transition.updateFrame(node: self.backgroundNode, frame: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
self.backgroundNode.update(size: self.backgroundNode.bounds.size, transition: transition)
transition.updateFrame(node: self.topSeparatorNode, frame: CGRect(x: 0.0, y: 0.0, width: size.width, height: UIScreenPixel))
let titleSize = self.titleNode.updateLayout(self.bounds.size)

View File

@ -845,7 +845,7 @@ public final class ShareController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
private func saveToCameraRoll(messages: [Message]) {

View File

@ -280,7 +280,7 @@ public final class StickerPackPreviewController: ViewController, StandalonePrese
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -69,7 +69,7 @@ public final class StickerPreviewController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
public func updateItem(_ item: StickerPackItem) {

View File

@ -75,7 +75,23 @@ public struct WallpaperSettings: PostboxCoding, Equatable {
}
public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
case builtin(WallpaperSettings)
public struct Gradient: Equatable, PostboxCoding {
public var colors: [UInt32]
public init(colors: [UInt32]) {
self.colors = colors
}
public init(decoder: PostboxDecoder) {
self.colors = decoder.decodeInt32ArrayForKey("colors").map({ UInt32(bitPattern: $0) })
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32Array(self.colors.map({ Int32(bitPattern: $0) }), forKey: "colors")
}
}
case builtin(Gradient?, WallpaperSettings)
case color(UInt32)
case gradient(UInt32, UInt32, WallpaperSettings)
case image([TelegramMediaImageRepresentation], WallpaperSettings)
@ -84,8 +100,9 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
public init(decoder: PostboxDecoder) {
switch decoder.decodeInt32ForKey("v", orElse: 0) {
case 0:
let gradient = decoder.decodeObjectForKey("gradient", decoder: { Gradient(decoder: $0) }) as? Gradient
let settings = decoder.decodeObjectForKey("settings", decoder: { WallpaperSettings(decoder: $0) }) as? WallpaperSettings ?? WallpaperSettings()
self = .builtin(settings)
self = .builtin(gradient, settings)
case 1:
self = .color(UInt32(bitPattern: decoder.decodeInt32ForKey("c", orElse: 0)))
case 2:
@ -118,8 +135,13 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
public func encode(_ encoder: PostboxEncoder) {
switch self {
case let .builtin(settings):
case let .builtin(gradient, settings):
encoder.encodeInt32(0, forKey: "v")
if let gradient = gradient {
encoder.encodeObject(gradient, forKey: "gradient")
} else {
encoder.encodeNil(forKey: "gradient")
}
encoder.encodeObject(settings, forKey: "settings")
case let .color(color):
encoder.encodeInt32(1, forKey: "v")
@ -149,8 +171,8 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
public static func ==(lhs: TelegramWallpaper, rhs: TelegramWallpaper) -> Bool {
switch lhs {
case let .builtin(settings):
if case .builtin(settings) = rhs {
case let .builtin(gradient, settings):
if case .builtin(gradient, settings) = rhs {
return true
} else {
return false
@ -184,8 +206,8 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
public func isBasicallyEqual(to wallpaper: TelegramWallpaper) -> Bool {
switch self {
case .builtin:
if case .builtin = wallpaper {
case let .builtin(gradient, _):
if case .builtin(gradient, _) = wallpaper {
return true
} else {
return false
@ -219,7 +241,7 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
public var settings: WallpaperSettings? {
switch self {
case let .builtin(settings), let .gradient(_, _, settings), let .image(_, settings), let .file(_, _, _, _, _, _, _, _, settings):
case let .builtin(_, settings), let .gradient(_, _, settings), let .image(_, settings), let .file(_, _, _, _, _, _, _, _, settings):
return settings
default:
return nil
@ -228,8 +250,8 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
public func withUpdatedSettings(_ settings: WallpaperSettings) -> TelegramWallpaper {
switch self {
case .builtin:
return .builtin(settings)
case let .builtin(gradient, _):
return .builtin(gradient, settings)
case .color:
return self
case let .gradient(topColor, bottomColor, _):

View File

@ -29,7 +29,7 @@ final class LocationBroadcastNavigationAccessoryPanel: ASDisplayNode {
private let tapAction: () -> Void
private let close: () -> Void
private let contentNode: NavigationBackgroundNode
private let contentNode: ASDisplayNode
private let iconNode: ASImageNode
private let wavesNode: LiveLocationWavesNode
@ -49,8 +49,8 @@ final class LocationBroadcastNavigationAccessoryPanel: ASDisplayNode {
self.tapAction = tapAction
self.close = close
self.contentNode = NavigationBackgroundNode(color: self.theme.rootController.navigationBar.backgroundColor)
self.contentNode = ASDisplayNode()
self.iconNode = ASImageNode()
self.iconNode.isLayerBacked = true
@ -100,7 +100,6 @@ final class LocationBroadcastNavigationAccessoryPanel: ASDisplayNode {
self.theme = presentationData.theme
self.strings = presentationData.strings
self.contentNode.color = self.theme.rootController.navigationBar.backgroundColor
self.iconNode.image = PresentationResourcesRootController.navigationLiveLocationIcon(self.theme)
self.wavesNode.color = self.theme.rootController.navigationBar.accentTextColor
@ -112,7 +111,6 @@ final class LocationBroadcastNavigationAccessoryPanel: ASDisplayNode {
self.validLayout = (size, leftInset, rightInset)
transition.updateFrame(node: self.contentNode, frame: CGRect(origin: CGPoint(), size: size))
self.contentNode.update(size: self.contentNode.bounds.size, transition: transition)
let titleString = NSAttributedString(string: self.strings.Conversation_LiveLocation, font: titleFont, textColor: self.theme.rootController.navigationBar.primaryTextColor)
var subtitleString: NSAttributedString?
@ -178,7 +176,7 @@ final class LocationBroadcastNavigationAccessoryPanel: ASDisplayNode {
let closeButtonSize = self.closeButton.measure(CGSize(width: 100.0, height: 100.0))
transition.updateFrame(node: self.closeButton, frame: CGRect(origin: CGPoint(x: bounds.size.width - 18.0 - closeButtonSize.width - rightInset, y: minimizedTitleFrame.minY + 8.0), size: closeButtonSize))
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: size.height - UIScreenPixel), size: CGSize(width: size.width, height: UIScreenPixel)))
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: UIScreenPixel)))
}
func update(peers: [Peer], mode: LocationBroadcastNavigationAccessoryPanelMode, canClose: Bool) {
@ -191,9 +189,16 @@ final class LocationBroadcastNavigationAccessoryPanel: ASDisplayNode {
func animateIn(_ transition: ContainedViewLayoutTransition) {
self.clipsToBounds = true
let contentPosition = self.contentNode.layer.position
transition.animatePosition(node: self.contentNode, from: CGPoint(x: contentPosition.x, y: contentPosition.y - 37.0), completion: { [weak self] _ in
self?.clipsToBounds = false
})
guard let (size, _, _) = self.validLayout else {
return
}
transition.animatePositionAdditive(node: self.separatorNode, offset: CGPoint(x: 0.0, y: size.height))
}
func animateOut(_ transition: ContainedViewLayoutTransition, completion: @escaping () -> Void) {
@ -203,6 +208,12 @@ final class LocationBroadcastNavigationAccessoryPanel: ASDisplayNode {
self?.clipsToBounds = false
completion()
})
guard let (size, _, _) = self.validLayout else {
return
}
transition.updatePosition(node: self.separatorNode, position: self.separatorNode.position.offsetBy(dx: 0.0, dy: size.height))
}
@objc func closePressed() {

View File

@ -8,7 +8,7 @@ import TelegramPresentationData
import AccountContext
public final class MediaNavigationAccessoryContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
public let backgroundNode: NavigationBackgroundNode
public let backgroundNode: ASDisplayNode
public let headerNode: MediaNavigationAccessoryHeaderNode
private let currentHeaderHeight: CGFloat = MediaNavigationAccessoryHeaderNode.minimizedHeight
@ -18,7 +18,7 @@ public final class MediaNavigationAccessoryContainerNode: ASDisplayNode, UIGestu
init(context: AccountContext) {
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.backgroundNode = NavigationBackgroundNode(color: self.presentationData.theme.rootController.navigationBar.backgroundColor)
self.backgroundNode = ASDisplayNode()
self.headerNode = MediaNavigationAccessoryHeaderNode(presentationData: self.presentationData)
super.init()
@ -30,14 +30,20 @@ public final class MediaNavigationAccessoryContainerNode: ASDisplayNode, UIGestu
func updatePresentationData(_ presentationData: PresentationData) {
self.presentationData = presentationData
self.backgroundNode.color = self.presentationData.theme.rootController.navigationBar.backgroundColor
self.headerNode.updatePresentationData(presentationData)
}
func animateIn(transition: ContainedViewLayoutTransition) {
self.headerNode.animateIn(transition: transition)
}
func animateOut(transition: ContainedViewLayoutTransition) {
self.headerNode.animateOut(transition: transition)
}
func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) {
transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: self.currentHeaderHeight)))
self.backgroundNode.update(size: self.backgroundNode.bounds.size, transition: transition)
let headerHeight = self.currentHeaderHeight
transition.updateFrame(node: self.headerNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: headerHeight)))

View File

@ -266,8 +266,8 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, UIScrollVi
self.scrollNode.addSubnode(self.previousItemNode)
self.scrollNode.addSubnode(self.nextItemNode)
self.addSubnode(self.leftMaskNode)
self.addSubnode(self.rightMaskNode)
//self.addSubnode(self.leftMaskNode)
//self.addSubnode(self.rightMaskNode)
self.addSubnode(self.closeButton)
self.addSubnode(self.rateButton)
@ -415,6 +415,22 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, UIScrollVi
self.playNext?()
}
}
func animateIn(transition: ContainedViewLayoutTransition) {
guard let (size, _, _) = self.validLayout else {
return
}
transition.animatePositionAdditive(node: self.separatorNode, offset: CGPoint(x: 0.0, y: size.height))
}
func animateOut(transition: ContainedViewLayoutTransition) {
guard let (size, _, _) = self.validLayout else {
return
}
transition.updatePosition(node: self.separatorNode, position: self.separatorNode.position.offsetBy(dx: 0.0, dy: size.height))
}
public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) {
self.validLayout = (size, leftInset, rightInset)
@ -466,7 +482,7 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, UIScrollVi
transition.updateFrame(node: self.actionButton, frame: CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: 40.0, height: 37.0)))
transition.updateFrame(node: self.scrubbingNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 37.0 - 2.0), size: CGSize(width: size.width, height: 2.0)))
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: minHeight - UIScreenPixel), size: CGSize(width: size.width, height: UIScreenPixel)))
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: UIScreenPixel)))
self.accessibilityAreaNode.frame = CGRect(origin: CGPoint(x: self.actionButton.frame.maxX, y: 0.0), size: CGSize(width: self.rateButton.frame.minX - self.actionButton.frame.maxX, height: minHeight))
}

View File

@ -61,6 +61,9 @@ public final class MediaNavigationAccessoryPanel: ASDisplayNode {
public func animateIn(transition: ContainedViewLayoutTransition) {
self.clipsToBounds = true
let contentPosition = self.containerNode.layer.position
self.containerNode.animateIn(transition: transition)
transition.animatePosition(node: self.containerNode, from: CGPoint(x: contentPosition.x, y: contentPosition.y - 37.0), completion: { [weak self] _ in
self?.clipsToBounds = false
})
@ -69,6 +72,9 @@ public final class MediaNavigationAccessoryPanel: ASDisplayNode {
public func animateOut(transition: ContainedViewLayoutTransition, completion: @escaping () -> Void) {
self.clipsToBounds = true
let contentPosition = self.containerNode.layer.position
self.containerNode.animateOut(transition: transition)
transition.animatePosition(node: self.containerNode, to: CGPoint(x: contentPosition.x, y: contentPosition.y - 37.0), removeOnCompletion: false, completion: { [weak self] _ in
self?.clipsToBounds = false
completion()

View File

@ -94,19 +94,7 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
private var presentationDataDisposable: Disposable?
private var playlistPreloadDisposable: Disposable?
override open var navigationHeight: CGFloat {
return super.navigationHeight + self.additionalHeight
}
override open var navigationInsetHeight: CGFloat {
return super.navigationInsetHeight + self.additionalHeight
}
override open var visualNavigationInsetHeight: CGFloat {
return super.visualNavigationInsetHeight + self.additionalHeight
}
public var additionalHeight: CGFloat {
override open var additionalNavigationBarHeight: CGFloat {
var height: CGFloat = 0.0
if let _ = self.groupCallAccessoryPanel {
height += 50.0
@ -120,10 +108,6 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
return height
}
open var primaryNavigationHeight: CGFloat {
return super.navigationHeight
}
public init(context: AccountContext, navigationBarPresentationData: NavigationBarPresentationData?, mediaAccessoryPanelVisibility: MediaAccessoryPanelVisibility, locationBroadcastPanelSource: LocationBroadcastPanelSource, groupCallPanelSource: GroupCallPanelSource) {
self.context = context
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
@ -376,11 +360,25 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
required public init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private var suspendNavigationBarLayout: Bool = false
private var suspendedNavigationBarLayout: ContainerViewLayout?
private var additionalNavigationBarBackgroundHeight: CGFloat = 0.0
override open func updateNavigationBarLayout(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
if self.suspendNavigationBarLayout {
self.suspendedNavigationBarLayout = layout
return
}
self.applyNavigationBarLayout(layout, navigationLayout: self.navigationLayout(layout: layout), additionalBackgroundHeight: self.additionalNavigationBarBackgroundHeight, transition: transition)
}
override open func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
self.suspendNavigationBarLayout = true
super.containerLayoutUpdated(layout, transition: transition)
var navigationHeight = super.navigationHeight
var navigationHeight = super.navigationLayout(layout: layout).navigationFrame.maxY - self.additionalNavigationBarHeight
if !self.displayNavigationBar {
navigationHeight = 0.0
}
@ -409,11 +407,7 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
activeCall: CachedChannelData.ActiveCall(id: groupCallPanelData.info.id, accessHash: groupCallPanelData.info.accessHash, title: groupCallPanelData.info.title, scheduleTimestamp: groupCallPanelData.info.scheduleTimestamp, subscribedToScheduled: groupCallPanelData.info.subscribedToScheduled)
)
})
if let navigationBar = self.navigationBar {
self.displayNode.insertSubnode(groupCallAccessoryPanel, aboveSubnode: navigationBar)
} else {
self.displayNode.addSubnode(groupCallAccessoryPanel)
}
self.navigationBar?.additionalContentNode.addSubnode(groupCallAccessoryPanel)
self.groupCallAccessoryPanel = groupCallAccessoryPanel
groupCallAccessoryPanel.frame = panelFrame
@ -560,11 +554,7 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
strongSelf.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
}
})
if let navigationBar = self.navigationBar {
self.displayNode.insertSubnode(locationBroadcastAccessoryPanel, aboveSubnode: navigationBar)
} else {
self.displayNode.addSubnode(locationBroadcastAccessoryPanel)
}
self.navigationBar?.additionalContentNode.addSubnode(locationBroadcastAccessoryPanel)
self.locationBroadcastAccessoryPanel = locationBroadcastAccessoryPanel
locationBroadcastAccessoryPanel.frame = panelFrame
@ -806,11 +796,9 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
}
mediaAccessoryPanel.frame = panelFrame
if let dismissingPanel = self.dismissingPanel {
self.displayNode.insertSubnode(mediaAccessoryPanel, aboveSubnode: dismissingPanel)
} else if let navigationBar = self.navigationBar {
self.displayNode.insertSubnode(mediaAccessoryPanel, belowSubnode: navigationBar)
self.navigationBar?.additionalContentNode.insertSubnode(mediaAccessoryPanel, aboveSubnode: dismissingPanel)
} else {
self.displayNode.addSubnode(mediaAccessoryPanel)
self.navigationBar?.additionalContentNode.addSubnode(mediaAccessoryPanel)
}
self.mediaAccessoryPanel = (mediaAccessoryPanel, type)
mediaAccessoryPanel.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: .immediate)
@ -842,6 +830,12 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
}
})
}
self.suspendNavigationBarLayout = false
if let suspendedNavigationBarLayout = self.suspendedNavigationBarLayout {
self.suspendedNavigationBarLayout = suspendedNavigationBarLayout
self.applyNavigationBarLayout(suspendedNavigationBarLayout, navigationLayout: self.navigationLayout(layout: layout), additionalBackgroundHeight: self.additionalNavigationBarBackgroundHeight, transition: transition)
}
}
open var keyShortcuts: [KeyShortcut] {

View File

@ -343,7 +343,7 @@ public final class CallController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
override public func dismiss(completion: (() -> Void)? = nil) {

View File

@ -131,7 +131,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
private var audioLevelGenerators: [PeerId: FakeAudioLevelGenerator] = [:]
private var audioLevelGeneratorTimer: SwiftSignalKit.Timer?
private let backgroundNode: NavigationBackgroundNode
private let backgroundNode: ASDisplayNode
private let separatorNode: ASDisplayNode
private let membersDisposable = MetaDisposable()
@ -176,7 +176,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
self.avatarsContext = AnimatedAvatarSetContext()
self.avatarsNode = AnimatedAvatarSetNode()
self.backgroundNode = NavigationBackgroundNode(color: .clear)
self.backgroundNode = ASDisplayNode()
self.separatorNode = ASDisplayNode()
self.separatorNode.isLayerBacked = true
@ -284,8 +284,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
self.theme = presentationData.theme
self.strings = presentationData.strings
self.dateTimeFormat = presentationData.dateTimeFormat
self.backgroundNode.color = self.theme.rootController.navigationBar.backgroundColor
self.separatorNode.backgroundColor = presentationData.theme.chat.historyNavigation.strokeColor
self.joinButtonTitleNode.attributedText = NSAttributedString(string: self.joinButtonTitleNode.attributedText?.string ?? "", font: Font.with(size: 15.0, design: .round, weight: .semibold, traits: [.monospacedNumbers]), textColor: self.isScheduled ? .white : presentationData.theme.chat.inputPanel.actionControlForegroundColor)
@ -634,9 +633,8 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
self.joinButton.isHidden = self.currentData?.groupCall != nil
self.micButton.isHidden = self.currentData?.groupCall == nil
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: panelHeight - UIScreenPixel), size: CGSize(width: size.width, height: UIScreenPixel)))
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: UIScreenPixel)))
transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: panelHeight)))
self.backgroundNode.update(size: self.backgroundNode.bounds.size, transition: transition)
}
public func animateIn(_ transition: ContainedViewLayoutTransition) {
@ -645,6 +643,12 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
transition.animatePosition(node: self.contentNode, from: CGPoint(x: contentPosition.x, y: contentPosition.y - 50.0), completion: { [weak self] _ in
self?.clipsToBounds = false
})
guard let (size, _, _) = self.validLayout else {
return
}
transition.animatePositionAdditive(node: self.separatorNode, offset: CGPoint(x: 0.0, y: size.height))
}
public func animateOut(_ transition: ContainedViewLayoutTransition, completion: @escaping () -> Void) {
@ -654,6 +658,12 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
self?.clipsToBounds = false
completion()
})
guard let (size, _, _) = self.validLayout else {
return
}
transition.updatePosition(node: self.separatorNode, position: self.separatorNode.position.offsetBy(dx: 0.0, dy: size.height))
}
func rightButtonSnapshotViews() -> (background: UIView, foreground: UIView)? {

View File

@ -98,7 +98,7 @@ final class VoiceChatCameraPreviewController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -5815,7 +5815,7 @@ public final class VoiceChatController: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.validLayout = layout
self.controllerNode.containerLayoutUpdated(layout, navigationHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
}

View File

@ -183,7 +183,7 @@ public final class VoiceChatJoinScreen: ViewController {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
class Node: ViewControllerTracingNode, UIScrollViewDelegate {

View File

@ -19,14 +19,14 @@ public func telegramWallpapers(postbox: Postbox, network: Network, forceUpdate:
if case let .file(file) = wallpaper, !file.isDefault {
} else if !addedBuiltin {
addedBuiltin = true
items.append(.builtin(WallpaperSettings()))
items.append(.builtin(nil, WallpaperSettings()))
}
items.append(wallpaper)
}
if !addedBuiltin {
addedBuiltin = true
items.append(.builtin(WallpaperSettings()))
items.append(.builtin(nil, WallpaperSettings()))
}
if items == current {
@ -60,7 +60,7 @@ public func telegramWallpapers(postbox: Postbox, network: Network, forceUpdate:
let configuration = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedWallpapersConfiguration, key: ValueBoxKey(length: 0))) as? CachedWallpapersConfiguration
let items = transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudWallpapers)
if items.count == 0 {
return ([.builtin(WallpaperSettings())], 0)
return ([.builtin(nil, WallpaperSettings())], 0)
} else {
return (items.map { $0.contents as! TelegramWallpaper }, configuration?.hash)
}

View File

@ -39,7 +39,7 @@ public final class PermissionController: ViewController {
let navigationBarPresentationData: NavigationBarPresentationData
if splashScreen {
navigationBarPresentationData = NavigationBarPresentationData(theme: NavigationBarTheme(buttonColor: self.presentationData.theme.rootController.navigationBar.accentTextColor, disabledButtonColor: self.presentationData.theme.rootController.navigationBar.disabledButtonColor, primaryTextColor: self.presentationData.theme.rootController.navigationBar.primaryTextColor, backgroundColor: .clear, separatorColor: .clear, badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear), strings: NavigationBarStrings(presentationStrings: self.presentationData.strings))
navigationBarPresentationData = NavigationBarPresentationData(theme: NavigationBarTheme(buttonColor: self.presentationData.theme.rootController.navigationBar.accentTextColor, disabledButtonColor: self.presentationData.theme.rootController.navigationBar.disabledButtonColor, primaryTextColor: self.presentationData.theme.rootController.navigationBar.primaryTextColor, backgroundColor: .clear, enableBackgroundBlur: false, separatorColor: .clear, badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear), strings: NavigationBarStrings(presentationStrings: self.presentationData.strings))
} else {
navigationBarPresentationData = NavigationBarPresentationData(presentationData: self.presentationData)
}
@ -89,7 +89,7 @@ public final class PermissionController: ViewController {
let navigationBarPresentationData: NavigationBarPresentationData
if self.splashScreen {
navigationBarPresentationData = NavigationBarPresentationData(theme: NavigationBarTheme(buttonColor: self.presentationData.theme.rootController.navigationBar.accentTextColor, disabledButtonColor: self.presentationData.theme.rootController.navigationBar.disabledButtonColor, primaryTextColor: self.presentationData.theme.rootController.navigationBar.primaryTextColor, backgroundColor: .clear, separatorColor: .clear, badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear), strings: NavigationBarStrings(presentationStrings: self.presentationData.strings))
navigationBarPresentationData = NavigationBarPresentationData(theme: NavigationBarTheme(buttonColor: self.presentationData.theme.rootController.navigationBar.accentTextColor, disabledButtonColor: self.presentationData.theme.rootController.navigationBar.disabledButtonColor, primaryTextColor: self.presentationData.theme.rootController.navigationBar.primaryTextColor, backgroundColor: .clear, enableBackgroundBlur: false, separatorColor: .clear, badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear), strings: NavigationBarStrings(presentationStrings: self.presentationData.strings))
} else {
navigationBarPresentationData = NavigationBarPresentationData(presentationData: self.presentationData)
}
@ -253,7 +253,7 @@ public final class PermissionController: ViewController {
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed))
}
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.splashScreen ? 0.0 : self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.splashScreen ? 0.0 : self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc private func nextPressed() {

View File

@ -45,9 +45,9 @@ public extension TabBarControllerTheme {
}
public extension NavigationBarTheme {
convenience init(rootControllerTheme: PresentationTheme, hideBackground: Bool = false, hideBadge: Bool = false) {
convenience init(rootControllerTheme: PresentationTheme, enableBackgroundBlur: Bool = true, hideBackground: Bool = false, hideBadge: Bool = false) {
let theme = rootControllerTheme.rootController.navigationBar
self.init(buttonColor: theme.buttonColor, disabledButtonColor: theme.disabledButtonColor, primaryTextColor: theme.primaryTextColor, backgroundColor: hideBackground ? .clear : theme.backgroundColor, separatorColor: hideBackground ? .clear : theme.separatorColor, badgeBackgroundColor: hideBadge ? .clear : theme.badgeBackgroundColor, badgeStrokeColor: hideBadge ? .clear : theme.badgeStrokeColor, badgeTextColor: hideBadge ? .clear : theme.badgeTextColor)
self.init(buttonColor: theme.buttonColor, disabledButtonColor: theme.disabledButtonColor, primaryTextColor: theme.primaryTextColor, backgroundColor: hideBackground ? .clear : theme.backgroundColor, enableBackgroundBlur: enableBackgroundBlur, separatorColor: hideBackground ? .clear : theme.separatorColor, badgeBackgroundColor: hideBadge ? .clear : theme.badgeBackgroundColor, badgeStrokeColor: hideBadge ? .clear : theme.badgeStrokeColor, badgeTextColor: hideBadge ? .clear : theme.badgeTextColor)
}
}

View File

@ -231,18 +231,6 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
}
public func makeDefaultDarkPresentationTheme(extendingThemeReference: PresentationThemeReference? = nil, preview: Bool) -> PresentationTheme {
let rootTabBar = PresentationThemeRootTabBar(
backgroundColor: UIColor(rgb: 0x1c1c1d, alpha: 0.5),
separatorColor: UIColor(rgb: 0x3d3d40),
iconColor: UIColor(rgb: 0x828282),
selectedIconColor: UIColor(rgb: 0xffffff),
textColor: UIColor(rgb: 0x828282),
selectedTextColor: UIColor(rgb: 0xffffff),
badgeBackgroundColor: UIColor(rgb: 0xffffff),
badgeStrokeColor: UIColor(rgb: 0x1c1c1d),
badgeTextColor: UIColor(rgb: 0x000000)
)
let rootNavigationBar = PresentationThemeRootNavigationBar(
buttonColor: UIColor(rgb: 0xffffff),
disabledButtonColor: UIColor(rgb: 0x525252),
@ -250,7 +238,7 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5),
controlColor: UIColor(rgb: 0x767676),
accentTextColor: UIColor(rgb: 0xffffff),
backgroundColor: UIColor(rgb: 0x1c1c1d, alpha: 0.7).withMultipliedBrightnessBy(1.1),
backgroundColor: UIColor(rgb: 0x1d1d1d, alpha: 0.94),
separatorColor: UIColor(rgb: 0x3d3d40),
badgeBackgroundColor: UIColor(rgb: 0xffffff),
badgeStrokeColor: UIColor(rgb: 0x1c1c1d),
@ -263,6 +251,18 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
clearButtonForegroundColor: UIColor(rgb: 0xffffff)
)
let rootTabBar = PresentationThemeRootTabBar(
backgroundColor: rootNavigationBar.backgroundColor,
separatorColor: UIColor(rgb: 0x3d3d40),
iconColor: UIColor(rgb: 0x828282),
selectedIconColor: UIColor(rgb: 0xffffff),
textColor: UIColor(rgb: 0x828282),
selectedTextColor: UIColor(rgb: 0xffffff),
badgeBackgroundColor: UIColor(rgb: 0xffffff),
badgeStrokeColor: UIColor(rgb: 0x1c1c1d),
badgeTextColor: UIColor(rgb: 0x000000)
)
let navigationSearchBar = PresentationThemeNavigationSearchBar(
backgroundColor: UIColor(rgb: 0x1c1c1d),
accentColor: UIColor(rgb: 0xffffff),
@ -439,8 +439,8 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
)
let inputPanel = PresentationThemeChatInputPanel(
panelBackgroundColor: UIColor(rgb: 0x1c1c1d, alpha: 0.5),
panelBackgroundColorNoWallpaper: UIColor(rgb: 0x000000, alpha: 0.5),
panelBackgroundColor: rootNavigationBar.backgroundColor,
panelBackgroundColorNoWallpaper: UIColor(rgb: 0x000000, alpha: 0.94),
panelSeparatorColor: UIColor(rgb: 0x3d3d40),
panelControlAccentColor: UIColor(rgb: 0xffffff),
panelControlColor: UIColor(rgb: 0x808080),

View File

@ -44,7 +44,7 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
suggestedWallpaper = .gradient(topColor.argb, bottomColor.argb, WallpaperSettings())
} else {
bubbleColors = (UIColor(rgb: 0xe1ffc7), nil)
suggestedWallpaper = .builtin(WallpaperSettings())
suggestedWallpaper = .builtin(nil, WallpaperSettings())
}
}
}
@ -345,7 +345,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
secondaryTextColor: UIColor(rgb: 0x787878),
controlColor: UIColor(rgb: 0x7e8791),
accentTextColor: UIColor(rgb: 0x007ee5),
backgroundColor: UIColor(rgb: 0xffffff, alpha: 0.75),
backgroundColor: UIColor(rgb: 0xf7f7f7, alpha: 0.86),
separatorColor: UIColor(rgb: 0xc8c7cc),
badgeBackgroundColor: UIColor(rgb: 0xff3b30),
badgeStrokeColor: UIColor(rgb: 0xff3b30),
@ -713,7 +713,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
)
let chat = PresentationThemeChat(
defaultWallpaper: day ? .color(0xffffff) : .builtin(WallpaperSettings()),
defaultWallpaper: day ? .color(0xffffff) : .builtin(nil, WallpaperSettings(motion: true)),
message: day ? messageDay : message,
serviceMessage: day ? serviceMessageDay : serviceMessage,
inputPanel: inputPanel,
@ -806,3 +806,10 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
preview: preview
)
}
public let defaultBuiltinWallpaperGradientColors: [UIColor] = [
UIColor(rgb: 0x7FA381),
UIColor(rgb: 0xFFF5C5),
UIColor(rgb: 0x336F55),
UIColor(rgb: 0xFBE37D)
]

View File

@ -496,7 +496,7 @@ public func chatServiceBackgroundColor(wallpaper: TelegramWallpaper, mediaBox: M
} else {
switch wallpaper {
case .builtin:
return .single(UIColor(rgb: 0x748391, alpha: 0.45))
return .single(UIColor(rgb: 0x000000, alpha: 0.2))
case let .color(color):
return .single(serviceColor(with: UIColor(argb: color)))
case let .gradient(topColor, bottomColor, _):
@ -681,7 +681,7 @@ public func defaultPresentationData() -> PresentationData {
let chatBubbleCorners = PresentationChatBubbleCorners(mainRadius: CGFloat(themeSettings.chatBubbleSettings.mainRadius), auxiliaryRadius: CGFloat(themeSettings.chatBubbleSettings.auxiliaryRadius), mergeBubbleCorners: themeSettings.chatBubbleSettings.mergeBubbleCorners)
return PresentationData(strings: defaultPresentationStrings, theme: defaultPresentationTheme, autoNightModeTriggered: false, chatWallpaper: .builtin(WallpaperSettings()), chatFontSize: chatFontSize, chatBubbleCorners: chatBubbleCorners, listsFontSize: listsFontSize, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, nameSortOrder: nameSortOrder, disableAnimations: themeSettings.disableAnimations, largeEmoji: themeSettings.largeEmoji)
return PresentationData(strings: defaultPresentationStrings, theme: defaultPresentationTheme, autoNightModeTriggered: false, chatWallpaper: .builtin(nil, WallpaperSettings()), chatFontSize: chatFontSize, chatBubbleCorners: chatBubbleCorners, listsFontSize: listsFontSize, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, nameSortOrder: nameSortOrder, disableAnimations: themeSettings.disableAnimations, largeEmoji: themeSettings.largeEmoji)
}
public extension PresentationData {

View File

@ -40,7 +40,7 @@ extension TelegramWallpaper: Codable {
if let value = try? values.decode(String.self) {
switch value.lowercased() {
case "builtin":
self = .builtin(WallpaperSettings())
self = .builtin(nil, WallpaperSettings())
default:
let optionKeys = ["motion", "blur"]

View File

@ -85,7 +85,7 @@ final class AuthorizationSequenceAwaitingAccountResetController: ViewController
override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc func logoutPressed() {

View File

@ -119,7 +119,7 @@ final class AuthorizationSequenceCodeEntryController: ViewController {
override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationHeight, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
}
@objc func nextPressed() {

Some files were not shown because too many files have changed in this diff Show More