mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 14:45:21 +00:00
Static spoiler for media
This commit is contained in:
@@ -6,25 +6,11 @@ import AsyncDisplayKit
|
|||||||
import Display
|
import Display
|
||||||
import AppBundle
|
import AppBundle
|
||||||
import LegacyComponents
|
import LegacyComponents
|
||||||
import GameplayKit
|
|
||||||
|
|
||||||
private struct ArbitraryRandomNumberGenerator : RandomNumberGenerator {
|
struct ArbitraryRandomNumberGenerator : RandomNumberGenerator {
|
||||||
init(seed: Int) { srand48(seed) }
|
init(seed: Int) { srand48(seed) }
|
||||||
func next() -> UInt64 { return UInt64(drand48() * Double(UInt64.max)) }
|
func next() -> UInt64 { return UInt64(drand48() * Double(UInt64.max)) }
|
||||||
}
|
}
|
||||||
// mutating func next() -> UInt64 {
|
|
||||||
// // GKRandom produces values in [INT32_MIN, INT32_MAX] range; hence we need two numbers to produce 64-bit value.
|
|
||||||
// let next1 = UInt64(bitPattern: Int64(gkrandom.nextInt()))
|
|
||||||
// let next2 = UInt64(bitPattern: Int64(gkrandom.nextInt()))
|
|
||||||
// return next1 ^ (next2 << 32)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// init(seed: UInt64) {
|
|
||||||
// self.gkrandom = GKMersenneTwisterRandomSource(seed: seed)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private let gkrandom: GKRandom
|
|
||||||
//}
|
|
||||||
|
|
||||||
func createEmitterBehavior(type: String) -> NSObject {
|
func createEmitterBehavior(type: String) -> NSObject {
|
||||||
let selector = ["behaviorWith", "Type:"].joined(separator: "")
|
let selector = ["behaviorWith", "Type:"].joined(separator: "")
|
||||||
@@ -323,7 +309,7 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print("combining \(CACurrentMediaTime() - start)")
|
print("combining \(CACurrentMediaTime() - start)")
|
||||||
|
Queue.concurrentDefaultQueue().async {
|
||||||
var generator = ArbitraryRandomNumberGenerator(seed: 1)
|
var generator = ArbitraryRandomNumberGenerator(seed: 1)
|
||||||
let image = generateImage(size, rotatedContext: { size, context in
|
let image = generateImage(size, rotatedContext: { size, context in
|
||||||
let bounds = CGRect(origin: .zero, size: size)
|
let bounds = CGRect(origin: .zero, size: size)
|
||||||
@@ -340,8 +326,11 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
self.staticNode?.frame = CGRect(origin: CGPoint(), size: size)
|
Queue.mainQueue().async {
|
||||||
self.staticNode?.image = image
|
self.staticNode?.image = image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.staticNode?.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
print("total draw \(CACurrentMediaTime() - start)")
|
print("total draw \(CACurrentMediaTime() - start)")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ public class MediaDustLayer: CALayer {
|
|||||||
public class MediaDustNode: ASDisplayNode {
|
public class MediaDustNode: ASDisplayNode {
|
||||||
private var currentParams: (size: CGSize, color: UIColor)?
|
private var currentParams: (size: CGSize, color: UIColor)?
|
||||||
private var animColor: CGColor?
|
private var animColor: CGColor?
|
||||||
|
private let enableAnimations: Bool
|
||||||
|
|
||||||
private var emitterNode: ASDisplayNode
|
private var emitterNode: ASDisplayNode
|
||||||
private var emitter: CAEmitterCell?
|
private var emitter: CAEmitterCell?
|
||||||
@@ -101,13 +102,18 @@ public class MediaDustNode: ASDisplayNode {
|
|||||||
private let emitterSpotNode: ASImageNode
|
private let emitterSpotNode: ASImageNode
|
||||||
private let emitterMaskFillNode: ASDisplayNode
|
private let emitterMaskFillNode: ASDisplayNode
|
||||||
|
|
||||||
|
private var staticNode: ASImageNode?
|
||||||
|
private var staticParams: CGSize?
|
||||||
|
|
||||||
public var isRevealed = false
|
public var isRevealed = false
|
||||||
private var isExploding = false
|
private var isExploding = false
|
||||||
|
|
||||||
public var revealed: () -> Void = {}
|
public var revealed: () -> Void = {}
|
||||||
public var tapped: () -> Void = {}
|
public var tapped: () -> Void = {}
|
||||||
|
|
||||||
public override init() {
|
public init(enableAnimations: Bool) {
|
||||||
|
self.enableAnimations = enableAnimations
|
||||||
|
|
||||||
self.emitterNode = ASDisplayNode()
|
self.emitterNode = ASDisplayNode()
|
||||||
self.emitterNode.isUserInteractionEnabled = false
|
self.emitterNode.isUserInteractionEnabled = false
|
||||||
self.emitterNode.clipsToBounds = true
|
self.emitterNode.clipsToBounds = true
|
||||||
@@ -132,6 +138,7 @@ public class MediaDustNode: ASDisplayNode {
|
|||||||
public override func didLoad() {
|
public override func didLoad() {
|
||||||
super.didLoad()
|
super.didLoad()
|
||||||
|
|
||||||
|
if self.enableAnimations {
|
||||||
let emitter = CAEmitterCell()
|
let emitter = CAEmitterCell()
|
||||||
emitter.color = UIColor(rgb: 0xffffff, alpha: 0.0).cgColor
|
emitter.color = UIColor(rgb: 0xffffff, alpha: 0.0).cgColor
|
||||||
emitter.contents = UIImage(bundleImageName: "Components/TextSpeckle")?.cgImage
|
emitter.contents = UIImage(bundleImageName: "Components/TextSpeckle")?.cgImage
|
||||||
@@ -191,6 +198,11 @@ public class MediaDustNode: ASDisplayNode {
|
|||||||
self.emitterLayer = emitterLayer
|
self.emitterLayer = emitterLayer
|
||||||
|
|
||||||
self.emitterNode.layer.addSublayer(emitterLayer)
|
self.emitterNode.layer.addSublayer(emitterLayer)
|
||||||
|
} else {
|
||||||
|
let staticNode = ASImageNode()
|
||||||
|
self.staticNode = staticNode
|
||||||
|
self.addSubnode(staticNode)
|
||||||
|
}
|
||||||
|
|
||||||
self.updateEmitter()
|
self.updateEmitter()
|
||||||
|
|
||||||
@@ -207,6 +219,8 @@ public class MediaDustNode: ASDisplayNode {
|
|||||||
self.tapped()
|
self.tapped()
|
||||||
|
|
||||||
self.isRevealed = true
|
self.isRevealed = true
|
||||||
|
|
||||||
|
if self.enableAnimations {
|
||||||
self.isExploding = true
|
self.isExploding = true
|
||||||
|
|
||||||
let position = gestureRecognizer.location(in: self.view)
|
let position = gestureRecognizer.location(in: self.view)
|
||||||
@@ -251,6 +265,12 @@ public class MediaDustNode: ASDisplayNode {
|
|||||||
self.emitterSpotNode.layer.removeAllAnimations()
|
self.emitterSpotNode.layer.removeAllAnimations()
|
||||||
self.emitterMaskFillNode.layer.removeAllAnimations()
|
self.emitterMaskFillNode.layer.removeAllAnimations()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
self.supernode?.alpha = 0.0
|
||||||
|
self.supernode?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, completion: { [weak self] _ in
|
||||||
|
self?.revealed()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var didSetupAnimations = false
|
private var didSetupAnimations = false
|
||||||
@@ -327,7 +347,7 @@ public class MediaDustNode: ASDisplayNode {
|
|||||||
guard let (size, _) = self.currentParams else {
|
guard let (size, _) = self.currentParams else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if self.enableAnimations {
|
||||||
self.emitterLayer?.frame = CGRect(origin: CGPoint(), size: size)
|
self.emitterLayer?.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
self.emitterLayer?.emitterSize = size
|
self.emitterLayer?.emitterSize = size
|
||||||
self.emitterLayer?.emitterPosition = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
self.emitterLayer?.emitterPosition = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
||||||
@@ -340,6 +360,37 @@ public class MediaDustNode: ASDisplayNode {
|
|||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
self.emitter?.birthRate = min(100000.0, square * 0.02)
|
self.emitter?.birthRate = min(100000.0, square * 0.02)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if let staticParams = self.staticParams, staticParams == size && self.staticNode?.image != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.staticParams = size
|
||||||
|
|
||||||
|
let start = CACurrentMediaTime()
|
||||||
|
|
||||||
|
Queue.concurrentDefaultQueue().async {
|
||||||
|
var generator = ArbitraryRandomNumberGenerator(seed: 1)
|
||||||
|
let image = generateImage(size, rotatedContext: { size, context in
|
||||||
|
let bounds = CGRect(origin: .zero, size: size)
|
||||||
|
context.clear(bounds)
|
||||||
|
|
||||||
|
context.setFillColor(UIColor.white.cgColor)
|
||||||
|
let rect = CGRect(origin: .zero, size: size)
|
||||||
|
|
||||||
|
let rate = Int(rect.width * rect.height * 0.04)
|
||||||
|
for _ in 0 ..< rate {
|
||||||
|
let location = CGPoint(x: .random(in: rect.minX ..< rect.maxX, using: &generator), y: .random(in: rect.minY ..< rect.maxY, using: &generator))
|
||||||
|
context.fillEllipse(in: CGRect(origin: location, size: CGSize(width: 1.0, height: 1.0)))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
self.staticNode?.image = image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.staticNode?.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
|
print("total draw \(CACurrentMediaTime() - start)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func update(size: CGSize, color: UIColor, transition: ContainedViewLayoutTransition) {
|
public func update(size: CGSize, color: UIColor, transition: ContainedViewLayoutTransition) {
|
||||||
@@ -351,6 +402,8 @@ public class MediaDustNode: ASDisplayNode {
|
|||||||
self.emitterMaskNode.frame = bounds
|
self.emitterMaskNode.frame = bounds
|
||||||
self.emitterMaskFillNode.frame = bounds
|
self.emitterMaskFillNode.frame = bounds
|
||||||
|
|
||||||
|
self.staticNode?.frame = bounds
|
||||||
|
|
||||||
if self.isNodeLoaded {
|
if self.isNodeLoaded {
|
||||||
self.updateEmitter()
|
self.updateEmitter()
|
||||||
self.setupRandomAnimations()
|
self.setupRandomAnimations()
|
||||||
|
|||||||
@@ -25,24 +25,26 @@ final class MediaPickerGridItem: GridItem {
|
|||||||
let content: MediaPickerGridItemContent
|
let content: MediaPickerGridItemContent
|
||||||
let interaction: MediaPickerInteraction
|
let interaction: MediaPickerInteraction
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
|
let enableAnimations: Bool
|
||||||
|
|
||||||
let section: GridSection? = nil
|
let section: GridSection? = nil
|
||||||
|
|
||||||
init(content: MediaPickerGridItemContent, interaction: MediaPickerInteraction, theme: PresentationTheme) {
|
init(content: MediaPickerGridItemContent, interaction: MediaPickerInteraction, theme: PresentationTheme, enableAnimations: Bool) {
|
||||||
self.content = content
|
self.content = content
|
||||||
self.interaction = interaction
|
self.interaction = interaction
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
self.enableAnimations = enableAnimations
|
||||||
}
|
}
|
||||||
|
|
||||||
func node(layout: GridNodeLayout, synchronousLoad: Bool) -> GridItemNode {
|
func node(layout: GridNodeLayout, synchronousLoad: Bool) -> GridItemNode {
|
||||||
switch self.content {
|
switch self.content {
|
||||||
case let .asset(fetchResult, index):
|
case let .asset(fetchResult, index):
|
||||||
let node = MediaPickerGridItemNode()
|
let node = MediaPickerGridItemNode()
|
||||||
node.setup(interaction: self.interaction, fetchResult: fetchResult, index: index, theme: self.theme)
|
node.setup(interaction: self.interaction, fetchResult: fetchResult, index: index, theme: self.theme, enableAnimations: self.enableAnimations)
|
||||||
return node
|
return node
|
||||||
case let .media(media, index):
|
case let .media(media, index):
|
||||||
let node = MediaPickerGridItemNode()
|
let node = MediaPickerGridItemNode()
|
||||||
node.setup(interaction: self.interaction, media: media, index: index, theme: self.theme)
|
node.setup(interaction: self.interaction, media: media, index: index, theme: self.theme, enableAnimations: self.enableAnimations)
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,13 +56,13 @@ final class MediaPickerGridItem: GridItem {
|
|||||||
assertionFailure()
|
assertionFailure()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
node.setup(interaction: self.interaction, fetchResult: fetchResult, index: index, theme: self.theme)
|
node.setup(interaction: self.interaction, fetchResult: fetchResult, index: index, theme: self.theme, enableAnimations: self.enableAnimations)
|
||||||
case let .media(media, index):
|
case let .media(media, index):
|
||||||
guard let node = node as? MediaPickerGridItemNode else {
|
guard let node = node as? MediaPickerGridItemNode else {
|
||||||
assertionFailure()
|
assertionFailure()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
node.setup(interaction: self.interaction, media: media, index: index, theme: self.theme)
|
node.setup(interaction: self.interaction, media: media, index: index, theme: self.theme, enableAnimations: self.enableAnimations)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,6 +83,8 @@ private let maskImage = generateImage(CGSize(width: 1.0, height: 24.0), opaque:
|
|||||||
final class MediaPickerGridItemNode: GridItemNode {
|
final class MediaPickerGridItemNode: GridItemNode {
|
||||||
var currentMediaState: (TGMediaSelectableItem, Int)?
|
var currentMediaState: (TGMediaSelectableItem, Int)?
|
||||||
var currentState: (PHFetchResult<PHAsset>, Int)?
|
var currentState: (PHFetchResult<PHAsset>, Int)?
|
||||||
|
var enableAnimations: Bool = true
|
||||||
|
|
||||||
private let imageNode: ImageNode
|
private let imageNode: ImageNode
|
||||||
private var checkNode: InteractiveCheckNode?
|
private var checkNode: InteractiveCheckNode?
|
||||||
private let gradientNode: ASImageNode
|
private let gradientNode: ASImageNode
|
||||||
@@ -214,9 +218,10 @@ final class MediaPickerGridItemNode: GridItemNode {
|
|||||||
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.imageNodeTap(_:))))
|
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.imageNodeTap(_:))))
|
||||||
}
|
}
|
||||||
|
|
||||||
func setup(interaction: MediaPickerInteraction, media: MediaPickerScreen.Subject.Media, index: Int, theme: PresentationTheme) {
|
func setup(interaction: MediaPickerInteraction, media: MediaPickerScreen.Subject.Media, index: Int, theme: PresentationTheme, enableAnimations: Bool) {
|
||||||
self.interaction = interaction
|
self.interaction = interaction
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
self.enableAnimations = enableAnimations
|
||||||
|
|
||||||
self.backgroundColor = theme.list.mediaPlaceholderColor
|
self.backgroundColor = theme.list.mediaPlaceholderColor
|
||||||
|
|
||||||
@@ -281,9 +286,10 @@ final class MediaPickerGridItemNode: GridItemNode {
|
|||||||
self.updateHiddenMedia()
|
self.updateHiddenMedia()
|
||||||
}
|
}
|
||||||
|
|
||||||
func setup(interaction: MediaPickerInteraction, fetchResult: PHFetchResult<PHAsset>, index: Int, theme: PresentationTheme) {
|
func setup(interaction: MediaPickerInteraction, fetchResult: PHFetchResult<PHAsset>, index: Int, theme: PresentationTheme, enableAnimations: Bool) {
|
||||||
self.interaction = interaction
|
self.interaction = interaction
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
self.enableAnimations = enableAnimations
|
||||||
|
|
||||||
self.backgroundColor = theme.list.mediaPlaceholderColor
|
self.backgroundColor = theme.list.mediaPlaceholderColor
|
||||||
|
|
||||||
@@ -395,7 +401,7 @@ final class MediaPickerGridItemNode: GridItemNode {
|
|||||||
|
|
||||||
if hasSpoiler {
|
if hasSpoiler {
|
||||||
if self.spoilerNode == nil {
|
if self.spoilerNode == nil {
|
||||||
let spoilerNode = SpoilerOverlayNode()
|
let spoilerNode = SpoilerOverlayNode(enableAnimations: self.enableAnimations)
|
||||||
self.insertSubnode(spoilerNode, aboveSubnode: self.imageNode)
|
self.insertSubnode(spoilerNode, aboveSubnode: self.imageNode)
|
||||||
self.spoilerNode = spoilerNode
|
self.spoilerNode = spoilerNode
|
||||||
|
|
||||||
@@ -458,12 +464,12 @@ class SpoilerOverlayNode: ASDisplayNode {
|
|||||||
private var maskView: UIView?
|
private var maskView: UIView?
|
||||||
private var maskLayer: CAShapeLayer?
|
private var maskLayer: CAShapeLayer?
|
||||||
|
|
||||||
override init() {
|
init(enableAnimations: Bool) {
|
||||||
self.blurNode = ASImageNode()
|
self.blurNode = ASImageNode()
|
||||||
self.blurNode.displaysAsynchronously = false
|
self.blurNode.displaysAsynchronously = false
|
||||||
self.blurNode.contentMode = .scaleAspectFill
|
self.blurNode.contentMode = .scaleAspectFill
|
||||||
|
|
||||||
self.dustNode = MediaDustNode()
|
self.dustNode = MediaDustNode(enableAnimations: enableAnimations)
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ private struct MediaPickerGridEntry: Comparable, Identifiable {
|
|||||||
return lhs.stableId < rhs.stableId
|
return lhs.stableId < rhs.stableId
|
||||||
}
|
}
|
||||||
|
|
||||||
func item(account: Account, interaction: MediaPickerInteraction, theme: PresentationTheme) -> MediaPickerGridItem {
|
func item(context: AccountContext, interaction: MediaPickerInteraction, theme: PresentationTheme) -> MediaPickerGridItem {
|
||||||
return MediaPickerGridItem(content: self.content, interaction: interaction, theme: theme)
|
return MediaPickerGridItem(content: self.content, interaction: interaction, theme: theme, enableAnimations: context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,12 +64,12 @@ private struct MediaPickerGridTransaction {
|
|||||||
let updates: [GridNodeUpdateItem]
|
let updates: [GridNodeUpdateItem]
|
||||||
let scrollToItem: GridNodeScrollToItem?
|
let scrollToItem: GridNodeScrollToItem?
|
||||||
|
|
||||||
init(previousList: [MediaPickerGridEntry], list: [MediaPickerGridEntry], account: Account, interaction: MediaPickerInteraction, theme: PresentationTheme, scrollToItem: GridNodeScrollToItem?) {
|
init(previousList: [MediaPickerGridEntry], list: [MediaPickerGridEntry], context: AccountContext, interaction: MediaPickerInteraction, theme: PresentationTheme, scrollToItem: GridNodeScrollToItem?) {
|
||||||
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: previousList, rightList: list)
|
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: previousList, rightList: list)
|
||||||
|
|
||||||
self.deletions = deleteIndices
|
self.deletions = deleteIndices
|
||||||
self.insertions = indicesAndItems.map { GridNodeInsertItem(index: $0.0, item: $0.1.item(account: account, interaction: interaction, theme: theme), previousIndex: $0.2) }
|
self.insertions = indicesAndItems.map { GridNodeInsertItem(index: $0.0, item: $0.1.item(context: context, interaction: interaction, theme: theme), previousIndex: $0.2) }
|
||||||
self.updates = updateIndices.map { GridNodeUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, interaction: interaction, theme: theme)) }
|
self.updates = updateIndices.map { GridNodeUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, interaction: interaction, theme: theme)) }
|
||||||
|
|
||||||
self.scrollToItem = scrollToItem
|
self.scrollToItem = scrollToItem
|
||||||
}
|
}
|
||||||
@@ -545,7 +545,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
|||||||
scrollToItem = GridNodeScrollToItem(index: entries.count - 1, position: .bottom(0.0), transition: .immediate, directionHint: .down, adjustForSection: false)
|
scrollToItem = GridNodeScrollToItem(index: entries.count - 1, position: .bottom(0.0), transition: .immediate, directionHint: .down, adjustForSection: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
let transaction = MediaPickerGridTransaction(previousList: previousEntries, list: entries, account: controller.context.account, interaction: interaction, theme: self.presentationData.theme, scrollToItem: scrollToItem)
|
let transaction = MediaPickerGridTransaction(previousList: previousEntries, list: entries, context: controller.context, interaction: interaction, theme: self.presentationData.theme, scrollToItem: scrollToItem)
|
||||||
self.enqueueTransaction(transaction)
|
self.enqueueTransaction(transaction)
|
||||||
|
|
||||||
if updateLayout, let (layout, navigationBarHeight) = self.validLayout {
|
if updateLayout, let (layout, navigationBarHeight) = self.validLayout {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import ChatMessageBackground
|
|||||||
private class MediaPickerSelectedItemNode: ASDisplayNode {
|
private class MediaPickerSelectedItemNode: ASDisplayNode {
|
||||||
let asset: TGMediaEditableItem
|
let asset: TGMediaEditableItem
|
||||||
private let interaction: MediaPickerInteraction?
|
private let interaction: MediaPickerInteraction?
|
||||||
|
private let enableAnimations: Bool
|
||||||
|
|
||||||
private let imageNode: ImageNode
|
private let imageNode: ImageNode
|
||||||
private var checkNode: InteractiveCheckNode?
|
private var checkNode: InteractiveCheckNode?
|
||||||
@@ -56,15 +57,16 @@ private class MediaPickerSelectedItemNode: ASDisplayNode {
|
|||||||
|
|
||||||
private var videoDuration: Double?
|
private var videoDuration: Double?
|
||||||
|
|
||||||
init(asset: TGMediaEditableItem, interaction: MediaPickerInteraction?) {
|
init(asset: TGMediaEditableItem, interaction: MediaPickerInteraction?, enableAnimations: Bool) {
|
||||||
|
self.asset = asset
|
||||||
|
self.interaction = interaction
|
||||||
|
self.enableAnimations = enableAnimations
|
||||||
|
|
||||||
self.imageNode = ImageNode()
|
self.imageNode = ImageNode()
|
||||||
self.imageNode.contentMode = .scaleAspectFill
|
self.imageNode.contentMode = .scaleAspectFill
|
||||||
self.imageNode.clipsToBounds = true
|
self.imageNode.clipsToBounds = true
|
||||||
self.imageNode.animateFirstTransition = false
|
self.imageNode.animateFirstTransition = false
|
||||||
|
|
||||||
self.asset = asset
|
|
||||||
self.interaction = interaction
|
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.clipsToBounds = true
|
self.clipsToBounds = true
|
||||||
@@ -165,7 +167,7 @@ private class MediaPickerSelectedItemNode: ASDisplayNode {
|
|||||||
|
|
||||||
if hasSpoiler {
|
if hasSpoiler {
|
||||||
if self.spoilerNode == nil {
|
if self.spoilerNode == nil {
|
||||||
let spoilerNode = SpoilerOverlayNode()
|
let spoilerNode = SpoilerOverlayNode(enableAnimations: self.enableAnimations)
|
||||||
self.insertSubnode(spoilerNode, aboveSubnode: self.imageNode)
|
self.insertSubnode(spoilerNode, aboveSubnode: self.imageNode)
|
||||||
self.spoilerNode = spoilerNode
|
self.spoilerNode = spoilerNode
|
||||||
|
|
||||||
@@ -781,7 +783,7 @@ final class MediaPickerSelectedListNode: ASDisplayNode, UIScrollViewDelegate, UI
|
|||||||
if let current = self.itemNodes[identifier] {
|
if let current = self.itemNodes[identifier] {
|
||||||
itemNode = current
|
itemNode = current
|
||||||
} else {
|
} else {
|
||||||
itemNode = MediaPickerSelectedItemNode(asset: asset, interaction: self.interaction)
|
itemNode = MediaPickerSelectedItemNode(asset: asset, interaction: self.interaction, enableAnimations: self.context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||||
self.itemNodes[identifier] = itemNode
|
self.itemNodes[identifier] = itemNode
|
||||||
self.scrollNode.addSubnode(itemNode)
|
self.scrollNode.addSubnode(itemNode)
|
||||||
|
|
||||||
|
|||||||
@@ -189,11 +189,11 @@ private class ExtendedMediaOverlayNode: ASDisplayNode {
|
|||||||
var isRevealed = false
|
var isRevealed = false
|
||||||
var tapped: () -> Void = {}
|
var tapped: () -> Void = {}
|
||||||
|
|
||||||
override init() {
|
init(enableAnimations: Bool) {
|
||||||
self.blurredImageNode = TransformImageNode()
|
self.blurredImageNode = TransformImageNode()
|
||||||
self.blurredImageNode.contentAnimations = []
|
self.blurredImageNode.contentAnimations = []
|
||||||
|
|
||||||
self.dustNode = MediaDustNode()
|
self.dustNode = MediaDustNode(enableAnimations: enableAnimations)
|
||||||
|
|
||||||
self.buttonNode = HighlightTrackingButtonNode()
|
self.buttonNode = HighlightTrackingButtonNode()
|
||||||
self.buttonNode.backgroundColor = UIColor(rgb: 0x000000, alpha: 0.3)
|
self.buttonNode.backgroundColor = UIColor(rgb: 0x000000, alpha: 0.3)
|
||||||
@@ -1898,7 +1898,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
|
|
||||||
if displaySpoiler {
|
if displaySpoiler {
|
||||||
if self.extendedMediaOverlayNode == nil {
|
if self.extendedMediaOverlayNode == nil {
|
||||||
let extendedMediaOverlayNode = ExtendedMediaOverlayNode()
|
let extendedMediaOverlayNode = ExtendedMediaOverlayNode(enableAnimations: self.context?.sharedContext.energyUsageSettings.fullTranslucency ?? true)
|
||||||
extendedMediaOverlayNode.tapped = { [weak self] in
|
extendedMediaOverlayNode.tapped = { [weak self] in
|
||||||
self?.internallyVisible = true
|
self?.internallyVisible = true
|
||||||
self?.updateVisibility()
|
self?.updateVisibility()
|
||||||
|
|||||||
Reference in New Issue
Block a user