From 99b441e2e2e1e280468bb8257f8647aeb437d06c Mon Sep 17 00:00:00 2001 From: TSI-amrutwaghmare <96108296+TSI-amrutwaghmare@users.noreply.github.com> Date: Tue, 28 Nov 2023 11:37:14 +0530 Subject: [PATCH 1/6] nmc 2157 - move copy customisation --- .../NextcloudUnitTests/MoveAndCopyTests.swift | 106 ++++++++++++++++ .../Select/NCSelectCommandViewCopyMove.xib | 113 +++++++++--------- 2 files changed, 164 insertions(+), 55 deletions(-) create mode 100644 Tests/NextcloudUnitTests/MoveAndCopyTests.swift diff --git a/Tests/NextcloudUnitTests/MoveAndCopyTests.swift b/Tests/NextcloudUnitTests/MoveAndCopyTests.swift new file mode 100644 index 0000000000..bd674a472f --- /dev/null +++ b/Tests/NextcloudUnitTests/MoveAndCopyTests.swift @@ -0,0 +1,106 @@ +// +// MoveAndCopyTests.swift +// NextcloudTests +// +// Created by A200073704 on 05/06/23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// + +@testable import Nextcloud +import XCTest +import NextcloudKit + + + class MoveAndCopyTests: XCTestCase { + + var view : NCSelectCommandView? + var viewController : NCSelect? + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + let storyboard = UIStoryboard(name: "NCSelect", bundle: nil) + if let navigationController = storyboard.instantiateInitialViewController() as? UINavigationController { + let viewController = navigationController.topViewController as? NCSelect + + let _ = viewController?.view + viewController?.loadViewIfNeeded() + } + view = NCSelectCommandView() + + } + + override func setUp() { + super.setUp() + let nib = Bundle.main.loadNibNamed("NCSelectCommandViewCopyMove", owner: nil, options: nil) + view = nib?.first as? NCSelectCommandView + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + + viewController = nil + view = nil + + } + + func testCreateFolderButton() { + + let image: Void? = view?.createFolderButton?.setImage(UIImage(named: "addFolder")?.withTintColor(UIColor.label), for: .normal) + + XCTAssertNotNil(image) + } + + func testOverwriteSwitch() { + + let mySwitch = view?.overwriteSwitch + + XCTAssertNotNil(mySwitch) + + } + + func testCopyButton() { + + let copy = view?.copyButton + + XCTAssertNotNil(copy) + } + + + func testOverwriteSwitchAlwaysOn() { + + XCTAssertTrue(view?.overwriteSwitch?.isOn ?? false, "Overwrite Switch should always be on") + } + + func testCopyButtonandMoveButtonCondition() { + + // Disable copy and move + view?.copyButton?.isEnabled = false + view?.moveButton?.isEnabled = false + + // Creating a test item + let item = tableMetadata() + item.serverUrl = "serverUrl" // Set the serverUrl property of the item + + let items: [tableMetadata] = [item] + + // Update the items in the view controller + viewController?.items = items + + // Verify that the copy and move buttons are still disabled + XCTAssertFalse(view?.copyButton?.isEnabled ?? true, "Copy Button should remain disabled when items.first matches the condition") + XCTAssertFalse(view?.moveButton?.isEnabled ?? true, "Move Button should remain disabled when items.first matches the condition") + + // Enable copy and move + view?.copyButton?.isEnabled = true + view?.moveButton?.isEnabled = true + + // Update the items in the view controller + viewController?.items = [] // Empty items + + // Verify that the copyButton is still enabled + XCTAssertTrue(view?.copyButton?.isEnabled ?? false, "Copy Button should remain enabled when items.first doesn't match the condition") + XCTAssertTrue(view?.moveButton?.isEnabled ?? false, "Move Button should remain enabled when items.first doesn't match the condition") + } + +} diff --git a/iOSClient/Select/NCSelectCommandViewCopyMove.xib b/iOSClient/Select/NCSelectCommandViewCopyMove.xib index ddf3475d85..4941320594 100644 --- a/iOSClient/Select/NCSelectCommandViewCopyMove.xib +++ b/iOSClient/Select/NCSelectCommandViewCopyMove.xib @@ -1,9 +1,9 @@ - - + + - + @@ -11,115 +11,118 @@ - - + + - - + + - + - - + + - + - + - - - - - - - - - - - - + + + + + + + + + + + + + + - + - - - - - - + + + + + + - - - - - - - + + + + + + + + From d4031943c3bc076deafb514270053ba74f147288 Mon Sep 17 00:00:00 2001 From: TSI-amrutwaghmare <96108296+TSI-amrutwaghmare@users.noreply.github.com> Date: Fri, 12 Apr 2024 16:07:35 +0530 Subject: [PATCH 2/6] NMC 2157 - size lable upated after nextcloud 5.2.2 release --- iOSClient/Main/Collection Common/Cell/NCListCell.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/iOSClient/Main/Collection Common/Cell/NCListCell.swift b/iOSClient/Main/Collection Common/Cell/NCListCell.swift index 198b12be8d..8280e6acd6 100755 --- a/iOSClient/Main/Collection Common/Cell/NCListCell.swift +++ b/iOSClient/Main/Collection Common/Cell/NCListCell.swift @@ -260,6 +260,7 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP func writeInfoDateSize(date: NSDate, size: Int64) { labelInfo.text = NCUtility().getRelativeDateTitle(date as Date) labelSubinfo.text = NCUtilityFileSystem().transformedSize(size) +// labelSubinfo.text = "" } func setAccessibility(label: String, value: String) { From a929e16c5711868bf3601dd999715e437a62ff70 Mon Sep 17 00:00:00 2001 From: harshada-15-tsys Date: Fri, 11 Apr 2025 12:31:00 +0530 Subject: [PATCH 3/6] NMC 2157 - Move copy customisation chnages --- Nextcloud.xcodeproj/project.pbxproj | 8 ++++ .../Collection Common/Cell/NCListCell.swift | 44 ++++++++++++++++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index b24d42ac75..2fa3859186 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -90,6 +90,10 @@ AFCE353727E4ED7B00FEA6C2 /* NCShareCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */; }; AFCE353927E5DE0500FEA6C2 /* Shareable.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353827E5DE0400FEA6C2 /* Shareable.swift */; }; CB3666201AF7550816B5CD6A /* NCContextMenuComment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8932E90EC4278026D86CCCC9 /* NCContextMenuComment.swift */; }; + AFCE353927E5DE0500FEA6C2 /* NCShare+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */; }; + B52FAED32DA8F22F001AB1BD /* MoveAndCopyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FAED22DA8F22F001AB1BD /* MoveAndCopyTests.swift */; }; + C04E2F232A17BB4D001BAD85 /* FilesIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04E2F222A17BB4D001BAD85 /* FilesIntegrationTests.swift */; }; + D575039F27146F93008DC9DC /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extension.swift */; }; D5B6AA7827200C7200D49C24 /* NCActivityTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */; }; F310B1EF2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = F310B1EE2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift */; }; F31165022F9674A1009A1E37 /* AppIcon.icon in Resources */ = {isa = PBXBuildFile; fileRef = F31165012F9674A1009A1E37 /* AppIcon.icon */; }; @@ -1280,6 +1284,8 @@ AFCE353827E5DE0400FEA6C2 /* Shareable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shareable.swift; sourceTree = ""; }; B4C7A5B36D1ED178FB6B76CB /* NCContextMenuPlayerTracks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCContextMenuPlayerTracks.swift; sourceTree = ""; }; BB7697C94BA14450A0867940 /* NCContextMenuProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCContextMenuProfile.swift; sourceTree = ""; }; + AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCShare+Helper.swift"; sourceTree = ""; }; + B52FAED22DA8F22F001AB1BD /* MoveAndCopyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveAndCopyTests.swift; sourceTree = ""; }; C0046CDA2A17B98400D87C9D /* NextcloudUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NextcloudUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C04E2F202A17BB4D001BAD85 /* NextcloudIntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NextcloudIntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCActivityTableViewCell.swift; sourceTree = ""; }; @@ -2104,6 +2110,8 @@ children = ( F34BDB3B2F574A58007A222C /* BidiSafeFilenameTests.swift */, AA52EB452D42AC5A0089C348 /* Placeholder.swift */, + B52FAED22DA8F22F001AB1BD /* MoveAndCopyTests.swift */, + AF8ED1FB2757821000B8DBC4 /* NextcloudUnitTests.swift */, ); path = NextcloudUnitTests; sourceTree = ""; diff --git a/iOSClient/Main/Collection Common/Cell/NCListCell.swift b/iOSClient/Main/Collection Common/Cell/NCListCell.swift index 8280e6acd6..dc005e0451 100755 --- a/iOSClient/Main/Collection Common/Cell/NCListCell.swift +++ b/iOSClient/Main/Collection Common/Cell/NCListCell.swift @@ -93,6 +93,10 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP } func initCell() { + + imageItem.layer.cornerRadius = 6 + imageItem.layer.masksToBounds = true + accessibilityHint = nil accessibilityLabel = nil accessibilityValue = nil @@ -202,7 +206,6 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { let locationInButton = touch.location(in: buttonMore) let result = buttonMore.bounds.contains(locationInButton) - return result } @@ -240,27 +243,47 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP moreContainer.isHidden = false backgroundView = nil } + } + + func selected(_ status: Bool, isEditMode: Bool) { + // NMC-1190 - iOS - Files - Deleting files while files are still uploading won't delete properly : to fix this issue remove check for !metadata.isInTransfer in below line + guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId), !metadata.isInTransfer, !metadata.e2eEncrypted else { +// guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId), !metadata.e2eEncrypted else { + backgroundView = nil + separator.isHidden = false + imageSelect.isHidden = true + + return + } + if status { + var blurEffect: UIVisualEffect? var blurEffectView: UIView? - blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial)) - blurEffectView?.backgroundColor = .lightGray + if traitCollection.userInterfaceStyle == .dark { + blurEffect = UIBlurEffect(style: .dark) + blurEffectView = UIVisualEffectView(effect: blurEffect) + blurEffectView?.backgroundColor = .black + } else { + blurEffect = UIBlurEffect(style: .extraLight) + blurEffectView = UIVisualEffectView(effect: blurEffect) + blurEffectView?.backgroundColor = .lightGray + } blurEffectView?.frame = self.bounds blurEffectView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] imageSelect.image = NCImageCache.shared.getImageCheckedYes(color: color) backgroundView = blurEffectView + imageSelect.image = NCImageCache.images.checkedYes separator.isHidden = true } else { imageSelect.image = NCImageCache.shared.getImageCheckedNo(color: color) backgroundView = nil separator.isHidden = false } - } func writeInfoDateSize(date: NSDate, size: Int64) { - labelInfo.text = NCUtility().getRelativeDateTitle(date as Date) - labelSubinfo.text = NCUtilityFileSystem().transformedSize(size) -// labelSubinfo.text = "" + labelInfo.text = NCUtility().dateDiff(date as Date) + " · " + NCUtilityFileSystem().transformedSize(size) + labelSubinfo.text = "" } func setAccessibility(label: String, value: String) { @@ -372,6 +395,13 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP } } +protocol NCListCellDelegate: AnyObject { + func tapShareListItem(with ocId: String, ocIdTransfer: String, sender: Any) + func tapMoreListItem(with ocId: String, ocIdTransfer: String, namedButtonMore: String, image: UIImage?, sender: Any) + func longPressMoreListItem(with ocId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) + func longPressListItem(with ocId: String, ocIdTransfer: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) +} + // MARK: - List Layout class NCListLayout: UICollectionViewFlowLayout { From 23e5e4f2e8d0ce9d50c7796792236139cb6e625d Mon Sep 17 00:00:00 2001 From: harshada-15-tsys Date: Fri, 3 Oct 2025 11:56:17 +0530 Subject: [PATCH 4/6] NMC 2157 - Move copy customisation changes --- .../Collection Common/Cell/NCListCell.swift | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/iOSClient/Main/Collection Common/Cell/NCListCell.swift b/iOSClient/Main/Collection Common/Cell/NCListCell.swift index dc005e0451..9e53d8da01 100755 --- a/iOSClient/Main/Collection Common/Cell/NCListCell.swift +++ b/iOSClient/Main/Collection Common/Cell/NCListCell.swift @@ -45,6 +45,7 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP delegate?.openContextMenu(with: metadata, button: buttonMore, sender: self) /* preconfigure UIMenu with each metadata */ } } + var previewImg: UIImageView? { get { return imageItem } set { imageItem = newValue } @@ -62,17 +63,9 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP set { labelInfo = newValue } } - override var accessibilityIdentifier: String? { - get { - super.accessibilityIdentifier - } - set { - super.accessibilityIdentifier = newValue - - if let newValue { - buttonShared.accessibilityIdentifier = "\(newValue)/shareButton" - } - } + var fileSharedLabel: UILabel? { + get { return labelShared } + set { labelShared = newValue } } override func awakeFromNib() { @@ -96,6 +89,17 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP imageItem.layer.cornerRadius = 6 imageItem.layer.masksToBounds = true + imageStatus.image = nil + imageFavorite.image = nil + imageFavoriteBackground.isHidden = true + imageLocal.image = nil + labelTitle.text = "" + labelInfo.text = "" + labelSubinfo.text = "" + imageShared.image = nil + imageMore.image = nil + + // use entire cell as accessibility element accessibilityHint = nil accessibilityLabel = nil @@ -121,6 +125,7 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP imageItemLeftConstraint.constant = 10 separatorHeightConstraint.constant = 0.5 + titleInfoTrailingDefault() // Dynamic Type Font Configuration // @@ -190,7 +195,24 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP override func snapshotView(afterScreenUpdates afterUpdates: Bool) -> UIView? { return nil } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + updateConstraintsForCurrentDevice() + } + func updateConstraintsForCurrentDevice() { + if labelShared?.isHidden == false { + iPhoneLabelTitleTrailingConstraint.isActive = false + iPadLabelTitleTrailingConstraint.isActive = true + } else { + iPhoneLabelTitleTrailingConstraint.isActive = true + iPadLabelTitleTrailingConstraint.isActive = false + } +// iPhoneLabelTitleTrailingConstraint.isActive = UIDevice.current.userInterfaceIdiom == .pad ? false : true +// iPadLabelTitleTrailingConstraint.isActive = UIDevice.current.userInterfaceIdiom == .pad ? true : false + } + @IBAction func touchUpInsideShare(_ sender: Any) { delegate?.tapShareListItem(with: metadata, button: buttonShared, sender: sender) } @@ -282,7 +304,7 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP } func writeInfoDateSize(date: NSDate, size: Int64) { - labelInfo.text = NCUtility().dateDiff(date as Date) + " · " + NCUtilityFileSystem().transformedSize(size) + labelInfo.text = NCUtility().getRelativeDateTitle(date as Date) + " · " + NCUtilityFileSystem().transformedSize(size) labelSubinfo.text = "" } From 31c645d3fdbe32c786c6f4a2248d7479783b0a16 Mon Sep 17 00:00:00 2001 From: harshada-15-tsys Date: Tue, 16 Dec 2025 14:57:00 +0530 Subject: [PATCH 5/6] NMC 2157 - Move copy customisation changes --- .../Collection Common/Cell/NCListCell.swift | 87 ++++---------- .../Select/NCSelectCommandViewCopyMove.xib | 113 +++++++++--------- 2 files changed, 76 insertions(+), 124 deletions(-) diff --git a/iOSClient/Main/Collection Common/Cell/NCListCell.swift b/iOSClient/Main/Collection Common/Cell/NCListCell.swift index 9e53d8da01..ea24139737 100755 --- a/iOSClient/Main/Collection Common/Cell/NCListCell.swift +++ b/iOSClient/Main/Collection Common/Cell/NCListCell.swift @@ -17,6 +17,7 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP @IBOutlet weak var imageSelect: UIImageView! @IBOutlet weak var imageStatus: UIImageView! @IBOutlet weak var imageFavorite: UIImageView! +// @IBOutlet weak var imageFavoriteBackground: UIImageView! @IBOutlet weak var imageLocal: UIImageView! @IBOutlet weak var labelTitle: UILabel! @@ -63,9 +64,17 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP set { labelInfo = newValue } } - var fileSharedLabel: UILabel? { - get { return labelShared } - set { labelShared = newValue } + override var accessibilityIdentifier: String? { + get { + super.accessibilityIdentifier + } + set { + super.accessibilityIdentifier = newValue + + if let newValue { + buttonShared.accessibilityIdentifier = "\(newValue)/shareButton" + } + } } override func awakeFromNib() { @@ -81,26 +90,10 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP override func prepareForReuse() { super.prepareForReuse() - initCell() } func initCell() { - - imageItem.layer.cornerRadius = 6 - imageItem.layer.masksToBounds = true - imageStatus.image = nil - imageFavorite.image = nil - imageFavoriteBackground.isHidden = true - imageLocal.image = nil - labelTitle.text = "" - labelInfo.text = "" - labelSubinfo.text = "" - imageShared.image = nil - imageMore.image = nil - - // use entire cell as accessibility element - accessibilityHint = nil accessibilityLabel = nil accessibilityValue = nil @@ -111,6 +104,7 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP imageItem.layer.masksToBounds = true imageStatus.image = nil imageFavorite.image = nil +// imageFavoriteBackground.isHidden = true imageLocal.image = nil buttonShared.setImage(nil, for: .normal) @@ -195,24 +189,7 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP override func snapshotView(afterScreenUpdates afterUpdates: Bool) -> UIView? { return nil } - - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - updateConstraintsForCurrentDevice() - } - func updateConstraintsForCurrentDevice() { - if labelShared?.isHidden == false { - iPhoneLabelTitleTrailingConstraint.isActive = false - iPadLabelTitleTrailingConstraint.isActive = true - } else { - iPhoneLabelTitleTrailingConstraint.isActive = true - iPadLabelTitleTrailingConstraint.isActive = false - } -// iPhoneLabelTitleTrailingConstraint.isActive = UIDevice.current.userInterfaceIdiom == .pad ? false : true -// iPadLabelTitleTrailingConstraint.isActive = UIDevice.current.userInterfaceIdiom == .pad ? true : false - } - @IBAction func touchUpInsideShare(_ sender: Any) { delegate?.tapShareListItem(with: metadata, button: buttonShared, sender: sender) } @@ -265,47 +242,26 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP moreContainer.isHidden = false backgroundView = nil } - } - - func selected(_ status: Bool, isEditMode: Bool) { - // NMC-1190 - iOS - Files - Deleting files while files are still uploading won't delete properly : to fix this issue remove check for !metadata.isInTransfer in below line - guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId), !metadata.isInTransfer, !metadata.e2eEncrypted else { -// guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId), !metadata.e2eEncrypted else { - backgroundView = nil - separator.isHidden = false - imageSelect.isHidden = true - - return - } - if status { - var blurEffect: UIVisualEffect? var blurEffectView: UIView? - if traitCollection.userInterfaceStyle == .dark { - blurEffect = UIBlurEffect(style: .dark) - blurEffectView = UIVisualEffectView(effect: blurEffect) - blurEffectView?.backgroundColor = .black - } else { - blurEffect = UIBlurEffect(style: .extraLight) - blurEffectView = UIVisualEffectView(effect: blurEffect) - blurEffectView?.backgroundColor = .lightGray - } + blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial)) + blurEffectView?.backgroundColor = .lightGray blurEffectView?.frame = self.bounds blurEffectView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] imageSelect.image = NCImageCache.shared.getImageCheckedYes(color: color) backgroundView = blurEffectView - imageSelect.image = NCImageCache.images.checkedYes separator.isHidden = true } else { imageSelect.image = NCImageCache.shared.getImageCheckedNo(color: color) backgroundView = nil separator.isHidden = false } + } func writeInfoDateSize(date: NSDate, size: Int64) { - labelInfo.text = NCUtility().getRelativeDateTitle(date as Date) + " · " + NCUtilityFileSystem().transformedSize(size) - labelSubinfo.text = "" + labelInfo.text = NCUtility().getRelativeDateTitle(date as Date) + labelSubinfo.text = NCUtilityFileSystem().transformedSize(size) } func setAccessibility(label: String, value: String) { @@ -404,7 +360,7 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP } } } - + override func layoutSubviews() { super.layoutSubviews() // Keep the shadow path in sync with current bounds @@ -419,9 +375,8 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP protocol NCListCellDelegate: AnyObject { func tapShareListItem(with ocId: String, ocIdTransfer: String, sender: Any) - func tapMoreListItem(with ocId: String, ocIdTransfer: String, namedButtonMore: String, image: UIImage?, sender: Any) - func longPressMoreListItem(with ocId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) - func longPressListItem(with ocId: String, ocIdTransfer: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) + func tapMoreListItem(with ocId: String, ocIdTransfer: String, image: UIImage?, sender: Any) + func longPressListItem(with ocId: String, ocIdTransfer: String, gestureRecognizer: UILongPressGestureRecognizer) } // MARK: - List Layout diff --git a/iOSClient/Select/NCSelectCommandViewCopyMove.xib b/iOSClient/Select/NCSelectCommandViewCopyMove.xib index 4941320594..ddf3475d85 100644 --- a/iOSClient/Select/NCSelectCommandViewCopyMove.xib +++ b/iOSClient/Select/NCSelectCommandViewCopyMove.xib @@ -1,9 +1,9 @@ - - + + - + @@ -11,118 +11,115 @@ - - + + - - + + - + - - + + - + - + - - - - - - - - - - - - - - - + + + + + + + + + + + - + - - - - - - + + + + + + - - - - - - - - + + + + + + + From e0dd8bb623e6714250b3766c37576cd04d747242 Mon Sep 17 00:00:00 2001 From: harshada-15-tsys Date: Tue, 16 Jun 2026 18:59:08 +0530 Subject: [PATCH 6/6] NMC 2157 - Move copy customisation changes --- .../Collection Common/Cell/NCListCell.swift | 525 ++++++------------ 1 file changed, 166 insertions(+), 359 deletions(-) diff --git a/iOSClient/Main/Collection Common/Cell/NCListCell.swift b/iOSClient/Main/Collection Common/Cell/NCListCell.swift index ea24139737..12c305a283 100755 --- a/iOSClient/Main/Collection Common/Cell/NCListCell.swift +++ b/iOSClient/Main/Collection Common/Cell/NCListCell.swift @@ -2,66 +2,82 @@ // SPDX-FileCopyrightText: 2018 Marino Faggiana // SPDX-License-Identifier: GPL-3.0-or-later -import Foundation import UIKit -import NextcloudKit protocol NCListCellDelegate: AnyObject { func onMenuIntent(with metadata: tableMetadata?) - func openContextMenu(with metadata: tableMetadata?, button: UIButton, sender: Any) + func contextMenu(with metadata: tableMetadata?, button: UIButton, sender: Any) func tapShareListItem(with metadata: tableMetadata?, button: UIButton, sender: Any) } -class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainProtocol { +class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProtocol { @IBOutlet weak var imageItem: UIImageView! @IBOutlet weak var imageSelect: UIImageView! @IBOutlet weak var imageStatus: UIImageView! @IBOutlet weak var imageFavorite: UIImageView! -// @IBOutlet weak var imageFavoriteBackground: UIImageView! @IBOutlet weak var imageLocal: UIImageView! - @IBOutlet weak var labelTitle: UILabel! @IBOutlet weak var labelInfo: UILabel! - @IBOutlet weak var labelSubinfo: UILabel! @IBOutlet weak var labelInfoSeparator: UILabel! - @IBOutlet weak var tag1: PaddedAndBorderedLabel! - @IBOutlet weak var tag2: PaddedAndBorderedLabel! - @IBOutlet weak var tagMore: PaddedAndBorderedLabel! - @IBOutlet weak var labelExtension: UILabel! - + @IBOutlet weak var labelSubinfo: UILabel! + @IBOutlet weak var imageShared: UIImageView! @IBOutlet weak var buttonShared: UIButton! + @IBOutlet weak var imageMore: UIImageView! @IBOutlet weak var buttonMore: UIButton! - @IBOutlet weak var shareContainer: UIView! - @IBOutlet weak var moreContainer: UIView! @IBOutlet weak var separator: UIView! + @IBOutlet weak var tag0: UILabel! + @IBOutlet weak var tag1: UILabel! @IBOutlet weak var imageItemLeftConstraint: NSLayoutConstraint! @IBOutlet weak var separatorHeightConstraint: NSLayoutConstraint! + @IBOutlet weak var titleTrailingConstraint: NSLayoutConstraint! weak var delegate: NCListCellDelegate? - // Cell Protocol var metadata: tableMetadata? { didSet { - delegate?.openContextMenu(with: metadata, button: buttonMore, sender: self) /* preconfigure UIMenu with each metadata */ + delegate?.contextMenu(with: metadata, button: buttonMore, sender: self) /* preconfigure UIMenu with each metadata */ } } - var previewImg: UIImageView? { + var avatarImageView: UIImageView? { + return imageShared + } + var previewImageView: UIImageView? { get { return imageItem } set { imageItem = newValue } } - var localImg: UIImageView? { - get { return imageLocal } - set { imageLocal = newValue } + var title: UILabel? { + get { return labelTitle } + set { labelTitle = newValue } } - var statusImg: UIImageView? { + var info: UILabel? { + get { return labelInfo } + set { labelInfo = newValue } + } + var subInfo: UILabel? { + get { return labelSubinfo } + set { labelSubinfo = newValue } + } + var statusImageView: UIImageView? { get { return imageStatus } set { imageStatus = newValue } } - var infoLbl: UILabel? { - get { return labelInfo } - set { labelInfo = newValue } + var localImageView: UIImageView? { + get { return imageLocal } + set { imageLocal = newValue } + } + var favoriteImageView: UIImageView? { + get { return imageFavorite } + set { imageFavorite = newValue } + } + var shareImageView: UIImageView? { + get { return imageShared } + set { imageShared = newValue } + } + var separatorView: UIView? { + get { return separator } + set { separator = newValue } } override var accessibilityIdentifier: String? { @@ -104,86 +120,20 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP imageItem.layer.masksToBounds = true imageStatus.image = nil imageFavorite.image = nil -// imageFavoriteBackground.isHidden = true imageLocal.image = nil - - buttonShared.setImage(nil, for: .normal) - buttonShared.imageEdgeInsets = .zero - - buttonMore.setImage(nil, for: .normal) - buttonMore.menu = nil - buttonMore.showsMenuAsPrimaryAction = true - - shareContainer.isHidden = false - moreContainer.isHidden = false - - imageItemLeftConstraint.constant = 10 - separatorHeightConstraint.constant = 0.5 - titleInfoTrailingDefault() - - // Dynamic Type Font Configuration - // - // These labels use fonts generated by the custom UIFont helpers defined in - // the UIFont extension (e.g. `.callout()`, `.caption1()`). - // - // Those helpers wrap `UIFontMetrics` to provide Dynamic Type scaling while - // applying an upper bound to the maximum font size. This ensures: - // - // - The text respects the user's preferred accessibility size. - // - The UI layout remains stable and does not grow indefinitely. - // - // `adjustsFontForContentSizeCategory` is enabled to allow UIKit to - // automatically update the font when the user changes the Dynamic Type - // setting while the application is running. - // - // Without this flag, the label would keep the initially computed font size - // and would not react to content size category changes. - // - // In summary: - // - // UIFont helper: - // Defines how the font scales and its maximum size. - // - // adjustsFontForContentSizeCategory: - // Enables live updates when accessibility settings change. - // labelTitle.text = "" - labelTitle.font = .callout() - labelTitle.adjustsFontForContentSizeCategory = true - - labelExtension.text = "" - labelExtension.isHidden = true - labelExtension.font = .callout() - labelExtension.adjustsFontForContentSizeCategory = true - labelInfo.text = "" - labelInfo.font = .footnote() - labelInfo.adjustsFontForContentSizeCategory = true - - labelInfoSeparator.font = .footnote() - labelInfoSeparator.adjustsFontForContentSizeCategory = true - labelSubinfo.text = "" - labelSubinfo.font = .footnote() - labelSubinfo.adjustsFontForContentSizeCategory = true - + imageShared.image = nil + imageMore.image = nil + separatorHeightConstraint.constant = 0.5 + tag0.text = "" tag1.text = "" - tag2.text = "" - - tag1.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) - tag2.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) - - tag1.setContentHuggingPriority(.defaultLow, for: .horizontal) - tag2.setContentHuggingPriority(.defaultLow, for: .horizontal) - - tagMore.text = "" - tagMore.setContentCompressionResistancePriority(.required, for: .horizontal) - tagMore.setContentHuggingPriority(.required, for: .horizontal) - } + titleTrailingConstraint.constant = 90 - func setSharedAvatarImage(_ image: UIImage) { - buttonShared.setImage(image, for: .normal) - buttonShared.imageEdgeInsets = UIEdgeInsets(top: 4, left: 4, bottom: 4, right: 4) + contentView.bringSubviewToFront(buttonMore) + buttonMore.menu = nil + buttonMore.showsMenuAsPrimaryAction = true } override func snapshotView(afterScreenUpdates afterUpdates: Bool) -> UIView? { @@ -195,51 +145,60 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP } @objc private func handleTapObserver(_ g: UITapGestureRecognizer) { - let locationInButton = g.location(in: buttonMore) + let location = g.location(in: contentView) - if buttonMore.bounds.contains(locationInButton) { + if buttonMore.frame.contains(location) { delegate?.onMenuIntent(with: metadata) } } + // Allow the button to receive taps even with the long press gesture func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { - let locationInButton = touch.location(in: buttonMore) - let result = buttonMore.bounds.contains(locationInButton) - return result + let location = touch.location(in: contentView) + return buttonMore.frame.contains(location) + } + + func titleInfoTrailingFull() { + titleTrailingConstraint.constant = 10 } func setButtonMore(image: UIImage) { - buttonMore.setImage(image, for: .normal) + imageMore.image = image + } + + func hideButtonMore(_ status: Bool) { + imageMore.isHidden = status + buttonMore.isHidden = status } func hideButtonShare(_ status: Bool) { + imageShared.isHidden = status buttonShared.isHidden = status - shareContainer.isHidden = status } - func setButtonsHidden(_ hidden: Bool) { - buttonShared.isHidden = hidden - buttonMore.isHidden = hidden - shareContainer.isHidden = hidden - moreContainer.isHidden = hidden - } + func selected(_ status: Bool, isEditMode: Bool) { + // E2EE - remove encrypt folder selection + if let metadata = NCManageDatabase.shared.getMetadataFromOcId(self.metadata?.ocId), metadata.e2eEncrypted { + imageSelect.isHidden = true + } else { + imageSelect.isHidden = isEditMode ? false : true + } - func selected(_ status: Bool, isEditMode: Bool, color: UIColor) { if isEditMode { imageItemLeftConstraint.constant = 45 - imageSelect.isHidden = false +// imageSelect.isHidden = false + imageShared.isHidden = true + imageMore.isHidden = true buttonShared.isHidden = true buttonMore.isHidden = true - shareContainer.isHidden = true - moreContainer.isHidden = true accessibilityCustomActions = nil } else { imageItemLeftConstraint.constant = 10 - imageSelect.isHidden = true +// imageSelect.isHidden = true + imageShared.isHidden = false + imageMore.isHidden = false buttonShared.isHidden = false buttonMore.isHidden = false - shareContainer.isHidden = false - moreContainer.isHidden = false backgroundView = nil } if status { @@ -248,11 +207,11 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP blurEffectView?.backgroundColor = .lightGray blurEffectView?.frame = self.bounds blurEffectView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] - imageSelect.image = NCImageCache.shared.getImageCheckedYes(color: color) + imageSelect.image = NCImageCache.shared.getImageCheckedYes() backgroundView = blurEffectView separator.isHidden = true } else { - imageSelect.image = NCImageCache.shared.getImageCheckedNo(color: color) + imageSelect.image = NCImageCache.shared.getImageCheckedNo() backgroundView = nil separator.isHidden = false } @@ -269,69 +228,28 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP accessibilityValue = value } - func setTags(tags: [tableMetadataTag]) { - applyDefaultTagBorderStyle() - + func setTags(tags: [String]) { if tags.isEmpty { + tag0.isHidden = true tag1.isHidden = true - tag2.isHidden = true - tagMore.isHidden = true labelInfo.isHidden = false labelSubinfo.isHidden = false - labelInfoSeparator.isHidden = false +// labelInfoSeparator.isHidden = false } else { + tag0.isHidden = false + tag1.isHidden = true labelInfo.isHidden = true labelSubinfo.isHidden = true - labelInfoSeparator.isHidden = true +// labelInfoSeparator.isHidden = true - tag1.isHidden = true - tag2.isHidden = true - tagMore.isHidden = true - - if tags.count >= 1 { - let firstTag = tags[0] - tag1.isHidden = false - tag1.text = firstTag.name - applyTagBorderStyle(tag1, colorHex: firstTag.color) - } - if tags.count >= 2 { - let secondTag = tags[1] - tag2.isHidden = false - tag2.text = secondTag.name - applyTagBorderStyle(tag2, colorHex: secondTag.color) - } - if tags.count > 2 { - tagMore.isHidden = false - tagMore.text = "+\(tags.count - 2)" + if let tag = tags.first { + tag0.text = tag + if tags.count > 1 { + tag1.isHidden = false + tag1.text = "+\(tags.count - 1)" + } } } - - } - - private func applyDefaultTagBorderStyle() { - tag1.backgroundColor = .clear - tag2.backgroundColor = .clear - tagMore.backgroundColor = .clear - tag1.borderColor = .systemGray5 - tag2.borderColor = .systemGray5 - tagMore.borderColor = .systemGray5 - tag1.textColor = .systemGray - tag2.textColor = .systemGray - tagMore.textColor = .systemGray - tag1.setNeedsDisplay() - tag2.setNeedsDisplay() - tagMore.setNeedsDisplay() - } - - private func applyTagBorderStyle(_ label: PaddedAndBorderedLabel, colorHex: String?) { - guard let colorHex, let color = UIColor(hex: colorHex) else { - return - } - - label.backgroundColor = .clear - label.borderColor = color - label.textColor = color - label.setNeedsDisplay() } func setIconOutlines() { @@ -342,7 +260,7 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP if imageFavorite.image != nil { let outlineView = UIImageView() outlineView.translatesAutoresizingMaskIntoConstraints = false - outlineView.image = UIImage(systemName: "star") + outlineView.image = UIImage(systemName: "star.fill") outlineView.preferredSymbolConfiguration = UIImage.SymbolConfiguration(pointSize: 16, weight: .thin) outlineView.tintColor = .systemBackground @@ -359,8 +277,9 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP view.removeFromSuperview() } } + } - + override func layoutSubviews() { super.layoutSubviews() // Keep the shadow path in sync with current bounds @@ -373,12 +292,6 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellMainP } } -protocol NCListCellDelegate: AnyObject { - func tapShareListItem(with ocId: String, ocIdTransfer: String, sender: Any) - func tapMoreListItem(with ocId: String, ocIdTransfer: String, image: UIImage?, sender: Any) - func longPressListItem(with ocId: String, ocIdTransfer: String, gestureRecognizer: UILongPressGestureRecognizer) -} - // MARK: - List Layout class NCListLayout: UICollectionViewFlowLayout { @@ -418,181 +331,75 @@ class NCListLayout: UICollectionViewFlowLayout { } } -#if !EXTENSION -extension NCCollectionViewCommon { - func listCell(cell: NCListCell, indexPath: IndexPath, metadata: tableMetadata) -> NCListCell { - defer { - let capabilities = NCNetworking.shared.capabilities[session.account] ?? NKCapabilities.Capabilities() - if !metadata.isSharable() || (!capabilities.fileSharingApiEnabled && !capabilities.filesComments && capabilities.activity.isEmpty) { - cell.hideButtonShare(true) - } - } - var isShare = false - var isMounted = false - var a11yValues: [String] = [] - let existsImagePreview = utilityFileSystem.fileProviderStorageImageExists(metadata.ocId, etag: metadata.etag, userId: metadata.userId, urlBase: metadata.urlBase) - - // CONTENT MODE - cell.previewImg?.layer.borderWidth = 0 - - if existsImagePreview && layoutForView?.layout != global.layoutPhotoRatio { - cell.previewImg?.contentMode = .scaleAspectFill - } else { - cell.previewImg?.contentMode = .scaleAspectFit - } - - guard let metadata = self.dataSource.getMetadata(indexPath: indexPath) else { - return cell - } - - if let metadataFolder { - isShare = metadata.permissions.contains(NCMetadataPermissions.permissionShared) && !metadataFolder.permissions.contains(NCMetadataPermissions.permissionShared) - isMounted = metadata.permissions.contains(NCMetadataPermissions.permissionMounted) && !metadataFolder.permissions.contains(NCMetadataPermissions.permissionMounted) - } - - if isSearchingMode { - if metadata.name == global.appName { - cell.labelInfo?.text = NSLocalizedString("_in_", comment: "") + " " + utilityFileSystem.getPath(path: metadata.path, user: metadata.user) - } else { - cell.labelInfo?.text = metadata.subline - } - cell.labelSubinfo?.isHidden = true - } else if !metadata.sessionError.isEmpty, metadata.status != global.metadataStatusNormal { - cell.labelSubinfo?.isHidden = false - cell.labelInfo?.text = metadata.sessionError - } else { - cell.labelSubinfo?.isHidden = false - cell.writeInfoDateSize(date: metadata.date, size: metadata.size) - } - - cell.setBidiSafeFilename(metadata.fileNameView, isDirectory: metadata.directory, titleLabel: cell.labelTitle, extensionLabel: cell.labelExtension) - - // Accessibility [shared] if metadata.ownerId != appDelegate.userId, appDelegate.account == metadata.account { - if metadata.ownerId != metadata.userId { - a11yValues.append(NSLocalizedString("_shared_with_you_by_", comment: "") + " " + metadata.ownerDisplayName) - } - - if metadata.directory { - cellMainDirectory(cell: cell, metadata: metadata, isShare: isShare, isMounted: isMounted) - } else { - cellMainFile(cell: cell, metadata: metadata, a11yValues: &a11yValues) - } - - // image Favorite - if metadata.favorite { - cell.imageFavorite?.image = imageCache.getImageFavorite() - a11yValues.append(NSLocalizedString("_favorite_short_", comment: "")) - } - - // Share button image (SF Symbol) - if isShare { - cell.buttonShared.setImage(imageCache.getImageShared(), for: .normal) - } else if !metadata.shareType.isEmpty { - metadata.shareType.contains(NKShare.ShareType.publicLink.rawValue) ? - (cell.buttonShared.setImage(imageCache.getImageShareByLink(), for: .normal)) : - (cell.buttonShared.setImage(imageCache.getImageShared(), for: .normal)) - } else { - cell.buttonShared.setImage(imageCache.getImageCanShare(), for: .normal) - } - - // Button More - if metadata.lock == true { - cell.setButtonMore(image: imageCache.getImageButtonMoreLock()) - a11yValues.append(String(format: NSLocalizedString("_locked_by_", comment: ""), metadata.lockOwnerDisplayName)) - } else { - cell.setButtonMore(image: imageCache.getImageButtonMore()) - } - - // Status - cellMainStatus(cell: cell, metadata: metadata, a11yValues: &a11yValues) - - // AVATAR - if !metadata.ownerId.isEmpty, metadata.ownerId != metadata.userId { - let fileName = NCSession.shared.getFileName(urlBase: metadata.urlBase, user: metadata.ownerId) - if let image = NCImageCache.shared.getImageCache(key: fileName) { - cell.setSharedAvatarImage(image) - } else { - self.database.getImageAvatarLoaded(fileName: fileName) { image, tblAvatar in - if let image { - cell.setSharedAvatarImage(image) - NCImageCache.shared.addImageCache(image: image, key: fileName) - } else { - let image = self.utility.loadUserImage(for: metadata.ownerId, displayName: metadata.ownerDisplayName, urlBase: metadata.urlBase) - cell.setSharedAvatarImage(image) - } - - if !(tblAvatar?.loaded ?? false), - self.networking.downloadAvatarQueue.operations.filter({ ($0 as? NCOperationDownloadAvatar)?.fileName == fileName }).isEmpty { - self.networking.downloadAvatarQueue.addOperation(NCOperationDownloadAvatar(user: metadata.ownerId, fileName: fileName, account: metadata.account, view: self.collectionView)) - } - } - } - } - - // URL - if metadata.classFile == NKTypeClassFile.url.rawValue { - cell.imageLocal.image = nil - cell.setButtonsHidden(true) - } - - // Separator - if collectionView.numberOfItems(inSection: indexPath.section) == indexPath.row + 1 || isSearchingMode { - cell.separator?.isHidden = true - } else { - cell.separator?.isHidden = false - } - - // Edit mode - if fileSelect.contains(metadata.ocId) { - cell.selected(true, isEditMode: isEditMode, color: NCBrandColor.shared.getElement(account: session.account)) - a11yValues.append(NSLocalizedString("_selected_", comment: "")) - } else { - cell.selected(false, isEditMode: isEditMode, color: NCBrandColor.shared.getElement(account: session.account)) - } - - // Accessibility - cell.setAccessibility(label: metadata.fileNameView + ", " + (cell.labelInfo?.text ?? "") + (cell.labelSubinfo?.text ?? ""), value: a11yValues.joined(separator: ", ")) - - // Color string find in search - cell.labelTitle?.textColor = NCBrandColor.shared.textColor - cell.labelExtension?.textColor = NCBrandColor.shared.textColor - - if isSearchingMode, - let searchResultStore, - !searchResultStore.isEmpty, - let title = cell.labelTitle?.text { - let attributedString = NSMutableAttributedString(string: title) - let nsTitle = title as NSString - let range = nsTitle.range(of: searchResultStore, options: [.caseInsensitive]) - let color = NCBrandColor.shared.getElement(account: session.account) - - if range.location != NSNotFound, - NSMaxRange(range) <= nsTitle.length { - attributedString.addAttribute(.foregroundColor, value: color, range: range) - } - - cell.labelTitle?.attributedText = attributedString - } - - // TAGS - cell.setTags(tags: Array(metadata.tags)) - - // SearchingMode - TAG Separator Hidden - if isSearchingMode { - cell.labelInfoSeparator.isHidden = true - } - - // Hide buttons - if metadata.name != global.appName { - cell.setButtonsHidden(true) - } - - cell.setIconOutlines() - - // Obligatory here, at the end !! - cell.metadata = metadata - - return cell - } -} -#endif +//class BidiFilenameLabel: UILabel { +// var fullFilename: String = "" +// +// var isFolder: Bool = false +// +// var isRTL: Bool = false +// +// override init(frame: CGRect) { +// super.init(frame: frame) +// } +// +// required init?(coder: NSCoder) { +// super.init(coder: coder) +// } +// +// override func layoutSubviews() { +// super.layoutSubviews() +// updateText() +// } +// +// private func updateText() { +// guard !fullFilename.isEmpty else { +// self.text = "" +// return +// } +// +// let availableWidth = bounds.width +// guard availableWidth > 0 else { return } +// +// let isRTL = UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) == .rightToLeft +// let sanitizedFilename = fullFilename.sanitizeForBidiCharacters(isFolder: isFolder, isRTL: isRTL) +// +// let nsFilename = sanitizedFilename as NSString +// let ext = nsFilename.pathExtension +// let base = nsFilename.deletingPathExtension +// +// let dotExt = ext.isEmpty ? "" : "." + ext +// let truncatedBase = truncateBase(base: base, dotExt: dotExt, maxWidth: availableWidth, font: font ?? UIFont.systemFont(ofSize: 17)) +// +// self.text = sanitizedFilename.replacingOccurrences(of: base, with: truncatedBase) +// } +// +// private func truncateBase(base: String, dotExt: String, maxWidth: CGFloat, font: UIFont) -> String { +// let extWidth = (dotExt as NSString).size(withAttributes: [.font: font]).width +// +// if (base as NSString).size(withAttributes: [.font: font]).width + extWidth <= maxWidth { +// return base +// } +// +// let characters = Array(base) +// var low = 0 +// var high = characters.count +// var result = "" +// +// while low <= high { +// let mid = (low + high) / 2 +// let prefixCount = mid / 2 +// let suffixCount = mid - prefixCount +// let finalString = String(characters.prefix(prefixCount)) + "…" + String(characters.suffix(suffixCount)) +// let finalStringWidth = (finalString as NSString).size(withAttributes: [.font: font]).width + extWidth +// +// if finalStringWidth <= maxWidth { +// result = finalString +// low = mid + 1 +// } else { +// high = mid - 1 +// } +// } +// +// return result +// } +//}