Swiftgram/submodules/SettingsUI/Sources/Themes/ThemeGridControllerItem.swift

134 lines
4.7 KiB
Swift

import Foundation
import UIKit
import Display
import TelegramCore
import SwiftSignalKit
import AsyncDisplayKit
import Postbox
import AccountContext
import GridMessageSelectionNode
final class ThemeGridControllerItem: GridItem {
let context: AccountContext
let wallpaper: TelegramWallpaper
let wallpaperId: ThemeGridControllerEntry.StableId
let index: Int
let editable: Bool
let selected: Bool
let interaction: ThemeGridControllerInteraction
let section: GridSection? = nil
init(context: AccountContext, wallpaper: TelegramWallpaper, wallpaperId: ThemeGridControllerEntry.StableId, index: Int, editable: Bool, selected: Bool, interaction: ThemeGridControllerInteraction) {
self.context = context
self.wallpaper = wallpaper
self.wallpaperId = wallpaperId
self.index = index
self.editable = editable
self.selected = selected
self.interaction = interaction
}
func node(layout: GridNodeLayout, synchronousLoad: Bool) -> GridItemNode {
let node = ThemeGridControllerItemNode()
node.setup(item: self, synchronousLoad: synchronousLoad)
return node
}
func update(node: GridItemNode) {
guard let node = node as? ThemeGridControllerItemNode else {
assertionFailure()
return
}
node.setup(item: self, synchronousLoad: false)
}
}
final class ThemeGridControllerItemNode: GridItemNode {
private let wallpaperNode: SettingsThemeWallpaperNode
private var selectionNode: GridMessageSelectionNode?
private var item: ThemeGridControllerItem?
override init() {
self.wallpaperNode = SettingsThemeWallpaperNode(displayLoading: false)
super.init()
self.addSubnode(self.wallpaperNode)
}
override func didLoad() {
super.didLoad()
self.view.isExclusiveTouch = true
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
}
func setup(item: ThemeGridControllerItem, synchronousLoad: Bool) {
self.item = item
self.updateSelectionState(animated: false)
self.setNeedsLayout()
}
@objc func tapGesture(_ recognizer: UITapGestureRecognizer) {
if case .ended = recognizer.state {
if let item = self.item {
item.interaction.openWallpaper(item.wallpaper)
}
}
}
func updateSelectionState(animated: Bool) {
if let item = self.item {
let (editing, selectedIds) = item.interaction.selectionState
if editing && item.editable {
let selected = selectedIds.contains(item.wallpaperId)
if let selectionNode = self.selectionNode {
selectionNode.updateSelected(selected, animated: animated)
selectionNode.frame = CGRect(origin: CGPoint(), size: self.bounds.size)
} else {
let theme = item.context.sharedContext.currentPresentationData.with { $0 }.theme
let selectionNode = GridMessageSelectionNode(theme: theme, toggle: { [weak self] value in
if let strongSelf = self {
strongSelf.item?.interaction.toggleWallpaperSelection(item.wallpaperId, value)
}
})
selectionNode.frame = CGRect(origin: CGPoint(), size: self.bounds.size)
self.addSubnode(selectionNode)
self.selectionNode = selectionNode
selectionNode.updateSelected(selected, animated: false)
if animated {
selectionNode.animateIn()
}
}
}
else {
if let selectionNode = self.selectionNode {
self.selectionNode = nil
if animated {
selectionNode.animateOut { [weak selectionNode] in
selectionNode?.removeFromSupernode()
}
} else {
selectionNode.removeFromSupernode()
}
}
}
}
}
override func layout() {
super.layout()
let bounds = self.bounds
if let item = self.item {
self.wallpaperNode.setWallpaper(context: item.context, wallpaper: item.wallpaper, selected: item.selected, size: bounds.size, synchronousLoad: false)
self.selectionNode?.frame = CGRect(origin: CGPoint(), size: bounds.size)
}
}
}