Swiftgram/TelegramUI/WallpaperPatternPanelNode.swift
2019-01-28 14:41:49 +03:00

171 lines
7.2 KiB
Swift

import Foundation
import AsyncDisplayKit
import SwiftSignalKit
import Display
import TelegramCore
private let itemSize = CGSize(width: 88.0, height: 88.0)
private let inset: CGFloat = 12.0
final class WallpaperPatternPanelNode: ASDisplayNode {
private let theme: PresentationTheme
private let backgroundNode: ASDisplayNode
private let topSeparatorNode: ASDisplayNode
private let scrollNode: ASScrollNode
private let intensityNode: WallpaperIntensityPickerNode
private var disposable: Disposable?
private var wallpapers: [TelegramWallpaper] = []
private var currentWallpaper: TelegramWallpaper?
var color: UIColor = .white {
didSet {
let min = self.color.hsv
let max = patternColor(for: self.color, intensity: 1.0).hsv
self.intensityNode.updateExtrema(min: min, max: max)
}
}
var patternChanged: ((TelegramWallpaper, Int32?, Bool) -> Void)?
init(account: Account, theme: PresentationTheme, strings: PresentationStrings) {
self.theme = theme
self.backgroundNode = ASDisplayNode()
self.backgroundNode.backgroundColor = theme.chat.inputPanel.panelBackgroundColor
self.topSeparatorNode = ASDisplayNode()
self.topSeparatorNode.backgroundColor = theme.chat.inputPanel.panelStrokeColor
self.scrollNode = ASScrollNode()
self.intensityNode = WallpaperIntensityPickerNode(theme: theme, title: strings.WallpaperPreview_PatternIntensity, bordered: false)
self.intensityNode.value = 0.4
super.init()
self.addSubnode(self.backgroundNode)
self.addSubnode(self.topSeparatorNode)
self.addSubnode(self.scrollNode)
self.addSubnode(self.intensityNode)
self.disposable = ((telegramWallpapers(postbox: account.postbox, network: account.network)
|> map { wallpapers in
return wallpapers.filter { wallpaper in
if case let .file(file) = wallpaper, file.isPattern, file.file.mimeType != "image/webp" {
return true
} else {
return false
}
}
}
|> deliverOnMainQueue).start(next: { [weak self] wallpapers in
if let strongSelf = self {
if let subnodes = strongSelf.scrollNode.subnodes {
for node in subnodes {
node.removeFromSupernode()
}
}
var selected = true
for wallpaper in wallpapers {
let node = SettingsThemeWallpaperNode(overlayBackgroundColor: UIColor(rgb: 0x748698, alpha: 0.4))
node.clipsToBounds = true
node.cornerRadius = 5.0
var updatedWallpaper = wallpaper
if case let .file(file) = updatedWallpaper {
let settings = WallpaperSettings(blur: false, motion: false, color: 0xd6e2ee, intensity: 100)
updatedWallpaper = .file(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: file.isPattern, slug: file.slug, file: file.file, settings: settings)
}
node.setWallpaper(account: account, wallpaper: updatedWallpaper, selected: selected, size: itemSize)
node.pressed = { [weak self, weak node] in
if let strongSelf = self {
strongSelf.currentWallpaper = updatedWallpaper
strongSelf.patternChanged?(updatedWallpaper, Int32(strongSelf.intensityNode.value * 100), false)
if let subnodes = strongSelf.scrollNode.subnodes {
for case let subnode as SettingsThemeWallpaperNode in subnodes {
subnode.setSelected(node === subnode, animated: true)
}
}
}
}
strongSelf.scrollNode.addSubnode(node)
selected = false
}
strongSelf.scrollNode.view.contentSize = CGSize(width: (itemSize.width + inset) * CGFloat(wallpapers.count) + inset, height: 112.0)
strongSelf.layoutItemNodes(transition: .immediate)
strongSelf.wallpapers = wallpapers
}
}))
self.intensityNode.valueChanged = { [weak self] value in
if let strongSelf = self, let wallpaper = strongSelf.currentWallpaper {
strongSelf.patternChanged?(wallpaper, strongSelf.intensityNode.intensity, true)
}
}
self.intensityNode.valueChangeEnded = { [weak self] value in
if let strongSelf = self, let wallpaper = strongSelf.currentWallpaper {
strongSelf.patternChanged?(wallpaper, strongSelf.intensityNode.intensity, false)
}
}
}
deinit {
self.disposable?.dispose()
}
override func didLoad() {
super.didLoad()
self.scrollNode.view.showsHorizontalScrollIndicator = false
self.scrollNode.view.showsVerticalScrollIndicator = false
self.scrollNode.view.alwaysBounceHorizontal = true
}
func didAppear() {
if let wallpaper = self.wallpapers.first {
self.currentWallpaper = wallpaper
self.intensityNode.value = 0.4
self.scrollNode.view.contentOffset = CGPoint()
var selected = true
if let subnodes = self.scrollNode.subnodes {
for case let subnode as SettingsThemeWallpaperNode in subnodes {
subnode.setSelected(selected, animated: false)
selected = false
}
}
self.patternChanged?(wallpaper, self.intensityNode.intensity, false)
}
}
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) {
let separatorHeight = UIScreenPixel
transition.updateFrame(node: self.backgroundNode, frame: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
transition.updateFrame(node: self.topSeparatorNode, frame: CGRect(x: 0.0, y: 0.0, width: size.width, height: separatorHeight))
transition.updateFrame(node: self.scrollNode, frame: CGRect(x: 0.0, y: 0.0, width: size.width, height: 114.0))
transition.updateFrame(node: self.intensityNode, frame: CGRect(x: 16.0, y: 114.0 + 13.0, width: size.width - 16.0 * 2.0, height: 50.0))
self.layoutItemNodes(transition: transition)
}
private func layoutItemNodes(transition: ContainedViewLayoutTransition) {
var offset: CGFloat = 12.0
if let subnodes = self.scrollNode.subnodes {
for node in subnodes {
transition.updateFrame(node: node, frame: CGRect(x: offset, y: 12.0, width: itemSize.width, height: itemSize.height))
offset += inset + itemSize.width
}
}
}
}