marinofaggiana 6 жил өмнө
parent
commit
bf8fc4f965

+ 215 - 191
iOSClient/Activity/NCActivity.swift

@@ -25,7 +25,7 @@ import Foundation
 import UIKit
 import SwiftRichString
 
-class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate, UITableViewDataSourcePrefetching, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
+class NCActivity: UIViewController, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
     
     @IBOutlet weak var tableView: UITableView!
 
@@ -87,47 +87,48 @@ class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate,
     func emptyDataSetShouldAllowScroll(_ scrollView: UIScrollView) -> Bool {
         return true
     }
+}
+
+class activityTableViewCell: UITableViewCell {
     
-    // MARK: TableView
+    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
 
-    func loadDataSource() {
-        
-        sectionDate.removeAll()
+    @IBOutlet weak var collectionView: UICollectionView!
     
-        activities = NCManageDatabase.sharedInstance.getActivity(predicate: NSPredicate(format: "account == %@", appDelegate.activeAccount))
-        for tableActivity in activities {
-            guard let date = Calendar.current.date(from: Calendar.current.dateComponents([.year, .month, .day], from: tableActivity.date as Date)) else {
-                continue
-            }
-            if !sectionDate.contains(date) {
-                sectionDate.append(date)
-            }
-        }
-        tableView.reloadData()
-    }
+    @IBOutlet weak var icon: UIImageView!
+    @IBOutlet weak var avatar: UIImageView!
+    @IBOutlet weak var subject: UILabel!
+    @IBOutlet weak var subjectTrailingConstraint: NSLayoutConstraint!
+    @IBOutlet weak var collectionViewHeightConstraint: NSLayoutConstraint!
+
+    var idActivity: Int = 0
+    var account: String = ""
+    var activityPreviews = [tableActivityPreview]()
     
-    func getTableActivitiesFromSection(_ section: Int) -> [tableActivity] {
-        let startDate = sectionDate[section]
-        let endDate: Date = {
-            let components = DateComponents(day: 1, second: -1)
-            return Calendar.current.date(byAdding: components, to: startDate)!
-        }()
+    override func awakeFromNib() {
+        super.awakeFromNib()
         
-        return NCManageDatabase.sharedInstance.getActivity(predicate: NSPredicate(format: "account == %@ && date BETWEEN %@", appDelegate.activeAccount, [startDate, endDate]))
-    }
-    
-    func numberOfSections(in tableView: UITableView) -> Int {
-        return sectionDate.count
+        collectionView.delegate = self
+        collectionView.dataSource = self
     }
+}
+
+// MARK: - Table View
+
+extension NCActivity: UITableViewDelegate {
     
-    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-        return getTableActivitiesFromSection(section).count
+    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
+        return 120
     }
     
     func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
         return 60
     }
     
+    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+        return UITableView.automaticDimension
+    }
+    
     func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
         
         let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.width, height: 60))
@@ -148,33 +149,16 @@ class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate,
         view.addSubview(label)
         return view
     }
+}
 
-    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
-        return 120
-    }
-    
-    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
-        return UITableView.automaticDimension
-    }
+extension NCActivity: UITableViewDataSource {
     
-    func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
-        
-        let section = indexPaths.last?.section ?? 0
-        let row = indexPaths.last?.row ?? 0
-        
-        let lastSection = self.sectionDate.count - 1
-        let lastRow = getTableActivitiesFromSection(section).count - 1
-        
-        if section == lastSection && row > lastRow - 1 {
-            let results = getTableActivitiesFromSection(section)
-            let activity = results[lastRow]
-            
-            loadActivity(idActivity: activity.idActivity)
-        }
+    func numberOfSections(in tableView: UITableView) -> Int {
+        return sectionDate.count
     }
     
-    func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
-        //print("cancelPrefetchingForRowsAt \(indexPaths)")
+    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return getTableActivitiesFromSection(section).count
     }
     
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
@@ -184,13 +168,13 @@ class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate,
             let results = getTableActivitiesFromSection(indexPath.section)
             let activity = results[indexPath.row]
             var orderKeysId = [String]()
-
+            
             cell.idActivity = activity.idActivity
             cell.account = activity.account
             cell.avatar.image = nil
             cell.avatar.isHidden = true
             cell.subjectTrailingConstraint.constant = 10
-
+            
             // icon
             if activity.icon.count > 0 {
                 
@@ -220,7 +204,7 @@ class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate,
                     }
                 }
             }
-    
+            
             // avatar
             if activity.user.count > 0 && activity.user != appDelegate.activeUserID {
                 
@@ -289,160 +273,45 @@ class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate,
                 cell.collectionViewHeightConstraint.constant = 60
             }
             cell.collectionView.reloadData()
-
+            
             return cell
         }
         
         return UITableViewCell()
     }
-    
-    // MARK: NC API
-    
-    @objc func loadActivityRefreshing() {
-        loadActivity(idActivity: 0)
-    }
+}
 
-    @objc func loadActivity(idActivity: Int) {
+extension NCActivity: UITableViewDataSourcePrefetching {
+    
+    func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
         
-        if loadingActivity {
-            return
-        } else {
-            loadingActivity = true
-        }
+        let section = indexPaths.last?.section ?? 0
+        let row = indexPaths.last?.row ?? 0
         
-        if idActivity > 0 {
-            NCUtility.sharedInstance.startActivityIndicator(view: self.view, bottom: 50)
-        }
+        let lastSection = self.sectionDate.count - 1
+        let lastRow = getTableActivitiesFromSection(section).count - 1
         
-        OCNetworking.sharedManager().getActivityWithAccount(appDelegate.activeAccount, since: idActivity, limit: 100, link: "", completion: { (account, listOfActivity, message, errorCode) in
-            
-            if errorCode == 0 && account == self.appDelegate.activeAccount {
-                NCManageDatabase.sharedInstance.addActivity(listOfActivity as! [OCActivity], account: account!)
-                
-                self.loadDataSource()
-            }
-            
-            self.refreshControl.endRefreshing()
-            NCUtility.sharedInstance.stopActivityIndicator()
+        if section == lastSection && row > lastRow - 1 {
+            let results = getTableActivitiesFromSection(section)
+            let activity = results[lastRow]
             
-            self.loadingActivity = false
-        })
-    }
-}
-
-class activityTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
-    
-    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
-
-    @IBOutlet weak var collectionView: UICollectionView!
-    
-    @IBOutlet weak var icon: UIImageView!
-    @IBOutlet weak var avatar: UIImageView!
-    @IBOutlet weak var subject: UILabel!
-    @IBOutlet weak var subjectTrailingConstraint: NSLayoutConstraint!
-    @IBOutlet weak var collectionViewHeightConstraint: NSLayoutConstraint!
-
-    var idActivity: Int = 0
-    var account: String = ""
-    var activityPreviews = [tableActivityPreview]()
-    
-    override func awakeFromNib() {
-        super.awakeFromNib()
-        
-        collectionView.delegate = self
-        collectionView.dataSource = self
-    }
-    
-    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
-        return CGSize(width: 50, height: 50)
-    }
-    
-    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
-        return 20
-    }
-    
-    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
-        return UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
-    }
-    
-    func numberOfSections(in collectionView: UICollectionView) -> Int {
-        return 1
+            loadActivity(idActivity: activity.idActivity)
+        }
     }
     
-    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
-        return activityPreviews.count
+    func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
+        //print("cancelPrefetchingForRowsAt \(indexPaths)")
     }
-    
-    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
-      
-        if let cell: activityCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as? activityCollectionViewCell {
-            
-            cell.imageView.image = nil
-            
-            let activityPreview = activityPreviews[indexPath.row]
-            let fileID = String(activityPreview.fileId)
+}
 
-            // Trashbin
-            if activityPreview.view == "trashbin" {
-                
-                let source = activityPreview.source
-                
-                NCUtility.sharedInstance.convertSVGtoPNGWriteToUserData(svgUrlString: source, fileName: nil, width: 100, rewrite: false) { (imageNamePath) in
-                    if imageNamePath != nil {
-                        if let image = UIImage(contentsOfFile: imageNamePath!) {
-                            cell.imageView.image = image
-                        }
-                    }
-                }
-                
-            } else {
-                
-                if activityPreview.isMimeTypeIcon {
-                    
-                    let source = activityPreview.source
+// MARK: - Collection View
 
-                    NCUtility.sharedInstance.convertSVGtoPNGWriteToUserData(svgUrlString: source, fileName: nil, width: 100, rewrite: false) { (imageNamePath) in
-                        if imageNamePath != nil {
-                            if let image = UIImage(contentsOfFile: imageNamePath!) {
-                                cell.imageView.image = image
-                            }
-                        }
-                    }
-                    
-                } else {
-                    
-                    if let activitySubjectRich = NCManageDatabase.sharedInstance.getActivitySubjectRich(account: account, idActivity: idActivity, id: fileID) {
-                    
-                        let fileNamePath = CCUtility.getDirectoryUserData() + "/" + activitySubjectRich.name
-                        
-                        if FileManager.default.fileExists(atPath: fileNamePath) {
-                            
-                            if let image = UIImage(contentsOfFile: fileNamePath) {
-                                cell.imageView.image = image
-                            }
-                            
-                        } else {
-                            
-                            OCNetworking.sharedManager()?.downloadPreview(withAccount: appDelegate.activeAccount, serverPath: activityPreview.source, fileNamePath: fileNamePath, completion: { (account, image, message, errorCode) in
-                                if errorCode == 0 {
-                                    cell.imageView.image = image
-                                }
-                            })
-                        }
-                    }
-                }
-            }
-            
-            return cell
-        }
-        
-        return UICollectionViewCell()
-    }
+extension activityTableViewCell: UICollectionViewDelegate {
     
     func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
         
         let activityPreview = activityPreviews[indexPath.row]
-
+        
         if activityPreview.view == "trashbin" {
             
             var responder: UIResponder? = collectionView
@@ -503,7 +372,7 @@ class activityTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollec
                     OCNetworking.sharedManager()?.readFile(withAccount: activityPreview.account, serverUrl: serverUrl, fileName: fileName, completion: { (account, metadata, message, errorCode) in
                         
                         NCUtility.sharedInstance.stopActivityIndicator()
-
+                        
                         if account == self.appDelegate.activeAccount && errorCode == 0 {
                             
                             // move from id to oc:id + instanceid (fileID)
@@ -528,6 +397,84 @@ class activityTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollec
     }
 }
 
+extension activityTableViewCell: UICollectionViewDataSource {
+    
+    func numberOfSections(in collectionView: UICollectionView) -> Int {
+        return 1
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return activityPreviews.count
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        
+        if let cell: activityCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as? activityCollectionViewCell {
+            
+            cell.imageView.image = nil
+            
+            let activityPreview = activityPreviews[indexPath.row]
+            let fileID = String(activityPreview.fileId)
+            
+            // Trashbin
+            if activityPreview.view == "trashbin" {
+                
+                let source = activityPreview.source
+                
+                NCUtility.sharedInstance.convertSVGtoPNGWriteToUserData(svgUrlString: source, fileName: nil, width: 100, rewrite: false) { (imageNamePath) in
+                    if imageNamePath != nil {
+                        if let image = UIImage(contentsOfFile: imageNamePath!) {
+                            cell.imageView.image = image
+                        }
+                    }
+                }
+                
+            } else {
+                
+                if activityPreview.isMimeTypeIcon {
+                    
+                    let source = activityPreview.source
+                    
+                    NCUtility.sharedInstance.convertSVGtoPNGWriteToUserData(svgUrlString: source, fileName: nil, width: 100, rewrite: false) { (imageNamePath) in
+                        if imageNamePath != nil {
+                            if let image = UIImage(contentsOfFile: imageNamePath!) {
+                                cell.imageView.image = image
+                            }
+                        }
+                    }
+                    
+                } else {
+                    
+                    if let activitySubjectRich = NCManageDatabase.sharedInstance.getActivitySubjectRich(account: account, idActivity: idActivity, id: fileID) {
+                        
+                        let fileNamePath = CCUtility.getDirectoryUserData() + "/" + activitySubjectRich.name
+                        
+                        if FileManager.default.fileExists(atPath: fileNamePath) {
+                            
+                            if let image = UIImage(contentsOfFile: fileNamePath) {
+                                cell.imageView.image = image
+                            }
+                            
+                        } else {
+                            
+                            OCNetworking.sharedManager()?.downloadPreview(withAccount: appDelegate.activeAccount, serverPath: activityPreview.source, fileNamePath: fileNamePath, completion: { (account, image, message, errorCode) in
+                                if errorCode == 0 {
+                                    cell.imageView.image = image
+                                }
+                            })
+                        }
+                    }
+                }
+            }
+            
+            return cell
+        }
+        
+        return UICollectionViewCell()
+    }
+    
+}
+
 class activityCollectionViewCell: UICollectionViewCell {
     
     @IBOutlet weak var imageView: UIImageView!
@@ -536,3 +483,80 @@ class activityCollectionViewCell: UICollectionViewCell {
         super.awakeFromNib()
     }
 }
+
+extension activityTableViewCell: UICollectionViewDelegateFlowLayout {
+    
+    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
+        return CGSize(width: 50, height: 50)
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
+        return 20
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
+        return UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
+    }
+}
+
+// MARK: - NC API & Algorithm
+
+extension NCActivity {
+    
+    func loadDataSource() {
+        
+        sectionDate.removeAll()
+        
+        activities = NCManageDatabase.sharedInstance.getActivity(predicate: NSPredicate(format: "account == %@", appDelegate.activeAccount))
+        for tableActivity in activities {
+            guard let date = Calendar.current.date(from: Calendar.current.dateComponents([.year, .month, .day], from: tableActivity.date as Date)) else {
+                continue
+            }
+            if !sectionDate.contains(date) {
+                sectionDate.append(date)
+            }
+        }
+        tableView.reloadData()
+    }
+    
+    func getTableActivitiesFromSection(_ section: Int) -> [tableActivity] {
+        let startDate = sectionDate[section]
+        let endDate: Date = {
+            let components = DateComponents(day: 1, second: -1)
+            return Calendar.current.date(byAdding: components, to: startDate)!
+        }()
+        
+        return NCManageDatabase.sharedInstance.getActivity(predicate: NSPredicate(format: "account == %@ && date BETWEEN %@", appDelegate.activeAccount, [startDate, endDate]))
+    }
+    
+    @objc func loadActivityRefreshing() {
+        loadActivity(idActivity: 0)
+    }
+    
+    @objc func loadActivity(idActivity: Int) {
+        
+        if loadingActivity {
+            return
+        } else {
+            loadingActivity = true
+        }
+        
+        if idActivity > 0 {
+            NCUtility.sharedInstance.startActivityIndicator(view: self.view, bottom: 50)
+        }
+        
+        OCNetworking.sharedManager().getActivityWithAccount(appDelegate.activeAccount, since: idActivity, limit: 100, link: "", completion: { (account, listOfActivity, message, errorCode) in
+            
+            if errorCode == 0 && account == self.appDelegate.activeAccount {
+                NCManageDatabase.sharedInstance.addActivity(listOfActivity as! [OCActivity], account: account!)
+                
+                self.loadDataSource()
+            }
+            
+            self.refreshControl.endRefreshing()
+            NCUtility.sharedInstance.stopActivityIndicator()
+            
+            self.loadingActivity = false
+        })
+    }
+}

+ 175 - 164
iOSClient/Select/NCSelect.swift

@@ -28,7 +28,7 @@ import Sheeeeeeeeet
     @objc func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String)
 }
 
-class NCSelect: UIViewController ,UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UIGestureRecognizerDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, DropdownMenuDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate, BKPasscodeViewControllerDelegate {
+class NCSelect: UIViewController, UIGestureRecognizerDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, DropdownMenuDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate, BKPasscodeViewControllerDelegate {
     
     @IBOutlet fileprivate weak var collectionView: UICollectionView!
     @IBOutlet fileprivate weak var toolbar: UIToolbar!
@@ -457,99 +457,105 @@ class NCSelect: UIViewController ,UICollectionViewDataSource, UICollectionViewDe
         }
     }
     
-    // MARK: NC API
-    
-    func createFolder(with fileName: String) {
-        
-        OCNetworking.sharedManager().createFolder(withAccount: appDelegate.activeAccount, serverUrl: serverUrl, fileName: fileName, completion: { (account, fileID, date, message, errorCode) in
-            if errorCode == 0 && account == self.appDelegate.activeAccount {
-                self.loadDatasource(withLoadFolder: true)
-            } else if errorCode != 0 {
-                self.appDelegate.messageNotification("_error_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
-            } else {
-                print("[LOG] It has been changed user during networking process, error.")
-            }
-        })
-    }
+    // MARK: NAVIGATION
     
-    func loadFolder() {
+    private func performSegueDirectoryWithControlPasscode(controlPasscode: Bool) {
         
-        networkInProgress = true
-        collectionView.reloadData()
+        guard let directoryPush = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.activeAccount, serverUrlPush))  else {
+            return
+        }
         
-        OCNetworking.sharedManager().readFolder(withAccount: appDelegate.activeAccount, serverUrl: serverUrl, depth: "1", completion: { (account, metadatas, metadataFolder, message, errorCode) in
-            
-            if errorCode == 0 && account == self.appDelegate.activeAccount {
+        if directoryPush.lock == true && CCUtility.getBlockCode() != nil && (CCUtility.getBlockCode()?.count)! > 0 && controlPasscode {
             
-                self.metadataFolder = metadataFolder
-                
-                // Update directory etag
-                NCManageDatabase.sharedInstance.setDirectory(serverUrl: self.serverUrl, serverUrlTo: nil, etag: metadataFolder?.etag, fileID: metadataFolder?.fileID, encrypted: metadataFolder!.e2eEncrypted, account: self.appDelegate.activeAccount)
-                NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d)", self.appDelegate.activeAccount ,self.serverUrl, k_metadataStatusNormal, k_metadataStatusHide))
-                NCManageDatabase.sharedInstance.setDateReadDirectory(serverUrl: self.serverUrl, account: self.appDelegate.activeAccount)
-                
-                _ = NCManageDatabase.sharedInstance.addMetadatas(metadatas as! [tableMetadata])
-                
-                if let metadatasInDownload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", self.appDelegate.activeAccount ,self.serverUrl, k_metadataStatusWaitDownload, k_metadataStatusInDownload, k_metadataStatusDownloading, k_metadataStatusDownloadError), sorted: nil, ascending: false) {
-                    
-                    _ = NCManageDatabase.sharedInstance.addMetadatas(metadatasInDownload)
-                }
-                
-            } else if errorCode != 0 {
-                self.appDelegate.messageNotification("_error_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
+            let viewController = CCBKPasscode.init(nibName: nil, bundle: nil)
+            guard let touchIDManager = BKTouchIDManager.init(keychainServiceName: k_serviceShareKeyChain) else {
+                return
+            }
+            touchIDManager.promptText = NSLocalizedString("_scan_fingerprint_", comment: "")
+
+            viewController.delegate = self
+            viewController.type = BKPasscodeViewControllerCheckPasscodeType
+            viewController.inputViewTitlePassword = true
+            if CCUtility.getSimplyBlockCode() {
+                viewController.passcodeStyle = BKPasscodeInputViewNumericPasscodeStyle
+                viewController.passcodeInputView.maximumLength = 6
             } else {
-                print("[LOG] It has been changed user during networking process, error.")
+                viewController.passcodeStyle = BKPasscodeInputViewNormalPasscodeStyle
+                viewController.passcodeInputView.maximumLength = 64
             }
+            viewController.touchIDManager = touchIDManager
+            viewController.title = NSLocalizedString("_folder_blocked_", comment: "")
+            viewController.navigationItem.leftBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonItem.SystemItem.cancel, target: self, action: #selector(passcodeViewCloseButtonPressed(_:)))
+            viewController.navigationItem.leftBarButtonItem?.tintColor = UIColor.black
             
-            self.networkInProgress = false
-            self.loadDatasource(withLoadFolder: false)
-        })
+            let navigationController = UINavigationController.init(rootViewController: viewController)
+            self.present(navigationController, animated: true, completion: nil)
+            
+            return
+        }
+        
+        guard let visualController = UIStoryboard(name: "NCSelect", bundle: nil).instantiateViewController(withIdentifier: "NCSelect.storyboard") as? NCSelect else {
+            return
+        }
+        
+        visualController.delegate = delegate
+        
+        visualController.hideButtonCreateFolder = hideButtonCreateFolder
+        visualController.selectFile = selectFile
+        visualController.includeDirectoryE2EEncryption = includeDirectoryE2EEncryption
+        visualController.includeImages = includeImages
+        visualController.type = type
+        visualController.titleButtonDone = titleButtonDone
+        visualController.layoutViewSelect = layoutViewSelect
+        
+        visualController.titleCurrentFolder = metadataPush!.fileNameView
+        visualController.serverUrl = serverUrlPush
+        
+        self.navigationController?.pushViewController(visualController, animated: true)
     }
-    
-    // MARK: DATASOURCE
-    @objc func loadDatasource(withLoadFolder: Bool) {
+}
+
+// MARK: - Collection View
+
+extension NCSelect: UICollectionViewDelegate {
+
+    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
         
-        sectionDatasource = CCSectionDataSourceMetadata()
-        var predicate: NSPredicate?
+        guard let metadata = NCMainCommon.sharedInstance.getMetadataFromSectionDataSourceIndexPath(indexPath, sectionDataSource: sectionDatasource) else {
+            return
+        }
         
-        if serverUrl == "" {
-            
-            serverUrl = CCUtility.getHomeServerUrlActiveUrl(appDelegate.activeUrl)
+        if isEditMode {
+            if let index = selectFileID.index(of: metadata.fileID) {
+                selectFileID.remove(at: index)
+            } else {
+                selectFileID.append(metadata.fileID)
+            }
+            collectionView.reloadItems(at: [indexPath])
+            return
         }
         
-        if includeDirectoryE2EEncryption {
+        if metadata.directory {
             
-            if includeImages {
-                predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND (directory == true OR typeFile == 'image')", appDelegate.activeAccount, serverUrl)
-            } else {
-                predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND directory == true", appDelegate.activeAccount, serverUrl)
+            guard let serverUrlPush = CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName) else {
+                return
             }
             
-        } else {
+            self.serverUrlPush = serverUrlPush
+            self.metadataPush = metadata
             
-            if includeImages {
-                predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND e2eEncrypted == false AND (directory == true OR typeFile == 'image')", appDelegate.activeAccount, serverUrl)
-            } else {
-                predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND e2eEncrypted == false AND directory == true", appDelegate.activeAccount, serverUrl)
-            }
-        }
-        
-        if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: predicate!, sorted: nil, ascending: false) {
+            performSegueDirectoryWithControlPasscode(controlPasscode: true)
             
-            sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterFileID: nil, filterTypeFileImage: false, filterTypeFileVideo: false, sorted: datasourceSorted, ascending: datasourceAscending, activeAccount: appDelegate.activeAccount)
-        }
-        
-        if withLoadFolder {
-            loadFolder()
         } else {
-            self.refreshControl.endRefreshing()
+            
+            delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadata, type: type)
+            self.dismiss(animated: true, completion: nil)
         }
-        
-        collectionView.reloadData()
     }
-    
-    // MARK: COLLECTIONVIEW METHODS
-    
+}
+
+extension NCSelect: UICollectionViewDataSource {
+
     func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
         
         if (indexPath.section == 0) {
@@ -610,27 +616,6 @@ class NCSelect: UIViewController ,UICollectionViewDataSource, UICollectionViewDe
         }
     }
     
-    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
-        if section == 0 {
-            if datasourceGroupBy == "none" {
-                return CGSize(width: collectionView.frame.width, height: headerMenuHeight)
-            } else {
-                return CGSize(width: collectionView.frame.width, height: headerMenuHeight + sectionHeaderHeight)
-            }
-        } else {
-            return CGSize(width: collectionView.frame.width, height: sectionHeaderHeight)
-        }
-    }
-    
-    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
-        let sections = sectionDatasource.sectionArrayRow.allKeys.count
-        if (section == sections - 1) {
-            return CGSize(width: collectionView.frame.width, height: footerHeight)
-        } else {
-            return CGSize(width: collectionView.frame.width, height: 0)
-        }
-    }
-    
     func numberOfSections(in collectionView: UICollectionView) -> Int {
         let sections = sectionDatasource.sectionArrayRow.allKeys.count
         return sections
@@ -660,95 +645,121 @@ class NCSelect: UIViewController ,UICollectionViewDataSource, UICollectionViewDe
         
         return cell
     }
-    
-    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
-        
-        guard let metadata = NCMainCommon.sharedInstance.getMetadataFromSectionDataSourceIndexPath(indexPath, sectionDataSource: sectionDatasource) else {
-            return
-        }
-        
-        if isEditMode {
-            if let index = selectFileID.index(of: metadata.fileID) {
-                selectFileID.remove(at: index)
+}
+
+extension NCSelect: UICollectionViewDelegateFlowLayout {
+
+    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
+        if section == 0 {
+            if datasourceGroupBy == "none" {
+                return CGSize(width: collectionView.frame.width, height: headerMenuHeight)
             } else {
-                selectFileID.append(metadata.fileID)
-            }
-            collectionView.reloadItems(at: [indexPath])
-            return
-        }
-        
-        if metadata.directory {
-            
-            guard let serverUrlPush = CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName) else {
-                return
+                return CGSize(width: collectionView.frame.width, height: headerMenuHeight + sectionHeaderHeight)
             }
-            
-            self.serverUrlPush = serverUrlPush
-            self.metadataPush = metadata
-            
-            performSegueDirectoryWithControlPasscode(controlPasscode: true)
-            
         } else {
-            
-            delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadata, type: type)
-            self.dismiss(animated: true, completion: nil)
+            return CGSize(width: collectionView.frame.width, height: sectionHeaderHeight)
         }
     }
     
-    // MARK: NAVIGATION
-    
-    private func performSegueDirectoryWithControlPasscode(controlPasscode: Bool) {
+    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
+        let sections = sectionDatasource.sectionArrayRow.allKeys.count
+        if (section == sections - 1) {
+            return CGSize(width: collectionView.frame.width, height: footerHeight)
+        } else {
+            return CGSize(width: collectionView.frame.width, height: 0)
+        }
+    }
+}
+
+// MARK: - NC API & Algorithm
+
+extension NCSelect {
+
+    @objc func loadDatasource(withLoadFolder: Bool) {
         
-        guard let directoryPush = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.activeAccount, serverUrlPush))  else {
-            return
+        sectionDatasource = CCSectionDataSourceMetadata()
+        var predicate: NSPredicate?
+        
+        if serverUrl == "" {
+            
+            serverUrl = CCUtility.getHomeServerUrlActiveUrl(appDelegate.activeUrl)
         }
         
-        if directoryPush.lock == true && CCUtility.getBlockCode() != nil && (CCUtility.getBlockCode()?.count)! > 0 && controlPasscode {
+        if includeDirectoryE2EEncryption {
             
-            let viewController = CCBKPasscode.init(nibName: nil, bundle: nil)
-            guard let touchIDManager = BKTouchIDManager.init(keychainServiceName: k_serviceShareKeyChain) else {
-                return
-            }
-            touchIDManager.promptText = NSLocalizedString("_scan_fingerprint_", comment: "")
-
-            viewController.delegate = self
-            viewController.type = BKPasscodeViewControllerCheckPasscodeType
-            viewController.inputViewTitlePassword = true
-            if CCUtility.getSimplyBlockCode() {
-                viewController.passcodeStyle = BKPasscodeInputViewNumericPasscodeStyle
-                viewController.passcodeInputView.maximumLength = 6
+            if includeImages {
+                predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND (directory == true OR typeFile == 'image')", appDelegate.activeAccount, serverUrl)
             } else {
-                viewController.passcodeStyle = BKPasscodeInputViewNormalPasscodeStyle
-                viewController.passcodeInputView.maximumLength = 64
+                predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND directory == true", appDelegate.activeAccount, serverUrl)
             }
-            viewController.touchIDManager = touchIDManager
-            viewController.title = NSLocalizedString("_folder_blocked_", comment: "")
-            viewController.navigationItem.leftBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonItem.SystemItem.cancel, target: self, action: #selector(passcodeViewCloseButtonPressed(_:)))
-            viewController.navigationItem.leftBarButtonItem?.tintColor = UIColor.black
             
-            let navigationController = UINavigationController.init(rootViewController: viewController)
-            self.present(navigationController, animated: true, completion: nil)
+        } else {
             
-            return
+            if includeImages {
+                predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND e2eEncrypted == false AND (directory == true OR typeFile == 'image')", appDelegate.activeAccount, serverUrl)
+            } else {
+                predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND e2eEncrypted == false AND directory == true", appDelegate.activeAccount, serverUrl)
+            }
         }
         
-        guard let visualController = UIStoryboard(name: "NCSelect", bundle: nil).instantiateViewController(withIdentifier: "NCSelect.storyboard") as? NCSelect else {
-            return
+        if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: predicate!, sorted: nil, ascending: false) {
+            
+            sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterFileID: nil, filterTypeFileImage: false, filterTypeFileVideo: false, sorted: datasourceSorted, ascending: datasourceAscending, activeAccount: appDelegate.activeAccount)
         }
         
-        visualController.delegate = delegate
+        if withLoadFolder {
+            loadFolder()
+        } else {
+            self.refreshControl.endRefreshing()
+        }
         
-        visualController.hideButtonCreateFolder = hideButtonCreateFolder
-        visualController.selectFile = selectFile
-        visualController.includeDirectoryE2EEncryption = includeDirectoryE2EEncryption
-        visualController.includeImages = includeImages
-        visualController.type = type
-        visualController.titleButtonDone = titleButtonDone
-        visualController.layoutViewSelect = layoutViewSelect
+        collectionView.reloadData()
+    }
+    
+    func createFolder(with fileName: String) {
         
-        visualController.titleCurrentFolder = metadataPush!.fileNameView
-        visualController.serverUrl = serverUrlPush
+        OCNetworking.sharedManager().createFolder(withAccount: appDelegate.activeAccount, serverUrl: serverUrl, fileName: fileName, completion: { (account, fileID, date, message, errorCode) in
+            if errorCode == 0 && account == self.appDelegate.activeAccount {
+                self.loadDatasource(withLoadFolder: true)
+            } else if errorCode != 0 {
+                self.appDelegate.messageNotification("_error_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
+            } else {
+                print("[LOG] It has been changed user during networking process, error.")
+            }
+        })
+    }
+    
+    func loadFolder() {
         
-        self.navigationController?.pushViewController(visualController, animated: true)
+        networkInProgress = true
+        collectionView.reloadData()
+        
+        OCNetworking.sharedManager().readFolder(withAccount: appDelegate.activeAccount, serverUrl: serverUrl, depth: "1", completion: { (account, metadatas, metadataFolder, message, errorCode) in
+            
+            if errorCode == 0 && account == self.appDelegate.activeAccount {
+                
+                self.metadataFolder = metadataFolder
+                
+                // Update directory etag
+                NCManageDatabase.sharedInstance.setDirectory(serverUrl: self.serverUrl, serverUrlTo: nil, etag: metadataFolder?.etag, fileID: metadataFolder?.fileID, encrypted: metadataFolder!.e2eEncrypted, account: self.appDelegate.activeAccount)
+                NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d)", self.appDelegate.activeAccount ,self.serverUrl, k_metadataStatusNormal, k_metadataStatusHide))
+                NCManageDatabase.sharedInstance.setDateReadDirectory(serverUrl: self.serverUrl, account: self.appDelegate.activeAccount)
+                
+                _ = NCManageDatabase.sharedInstance.addMetadatas(metadatas as! [tableMetadata])
+                
+                if let metadatasInDownload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", self.appDelegate.activeAccount ,self.serverUrl, k_metadataStatusWaitDownload, k_metadataStatusInDownload, k_metadataStatusDownloading, k_metadataStatusDownloadError), sorted: nil, ascending: false) {
+                    
+                    _ = NCManageDatabase.sharedInstance.addMetadatas(metadatasInDownload)
+                }
+                
+            } else if errorCode != 0 {
+                self.appDelegate.messageNotification("_error_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
+            } else {
+                print("[LOG] It has been changed user during networking process, error.")
+            }
+            
+            self.networkInProgress = false
+            self.loadDatasource(withLoadFolder: false)
+        })
     }
 }

+ 17 - 5
iOSClient/Trash/NCTrash.swift

@@ -28,7 +28,7 @@ class NCTrash: UIViewController, UIGestureRecognizerDelegate, NCTrashListCellDel
     
     @IBOutlet fileprivate weak var collectionView: UICollectionView!
 
-    var path = ""
+    var serverUrl = ""
     var titleCurrentFolder = NSLocalizedString("_trash_view_", comment: "")
     var scrollToFileID = ""
     var scrollToIndexPath: IndexPath?
@@ -109,7 +109,7 @@ class NCTrash: UIViewController, UIGestureRecognizerDelegate, NCTrashListCellDel
         super.viewDidAppear(animated)
         
         if scrollToFileID != "" {
-            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
+            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                 for item in 0...self.datasource.count-1 {
                     if self.datasource[item].fileID.contains(self.scrollToFileID) {
                         self.scrollToIndexPath = IndexPath(item: item, section: 0)
@@ -491,7 +491,7 @@ extension NCTrash: UICollectionViewDelegate {
             
             let ncTrash:NCTrash = UIStoryboard(name: "NCTrash", bundle: nil).instantiateInitialViewController() as! NCTrash
             
-            ncTrash.path = tableTrash.filePath + tableTrash.fileName
+            ncTrash.serverUrl = tableTrash.filePath + tableTrash.fileName
             ncTrash.titleCurrentFolder = tableTrash.trashbinFileName
             
             self.navigationController?.pushViewController(ncTrash, animated: true)
@@ -646,10 +646,13 @@ extension NCTrash {
     @objc func loadDatasource() {
         
         datasource.removeAll()
+        var path = ""
         
-        if path == "" {
+        if serverUrl == "" {
             let userID = (appDelegate.activeUserID as NSString).addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlFragmentAllowed)
             path = k_dav + "/trashbin/" + userID! + "/trash/"
+        } else {
+            path = serverUrl
         }
         
         guard let tashItems = NCManageDatabase.sharedInstance.getTrash(filePath: path, sorted: datasourceSorted, ascending: datasourceAscending, account: appDelegate.activeAccount) else {
@@ -663,12 +666,21 @@ extension NCTrash {
     
     @objc func loadListingTrash() {
         
+        var path = ""
+
+        if serverUrl == "" {
+            let userID = (appDelegate.activeUserID as NSString).addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlFragmentAllowed)
+            path = k_dav + "/trashbin/" + userID! + "/trash/"
+        } else {
+            path = serverUrl
+        }
+        
         OCNetworking.sharedManager().listingTrash(withAccount: appDelegate.activeAccount, path: path, serverUrl: appDelegate.activeUrl, completion: { (account, item, message, errorCode) in
             
             self.refreshControl.endRefreshing()
             
             if errorCode == 0 && account == self.appDelegate.activeAccount {
-                NCManageDatabase.sharedInstance.deleteTrash(filePath: self.path, account: self.appDelegate.activeAccount)
+                NCManageDatabase.sharedInstance.deleteTrash(filePath: path, account: self.appDelegate.activeAccount)
                 NCManageDatabase.sharedInstance.addTrashs(item as! [tableTrash])
             } else if errorCode == kOCErrorServerUnauthorized {
                 self.appDelegate.openLoginView(self, delegate: self.appDelegate.activeMain, loginType: Int(k_login_Modify_Password), selector: Int(k_intro_login))