You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
439 lines
15 KiB
439 lines
15 KiB
//
|
|
// Created by Marco Schmickler on 04.06.15.
|
|
// Copyright (c) 2015 Marco Schmickler. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import Nimbus
|
|
import Alamofire
|
|
|
|
/**
|
|
NIPhotoScrollView
|
|
|
|
if (NIPhotoScrollViewPhotoSizeThumbnail != photoSize) {
|
|
// Don't let minScale exceed maxScale. (If the image is smaller than the screen, we
|
|
// don't want to force it to be zoomed.)
|
|
// todo marco minScale = MIN(minScale, maxScale);
|
|
}
|
|
|
|
*/
|
|
|
|
class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollViewDataSource, NIPhotoScrubberViewDataSource {
|
|
|
|
var items = [MediaItem]()
|
|
var completionHandler: (() -> Void)?
|
|
|
|
var loadOriginal : ImageLoadOperation?
|
|
var loadNext : ImageLoadOperation?
|
|
var nextImage : UIImage?
|
|
var nextImageIndex = 0
|
|
|
|
var slide = 0
|
|
|
|
var timer: Timer?
|
|
|
|
var thumbnails: ThumbnailCache?
|
|
|
|
lazy var operationQueue: OperationQueue = {
|
|
var queue = OperationQueue()
|
|
queue.name = "Photo queue"
|
|
queue.maxConcurrentOperationCount = 1
|
|
return queue
|
|
}()
|
|
|
|
override func viewDidDisappear(_ animated: Bool) {
|
|
operationQueue.cancelAllOperations()
|
|
}
|
|
|
|
override func setChromeTitle() {
|
|
let idx = photoAlbumView.centerPageIndex
|
|
if (items.count > idx) {
|
|
let selected = items[idx]
|
|
title = "(\(idx + 1) / \(photoAlbumView.numberOfPages)) \(selected.path) \(selected.name)"
|
|
}
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
let backButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(MediaPhotoController.back))
|
|
let slideButton = UIBarButtonItem(barButtonSystemItem: .fastForward, target: self, action: #selector(MediaPhotoController.slideShow))
|
|
navigationItem.leftBarButtonItems = [backButton, slideButton]
|
|
|
|
let playButton = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(MediaPhotoController.play))
|
|
let shotButton = UIBarButtonItem(barButtonSystemItem: .camera, target: self, action: #selector(MediaPhotoController.shot))
|
|
navigationItem.rightBarButtonItems = [playButton, shotButton]
|
|
|
|
setChromeVisibility(true, animated: true)
|
|
|
|
thumbnails = ThumbnailCache(items: items, refresh: {
|
|
() -> Void in
|
|
self.photoScrubberView.reloadData();
|
|
});
|
|
|
|
self.photoAlbumView.reloadData();
|
|
|
|
pagingScrollViewDidChangePages(photoAlbumView)
|
|
}
|
|
|
|
override func didReceiveMemoryWarning() {
|
|
print("warning")
|
|
thumbnails?.cancel()
|
|
|
|
super.didReceiveMemoryWarning()
|
|
}
|
|
|
|
@objc func shot() {
|
|
let currentItem = items[photoAlbumView.centerPageIndex]
|
|
var imageUrl = currentItem.thumbUrl!.replacingOccurrences(of: "_thumb.jpg", with: ".jpg")
|
|
imageUrl = imageUrl.replacingOccurrences(of: "?preview=true", with: "")
|
|
|
|
if imageUrl.starts(with: "file://") {
|
|
|
|
let pages = photoAlbumView.visiblePages()!
|
|
for case let page as NIPhotoScrollView in pages {
|
|
if (page.pageIndex == photoAlbumView.centerPageIndex) {
|
|
let scroll = page.value(forKey: "scrollView") as! UIScrollView
|
|
|
|
if scroll.isScrollEnabled {
|
|
currentItem.scale = Double(scroll.zoomScale)
|
|
currentItem.offset = scroll.contentOffset
|
|
currentItem.size = scroll.contentSize
|
|
|
|
let jsonFile = currentItem.path + "/" + currentItem.name.replacingOccurrences(of: ".jpg", with: ".json")
|
|
let url = FileHelper.getDocumentsDirectory().appendingPathComponent(jsonFile)
|
|
LocalManager.sharedInstance.saveFavDir(url: url, item: currentItem)
|
|
// print(currentItem.toJSON())
|
|
|
|
scroll.isScrollEnabled = false
|
|
}
|
|
else {
|
|
scroll.isScrollEnabled = true
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
else {
|
|
let url = NetworkManager.sharedInstance.baseurl + "/service/linkfavpic" + imageUrl
|
|
|
|
print(url)
|
|
AF.request(url).responseString {
|
|
(result) in
|
|
print("ok")
|
|
}
|
|
}
|
|
}
|
|
|
|
@objc func back() {
|
|
if let t = timer {
|
|
t.invalidate()
|
|
}
|
|
|
|
operationQueue.cancelAllOperations()
|
|
|
|
thumbnails?.cancel();
|
|
|
|
completionHandler!()
|
|
}
|
|
|
|
@objc func slideShow() {
|
|
slide += 1
|
|
if (slide > 2) {
|
|
slide = 0
|
|
}
|
|
|
|
if timer == nil {
|
|
showItem()
|
|
}
|
|
}
|
|
|
|
@objc func showItem() {
|
|
var nextItem = photoAlbumView.centerPageIndex + 1
|
|
|
|
if (nextItem >= (items).count) {
|
|
nextItem = 0
|
|
}
|
|
|
|
photoAlbumView.moveToPage(at: nextItem, animated: false);
|
|
photoScrubberView.setSelectedPhotoIndex(nextItem, animated: true)
|
|
pagingScrollViewDidChangePages(photoAlbumView)
|
|
|
|
}
|
|
|
|
@objc func play() {
|
|
let currentItem = items[photoAlbumView.centerPageIndex]
|
|
|
|
if (currentItem.type == ItemType.PICS) {
|
|
let items = currentItem
|
|
|
|
let len = items.root.count
|
|
let url = NetworkManager.sharedInstance.baseurl + "/service/listfiles" + items.root + "/" + items.path + "/" + items.name
|
|
|
|
print(items)
|
|
print(url)
|
|
|
|
AF.request(url).responseJSON {
|
|
(response) in
|
|
|
|
var im = [MediaItem]()
|
|
|
|
if let json = response.value {
|
|
|
|
for s in json as! [String] {
|
|
if s.hasSuffix(".jpg") {
|
|
let l = s.count
|
|
let name = NSURL(fileURLWithPath: s).lastPathComponent!
|
|
var pathlen = l - len - name.count
|
|
|
|
// if (pathlen > 1000) {
|
|
print(pathlen)
|
|
print(name)
|
|
print(s)
|
|
// }
|
|
if (pathlen < 2) {
|
|
pathlen = 2
|
|
}
|
|
|
|
let path = (s as NSString).substring(with: NSMakeRange(len + 1, pathlen - 2))
|
|
|
|
let folderName = NSURL(fileURLWithPath: path).lastPathComponent!
|
|
let fl = path.length()
|
|
let pfl = fl - folderName.length()
|
|
|
|
print("\(folderName) \(pfl)")
|
|
let fpath = s.substringLeft(pfl)
|
|
|
|
let i = MediaItem(name: folderName, path: fpath, root: items.root, type: ItemType.PICS)
|
|
i.thumbUrl = "\(s)?preview=true"
|
|
if !name.hasPrefix(".") {
|
|
im.append(i)
|
|
}
|
|
}
|
|
}
|
|
|
|
let pc = MediaPhotoController()
|
|
pc.items = im
|
|
pc.completionHandler = {
|
|
self.dismiss(animated: true, completion: nil);
|
|
}
|
|
let navController = UINavigationController(rootViewController: pc) // Creating a navigation controller with pc at the root of the navigation stack.
|
|
|
|
self.present(navController, animated: false, completion: nil)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
let controller = VideoController()
|
|
controller.edit = false
|
|
controller.allowEdit = false
|
|
|
|
controller.currentItem = currentItem
|
|
controller.setItems(items: [currentItem])
|
|
controller.navigationItem.leftItemsSupplementBackButton = true
|
|
navigationController!.navigationBar.barTintColor = UIColor.black
|
|
navigationController!.pushViewController(controller, animated: true)
|
|
|
|
controller.completionHandler = {
|
|
() in
|
|
// NetworkManager.sharedInstance.saveItem(self.currentItem!)
|
|
self.dismiss(animated: true, completion: nil);
|
|
}
|
|
}
|
|
|
|
override func loadView() {
|
|
super.loadView()
|
|
photoAlbumView.dataSource = self
|
|
photoScrubberView.dataSource = self
|
|
|
|
isToolbarTranslucent = true
|
|
hidesChromeWhenScrolling = true
|
|
chromeCanBeHidden = true
|
|
isScrubberEnabled = true
|
|
|
|
|
|
// Toolbar Setup
|
|
let bounds = self.view.bounds;
|
|
let toolbarHeight = CGFloat(120.0)
|
|
toolbar.frame = CGRect(x: 0, y: bounds.size.height - toolbarHeight, width: bounds.size.width, height: toolbarHeight)
|
|
photoAlbumView.isZoomingAboveOriginalSizeEnabled = true;
|
|
|
|
// This title will be displayed until we get the results back for the album information.
|
|
self.title = "loading"
|
|
|
|
// self.photoAlbumView.loadingImage = UIImage(named: "Kirschkeks-256x256.png")
|
|
print("\(items.count)")
|
|
}
|
|
|
|
func photoAlbumScrollView(_ photoAlbumScrollView: NIPhotoAlbumScrollView!, photoAt photoAtIndex: Int, photoSize: UnsafeMutablePointer<NIPhotoScrollViewPhotoSize>,
|
|
isLoading: UnsafeMutablePointer<ObjCBool>, originalPhotoDimensions: UnsafeMutablePointer<CGSize>) -> UIImage! {
|
|
let newItem = items[photoAtIndex]
|
|
let u1 = URL(string: newItem.imageUrlAbsolute)
|
|
let u2 = URL(string: newItem.thumbUrlAbsolute)
|
|
if let hqURL = u1, let u5 = u2 {
|
|
|
|
var image: UIImage? = nil
|
|
|
|
var size = NIPhotoScrollViewPhotoSizeUnknown
|
|
|
|
image = thumbnails?.getThumbnail(newItem)
|
|
|
|
if image != nil {
|
|
size = NIPhotoScrollViewPhotoSizeThumbnail
|
|
isLoading[0] = false
|
|
} else {
|
|
let thumbnail: (UIImage, Int) -> () = { (i: UIImage, thumbnailIndex: Int) in
|
|
self.photoAlbumView.didLoadPhoto(i, at: photoAtIndex, photoSize: NIPhotoScrollViewPhotoSizeThumbnail)
|
|
self.photoScrubberView.didLoadThumbnail(i, at: thumbnailIndex)
|
|
}
|
|
|
|
let image = thumbnails?.loadThumbnail(thumbnailIndex: photoAtIndex, thumbnail: thumbnail)
|
|
}
|
|
|
|
if (image == nil) {
|
|
isLoading[0] = true
|
|
}
|
|
|
|
photoSize[0] = size
|
|
|
|
return image
|
|
} else {
|
|
print("## Invalid URL: \(newItem.imageUrlAbsolute)")
|
|
|
|
return nil
|
|
}
|
|
}
|
|
|
|
public override func pagingScrollViewDidChangePages(_ pagingScrollView: NIPagingScrollView!) {
|
|
setChromeTitle()
|
|
|
|
let currentIndex: Int = self.photoAlbumView.centerPageIndex
|
|
let hqURL = URL(string: items[currentIndex].imageUrlAbsolute)!
|
|
|
|
if let op = loadOriginal {
|
|
op.cancel()
|
|
loadOriginal = nil
|
|
}
|
|
|
|
let view2 = photoAlbumView.centerPageView() as! NIPhotoScrollView
|
|
restoreScrollState(currentIndex: currentIndex, view: view2)
|
|
|
|
if view2.photoSize() != NIPhotoScrollViewPhotoSizeOriginal {
|
|
if nextImage != nil && currentIndex == nextImageIndex {
|
|
self.photoAlbumView.didLoadPhoto(nextImage!, at: currentIndex, photoSize: NIPhotoScrollViewPhotoSizeOriginal)
|
|
nextImage = nil
|
|
}
|
|
else {
|
|
let op2 = ImageLoadOperation(imageURL: hqURL, succeeder: {
|
|
i in
|
|
// self.photoAlbumView.isZoomingAboveOriginalSizeEnabled = max(i.size.height, i.size.width) <= 6000;
|
|
self.photoAlbumView.didLoadPhoto(i, at: currentIndex, photoSize: NIPhotoScrollViewPhotoSizeOriginal)
|
|
self.restoreScrollState(currentIndex: currentIndex, view: view2)
|
|
}, index: currentIndex)
|
|
loadOriginal = op2
|
|
op2.qualityOfService = QualityOfService.userInitiated
|
|
operationQueue.addOperation(op2)
|
|
}
|
|
}
|
|
|
|
if currentIndex + 1 < items.count {
|
|
if let op = loadNext {
|
|
op.cancel()
|
|
loadNext = nil
|
|
}
|
|
|
|
if let image = thumbnails?.getThumbnail(items[currentIndex+1]) {
|
|
self.photoAlbumView.didLoadPhoto(image, at: currentIndex+1, photoSize: NIPhotoScrollViewPhotoSizeThumbnail)
|
|
}
|
|
|
|
let hqURL2 = URL(string: items[currentIndex+1].imageUrlAbsolute)!
|
|
nextImage = nil
|
|
|
|
let op3 = ImageLoadOperation(imageURL: hqURL2, succeeder: {
|
|
i in
|
|
self.nextImage = i
|
|
self.nextImageIndex = currentIndex + 1
|
|
|
|
if (self.slide > 0) {
|
|
self.timer = Timer.scheduledTimer(timeInterval: Double(self.slide) / 2, target: self, selector: #selector(self.showItem), userInfo: nil, repeats: false)
|
|
} else {
|
|
self.timer = nil
|
|
}
|
|
}, index: currentIndex)
|
|
loadNext = op3
|
|
op3.qualityOfService = QualityOfService.userInitiated
|
|
operationQueue.addOperation(op3)
|
|
}
|
|
|
|
let oldIndex = currentIndex - 1;
|
|
|
|
if (oldIndex >= 0) {
|
|
let newItem = items[oldIndex]
|
|
if let image = thumbnails?.getThumbnail(newItem) {
|
|
self.photoAlbumView.didLoadPhoto(image, at: oldIndex, photoSize: NIPhotoScrollViewPhotoSizeThumbnail)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private func restoreScrollState(currentIndex: Int, view: NIPhotoScrollView) {
|
|
let item = items[currentIndex]
|
|
|
|
if item.scale > 0.0 {
|
|
// view.setValue(false, forKey: "zoomingIsEnabled")
|
|
let scroll = view.value(forKey: "scrollView") as! UIScrollView
|
|
scroll.zoomScale = CGFloat(item.scale)
|
|
scroll.contentSize = item.size
|
|
scroll.contentOffset = item.offset
|
|
scroll.isScrollEnabled = false
|
|
}
|
|
}
|
|
|
|
func numberOfPages(in pagingScrollView: NIPagingScrollView) -> Int {
|
|
let c = items.count
|
|
return c
|
|
}
|
|
|
|
/**
|
|
* Fetches a page that will be displayed at the given page index.
|
|
*
|
|
* You should always try to reuse pages by calling dequeueReusablePageWithIdentifier: on the
|
|
* paging scroll view before allocating a new page.
|
|
*/
|
|
func pagingScrollView(_ pagingScrollView: NIPagingScrollView, pageViewFor pageViewForIndex: Int) -> (UIView & NIPagingScrollViewPageProtocol)! {
|
|
let view = photoAlbumView.pagingScrollView(pagingScrollView, pageViewFor: pageViewForIndex) as! NIPhotoScrollView
|
|
|
|
// view.maximumScale = 2;
|
|
|
|
|
|
return view;
|
|
}
|
|
|
|
func numberOfPhotos(in photoScrubberView: NIPhotoScrubberView!) -> Int {
|
|
let c = items.count
|
|
return c
|
|
}
|
|
|
|
/**
|
|
* Fetch the thumbnail image for the given photo index.
|
|
*
|
|
* Please read and understand the performance considerations for this data source.
|
|
*/
|
|
func photoScrubberView(_ photoScrubberView: NIPhotoScrubberView!, thumbnailAt thumbnailIndex: Int) -> UIImage! {
|
|
if thumbnailIndex < 0 {
|
|
return nil
|
|
}
|
|
let thumbnail: (UIImage, Int) -> () = { (i: UIImage, thumbnailIndex: Int) in
|
|
self.photoScrubberView.didLoadThumbnail(i, at: thumbnailIndex)
|
|
}
|
|
|
|
let image = thumbnails?.loadThumbnail(thumbnailIndex: thumbnailIndex, thumbnail: thumbnail)
|
|
|
|
return image
|
|
}
|
|
|
|
|
|
}
|
|
|