mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Wallpaper improvements
This commit is contained in:
@@ -25,7 +25,7 @@ func presentCustomWallpaperPicker(context: AccountContext, present: @escaping (V
|
||||
controller.selectionBlock = { [weak legacyController] asset, _ in
|
||||
if let asset = asset {
|
||||
let controller = WallpaperGalleryController(context: context, source: .asset(asset.backingAsset))
|
||||
controller.apply = { [weak legacyController, weak controller] wallpaper, mode, editedImage, cropRect, brightness in
|
||||
controller.apply = { [weak legacyController, weak controller] wallpaper, mode, editedImage, cropRect, brightness, _ in
|
||||
if let legacyController = legacyController, let controller = controller {
|
||||
uploadCustomWallpaper(context: context, wallpaper: wallpaper, mode: mode, editedImage: nil, cropRect: cropRect, brightness: brightness, completion: { [weak legacyController, weak controller] in
|
||||
if let legacyController = legacyController, let controller = controller {
|
||||
@@ -200,7 +200,7 @@ func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperGalleryE
|
||||
}).start()
|
||||
}
|
||||
|
||||
public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: WallpaperGalleryEntry, mode: WallpaperPresentationOptions, editedImage: UIImage?, cropRect: CGRect?, brightness: CGFloat?, peerId: PeerId, completion: @escaping () -> Void) {
|
||||
public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: WallpaperGalleryEntry, mode: WallpaperPresentationOptions, editedImage: UIImage?, cropRect: CGRect?, brightness: CGFloat?, peerId: PeerId, forBoth: Bool, completion: @escaping () -> Void) {
|
||||
var imageSignal: Signal<UIImage, NoError>
|
||||
switch wallpaper {
|
||||
case let .wallpaper(wallpaper, _):
|
||||
@@ -308,7 +308,7 @@ public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: Wallpa
|
||||
let settings = WallpaperSettings(blur: mode.contains(.blur), motion: mode.contains(.motion), colors: [], intensity: intensity)
|
||||
let temporaryWallpaper: TelegramWallpaper = .image([TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false), TelegramMediaImageRepresentation(dimensions: PixelDimensions(croppedImage.size), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false)], settings)
|
||||
|
||||
context.account.pendingPeerMediaUploadManager.add(peerId: peerId, content: .wallpaper(temporaryWallpaper))
|
||||
context.account.pendingPeerMediaUploadManager.add(peerId: peerId, content: .wallpaper(wallpaper: temporaryWallpaper, forBoth: forBoth))
|
||||
|
||||
Queue.mainQueue().after(0.05) {
|
||||
completion()
|
||||
|
||||
@@ -307,8 +307,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
let doneButtonType: WallpaperGalleryToolbarDoneButtonType
|
||||
if case .edit(_, _, _, _, _, true, _) = self.mode {
|
||||
doneButtonType = .proceed
|
||||
} else if case .peer = resultMode {
|
||||
doneButtonType = .setPeer
|
||||
} else if case let .peer(peer) = resultMode {
|
||||
doneButtonType = .setPeer(peer.compactDisplayTitle, context.isPremium)
|
||||
} else {
|
||||
doneButtonType = .set
|
||||
}
|
||||
@@ -437,7 +437,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
}
|
||||
}
|
||||
|
||||
self.toolbarNode.done = { [weak self] in
|
||||
self.toolbarNode.done = { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
if strongSelf.state.displayPatternPanel {
|
||||
strongSelf.updateState({ current in
|
||||
@@ -774,8 +774,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
} else {
|
||||
if case .edit(_, _, _, _, _, true, _) = self.mode {
|
||||
doneButtonType = .proceed
|
||||
} else if case .peer = self.resultMode {
|
||||
doneButtonType = .setPeer
|
||||
} else if case let .peer(peer) = self.resultMode {
|
||||
doneButtonType = .setPeer(peer.compactDisplayTitle, self.context.isPremium)
|
||||
} else {
|
||||
doneButtonType = .set
|
||||
}
|
||||
@@ -1179,9 +1179,12 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
}
|
||||
|
||||
var toolbarBottomInset = layout.intrinsicInsets.bottom
|
||||
if case .background = mode, toolbarBottomInset.isZero {
|
||||
if case .background = self.mode, toolbarBottomInset.isZero {
|
||||
toolbarBottomInset = 16.0
|
||||
}
|
||||
if case .peer = self.resultMode {
|
||||
toolbarBottomInset += 58.0
|
||||
}
|
||||
let toolbarHeight = 49.0 + toolbarBottomInset
|
||||
transition.updateFrame(node: self.toolbarNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - toolbarHeight), size: CGSize(width: layout.size.width, height: toolbarHeight)))
|
||||
self.toolbarNode.updateLayout(size: CGSize(width: layout.size.width, height: 49.0), layout: layout, transition: transition)
|
||||
|
||||
@@ -157,7 +157,7 @@ final class ThemeColorsGridControllerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
controller.navigationPresentation = .modal
|
||||
controller.apply = { [weak self] wallpaper, _, _, _, _ in
|
||||
controller.apply = { [weak self] wallpaper, _, _, _, _, _ in
|
||||
if let strongSelf = self, let mode = strongSelf.controller?.mode, case let .peer(peer) = mode, case let .wallpaper(wallpaperValue, _) = wallpaper {
|
||||
let _ = (strongSelf.context.engine.themes.setChatWallpaper(peerId: peer.id, wallpaper: wallpaperValue)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|
||||
@@ -120,7 +120,7 @@ public final class ThemeGridController: ViewController {
|
||||
self.displayNode = ThemeGridControllerNode(context: self.context, presentationData: self.presentationData, presentPreviewController: { [weak self] source in
|
||||
if let strongSelf = self {
|
||||
let controller = WallpaperGalleryController(context: strongSelf.context, source: source)
|
||||
controller.apply = { [weak self, weak controller] wallpaper, options, editedImage, cropRect, brightness in
|
||||
controller.apply = { [weak self, weak controller] wallpaper, options, editedImage, cropRect, brightness, _ in
|
||||
if let strongSelf = self {
|
||||
uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: { [weak self, weak controller] in
|
||||
if let strongSelf = self {
|
||||
@@ -160,7 +160,7 @@ public final class ThemeGridController: ViewController {
|
||||
return
|
||||
}
|
||||
let controller = WallpaperGalleryController(context: strongSelf.context, source: .asset(asset))
|
||||
controller.apply = { [weak self] wallpaper, options, editedImage, cropRect, brightness in
|
||||
controller.apply = { [weak self] wallpaper, options, editedImage, cropRect, brightness, _ in
|
||||
if let strongSelf = self {
|
||||
uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: {
|
||||
dismissControllers()
|
||||
|
||||
@@ -183,7 +183,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.toolbarNode.cancel = {
|
||||
dismiss()
|
||||
}
|
||||
self.toolbarNode.done = { [weak self] in
|
||||
self.toolbarNode.done = { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
if !strongSelf.dismissed {
|
||||
strongSelf.dismissed = true
|
||||
|
||||
@@ -192,7 +192,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
private let context: AccountContext
|
||||
private let source: WallpaperListSource
|
||||
private let mode: Mode
|
||||
public var apply: ((WallpaperGalleryEntry, WallpaperPresentationOptions, UIImage?, CGRect?, CGFloat?) -> Void)?
|
||||
public var apply: ((WallpaperGalleryEntry, WallpaperPresentationOptions, UIImage?, CGRect?, CGFloat?, Bool) -> Void)?
|
||||
|
||||
private var interaction: WallpaperGalleryInteraction?
|
||||
|
||||
@@ -497,8 +497,8 @@ public class WallpaperGalleryController: ViewController {
|
||||
default:
|
||||
break
|
||||
}
|
||||
if case .peer = self.mode {
|
||||
doneButtonType = .setPeer
|
||||
if case let .peer(peer, _) = self.mode {
|
||||
doneButtonType = .setPeer(peer.compactDisplayTitle, self.context.isPremium)
|
||||
}
|
||||
|
||||
let toolbarNode = WallpaperGalleryToolbarNode(theme: presentationData.theme, strings: presentationData.strings, doneButtonType: doneButtonType)
|
||||
@@ -515,8 +515,23 @@ public class WallpaperGalleryController: ViewController {
|
||||
self?.dismiss(forceAway: true)
|
||||
}
|
||||
var dismissed = false
|
||||
toolbarNode.done = { [weak self] in
|
||||
toolbarNode.done = { [weak self] forBoth in
|
||||
if let strongSelf = self, !dismissed {
|
||||
if forBoth && !strongSelf.context.isPremium {
|
||||
let context = strongSelf.context
|
||||
var replaceImpl: ((ViewController) -> Void)?
|
||||
let controller = context.sharedContext.makePremiumDemoController(context: context, subject: .voiceToText, action: {
|
||||
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .settings, forceDark: false, dismissed: nil)
|
||||
replaceImpl?(controller)
|
||||
})
|
||||
replaceImpl = { [weak controller] c in
|
||||
controller?.replace(with: c)
|
||||
}
|
||||
strongSelf.push(controller)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if let centralItemNode = strongSelf.galleryNode.pager.centralItemNode() as? WallpaperGalleryItemNode {
|
||||
if centralItemNode.cropNode.scrollNode.view.isDecelerating {
|
||||
return
|
||||
@@ -554,12 +569,12 @@ public class WallpaperGalleryController: ViewController {
|
||||
|> filter({ $0.complete })
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
apply?(entry, options, nil, nil, centralItemNode.brightness)
|
||||
apply?(entry, options, nil, nil, centralItemNode.brightness, forBoth)
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
apply?(entry, options, centralItemNode.editedFullSizeImage, centralItemNode.editedCropRect, centralItemNode.brightness)
|
||||
apply?(entry, options, centralItemNode.editedFullSizeImage, centralItemNode.editedCropRect, centralItemNode.brightness, forBoth)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -717,7 +732,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
break
|
||||
}
|
||||
|
||||
strongSelf.apply?(entry, options, nil, centralItemNode.cropRect, centralItemNode.brightness)
|
||||
strongSelf.apply?(entry, options, nil, centralItemNode.cropRect, centralItemNode.brightness, forBoth)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -953,7 +968,10 @@ public class WallpaperGalleryController: ViewController {
|
||||
self.galleryNode.containerLayoutUpdated(pagerLayout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
|
||||
self.overlayNode?.frame = self.galleryNode.bounds
|
||||
|
||||
let toolbarHeight: CGFloat = 66.0
|
||||
var toolbarHeight: CGFloat = 66.0
|
||||
if case .peer = self.mode {
|
||||
toolbarHeight += 58.0
|
||||
}
|
||||
transition.updateFrame(node: self.toolbarNode!, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - toolbarHeight - layout.intrinsicInsets.bottom), size: CGSize(width: layout.size.width, height: toolbarHeight + layout.intrinsicInsets.bottom)))
|
||||
self.toolbarNode!.updateLayout(size: CGSize(width: layout.size.width, height: toolbarHeight), layout: layout, transition: transition)
|
||||
|
||||
@@ -1051,7 +1069,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
|
||||
self.toolbarNode?.setDoneIsSolid(self.patternPanelEnabled || self.colorsPanelEnabled, transition: transition)
|
||||
|
||||
bottomInset += 66.0
|
||||
bottomInset += toolbarHeight
|
||||
|
||||
self.validLayout = (layout, bottomInset)
|
||||
if !hadLayout {
|
||||
|
||||
@@ -1329,7 +1329,10 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
|
||||
let buttonSpacing: CGFloat = 18.0
|
||||
|
||||
let toolbarHeight: CGFloat = 66.0
|
||||
var toolbarHeight: CGFloat = 66.0
|
||||
if let mode = self.mode, case .peer = mode {
|
||||
toolbarHeight += 58.0
|
||||
}
|
||||
|
||||
let leftButtonFrame = CGRect(origin: CGPoint(x: floor(layout.size.width / 2.0 - buttonSize.width - buttonSpacing) + offset.x, y: layout.size.height - toolbarHeight - layout.intrinsicInsets.bottom - 54.0 + offset.y + additionalYOffset), size: buttonSize)
|
||||
let centerButtonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - buttonSize.width) / 2.0) + offset.x, y: layout.size.height - toolbarHeight - layout.intrinsicInsets.bottom - 54.0 + offset.y + additionalYOffset), size: buttonSize)
|
||||
@@ -1479,6 +1482,9 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
self.nativeNode.updateBubbleTheme(bubbleTheme: self.presentationData.theme, bubbleCorners: self.presentationData.chatBubbleCorners)
|
||||
|
||||
var bottomInset: CGFloat = 132.0
|
||||
if let mode = self.mode, case .peer = mode {
|
||||
bottomInset += 58.0
|
||||
}
|
||||
|
||||
var items: [ListViewItem] = []
|
||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1))
|
||||
|
||||
@@ -3,6 +3,7 @@ import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import TelegramPresentationData
|
||||
import ManagedAnimationNode
|
||||
|
||||
enum WallpaperGalleryToolbarCancelButtonType {
|
||||
case cancel
|
||||
@@ -11,7 +12,7 @@ enum WallpaperGalleryToolbarCancelButtonType {
|
||||
|
||||
enum WallpaperGalleryToolbarDoneButtonType {
|
||||
case set
|
||||
case setPeer
|
||||
case setPeer(String, Bool)
|
||||
case proceed
|
||||
case apply
|
||||
case none
|
||||
@@ -22,7 +23,7 @@ protocol WallpaperGalleryToolbar: ASDisplayNode {
|
||||
var doneButtonType: WallpaperGalleryToolbarDoneButtonType { get set }
|
||||
|
||||
var cancel: (() -> Void)? { get set }
|
||||
var done: (() -> Void)? { get set }
|
||||
var done: ((Bool) -> Void)? { get set }
|
||||
|
||||
func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings)
|
||||
|
||||
@@ -30,6 +31,169 @@ protocol WallpaperGalleryToolbar: ASDisplayNode {
|
||||
}
|
||||
|
||||
final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar {
|
||||
class ButtonNode: ASDisplayNode {
|
||||
private let doneButton = HighlightTrackingButtonNode()
|
||||
private var doneButtonBackgroundNode: ASDisplayNode
|
||||
private let doneButtonTitleNode: ImmediateTextNode
|
||||
private let doneButtonSolidBackgroundNode: ASDisplayNode
|
||||
private let doneButtonSolidTitleNode: ImmediateTextNode
|
||||
|
||||
private let animationNode: SimpleAnimationNode
|
||||
|
||||
var action: () -> Void = {}
|
||||
|
||||
var isLocked: Bool = false {
|
||||
didSet {
|
||||
self.animationNode.isHidden = !self.isLocked
|
||||
}
|
||||
}
|
||||
|
||||
override init() {
|
||||
self.doneButtonBackgroundNode = WallpaperLightButtonBackgroundNode()
|
||||
self.doneButtonBackgroundNode.cornerRadius = 14.0
|
||||
|
||||
self.doneButtonTitleNode = ImmediateTextNode()
|
||||
self.doneButtonTitleNode.displaysAsynchronously = false
|
||||
self.doneButtonTitleNode.isUserInteractionEnabled = false
|
||||
|
||||
self.doneButtonSolidBackgroundNode = ASDisplayNode()
|
||||
self.doneButtonSolidBackgroundNode.alpha = 0.0
|
||||
self.doneButtonSolidBackgroundNode.clipsToBounds = true
|
||||
self.doneButtonSolidBackgroundNode.layer.cornerRadius = 14.0
|
||||
if #available(iOS 13.0, *) {
|
||||
self.doneButtonSolidBackgroundNode.layer.cornerCurve = .continuous
|
||||
}
|
||||
self.doneButtonSolidBackgroundNode.isUserInteractionEnabled = false
|
||||
|
||||
self.doneButtonSolidTitleNode = ImmediateTextNode()
|
||||
self.doneButtonSolidTitleNode.alpha = 0.0
|
||||
self.doneButtonSolidTitleNode.displaysAsynchronously = false
|
||||
self.doneButtonSolidTitleNode.isUserInteractionEnabled = false
|
||||
|
||||
self.animationNode = SimpleAnimationNode(animationName: "premium_unlock", size: CGSize(width: 30.0, height: 30.0))
|
||||
self.animationNode.customColor = .white
|
||||
self.animationNode.isHidden = true
|
||||
|
||||
super.init()
|
||||
|
||||
self.doneButton.isExclusiveTouch = true
|
||||
|
||||
self.addSubnode(self.doneButtonBackgroundNode)
|
||||
self.addSubnode(self.doneButtonTitleNode)
|
||||
|
||||
self.addSubnode(self.doneButtonSolidBackgroundNode)
|
||||
self.addSubnode(self.doneButtonSolidTitleNode)
|
||||
|
||||
self.addSubnode(self.animationNode)
|
||||
|
||||
self.addSubnode(self.doneButton)
|
||||
|
||||
self.doneButton.highligthedChanged = { [weak self] highlighted in
|
||||
if let strongSelf = self {
|
||||
if highlighted {
|
||||
if strongSelf.isSolid {
|
||||
strongSelf.doneButtonSolidBackgroundNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.doneButtonSolidBackgroundNode.alpha = 0.55
|
||||
strongSelf.doneButtonSolidTitleNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.doneButtonSolidTitleNode.alpha = 0.55
|
||||
} else {
|
||||
strongSelf.doneButtonBackgroundNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.doneButtonBackgroundNode.alpha = 0.55
|
||||
strongSelf.doneButtonTitleNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.doneButtonTitleNode.alpha = 0.55
|
||||
}
|
||||
} else {
|
||||
if strongSelf.isSolid {
|
||||
strongSelf.doneButtonSolidBackgroundNode.alpha = 1.0
|
||||
strongSelf.doneButtonSolidBackgroundNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
strongSelf.doneButtonSolidTitleNode.alpha = 1.0
|
||||
strongSelf.doneButtonSolidTitleNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
} else {
|
||||
strongSelf.doneButtonBackgroundNode.alpha = 1.0
|
||||
strongSelf.doneButtonBackgroundNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
strongSelf.doneButtonTitleNode.alpha = 1.0
|
||||
strongSelf.doneButtonTitleNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.doneButton.addTarget(self, action: #selector(self.pressed), forControlEvents: .touchUpInside)
|
||||
}
|
||||
|
||||
func setEnabled(_ enabled: Bool) {
|
||||
self.doneButton.alpha = enabled ? 1.0 : 0.4
|
||||
self.doneButton.isUserInteractionEnabled = enabled
|
||||
}
|
||||
|
||||
private var isSolid = false
|
||||
func setIsSolid(_ isSolid: Bool, transition: ContainedViewLayoutTransition) {
|
||||
guard self.isSolid != isSolid else {
|
||||
return
|
||||
}
|
||||
self.isSolid = isSolid
|
||||
|
||||
transition.updateAlpha(node: self.doneButtonBackgroundNode, alpha: isSolid ? 0.0 : 1.0)
|
||||
transition.updateAlpha(node: self.doneButtonSolidBackgroundNode, alpha: isSolid ? 1.0 : 0.0)
|
||||
transition.updateAlpha(node: self.doneButtonTitleNode, alpha: isSolid ? 0.0 : 1.0)
|
||||
transition.updateAlpha(node: self.doneButtonSolidTitleNode, alpha: isSolid ? 1.0 : 0.0)
|
||||
}
|
||||
|
||||
func updateTitle(_ title: String, theme: PresentationTheme) {
|
||||
self.doneButtonTitleNode.attributedText = NSAttributedString(string: title, font: Font.semibold(17.0), textColor: .white)
|
||||
|
||||
self.doneButtonSolidBackgroundNode.backgroundColor = theme.list.itemCheckColors.fillColor
|
||||
self.doneButtonSolidTitleNode.attributedText = NSAttributedString(string: title, font: Font.semibold(17.0), textColor: theme.list.itemCheckColors.foregroundColor)
|
||||
}
|
||||
|
||||
func updateSize(_ size: CGSize) {
|
||||
let bounds = CGRect(origin: .zero, size: size)
|
||||
self.doneButtonBackgroundNode.frame = bounds
|
||||
if let backgroundNode = self.doneButtonBackgroundNode as? WallpaperOptionBackgroundNode {
|
||||
backgroundNode.updateLayout(size: size)
|
||||
} else if let backgroundNode = self.doneButtonBackgroundNode as? WallpaperLightButtonBackgroundNode {
|
||||
backgroundNode.updateLayout(size: size)
|
||||
}
|
||||
self.doneButtonSolidBackgroundNode.frame = bounds
|
||||
|
||||
let iconSize = CGSize(width: 30.0, height: 30.0)
|
||||
let doneTitleSize = self.doneButtonTitleNode.updateLayout(size)
|
||||
|
||||
var totalWidth = doneTitleSize.width
|
||||
if self.isLocked {
|
||||
totalWidth += iconSize.width + 1.0
|
||||
}
|
||||
let titleOriginX = floorToScreenPixels((bounds.width - totalWidth) / 2.0)
|
||||
|
||||
self.animationNode.frame = CGRect(origin: CGPoint(x: titleOriginX, y: floorToScreenPixels((bounds.height - iconSize.height) / 2.0)), size: iconSize)
|
||||
self.doneButtonTitleNode.frame = CGRect(origin: CGPoint(x: titleOriginX + totalWidth - doneTitleSize.width, y: floorToScreenPixels((bounds.height - doneTitleSize.height) / 2.0)), size: doneTitleSize).offsetBy(dx: bounds.minX, dy: bounds.minY)
|
||||
|
||||
let _ = self.doneButtonSolidTitleNode.updateLayout(size)
|
||||
self.doneButtonSolidTitleNode.frame = self.doneButtonTitleNode.frame
|
||||
|
||||
self.doneButton.frame = bounds
|
||||
}
|
||||
|
||||
var dark: Bool = false {
|
||||
didSet {
|
||||
if self.dark != oldValue {
|
||||
self.doneButtonBackgroundNode.removeFromSupernode()
|
||||
if self.dark {
|
||||
self.doneButtonBackgroundNode = WallpaperOptionBackgroundNode(enableSaturation: true)
|
||||
} else {
|
||||
self.doneButtonBackgroundNode = WallpaperLightButtonBackgroundNode()
|
||||
}
|
||||
self.doneButtonBackgroundNode.cornerRadius = 14.0
|
||||
self.insertSubnode(self.doneButtonBackgroundNode, at: 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc func pressed() {
|
||||
self.action()
|
||||
}
|
||||
}
|
||||
|
||||
private var theme: PresentationTheme
|
||||
private let strings: PresentationStrings
|
||||
|
||||
@@ -44,110 +208,49 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar
|
||||
}
|
||||
}
|
||||
|
||||
var dark: Bool {
|
||||
var dark: Bool = false {
|
||||
didSet {
|
||||
if self.dark != oldValue {
|
||||
self.doneButtonBackgroundNode.removeFromSupernode()
|
||||
if self.dark {
|
||||
self.doneButtonBackgroundNode = WallpaperOptionBackgroundNode(enableSaturation: true)
|
||||
} else {
|
||||
self.doneButtonBackgroundNode = WallpaperLightButtonBackgroundNode()
|
||||
}
|
||||
self.doneButtonBackgroundNode.cornerRadius = 14.0
|
||||
self.insertSubnode(self.doneButtonBackgroundNode, at: 0)
|
||||
}
|
||||
self.applyButton.dark = self.dark
|
||||
self.applyForBothButton.dark = self.dark
|
||||
}
|
||||
}
|
||||
|
||||
private let doneButton = HighlightTrackingButtonNode()
|
||||
private var doneButtonBackgroundNode: ASDisplayNode
|
||||
|
||||
private let doneButtonTitleNode: ImmediateTextNode
|
||||
|
||||
private let doneButtonSolidBackgroundNode: ASDisplayNode
|
||||
private let doneButtonSolidTitleNode: ImmediateTextNode
|
||||
private let applyButton = ButtonNode()
|
||||
private let applyForBothButton = ButtonNode()
|
||||
|
||||
var cancel: (() -> Void)?
|
||||
var done: (() -> Void)?
|
||||
var done: ((Bool) -> Void)?
|
||||
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, cancelButtonType: WallpaperGalleryToolbarCancelButtonType = .cancel, doneButtonType: WallpaperGalleryToolbarDoneButtonType = .set) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.cancelButtonType = cancelButtonType
|
||||
self.doneButtonType = doneButtonType
|
||||
self.dark = false
|
||||
|
||||
self.doneButtonBackgroundNode = WallpaperLightButtonBackgroundNode()
|
||||
self.doneButtonBackgroundNode.cornerRadius = 14.0
|
||||
|
||||
self.doneButtonTitleNode = ImmediateTextNode()
|
||||
self.doneButtonTitleNode.displaysAsynchronously = false
|
||||
self.doneButtonTitleNode.isUserInteractionEnabled = false
|
||||
|
||||
self.doneButtonSolidBackgroundNode = ASDisplayNode()
|
||||
self.doneButtonSolidBackgroundNode.alpha = 0.0
|
||||
self.doneButtonSolidBackgroundNode.clipsToBounds = true
|
||||
self.doneButtonSolidBackgroundNode.layer.cornerRadius = 14.0
|
||||
if #available(iOS 13.0, *) {
|
||||
self.doneButtonSolidBackgroundNode.layer.cornerCurve = .continuous
|
||||
}
|
||||
self.doneButtonSolidBackgroundNode.isUserInteractionEnabled = false
|
||||
|
||||
self.doneButtonSolidTitleNode = ImmediateTextNode()
|
||||
self.doneButtonSolidTitleNode.alpha = 0.0
|
||||
self.doneButtonSolidTitleNode.displaysAsynchronously = false
|
||||
self.doneButtonSolidTitleNode.isUserInteractionEnabled = false
|
||||
|
||||
super.init()
|
||||
|
||||
self.doneButton.isExclusiveTouch = true
|
||||
|
||||
self.addSubnode(self.doneButtonBackgroundNode)
|
||||
self.addSubnode(self.doneButtonTitleNode)
|
||||
|
||||
self.addSubnode(self.doneButtonSolidBackgroundNode)
|
||||
self.addSubnode(self.doneButtonSolidTitleNode)
|
||||
|
||||
self.addSubnode(self.doneButton)
|
||||
self.addSubnode(self.applyButton)
|
||||
if case .setPeer = doneButtonType {
|
||||
self.addSubnode(self.applyForBothButton)
|
||||
}
|
||||
|
||||
self.updateThemeAndStrings(theme: theme, strings: strings)
|
||||
|
||||
self.doneButton.highligthedChanged = { [weak self] highlighted in
|
||||
if let strongSelf = self {
|
||||
if highlighted {
|
||||
if strongSelf.isSolid {
|
||||
strongSelf.doneButtonSolidBackgroundNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.doneButtonSolidBackgroundNode.alpha = 0.55
|
||||
strongSelf.doneButtonSolidTitleNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.doneButtonSolidTitleNode.alpha = 0.55
|
||||
} else {
|
||||
strongSelf.doneButtonBackgroundNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.doneButtonBackgroundNode.alpha = 0.55
|
||||
strongSelf.doneButtonTitleNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.doneButtonTitleNode.alpha = 0.55
|
||||
}
|
||||
} else {
|
||||
if strongSelf.isSolid {
|
||||
strongSelf.doneButtonSolidBackgroundNode.alpha = 1.0
|
||||
strongSelf.doneButtonSolidBackgroundNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
strongSelf.doneButtonSolidTitleNode.alpha = 1.0
|
||||
strongSelf.doneButtonSolidTitleNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
} else {
|
||||
strongSelf.doneButtonBackgroundNode.alpha = 1.0
|
||||
strongSelf.doneButtonBackgroundNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
strongSelf.doneButtonTitleNode.alpha = 1.0
|
||||
strongSelf.doneButtonTitleNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
self.applyButton.action = { [weak self] in
|
||||
if let self {
|
||||
self.done?(false)
|
||||
}
|
||||
}
|
||||
self.applyForBothButton.action = { [weak self] in
|
||||
if let self {
|
||||
self.done?(true)
|
||||
}
|
||||
}
|
||||
|
||||
self.doneButton.addTarget(self, action: #selector(self.donePressed), forControlEvents: .touchUpInside)
|
||||
}
|
||||
|
||||
func setDoneEnabled(_ enabled: Bool) {
|
||||
self.doneButton.alpha = enabled ? 1.0 : 0.4
|
||||
self.doneButton.isUserInteractionEnabled = enabled
|
||||
self.applyButton.setEnabled(enabled)
|
||||
self.applyForBothButton.setEnabled(enabled)
|
||||
}
|
||||
|
||||
private var isSolid = false
|
||||
@@ -155,65 +258,57 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar
|
||||
guard self.isSolid != isSolid else {
|
||||
return
|
||||
}
|
||||
self.isSolid = isSolid
|
||||
|
||||
transition.updateAlpha(node: self.doneButtonBackgroundNode, alpha: isSolid ? 0.0 : 1.0)
|
||||
transition.updateAlpha(node: self.doneButtonSolidBackgroundNode, alpha: isSolid ? 1.0 : 0.0)
|
||||
transition.updateAlpha(node: self.doneButtonTitleNode, alpha: isSolid ? 0.0 : 1.0)
|
||||
transition.updateAlpha(node: self.doneButtonSolidTitleNode, alpha: isSolid ? 1.0 : 0.0)
|
||||
self.isSolid = isSolid
|
||||
self.applyButton.setIsSolid(isSolid, transition: transition)
|
||||
self.applyForBothButton.setIsSolid(isSolid, transition: transition)
|
||||
}
|
||||
|
||||
func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) {
|
||||
self.theme = theme
|
||||
|
||||
let doneTitle: String
|
||||
let applyTitle: String
|
||||
var applyForBothTitle: String? = nil
|
||||
var applyForBothLocked = false
|
||||
switch self.doneButtonType {
|
||||
case .set:
|
||||
doneTitle = strings.Wallpaper_ApplyForAll
|
||||
case .setPeer:
|
||||
doneTitle = strings.Wallpaper_ApplyForChat
|
||||
case .proceed:
|
||||
doneTitle = strings.Theme_Colors_Proceed
|
||||
case .apply:
|
||||
doneTitle = strings.WallpaperPreview_PatternPaternApply
|
||||
case .none:
|
||||
doneTitle = ""
|
||||
self.doneButton.isUserInteractionEnabled = false
|
||||
case .set:
|
||||
applyTitle = strings.Wallpaper_ApplyForAll
|
||||
case let .setPeer(name, isPremium):
|
||||
applyTitle = strings.Wallpaper_ApplyForMe
|
||||
applyForBothTitle = strings.Wallpaper_ApplyForBoth(name).string
|
||||
applyForBothLocked = !isPremium
|
||||
case .proceed:
|
||||
applyTitle = strings.Theme_Colors_Proceed
|
||||
case .apply:
|
||||
applyTitle = strings.WallpaperPreview_PatternPaternApply
|
||||
case .none:
|
||||
applyTitle = ""
|
||||
self.applyButton.isUserInteractionEnabled = false
|
||||
}
|
||||
self.doneButtonTitleNode.attributedText = NSAttributedString(string: doneTitle, font: Font.semibold(17.0), textColor: .white)
|
||||
|
||||
self.doneButtonSolidBackgroundNode.backgroundColor = theme.list.itemCheckColors.fillColor
|
||||
self.doneButtonSolidTitleNode.attributedText = NSAttributedString(string: doneTitle, font: Font.semibold(17.0), textColor: theme.list.itemCheckColors.foregroundColor)
|
||||
self.applyButton.updateTitle(applyTitle, theme: theme)
|
||||
self.applyForBothButton.updateTitle(applyForBothTitle ?? "", theme: theme)
|
||||
self.applyForBothButton.isLocked = applyForBothLocked
|
||||
}
|
||||
|
||||
func updateLayout(size: CGSize, layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||
let inset: CGFloat = 16.0
|
||||
let buttonHeight: CGFloat = 50.0
|
||||
|
||||
let doneFrame = CGRect(origin: CGPoint(x: inset, y: 2.0), size: CGSize(width: size.width - inset * 2.0, height: buttonHeight))
|
||||
self.doneButton.frame = doneFrame
|
||||
self.doneButtonBackgroundNode.frame = doneFrame
|
||||
if let backgroundNode = self.doneButtonBackgroundNode as? WallpaperOptionBackgroundNode {
|
||||
backgroundNode.updateLayout(size: doneFrame.size)
|
||||
} else if let backgroundNode = self.doneButtonBackgroundNode as? WallpaperLightButtonBackgroundNode {
|
||||
backgroundNode.updateLayout(size: doneFrame.size)
|
||||
}
|
||||
self.doneButtonSolidBackgroundNode.frame = doneFrame
|
||||
let spacing: CGFloat = 8.0
|
||||
|
||||
let doneTitleSize = self.doneButtonTitleNode.updateLayout(doneFrame.size)
|
||||
self.doneButtonTitleNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((doneFrame.width - doneTitleSize.width) / 2.0), y: floorToScreenPixels((doneFrame.height - doneTitleSize.height) / 2.0)), size: doneTitleSize).offsetBy(dx: doneFrame.minX, dy: doneFrame.minY)
|
||||
let applyFrame = CGRect(origin: CGPoint(x: inset, y: 2.0), size: CGSize(width: size.width - inset * 2.0, height: buttonHeight))
|
||||
let applyForBothFrame = CGRect(origin: CGPoint(x: inset, y: applyFrame.maxY + spacing), size: CGSize(width: size.width - inset * 2.0, height: buttonHeight))
|
||||
|
||||
let _ = self.doneButtonSolidTitleNode.updateLayout(doneFrame.size)
|
||||
self.doneButtonSolidTitleNode.frame = self.doneButtonTitleNode.frame
|
||||
self.applyButton.frame = applyFrame
|
||||
self.applyButton.updateSize(applyFrame.size)
|
||||
self.applyForBothButton.frame = applyForBothFrame
|
||||
self.applyForBothButton.updateSize(applyForBothFrame.size)
|
||||
}
|
||||
|
||||
@objc func cancelPressed() {
|
||||
self.cancel?()
|
||||
}
|
||||
|
||||
@objc func donePressed() {
|
||||
self.done?()
|
||||
}
|
||||
}
|
||||
|
||||
final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolbar {
|
||||
@@ -240,7 +335,7 @@ final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolb
|
||||
private let topSeparatorNode = ASDisplayNode()
|
||||
|
||||
var cancel: (() -> Void)?
|
||||
var done: (() -> Void)?
|
||||
var done: ((Bool) -> Void)?
|
||||
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, cancelButtonType: WallpaperGalleryToolbarCancelButtonType = .cancel, doneButtonType: WallpaperGalleryToolbarDoneButtonType = .set) {
|
||||
self.theme = theme
|
||||
@@ -343,6 +438,6 @@ final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolb
|
||||
}
|
||||
|
||||
@objc func donePressed() {
|
||||
self.done?()
|
||||
self.done?(false)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user