mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-06 17:00:13 +00:00
UI bug fixes
This commit is contained in:
parent
6854173dae
commit
918b069431
@ -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";
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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? {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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]) {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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? {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -0,0 +1 @@
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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]) {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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, _):
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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)))
|
||||
|
||||
@ -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))
|
||||
}
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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] {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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)? {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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)
|
||||
]
|
||||
|
||||
@ -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 {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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"]
|
||||
|
||||
|
||||
Binary file not shown.
@ -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() {
|
||||
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user