diff --git a/Nextcloud.xcodeproj/xcshareddata/xcschemes/File Provider Extension UI.xcscheme b/Nextcloud.xcodeproj/xcshareddata/xcschemes/File Provider Extension UI.xcscheme index c06627e268..e19e0492e1 100644 --- a/Nextcloud.xcodeproj/xcshareddata/xcschemes/File Provider Extension UI.xcscheme +++ b/Nextcloud.xcodeproj/xcshareddata/xcschemes/File Provider Extension UI.xcscheme @@ -73,7 +73,6 @@ savedToolIdentifier = "" useCustomWorkingDirectory = "NO" debugDocumentVersioning = "YES" - askForAppToLaunch = "Yes" launchAutomaticallySubstyle = "2"> diff --git a/Nextcloud.xcodeproj/xcshareddata/xcschemes/WidgetDashboardIntentHandler.xcscheme b/Nextcloud.xcodeproj/xcshareddata/xcschemes/WidgetDashboardIntentHandler.xcscheme index e7fe4caf7c..0b68bbe8b4 100644 --- a/Nextcloud.xcodeproj/xcshareddata/xcschemes/WidgetDashboardIntentHandler.xcscheme +++ b/Nextcloud.xcodeproj/xcshareddata/xcschemes/WidgetDashboardIntentHandler.xcscheme @@ -73,7 +73,6 @@ savedToolIdentifier = "" useCustomWorkingDirectory = "NO" debugDocumentVersioning = "YES" - askForAppToLaunch = "Yes" launchAutomaticallySubstyle = "2"> diff --git a/iOSClient/Trash/Cell/NCTrashGridCell.swift b/iOSClient/Trash/Cell/NCTrashGridCell.swift index 44c53a1ae2..39cf2bdb73 100644 --- a/iOSClient/Trash/Cell/NCTrashGridCell.swift +++ b/iOSClient/Trash/Cell/NCTrashGridCell.swift @@ -2,47 +2,74 @@ // NCTrashGridCell.swift // Nextcloud // -// Created by Marino Faggiana on 19/03/2024. -// Copyright © 2024 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 . +// Created by A200073704 on 27/06/23. +// Copyright © 2023 Marino Faggiana. All rights reserved. // import UIKit -protocol NCTrashGridCellDelegate: AnyObject { - func tapMoreGridItem(with objectId: String, namedButtonMore: String, image: UIImage?, indexPath: IndexPath, sender: Any) -} - class NCTrashGridCell: UICollectionViewCell, NCTrashCellProtocol { + @IBOutlet weak var imageItem: UIImageView! @IBOutlet weak var imageSelect: UIImageView! + @IBOutlet weak var imageStatus: UIImageView! + @IBOutlet weak var imageFavorite: UIImageView! + @IBOutlet weak var imageLocal: UIImageView! @IBOutlet weak var labelTitle: UILabel! @IBOutlet weak var labelInfo: UILabel! - @IBOutlet weak var labelSubinfo: UILabel! @IBOutlet weak var buttonMore: UIButton! @IBOutlet weak var imageVisualEffect: UIVisualEffectView! + @IBOutlet weak var progressView: UIProgressView! - weak var delegate: NCTrashGridCellDelegate? - var objectId = "" + internal var objectId = "" var indexPath = IndexPath() - var user = "" + private var user = "" + + weak var delegate: NCGridCellDelegate? var namedButtonMore = "" + var fileObjectId: String? { + get { return objectId } + set { objectId = newValue ?? "" } + } + var filePreviewImageView: UIImageView? { + get { return imageItem } + set { imageItem = newValue } + } + var fileUser: String? { + get { return user } + set { user = newValue ?? "" } + } + var fileTitleLabel: UILabel? { + get { return labelTitle } + set { labelTitle = newValue } + } + var fileInfoLabel: UILabel? { + get { return labelInfo } + set { labelInfo = newValue } + } + var fileProgressView: UIProgressView? { + get { return progressView } + set { progressView = newValue } + } + var fileSelectImage: UIImageView? { + get { return imageSelect } + set { imageSelect = newValue } + } + var fileStatusImage: UIImageView? { + get { return imageStatus } + set { imageStatus = newValue } + } + var fileLocalImage: UIImageView? { + get { return imageLocal } + set { imageLocal = newValue } + } + var fileFavoriteImage: UIImageView? { + get { return imageFavorite } + set { imageFavorite = newValue } + } + override func awakeFromNib() { super.awakeFromNib() initCell() @@ -66,9 +93,14 @@ class NCTrashGridCell: UICollectionViewCell, NCTrashCellProtocol { imageVisualEffect.clipsToBounds = true imageVisualEffect.alpha = 0.5 + progressView.tintColor = NCBrandColor.shared.brandElement + progressView.transform = CGAffineTransform(scaleX: 1.0, y: 0.5) + progressView.trackTintColor = .clear + labelTitle.text = "" labelInfo.text = "" - labelSubinfo.text = "" + labelTitle.textColor = .label + labelInfo.textColor = .systemGray } override func snapshotView(afterScreenUpdates afterUpdates: Bool) -> UIView? { @@ -79,9 +111,10 @@ class NCTrashGridCell: UICollectionViewCell, NCTrashCellProtocol { delegate?.tapMoreGridItem(with: objectId, namedButtonMore: namedButtonMore, image: imageItem.image, indexPath: indexPath, sender: sender) } + fileprivate func setA11yActions() { let moreName = namedButtonMore == NCGlobal.shared.buttonMoreStop ? "_cancel_" : "_more_" - + self.accessibilityCustomActions = [ UIAccessibilityCustomAction( name: NSLocalizedString(moreName, comment: ""), @@ -89,7 +122,7 @@ class NCTrashGridCell: UICollectionViewCell, NCTrashCellProtocol { selector: #selector(touchUpInsideMore)) ] } - + func setButtonMore(named: String, image: UIImage) { namedButtonMore = named buttonMore.setImage(image, for: .normal) @@ -113,7 +146,7 @@ class NCTrashGridCell: UICollectionViewCell, NCTrashCellProtocol { imageSelect.isHidden = false imageVisualEffect.isHidden = false } else { - imageSelect.isHidden = true + imageSelect.image = NCImageCache.images.checkedNo imageVisualEffect.isHidden = true } } @@ -124,8 +157,7 @@ class NCTrashGridCell: UICollectionViewCell, NCTrashCellProtocol { dateFormatter.timeStyle = .none dateFormatter.locale = Locale.current - labelInfo.text = dateFormatter.string(from: date as Date) - labelSubinfo.text = NCUtilityFileSystem().transformedSize(size) + labelInfo.text = dateFormatter.string(from: date as Date) + " · " + NCUtilityFileSystem().transformedSize(size) } func setAccessibility(label: String, value: String) { @@ -133,59 +165,3 @@ class NCTrashGridCell: UICollectionViewCell, NCTrashCellProtocol { accessibilityValue = value } } - -// MARK: - Grid Layout - -class NCTrashGridLayout: UICollectionViewFlowLayout { - - var heightLabelPlusButton: CGFloat = 60 - var marginLeftRight: CGFloat = 10 - var itemForLine: CGFloat = 3 - var itemWidthDefault: CGFloat = 140 - - // MARK: - View Life Cycle - - override init() { - super.init() - - sectionHeadersPinToVisibleBounds = false - - minimumInteritemSpacing = 1 - minimumLineSpacing = marginLeftRight - - self.scrollDirection = .vertical - self.sectionInset = UIEdgeInsets(top: 10, left: marginLeftRight, bottom: 0, right: marginLeftRight) - } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override var itemSize: CGSize { - get { - if let collectionView = collectionView { - - if collectionView.frame.width < 400 { - itemForLine = 3 - } else { - itemForLine = collectionView.frame.width / itemWidthDefault - } - - let itemWidth: CGFloat = (collectionView.frame.width - marginLeftRight * 2 - marginLeftRight * (itemForLine - 1)) / itemForLine - let itemHeight: CGFloat = itemWidth + heightLabelPlusButton - - return CGSize(width: itemWidth, height: itemHeight) - } - - // Default fallback - return CGSize(width: itemWidthDefault, height: itemWidthDefault) - } - set { - super.itemSize = newValue - } - } - - override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint { - return proposedContentOffset - } -} diff --git a/iOSClient/Trash/Cell/NCTrashGridCell.xib b/iOSClient/Trash/Cell/NCTrashGridCell.xib index 607f2744c6..91bd5f805d 100644 --- a/iOSClient/Trash/Cell/NCTrashGridCell.xib +++ b/iOSClient/Trash/Cell/NCTrashGridCell.xib @@ -1,9 +1,9 @@ - - + + - + @@ -11,140 +11,130 @@ - - + + - + - - + + - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + - - - - - - - + + + + + + + + + + - + - - + - - - - - - - + diff --git a/iOSClient/Trash/Cell/NCTrashListCell.swift b/iOSClient/Trash/Cell/NCTrashListCell.swift index 5a10f3ac34..e6c28c8115 100644 --- a/iOSClient/Trash/Cell/NCTrashListCell.swift +++ b/iOSClient/Trash/Cell/NCTrashListCell.swift @@ -46,6 +46,7 @@ class NCTrashListCell: UICollectionViewCell, NCTrashCellProtocol { weak var delegate: NCTrashListCellDelegate? var objectId = "" var indexPath = IndexPath() + let utility = NCUtility() override func awakeFromNib() { super.awakeFromNib() @@ -72,8 +73,11 @@ class NCTrashListCell: UICollectionViewCell, NCTrashCellProtocol { ] - imageRestore.image = NCUtility().loadImage(named: "arrow.circlepath", colors: [NCBrandColor.shared.iconImageColor]) - imageMore.image = NCUtility().loadImage(named: "trash", colors: [.red]) + imageRestore.image = utility.loadImage(named: "restore", color: NCBrandColor.shared.iconColor) + + imageMore.image = UIImage(systemName: "trash") + imageMore.tintColor = NCBrandColor.shared.iconColor + imageItem.layer.cornerRadius = 6 imageItem.layer.masksToBounds = true diff --git a/iOSClient/Trash/NCTrash+CollectionView.swift b/iOSClient/Trash/NCTrash+CollectionView.swift index 48ea792fe5..06c862db25 100644 --- a/iOSClient/Trash/NCTrash+CollectionView.swift +++ b/iOSClient/Trash/NCTrash+CollectionView.swift @@ -23,11 +23,15 @@ import UIKit import RealmSwift +import Foundation // MARK: UICollectionViewDelegate extension NCTrash: UICollectionViewDelegate { + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + let tableTrash = datasource[indexPath.item] + guard !isEditMode else { if let index = selectOcId.firstIndex(of: tableTrash.fileId) { selectOcId.remove(at: index) @@ -35,15 +39,14 @@ extension NCTrash: UICollectionViewDelegate { selectOcId.append(tableTrash.fileId) } collectionView.reloadItems(at: [indexPath]) - tabBarSelect.update(selectOcId: selectOcId) + setNavigationRightItems() return } if tableTrash.directory, let ncTrash: NCTrash = UIStoryboard(name: "NCTrash", bundle: nil).instantiateInitialViewController() as? NCTrash { - ncTrash.filePath = tableTrash.filePath + tableTrash.fileName + ncTrash.trashPath = tableTrash.filePath + tableTrash.fileName ncTrash.titleCurrentFolder = tableTrash.trashbinFileName - ncTrash.filename = tableTrash.fileName self.navigationController?.pushViewController(ncTrash, animated: true) } } @@ -51,30 +54,22 @@ extension NCTrash: UICollectionViewDelegate { // MARK: UICollectionViewDataSource extension NCTrash: UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + emptyDataSet?.numberOfItemsInSection(datasource.count, section: section) + setNavigationRightItems() return datasource.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let tableTrash = datasource[indexPath.item] var image: UIImage? - var cell: NCTrashCellProtocol & UICollectionViewCell - - if layoutForView?.layout == NCGlobal.shared.layoutList { - guard let listCell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as? NCTrashListCell else { return NCTrashListCell() } - listCell.delegate = self - cell = listCell - } else { - guard let gridCell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as? NCTrashGridCell else { return NCTrashGridCell() } - gridCell.setButtonMore(named: NCGlobal.shared.buttonMoreMore, image: NCImageCache.images.buttonMore) - gridCell.delegate = self - cell = gridCell - } if tableTrash.iconName.isEmpty { - image = NCImageCache.images.file + image = UIImage(named: "file") } else { - image = NCUtility().loadImage(named: tableTrash.iconName, useTypeIconFile: true) + image = UIImage(named: tableTrash.iconName) } if FileManager().fileExists(atPath: utilityFileSystem.getDirectoryProviderStorageIconOcId(tableTrash.fileId, etag: tableTrash.fileName)) { @@ -87,8 +82,21 @@ extension NCTrash: UICollectionViewDataSource { } } + var cell: NCTrashCellProtocol & UICollectionViewCell + + if layoutForView?.layout == NCGlobal.shared.layoutList { + guard let listCell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as? NCTrashListCell else { return UICollectionViewCell() } + listCell.delegate = self + cell = listCell + } else { + // GRID + guard let gridCell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as? NCTrashGridCell else { return UICollectionViewCell() } + gridCell.setButtonMore(named: NCGlobal.shared.buttonMoreMore, image: NCImageCache.images.buttonMore) + gridCell.delegate = self + cell = gridCell + } + cell.indexPath = indexPath - cell.objectId = tableTrash.fileId cell.setupCellUI(tableTrash: tableTrash, image: image) cell.selected(selectOcId.contains(tableTrash.fileId), isEditMode: isEditMode) @@ -96,6 +104,7 @@ extension NCTrash: UICollectionViewDataSource { } func setTextFooter(datasource: [tableTrash]) -> String { + var folders: Int = 0, foldersText = "" var files: Int = 0, filesText = "" var size: Int64 = 0 @@ -135,17 +144,34 @@ extension NCTrash: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { if kind == UICollectionView.elementKindSectionHeader { - guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionFirstHeaderEmptyData", for: indexPath) as? NCSectionFirstHeaderEmptyData - else { return NCSectionFirstHeaderEmptyData() } - header.emptyImage.image = utility.loadImage(named: "trash", colors: [NCBrandColor.shared.brandElement]) - header.emptyTitle.text = NSLocalizedString("_trash_no_trash_", comment: "") - header.emptyDescription.text = NSLocalizedString("_trash_no_trash_description_", comment: "") + guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionHeaderMenu", for: indexPath) as? NCSectionHeaderMenu + else { return UICollectionReusableView() } + + if layoutForView?.layout == NCGlobal.shared.layoutGrid { + header.setImageSwitchList() + header.buttonSwitch.accessibilityLabel = NSLocalizedString("_list_view_", comment: "") + } else { + header.setImageSwitchGrid() + header.buttonSwitch.accessibilityLabel = NSLocalizedString("_grid_view_", comment: "") + } + + header.delegate = self + header.setStatusButtonsView(enable: !datasource.isEmpty) + header.setSortedTitle(layoutForView?.titleButtonHeader ?? "") + header.setButtonsView(height: NCGlobal.shared.heightButtonsView) + header.setRichWorkspaceHeight(0) + header.setSectionHeight(0) + header.setViewTransfer(isHidden: true) + return header + } else { guard let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionFooter", for: indexPath) as? NCSectionFooter - else { return NCSectionFooter() } + else { return UICollectionReusableView() } + footer.setTitleLabel(setTextFooter(datasource: datasource)) footer.separatorIsHidden(true) + return footer } } @@ -153,12 +179,9 @@ extension NCTrash: UICollectionViewDataSource { // MARK: UICollectionViewDelegateFlowLayout extension NCTrash: UICollectionViewDelegateFlowLayout { + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { - var height: Double = 0 - if datasource.isEmpty { - height = NCGlobal.shared.getHeightHeaderEmptyData(view: view, portraitOffset: 0, landscapeOffset: 0) - } - return CGSize(width: collectionView.frame.width, height: height) + return CGSize(width: collectionView.frame.width, height: NCGlobal.shared.heightButtonsView) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { return CGSize(width: collectionView.frame.width, height: NCGlobal.shared.endHeightFooter) diff --git a/iOSClient/Trash/NCTrash.swift b/iOSClient/Trash/NCTrash.swift index 8651d4a040..20d2298a33 100644 --- a/iOSClient/Trash/NCTrash.swift +++ b/iOSClient/Trash/NCTrash.swift @@ -194,6 +194,20 @@ class NCTrash: UIViewController, NCTrashListCellDelegate, NCTrashGridCellDelegat } } + func tapButtonSwitch(_ sender: Any) { + if layoutForView?.layout == NCGlobal.shared.layoutGrid { + onListSelected() + } else { + onGridSelected() + } + } + + func tapButtonOrder(_ sender: Any) { + + let sortMenu = NCSortMenu() + sortMenu.toggleMenu(viewController: self, account: appDelegate.account, key: layoutKey, sortButton: sender as? UIButton, serverUrl: serverUrl) + } + func longPressGridItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer) { } func longPressMoreGridItem(with objectId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) { }