Browse Source

Change class name

Signed-off-by: marinofaggiana <marino@marinofaggiana.com>
marinofaggiana 3 years ago
parent
commit
997e105fe3

+ 12 - 12
Nextcloud.xcodeproj/project.pbxproj

@@ -42,9 +42,9 @@
 		F704B5E52430AA8000632F5F /* NCCreateFormUploadConflict.swift in Sources */ = {isa = PBXBuildFile; fileRef = F704B5E42430AA8000632F5F /* NCCreateFormUploadConflict.swift */; };
 		F704B5E72430C06700632F5F /* NCCreateFormUploadConflictCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F704B5E62430C06700632F5F /* NCCreateFormUploadConflictCell.xib */; };
 		F704B5E92430C0B800632F5F /* NCCreateFormUploadConflictCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F704B5E82430C0B800632F5F /* NCCreateFormUploadConflictCell.swift */; };
-		F70753EB2542A99800972D44 /* NCViewerMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70753EA2542A99800972D44 /* NCViewerMedia.swift */; };
-		F70753F12542A9A200972D44 /* NCViewerMediaZoom.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70753F02542A9A200972D44 /* NCViewerMediaZoom.swift */; };
-		F70753F72542A9C000972D44 /* NCViewerMedia.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F70753F62542A9C000972D44 /* NCViewerMedia.storyboard */; };
+		F70753EB2542A99800972D44 /* NCViewerMediaPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70753EA2542A99800972D44 /* NCViewerMediaPage.swift */; };
+		F70753F12542A9A200972D44 /* NCViewerMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70753F02542A9A200972D44 /* NCViewerMedia.swift */; };
+		F70753F72542A9C000972D44 /* NCViewerMediaPage.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F70753F62542A9C000972D44 /* NCViewerMediaPage.storyboard */; };
 		F707C26521A2DC5200F6181E /* NCStoreReview.swift in Sources */ = {isa = PBXBuildFile; fileRef = F707C26421A2DC5200F6181E /* NCStoreReview.swift */; };
 		F70968A424212C4E00ED60E5 /* NCLivePhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70968A324212C4E00ED60E5 /* NCLivePhoto.swift */; };
 		F70A58BE24D0349500DED00D /* NCCapabilitiesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70A58BD24D0349500DED00D /* NCCapabilitiesViewController.swift */; };
@@ -442,9 +442,9 @@
 		F7063DEC2199E55F003F38DA /* SVGKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SVGKit.framework; path = Carthage/Build/iOS/SVGKit.framework; sourceTree = "<group>"; };
 		F7063DEE2199E568003F38DA /* CocoaLumberjack.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CocoaLumberjack.framework; path = Carthage/Build/iOS/CocoaLumberjack.framework; sourceTree = "<group>"; };
 		F7063DF02199E56E003F38DA /* CocoaLumberjackSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CocoaLumberjackSwift.framework; path = Carthage/Build/iOS/CocoaLumberjackSwift.framework; sourceTree = "<group>"; };
-		F70753EA2542A99800972D44 /* NCViewerMedia.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCViewerMedia.swift; sourceTree = "<group>"; };
-		F70753F02542A9A200972D44 /* NCViewerMediaZoom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCViewerMediaZoom.swift; sourceTree = "<group>"; };
-		F70753F62542A9C000972D44 /* NCViewerMedia.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCViewerMedia.storyboard; sourceTree = "<group>"; };
+		F70753EA2542A99800972D44 /* NCViewerMediaPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCViewerMediaPage.swift; sourceTree = "<group>"; };
+		F70753F02542A9A200972D44 /* NCViewerMedia.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCViewerMedia.swift; sourceTree = "<group>"; };
+		F70753F62542A9C000972D44 /* NCViewerMediaPage.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCViewerMediaPage.storyboard; sourceTree = "<group>"; };
 		F707C26421A2DC5200F6181E /* NCStoreReview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCStoreReview.swift; sourceTree = "<group>"; };
 		F70968A324212C4E00ED60E5 /* NCLivePhoto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCLivePhoto.swift; sourceTree = "<group>"; };
 		F70A07C8205285FB00DC1231 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Localizable.strings"; sourceTree = "<group>"; };
@@ -1179,10 +1179,10 @@
 			isa = PBXGroup;
 			children = (
 				F79EDA9E26B004980007D134 /* NCPlayer */,
-				F70753F62542A9C000972D44 /* NCViewerMedia.storyboard */,
-				F70753EA2542A99800972D44 /* NCViewerMedia.swift */,
+				F70753F62542A9C000972D44 /* NCViewerMediaPage.storyboard */,
+				F70753EA2542A99800972D44 /* NCViewerMediaPage.swift */,
 				F718C24D254D507B00C5C256 /* NCViewerMediaDetailView.swift */,
-				F70753F02542A9A200972D44 /* NCViewerMediaZoom.swift */,
+				F70753F02542A9A200972D44 /* NCViewerMedia.swift */,
 			);
 			path = NCViewerMedia;
 			sourceTree = "<group>";
@@ -1958,7 +1958,7 @@
 				F7725A61251F33BB00D125E0 /* NCFiles.storyboard in Resources */,
 				F700510122DF63AC003A3356 /* NCShare.storyboard in Resources */,
 				F787704F22E7019900F287A9 /* NCShareLinkCell.xib in Resources */,
-				F70753F72542A9C000972D44 /* NCViewerMedia.storyboard in Resources */,
+				F70753F72542A9C000972D44 /* NCViewerMediaPage.storyboard in Resources */,
 				F70A58C024D0545100DED00D /* NCCapabilitiesViewController.storyboard in Resources */,
 				F749C10D23C4A5340027D966 /* NCIntro.storyboard in Resources */,
 				F7239877253D86D300257F49 /* NCEmptyView.xib in Resources */,
@@ -2136,7 +2136,7 @@
 				F72A47EC2487B06B005AD489 /* NCOperationQueue.swift in Sources */,
 				F769454622E9F1B0000A798A /* NCShareCommon.swift in Sources */,
 				F738E8421F90FFD100F95C8E /* NCManageEndToEndEncryption.m in Sources */,
-				F70753F12542A9A200972D44 /* NCViewerMediaZoom.swift in Sources */,
+				F70753F12542A9A200972D44 /* NCViewerMedia.swift in Sources */,
 				F7A80BCB252624C100C7CD01 /* NCFileViewInFolder.swift in Sources */,
 				F78A18B823CDE2B300F681F3 /* NCViewerRichWorkspace.swift in Sources */,
 				F77910AB25DD53C700CEDB9E /* NCSettingsBundleHelper.swift in Sources */,
@@ -2211,7 +2211,7 @@
 				F79A65C62191D95E00FF6DCC /* NCSelect.swift in Sources */,
 				F75D19E325EFE09000D74598 /* NCTrash+Menu.swift in Sources */,
 				F70CAE3A1F8CF31A008125FD /* NCEndToEndEncryption.m in Sources */,
-				F70753EB2542A99800972D44 /* NCViewerMedia.swift in Sources */,
+				F70753EB2542A99800972D44 /* NCViewerMediaPage.swift in Sources */,
 				F74C0436253F1CDC009762AB /* NCShares.swift in Sources */,
 				F7AE00F5230D5F9E007ACF8A /* NCLoginWeb.swift in Sources */,
 				F707C26521A2DC5200F6181E /* NCStoreReview.swift in Sources */,

+ 1 - 1
iOSClient/Viewer/NCViewer.swift

@@ -48,7 +48,7 @@ class NCViewer: NSObject {
             
             if let navigationController = viewController.navigationController {
                             
-                let viewerMediaPageContainer:NCViewerMedia = UIStoryboard(name: "NCViewerMedia", bundle: nil).instantiateInitialViewController() as! NCViewerMedia
+                let viewerMediaPageContainer:NCViewerMediaPage = UIStoryboard(name: "NCViewerMediaPage", bundle: nil).instantiateInitialViewController() as! NCViewerMediaPage
                 var index = 0
                 for medatasImage in metadatas {
                     if medatasImage.ocId == metadata.ocId {

+ 5 - 5
iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayerToolBar.swift

@@ -54,7 +54,7 @@ class NCPlayerToolBar: UIView {
     private var timerAutoHide: Timer?
     
     var pictureInPictureController: AVPictureInPictureController?
-    weak var viewerMedia: NCViewerMedia?
+    weak var viewerMediaPage: NCViewerMediaPage?
 
     // MARK: - View Life Cycle
 
@@ -489,7 +489,7 @@ class NCPlayerToolBar: UIView {
         
         var index: Int = 0
         
-        if let currentIndex = self.viewerMedia?.currentIndex, let metadatas = self.viewerMedia?.metadatas, let ncplayer = self.ncplayer {
+        if let currentIndex = self.viewerMediaPage?.currentIndex, let metadatas = self.viewerMediaPage?.metadatas, let ncplayer = self.ncplayer {
         
             if currentIndex == metadatas.count - 1 {
                 index = 0
@@ -497,7 +497,7 @@ class NCPlayerToolBar: UIView {
                 index = currentIndex + 1
             }
             
-            self.viewerMedia?.goTo(index: index, direction: .forward, autoPlay: ncplayer.isPlay())
+            self.viewerMediaPage?.goTo(index: index, direction: .forward, autoPlay: ncplayer.isPlay())
         }
     }
     
@@ -505,7 +505,7 @@ class NCPlayerToolBar: UIView {
         
         var index: Int = 0
 
-        if let currentIndex = self.viewerMedia?.currentIndex, let metadatas = self.viewerMedia?.metadatas, let ncplayer = self.ncplayer {
+        if let currentIndex = self.viewerMediaPage?.currentIndex, let metadatas = self.viewerMediaPage?.metadatas, let ncplayer = self.ncplayer {
             
             if currentIndex == 0 {
                 index = metadatas.count - 1
@@ -513,7 +513,7 @@ class NCPlayerToolBar: UIView {
                 index = currentIndex - 1
             }
             
-            self.viewerMedia?.goTo(index: index, direction: .reverse, autoPlay: ncplayer.isPlay())
+            self.viewerMediaPage?.goTo(index: index, direction: .reverse, autoPlay: ncplayer.isPlay())
         }
     }
 }

+ 320 - 555
iOSClient/Viewer/NCViewerMedia/NCViewerMedia.swift

@@ -22,668 +22,433 @@
 //
 
 import UIKit
-import SVGKit
 import NCCommunication
-import MediaPlayer
 
 class NCViewerMedia: UIViewController {
-
-    @IBOutlet weak var progressView: UIProgressView!
     
-    enum ScreenMode {
-        case full, normal
-    }
-    var currentScreenMode: ScreenMode = .normal
-    var saveScreenModeImage: ScreenMode = .normal
+    @IBOutlet weak var detailViewTopConstraint: NSLayoutConstraint!
+    @IBOutlet weak var detailViewHeighConstraint: NSLayoutConstraint!
+    @IBOutlet weak var imageViewTopConstraint: NSLayoutConstraint!
+    @IBOutlet weak var imageViewBottomConstraint: NSLayoutConstraint!
+    @IBOutlet weak var scrollView: UIScrollView!
+    @IBOutlet weak var imageVideoContainer: imageVideoContainerView!
+    @IBOutlet weak var statusViewImage: UIImageView!
+    @IBOutlet weak var statusLabel: UILabel!
+    @IBOutlet weak var detailView: NCViewerMediaDetailView!
+    @IBOutlet weak var playerToolBar: NCPlayerToolBar!
+    
+    private var _autoPlay: Bool = false
 
-    var pageViewController: UIPageViewController {
-        return self.children[0] as! UIPageViewController
-    }
-    
-    var currentViewController: NCViewerMediaZoom {
-        return self.pageViewController.viewControllers![0] as! NCViewerMediaZoom
-    }
-    
     let appDelegate = UIApplication.shared.delegate as! AppDelegate
-
-    var metadatas: [tableMetadata] = []
-    var currentIndex = 0
-    var nextIndex: Int?
-    var IndexInPlay: Int = -1
-    var ncplayerLivePhoto: NCPlayer?
-    var panGestureRecognizer: UIPanGestureRecognizer!
-    var singleTapGestureRecognizer: UITapGestureRecognizer!
-    var longtapGestureRecognizer: UILongPressGestureRecognizer!
-    
-    var textColor: UIColor = NCBrandColor.shared.label
+    var viewerMediaPage: NCViewerMediaPage?
+    var ncplayer: NCPlayer?
+    var image: UIImage?
+    var metadata: tableMetadata = tableMetadata()
+    var index: Int = 0
+    var doubleTapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer()
+    var imageViewConstraint: CGFloat = 0
+    var isDetailViewInitializze: Bool = false
     
-    var playCommand: Any?
-    var pauseCommand: Any?
-    var skipForwardCommand: Any?
-    var skipBackwardCommand: Any?
-    var nextTrackCommand: Any?
-    var previousTrackCommand: Any?
+    var autoPlay: Bool {
+        get {
+            let temp = _autoPlay
+            _autoPlay = false
+            return temp
+        }
+        set(newVal) {
+            _autoPlay = newVal
+        }
+    }
     
-
     // MARK: - View Life Cycle
 
-    override func viewDidLoad() {
-        super.viewDidLoad()
-        
-        navigationItem.rightBarButtonItem = UIBarButtonItem.init(image: UIImage(named: "more")!.image(color: NCBrandColor.shared.label, size: 25), style: .plain, target: self, action: #selector(self.openMenuMore))
-        
-        singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didSingleTapWith(gestureRecognizer:)))
-        panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(didPanWith(gestureRecognizer:)))
-        longtapGestureRecognizer = UILongPressGestureRecognizer()
-        longtapGestureRecognizer.delaysTouchesBegan = true
-        longtapGestureRecognizer.minimumPressDuration = 0.3
-        longtapGestureRecognizer.delegate = self
-        longtapGestureRecognizer.addTarget(self, action: #selector(didLongpressGestureEvent(gestureRecognizer:)))
+    required init?(coder aDecoder: NSCoder) {
+        super.init(coder: aDecoder)
         
-        pageViewController.delegate = self
-        pageViewController.dataSource = self
-        pageViewController.view.addGestureRecognizer(panGestureRecognizer)
-        pageViewController.view.addGestureRecognizer(singleTapGestureRecognizer)
-        pageViewController.view.addGestureRecognizer(longtapGestureRecognizer)
-        
-        let viewerMediaZoom = getViewerMediaZoom(index: currentIndex, image: getImageMetadata(metadatas[currentIndex]), metadata: metadatas[currentIndex], direction: .forward)
-        pageViewController.setViewControllers([viewerMediaZoom], direction: .forward, animated: true, completion: nil)
-        
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterChangeTheming), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(viewUnload), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMenuDetailClose), object: nil)
-        
-        progressView.tintColor = NCBrandColor.shared.brandElement
-        progressView.trackTintColor = .clear
-        progressView.progress = 0
-        
-        NotificationCenter.default.addObserver(self, selector: #selector(deleteFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterDeleteFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(renameFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterRenameFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(moveFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMoveFile), object: nil)
-
-        NotificationCenter.default.addObserver(self, selector: #selector(downloadedFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterDownloadedFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(triggerProgressTask(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterProgressTask), object:nil)
-        
-        NotificationCenter.default.addObserver(self, selector: #selector(hidePlayerToolBar(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterHidePlayerToolBar), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(showPlayerToolBar(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterShowPlayerToolBar), object: nil)
+        doubleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didDoubleTapWith(gestureRecognizer:)))
+        doubleTapGestureRecognizer.numberOfTapsRequired = 2
+    }
+    
+    deinit {
+        print("deinit NCViewerMedia")
         
-        NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterApplicationDidBecomeActive), object: nil)
+        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterOpenMediaDetail), object: nil)
     }
     
-    override func viewDidDisappear(_ animated: Bool) {
-        super.viewDidDisappear(animated)
+    override func viewDidLoad() {
+        super.viewDidLoad()
         
-        // Clear
-        if let ncplayer = currentViewController.ncplayer, ncplayer.isPlay() {
-            ncplayer.playerPause()
-            ncplayer.saveCurrentTime()
-        }
-        currentViewController.playerToolBar.stopTimerAutoHide()
-        clearCommandCenter()
+        scrollView.delegate = self
+        scrollView.maximumZoomScale = 4
+        scrollView.minimumZoomScale = 1
         
-        metadatas.removeAll()
-        ncplayerLivePhoto = nil
+        view.addGestureRecognizer(doubleTapGestureRecognizer)
         
-        // Remove Observer
-        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterDeleteFile), object: nil)
-        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterRenameFile), object: nil)
-        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMoveFile), object: nil)
+        if metadata.classFile == NCCommunicationCommon.typeClassFile.video.rawValue {
+            if image == nil {
+                image = UIImage.init(named: "noPreviewVideo")!.image(color: .gray, size: view.frame.width)
+            }
+            imageVideoContainer.image = image
+            
+        } else if metadata.classFile == NCCommunicationCommon.typeClassFile.audio.rawValue {
+            if image == nil {
+                image = UIImage.init(named: "noPreviewAudio")!.image(color: .gray, size: view.frame.width)
+            }
+            imageVideoContainer.image = image
 
-        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterDownloadedFile), object: nil)
-        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterProgressTask), object: nil)
-        
-        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterHidePlayerToolBar), object: nil)
-        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterShowPlayerToolBar), object: nil)
-        
-        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterApplicationDidBecomeActive), object: nil)
-    }
-    
-    override var preferredStatusBarStyle: UIStatusBarStyle {
-        
-        if currentScreenMode == .normal {
-            return .default
         } else {
-            return .lightContent
+            if image == nil {
+                image = UIImage.init(named: "noPreview")!.image(color: .gray, size: view.frame.width)
+            }
+            imageVideoContainer.image = image
         }
-    }
-    
-    // MARK: -
-    
-    func getViewerMediaZoom(index: Int, image: UIImage?, metadata: tableMetadata, direction: UIPageViewController.NavigationDirection) -> NCViewerMediaZoom {
         
-        let viewerMediaZoom = UIStoryboard(name: "NCViewerMedia", bundle: nil).instantiateViewController(withIdentifier: "NCViewerMediaZoom") as! NCViewerMediaZoom
-        viewerMediaZoom.index = index
-        viewerMediaZoom.image = image
-        viewerMediaZoom.metadata = metadata
-        viewerMediaZoom.viewerMedia = self
-
-        singleTapGestureRecognizer.require(toFail: viewerMediaZoom.doubleTapGestureRecognizer)
-       
-        return viewerMediaZoom
-    }
-
-    @objc func viewUnload() {
+        if NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) != nil {
+            statusViewImage.image = NCUtility.shared.loadImage(named: "livephoto", color: .gray)
+            statusLabel.text = "LIVE"
+        }  else {
+            statusViewImage.image = nil
+            statusLabel.text = ""
+        }
         
-        navigationController?.popViewController(animated: true)
-    }
-    
-    @objc func openMenuMore() {
+        playerToolBar.viewerMediaPage = viewerMediaPage
+        
+        detailViewTopConstraint.constant = 0
+        detailView.hide()
         
-        let imageIcon = UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(currentViewController.metadata.ocId, etag: currentViewController.metadata.etag))
-        NCViewer.shared.toggleMenu(viewController: self, metadata: currentViewController.metadata, webView: false, imageIcon: imageIcon)
+        // DOWNLOAD
+        downloadFile()
     }
     
-    func changeScreenMode(mode: ScreenMode, enableTimerAutoHide: Bool = false) {
+    override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
         
-        if mode == .normal {
+        viewerMediaPage?.navigationController?.navigationBar.prefersLargeTitles = false
+        viewerMediaPage?.navigationItem.title = metadata.fileNameView
+        
+        if metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue, let viewerMediaPage = self.viewerMediaPage {
+            viewerMediaPage.currentScreenMode = viewerMediaPage.saveScreenModeImage
+        }
+                
+        if viewerMediaPage?.currentScreenMode == .full {
             
-            navigationController?.setNavigationBarHidden(false, animated: true)
-            progressView.isHidden = false
-
-            if !currentViewController.detailView.isShow() {
-                currentViewController.playerToolBar.show(enableTimerAutoHide: enableTimerAutoHide)
-            }
+            viewerMediaPage?.navigationController?.setNavigationBarHidden(true, animated: true)
+            
+            NCUtility.shared.colorNavigationController(viewerMediaPage?.navigationController, backgroundColor: .black, titleColor: .white, tintColor: nil, withoutShadow: false)
             
-            NCUtility.shared.colorNavigationController(navigationController, backgroundColor: NCBrandColor.shared.systemBackground, titleColor: NCBrandColor.shared.label, tintColor: nil, withoutShadow: false)
-            view.backgroundColor = NCBrandColor.shared.systemBackground
-            textColor = NCBrandColor.shared.label
+            viewerMediaPage?.view.backgroundColor = .black
+            viewerMediaPage?.textColor = .white
+            viewerMediaPage?.progressView.isHidden = true
             
         } else {
             
-            navigationController?.setNavigationBarHidden(true, animated: true)
-            progressView.isHidden = true
+            viewerMediaPage?.navigationController?.setNavigationBarHidden(false, animated: true)
+                
+            NCUtility.shared.colorNavigationController(viewerMediaPage?.navigationController, backgroundColor: NCBrandColor.shared.systemBackground, titleColor: NCBrandColor.shared.label, tintColor: nil, withoutShadow: false)
             
-            currentViewController.playerToolBar.hide()
-
-            view.backgroundColor = .black
-            textColor = .white
+            viewerMediaPage?.view.backgroundColor = NCBrandColor.shared.systemBackground
+            viewerMediaPage?.textColor = NCBrandColor.shared.label
+            viewerMediaPage?.progressView.isHidden = false
         }
-        
-        currentScreenMode = mode
-        
-        if currentViewController.metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue {
-            saveScreenModeImage = mode
-        }
-        
-        setNeedsStatusBarAppearanceUpdate()
-        currentViewController.reloadDetail()
-    }
-    
-    //MARK: - NotificationCenter
-
-    @objc func downloadedFile(_ notification: NSNotification) {
-        
-        progressView.progress = 0
     }
     
-    @objc func triggerProgressTask(_ notification: NSNotification) {
+    override func viewDidAppear(_ animated: Bool) {
+        super.viewDidAppear(animated)
         
-        if let userInfo = notification.userInfo as NSDictionary? {
-            if let serverUrl = userInfo["serverUrl"] as? String, let fileName = userInfo["fileName"] as? String, let progressNumber = userInfo["progress"] as? NSNumber {
-                if self.metadatas.first(where: { $0.serverUrl == serverUrl && $0.fileName == fileName}) != nil {
-                    let progress = progressNumber.floatValue
-                    if progress == 1 {
-                        self.progressView.progress = 0
-                    } else {
-                        self.progressView.progress = progress
-                    }
+        if (metadata.classFile == NCCommunicationCommon.typeClassFile.video.rawValue || metadata.classFile == NCCommunicationCommon.typeClassFile.audio.rawValue) {
+            
+            if ncplayer == nil, let url = NCKTVHTTPCache.shared.getVideoURL(metadata: metadata) {
+                self.ncplayer = NCPlayer.init(url: url, autoPlay: self.autoPlay, imageVideoContainer: self.imageVideoContainer, playerToolBar: self.playerToolBar, metadata: self.metadata, detailView: self.detailView)
+            } else {
+                self.ncplayer?.activateObserver(playerToolBar: self.playerToolBar)
+                if detailView.isShow() == false && ncplayer?.isPlay() == false {
+                    NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterShowPlayerToolBar, userInfo: ["ocId":metadata.ocId, "enableTimerAutoHide": false])
                 }
             }
-        }
-    }
-    
-    @objc func deleteFile(_ notification: NSNotification) {
-        
-        if let userInfo = notification.userInfo as NSDictionary? {
-            if let ocId = userInfo["ocId"] as? String {
-                
-                let metadatas = self.metadatas.filter { $0.ocId != ocId }
-                if self.metadatas.count == metadatas.count { return }
-                self.metadatas = metadatas
-                
-                if ocId == currentViewController.metadata.ocId {
-                    if !shiftCurrentPage() {
-                        self.viewUnload()
-                    }
-                }
+            
+            if let ncplayer = self.ncplayer {
+                self.viewerMediaPage?.updateCommandCenter(ncplayer: ncplayer, metadata: self.metadata)
             }
-        }
-    }
-    
-    @objc func renameFile(_ notification: NSNotification) {
-        
-        if let userInfo = notification.userInfo as NSDictionary? {
-            if let ocId = userInfo["ocId"] as? String, let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
-                
-                if let index = metadatas.firstIndex(where: {$0.ocId == metadata.ocId}) {
-                    metadatas[index] = metadata
-                    if index == currentIndex {
-                        navigationItem.title = metadata.fileNameView
-                        currentViewController.metadata = metadata
-                        self.currentViewController.metadata = metadata
-                    }
-                }
+            
+        } else if metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue {
+            
+            if let image = viewerMediaPage?.getImageMetadata(metadata) {
+                self.image = image
+                self.imageVideoContainer.image = image
             }
+            viewerMediaPage?.clearCommandCenter()
         }
-    }
-    
-    @objc func moveFile(_ notification: NSNotification) {
         
-        if let userInfo = notification.userInfo as NSDictionary? {
-            if let ocId = userInfo["ocId"] as? String, let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
-                
-                if metadatas.firstIndex(where: {$0.ocId == metadata.ocId}) != nil {
-                    deleteFile(notification)
-                }
-            }
-        }
+        NotificationCenter.default.addObserver(self, selector: #selector(openDetail(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterOpenMediaDetail), object: nil)
     }
     
-    @objc func changeTheming() {
-    }
-    
-    @objc func hidePlayerToolBar(_ notification: NSNotification) {
-        
-        if let userInfo = notification.userInfo as NSDictionary?, let ocId = userInfo["ocId"] as? String {
-            if currentViewController.metadata.ocId == ocId {
-                changeScreenMode(mode: .full)
-            }
-        }
+    override func viewDidDisappear(_ animated: Bool) {
+        super.viewDidDisappear(animated)
     }
     
-    @objc func showPlayerToolBar(_ notification: NSNotification) {
+    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
+        super.viewWillTransition(to: size, with: coordinator)
         
-        if let userInfo = notification.userInfo as NSDictionary?, let ocId = userInfo["ocId"] as? String, let enableTimerAutoHide = userInfo["enableTimerAutoHide"] as? Bool{
-            if currentViewController.metadata.ocId == ocId, let playerToolBar = currentViewController.playerToolBar, !playerToolBar.isPictureInPictureActive() {
-                changeScreenMode(mode: .normal, enableTimerAutoHide: enableTimerAutoHide)
+        coordinator.animate(alongsideTransition: { (context) in
+            // back to the original size
+            self.scrollView.zoom(to: CGRect(x: 0, y: 0, width: self.scrollView.bounds.width, height: self.scrollView.bounds.height), animated: false)
+            self.view.layoutIfNeeded()
+            UIView.animate(withDuration: context.transitionDuration) {
+                if self.detailView.isShow() {
+                    self.openDetail()
+                }
             }
-        }
+        }) { (_) in }
     }
     
-    @objc func applicationDidBecomeActive(_ notification: NSNotification) {
-        
-        progressView.progress = 0
-    }
-    
-    //MARK: - Image
-    
-    func getImageMetadata(_ metadata: tableMetadata) -> UIImage? {
-                
-        if let image = getImage(metadata: metadata) {
-            return image
-        }
+    //MARK: - Gesture
+
+    @objc func didDoubleTapWith(gestureRecognizer: UITapGestureRecognizer) {
         
-        if metadata.classFile == NCCommunicationCommon.typeClassFile.video.rawValue && !metadata.hasPreview {
-            NCUtility.shared.createImageFrom(fileName: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, classFile: metadata.classFile)
-        }
+        if detailView.isShow() { return }
+        // NO ZOOM for Audio
+        if metadata.classFile == NCCommunicationCommon.typeClassFile.audio.rawValue { return }
         
-        if CCUtility.fileProviderStoragePreviewIconExists(metadata.ocId, etag: metadata.etag) {
-            if let imagePreviewPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag) {
-                return UIImage.init(contentsOfFile: imagePreviewPath)
-            } 
+        let pointInView = gestureRecognizer.location(in: self.imageVideoContainer)
+        var newZoomScale = self.scrollView.maximumZoomScale
+            
+        if self.scrollView.zoomScale >= newZoomScale || abs(self.scrollView.zoomScale - newZoomScale) <= 0.01 {
+            newZoomScale = self.scrollView.minimumZoomScale
         }
-        
-        return nil
+                
+        let width = self.scrollView.bounds.width / newZoomScale
+        let height = self.scrollView.bounds.height / newZoomScale
+        let originX = pointInView.x - (width / 2.0)
+        let originY = pointInView.y - (height / 2.0)
+        let rectToZoomTo = CGRect(x: originX, y: originY, width: width, height: height)
+        self.scrollView.zoom(to: rectToZoomTo, animated: true)
     }
-    
-    private func getImage(metadata: tableMetadata) -> UIImage? {
+      
+    @objc func didPanWith(gestureRecognizer: UIPanGestureRecognizer) {
+                
+        let currentLocation = gestureRecognizer.translation(in: self.view)
         
-        let ext = CCUtility.getExtension(metadata.fileNameView)
-        var image: UIImage?
+        switch gestureRecognizer.state {
         
-        if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) && metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue {
-           
-            let previewPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag)!
-            let imagePath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!
+        case .began:
             
-            if ext == "GIF" {
-                if !FileManager().fileExists(atPath: previewPath) {
-                    NCUtility.shared.createImageFrom(fileName: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, classFile: metadata.classFile)
-                }
-                image = UIImage.animatedImage(withAnimatedGIFURL: URL(fileURLWithPath: imagePath))
-            } else if ext == "SVG" {
-                if let svgImage = SVGKImage(contentsOfFile: imagePath) {
-                    svgImage.size = CGSize(width: NCGlobal.shared.sizePreview, height: NCGlobal.shared.sizePreview)
-                    if let image = svgImage.uiImage {
-                        if !FileManager().fileExists(atPath: previewPath) {
-                            do {
-                                try image.pngData()?.write(to: URL(fileURLWithPath: previewPath), options: .atomic)
-                            } catch { }
-                        }
-                        return image
-                    } else {
-                        return nil
-                    }
-                } else {
-                    return nil
-                }
-            } else {
-                NCUtility.shared.createImageFrom(fileName: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, classFile: metadata.classFile)
-                image = UIImage.init(contentsOfFile: imagePath)
-            }
-        }
-        
-        return image
-    }
-    
-    // MARK: - Command Center
-
-    func updateCommandCenter(ncplayer: NCPlayer, metadata: tableMetadata) {
+//        let velocity = gestureRecognizer.velocity(in: self.view)
 
-        var nowPlayingInfo = [String : Any]()
+//            gesture moving Up
+//            if velocity.y < 0 {
 
-        // Clear
-        clearCommandCenter()
-        UIApplication.shared.beginReceivingRemoteControlEvents()
+//            }
+            break
 
-        // Add handler for Play Command
-        MPRemoteCommandCenter.shared().playCommand.isEnabled = true
-        playCommand = MPRemoteCommandCenter.shared().playCommand.addTarget { event in
-            
-            if !ncplayer.isPlay() {
-                ncplayer.playerPlay()
-                return .success
-            }
-            return .commandFailed
-        }
-      
-        // Add handler for Pause Command
-        MPRemoteCommandCenter.shared().pauseCommand.isEnabled = true
-        pauseCommand = MPRemoteCommandCenter.shared().pauseCommand.addTarget { event in
-          
-            if ncplayer.isPlay() {
-                ncplayer.playerPause()
-                return .success
-            }
-            return .commandFailed
-        }
-        
-        // VIDEO / AUDIO () ()
-        if metadata.classFile == NCCommunicationCommon.typeClassFile.video.rawValue || metadata.classFile == NCCommunicationCommon.typeClassFile.audio.rawValue {
-            
-            MPRemoteCommandCenter.shared().skipForwardCommand.isEnabled = true
-            skipForwardCommand = MPRemoteCommandCenter.shared().skipForwardCommand.addTarget { event in
-                
-                let seconds = Float64((event as! MPSkipIntervalCommandEvent).interval)
-                self.currentViewController.playerToolBar.skip(seconds: seconds)
-                return.success
-            }
+        case .ended:
             
-            MPRemoteCommandCenter.shared().skipBackwardCommand.isEnabled = true
-            skipBackwardCommand = MPRemoteCommandCenter.shared().skipBackwardCommand.addTarget { event in
-                
-                let seconds = Float64((event as! MPSkipIntervalCommandEvent).interval)
-                self.currentViewController.playerToolBar.skip(seconds: -seconds)
-                return.success
+            if detailView.isShow() {
+                self.imageViewTopConstraint.constant = -imageViewConstraint
+                self.imageViewBottomConstraint.constant = imageViewConstraint
+            } else {
+                self.imageViewTopConstraint.constant = 0
+                self.imageViewBottomConstraint.constant = 0
             }
-        }
-                
-        // AUDIO < >
-        /*
-        if metadata?.classFile == NCCommunicationCommon.typeClassFile.audio.rawValue {
+
+        case .changed:
                         
-            MPRemoteCommandCenter.shared().nextTrackCommand.isEnabled = true
-            appDelegate.nextTrackCommand = MPRemoteCommandCenter.shared().nextTrackCommand.addTarget { event in
+            imageViewTopConstraint.constant = (currentLocation.y - imageViewConstraint)
+            imageViewBottomConstraint.constant = -(currentLocation.y - imageViewConstraint)
+            
+            // DISMISS VIEW
+            if detailView.isHidden && (currentLocation.y > 20) {
                 
-                self.forward()
-                return .success
+                viewerMediaPage?.navigationController?.popViewController(animated: true)
+                gestureRecognizer.state = .ended
             }
             
-            MPRemoteCommandCenter.shared().previousTrackCommand.isEnabled = true
-            appDelegate.previousTrackCommand = MPRemoteCommandCenter.shared().previousTrackCommand.addTarget { event in
-             
-                self.backward()
-                return .success
+            // CLOSE DETAIL
+            if !detailView.isHidden && (currentLocation.y > 20) {
+                               
+                self.closeDetail()
+                gestureRecognizer.state = .ended
             }
-        }
-        */
-        
-        nowPlayingInfo[MPMediaItemPropertyTitle] = metadata.fileNameView
-        nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = ncplayer.durationTime.seconds
-        if let image = currentViewController.image {
-            nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size) { size in
-                return image
-            }
-        }
-        MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
-    }
-
-    func clearCommandCenter() {
-        
-        UIApplication.shared.endReceivingRemoteControlEvents()
-        MPNowPlayingInfoCenter.default().nowPlayingInfo = [:]
-
-        MPRemoteCommandCenter.shared().playCommand.isEnabled = false
-        MPRemoteCommandCenter.shared().pauseCommand.isEnabled = false
-        MPRemoteCommandCenter.shared().skipForwardCommand.isEnabled = false
-        MPRemoteCommandCenter.shared().skipBackwardCommand.isEnabled = false
-        MPRemoteCommandCenter.shared().nextTrackCommand.isEnabled = false
-        MPRemoteCommandCenter.shared().previousTrackCommand.isEnabled = false
 
-        if let playCommand = playCommand {
-            MPRemoteCommandCenter.shared().playCommand.removeTarget(playCommand)
-            self.playCommand = nil
-        }
-        if let pauseCommand = pauseCommand {
-            MPRemoteCommandCenter.shared().pauseCommand.removeTarget(pauseCommand)
-            self.pauseCommand = nil
-        }
-        if let skipForwardCommand = skipForwardCommand {
-            MPRemoteCommandCenter.shared().skipForwardCommand.removeTarget(skipForwardCommand)
-            self.skipForwardCommand = nil
-        }
-        if let skipBackwardCommand = skipBackwardCommand {
-            MPRemoteCommandCenter.shared().skipBackwardCommand.removeTarget(skipBackwardCommand)
-            self.skipBackwardCommand = nil
-        }
-        if let nextTrackCommand = nextTrackCommand {
-            MPRemoteCommandCenter.shared().nextTrackCommand.removeTarget(nextTrackCommand)
-            self.nextTrackCommand = nil
-        }
-        if let previousTrackCommand = previousTrackCommand {
-            MPRemoteCommandCenter.shared().previousTrackCommand.removeTarget(previousTrackCommand)
-            self.previousTrackCommand = nil
+            // OPEN DETAIL
+            if detailView.isHidden && (currentLocation.y < -20) {
+                       
+                self.openDetail()
+                gestureRecognizer.state = .ended
+            }
+                        
+        default:
+            break
         }
     }
 }
 
-// MARK: - UIPageViewController Delegate Datasource
+//MARK: -
 
-extension NCViewerMedia: UIPageViewControllerDelegate, UIPageViewControllerDataSource {
+extension NCViewerMedia {
     
-    func shiftCurrentPage() -> Bool {
+    @objc func openDetail(_ notification: NSNotification) {
         
-        if metadatas.count == 0 { return false }
-        
-        var direction: UIPageViewController.NavigationDirection = .forward
-        
-        if currentIndex == metadatas.count {
-            currentIndex -= 1
-            direction = .reverse
+        if let userInfo = notification.userInfo as NSDictionary?, let ocId = userInfo["ocId"] as? String, ocId == metadata.ocId {
+            openDetail()
         }
-        
-        currentViewController.ncplayer?.deactivateObserver()
-        
-        let viewerMediaZoom = getViewerMediaZoom(index: currentIndex, image: getImageMetadata(metadatas[currentIndex]), metadata: metadatas[currentIndex], direction: direction)
-        pageViewController.setViewControllers([viewerMediaZoom], direction: direction, animated: true, completion: nil)
-        
-        return true
     }
     
-    func goTo(index: Int, direction: UIPageViewController.NavigationDirection, autoPlay: Bool) {
-        
-        currentIndex = index
+    private func openDetail() {
         
-        currentViewController.ncplayer?.deactivateObserver()
-
-        let viewerMediaZoom = getViewerMediaZoom(index: currentIndex, image: getImageMetadata(metadatas[currentIndex]), metadata: metadatas[currentIndex], direction: direction)
-        viewerMediaZoom.autoPlay = autoPlay
-        pageViewController.setViewControllers([viewerMediaZoom], direction: direction, animated: true, completion: nil)
-    }
-    
-    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
-        
-        if currentIndex == 0 { return nil }
-
-        let viewerMediaZoom = getViewerMediaZoom(index: currentIndex-1, image: getImageMetadata(metadatas[currentIndex-1]), metadata: metadatas[currentIndex-1], direction: .reverse)
-        return viewerMediaZoom
+        CCUtility.setExif(metadata) { (latitude, longitude, location, date, lensModel) in
+            
+            if (latitude != -1 && latitude != 0 && longitude != -1 && longitude != 0) {
+                self.detailViewHeighConstraint.constant = self.view.bounds.height / 2
+            } else {
+                self.detailViewHeighConstraint.constant = 170
+            }
+            self.view.layoutIfNeeded()
+            
+            self.detailView.show(metadata:self.metadata, image: self.image, textColor: self.viewerMediaPage?.textColor, latitude: latitude, longitude: longitude, location: location, date: date, lensModel: lensModel, delegate: self)
+                
+            if let image = self.imageVideoContainer.image {
+                let ratioW = self.imageVideoContainer.frame.width / image.size.width
+                let ratioH = self.imageVideoContainer.frame.height / image.size.height
+                let ratio = ratioW < ratioH ? ratioW : ratioH
+                let imageHeight = image.size.height * ratio
+                self.imageViewConstraint = self.detailView.frame.height - ((self.view.frame.height - imageHeight) / 2) + self.view.safeAreaInsets.bottom
+                if self.imageViewConstraint < 0 { self.imageViewConstraint = 0 }
+            }
+                
+            UIView.animate(withDuration: 0.3) {
+                self.imageViewTopConstraint.constant = -self.imageViewConstraint
+                self.imageViewBottomConstraint.constant = self.imageViewConstraint
+                self.detailViewTopConstraint.constant = self.detailViewHeighConstraint.constant
+                self.view.layoutIfNeeded()
+            } completion: { (_) in
+            }
+                
+            self.scrollView.pinchGestureRecognizer?.isEnabled = false
+            self.playerToolBar.hide()
+        }
     }
     
-    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
+    private func closeDetail() {
         
-        if currentIndex == metadatas.count-1 { return nil }
-
-        let viewerMediaZoom = getViewerMediaZoom(index: currentIndex+1, image: getImageMetadata(metadatas[currentIndex+1]), metadata: metadatas[currentIndex+1], direction: .forward)
-        return viewerMediaZoom
-    }
-    
-    // START TRANSITION
-    func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
+        self.detailView.hide()
+        imageViewConstraint = 0
         
-        // Save time video
-        if let ncplayer = currentViewController.ncplayer, ncplayer.isPlay() {
-            ncplayer.saveCurrentTime()
+        UIView.animate(withDuration: 0.3) {
+            self.imageViewTopConstraint.constant = 0
+            self.imageViewBottomConstraint.constant = 0
+            self.detailViewTopConstraint.constant = 0
+            self.view.layoutIfNeeded()
+        } completion: { (_) in
         }
         
-        guard let nextViewController = pendingViewControllers.first as? NCViewerMediaZoom else { return }
-        nextIndex = nextViewController.index        
+        scrollView.pinchGestureRecognizer?.isEnabled = true
+        if metadata.classFile == NCCommunicationCommon.typeClassFile.video.rawValue && !metadata.livePhoto && ncplayer?.player?.timeControlStatus == .paused {
+            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterShowPlayerToolBar, userInfo: ["ocId":metadata.ocId, "enableTimerAutoHide": false])
+        }
     }
     
-    // END TRANSITION
-    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
+    func reloadDetail() {
         
-        if (completed && nextIndex != nil) {
-            previousViewControllers.forEach { viewController in
-                let viewerMediaZoom = viewController as! NCViewerMediaZoom
-                viewerMediaZoom.ncplayer?.deactivateObserver()
+        if self.detailView.isShow() {
+            CCUtility.setExif(metadata) { (latitude, longitude, location, date, lensModel) in
+                self.detailView.show(metadata:self.metadata, image: self.image, textColor: self.viewerMediaPage?.textColor, latitude: latitude, longitude: longitude, location: location, date: date, lensModel: lensModel, delegate: self)
             }
-            currentIndex = nextIndex!
         }
-        
-        self.nextIndex = nil
     }
-}
-
-//MARK: - UIGestureRecognizerDelegate
-
-extension NCViewerMedia: UIGestureRecognizerDelegate {
-
-    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
+    
+    func downloadFile() {
         
-        if let gestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer {
-            let velocity = gestureRecognizer.velocity(in: self.view)
-            
-            var velocityCheck : Bool = false
+        let isFolderEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase)
+        let ext = CCUtility.getExtension(metadata.fileNameView)
+        var etagResource: String?
+        
+        // DOWNLOAD preview for image
+        if !CCUtility.fileProviderStoragePreviewIconExists(metadata.ocId, etag: metadata.etag) && metadata.hasPreview && metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue {
             
-            if UIDevice.current.orientation.isLandscape {
-                velocityCheck = velocity.x < 0
+            let fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, account: metadata.account)!
+            let fileNamePreviewLocalPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag)!
+            let fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)!
+            if FileManager.default.fileExists(atPath: fileNameIconLocalPath) && FileManager.default.fileExists(atPath: fileNamePreviewLocalPath) {
+                etagResource = metadata.etagResource
             }
-            else {
-                velocityCheck = velocity.y < 0
-            }
-            if velocityCheck {
-                return false
+            
+            NCCommunication.shared.downloadPreview(fileNamePathOrFileId: fileNamePath, fileNamePreviewLocalPath: fileNamePreviewLocalPath , widthPreview: NCGlobal.shared.sizePreview, heightPreview: NCGlobal.shared.sizePreview, fileNameIconLocalPath: fileNameIconLocalPath, sizeIcon: NCGlobal.shared.sizeIcon, etag: etagResource, queue: NCCommunicationCommon.shared.backgroundQueue) { (account, imagePreview, imageIcon, imageOriginal, etag, errorCode, errorDescription) in
+                
+                if errorCode == 0, let image = self.viewerMediaPage?.getImageMetadata(self.metadata) {
+                    DispatchQueue.main.async {
+                        self.image = image
+                        self.imageVideoContainer.image = image
+                    }
+                }
             }
         }
         
-        return true
-    }
-    
-    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
-        
-        if otherGestureRecognizer == currentViewController.scrollView.panGestureRecognizer {
-            if self.currentViewController.scrollView.contentOffset.y == 0 {
-                return true
+        // DOWNLOAD FILE
+        if ((metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue && CCUtility.getAutomaticDownloadImage()) || (metadata.contentType == "image/heic" &&  metadata.hasPreview == false) || ext == "GIF" || ext == "SVG" || isFolderEncrypted) && metadata.session == "" && !CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
+            
+            NCNetworking.shared.download(metadata: metadata, selector: "") { (errorCode) in
+                
+                if errorCode == 0, let image = self.viewerMediaPage?.getImageMetadata(self.metadata) {
+                    DispatchQueue.main.async {
+                        self.image = image
+                        self.imageVideoContainer.image = image
+                    }
+                }
             }
         }
-        
-        return false
     }
+}
 
-    @objc func didPanWith(gestureRecognizer: UIPanGestureRecognizer) {
-        
-        currentViewController.didPanWith(gestureRecognizer: gestureRecognizer)
-    }
+//MARK: -
+
+extension NCViewerMedia: UIScrollViewDelegate {
     
-    @objc func didSingleTapWith(gestureRecognizer: UITapGestureRecognizer) {
-                
-        if let playerToolBar = currentViewController.playerToolBar, playerToolBar.isPictureInPictureActive() {
-            playerToolBar.pictureInPictureController?.stopPictureInPicture()
-        }
-        
-        if currentScreenMode == .full {
-            
-            changeScreenMode(mode: .normal, enableTimerAutoHide: true)
-                        
-        } else {
-            
-            changeScreenMode(mode: .full)
-        }
+    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
+        return imageVideoContainer
     }
     
-    //
-    // LIVE PHOTO
-    //
-    @objc func didLongpressGestureEvent(gestureRecognizer: UITapGestureRecognizer) {
+    func scrollViewDidZoom(_ scrollView: UIScrollView) {
         
-        if !currentViewController.metadata.livePhoto { return }
-        
-        if gestureRecognizer.state == .began {
-            
-            currentViewController.updateViewConstraints()
-            currentViewController.statusViewImage.isHidden = true
-            currentViewController.statusLabel.isHidden = true
-            
-            let fileName = (currentViewController.metadata.fileNameView as NSString).deletingPathExtension + ".mov"
-            if let metadata = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView LIKE[c] %@", currentViewController.metadata.account, currentViewController.metadata.serverUrl, fileName)) {
+        if scrollView.zoomScale > 1 {
+            if let image = imageVideoContainer.image {
                 
-                if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
-                    
-                    AudioServicesPlaySystemSound(1519) // peek feedback
-                    
-                    if let url = NCKTVHTTPCache.shared.getVideoURL(metadata: metadata) {
-                        self.ncplayerLivePhoto = NCPlayer.init(url: url, autoPlay: true, imageVideoContainer: self.currentViewController.imageVideoContainer, playerToolBar: nil, metadata: metadata, detailView: nil)
-                    }
-                    
-                } else {
-                    
-                    let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileNameView
-                    let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!
-                                    
-                    NCCommunication.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, requestHandler: { (_) in
-                        
-                    }, taskHandler: { (_) in
-                        
-                    }, progressHandler: { (progress) in
-                                        
-                        self.progressView.progress = Float(progress.fractionCompleted)
-                        
-                    }) { (account, etag, date, length, allHeaderFields, error, errorCode, errorDescription) in
-                        
-                        self.progressView.progress = 0
-                        
-                        if errorCode == 0 && account == metadata.account {
-                            
-                            NCManageDatabase.shared.addLocalFile(metadata: metadata)
-                            
-                            if gestureRecognizer.state == .changed || gestureRecognizer.state == .began {
-                                AudioServicesPlaySystemSound(1519) // peek feedback
-                                
-                                if let url = NCKTVHTTPCache.shared.getVideoURL(metadata: metadata) {
-                                    self.ncplayerLivePhoto = NCPlayer.init(url: url, autoPlay: true, imageVideoContainer: self.currentViewController.imageVideoContainer, playerToolBar: nil, metadata: metadata, detailView: nil)
-                                }
-                            }
-                        }
-                    }
-                }
+                let ratioW = imageVideoContainer.frame.width / image.size.width
+                let ratioH = imageVideoContainer.frame.height / image.size.height
+                let ratio = ratioW < ratioH ? ratioW : ratioH
+                let newWidth = image.size.width * ratio
+                let newHeight = image.size.height * ratio
+                let conditionLeft = newWidth*scrollView.zoomScale > imageVideoContainer.frame.width
+                let left = 0.5 * (conditionLeft ? newWidth - imageVideoContainer.frame.width : (scrollView.frame.width - scrollView.contentSize.width))
+                let conditioTop = newHeight*scrollView.zoomScale > imageVideoContainer.frame.height
+                
+                let top = 0.5 * (conditioTop ? newHeight - imageVideoContainer.frame.height : (scrollView.frame.height - scrollView.contentSize.height))
+                
+                scrollView.contentInset = UIEdgeInsets(top: top, left: left, bottom: top, right: left)
             }
-            
-        } else if gestureRecognizer.state == .ended {
-            
-            currentViewController.statusViewImage.isHidden = false
-            currentViewController.statusLabel.isHidden = false
-            currentViewController.imageVideoContainer.image = currentViewController.image
-            ncplayerLivePhoto?.videoLayer?.removeFromSuperlayer()
-            ncplayerLivePhoto?.deactivateObserver()
+        } else {
+            scrollView.contentInset = .zero
         }
     }
+    
+    func scrollViewDidScroll(_ scrollView: UIScrollView) {
+    }
+}
+
+extension NCViewerMedia: NCViewerMediaDetailViewDelegate  {
+    
+    func downloadFullResolution() {
+        closeDetail()
+        NCNetworking.shared.download(metadata: metadata, selector: NCGlobal.shared.selectorOpenDetail) { (_) in }
+    }
+}
+
+//MARK: -
+
+class imageVideoContainerView: UIImageView {
+    var playerLayer: CALayer?
+    var metadata: tableMetadata?
+    override func layoutSublayers(of layer: CALayer) {
+        super.layoutSublayers(of: layer)
+        playerLayer?.frame = self.bounds
+    }
 }

+ 4 - 4
iOSClient/Viewer/NCViewerMedia/NCViewerMedia.storyboard → iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.storyboard

@@ -10,10 +10,10 @@
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <scenes>
-        <!--Viewer Media-->
+        <!--Viewer Media Page-->
         <scene sceneID="yQe-Pb-BKZ">
             <objects>
-                <viewController automaticallyAdjustsScrollViewInsets="NO" hidesBottomBarWhenPushed="YES" id="ne8-hS-cp3" customClass="NCViewerMedia" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController">
+                <viewController automaticallyAdjustsScrollViewInsets="NO" hidesBottomBarWhenPushed="YES" id="ne8-hS-cp3" customClass="NCViewerMediaPage" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController">
                     <layoutGuides>
                         <viewControllerLayoutGuide type="top" id="8k6-KQ-iNa"/>
                         <viewControllerLayoutGuide type="bottom" id="baP-ZX-MR4"/>
@@ -65,10 +65,10 @@
             </objects>
             <point key="canvasLocation" x="3748" y="777.66116941529242"/>
         </scene>
-        <!--Viewer Media Zoom-->
+        <!--Viewer Media-->
         <scene sceneID="rpT-vc-Kiv">
             <objects>
-                <viewController storyboardIdentifier="NCViewerMediaZoom" automaticallyAdjustsScrollViewInsets="NO" id="gXy-ag-ank" customClass="NCViewerMediaZoom" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController">
+                <viewController storyboardIdentifier="NCViewerMedia" automaticallyAdjustsScrollViewInsets="NO" id="gXy-ag-ank" customClass="NCViewerMedia" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController">
                     <layoutGuides>
                         <viewControllerLayoutGuide type="top" id="IQm-1K-tBr"/>
                         <viewControllerLayoutGuide type="bottom" id="zwn-Sc-mqc"/>

+ 689 - 0
iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.swift

@@ -0,0 +1,689 @@
+//
+//  NCViewerMediaPage.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 24/10/2020.
+//  Copyright © 2020 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+import UIKit
+import SVGKit
+import NCCommunication
+import MediaPlayer
+
+class NCViewerMediaPage: UIViewController {
+
+    @IBOutlet weak var progressView: UIProgressView!
+    
+    enum ScreenMode {
+        case full, normal
+    }
+    var currentScreenMode: ScreenMode = .normal
+    var saveScreenModeImage: ScreenMode = .normal
+
+    var pageViewController: UIPageViewController {
+        return self.children[0] as! UIPageViewController
+    }
+    
+    var currentViewController: NCViewerMedia {
+        return self.pageViewController.viewControllers![0] as! NCViewerMedia
+    }
+    
+    let appDelegate = UIApplication.shared.delegate as! AppDelegate
+
+    var metadatas: [tableMetadata] = []
+    var currentIndex = 0
+    var nextIndex: Int?
+    var IndexInPlay: Int = -1
+    var ncplayerLivePhoto: NCPlayer?
+    var panGestureRecognizer: UIPanGestureRecognizer!
+    var singleTapGestureRecognizer: UITapGestureRecognizer!
+    var longtapGestureRecognizer: UILongPressGestureRecognizer!
+    
+    var textColor: UIColor = NCBrandColor.shared.label
+    
+    var playCommand: Any?
+    var pauseCommand: Any?
+    var skipForwardCommand: Any?
+    var skipBackwardCommand: Any?
+    var nextTrackCommand: Any?
+    var previousTrackCommand: Any?
+    
+
+    // MARK: - View Life Cycle
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        
+        navigationItem.rightBarButtonItem = UIBarButtonItem.init(image: UIImage(named: "more")!.image(color: NCBrandColor.shared.label, size: 25), style: .plain, target: self, action: #selector(self.openMenuMore))
+        
+        singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didSingleTapWith(gestureRecognizer:)))
+        panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(didPanWith(gestureRecognizer:)))
+        longtapGestureRecognizer = UILongPressGestureRecognizer()
+        longtapGestureRecognizer.delaysTouchesBegan = true
+        longtapGestureRecognizer.minimumPressDuration = 0.3
+        longtapGestureRecognizer.delegate = self
+        longtapGestureRecognizer.addTarget(self, action: #selector(didLongpressGestureEvent(gestureRecognizer:)))
+        
+        pageViewController.delegate = self
+        pageViewController.dataSource = self
+        pageViewController.view.addGestureRecognizer(panGestureRecognizer)
+        pageViewController.view.addGestureRecognizer(singleTapGestureRecognizer)
+        pageViewController.view.addGestureRecognizer(longtapGestureRecognizer)
+        
+        let viewerMedia = getViewerMedia(index: currentIndex, image: getImageMetadata(metadatas[currentIndex]), metadata: metadatas[currentIndex], direction: .forward)
+        pageViewController.setViewControllers([viewerMedia], direction: .forward, animated: true, completion: nil)
+        
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterChangeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(viewUnload), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMenuDetailClose), object: nil)
+        
+        progressView.tintColor = NCBrandColor.shared.brandElement
+        progressView.trackTintColor = .clear
+        progressView.progress = 0
+        
+        NotificationCenter.default.addObserver(self, selector: #selector(deleteFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterDeleteFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(renameFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterRenameFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(moveFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMoveFile), object: nil)
+
+        NotificationCenter.default.addObserver(self, selector: #selector(downloadedFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterDownloadedFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(triggerProgressTask(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterProgressTask), object:nil)
+        
+        NotificationCenter.default.addObserver(self, selector: #selector(hidePlayerToolBar(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterHidePlayerToolBar), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(showPlayerToolBar(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterShowPlayerToolBar), object: nil)
+        
+        NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterApplicationDidBecomeActive), object: nil)
+    }
+    
+    override func viewDidDisappear(_ animated: Bool) {
+        super.viewDidDisappear(animated)
+        
+        // Clear
+        if let ncplayer = currentViewController.ncplayer, ncplayer.isPlay() {
+            ncplayer.playerPause()
+            ncplayer.saveCurrentTime()
+        }
+        currentViewController.playerToolBar.stopTimerAutoHide()
+        clearCommandCenter()
+        
+        metadatas.removeAll()
+        ncplayerLivePhoto = nil
+        
+        // Remove Observer
+        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterDeleteFile), object: nil)
+        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterRenameFile), object: nil)
+        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMoveFile), object: nil)
+
+        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterDownloadedFile), object: nil)
+        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterProgressTask), object: nil)
+        
+        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterHidePlayerToolBar), object: nil)
+        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterShowPlayerToolBar), object: nil)
+        
+        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterApplicationDidBecomeActive), object: nil)
+    }
+    
+    override var preferredStatusBarStyle: UIStatusBarStyle {
+        
+        if currentScreenMode == .normal {
+            return .default
+        } else {
+            return .lightContent
+        }
+    }
+    
+    // MARK: -
+    
+    func getViewerMedia(index: Int, image: UIImage?, metadata: tableMetadata, direction: UIPageViewController.NavigationDirection) -> NCViewerMedia {
+        
+        let viewerMedia = UIStoryboard(name: "NCViewerMediaPage", bundle: nil).instantiateViewController(withIdentifier: "NCViewerMedia") as! NCViewerMedia
+        viewerMedia.index = index
+        viewerMedia.image = image
+        viewerMedia.metadata = metadata
+        viewerMedia.viewerMediaPage = self
+
+        singleTapGestureRecognizer.require(toFail: viewerMedia.doubleTapGestureRecognizer)
+       
+        return viewerMedia
+    }
+
+    @objc func viewUnload() {
+        
+        navigationController?.popViewController(animated: true)
+    }
+    
+    @objc func openMenuMore() {
+        
+        let imageIcon = UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(currentViewController.metadata.ocId, etag: currentViewController.metadata.etag))
+        NCViewer.shared.toggleMenu(viewController: self, metadata: currentViewController.metadata, webView: false, imageIcon: imageIcon)
+    }
+    
+    func changeScreenMode(mode: ScreenMode, enableTimerAutoHide: Bool = false) {
+        
+        if mode == .normal {
+            
+            navigationController?.setNavigationBarHidden(false, animated: true)
+            progressView.isHidden = false
+
+            if !currentViewController.detailView.isShow() {
+                currentViewController.playerToolBar.show(enableTimerAutoHide: enableTimerAutoHide)
+            }
+            
+            NCUtility.shared.colorNavigationController(navigationController, backgroundColor: NCBrandColor.shared.systemBackground, titleColor: NCBrandColor.shared.label, tintColor: nil, withoutShadow: false)
+            view.backgroundColor = NCBrandColor.shared.systemBackground
+            textColor = NCBrandColor.shared.label
+            
+        } else {
+            
+            navigationController?.setNavigationBarHidden(true, animated: true)
+            progressView.isHidden = true
+            
+            currentViewController.playerToolBar.hide()
+
+            view.backgroundColor = .black
+            textColor = .white
+        }
+        
+        currentScreenMode = mode
+        
+        if currentViewController.metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue {
+            saveScreenModeImage = mode
+        }
+        
+        setNeedsStatusBarAppearanceUpdate()
+        currentViewController.reloadDetail()
+    }
+    
+    //MARK: - NotificationCenter
+
+    @objc func downloadedFile(_ notification: NSNotification) {
+        
+        progressView.progress = 0
+    }
+    
+    @objc func triggerProgressTask(_ notification: NSNotification) {
+        
+        if let userInfo = notification.userInfo as NSDictionary? {
+            if let serverUrl = userInfo["serverUrl"] as? String, let fileName = userInfo["fileName"] as? String, let progressNumber = userInfo["progress"] as? NSNumber {
+                if self.metadatas.first(where: { $0.serverUrl == serverUrl && $0.fileName == fileName}) != nil {
+                    let progress = progressNumber.floatValue
+                    if progress == 1 {
+                        self.progressView.progress = 0
+                    } else {
+                        self.progressView.progress = progress
+                    }
+                }
+            }
+        }
+    }
+    
+    @objc func deleteFile(_ notification: NSNotification) {
+        
+        if let userInfo = notification.userInfo as NSDictionary? {
+            if let ocId = userInfo["ocId"] as? String {
+                
+                let metadatas = self.metadatas.filter { $0.ocId != ocId }
+                if self.metadatas.count == metadatas.count { return }
+                self.metadatas = metadatas
+                
+                if ocId == currentViewController.metadata.ocId {
+                    if !shiftCurrentPage() {
+                        self.viewUnload()
+                    }
+                }
+            }
+        }
+    }
+    
+    @objc func renameFile(_ notification: NSNotification) {
+        
+        if let userInfo = notification.userInfo as NSDictionary? {
+            if let ocId = userInfo["ocId"] as? String, let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
+                
+                if let index = metadatas.firstIndex(where: {$0.ocId == metadata.ocId}) {
+                    metadatas[index] = metadata
+                    if index == currentIndex {
+                        navigationItem.title = metadata.fileNameView
+                        currentViewController.metadata = metadata
+                        self.currentViewController.metadata = metadata
+                    }
+                }
+            }
+        }
+    }
+    
+    @objc func moveFile(_ notification: NSNotification) {
+        
+        if let userInfo = notification.userInfo as NSDictionary? {
+            if let ocId = userInfo["ocId"] as? String, let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
+                
+                if metadatas.firstIndex(where: {$0.ocId == metadata.ocId}) != nil {
+                    deleteFile(notification)
+                }
+            }
+        }
+    }
+    
+    @objc func changeTheming() {
+    }
+    
+    @objc func hidePlayerToolBar(_ notification: NSNotification) {
+        
+        if let userInfo = notification.userInfo as NSDictionary?, let ocId = userInfo["ocId"] as? String {
+            if currentViewController.metadata.ocId == ocId {
+                changeScreenMode(mode: .full)
+            }
+        }
+    }
+    
+    @objc func showPlayerToolBar(_ notification: NSNotification) {
+        
+        if let userInfo = notification.userInfo as NSDictionary?, let ocId = userInfo["ocId"] as? String, let enableTimerAutoHide = userInfo["enableTimerAutoHide"] as? Bool{
+            if currentViewController.metadata.ocId == ocId, let playerToolBar = currentViewController.playerToolBar, !playerToolBar.isPictureInPictureActive() {
+                changeScreenMode(mode: .normal, enableTimerAutoHide: enableTimerAutoHide)
+            }
+        }
+    }
+    
+    @objc func applicationDidBecomeActive(_ notification: NSNotification) {
+        
+        progressView.progress = 0
+    }
+    
+    //MARK: - Image
+    
+    func getImageMetadata(_ metadata: tableMetadata) -> UIImage? {
+                
+        if let image = getImage(metadata: metadata) {
+            return image
+        }
+        
+        if metadata.classFile == NCCommunicationCommon.typeClassFile.video.rawValue && !metadata.hasPreview {
+            NCUtility.shared.createImageFrom(fileName: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, classFile: metadata.classFile)
+        }
+        
+        if CCUtility.fileProviderStoragePreviewIconExists(metadata.ocId, etag: metadata.etag) {
+            if let imagePreviewPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag) {
+                return UIImage.init(contentsOfFile: imagePreviewPath)
+            } 
+        }
+        
+        return nil
+    }
+    
+    private func getImage(metadata: tableMetadata) -> UIImage? {
+        
+        let ext = CCUtility.getExtension(metadata.fileNameView)
+        var image: UIImage?
+        
+        if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) && metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue {
+           
+            let previewPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag)!
+            let imagePath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!
+            
+            if ext == "GIF" {
+                if !FileManager().fileExists(atPath: previewPath) {
+                    NCUtility.shared.createImageFrom(fileName: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, classFile: metadata.classFile)
+                }
+                image = UIImage.animatedImage(withAnimatedGIFURL: URL(fileURLWithPath: imagePath))
+            } else if ext == "SVG" {
+                if let svgImage = SVGKImage(contentsOfFile: imagePath) {
+                    svgImage.size = CGSize(width: NCGlobal.shared.sizePreview, height: NCGlobal.shared.sizePreview)
+                    if let image = svgImage.uiImage {
+                        if !FileManager().fileExists(atPath: previewPath) {
+                            do {
+                                try image.pngData()?.write(to: URL(fileURLWithPath: previewPath), options: .atomic)
+                            } catch { }
+                        }
+                        return image
+                    } else {
+                        return nil
+                    }
+                } else {
+                    return nil
+                }
+            } else {
+                NCUtility.shared.createImageFrom(fileName: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, classFile: metadata.classFile)
+                image = UIImage.init(contentsOfFile: imagePath)
+            }
+        }
+        
+        return image
+    }
+    
+    // MARK: - Command Center
+
+    func updateCommandCenter(ncplayer: NCPlayer, metadata: tableMetadata) {
+
+        var nowPlayingInfo = [String : Any]()
+
+        // Clear
+        clearCommandCenter()
+        UIApplication.shared.beginReceivingRemoteControlEvents()
+
+        // Add handler for Play Command
+        MPRemoteCommandCenter.shared().playCommand.isEnabled = true
+        playCommand = MPRemoteCommandCenter.shared().playCommand.addTarget { event in
+            
+            if !ncplayer.isPlay() {
+                ncplayer.playerPlay()
+                return .success
+            }
+            return .commandFailed
+        }
+      
+        // Add handler for Pause Command
+        MPRemoteCommandCenter.shared().pauseCommand.isEnabled = true
+        pauseCommand = MPRemoteCommandCenter.shared().pauseCommand.addTarget { event in
+          
+            if ncplayer.isPlay() {
+                ncplayer.playerPause()
+                return .success
+            }
+            return .commandFailed
+        }
+        
+        // VIDEO / AUDIO () ()
+        if metadata.classFile == NCCommunicationCommon.typeClassFile.video.rawValue || metadata.classFile == NCCommunicationCommon.typeClassFile.audio.rawValue {
+            
+            MPRemoteCommandCenter.shared().skipForwardCommand.isEnabled = true
+            skipForwardCommand = MPRemoteCommandCenter.shared().skipForwardCommand.addTarget { event in
+                
+                let seconds = Float64((event as! MPSkipIntervalCommandEvent).interval)
+                self.currentViewController.playerToolBar.skip(seconds: seconds)
+                return.success
+            }
+            
+            MPRemoteCommandCenter.shared().skipBackwardCommand.isEnabled = true
+            skipBackwardCommand = MPRemoteCommandCenter.shared().skipBackwardCommand.addTarget { event in
+                
+                let seconds = Float64((event as! MPSkipIntervalCommandEvent).interval)
+                self.currentViewController.playerToolBar.skip(seconds: -seconds)
+                return.success
+            }
+        }
+                
+        // AUDIO < >
+        /*
+        if metadata?.classFile == NCCommunicationCommon.typeClassFile.audio.rawValue {
+                        
+            MPRemoteCommandCenter.shared().nextTrackCommand.isEnabled = true
+            appDelegate.nextTrackCommand = MPRemoteCommandCenter.shared().nextTrackCommand.addTarget { event in
+                
+                self.forward()
+                return .success
+            }
+            
+            MPRemoteCommandCenter.shared().previousTrackCommand.isEnabled = true
+            appDelegate.previousTrackCommand = MPRemoteCommandCenter.shared().previousTrackCommand.addTarget { event in
+             
+                self.backward()
+                return .success
+            }
+        }
+        */
+        
+        nowPlayingInfo[MPMediaItemPropertyTitle] = metadata.fileNameView
+        nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = ncplayer.durationTime.seconds
+        if let image = currentViewController.image {
+            nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size) { size in
+                return image
+            }
+        }
+        MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
+    }
+
+    func clearCommandCenter() {
+        
+        UIApplication.shared.endReceivingRemoteControlEvents()
+        MPNowPlayingInfoCenter.default().nowPlayingInfo = [:]
+
+        MPRemoteCommandCenter.shared().playCommand.isEnabled = false
+        MPRemoteCommandCenter.shared().pauseCommand.isEnabled = false
+        MPRemoteCommandCenter.shared().skipForwardCommand.isEnabled = false
+        MPRemoteCommandCenter.shared().skipBackwardCommand.isEnabled = false
+        MPRemoteCommandCenter.shared().nextTrackCommand.isEnabled = false
+        MPRemoteCommandCenter.shared().previousTrackCommand.isEnabled = false
+
+        if let playCommand = playCommand {
+            MPRemoteCommandCenter.shared().playCommand.removeTarget(playCommand)
+            self.playCommand = nil
+        }
+        if let pauseCommand = pauseCommand {
+            MPRemoteCommandCenter.shared().pauseCommand.removeTarget(pauseCommand)
+            self.pauseCommand = nil
+        }
+        if let skipForwardCommand = skipForwardCommand {
+            MPRemoteCommandCenter.shared().skipForwardCommand.removeTarget(skipForwardCommand)
+            self.skipForwardCommand = nil
+        }
+        if let skipBackwardCommand = skipBackwardCommand {
+            MPRemoteCommandCenter.shared().skipBackwardCommand.removeTarget(skipBackwardCommand)
+            self.skipBackwardCommand = nil
+        }
+        if let nextTrackCommand = nextTrackCommand {
+            MPRemoteCommandCenter.shared().nextTrackCommand.removeTarget(nextTrackCommand)
+            self.nextTrackCommand = nil
+        }
+        if let previousTrackCommand = previousTrackCommand {
+            MPRemoteCommandCenter.shared().previousTrackCommand.removeTarget(previousTrackCommand)
+            self.previousTrackCommand = nil
+        }
+    }
+}
+
+// MARK: - UIPageViewController Delegate Datasource
+
+extension NCViewerMediaPage: UIPageViewControllerDelegate, UIPageViewControllerDataSource {
+    
+    func shiftCurrentPage() -> Bool {
+        
+        if metadatas.count == 0 { return false }
+        
+        var direction: UIPageViewController.NavigationDirection = .forward
+        
+        if currentIndex == metadatas.count {
+            currentIndex -= 1
+            direction = .reverse
+        }
+        
+        currentViewController.ncplayer?.deactivateObserver()
+        
+        let viewerMedia = getViewerMedia(index: currentIndex, image: getImageMetadata(metadatas[currentIndex]), metadata: metadatas[currentIndex], direction: direction)
+        pageViewController.setViewControllers([viewerMedia], direction: direction, animated: true, completion: nil)
+        
+        return true
+    }
+    
+    func goTo(index: Int, direction: UIPageViewController.NavigationDirection, autoPlay: Bool) {
+        
+        currentIndex = index
+        
+        currentViewController.ncplayer?.deactivateObserver()
+
+        let viewerMedia = getViewerMedia(index: currentIndex, image: getImageMetadata(metadatas[currentIndex]), metadata: metadatas[currentIndex], direction: direction)
+        viewerMedia.autoPlay = autoPlay
+        pageViewController.setViewControllers([viewerMedia], direction: direction, animated: true, completion: nil)
+    }
+    
+    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
+        
+        if currentIndex == 0 { return nil }
+
+        let viewerMedia = getViewerMedia(index: currentIndex-1, image: getImageMetadata(metadatas[currentIndex-1]), metadata: metadatas[currentIndex-1], direction: .reverse)
+        return viewerMedia
+    }
+    
+    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
+        
+        if currentIndex == metadatas.count-1 { return nil }
+
+        let viewerMedia = getViewerMedia(index: currentIndex+1, image: getImageMetadata(metadatas[currentIndex+1]), metadata: metadatas[currentIndex+1], direction: .forward)
+        return viewerMedia
+    }
+    
+    // START TRANSITION
+    func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
+        
+        // Save time video
+        if let ncplayer = currentViewController.ncplayer, ncplayer.isPlay() {
+            ncplayer.saveCurrentTime()
+        }
+        
+        guard let nextViewController = pendingViewControllers.first as? NCViewerMedia else { return }
+        nextIndex = nextViewController.index        
+    }
+    
+    // END TRANSITION
+    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
+        
+        if (completed && nextIndex != nil) {
+            previousViewControllers.forEach { viewController in
+                let viewerMedia = viewController as! NCViewerMedia
+                viewerMedia.ncplayer?.deactivateObserver()
+            }
+            currentIndex = nextIndex!
+        }
+        
+        self.nextIndex = nil
+    }
+}
+
+//MARK: - UIGestureRecognizerDelegate
+
+extension NCViewerMediaPage: UIGestureRecognizerDelegate {
+
+    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
+        
+        if let gestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer {
+            let velocity = gestureRecognizer.velocity(in: self.view)
+            
+            var velocityCheck : Bool = false
+            
+            if UIDevice.current.orientation.isLandscape {
+                velocityCheck = velocity.x < 0
+            }
+            else {
+                velocityCheck = velocity.y < 0
+            }
+            if velocityCheck {
+                return false
+            }
+        }
+        
+        return true
+    }
+    
+    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
+        
+        if otherGestureRecognizer == currentViewController.scrollView.panGestureRecognizer {
+            if self.currentViewController.scrollView.contentOffset.y == 0 {
+                return true
+            }
+        }
+        
+        return false
+    }
+
+    @objc func didPanWith(gestureRecognizer: UIPanGestureRecognizer) {
+        
+        currentViewController.didPanWith(gestureRecognizer: gestureRecognizer)
+    }
+    
+    @objc func didSingleTapWith(gestureRecognizer: UITapGestureRecognizer) {
+                
+        if let playerToolBar = currentViewController.playerToolBar, playerToolBar.isPictureInPictureActive() {
+            playerToolBar.pictureInPictureController?.stopPictureInPicture()
+        }
+        
+        if currentScreenMode == .full {
+            
+            changeScreenMode(mode: .normal, enableTimerAutoHide: true)
+                        
+        } else {
+            
+            changeScreenMode(mode: .full)
+        }
+    }
+    
+    //
+    // LIVE PHOTO
+    //
+    @objc func didLongpressGestureEvent(gestureRecognizer: UITapGestureRecognizer) {
+        
+        if !currentViewController.metadata.livePhoto { return }
+        
+        if gestureRecognizer.state == .began {
+            
+            currentViewController.updateViewConstraints()
+            currentViewController.statusViewImage.isHidden = true
+            currentViewController.statusLabel.isHidden = true
+            
+            let fileName = (currentViewController.metadata.fileNameView as NSString).deletingPathExtension + ".mov"
+            if let metadata = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView LIKE[c] %@", currentViewController.metadata.account, currentViewController.metadata.serverUrl, fileName)) {
+                
+                if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
+                    
+                    AudioServicesPlaySystemSound(1519) // peek feedback
+                    
+                    if let url = NCKTVHTTPCache.shared.getVideoURL(metadata: metadata) {
+                        self.ncplayerLivePhoto = NCPlayer.init(url: url, autoPlay: true, imageVideoContainer: self.currentViewController.imageVideoContainer, playerToolBar: nil, metadata: metadata, detailView: nil)
+                    }
+                    
+                } else {
+                    
+                    let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileNameView
+                    let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!
+                                    
+                    NCCommunication.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, requestHandler: { (_) in
+                        
+                    }, taskHandler: { (_) in
+                        
+                    }, progressHandler: { (progress) in
+                                        
+                        self.progressView.progress = Float(progress.fractionCompleted)
+                        
+                    }) { (account, etag, date, length, allHeaderFields, error, errorCode, errorDescription) in
+                        
+                        self.progressView.progress = 0
+                        
+                        if errorCode == 0 && account == metadata.account {
+                            
+                            NCManageDatabase.shared.addLocalFile(metadata: metadata)
+                            
+                            if gestureRecognizer.state == .changed || gestureRecognizer.state == .began {
+                                AudioServicesPlaySystemSound(1519) // peek feedback
+                                
+                                if let url = NCKTVHTTPCache.shared.getVideoURL(metadata: metadata) {
+                                    self.ncplayerLivePhoto = NCPlayer.init(url: url, autoPlay: true, imageVideoContainer: self.currentViewController.imageVideoContainer, playerToolBar: nil, metadata: metadata, detailView: nil)
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            
+        } else if gestureRecognizer.state == .ended {
+            
+            currentViewController.statusViewImage.isHidden = false
+            currentViewController.statusLabel.isHidden = false
+            currentViewController.imageVideoContainer.image = currentViewController.image
+            ncplayerLivePhoto?.videoLayer?.removeFromSuperlayer()
+            ncplayerLivePhoto?.deactivateObserver()
+        }
+    }
+}

+ 0 - 454
iOSClient/Viewer/NCViewerMedia/NCViewerMediaZoom.swift

@@ -1,454 +0,0 @@
-//
-//  NCViewerMediaZoom.swift
-//  Nextcloud
-//
-//  Created by Marino Faggiana on 24/10/2020.
-//  Copyright © 2020 Marino Faggiana. All rights reserved.
-//
-//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
-//
-//  This program is free software: you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License as published by
-//  the Free Software Foundation, either version 3 of the License, or
-//  (at your option) any later version.
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-//
-
-import UIKit
-import NCCommunication
-
-class NCViewerMediaZoom: UIViewController {
-    
-    @IBOutlet weak var detailViewTopConstraint: NSLayoutConstraint!
-    @IBOutlet weak var detailViewHeighConstraint: NSLayoutConstraint!
-    @IBOutlet weak var imageViewTopConstraint: NSLayoutConstraint!
-    @IBOutlet weak var imageViewBottomConstraint: NSLayoutConstraint!
-    @IBOutlet weak var scrollView: UIScrollView!
-    @IBOutlet weak var imageVideoContainer: imageVideoContainerView!
-    @IBOutlet weak var statusViewImage: UIImageView!
-    @IBOutlet weak var statusLabel: UILabel!
-    @IBOutlet weak var detailView: NCViewerMediaDetailView!
-    @IBOutlet weak var playerToolBar: NCPlayerToolBar!
-    
-    private var _autoPlay: Bool = false
-
-    let appDelegate = UIApplication.shared.delegate as! AppDelegate
-    var viewerMedia: NCViewerMedia?
-    var ncplayer: NCPlayer?
-    var image: UIImage?
-    var metadata: tableMetadata = tableMetadata()
-    var index: Int = 0
-    var doubleTapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer()
-    var imageViewConstraint: CGFloat = 0
-    var isDetailViewInitializze: Bool = false
-    
-    var autoPlay: Bool {
-        get {
-            let temp = _autoPlay
-            _autoPlay = false
-            return temp
-        }
-        set(newVal) {
-            _autoPlay = newVal
-        }
-    }
-    
-    // MARK: - View Life Cycle
-
-    required init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        
-        doubleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didDoubleTapWith(gestureRecognizer:)))
-        doubleTapGestureRecognizer.numberOfTapsRequired = 2
-    }
-    
-    deinit {
-        print("deinit NCViewerMediaZoom")
-        
-        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterOpenMediaDetail), object: nil)
-    }
-    
-    override func viewDidLoad() {
-        super.viewDidLoad()
-        
-        scrollView.delegate = self
-        scrollView.maximumZoomScale = 4
-        scrollView.minimumZoomScale = 1
-        
-        view.addGestureRecognizer(doubleTapGestureRecognizer)
-        
-        if metadata.classFile == NCCommunicationCommon.typeClassFile.video.rawValue {
-            if image == nil {
-                image = UIImage.init(named: "noPreviewVideo")!.image(color: .gray, size: view.frame.width)
-            }
-            imageVideoContainer.image = image
-            
-        } else if metadata.classFile == NCCommunicationCommon.typeClassFile.audio.rawValue {
-            if image == nil {
-                image = UIImage.init(named: "noPreviewAudio")!.image(color: .gray, size: view.frame.width)
-            }
-            imageVideoContainer.image = image
-
-        } else {
-            if image == nil {
-                image = UIImage.init(named: "noPreview")!.image(color: .gray, size: view.frame.width)
-            }
-            imageVideoContainer.image = image
-        }
-        
-        if NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) != nil {
-            statusViewImage.image = NCUtility.shared.loadImage(named: "livephoto", color: .gray)
-            statusLabel.text = "LIVE"
-        }  else {
-            statusViewImage.image = nil
-            statusLabel.text = ""
-        }
-        
-        playerToolBar.viewerMedia = viewerMedia
-        
-        detailViewTopConstraint.constant = 0
-        detailView.hide()
-        
-        // DOWNLOAD
-        downloadFile()
-    }
-    
-    override func viewWillAppear(_ animated: Bool) {
-        super.viewWillAppear(animated)
-        
-        viewerMedia?.navigationController?.navigationBar.prefersLargeTitles = false
-        viewerMedia?.navigationItem.title = metadata.fileNameView
-        
-        if metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue, let viewerMedia = self.viewerMedia {
-            viewerMedia.currentScreenMode = viewerMedia.saveScreenModeImage
-        }
-                
-        if viewerMedia?.currentScreenMode == .full {
-            
-            viewerMedia?.navigationController?.setNavigationBarHidden(true, animated: true)
-            
-            NCUtility.shared.colorNavigationController(viewerMedia?.navigationController, backgroundColor: .black, titleColor: .white, tintColor: nil, withoutShadow: false)
-            
-            viewerMedia?.view.backgroundColor = .black
-            viewerMedia?.textColor = .white
-            viewerMedia?.progressView.isHidden = true
-            
-        } else {
-            
-            viewerMedia?.navigationController?.setNavigationBarHidden(false, animated: true)
-                
-            NCUtility.shared.colorNavigationController(viewerMedia?.navigationController, backgroundColor: NCBrandColor.shared.systemBackground, titleColor: NCBrandColor.shared.label, tintColor: nil, withoutShadow: false)
-            
-            viewerMedia?.view.backgroundColor = NCBrandColor.shared.systemBackground
-            viewerMedia?.textColor = NCBrandColor.shared.label
-            viewerMedia?.progressView.isHidden = false
-        }
-    }
-    
-    override func viewDidAppear(_ animated: Bool) {
-        super.viewDidAppear(animated)
-        
-        if (metadata.classFile == NCCommunicationCommon.typeClassFile.video.rawValue || metadata.classFile == NCCommunicationCommon.typeClassFile.audio.rawValue) {
-            
-            if ncplayer == nil, let url = NCKTVHTTPCache.shared.getVideoURL(metadata: metadata) {
-                self.ncplayer = NCPlayer.init(url: url, autoPlay: self.autoPlay, imageVideoContainer: self.imageVideoContainer, playerToolBar: self.playerToolBar, metadata: self.metadata, detailView: self.detailView)
-            } else {
-                self.ncplayer?.activateObserver(playerToolBar: self.playerToolBar)
-                if detailView.isShow() == false && ncplayer?.isPlay() == false {
-                    NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterShowPlayerToolBar, userInfo: ["ocId":metadata.ocId, "enableTimerAutoHide": false])
-                }
-            }
-            
-            if let ncplayer = self.ncplayer {
-                self.viewerMedia?.updateCommandCenter(ncplayer: ncplayer, metadata: self.metadata)
-            }
-            
-        } else if metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue {
-            
-            if let image = viewerMedia?.getImageMetadata(metadata) {
-                self.image = image
-                self.imageVideoContainer.image = image
-            }
-            viewerMedia?.clearCommandCenter()
-        }
-        
-        NotificationCenter.default.addObserver(self, selector: #selector(openDetail(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterOpenMediaDetail), object: nil)
-    }
-    
-    override func viewDidDisappear(_ animated: Bool) {
-        super.viewDidDisappear(animated)
-    }
-    
-    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
-        super.viewWillTransition(to: size, with: coordinator)
-        
-        coordinator.animate(alongsideTransition: { (context) in
-            // back to the original size
-            self.scrollView.zoom(to: CGRect(x: 0, y: 0, width: self.scrollView.bounds.width, height: self.scrollView.bounds.height), animated: false)
-            self.view.layoutIfNeeded()
-            UIView.animate(withDuration: context.transitionDuration) {
-                if self.detailView.isShow() {
-                    self.openDetail()
-                }
-            }
-        }) { (_) in }
-    }
-    
-    //MARK: - Gesture
-
-    @objc func didDoubleTapWith(gestureRecognizer: UITapGestureRecognizer) {
-        
-        if detailView.isShow() { return }
-        // NO ZOOM for Audio
-        if metadata.classFile == NCCommunicationCommon.typeClassFile.audio.rawValue { return }
-        
-        let pointInView = gestureRecognizer.location(in: self.imageVideoContainer)
-        var newZoomScale = self.scrollView.maximumZoomScale
-            
-        if self.scrollView.zoomScale >= newZoomScale || abs(self.scrollView.zoomScale - newZoomScale) <= 0.01 {
-            newZoomScale = self.scrollView.minimumZoomScale
-        }
-                
-        let width = self.scrollView.bounds.width / newZoomScale
-        let height = self.scrollView.bounds.height / newZoomScale
-        let originX = pointInView.x - (width / 2.0)
-        let originY = pointInView.y - (height / 2.0)
-        let rectToZoomTo = CGRect(x: originX, y: originY, width: width, height: height)
-        self.scrollView.zoom(to: rectToZoomTo, animated: true)
-    }
-      
-    @objc func didPanWith(gestureRecognizer: UIPanGestureRecognizer) {
-                
-        let currentLocation = gestureRecognizer.translation(in: self.view)
-        
-        switch gestureRecognizer.state {
-        
-        case .began:
-            
-//        let velocity = gestureRecognizer.velocity(in: self.view)
-
-//            gesture moving Up
-//            if velocity.y < 0 {
-
-//            }
-            break
-
-        case .ended:
-            
-            if detailView.isShow() {
-                self.imageViewTopConstraint.constant = -imageViewConstraint
-                self.imageViewBottomConstraint.constant = imageViewConstraint
-            } else {
-                self.imageViewTopConstraint.constant = 0
-                self.imageViewBottomConstraint.constant = 0
-            }
-
-        case .changed:
-                        
-            imageViewTopConstraint.constant = (currentLocation.y - imageViewConstraint)
-            imageViewBottomConstraint.constant = -(currentLocation.y - imageViewConstraint)
-            
-            // DISMISS VIEW
-            if detailView.isHidden && (currentLocation.y > 20) {
-                
-                viewerMedia?.navigationController?.popViewController(animated: true)
-                gestureRecognizer.state = .ended
-            }
-            
-            // CLOSE DETAIL
-            if !detailView.isHidden && (currentLocation.y > 20) {
-                               
-                self.closeDetail()
-                gestureRecognizer.state = .ended
-            }
-
-            // OPEN DETAIL
-            if detailView.isHidden && (currentLocation.y < -20) {
-                       
-                self.openDetail()
-                gestureRecognizer.state = .ended
-            }
-                        
-        default:
-            break
-        }
-    }
-}
-
-//MARK: -
-
-extension NCViewerMediaZoom {
-    
-    @objc func openDetail(_ notification: NSNotification) {
-        
-        if let userInfo = notification.userInfo as NSDictionary?, let ocId = userInfo["ocId"] as? String, ocId == metadata.ocId {
-            openDetail()
-        }
-    }
-    
-    private func openDetail() {
-        
-        CCUtility.setExif(metadata) { (latitude, longitude, location, date, lensModel) in
-            
-            if (latitude != -1 && latitude != 0 && longitude != -1 && longitude != 0) {
-                self.detailViewHeighConstraint.constant = self.view.bounds.height / 2
-            } else {
-                self.detailViewHeighConstraint.constant = 170
-            }
-            self.view.layoutIfNeeded()
-            
-            self.detailView.show(metadata:self.metadata, image: self.image, textColor: self.viewerMedia?.textColor, latitude: latitude, longitude: longitude, location: location, date: date, lensModel: lensModel, delegate: self)
-                
-            if let image = self.imageVideoContainer.image {
-                let ratioW = self.imageVideoContainer.frame.width / image.size.width
-                let ratioH = self.imageVideoContainer.frame.height / image.size.height
-                let ratio = ratioW < ratioH ? ratioW : ratioH
-                let imageHeight = image.size.height * ratio
-                self.imageViewConstraint = self.detailView.frame.height - ((self.view.frame.height - imageHeight) / 2) + self.view.safeAreaInsets.bottom
-                if self.imageViewConstraint < 0 { self.imageViewConstraint = 0 }
-            }
-                
-            UIView.animate(withDuration: 0.3) {
-                self.imageViewTopConstraint.constant = -self.imageViewConstraint
-                self.imageViewBottomConstraint.constant = self.imageViewConstraint
-                self.detailViewTopConstraint.constant = self.detailViewHeighConstraint.constant
-                self.view.layoutIfNeeded()
-            } completion: { (_) in
-            }
-                
-            self.scrollView.pinchGestureRecognizer?.isEnabled = false
-            self.playerToolBar.hide()
-        }
-    }
-    
-    private func closeDetail() {
-        
-        self.detailView.hide()
-        imageViewConstraint = 0
-        
-        UIView.animate(withDuration: 0.3) {
-            self.imageViewTopConstraint.constant = 0
-            self.imageViewBottomConstraint.constant = 0
-            self.detailViewTopConstraint.constant = 0
-            self.view.layoutIfNeeded()
-        } completion: { (_) in
-        }
-        
-        scrollView.pinchGestureRecognizer?.isEnabled = true
-        if metadata.classFile == NCCommunicationCommon.typeClassFile.video.rawValue && !metadata.livePhoto && ncplayer?.player?.timeControlStatus == .paused {
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterShowPlayerToolBar, userInfo: ["ocId":metadata.ocId, "enableTimerAutoHide": false])
-        }
-    }
-    
-    func reloadDetail() {
-        
-        if self.detailView.isShow() {
-            CCUtility.setExif(metadata) { (latitude, longitude, location, date, lensModel) in
-                self.detailView.show(metadata:self.metadata, image: self.image, textColor: self.viewerMedia?.textColor, latitude: latitude, longitude: longitude, location: location, date: date, lensModel: lensModel, delegate: self)
-            }
-        }
-    }
-    
-    func downloadFile() {
-        
-        let isFolderEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase)
-        let ext = CCUtility.getExtension(metadata.fileNameView)
-        var etagResource: String?
-        
-        // DOWNLOAD preview for image
-        if !CCUtility.fileProviderStoragePreviewIconExists(metadata.ocId, etag: metadata.etag) && metadata.hasPreview && metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue {
-            
-            let fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, account: metadata.account)!
-            let fileNamePreviewLocalPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag)!
-            let fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)!
-            if FileManager.default.fileExists(atPath: fileNameIconLocalPath) && FileManager.default.fileExists(atPath: fileNamePreviewLocalPath) {
-                etagResource = metadata.etagResource
-            }
-            
-            NCCommunication.shared.downloadPreview(fileNamePathOrFileId: fileNamePath, fileNamePreviewLocalPath: fileNamePreviewLocalPath , widthPreview: NCGlobal.shared.sizePreview, heightPreview: NCGlobal.shared.sizePreview, fileNameIconLocalPath: fileNameIconLocalPath, sizeIcon: NCGlobal.shared.sizeIcon, etag: etagResource, queue: NCCommunicationCommon.shared.backgroundQueue) { (account, imagePreview, imageIcon, imageOriginal, etag, errorCode, errorDescription) in
-                
-                if errorCode == 0, let image = self.viewerMedia?.getImageMetadata(self.metadata) {
-                    DispatchQueue.main.async {
-                        self.image = image
-                        self.imageVideoContainer.image = image
-                    }
-                }
-            }
-        }
-        
-        // DOWNLOAD FILE
-        if ((metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue && CCUtility.getAutomaticDownloadImage()) || (metadata.contentType == "image/heic" &&  metadata.hasPreview == false) || ext == "GIF" || ext == "SVG" || isFolderEncrypted) && metadata.session == "" && !CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
-            
-            NCNetworking.shared.download(metadata: metadata, selector: "") { (errorCode) in
-                
-                if errorCode == 0, let image = self.viewerMedia?.getImageMetadata(self.metadata) {
-                    DispatchQueue.main.async {
-                        self.image = image
-                        self.imageVideoContainer.image = image
-                    }
-                }
-            }
-        }
-    }
-}
-
-//MARK: -
-
-extension NCViewerMediaZoom: UIScrollViewDelegate {
-    
-    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
-        return imageVideoContainer
-    }
-    
-    func scrollViewDidZoom(_ scrollView: UIScrollView) {
-        
-        if scrollView.zoomScale > 1 {
-            if let image = imageVideoContainer.image {
-                
-                let ratioW = imageVideoContainer.frame.width / image.size.width
-                let ratioH = imageVideoContainer.frame.height / image.size.height
-                let ratio = ratioW < ratioH ? ratioW : ratioH
-                let newWidth = image.size.width * ratio
-                let newHeight = image.size.height * ratio
-                let conditionLeft = newWidth*scrollView.zoomScale > imageVideoContainer.frame.width
-                let left = 0.5 * (conditionLeft ? newWidth - imageVideoContainer.frame.width : (scrollView.frame.width - scrollView.contentSize.width))
-                let conditioTop = newHeight*scrollView.zoomScale > imageVideoContainer.frame.height
-                
-                let top = 0.5 * (conditioTop ? newHeight - imageVideoContainer.frame.height : (scrollView.frame.height - scrollView.contentSize.height))
-                
-                scrollView.contentInset = UIEdgeInsets(top: top, left: left, bottom: top, right: left)
-            }
-        } else {
-            scrollView.contentInset = .zero
-        }
-    }
-    
-    func scrollViewDidScroll(_ scrollView: UIScrollView) {
-    }
-}
-
-extension NCViewerMediaZoom: NCViewerMediaDetailViewDelegate  {
-    
-    func downloadFullResolution() {
-        closeDetail()
-        NCNetworking.shared.download(metadata: metadata, selector: NCGlobal.shared.selectorOpenDetail) { (_) in }
-    }
-}
-
-//MARK: -
-
-class imageVideoContainerView: UIImageView {
-    var playerLayer: CALayer?
-    var metadata: tableMetadata?
-    override func layoutSublayers(of layer: CALayer) {
-        super.layoutSublayers(of: layer)
-        playerLayer?.frame = self.bounds
-    }
-}