// // NCSelect.swift // Nextcloud // // Created by Marino Faggiana on 06/11/2018. // Copyright © 2018 Marino Faggiana. All rights reserved. // // Author Marino Faggiana // // 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 . // import Foundation import NCCommunication @objc protocol NCSelectDelegate { @objc func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], buttonType: String, overwrite: Bool) } class NCSelect: UIViewController, UIGestureRecognizerDelegate, UIAdaptivePresentationControllerDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, NCEmptyDataSetDelegate { @IBOutlet fileprivate weak var collectionView: UICollectionView! @IBOutlet fileprivate weak var toolbar: UIView! @IBOutlet fileprivate weak var overwriteView: UIView! @IBOutlet fileprivate weak var buttonCancel: UIBarButtonItem! @IBOutlet fileprivate weak var buttonCreateFolder: UIButton! @IBOutlet fileprivate weak var buttonDone: UIButton! @IBOutlet fileprivate weak var buttonDone1: UIButton! @IBOutlet fileprivate weak var overwriteSwitch: UISwitch! @IBOutlet fileprivate weak var overwriteLabel: UILabel! @IBOutlet fileprivate weak var toolBarTop: NSLayoutConstraint! // ------ external settings ------------------------------------ @objc var delegate: NCSelectDelegate? @objc var hideButtonCreateFolder = false @objc var selectFile = false @objc var includeDirectoryE2EEncryption = false @objc var includeImages = false @objc var type = "" @objc var titleButtonDone = NSLocalizedString("_move_", comment: "") @objc var titleButtonDone1 = NSLocalizedString("_copy_", comment: "") @objc var isButtonDone1Hide = true @objc var isOverwriteHide = true @objc var items: [Any] = [] var titleCurrentFolder = NCBrandOptions.shared.brand var serverUrl = "" // ------------------------------------------------------------- private let appDelegate = UIApplication.shared.delegate as! AppDelegate private var emptyDataSet: NCEmptyDataSet? private let keyLayout = k_layout_view_move private var serverUrlPush = "" private var metadataTouch: tableMetadata? private var metadataFolder = tableMetadata() private var isEditMode = false private var networkInProgress = false private var selectOcId: [String] = [] private var overwrite = false private var dataSource = NCDataSource() internal var richWorkspaceText: String? private var sort: String = "" private var ascending: Bool = true private var directoryOnTop: Bool = true private var layout = "" private var groupBy = "" private var titleButton = "" private var itemForLine = 0 private var autoUploadFileName = "" private var autoUploadDirectory = "" private var listLayout: NCListLayout! private var gridLayout: NCGridLayout! private let headerHeight: CGFloat = 50 private var headerRichWorkspaceHeight: CGFloat = 0 private let footerHeight: CGFloat = 100 private var shares: [tableShare]? private let refreshControl = UIRefreshControl() override func viewDidLoad() { super.viewDidLoad() self.navigationController?.navigationBar.prefersLargeTitles = true self.navigationController?.presentationController?.delegate = self // Cell collectionView.register(UINib.init(nibName: "NCListCell", bundle: nil), forCellWithReuseIdentifier: "listCell") collectionView.register(UINib.init(nibName: "NCGridCell", bundle: nil), forCellWithReuseIdentifier: "gridCell") // Header collectionView.register(UINib.init(nibName: "NCSectionHeaderMenu", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "sectionHeaderMenu") // Footer collectionView.register(UINib.init(nibName: "NCSectionFooter", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: "sectionFooter") collectionView.alwaysBounceVertical = true listLayout = NCListLayout() gridLayout = NCGridLayout() // Add Refresh Control collectionView.addSubview(refreshControl) refreshControl.tintColor = NCBrandColor.shared.brandText refreshControl.backgroundColor = NCBrandColor.shared.brandElement refreshControl.addTarget(self, action: #selector(loadDatasource), for: .valueChanged) // Empty emptyDataSet = NCEmptyDataSet.init(view: collectionView, offset: -200, delegate: self) // title button buttonCancel.title = NSLocalizedString("_cancel_", comment: "") buttonCreateFolder.setTitle(NSLocalizedString("_create_folder_", comment: ""), for: .normal) overwriteLabel.text = NSLocalizedString("_overwrite_", comment: "") // button buttonCreateFolder.layer.cornerRadius = 15 buttonCreateFolder.layer.masksToBounds = true buttonCreateFolder.layer.backgroundColor = NCBrandColor.shared.graySoft.withAlphaComponent(0.5).cgColor buttonCreateFolder.setTitleColor(.black, for: .normal) buttonDone.layer.cornerRadius = 15 buttonDone.layer.masksToBounds = true buttonDone.layer.backgroundColor = NCBrandColor.shared.graySoft.withAlphaComponent(0.5).cgColor buttonDone.setTitleColor(.black, for: .normal) buttonDone1.layer.cornerRadius = 15 buttonDone1.layer.masksToBounds = true buttonDone1.layer.backgroundColor = NCBrandColor.shared.graySoft.withAlphaComponent(0.5).cgColor buttonDone1.setTitleColor(.black, for: .normal) NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil) NotificationCenter.default.addObserver(self, selector: #selector(reloadDataSource), name: NSNotification.Name(rawValue: k_notificationCenter_reloadDataSource), object: nil) changeTheming() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.navigationItem.title = titleCurrentFolder toolBarTop.constant = -100 buttonDone.setTitle(titleButtonDone, for: .normal) buttonDone1.setTitle(titleButtonDone1, for: .normal) buttonDone1.isHidden = isButtonDone1Hide overwriteSwitch.isOn = overwrite overwriteView.isHidden = isOverwriteHide if selectFile { buttonDone.isHidden = true } if hideButtonCreateFolder { buttonCreateFolder.isHidden = true } // set the serverUrl if serverUrl == "" { serverUrl = NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) } // get auto upload folder autoUploadFileName = NCManageDatabase.shared.getAccountAutoUploadFileName() autoUploadDirectory = NCManageDatabase.shared.getAccountAutoUploadDirectory(urlBase: appDelegate.urlBase, account: appDelegate.account) (layout, sort, ascending, groupBy, directoryOnTop, titleButton, itemForLine) = NCUtility.shared.getLayoutForView(key: keyLayout,serverUrl: serverUrl) gridLayout.itemForLine = CGFloat(itemForLine) if layout == k_layout_list { collectionView.collectionViewLayout = listLayout } else { collectionView.collectionViewLayout = gridLayout } loadDatasource(withLoadFolder: true) shares = NCManageDatabase.shared.getTableShares(account: appDelegate.account, serverUrl: serverUrl) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) coordinator.animate(alongsideTransition: nil) { _ in self.collectionView?.collectionViewLayout.invalidateLayout() } } @objc func changeTheming() { view.backgroundColor = NCBrandColor.shared.backgroundView collectionView.backgroundColor = NCBrandColor.shared.backgroundView collectionView.reloadData() refreshControl.backgroundColor = NCBrandColor.shared.backgroundView toolbar.backgroundColor = NCBrandColor.shared.tabBar //toolbar.tintColor = .gray } func presentationControllerDidDismiss( _ presentationController: UIPresentationController) { delegate?.dismissSelect(serverUrl: nil, metadata: nil, type: type, items: items, buttonType: "cancel", overwrite: overwrite) } // MARK: - Empty func emptyDataSetView(_ view: NCEmptyView) { if networkInProgress { view.emptyImage.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "networkInProgress"), width: 300, height: 300, color: .gray) view.emptyTitle.text = NSLocalizedString("_request_in_progress_", comment: "") view.emptyDescription.text = "" } else { view.emptyImage.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "folder"), width: 300, height: 300, color: NCBrandColor.shared.brandElement) if includeImages { view.emptyTitle.text = NSLocalizedString("_files_no_files_", comment: "") } else { view.emptyTitle.text = NSLocalizedString("_files_no_folders_", comment: "") } view.emptyDescription.text = "" } } // MARK: ACTION @IBAction func actionCancel(_ sender: Any) { delegate?.dismissSelect(serverUrl: nil, metadata: nil, type: type, items: items, buttonType: "cancel", overwrite: overwrite) self.dismiss(animated: true, completion: nil) } @IBAction func actionDone(_ sender: Any) { delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadataFolder, type: type, items: items, buttonType: "done", overwrite: overwrite) self.dismiss(animated: true, completion: nil) } @IBAction func actionDone1(_ sender: Any) { delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadataFolder, type: type, items: items, buttonType: "done1", overwrite: overwrite) self.dismiss(animated: true, completion: nil) } @IBAction func actionCreateFolder(_ sender: Any) { let alertController = UIAlertController(title: NSLocalizedString("_create_folder_", comment: ""), message:"", preferredStyle: .alert) alertController.addTextField { (textField) in textField.autocapitalizationType = UITextAutocapitalizationType.words } let actionSave = UIAlertAction(title: NSLocalizedString("_save_", comment: ""), style: .default) { (action:UIAlertAction) in if let fileName = alertController.textFields?.first?.text { self.createFolder(with: fileName) } } let actionCancel = UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .cancel) { (action:UIAlertAction) in print("You've pressed cancel button") } alertController.addAction(actionSave) alertController.addAction(actionCancel) self.present(alertController, animated: true, completion:nil) } @IBAction func valueChangedSwitchOverwrite(_ sender: Any) { if let viewControllers = self.navigationController?.viewControllers { for viewController in viewControllers { if viewController is NCSelect { (viewController as! NCSelect).overwrite = overwriteSwitch.isOn } } } } // MARK: TAP EVENT func tapSwitchHeader(sender: Any) { if collectionView.collectionViewLayout == gridLayout { // list layout UIView.animate(withDuration: 0.0, animations: { self.collectionView.collectionViewLayout.invalidateLayout() self.collectionView.setCollectionViewLayout(self.listLayout, animated: false, completion: { (_) in self.collectionView.reloadData() }) }) layout = k_layout_list } else { // grid layout UIView.animate(withDuration: 0.0, animations: { self.collectionView.collectionViewLayout.invalidateLayout() self.collectionView.setCollectionViewLayout(self.gridLayout, animated: false, completion: { (_) in self.collectionView.reloadData() }) }) layout = k_layout_grid } } func tapOrderHeader(sender: Any) { let sortMenu = NCSortMenu() sortMenu.toggleMenu(viewController: self, key: keyLayout, sortButton: sender as? UIButton, serverUrl: serverUrl) } func tapMoreHeader(sender: Any) { } func tapMoreListItem(with objectId: String, namedButtonMore: String, sender: Any) { } func tapMoreGridItem(with objectId: String, namedButtonMore: String, sender: Any) { } func tapShareListItem(with objectId: String, sender: Any) { } func tapRichWorkspace(sender: Any) { } func longPressListItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer) { } func longPressGridItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer) { } func longPressMoreListItem(with objectId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) { } func longPressMoreGridItem(with objectId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) { } } // MARK: - Collection View extension NCSelect: UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { guard let metadata = dataSource.cellForItemAt(indexPath: indexPath) else { return } if isEditMode { if let index = selectOcId.firstIndex(of: metadata.ocId) { selectOcId.remove(at: index) } else { selectOcId.append(metadata.ocId) } collectionView.reloadItems(at: [indexPath]) return } if metadata.directory { guard let serverUrlPush = CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName) else { return } guard let visualController = UIStoryboard(name: "NCSelect", bundle: nil).instantiateViewController(withIdentifier: "NCSelect.storyboard") as? NCSelect else { return } self.serverUrlPush = serverUrlPush self.metadataTouch = metadata visualController.delegate = delegate visualController.hideButtonCreateFolder = hideButtonCreateFolder visualController.selectFile = selectFile visualController.includeDirectoryE2EEncryption = includeDirectoryE2EEncryption visualController.includeImages = includeImages visualController.type = type visualController.titleButtonDone = titleButtonDone visualController.titleButtonDone1 = titleButtonDone1 visualController.isButtonDone1Hide = isButtonDone1Hide visualController.isOverwriteHide = isOverwriteHide visualController.overwrite = overwrite visualController.items = items visualController.titleCurrentFolder = metadataTouch!.fileNameView visualController.serverUrl = serverUrlPush self.navigationController?.pushViewController(visualController, animated: true) } else { delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadata, type: type, items: items, buttonType: "select", overwrite: overwrite) self.dismiss(animated: true, completion: nil) } } } extension NCSelect: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { if kind == UICollectionView.elementKindSectionHeader { let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionHeaderMenu", for: indexPath) as! NCSectionHeaderMenu if collectionView.collectionViewLayout == gridLayout { header.buttonSwitch.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "switchList"), multiplier: 2, color: NCBrandColor.shared.icon), for: .normal) } else { header.buttonSwitch.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "switchGrid"), multiplier: 2, color: NCBrandColor.shared.icon), for: .normal) } header.delegate = self header.setStatusButton(count: dataSource.metadatas.count) header.setTitleSorted(datasourceTitleButton: titleButton) header.viewRichWorkspaceHeightConstraint.constant = headerRichWorkspaceHeight header.setRichWorkspaceText(richWorkspaceText: richWorkspaceText) return header } else { let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionFooter", for: indexPath) as! NCSectionFooter let info = dataSource.getFilesInformation() footer.setTitleLabel(directories: info.directories, files: info.files, size: info.size) return footer } } func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { let numberOfItems = dataSource.numberOfItems() emptyDataSet?.numberOfItemsInSection(numberOfItems, section:section) return numberOfItems } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let metadata = dataSource.cellForItemAt(indexPath: indexPath) else { if layout == k_layout_list { return collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! NCListCell } else { return collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as! NCGridCell } } var tableShare: tableShare? var isShare = false var isMounted = false // Download preview NCOperationQueue.shared.downloadThumbnail(metadata: metadata, urlBase: appDelegate.urlBase, view: collectionView, indexPath: indexPath) isShare = metadata.permissions.contains(k_permission_shared) && !metadataFolder.permissions.contains(k_permission_shared) isMounted = metadata.permissions.contains(k_permission_mounted) && !metadataFolder.permissions.contains(k_permission_mounted) if dataSource.metadataShare[metadata.ocId] != nil { tableShare = dataSource.metadataShare[metadata.ocId] } // LAYOUT LIST if layout == k_layout_list { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! NCListCell cell.delegate = self cell.objectId = metadata.ocId cell.indexPath = indexPath cell.labelTitle.text = metadata.fileNameView cell.labelTitle.textColor = NCBrandColor.shared.textView cell.separator.backgroundColor = NCBrandColor.shared.separator cell.imageSelect.image = nil cell.imageStatus.image = nil cell.imageLocal.image = nil cell.imageFavorite.image = nil cell.imageShared.image = nil cell.imageMore.image = nil cell.imageItem.image = nil cell.imageItem.backgroundColor = nil cell.progressView.progress = 0.0 if metadata.directory { if metadata.e2eEncrypted { cell.imageItem.image = NCCollectionCommon.images.cellFolderEncryptedImage } else if isShare { cell.imageItem.image = NCCollectionCommon.images.cellFolderSharedWithMeImage } else if (tableShare != nil && tableShare?.shareType != 3) { cell.imageItem.image = NCCollectionCommon.images.cellFolderSharedWithMeImage } else if (tableShare != nil && tableShare?.shareType == 3) { cell.imageItem.image = NCCollectionCommon.images.cellFolderPublicImage } else if metadata.mountType == "group" { cell.imageItem.image = NCCollectionCommon.images.cellFolderGroupImage } else if isMounted { cell.imageItem.image = NCCollectionCommon.images.cellFolderExternalImage } else if metadata.fileName == autoUploadFileName && metadata.serverUrl == autoUploadDirectory { cell.imageItem.image = NCCollectionCommon.images.cellFolderAutomaticUploadImage } else { cell.imageItem.image = NCCollectionCommon.images.cellFolderImage } cell.labelInfo.text = CCUtility.dateDiff(metadata.date as Date) let lockServerUrl = CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName)! let tableDirectory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account, lockServerUrl)) // Local image: offline if tableDirectory != nil && tableDirectory!.offline { cell.imageLocal.image = NCCollectionCommon.images.cellOfflineFlag } } else { if FileManager().fileExists(atPath: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) { cell.imageItem.image = UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) } else { if metadata.hasPreview { cell.imageItem.backgroundColor = .lightGray } else { if metadata.iconName.count > 0 { cell.imageItem.image = UIImage.init(named: metadata.iconName) } else { cell.imageItem.image = NCCollectionCommon.images.cellFileImage } } } cell.labelInfo.text = CCUtility.dateDiff(metadata.date as Date) + " · " + CCUtility.transformedSize(metadata.size) // image local if dataSource.metadataOffLine.contains(metadata.ocId) { cell.imageLocal.image = NCCollectionCommon.images.cellOfflineFlag } else if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) { cell.imageLocal.image = NCCollectionCommon.images.cellLocal } } // image Favorite if metadata.favorite { cell.imageFavorite.image = NCCollectionCommon.images.cellFavouriteImage } // Share image if (isShare) { cell.imageShared.image = NCCollectionCommon.images.cellSharedImage } else if (tableShare != nil && tableShare?.shareType == 3) { cell.imageShared.image = NCCollectionCommon.images.cellShareByLinkImage } else if (tableShare != nil && tableShare?.shareType != 3) { cell.imageShared.image = NCCollectionCommon.images.cellSharedImage } else { cell.imageShared.image = NCCollectionCommon.images.cellCanShareImage } if metadata.ownerId.count > 0 && metadata.ownerId != appDelegate.userID { // Load avatar let fileNameSource = CCUtility.getDirectoryUserData() + "/" + CCUtility.getStringUser(appDelegate.user, urlBase: appDelegate.urlBase) + "-" + metadata.ownerId + ".png" let fileNameSourceAvatar = CCUtility.getDirectoryUserData() + "/" + CCUtility.getStringUser(appDelegate.user, urlBase: appDelegate.urlBase) + "-avatar-" + metadata.ownerId + ".png" if FileManager.default.fileExists(atPath: fileNameSourceAvatar) { cell.imageShared.image = UIImage(contentsOfFile: fileNameSourceAvatar) } else if FileManager.default.fileExists(atPath: fileNameSource) { cell.imageShared.image = NCUtility.shared.createAvatar(fileNameSource: fileNameSource, fileNameSourceAvatar: fileNameSourceAvatar) } else { NCCommunication.shared.downloadAvatar(userID: metadata.ownerId, fileNameLocalPath: fileNameSource, size: Int(k_avatar_size)) { (account, data, errorCode, errorMessage) in if errorCode == 0 && account == self.appDelegate.account { cell.imageShared.image = NCUtility.shared.createAvatar(fileNameSource: fileNameSource, fileNameSourceAvatar: fileNameSourceAvatar) } } } } cell.imageSelect.isHidden = true cell.backgroundView = nil cell.hideButtonMore(true) cell.hideButtonShare(true) cell.selectMode(false) // Live Photo if metadata.livePhoto { cell.imageStatus.image = NCCollectionCommon.images.cellLivePhotoImage } // Remove last separator if collectionView.numberOfItems(inSection: indexPath.section) == indexPath.row + 1 { cell.separator.isHidden = true } else { cell.separator.isHidden = false } return cell } // LAYOUT GRID if layout == k_layout_grid { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as! NCGridCell cell.delegate = self cell.objectId = metadata.ocId cell.indexPath = indexPath cell.labelTitle.text = metadata.fileNameView cell.labelTitle.textColor = NCBrandColor.shared.textView cell.imageSelect.image = nil cell.imageStatus.image = nil cell.imageLocal.image = nil cell.imageFavorite.image = nil cell.imageItem.image = nil cell.imageItem.backgroundColor = nil cell.progressView.progress = 0.0 if metadata.directory { if metadata.e2eEncrypted { cell.imageItem.image = NCCollectionCommon.images.cellFolderEncryptedImage } else if isShare { cell.imageItem.image = NCCollectionCommon.images.cellFolderSharedWithMeImage } else if (tableShare != nil && tableShare!.shareType != 3) { cell.imageItem.image = NCCollectionCommon.images.cellFolderSharedWithMeImage } else if (tableShare != nil && tableShare!.shareType == 3) { cell.imageItem.image = NCCollectionCommon.images.cellFolderPublicImage } else if metadata.mountType == "group" { cell.imageItem.image = NCCollectionCommon.images.cellFolderGroupImage } else if isMounted { cell.imageItem.image = NCCollectionCommon.images.cellFolderExternalImage } else if metadata.fileName == autoUploadFileName && metadata.serverUrl == autoUploadDirectory { cell.imageItem.image = NCCollectionCommon.images.cellFolderAutomaticUploadImage } else { cell.imageItem.image = NCCollectionCommon.images.cellFolderImage } let lockServerUrl = CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName)! let tableDirectory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account, lockServerUrl)) // Local image: offline if tableDirectory != nil && tableDirectory!.offline { cell.imageLocal.image = NCCollectionCommon.images.cellOfflineFlag } } else { if FileManager().fileExists(atPath: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) { cell.imageItem.image = UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) } else { if metadata.hasPreview { cell.imageItem.backgroundColor = .lightGray } else { if metadata.iconName.count > 0 { cell.imageItem.image = UIImage.init(named: metadata.iconName) } else { cell.imageItem.image = NCCollectionCommon.images.cellFileImage } } } // image Local if dataSource.metadataOffLine.contains(metadata.ocId) { cell.imageLocal.image = NCCollectionCommon.images.cellOfflineFlag } else if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) { cell.imageLocal.image = NCCollectionCommon.images.cellLocal } } // image Favorite if metadata.favorite { cell.imageFavorite.image = NCCollectionCommon.images.cellFavouriteImage } cell.imageSelect.isHidden = true cell.backgroundView = nil cell.hideButtonMore(true) // Live Photo if metadata.livePhoto { cell.imageStatus.image = NCCollectionCommon.images.cellLivePhotoImage } return cell } return collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as! NCGridCell } } extension NCSelect: UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { if richWorkspaceText?.count ?? 0 == 0 { headerRichWorkspaceHeight = 0 } else { headerRichWorkspaceHeight = UIScreen.main.bounds.size.height / 4 } return CGSize(width: collectionView.frame.width, height: headerHeight + headerRichWorkspaceHeight) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { return CGSize(width: collectionView.frame.width, height: footerHeight) } } // MARK: - NC API & Algorithm extension NCSelect { @objc func reloadDataSource() { loadDatasource(withLoadFolder: false) } @objc func loadDatasource(withLoadFolder: Bool) { var predicate: NSPredicate? (layout, sort, ascending, groupBy, directoryOnTop, titleButton, itemForLine) = NCUtility.shared.getLayoutForView(key: keyLayout, serverUrl: serverUrl) if includeDirectoryE2EEncryption { if includeImages { predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND (directory == true OR typeFile == 'image')", appDelegate.account, serverUrl) } else { predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND directory == true", appDelegate.account, serverUrl) } } else { if includeImages { predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND e2eEncrypted == false AND (directory == true OR typeFile == 'image')", appDelegate.account, serverUrl) } else { predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND e2eEncrypted == false AND directory == true", appDelegate.account, serverUrl) } } let metadatasSource = NCManageDatabase.shared.getMetadatas(predicate: predicate!) self.dataSource = NCDataSource.init(metadatasSource: metadatasSource, sort: sort, ascending: ascending, directoryOnTop: directoryOnTop, favoriteOnTop: true, filterLivePhoto: true) if withLoadFolder { loadFolder() } else { self.refreshControl.endRefreshing() } let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account,serverUrl)) richWorkspaceText = directory?.richWorkspace collectionView.reloadData() } func createFolder(with fileName: String) { NCNetworking.shared.createFolder(fileName: fileName, serverUrl: serverUrl, account: appDelegate.account, urlBase: appDelegate.urlBase) { (errorCode, errorDescription) in if errorCode == 0 { self.loadDatasource(withLoadFolder: true) } else { NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode) } } } func loadFolder() { networkInProgress = true collectionView.reloadData() NCNetworking.shared.readFolder(serverUrl: serverUrl, account: appDelegate.account) { (_, _, _, _, _, errorCode, errorDescription) in if errorCode != 0 { NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode) } self.networkInProgress = false self.loadDatasource(withLoadFolder: false) } } }