152 lines
5.1 KiB
Swift
152 lines
5.1 KiB
Swift
// GalleryViewController.swift
|
|
// Tusker
|
|
//
|
|
// Created by Shadowfacts on 6/13/19.
|
|
// Copyright © 2019 Shadowfacts. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import Pachyderm
|
|
import AVFoundation
|
|
import AVKit
|
|
|
|
class GalleryViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate, LargeImageAnimatableViewController {
|
|
|
|
let attachments: [Attachment]
|
|
let sourceViews: WeakArray<UIImageView>
|
|
let startIndex: Int
|
|
|
|
let pages: [UIViewController]
|
|
|
|
var currentIndex: Int {
|
|
guard let vc = viewControllers?.first,
|
|
let index = pages.firstIndex(of: vc) else {
|
|
fatalError()
|
|
}
|
|
return index
|
|
}
|
|
|
|
var animationSourceView: UIImageView? { sourceViews[currentIndex] }
|
|
var animationImage: UIImage? {
|
|
if let page = pages[currentIndex] as? LoadingLargeImageViewController,
|
|
let image = page.largeImageVC?.image {
|
|
return image
|
|
} else {
|
|
return animationSourceView?.image
|
|
}
|
|
}
|
|
var animationGifData: Data? {
|
|
let attachment = attachments[currentIndex]
|
|
if attachment.url.pathExtension == "gif" {
|
|
return ImageCache.attachments.get(attachment.url)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
var dismissInteractionController: LargeImageInteractionController?
|
|
|
|
override var prefersStatusBarHidden: Bool {
|
|
return true
|
|
}
|
|
override var childForHomeIndicatorAutoHidden: UIViewController? {
|
|
return viewControllers?.first
|
|
}
|
|
|
|
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
|
|
if UIDevice.current.userInterfaceIdiom == .phone {
|
|
return .allButUpsideDown
|
|
} else {
|
|
return .all
|
|
}
|
|
}
|
|
|
|
init(attachments: [Attachment], sourceViews: [UIImageView?], startIndex: Int) {
|
|
self.attachments = attachments
|
|
self.sourceViews = WeakArray(sourceViews)
|
|
self.startIndex = startIndex
|
|
|
|
self.pages = attachments.map {
|
|
switch $0.kind {
|
|
case .image:
|
|
let vc = LoadingLargeImageViewController(attachment: $0)
|
|
vc.shrinkGestureEnabled = false
|
|
return vc
|
|
case .video, .audio:
|
|
let vc = AVPlayerViewController()
|
|
vc.player = AVPlayer(url: $0.url)
|
|
return vc
|
|
default:
|
|
fatalError()
|
|
}
|
|
}
|
|
|
|
super.init(transitionStyle: .scroll, navigationOrientation: .horizontal)
|
|
|
|
setViewControllers([pages[startIndex]], direction: .forward, animated: false)
|
|
|
|
modalPresentationStyle = .fullScreen
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
self.dataSource = self
|
|
self.delegate = self
|
|
|
|
overrideUserInterfaceStyle = .dark
|
|
|
|
dismissInteractionController = LargeImageInteractionController(viewController: self)
|
|
}
|
|
|
|
override func viewDidAppear(_ animated: Bool) {
|
|
super.viewDidAppear(animated)
|
|
|
|
if let vc = pages[currentIndex] as? AVPlayerViewController {
|
|
// when the gallery is first shown, after the transition finishes, the controls for the player controller appear semi-transparent
|
|
// hiding the controls and then immediately reshowing them makes sure they're visible when the gallery is presented
|
|
vc.showsPlaybackControls = false
|
|
vc.showsPlaybackControls = true
|
|
|
|
// begin playing the video as soon as we appear
|
|
vc.player?.play()
|
|
}
|
|
}
|
|
|
|
// MARK: - Page View Controller Data Source
|
|
|
|
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
|
|
guard let index = pages.firstIndex(of: viewController),
|
|
index > 0 else {
|
|
return nil
|
|
}
|
|
return pages[index - 1]
|
|
}
|
|
|
|
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
|
|
guard let index = pages.firstIndex(of: viewController),
|
|
index < pages.count - 1 else {
|
|
return nil
|
|
}
|
|
return pages[index + 1]
|
|
}
|
|
|
|
// MARK: - Page View Controller Delegate
|
|
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
|
|
if let pending = pendingViewControllers.first as? LoadingLargeImageViewController,
|
|
let current = viewControllers!.first as? LoadingLargeImageViewController {
|
|
pending.controlsVisible = current.controlsVisible
|
|
}
|
|
|
|
if let pending = pendingViewControllers.first as? AVPlayerViewController {
|
|
// show controls and begin playing when the player page becomes visible
|
|
pending.showsPlaybackControls = true
|
|
pending.player?.play()
|
|
}
|
|
}
|
|
|
|
}
|