mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
403 lines
22 KiB
Swift
403 lines
22 KiB
Swift
import Foundation
|
|
import AsyncDisplayKit
|
|
import Display
|
|
|
|
private let closeButtonImage = generateImage(CGSize(width: 12.0, height: 12.0), contextGenerator: { size, context in
|
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
|
context.setStrokeColor(UIColor(0x9099A2).cgColor)
|
|
context.setLineWidth(2.0)
|
|
context.setLineCap(.round)
|
|
context.move(to: CGPoint(x: 1.0, y: 1.0))
|
|
context.addLine(to: CGPoint(x: size.width - 1.0, y: size.height - 1.0))
|
|
context.strokePath()
|
|
context.move(to: CGPoint(x: size.width - 1.0, y: 1.0))
|
|
context.addLine(to: CGPoint(x: 1.0, y: size.height - 1.0))
|
|
context.strokePath()
|
|
})
|
|
|
|
private let titleFont = Font.regular(12.0)
|
|
private let subtitleFont = Font.regular(10.0)
|
|
private let maximizedTitleFont = Font.bold(17.0)
|
|
private let maximizedSubtitleFont = Font.regular(12.0)
|
|
|
|
private let titleColor = UIColor.black
|
|
private let subtitleColor = UIColor(0x8b8b8b)
|
|
|
|
private let playIcon = UIImage(bundleImageName: "GlobalMusicPlayer/MinimizedPlay")?.precomposed()
|
|
private let pauseIcon = UIImage(bundleImageName: "GlobalMusicPlayer/MinimizedPause")?.precomposed()
|
|
private let maximizedPlayIcon = UIImage(bundleImageName: "GlobalMusicPlayer/Play")?.precomposed()
|
|
private let maximizedPauseIcon = UIImage(bundleImageName: "GlobalMusicPlayer/Pause")?.precomposed()
|
|
private let maximizedPreviousIcon = UIImage(bundleImageName: "GlobalMusicPlayer/Previous")?.precomposed()
|
|
private let maximizedNextIcon = UIImage(bundleImageName: "GlobalMusicPlayer/Next")?.precomposed()
|
|
private let maximizedShuffleIcon = UIImage(bundleImageName: "GlobalMusicPlayer/Shuffle")?.precomposed()
|
|
private let maximizedRepeatIcon = UIImage(bundleImageName: "GlobalMusicPlayer/Repeat")?.precomposed()
|
|
|
|
final class MediaNavigationAccessoryHeaderNode: ASDisplayNode {
|
|
static let minimizedHeight: CGFloat = 37.0
|
|
static let maximizedHeight: CGFloat = 166.0
|
|
|
|
private let titleNode: TextNode
|
|
private let subtitleNode: TextNode
|
|
private let maximizedTitleNode: TextNode
|
|
private let maximizedSubtitleNode: TextNode
|
|
|
|
private let closeButton: HighlightableButtonNode
|
|
private let actionButton: HighlightTrackingButtonNode
|
|
private let actionPauseNode: ASImageNode
|
|
private let actionPlayNode: ASImageNode
|
|
|
|
private let maximizedLeftTimestampNode: MediaPlayerTimeTextNode
|
|
private let maximizedRightTimestampNode: MediaPlayerTimeTextNode
|
|
private let maximizedActionButton: HighlightableButtonNode
|
|
private let maximizedActionPauseNode: ASImageNode
|
|
private let maximizedActionPlayNode: ASImageNode
|
|
private let maximizedPreviousButton: HighlightableButtonNode
|
|
private let maximizedNextButton: HighlightableButtonNode
|
|
private let maximizedShuffleButton: HighlightableButtonNode
|
|
private let maximizedRepeatButton: HighlightableButtonNode
|
|
|
|
private let scrubbingNode: MediaPlayerScrubbingNode
|
|
private let maximizedScrubbingNode: MediaPlayerScrubbingNode
|
|
|
|
private var tapRecognizer: UITapGestureRecognizer?
|
|
|
|
var expand: (() -> Void)?
|
|
|
|
var close: (() -> Void)?
|
|
var togglePlayPause: (() -> Void)?
|
|
var previous: (() -> Void)?
|
|
var next: (() -> Void)?
|
|
var seek: ((Double) -> Void)?
|
|
|
|
var stateAndStatus: AudioPlaylistStateAndStatus? {
|
|
didSet {
|
|
if self.stateAndStatus != oldValue {
|
|
self.updateLayout(size: self.bounds.size, transition: .immediate)
|
|
self.scrubbingNode.status = stateAndStatus?.status
|
|
self.maximizedScrubbingNode.status = stateAndStatus?.status
|
|
self.maximizedLeftTimestampNode.status = stateAndStatus?.status
|
|
self.maximizedRightTimestampNode.status = stateAndStatus?.status
|
|
}
|
|
}
|
|
}
|
|
|
|
override init() {
|
|
self.titleNode = TextNode()
|
|
self.titleNode.isLayerBacked = true
|
|
self.subtitleNode = TextNode()
|
|
self.subtitleNode.isLayerBacked = true
|
|
|
|
self.maximizedTitleNode = TextNode()
|
|
self.maximizedTitleNode.isLayerBacked = true
|
|
self.maximizedSubtitleNode = TextNode()
|
|
self.maximizedSubtitleNode.isLayerBacked = true
|
|
|
|
self.closeButton = HighlightableButtonNode()
|
|
self.closeButton.setImage(closeButtonImage, for: [])
|
|
self.closeButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0)
|
|
self.closeButton.displaysAsynchronously = false
|
|
|
|
self.actionButton = HighlightTrackingButtonNode()
|
|
self.actionButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0)
|
|
self.actionButton.displaysAsynchronously = false
|
|
|
|
self.actionPauseNode = ASImageNode()
|
|
self.actionPauseNode.contentMode = .center
|
|
self.actionPauseNode.isLayerBacked = true
|
|
self.actionPauseNode.displaysAsynchronously = false
|
|
self.actionPauseNode.displayWithoutProcessing = true
|
|
self.actionPauseNode.image = pauseIcon
|
|
|
|
self.actionPlayNode = ASImageNode()
|
|
self.actionPlayNode.contentMode = .center
|
|
self.actionPlayNode.isLayerBacked = true
|
|
self.actionPlayNode.displaysAsynchronously = false
|
|
self.actionPlayNode.displayWithoutProcessing = true
|
|
self.actionPlayNode.image = playIcon
|
|
self.actionPlayNode.isHidden = true
|
|
|
|
self.maximizedLeftTimestampNode = MediaPlayerTimeTextNode()
|
|
self.maximizedRightTimestampNode = MediaPlayerTimeTextNode()
|
|
self.maximizedLeftTimestampNode.alignment = .right
|
|
self.maximizedRightTimestampNode.mode = .reversed
|
|
|
|
self.maximizedActionButton = HighlightableButtonNode()
|
|
self.maximizedActionButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0)
|
|
self.maximizedActionButton.displaysAsynchronously = false
|
|
|
|
self.maximizedActionPauseNode = ASImageNode()
|
|
self.maximizedActionPauseNode.isLayerBacked = true
|
|
self.maximizedActionPauseNode.displaysAsynchronously = false
|
|
self.maximizedActionPauseNode.displayWithoutProcessing = true
|
|
self.maximizedActionPauseNode.image = maximizedPauseIcon
|
|
|
|
self.maximizedActionPlayNode = ASImageNode()
|
|
self.maximizedActionPlayNode.isLayerBacked = true
|
|
self.maximizedActionPlayNode.displaysAsynchronously = false
|
|
self.maximizedActionPlayNode.displayWithoutProcessing = true
|
|
self.maximizedActionPlayNode.image = maximizedPlayIcon
|
|
self.maximizedActionPlayNode.isHidden = true
|
|
|
|
let maximizedActionButtonSize = CGSize(width: 66.0, height: 50.0)
|
|
self.maximizedActionButton.frame = CGRect(origin: CGPoint(), size: maximizedActionButtonSize)
|
|
if let maximizedPauseIcon = maximizedPauseIcon {
|
|
self.maximizedActionPauseNode.frame = CGRect(origin: CGPoint(x: floor((maximizedActionButtonSize.width - maximizedPauseIcon.size.width) / 2.0), y: floor((maximizedActionButtonSize.height - maximizedPauseIcon.size.height) / 2.0)), size: maximizedPauseIcon.size)
|
|
}
|
|
if let maximizedPlayIcon = maximizedPlayIcon {
|
|
self.maximizedActionPlayNode.frame = CGRect(origin: CGPoint(x: floor((maximizedActionButtonSize.width - maximizedPlayIcon.size.width) / 2.0) + 2.0, y: floor((maximizedActionButtonSize.height - maximizedPlayIcon.size.height) / 2.0)), size: maximizedPlayIcon.size)
|
|
}
|
|
|
|
self.maximizedPreviousButton = HighlightableButtonNode()
|
|
self.maximizedPreviousButton.setImage(maximizedPreviousIcon, for: [])
|
|
self.maximizedPreviousButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0)
|
|
self.maximizedPreviousButton.displaysAsynchronously = false
|
|
|
|
self.maximizedNextButton = HighlightableButtonNode()
|
|
self.maximizedNextButton.setImage(maximizedNextIcon, for: [])
|
|
self.maximizedNextButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0)
|
|
self.maximizedNextButton.displaysAsynchronously = false
|
|
|
|
self.maximizedShuffleButton = HighlightableButtonNode()
|
|
self.maximizedShuffleButton.setImage(maximizedShuffleIcon, for: [])
|
|
self.maximizedShuffleButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0)
|
|
self.maximizedShuffleButton.displaysAsynchronously = false
|
|
|
|
self.maximizedRepeatButton = HighlightableButtonNode()
|
|
self.maximizedRepeatButton.setImage(maximizedRepeatIcon, for: [])
|
|
self.maximizedRepeatButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0)
|
|
self.maximizedRepeatButton.displaysAsynchronously = false
|
|
|
|
self.scrubbingNode = MediaPlayerScrubbingNode(lineHeight: 2.0, lineCap: .square, scrubberHandle: false, backgroundColor: .clear, foregroundColor: UIColor(0x007ee5))
|
|
self.maximizedScrubbingNode = MediaPlayerScrubbingNode(lineHeight: 3.0, lineCap: .round, scrubberHandle: true, backgroundColor: UIColor(0xcfcccf), foregroundColor: UIColor(0x007ee5))
|
|
|
|
|
|
super.init()
|
|
|
|
self.clipsToBounds = true
|
|
|
|
self.addSubnode(self.titleNode)
|
|
self.addSubnode(self.subtitleNode)
|
|
self.addSubnode(self.maximizedTitleNode)
|
|
self.addSubnode(self.maximizedSubtitleNode)
|
|
|
|
self.addSubnode(self.closeButton)
|
|
|
|
self.actionButton.addSubnode(self.actionPauseNode)
|
|
self.actionButton.addSubnode(self.actionPlayNode)
|
|
self.addSubnode(self.actionButton)
|
|
|
|
self.addSubnode(self.maximizedLeftTimestampNode)
|
|
self.addSubnode(self.maximizedRightTimestampNode)
|
|
|
|
self.maximizedActionButton.addSubnode(self.maximizedActionPauseNode)
|
|
self.maximizedActionButton.addSubnode(self.maximizedActionPlayNode)
|
|
self.addSubnode(self.maximizedActionButton)
|
|
self.addSubnode(self.maximizedPreviousButton)
|
|
self.addSubnode(self.maximizedNextButton)
|
|
self.addSubnode(self.maximizedShuffleButton)
|
|
self.addSubnode(self.maximizedRepeatButton)
|
|
|
|
self.closeButton.addTarget(self, action: #selector(self.closeButtonPressed), forControlEvents: .touchUpInside)
|
|
self.actionButton.addTarget(self, action: #selector(self.actionButtonPressed), forControlEvents: .touchUpInside)
|
|
self.maximizedActionButton.addTarget(self, action: #selector(self.actionButtonPressed), forControlEvents: .touchUpInside)
|
|
self.maximizedPreviousButton.addTarget(self, action: #selector(self.previousButtonPressed), forControlEvents: .touchUpInside)
|
|
self.maximizedNextButton.addTarget(self, action: #selector(self.nextButtonPressed), forControlEvents: .touchUpInside)
|
|
self.maximizedShuffleButton.addTarget(self, action: #selector(self.shuffleButtonPressed), forControlEvents: .touchUpInside)
|
|
self.maximizedRepeatButton.addTarget(self, action: #selector(self.repeatButtonPressed), forControlEvents: .touchUpInside)
|
|
|
|
self.addSubnode(self.maximizedScrubbingNode)
|
|
self.addSubnode(self.scrubbingNode)
|
|
|
|
self.actionButton.highligthedChanged = { [weak self] highlighted in
|
|
if let strongSelf = self {
|
|
if highlighted {
|
|
strongSelf.actionButton.layer.removeAnimation(forKey: "opacity")
|
|
strongSelf.actionButton.alpha = 0.4
|
|
} else {
|
|
strongSelf.actionButton.alpha = 1.0
|
|
strongSelf.actionButton.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
|
}
|
|
}
|
|
}
|
|
|
|
self.scrubbingNode.playbackStatusUpdated = { [weak self] status in
|
|
if let strongSelf = self {
|
|
let paused: Bool
|
|
if let status = status {
|
|
switch status {
|
|
case .paused:
|
|
paused = true
|
|
case let .buffering(whilePlaying):
|
|
paused = !whilePlaying
|
|
case .playing:
|
|
paused = false
|
|
}
|
|
} else {
|
|
paused = true
|
|
}
|
|
strongSelf.actionPlayNode.isHidden = !paused
|
|
strongSelf.actionPauseNode.isHidden = paused
|
|
strongSelf.maximizedActionPlayNode.isHidden = !paused
|
|
strongSelf.maximizedActionPauseNode.isHidden = paused
|
|
}
|
|
}
|
|
|
|
self.maximizedScrubbingNode.seek = { [weak self] timestamp in
|
|
self?.seek?(timestamp)
|
|
}
|
|
}
|
|
|
|
override func didLoad() {
|
|
super.didLoad()
|
|
|
|
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))
|
|
self.tapRecognizer = tapRecognizer
|
|
self.view.addGestureRecognizer(tapRecognizer)
|
|
}
|
|
|
|
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) {
|
|
let minHeight = MediaNavigationAccessoryHeaderNode.minimizedHeight
|
|
let maxHeight = MediaNavigationAccessoryHeaderNode.maximizedHeight
|
|
let maximizationFactor = (size.height - minHeight) / (maxHeight - minHeight)
|
|
|
|
let enableExpandTap = maximizationFactor.isEqual(to: 0.0)
|
|
if let tapRecognizer = self.tapRecognizer, tapRecognizer.isEnabled != enableExpandTap {
|
|
tapRecognizer.isEnabled = enableExpandTap
|
|
}
|
|
|
|
var titleString: NSAttributedString?
|
|
var subtitleString: NSAttributedString?
|
|
var maximizedTitleString: NSAttributedString?
|
|
var maximizedSubtitleString: NSAttributedString?
|
|
if let stateAndStatus = self.stateAndStatus, let item = stateAndStatus.state.item, let info = item.info {
|
|
switch info.labelInfo {
|
|
case let .music(title, performer):
|
|
let titleText: String = title ?? "Unknown Track"
|
|
let subtitleText: String = performer ?? "Unknown Artist"
|
|
|
|
titleString = NSAttributedString(string: titleText, font: titleFont, textColor: titleColor)
|
|
subtitleString = NSAttributedString(string: subtitleText, font: subtitleFont, textColor: subtitleColor)
|
|
|
|
maximizedTitleString = NSAttributedString(string: titleText, font: maximizedTitleFont, textColor: titleColor)
|
|
maximizedSubtitleString = NSAttributedString(string: subtitleText, font: maximizedSubtitleFont, textColor: subtitleColor)
|
|
case .voice:
|
|
let titleText: String = "Voice Message"
|
|
titleString = NSAttributedString(string: titleText, font: titleFont, textColor: titleColor)
|
|
|
|
maximizedTitleString = NSAttributedString(string: titleText, font: maximizedTitleFont, textColor: titleColor)
|
|
}
|
|
}
|
|
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
|
|
let makeSubtitleLayout = TextNode.asyncLayout(self.subtitleNode)
|
|
let makeMaximizedTitleLayout = TextNode.asyncLayout(self.maximizedTitleNode)
|
|
let makeMaximizedSubtitleLayout = TextNode.asyncLayout(self.maximizedSubtitleNode)
|
|
|
|
let (titleLayout, titleApply) = makeTitleLayout(titleString, nil, 1, .middle, CGSize(width: size.width - 80.0, height: 100.0), .natural, nil)
|
|
let (subtitleLayout, subtitleApply) = makeSubtitleLayout(subtitleString, nil, 1, .middle, CGSize(width: size.width - 80.0, height: 100.0), .natural, nil)
|
|
|
|
let (maximizedTitleLayout, maximizedTitleApply) = makeMaximizedTitleLayout(maximizedTitleString, nil, 1, .middle, CGSize(width: size.width - 80.0, height: 100.0), .natural, nil)
|
|
let (maximizedSubtitleLayout, maximizedSubtitleApply) = makeMaximizedSubtitleLayout(maximizedSubtitleString, nil, 1, .middle, CGSize(width: size.width - 80.0, height: 100.0), .natural, nil)
|
|
|
|
titleApply()
|
|
subtitleApply()
|
|
maximizedTitleApply()
|
|
maximizedSubtitleApply()
|
|
|
|
let minimizedTitleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleLayout.size.width) / 2.0), y: 4.0), size: titleLayout.size)
|
|
let minimizedSubtitleFrame = CGRect(origin: CGPoint(x: floor((size.width - subtitleLayout.size.width) / 2.0), y: 20.0), size: subtitleLayout.size)
|
|
|
|
let maximizedTitleFrame = CGRect(origin: CGPoint(x: floor((size.width - maximizedTitleLayout.size.width) / 2.0), y: 57.0), size: maximizedTitleLayout.size)
|
|
let maximizedSubtitleFrame = CGRect(origin: CGPoint(x: floor((size.width - maximizedSubtitleLayout.size.width) / 2.0), y: 80.0), size: maximizedSubtitleLayout.size)
|
|
|
|
let maximizedTitleDistance = maximizedTitleFrame.midY - minimizedTitleFrame.midY
|
|
let maximizedSubtitleDistance = maximizedSubtitleFrame.midY - minimizedSubtitleFrame.midY
|
|
|
|
let updatedMinimizedTitleFrame = minimizedTitleFrame.offsetBy(dx: 0.0, dy: maximizedTitleDistance * maximizationFactor)
|
|
let updatedMaximizedTitleFrame = maximizedTitleFrame.offsetBy(dx: 0.0, dy: -maximizedTitleDistance * (1.0 - maximizationFactor))
|
|
|
|
transition.updateFrame(node: self.titleNode, frame: updatedMinimizedTitleFrame)
|
|
transition.updateFrame(node: self.subtitleNode, frame: minimizedSubtitleFrame.offsetBy(dx: 0.0, dy: maximizedSubtitleDistance * maximizationFactor))
|
|
|
|
transition.updateFrame(node: self.maximizedTitleNode, frame: updatedMaximizedTitleFrame)
|
|
transition.updateFrame(node: self.maximizedSubtitleNode, frame: maximizedSubtitleFrame.offsetBy(dx: 0.0, dy: -maximizedSubtitleDistance * (1.0 - maximizationFactor)))
|
|
|
|
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, y: updatedMinimizedTitleFrame.minY + 8.0), size: closeButtonSize))
|
|
transition.updateFrame(node: self.actionPlayNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 40.0, height: 37.0)))
|
|
transition.updateFrame(node: self.actionPauseNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 40.0, height: 37.0)))
|
|
transition.updateFrame(node: self.actionButton, frame: CGRect(origin: CGPoint(x: 0.0, y: updatedMinimizedTitleFrame.minY - 4.0), size: CGSize(width: 40.0, height: 37.0)))
|
|
transition.updateFrame(node: self.scrubbingNode, frame: CGRect(origin: CGPoint(x: 0.0, y: (37.0 + (maxHeight - minHeight) * maximizationFactor) - 2.0), size: CGSize(width: size.width, height: 2.0)))
|
|
transition.updateFrame(node: self.maximizedScrubbingNode, frame: CGRect(origin: CGPoint(x: 57.0, y: updatedMaximizedTitleFrame.minY - 38.0), size: CGSize(width: size.width - 114.0, height: 15.0)))
|
|
|
|
transition.updateFrame(node: self.maximizedLeftTimestampNode, frame: CGRect(origin: CGPoint(x: 0.0, y: updatedMaximizedTitleFrame.minY - 39.0), size: CGSize(width: 57.0 - 13.0, height: 20.0)))
|
|
transition.updateFrame(node: self.maximizedRightTimestampNode, frame: CGRect(origin: CGPoint(x: size.width - 57.0 + 13.0, y: updatedMaximizedTitleFrame.minY - 39.0), size: CGSize(width: 57.0 - 13.0, height: 20.0)))
|
|
|
|
let maximizedActionButtonSize = self.maximizedActionButton.bounds.size
|
|
let maximizedActionButtonFrame = CGRect(origin: CGPoint(x: floor((size.width - maximizedActionButtonSize.width) / 2.0), y: updatedMaximizedTitleFrame.maxY + 26.0), size: maximizedActionButtonSize)
|
|
transition.updateFrame(node: self.maximizedActionButton, frame: maximizedActionButtonFrame)
|
|
|
|
let actionButtonSpacing: CGFloat = 10.0
|
|
transition.updateFrame(node: self.maximizedPreviousButton, frame: CGRect(origin: CGPoint(x: maximizedActionButtonFrame.minX - maximizedActionButtonSize.width - actionButtonSpacing, y: maximizedActionButtonFrame.minY), size: maximizedActionButtonSize))
|
|
transition.updateFrame(node: self.maximizedNextButton, frame: CGRect(origin: CGPoint(x: maximizedActionButtonFrame.maxX + actionButtonSpacing, y: maximizedActionButtonFrame.minY), size: maximizedActionButtonSize))
|
|
transition.updateFrame(node: self.maximizedShuffleButton, frame: CGRect(origin: CGPoint(x: 0.0, y: maximizedActionButtonFrame.minY), size: CGSize(width: 56.0, height: 50.0)))
|
|
transition.updateFrame(node: self.maximizedRepeatButton, frame: CGRect(origin: CGPoint(x: size.width - 56.0, y: maximizedActionButtonFrame.minY), size: CGSize(width: 56.0, height: 50.0)))
|
|
|
|
transition.updateAlpha(node: self.actionButton, alpha: 1.0 - maximizationFactor)
|
|
transition.updateAlpha(node: self.closeButton, alpha: 1.0 - maximizationFactor)
|
|
|
|
transition.updateAlpha(node: self.maximizedActionButton, alpha: maximizationFactor)
|
|
transition.updateAlpha(node: self.maximizedPreviousButton, alpha: maximizationFactor)
|
|
transition.updateAlpha(node: self.maximizedNextButton, alpha: maximizationFactor)
|
|
transition.updateAlpha(node: self.maximizedPreviousButton, alpha: maximizationFactor)
|
|
transition.updateAlpha(node: self.maximizedShuffleButton, alpha: maximizationFactor)
|
|
transition.updateAlpha(node: self.maximizedRepeatButton, alpha: maximizationFactor)
|
|
|
|
transition.updateAlpha(node: self.titleNode, alpha: 1.0 - maximizationFactor)
|
|
transition.updateAlpha(node: self.subtitleNode, alpha: 1.0 - maximizationFactor)
|
|
transition.updateAlpha(node: self.scrubbingNode, alpha: 1.0 - maximizationFactor)
|
|
transition.updateAlpha(node: self.maximizedScrubbingNode, alpha: maximizationFactor)
|
|
transition.updateAlpha(node: self.maximizedTitleNode, alpha: maximizationFactor)
|
|
transition.updateAlpha(node: self.maximizedSubtitleNode, alpha: maximizationFactor)
|
|
transition.updateAlpha(node: self.maximizedLeftTimestampNode, alpha: maximizationFactor)
|
|
transition.updateAlpha(node: self.maximizedRightTimestampNode, alpha: maximizationFactor)
|
|
}
|
|
|
|
@objc func closeButtonPressed() {
|
|
if let close = self.close {
|
|
close()
|
|
}
|
|
}
|
|
|
|
@objc func actionButtonPressed() {
|
|
if let togglePlayPause = self.togglePlayPause {
|
|
togglePlayPause()
|
|
}
|
|
}
|
|
|
|
@objc func previousButtonPressed() {
|
|
if let previous = self.previous {
|
|
previous()
|
|
}
|
|
}
|
|
|
|
@objc func nextButtonPressed() {
|
|
if let next = self.next {
|
|
next()
|
|
}
|
|
}
|
|
|
|
@objc func shuffleButtonPressed() {
|
|
|
|
}
|
|
|
|
@objc func repeatButtonPressed() {
|
|
|
|
}
|
|
|
|
@objc func tapGesture(_ recognizer: UITapGestureRecognizer) {
|
|
if case .ended = recognizer.state {
|
|
self.expand?()
|
|
}
|
|
}
|
|
}
|