diff --git a/Brand/NCBrand.swift b/Brand/NCBrand.swift index b5e4c39a11..b6ff3ab070 100755 --- a/Brand/NCBrand.swift +++ b/Brand/NCBrand.swift @@ -196,6 +196,18 @@ class NCBrandColor: NSObject { return UIColor(red: 0.0 / 255.0, green: 199.0 / 255.0, blue: 190.0 / 255.0, alpha: 1.0) } } + + @objc public var iconColor: UIColor{ + if #available(iOS 13.0, *) { + if UITraitCollection.current.userInterfaceStyle == .dark { + return UIColor(displayP3Red: 204.0/255.0, green: 204.0/255.0, blue: 204.0/255.0, alpha: 1.0) + }else { + return UIColor(red: 38.0/255.0, green: 38.0/255.0, blue: 38.0/255.0, alpha: 1.0) + } + } else { + return UIColor(red: 38.0/255.0, green: 38.0/255.0, blue: 38.0/255.0, alpha: 1.0) + } + } override init() { brand = customer @@ -365,4 +377,50 @@ class NCBrandColor: NSObject { let palette3 = mixPalette(steps: steps, color1: blue, color2: red) return palette1 + palette2 + palette3 } + + @objc public var notificationAction: UIColor { + return UIColor(red: 0/255.0, green: 153/255.0, blue: 255/255.0, alpha: 1.0) + } + + @objc public var secondarySystemGroupedBackground: UIColor = UIColor.secondarySystemGroupedBackground + @objc public var label: UIColor = UIColor.label + @objc public var backgroundForm: UIColor = UIColor(red: 244.0/255.0, green: 244.0/255.0, blue: 244.0/255.0, alpha: 1.0) + @objc public let graySoft: UIColor = UIColor(red: 162.0/255.0, green: 162.0/255.0, blue: 162.0/255.0, alpha: 0.5) + @objc public let systemGray4: UIColor = UIColor.systemGray4 + @objc public let systemBackground: UIColor = UIColor.systemBackground + @objc public let textInfo: UIColor = UIColor(red: 153.0/255.0, green: 153.0/255.0, blue: 153.0/255.0, alpha: 1.0) + @objc public let systemGray: UIColor = UIColor.systemGray + @objc public let customerDarkGrey: UIColor = UIColor(red: 38.0/255.0, green: 38.0/255.0, blue: 38.0/255.0, alpha: 1.0) + @objc public var fileFolderName: UIColor = UIColor(displayP3Red: 102.0/255.0, green: 102.0/255.0, blue: 102.0/255.0, alpha: 1.0) + @objc public let optionItem: UIColor = UIColor(red: 178.0/255.0, green: 178.0/255.0, blue: 178.0/255.0, alpha: 1.0) + @objc public var singleTitleColorButton: UIColor = UIColor(red: 25.0/255.0, green: 25.0/255.0, blue: 25.0/255.0, alpha: 1.0) + @objc public var shareCellTitleColor: UIColor = UIColor(displayP3Red: 242.0/255.0, green: 242.0/255.0, blue: 242.0/255.0, alpha: 1.0) + @objc public var gray60: UIColor { + if UITraitCollection.current.userInterfaceStyle == .dark { + return UIColor(red: 178.0/255.0, green: 178.0/255.0, blue: 178.0/255.0, alpha: 1.0) + } else { + return UIColor(red: 102.0/255.0, green: 102.0/255.0, blue: 102.0/255.0, alpha: 1.0) + } + } + @objc public var systemGray2: UIColor = UIColor.systemGray2 + @objc public var shareByEmailTextColor: UIColor = UIColor(displayP3Red: 13.0/255.0, green: 57.0/255.0, blue: 223.0/255.0, alpha: 1.0) + @objc public var memoryConsuptionBackground: UIColor { + if UITraitCollection.current.userInterfaceStyle == .dark { + return UIColor(red: 25.0/255.0, green: 25.0/255.0, blue: 25.0/255.0, alpha: 1.0) + } else { + return UIColor(red: 244.0/255.0, green: 244.0/255.0, blue: 244.0/255.0, alpha: 1.0) + } + } + @objc public var nmcGray0: UIColor{ + if UITraitCollection.current.userInterfaceStyle == .dark { + return UIColor(displayP3Red: 242.0/255.0, green: 242.0/255.0, blue: 242.0/255.0, alpha: 1.0) + }else { + return UIColor(red: 19.0/255.0, green: 19.0/255.0, blue: 19.0/255.0, alpha: 1.0) + } + } + @objc public var commonViewInfoText: UIColor = UIColor(displayP3Red: 102.0/255.0, green: 102.0/255.0, blue: 102.0/255.0, alpha: 1.0) + @objc public let progressColorGreen60: UIColor = UIColor(red: 115.0/255.0, green: 195.0/255.0, blue: 84.0/255.0, alpha: 1.0) + @objc public var seperatorRename: UIColor = UIColor(red: 235.0/255.0, green: 235.0/255.0, blue: 235.0/255.0, alpha: 1.0) + @objc public let gray: UIColor = UIColor(red: 104.0/255.0, green: 104.0/255.0, blue: 104.0/255.0, alpha: 1.0) + @objc public var nmcIconSharedWithMe: UIColor = UIColor(displayP3Red: 0.0/255.0, green: 153.0/255.0, blue: 255.0/255.0, alpha: 1.0) } diff --git a/Tests/NextcloudUnitTests/SharingTest.swift b/Tests/NextcloudUnitTests/SharingTest.swift new file mode 100644 index 0000000000..66d94dbfbb --- /dev/null +++ b/Tests/NextcloudUnitTests/SharingTest.swift @@ -0,0 +1,232 @@ +// +// SharingTest.swift +// NextcloudTests +// +// Created by A200020526 on 07/06/23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// + +import XCTest +@testable import Nextcloud +final class SharingTest: XCTestCase { + + var button: UIButton? + var ncShare: NCShare? + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + super.setUp() + button = UIButton() + ncShare = NCShare() + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + button = nil + ncShare = nil + super.tearDown() + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + + + //Date exntesion test case + func testTomorrow() { + let tomorrow = Date.tomorrow + let expectedTomorrow = Calendar.current.date(byAdding: .day, value: 1, to: Date())! + XCTAssertEqual(tomorrow.extendedIso8601String, expectedTomorrow.extendedIso8601String, "Tomorrow date should be correct.") + } + func testToday() { + let today = Date.today + let currentDate = Date() + XCTAssertEqual(today.extendedIso8601String, currentDate.extendedIso8601String, "Today date should be correct.") + } + + func testDayAfter() { + let date = Date() + let dayAfter = date.dayAfter + let expectedDayAfter = Calendar.current.date(byAdding: .day, value: 1, to: date)! + XCTAssertEqual(dayAfter.extendedIso8601String, expectedDayAfter.extendedIso8601String, "Day after date should be correct.") + } + + //Date Formatter extension Test Case + func testShareExpDate() { + let dateFormatter = DateFormatter.shareExpDate + + XCTAssertEqual(dateFormatter.formatterBehavior, .behavior10_4, "Formatter behavior should be correct.") + XCTAssertEqual(dateFormatter.dateStyle, .medium, "Date style should be correct.") + XCTAssertEqual(dateFormatter.dateFormat, NCShareAdvancePermission.displayDateFormat, "Date format should be correct.") + } + + //Button Extension test case + func testSetBackgroundColor() { + // Arrange + let color = UIColor.red + let state: UIControl.State = .normal + + // Act + button?.setBackgroundColor(color, for: state) + + // Assert + XCTAssertNotNil(button?.currentBackgroundImage, "Button background image not nil") + } + + func testSetBackgroundColorForDifferentStates() { + // Arrange + + let selectedColor = UIColor.green + + // Act + button?.isSelected = true + button?.setBackgroundColor(selectedColor, for: .selected) + + // Assert + XCTAssertNotNil(button?.currentBackgroundImage, "Button background image not nil") + button?.isSelected = false + XCTAssertNil(button?.currentBackgroundImage,"Button background image will be nil") + button?.isHighlighted = true + XCTAssertNil(button?.currentBackgroundImage, "Button background image will be nil") + } + + //UIView extension shadow test case + func testAddShadowWithLocation() { + // Create a UIView instance + let view = UIView() + + // Set the shadow with bottom location + view.addShadow(location: .bottom, height: 2, color: .red, opacity: 0.4, radius: 2) + + // Verify that the shadow offset is set correctly for the bottom location + let bottomShadowOffset = view.layer.shadowOffset + XCTAssertEqual(bottomShadowOffset, CGSize(width: 0, height: 2), "Shadow offset not set correctly for bottom location") + + // Verify that the shadow color is set correctly + let shadowColor = view.layer.shadowColor + XCTAssertEqual(shadowColor, UIColor.red.cgColor, "Shadow color not set correctly") + + // Verify that the shadow opacity is set correctly + let shadowOpacity = view.layer.shadowOpacity + XCTAssertEqual(shadowOpacity, 0.4, "Shadow opacity not set correctly") + + // Verify that the shadow radius is set correctly + let shadowRadius = view.layer.shadowRadius + XCTAssertEqual(shadowRadius, 2.0, "Shadow radius not set correctly") + } + + func testAddShadowWithOffset() { + // Create a UIView instance + let view = UIView() + + // Set the shadow with a custom offset + view.addShadow(offset: CGSize(width: 0, height: -4), color: .blue, opacity: 0.6, radius: 3) + + // Verify that the shadow offset is set correctly + let shadowOffset = view.layer.shadowOffset + XCTAssertEqual(shadowOffset, CGSize(width: 0, height: -4), "Shadow offset not set correctly") + + // Verify that the shadow color is set correctly + let shadowColor = view.layer.shadowColor + XCTAssertEqual(shadowColor, UIColor.blue.cgColor, "Shadow color not set correctly") + + // Verify that the shadow opacity is set correctly + let shadowOpacity = view.layer.shadowOpacity + XCTAssertEqual(shadowOpacity, 0.6, "Shadow opacity not set correctly") + + // Verify that the shadow radius is set correctly + let shadowRadius = view.layer.shadowRadius + XCTAssertEqual(shadowRadius, 3.0, "Shadow radius not set correctly") + } + + func testAddShadowForLocation() { + // Create a UIView instance + let view = UIView() + + // Add shadow to the bottom + view.addShadow(location: .bottom, color: UIColor.black) + + // Verify that the shadow properties are set correctly for the bottom location + XCTAssertEqual(view.layer.shadowOffset, CGSize(width: 0, height: 2), "Shadow offset not set correctly for bottom location") + XCTAssertEqual(view.layer.shadowColor, UIColor.black.cgColor, "Shadow color not set correctly for bottom location") + XCTAssertEqual(view.layer.shadowOpacity, 0.4, "Shadow opacity not set correctly for bottom location") + XCTAssertEqual(view.layer.shadowRadius, 2.0, "Shadow radius not set correctly for bottom location") + + // Add shadow to the top + view.addShadow(location: .top) + + // Verify that the shadow properties are set correctly for the top location + XCTAssertEqual(view.layer.shadowOffset, CGSize(width: 0, height: -2), "Shadow offset not set correctly for top location") + XCTAssertEqual(view.layer.shadowColor, NCBrandColor.shared.customerDarkGrey.cgColor, "Shadow color not set correctly for top location") + XCTAssertEqual(view.layer.shadowOpacity, 0.4, "Shadow opacity not set correctly for top location") + XCTAssertEqual(view.layer.shadowRadius, 2.0, "Shadow radius not set correctly for top location") + } + + func testAddShadowForOffset() { + // Create a UIView instance + let view = UIView() + + // Add shadow with custom offset + view.addShadow(offset: CGSize(width: 2, height: 2)) + + // Verify that the shadow properties are set correctly for the custom offset + XCTAssertEqual(view.layer.shadowOffset, CGSize(width: 2, height: 2), "Shadow offset not set correctly for custom offset") + XCTAssertEqual(view.layer.shadowColor, UIColor.black.cgColor, "Shadow color not set correctly for custom offset") + XCTAssertEqual(view.layer.shadowOpacity, 0.5, "Shadow opacity not set correctly for custom offset") + XCTAssertEqual(view.layer.shadowRadius, 5.0, "Shadow radius not set correctly for custom offset") + } + + + func testHasUploadPermission() { + // Create an instance of NCShare + let share = NCShare() + + // Define the input parameters + let tableShareWithUploadPermission = tableShare() + tableShareWithUploadPermission.permissions = NCGlobal.shared.permissionMaxFileShare + + let tableShareWithoutUploadPermission = tableShare() + tableShareWithoutUploadPermission.permissions = NCGlobal.shared.permissionReadShare + + // Call the hasUploadPermission function + let hasUploadPermission1 = share.hasUploadPermission(tableShare: tableShareWithUploadPermission) + let hasUploadPermission2 = share.hasUploadPermission(tableShare: tableShareWithoutUploadPermission) + + // Verify the results + XCTAssertTrue(hasUploadPermission1, "hasUploadPermission returned false for a tableShare with upload permission") + XCTAssertFalse(hasUploadPermission2, "hasUploadPermission returned true for a tableShare without upload permission") + } + + func testGetImageShareType() { + let sut = NCShareCommon() // Replace with the actual class containing the getImageShareType function + + // Test case 1: SHARE_TYPE_USER + let shareType1 = sut.SHARE_TYPE_USER + let result1 = sut.getImageShareType(shareType: shareType1) + XCTAssertEqual(result1, UIImage(named: "shareTypeEmail")?.imageColor(NCBrandColor.shared.label)) + + // Test case 2: SHARE_TYPE_GROUP + let shareType2 = sut.SHARE_TYPE_GROUP + let result2 = sut.getImageShareType(shareType: shareType2) + XCTAssertEqual(result2, UIImage(named: "shareTypeGroup")?.imageColor(NCBrandColor.shared.label)) + + // Test case 3: SHARE_TYPE_LINK + let shareType3 = sut.SHARE_TYPE_LINK + let result3 = sut.getImageShareType(shareType: shareType3) + XCTAssertEqual(result3, UIImage(named: "shareTypeLink")?.imageColor(NCBrandColor.shared.label)) + + // Test case 4: SHARE_TYPE_EMAIL (with isDropDown=false) + let shareType4 = sut.SHARE_TYPE_EMAIL + let result4 = sut.getImageShareType(shareType: shareType4) + XCTAssertEqual(result4, UIImage(named: "shareTypeUser")?.imageColor(NCBrandColor.shared.label)) + + // Test case 5: SHARE_TYPE_EMAIL (with isDropDown=true) + let shareType5 = sut.SHARE_TYPE_EMAIL + let isDropDown5 = true + let result5 = sut.getImageShareType(shareType: shareType5, isDropDown: isDropDown5) + XCTAssertEqual(result5, UIImage(named: "email")?.imageColor(NCBrandColor.shared.label)) + } +} diff --git a/iOSClient/Data/NCManageDatabase+Share.swift b/iOSClient/Data/NCManageDatabase+Share.swift index 63071c9cce..0db0ef12c7 100644 --- a/iOSClient/Data/NCManageDatabase+Share.swift +++ b/iOSClient/Data/NCManageDatabase+Share.swift @@ -72,6 +72,13 @@ class tableShareV2: Object { override static func primaryKey() -> String { return "primaryKey" } + + func setPermission(value: Int) { + let realm = try! Realm() + try! realm.write { + permissions = value + } + } } extension NCManageDatabase { @@ -253,6 +260,24 @@ extension NCManageDatabase { NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)") } } + + /// Delete shares of specific file + /// - Parameters: + /// - account: account url for specific user + /// - filePath: file path of media which shares need to delete + func deleteTableShare(account: String, filePath: String) { + + do { + let realm = try Realm() + + try realm.write { + let result = realm.objects(tableShare.self).filter("account == %@ AND path == %@", account, "/"+filePath) + realm.delete(result) + } + } catch let error as NSError { + NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)") + } + } // There is currently only one share attribute “download” from the scope “permissions”. This attribute is only valid for user and group shares, not for public link shares. func setAttibuteDownload(state: Bool) -> String? { diff --git a/iOSClient/Extensions/DateFormatter+Extension.swift b/iOSClient/Extensions/DateFormatter+Extension.swift index aa126ce786..ef1060864d 100644 --- a/iOSClient/Extensions/DateFormatter+Extension.swift +++ b/iOSClient/Extensions/DateFormatter+Extension.swift @@ -28,6 +28,16 @@ extension DateFormatter { let dateFormatter = DateFormatter() dateFormatter.formatterBehavior = .behavior10_4 dateFormatter.dateStyle = .medium + dateFormatter.dateFormat = NCShareAdvancePermission.displayDateFormat return dateFormatter }() } + + +extension Date { + static var tomorrow: Date { return Date().dayAfter } + static var today: Date {return Date()} + var dayAfter: Date { + return Calendar.current.date(byAdding: .day, value: 1, to: Date())! + } +} diff --git a/iOSClient/Extensions/UIButton+Extension.swift b/iOSClient/Extensions/UIButton+Extension.swift new file mode 100644 index 0000000000..89c7ed2596 --- /dev/null +++ b/iOSClient/Extensions/UIButton+Extension.swift @@ -0,0 +1,22 @@ +// +// UIButton+Extension.swift +// Nextcloud +// +// Created by A200020526 on 30/05/23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// + +import UIKit + +extension UIButton { + + func setBackgroundColor(_ color: UIColor, for forState: UIControl.State) { + UIGraphicsBeginImageContext(CGSize(width: 1, height: 1)) + UIGraphicsGetCurrentContext()!.setFillColor(color.cgColor) + UIGraphicsGetCurrentContext()!.fill(CGRect(x: 0, y: 0, width: 1, height: 1)) + let colorImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + self.setBackgroundImage(colorImage, for: forState) + } +} + diff --git a/iOSClient/Extensions/UIImage+Extension.swift b/iOSClient/Extensions/UIImage+Extension.swift index 23d4b4e259..0c31752d27 100644 --- a/iOSClient/Extensions/UIImage+Extension.swift +++ b/iOSClient/Extensions/UIImage+Extension.swift @@ -141,7 +141,18 @@ extension UIImage { return newImage } - + + func imageColor(_ color: UIColor) -> UIImage { + if #available(iOS 13.0, *) { + return self.withTintColor(color, renderingMode: .alwaysOriginal) + } else { + return UIGraphicsImageRenderer(size: size, format: imageRendererFormat).image { _ in + color.set() + withRenderingMode(.alwaysTemplate).draw(at: .zero) + } + } + } + func isEqualToImage(image: UIImage?) -> Bool { if image == nil { return false } let data1: NSData = self.pngData()! as NSData diff --git a/iOSClient/Extensions/UIToolbar+Extension.swift b/iOSClient/Extensions/UIToolbar+Extension.swift index 53e63fca1b..7ea64fe36e 100644 --- a/iOSClient/Extensions/UIToolbar+Extension.swift +++ b/iOSClient/Extensions/UIToolbar+Extension.swift @@ -57,6 +57,21 @@ extension UIToolbar { ]) return view } + + static func doneToolbar(completion: @escaping () -> Void) -> UIToolbar { + let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50)) + doneToolbar.barStyle = .default + + let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) + let done: UIBarButtonItem = UIBarButtonItem(title: NSLocalizedString("_done_", comment: ""), style: .done) { + completion() + } + let items = [flexSpace, done] + doneToolbar.items = items + doneToolbar.sizeToFit() + return doneToolbar + } + } // https://stackoverflow.com/a/67985180/9506784 diff --git a/iOSClient/Extensions/UIView+Extension.swift b/iOSClient/Extensions/UIView+Extension.swift index 52d184e0e2..a938f5cc35 100644 --- a/iOSClient/Extensions/UIView+Extension.swift +++ b/iOSClient/Extensions/UIView+Extension.swift @@ -24,6 +24,11 @@ import Foundation import UIKit +enum VerticalLocation: String { + case bottom + case top +} + extension UIView { // Source @@ -45,4 +50,21 @@ extension UIView { hiddenView.fillSuperview() hiddenView.addSubview(view) } + + func addShadow(location: VerticalLocation, height: CGFloat = 2, color: UIColor = NCBrandColor.shared.customerDarkGrey, opacity: Float = 0.4, radius: CGFloat = 2) { + switch location { + case .bottom: + addShadow(offset: CGSize(width: 0, height: height), color: color, opacity: opacity, radius: radius) + case .top: + addShadow(offset: CGSize(width: 0, height: -height), color: color, opacity: opacity, radius: radius) + } + } + + func addShadow(offset: CGSize, color: UIColor = .black, opacity: Float = 0.5, radius: CGFloat = 5.0) { + self.layer.masksToBounds = false + self.layer.shadowColor = color.cgColor + self.layer.shadowOffset = offset + self.layer.shadowOpacity = opacity + self.layer.shadowRadius = radius + } } diff --git a/iOSClient/Images.xcassets/calender.imageset/Contents.json b/iOSClient/Images.xcassets/calender.imageset/Contents.json new file mode 100644 index 0000000000..8f3e754211 --- /dev/null +++ b/iOSClient/Images.xcassets/calender.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "default@500w.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Images.xcassets/calender.imageset/default@500w.pdf b/iOSClient/Images.xcassets/calender.imageset/default@500w.pdf new file mode 100644 index 0000000000..b451f0a735 Binary files /dev/null and b/iOSClient/Images.xcassets/calender.imageset/default@500w.pdf differ diff --git a/iOSClient/Images.xcassets/contact.imageset/Contents.json b/iOSClient/Images.xcassets/contact.imageset/Contents.json new file mode 100644 index 0000000000..212bb4dfb1 --- /dev/null +++ b/iOSClient/Images.xcassets/contact.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "contact.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Images.xcassets/contact.imageset/contact.svg b/iOSClient/Images.xcassets/contact.imageset/contact.svg new file mode 100644 index 0000000000..6b3f9684ae --- /dev/null +++ b/iOSClient/Images.xcassets/contact.imageset/contact.svg @@ -0,0 +1,7 @@ + + + 01_24px/icon/user_file/contacts/default + + + + \ No newline at end of file diff --git a/iOSClient/Images.xcassets/downArrow.imageset/Contents.json b/iOSClient/Images.xcassets/downArrow.imageset/Contents.json new file mode 100644 index 0000000000..81ef9bbb37 --- /dev/null +++ b/iOSClient/Images.xcassets/downArrow.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "downArrow@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Images.xcassets/downArrow.imageset/downArrow@2x.png b/iOSClient/Images.xcassets/downArrow.imageset/downArrow@2x.png new file mode 100644 index 0000000000..6da8c3c9c5 Binary files /dev/null and b/iOSClient/Images.xcassets/downArrow.imageset/downArrow@2x.png differ diff --git a/iOSClient/Images.xcassets/email.imageset/Contents.json b/iOSClient/Images.xcassets/email.imageset/Contents.json index 565a76d806..f8fa0bcc0b 100644 --- a/iOSClient/Images.xcassets/email.imageset/Contents.json +++ b/iOSClient/Images.xcassets/email.imageset/Contents.json @@ -1,15 +1,15 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "mail.pdf" + "filename" : "mail.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 }, "properties" : { "preserves-vector-representation" : true } -} \ No newline at end of file +} diff --git a/iOSClient/Images.xcassets/email.imageset/mail.pdf b/iOSClient/Images.xcassets/email.imageset/mail.pdf index 33d54d385e..60d8261613 100644 Binary files a/iOSClient/Images.xcassets/email.imageset/mail.pdf and b/iOSClient/Images.xcassets/email.imageset/mail.pdf differ diff --git a/iOSClient/Images.xcassets/file.imageset/Contents.json b/iOSClient/Images.xcassets/file.imageset/Contents.json index 48ca8dd53d..34568170ce 100644 --- a/iOSClient/Images.xcassets/file.imageset/Contents.json +++ b/iOSClient/Images.xcassets/file.imageset/Contents.json @@ -1,15 +1,15 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "file.pdf" + "filename" : "file.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 }, "properties" : { "preserves-vector-representation" : true } -} \ No newline at end of file +} diff --git a/iOSClient/Images.xcassets/file.imageset/file.pdf b/iOSClient/Images.xcassets/file.imageset/file.pdf index e629726c98..bdbe2682c2 100644 Binary files a/iOSClient/Images.xcassets/file.imageset/file.pdf and b/iOSClient/Images.xcassets/file.imageset/file.pdf differ diff --git a/iOSClient/Images.xcassets/rename.imageset/Contents.json b/iOSClient/Images.xcassets/rename.imageset/Contents.json new file mode 100644 index 0000000000..f361ec03e2 --- /dev/null +++ b/iOSClient/Images.xcassets/rename.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "actionSheetRename.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "actionSheetRename@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "actionSheetRename@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Images.xcassets/rename.imageset/actionSheetRename.png b/iOSClient/Images.xcassets/rename.imageset/actionSheetRename.png new file mode 100644 index 0000000000..ff3bf49a82 Binary files /dev/null and b/iOSClient/Images.xcassets/rename.imageset/actionSheetRename.png differ diff --git a/iOSClient/Images.xcassets/rename.imageset/actionSheetRename@2x.png b/iOSClient/Images.xcassets/rename.imageset/actionSheetRename@2x.png new file mode 100644 index 0000000000..46415573f0 Binary files /dev/null and b/iOSClient/Images.xcassets/rename.imageset/actionSheetRename@2x.png differ diff --git a/iOSClient/Images.xcassets/rename.imageset/actionSheetRename@3x.png b/iOSClient/Images.xcassets/rename.imageset/actionSheetRename@3x.png new file mode 100644 index 0000000000..27f7dff1cf Binary files /dev/null and b/iOSClient/Images.xcassets/rename.imageset/actionSheetRename@3x.png differ diff --git a/iOSClient/Images.xcassets/shareCopy.imageset/Contents.json b/iOSClient/Images.xcassets/shareCopy.imageset/Contents.json index 7bb54b538a..35821977f7 100644 --- a/iOSClient/Images.xcassets/shareCopy.imageset/Contents.json +++ b/iOSClient/Images.xcassets/shareCopy.imageset/Contents.json @@ -1,15 +1,15 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "shareCopy.pdf" + "filename" : "shareCopy.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 }, "properties" : { "preserves-vector-representation" : true } -} \ No newline at end of file +} diff --git a/iOSClient/Images.xcassets/shareCopy.imageset/shareCopy.pdf b/iOSClient/Images.xcassets/shareCopy.imageset/shareCopy.pdf index 689c6437a8..55582d8b9b 100644 Binary files a/iOSClient/Images.xcassets/shareCopy.imageset/shareCopy.pdf and b/iOSClient/Images.xcassets/shareCopy.imageset/shareCopy.pdf differ diff --git a/iOSClient/Images.xcassets/shareTypeEmail.imageset/Contents.json b/iOSClient/Images.xcassets/shareTypeEmail.imageset/Contents.json index 00298ac4b4..ffff08a617 100644 --- a/iOSClient/Images.xcassets/shareTypeEmail.imageset/Contents.json +++ b/iOSClient/Images.xcassets/shareTypeEmail.imageset/Contents.json @@ -1,15 +1,15 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "shareTypeEmail.pdf" + "filename" : "user.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 }, "properties" : { "preserves-vector-representation" : true } -} \ No newline at end of file +} diff --git a/iOSClient/Images.xcassets/shareTypeEmail.imageset/shareTypeEmail.pdf b/iOSClient/Images.xcassets/shareTypeEmail.imageset/shareTypeEmail.pdf deleted file mode 100644 index 48b0f832f5..0000000000 Binary files a/iOSClient/Images.xcassets/shareTypeEmail.imageset/shareTypeEmail.pdf and /dev/null differ diff --git a/iOSClient/Images.xcassets/shareTypeEmail.imageset/user.pdf b/iOSClient/Images.xcassets/shareTypeEmail.imageset/user.pdf new file mode 100644 index 0000000000..6985e202b0 Binary files /dev/null and b/iOSClient/Images.xcassets/shareTypeEmail.imageset/user.pdf differ diff --git a/iOSClient/Images.xcassets/shareTypeLink.imageset/Contents.json b/iOSClient/Images.xcassets/shareTypeLink.imageset/Contents.json index ee5aa2c64b..53055a1b95 100644 --- a/iOSClient/Images.xcassets/shareTypeLink.imageset/Contents.json +++ b/iOSClient/Images.xcassets/shareTypeLink.imageset/Contents.json @@ -1,15 +1,15 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "shareTypeLink.pdf" + "filename" : "shareTypeLink.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 }, "properties" : { "preserves-vector-representation" : true } -} \ No newline at end of file +} diff --git a/iOSClient/Images.xcassets/shareTypeLink.imageset/shareTypeLink.pdf b/iOSClient/Images.xcassets/shareTypeLink.imageset/shareTypeLink.pdf index d10d218cd1..d2a882d380 100644 Binary files a/iOSClient/Images.xcassets/shareTypeLink.imageset/shareTypeLink.pdf and b/iOSClient/Images.xcassets/shareTypeLink.imageset/shareTypeLink.pdf differ diff --git a/iOSClient/Images.xcassets/shareTypeUser.imageset/Contents.json b/iOSClient/Images.xcassets/shareTypeUser.imageset/Contents.json index 874a5b2007..11ca2fc9dd 100644 --- a/iOSClient/Images.xcassets/shareTypeUser.imageset/Contents.json +++ b/iOSClient/Images.xcassets/shareTypeUser.imageset/Contents.json @@ -1,15 +1,15 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "shareTypeUser.pdf" + "filename" : "shareTypeUser.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 }, "properties" : { "preserves-vector-representation" : true } -} \ No newline at end of file +} diff --git a/iOSClient/Images.xcassets/shareTypeUser.imageset/shareTypeUser.pdf b/iOSClient/Images.xcassets/shareTypeUser.imageset/shareTypeUser.pdf index 03d855dcc4..62d278bb89 100644 Binary files a/iOSClient/Images.xcassets/shareTypeUser.imageset/shareTypeUser.pdf and b/iOSClient/Images.xcassets/shareTypeUser.imageset/shareTypeUser.pdf differ diff --git a/iOSClient/Images.xcassets/success.imageset/Contents.json b/iOSClient/Images.xcassets/success.imageset/Contents.json new file mode 100644 index 0000000000..858785f7a8 --- /dev/null +++ b/iOSClient/Images.xcassets/success.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "success.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "success@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "success@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Images.xcassets/success.imageset/success.png b/iOSClient/Images.xcassets/success.imageset/success.png new file mode 100644 index 0000000000..b1d2459a4b Binary files /dev/null and b/iOSClient/Images.xcassets/success.imageset/success.png differ diff --git a/iOSClient/Images.xcassets/success.imageset/success@2x.png b/iOSClient/Images.xcassets/success.imageset/success@2x.png new file mode 100644 index 0000000000..9832eda028 Binary files /dev/null and b/iOSClient/Images.xcassets/success.imageset/success@2x.png differ diff --git a/iOSClient/Images.xcassets/success.imageset/success@3x.png b/iOSClient/Images.xcassets/success.imageset/success@3x.png new file mode 100644 index 0000000000..d89d2e4719 Binary files /dev/null and b/iOSClient/Images.xcassets/success.imageset/success@3x.png differ diff --git a/iOSClient/Images.xcassets/trash.imageset/Contents.json b/iOSClient/Images.xcassets/trash.imageset/Contents.json index e98514534c..0fead39b1f 100644 --- a/iOSClient/Images.xcassets/trash.imageset/Contents.json +++ b/iOSClient/Images.xcassets/trash.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "trash.pdf", + "filename" : "default@500w.pdf", "idiom" : "universal" } ], diff --git a/iOSClient/Images.xcassets/trash.imageset/default@500w.pdf b/iOSClient/Images.xcassets/trash.imageset/default@500w.pdf new file mode 100644 index 0000000000..225c983dec Binary files /dev/null and b/iOSClient/Images.xcassets/trash.imageset/default@500w.pdf differ diff --git a/iOSClient/Images.xcassets/trash.imageset/trash.pdf b/iOSClient/Images.xcassets/trash.imageset/trash.pdf deleted file mode 100644 index 9233b74c6f..0000000000 Binary files a/iOSClient/Images.xcassets/trash.imageset/trash.pdf and /dev/null differ diff --git a/iOSClient/Images.xcassets/viewInFolder.imageset/Contents.json b/iOSClient/Images.xcassets/viewInFolder.imageset/Contents.json new file mode 100644 index 0000000000..2ea287530d --- /dev/null +++ b/iOSClient/Images.xcassets/viewInFolder.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "viewInFolder-1.pdf", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "viewInFolderDark.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOSClient/Images.xcassets/viewInFolder.imageset/viewInFolder-1.pdf b/iOSClient/Images.xcassets/viewInFolder.imageset/viewInFolder-1.pdf new file mode 100644 index 0000000000..bb8489ccd9 Binary files /dev/null and b/iOSClient/Images.xcassets/viewInFolder.imageset/viewInFolder-1.pdf differ diff --git a/iOSClient/Images.xcassets/viewInFolder.imageset/viewInFolderDark.pdf b/iOSClient/Images.xcassets/viewInFolder.imageset/viewInFolderDark.pdf new file mode 100644 index 0000000000..1f59694303 Binary files /dev/null and b/iOSClient/Images.xcassets/viewInFolder.imageset/viewInFolderDark.pdf differ diff --git a/iOSClient/Main/NCActionCenter.swift b/iOSClient/Main/NCActionCenter.swift index 9000bb5904..305657e866 100644 --- a/iOSClient/Main/NCActionCenter.swift +++ b/iOSClient/Main/NCActionCenter.swift @@ -252,36 +252,11 @@ class NCActionCenter: NSObject, UIDocumentInteractionControllerDelegate, NCSelec NCActivityIndicator.shared.stop() if let metadata = metadata, error == .success { - - var pages: [NCBrandOptions.NCInfoPagingTab] = [] - let shareNavigationController = UIStoryboard(name: "NCShare", bundle: nil).instantiateInitialViewController() as? UINavigationController - let shareViewController = shareNavigationController?.topViewController as? NCSharePaging - - for value in NCBrandOptions.NCInfoPagingTab.allCases { - pages.append(value) - } - - if NCGlobal.shared.capabilityActivity.isEmpty, let idx = pages.firstIndex(of: .activity) { - pages.remove(at: idx) - } - if !metadata.isSharable(), let idx = pages.firstIndex(of: .sharing) { - pages.remove(at: idx) - } - - (pages, page) = NCApplicationHandle().filterPages(pages: pages, page: page, metadata: metadata) - - shareViewController?.pages = pages + let shareViewController = shareNavigationController?.topViewController as? NCShare + shareViewController?.metadata = metadata - if pages.contains(page) { - shareViewController?.page = page - } else if let page = pages.first { - shareViewController?.page = page - } else { - return - } - shareNavigationController?.modalPresentationStyle = .formSheet if let shareNavigationController = shareNavigationController { viewController.present(shareNavigationController, animated: true, completion: nil) diff --git a/iOSClient/Menu/NCShare+Menu.swift b/iOSClient/Menu/NCShare+Menu.swift index 14cc2f34fa..2a7353ee59 100644 --- a/iOSClient/Menu/NCShare+Menu.swift +++ b/iOSClient/Menu/NCShare+Menu.swift @@ -25,43 +25,62 @@ import Foundation import NextcloudKit extension NCShare { - func toggleShareMenu(for share: tableShare) { + func toggleShareMenu(for share: tableShare, sendMail: Bool, folder: Bool, sender: Any) { var actions = [NCMenuAction]() - - if share.shareType == 3, canReshare { + + if !folder { actions.append( NCMenuAction( - title: NSLocalizedString("_share_add_sharelink_", comment: ""), - icon: NCUtility.shared.loadImage(named: "shareAdd"), - action: { _ in - self.makeNewLinkShare() + title: NSLocalizedString("_open_in_", comment: ""), + icon: NCUtility.shared.loadImage(named: "viewInFolder").imageColor(NCBrandColor.shared.brandElement), + action: { menuAction in + NCShareCommon.shared.copyLink(link: share.url, viewController: self, sender: sender) } ) ) } + + actions.append( NCMenuAction( - title: NSLocalizedString("_details_", comment: ""), - icon: NCUtility.shared.loadImage(named: "pencil"), + title: NSLocalizedString("_advance_permissions_", comment: ""), + icon: NCUtility.shared.loadImage(named: "rename").imageColor(NCBrandColor.shared.brandElement), action: { _ in guard let advancePermission = UIStoryboard(name: "NCShare", bundle: nil).instantiateViewController(withIdentifier: "NCShareAdvancePermission") as? NCShareAdvancePermission, let navigationController = self.navigationController, !share.isInvalidated else { return } advancePermission.networking = self.networking advancePermission.share = tableShare(value: share) - advancePermission.oldTableShare = tableShare(value: share) + advancePermission.oldTableShare = share//tableShare(value: share) advancePermission.metadata = self.metadata navigationController.pushViewController(advancePermission, animated: true) } ) ) - + + if sendMail { + actions.append( + NCMenuAction( + title: NSLocalizedString("_send_new_email_", comment: ""), + icon: NCUtility.shared.loadImage(named: "email").imageColor(NCBrandColor.shared.brandElement), + action: { menuAction in + let storyboard = UIStoryboard(name: "NCShare", bundle: nil) + guard let viewNewUserComment = storyboard.instantiateViewController(withIdentifier: "NCShareNewUserAddComment") as? NCShareNewUserAddComment else { return } + viewNewUserComment.metadata = self.metadata + viewNewUserComment.share = tableShare(value: share) + viewNewUserComment.networking = self.networking + self.navigationController?.pushViewController(viewNewUserComment, animated: true) + } + ) + ) + } + actions.append( NCMenuAction( title: NSLocalizedString("_share_unshare_", comment: ""), - icon: NCUtility.shared.loadImage(named: "trash"), + icon: NCUtility.shared.loadImage(named: "trash").imageColor(NCBrandColor.shared.brandElement), action: { _ in Task { if share.shareType != NCShareCommon.shared.SHARE_TYPE_LINK, let metadata = self.metadata, metadata.e2eEncrypted && NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 { @@ -90,7 +109,7 @@ extension NCShare { actions.append( NCMenuAction( title: NSLocalizedString("_share_read_only_", comment: ""), - icon: NCUtility.shared.loadImage(named: "eye"), + icon: UIImage(), selected: tableShare.permissions == (NCGlobal.shared.permissionReadShare + NCGlobal.shared.permissionShareShare) || tableShare.permissions == NCGlobal.shared.permissionReadShare, on: false, action: { _ in @@ -104,7 +123,7 @@ extension NCShare { actions.append( NCMenuAction( title: isDirectory ? NSLocalizedString("_share_allow_upload_", comment: "") : NSLocalizedString("_share_editing_", comment: ""), - icon: NCUtility.shared.loadImage(named: "pencil"), + icon: UIImage(), selected: hasUploadPermission(tableShare: tableShare), on: false, action: { _ in @@ -114,11 +133,26 @@ extension NCShare { } ) ) - + + if isDirectory, + NCShareCommon.shared.isFileDropOptionVisible(isDirectory: isDirectory, shareType: tableShare.shareType) { + actions.append( + NCMenuAction( + title: NSLocalizedString("_share_file_drop_", comment: ""), + icon: tableShare.permissions == NCGlobal.shared.permissionCreateShare ? UIImage(named: "success")?.image(color: NCBrandColor.shared.customer, size: 25.0) ?? UIImage() : UIImage(), + selected: false, + on: false, + action: { menuAction in + let permissions = NCGlobal.shared.permissionCreateShare + self.updateSharePermissions(share: tableShare, permissions: permissions) + } + ) + ) + } self.presentMenu(with: actions) } - fileprivate func hasUploadPermission(tableShare: tableShare) -> Bool { + func hasUploadPermission(tableShare: tableShare) -> Bool { let uploadPermissions = [ NCGlobal.shared.permissionMaxFileShare, NCGlobal.shared.permissionMaxFolderShare, diff --git a/iOSClient/NCGlobal.swift b/iOSClient/NCGlobal.swift index f96ed1dc3a..3cfbb9032f 100644 --- a/iOSClient/NCGlobal.swift +++ b/iOSClient/NCGlobal.swift @@ -388,7 +388,15 @@ class NCGlobal: NSObject { let notificationCenterEnableSwipeGesture = "enableSwipeGesture" let notificationCenterDisableSwipeGesture = "disableSwipeGesture" - + + let notificationCenterShareViewIn = "ShareViewIn" + let notificationCenterShareAdvancePermission = "ShareAdvancePermission" + let notificationCenterShareSendEmail = "ShareSendEmail" + let notificationCenterShareUnshare = "ShareUnshare" + let notificationCenterStatusReadOnly = "statusReadOnly" + let notificationCenterStatusEditing = "statusEditing" + let notificationCenterStatusFileDrop = "statusFileDrop" + // TIP // let tipNCViewerPDFThumbnail = "tipncviewerpdfthumbnail" diff --git a/iOSClient/Networking/NCService.swift b/iOSClient/Networking/NCService.swift index efbb778e43..a5287dc3ad 100644 --- a/iOSClient/Networking/NCService.swift +++ b/iOSClient/Networking/NCService.swift @@ -201,6 +201,20 @@ class NCService: NSObject { } else { self.appDelegate.disableSharesView = false } + + // File Sharing + if NCGlobal.shared.capabilityFileSharingApiEnabled { + let home = NCUtilityFileSystem.shared.getHomeServer(urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId) + NextcloudKit.shared.readShares(parameters: NKShareParameter(), options: options) { account, shares, data, error in + if error == .success { + NCManageDatabase.shared.deleteTableShare(account: account) + if let shares = shares, !shares.isEmpty { + NCManageDatabase.shared.addShare(account: account, home: home, shares: shares) + NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataSource) + } + } + } + } // Text direct editor detail if NCGlobal.shared.capabilityServerVersionMajor >= NCGlobal.shared.nextcloudVersion18 { diff --git a/iOSClient/Scan document/PasswordInputField.swift b/iOSClient/Scan document/PasswordInputField.swift new file mode 100644 index 0000000000..c2b893324b --- /dev/null +++ b/iOSClient/Scan document/PasswordInputField.swift @@ -0,0 +1,75 @@ +// +// PasswordInputField.swift +// Nextcloud +// +// Created by Sumit on 10/06/21. +// Copyright © 2021 Marino Faggiana. All rights reserved. +// + +import Foundation + +class PasswordInputField: XLFormBaseCell,UITextFieldDelegate { + + @IBOutlet weak var fileNameInputTextField: UITextField! + @IBOutlet weak var separatorBottom: UIView! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + fileNameInputTextField.isSecureTextEntry = true + fileNameInputTextField.delegate = self + separatorBottom.backgroundColor = NCBrandColor.shared.systemGray4 + self.selectionStyle = .none + fileNameInputTextField.inputAccessoryView = UIToolbar.doneToolbar { + self.fileNameInputTextField.resignFirstResponder() + } + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + override func configure() { + super.configure() + // fileNameInputTextField.isEnabled = false + + } + + override func update() { + super.update() + } + + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + + if fileNameInputTextField == textField { + if let rowDescriptor = rowDescriptor, let text = self.fileNameInputTextField.text { + + if (text + " ").isEmpty == false { + rowDescriptor.value = self.fileNameInputTextField.text! + string + } else { + rowDescriptor.value = nil + } + } + } + + self.formViewController().textField(textField, shouldChangeCharactersIn: range, replacementString: string) + + return true + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + self.formViewController()?.textFieldShouldReturn(fileNameInputTextField) + return true + } + + func textFieldShouldClear(_ textField: UITextField) -> Bool { + self.formViewController()?.textFieldShouldClear(fileNameInputTextField) + return true + } + + override class func formDescriptorCellHeight(for rowDescriptor: XLFormRowDescriptor!) -> CGFloat { + return 45 + } +} diff --git a/iOSClient/Scan document/PasswordInputField.xib b/iOSClient/Scan document/PasswordInputField.xib new file mode 100644 index 0000000000..26914e0760 --- /dev/null +++ b/iOSClient/Scan document/PasswordInputField.xib @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOSClient/Share/Advanced/NCFilePermissionCell.swift b/iOSClient/Share/Advanced/NCFilePermissionCell.swift new file mode 100644 index 0000000000..4e5ec77f72 --- /dev/null +++ b/iOSClient/Share/Advanced/NCFilePermissionCell.swift @@ -0,0 +1,91 @@ +// +// NCFilePermissionCell.swift +// Nextcloud +// +// Created by T-systems on 17/08/21. +// Copyright © 2021 Marino Faggiana. All rights reserved. +// + +import UIKit + +class NCFilePermissionCell: XLFormButtonCell { + + @IBOutlet weak var seperator: UIView! + @IBOutlet weak var titleLabel: UILabel! + @IBOutlet weak var imageCheck: UIImageView! + @IBOutlet weak var seperatorBelow: UIView! + @IBOutlet weak var seperatorBelowFull: UIView! + @IBOutlet weak var titleLabelBottom: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + self.selectionStyle = .none + self.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + self.titleLabel.textColor = NCBrandColor.shared.label + NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterChangeTheming), object: nil) + } + + @objc func changeTheming() { + self.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + self.titleLabel.textColor = NCBrandColor.shared.label + self.titleLabelBottom.textColor = NCBrandColor.shared.iconColor + } + + override func configure() { + super.configure() + } + + + override func update() { + super.update() + self.selectionStyle = .none + if rowDescriptor.tag == "NCFilePermissionCellSharing" || rowDescriptor.tag == "NCFilePermissionCellAdvanceTxt" { + self.seperator.isHidden = true + self.seperatorBelowFull.isHidden = true + self.seperatorBelow.isHidden = true + self.titleLabel.font = UIFont.boldSystemFont(ofSize: 17) + self.titleLabelBottom.font = UIFont.boldSystemFont(ofSize: 17) + } + if rowDescriptor.tag == "kNMCFilePermissionCellEditing" { + self.seperator.isHidden = true +// self.seperatorBelowFull.isHidden = true + } + + if rowDescriptor.tag == "NCFilePermissionCellFileDrop" { + self.seperator.isHidden = true + self.seperatorBelow.isHidden = false + self.seperatorBelowFull.isHidden = true + } + + if rowDescriptor.tag == "kNMCFilePermissionEditCellEditingCanShare" { + self.seperator.isHidden = true + self.seperatorBelowFull.isHidden = false + } + + if rowDescriptor.tag == "kNMCFilePermissionCellEditingMsg" { + self.seperator.isHidden = true + self.seperatorBelow.isHidden = true + self.seperatorBelowFull.isHidden = false + } + + if rowDescriptor.tag == "kNMCFilePermissionCellFiledropMessage" { + self.seperator.isHidden = true + self.seperatorBelow.isHidden = true + self.seperatorBelowFull.isHidden = false + self.imageCheck.isHidden = true + } + } + + @objc func switchChanged(mySwitch: UISwitch) { + self.rowDescriptor.value = mySwitch.isOn + } + + override func formDescriptorCellDidSelected(withForm controller: XLFormViewController!) { + self.selectionStyle = .none + } + + override class func formDescriptorCellHeight(for rowDescriptor: XLFormRowDescriptor!) -> CGFloat { + return 44.0 + } + +} diff --git a/iOSClient/Share/Advanced/NCFilePermissionCell.xib b/iOSClient/Share/Advanced/NCFilePermissionCell.xib new file mode 100644 index 0000000000..e40c22e14d --- /dev/null +++ b/iOSClient/Share/Advanced/NCFilePermissionCell.xib @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOSClient/Share/Advanced/NCFilePermissionEditCell.swift b/iOSClient/Share/Advanced/NCFilePermissionEditCell.swift new file mode 100644 index 0000000000..b32d66a74f --- /dev/null +++ b/iOSClient/Share/Advanced/NCFilePermissionEditCell.swift @@ -0,0 +1,176 @@ +// +// NCFilePermissionEditCell.swift +// Nextcloud +// +// Created by T-systems on 10/08/21. +// Copyright © 2021 Marino Faggiana. All rights reserved. +// + +import UIKit + +class NCFilePermissionEditCell: XLFormBaseCell, UITextFieldDelegate { + + @IBOutlet weak var seperator: UIView! + @IBOutlet weak var seperatorMiddle: UIView! + @IBOutlet weak var seperatorBottom: UIView! + @IBOutlet weak var titleLabel: UILabel! + @IBOutlet weak var switchControl: UISwitch! + @IBOutlet weak var cellTextField: UITextField! + @IBOutlet weak var buttonLinkLabel: UIButton! + let datePicker = UIDatePicker() + var expirationDateText: String! + var expirationDate: NSDate! + + override func awakeFromNib() { + super.awakeFromNib() + self.cellTextField.delegate = self + self.cellTextField.isEnabled = false + self.selectionStyle = .none + switchControl.addTarget(self, action: #selector(switchChanged), for: UIControl.Event.valueChanged) + self.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + self.titleLabel.textColor = NCBrandColor.shared.label + self.cellTextField.attributedPlaceholder = NSAttributedString(string: "", + attributes: [NSAttributedString.Key.foregroundColor: NCBrandColor.shared.fileFolderName]) + self.cellTextField.textColor = NCBrandColor.shared.singleTitleColorButton + NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterChangeTheming), object: nil) + } + + @objc func changeTheming() { + self.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + self.titleLabel.textColor = NCBrandColor.shared.iconColor + } + + override func configure() { + super.configure() + } + + override func update() { + super.update() + + if rowDescriptor.tag == "kNMCFilePermissionCellEditingCanShare" { + self.seperatorMiddle.isHidden = true + self.seperatorBottom.isHidden = true + self.cellTextField.isHidden = true + } + if rowDescriptor.tag == "kNMCFilePermissionEditCellLinkLabel" { + self.switchControl.isHidden = true + self.cellTextField.isEnabled = true + self.seperatorBottom.isHidden = true + } + if rowDescriptor.tag == "kNMCFilePermissionEditCellLinkLabel" { + self.switchControl.isHidden = true + } + + if rowDescriptor.tag == "kNMCFilePermissionEditCellExpiration" { + self.seperator.isHidden = true + setDatePicker(sender: self.cellTextField) + } + + if rowDescriptor.tag == "kNMCFilePermissionEditPasswordCellWithText" { + self.seperatorMiddle.isHidden = true + self.seperator.isHidden = true + } + + if rowDescriptor.tag == "kNMCFilePermissionEditCellHideDownload" { + self.seperator.isHidden = true + self.seperatorMiddle.isHidden = true + } + + if rowDescriptor.tag == "kNMCFilePermissionEditCellEditingCanShare" { + self.seperator.isHidden = true + self.seperatorBottom.isHidden = true + } + } + + @objc func switchChanged(mySwitch: UISwitch) { + let isOn = mySwitch.isOn + if isOn { + //on + self.rowDescriptor.value = isOn + self.cellTextField.isEnabled = true + cellTextField.delegate = self + } else { + self.rowDescriptor.value = isOn + self.cellTextField.isEnabled = false + if rowDescriptor.tag == "kNMCFilePermissionEditCellExpiration" || rowDescriptor.tag == "kNMCFilePermissionEditCellPassword" { + self.cellTextField.text = "" + } + } + if rowDescriptor.tag == "kNMCFilePermissionEditPasswordCellWithText" { + seperatorBottom.isHidden = isOn + seperatorMiddle.isHidden = !isOn + } + if rowDescriptor.tag == "kNMCFilePermissionEditCellExpiration" { + seperatorBottom.isHidden = isOn + seperatorMiddle.isHidden = !isOn + } + } + + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + if self.cellTextField == textField { + if let rowDescriptor = rowDescriptor, let text = self.cellTextField.text { + + if (text + " ").isEmpty == false { + rowDescriptor.value = self.cellTextField.text! + string + } else { + rowDescriptor.value = nil + } + } + } + + self.formViewController().textField(textField, shouldChangeCharactersIn: range, replacementString: string) + return true + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + self.formViewController()?.textFieldShouldReturn(textField) + return true + } + + func textFieldShouldClear(_ textField: UITextField) -> Bool { + self.formViewController()?.textFieldShouldClear(textField) + return true + } + + override class func formDescriptorCellHeight(for rowDescriptor: XLFormRowDescriptor!) -> CGFloat { + return 30 + } + + override func formDescriptorCellDidSelected(withForm controller: XLFormViewController!) { + self.selectionStyle = .none + } + + func setDatePicker(sender: UITextField) { + //Format Date + datePicker.datePickerMode = .date + datePicker.minimumDate = Date() + //ToolBar + let toolbar = UIToolbar(); + toolbar.sizeToFit() + let doneButton = UIBarButtonItem(title: NSLocalizedString("_done_", comment: ""), style: .plain, target: self, action: #selector(doneDatePicker)); + let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil) + let cancelButton = UIBarButtonItem(title: NSLocalizedString("_cancel_", comment: ""), style: .plain, target: self, action: #selector(cancelDatePicker)); + + toolbar.setItems([doneButton,spaceButton,cancelButton], animated: false) + + sender.inputAccessoryView = toolbar + sender.inputView = datePicker + } + + @objc func doneDatePicker() { + let dateFormatter = DateFormatter() + dateFormatter.formatterBehavior = .behavior10_4 + dateFormatter.dateStyle = .medium + self.expirationDateText = dateFormatter.string(from: datePicker.date as Date) + + dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss" + self.expirationDate = datePicker.date as NSDate + self.cellTextField.text = self.expirationDateText + self.rowDescriptor.value = self.expirationDate + self.cellTextField.endEditing(true) + } + + @objc func cancelDatePicker() { + self.cellTextField.endEditing(true) + } +} diff --git a/iOSClient/Share/Advanced/NCFilePermissionEditCell.xib b/iOSClient/Share/Advanced/NCFilePermissionEditCell.xib new file mode 100644 index 0000000000..2a7aa3ac63 --- /dev/null +++ b/iOSClient/Share/Advanced/NCFilePermissionEditCell.xib @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermission.swift b/iOSClient/Share/Advanced/NCShareAdvancePermission.swift index c24dd276e7..487be5745a 100644 --- a/iOSClient/Share/Advanced/NCShareAdvancePermission.swift +++ b/iOSClient/Share/Advanced/NCShareAdvancePermission.swift @@ -26,46 +26,43 @@ import NextcloudKit import SVGKit import CloudKit -class NCShareAdvancePermission: UITableViewController, NCShareAdvanceFotterDelegate, NCShareDetail { +class NCShareAdvancePermission: XLFormViewController, NCShareAdvanceFotterDelegate, NCShareDetail { func dismissShareAdvanceView(shouldSave: Bool) { - guard shouldSave else { - guard oldTableShare?.hasChanges(comparedTo: share) != false else { - navigationController?.popViewController(animated: true) - return - } - let alert = UIAlertController( - title: NSLocalizedString("_cancel_request_", comment: ""), - message: NSLocalizedString("_discard_changes_info_", comment: ""), - preferredStyle: .alert) - alert.addAction(UIAlertAction( - title: NSLocalizedString("_discard_changes_", comment: ""), - style: .destructive, - handler: { _ in self.navigationController?.popViewController(animated: true) })) - alert.addAction(UIAlertAction(title: NSLocalizedString("_continue_editing_", comment: ""), style: .default)) - self.present(alert, animated: true) - return - } - Task { + if shouldSave { if isNewShare { - let serverUrl = metadata.serverUrl + "/" + metadata.fileName - if share.shareType != NCShareCommon.shared.SHARE_TYPE_LINK, metadata.e2eEncrypted, - NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 { - if NCNetworkingE2EE.shared.isInUpload(account: metadata.account, serverUrl: serverUrl) { - let error = NKError(errorCode: NCGlobal.shared.errorE2EEUploadInProgress, errorDescription: NSLocalizedString("_e2e_in_upload_", comment: "")) - return NCContentPresenter.shared.showInfo(error: error) - } - let error = await NCNetworkingE2EE().uploadMetadata(account: metadata.account, serverUrl: serverUrl, userId: metadata.userId, addUserId: share.shareWith, removeUserId: nil) - if error != .success { - NCContentPresenter.shared.showError(error: error) - return + let storyboard = UIStoryboard(name: "NCShare", bundle: nil) + guard let viewNewUserComment = storyboard.instantiateViewController(withIdentifier: "NCShareNewUserAddComment") as? NCShareNewUserAddComment else { return } + viewNewUserComment.metadata = self.metadata + viewNewUserComment.share = self.share + viewNewUserComment.networking = self.networking + self.navigationController?.pushViewController(viewNewUserComment, animated: true) + // networking?.createShare(option: share) + } else { + if let downloadSwitchCell = getDownloadLimitSwitchCell() { + let isDownloadLimitOn = downloadSwitchCell.switchControl.isOn + if !isDownloadLimitOn { + setDownloadLimit(deleteLimit: true, limit: "") + } else { + let downloadLimitInputCell = getDownloadLimitInputCell() + let enteredDownloadLimit = downloadLimitInputCell?.cellTextField.text ?? "" + if enteredDownloadLimit.isEmpty { + showDownloadLimitError(message: NSLocalizedString("_share_download_limit_alert_empty_", comment: "")) + return + } + if let num = Int(enteredDownloadLimit), num < 1 { + showDownloadLimitError(message: NSLocalizedString("_share_download_limit_alert_zero_", comment: "")) + return + } + setDownloadLimit(deleteLimit: false, limit: enteredDownloadLimit) } } - networking?.createShare(option: share) - } else { + networking?.updateShare(option: share) + navigationController?.popViewController(animated: true) } + } else { + navigationController?.popViewController(animated: true) } - navigationController?.popViewController(animated: true) } var oldTableShare: tableShare? @@ -74,17 +71,27 @@ class NCShareAdvancePermission: UITableViewController, NCShareAdvanceFotterDeleg var metadata: tableMetadata! var shareConfig: NCShareConfig! var networking: NCShareNetworking? - + let tableViewBottomInset: CGFloat = 80.0 + lazy var shareType: Int = { + isNewShare ? share.shareType : oldTableShare?.shareType ?? NCShareCommon.shared.SHARE_TYPE_USER + }() + static let displayDateFormat = "dd. MMM. yyyy" + var downloadLimit: DownloadLimit? + override func viewDidLoad() { super.viewDidLoad() self.shareConfig = NCShareConfig(parentMetadata: metadata, share: share) - - tableView.estimatedRowHeight = tableView.rowHeight - tableView.rowHeight = UITableView.automaticDimension self.setNavigationTitle() - self.navigationItem.hidesBackButton = true // disbale pull to dimiss isModalInPresentation = true + self.tableView.separatorStyle = UITableViewCell.SeparatorStyle.none + initializeForm() + changeTheming() + getDownloadLimit() + NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterChangeTheming), object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) + + NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) } override func viewWillLayoutSubviews() { @@ -93,114 +100,707 @@ class NCShareAdvancePermission: UITableViewController, NCShareAdvanceFotterDeleg setupHeaderView() setupFooterView() } + + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + if (UIDevice.current.userInterfaceIdiom == .phone), UIDevice().hasNotch { + let isLandscape = UIDevice.current.orientation.isLandscape + let tableViewWidth = isLandscape ? view.bounds.width - 80 : view.bounds.width + tableView.frame = CGRect(x: isLandscape ? 40 : 0, y: tableView.frame.minY, width: tableViewWidth, height: tableView.bounds.height) + tableView.layoutIfNeeded() + } + } + + @objc func keyboardWillShow(_ notification:Notification) { + if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { + tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height + 60, right: 0) + } + } + + @objc func keyboardWillHide(_ notification:Notification) { + if ((notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue) != nil { + tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: tableViewBottomInset, right: 0) + } + } + @objc func changeTheming() { + tableView.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + self.view.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + self.navigationController?.navigationBar.tintColor = NCBrandColor.shared.customer + tableView.reloadData() + } + func setupFooterView() { guard let footerView = (Bundle.main.loadNibNamed("NCShareAdvancePermissionFooter", owner: self, options: nil)?.first as? NCShareAdvancePermissionFooter) else { return } footerView.setupUI(delegate: self) // tableFooterView can't use auto layout directly - let container = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 120)) - container.addSubview(footerView) - tableView.tableFooterView = container + footerView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 100) + self.view.addSubview(footerView) footerView.translatesAutoresizingMaskIntoConstraints = false - footerView.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true - footerView.heightAnchor.constraint(equalTo: container.heightAnchor).isActive = true - footerView.widthAnchor.constraint(equalTo: container.widthAnchor).isActive = true + footerView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true + footerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true + footerView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true + footerView.heightAnchor.constraint(equalToConstant: 100).isActive = true + tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: tableViewBottomInset, right: 0) + } func setupHeaderView() { guard let headerView = (Bundle.main.loadNibNamed("NCShareAdvancePermissionHeader", owner: self, options: nil)?.first as? NCShareAdvancePermissionHeader) else { return } headerView.setupUI(with: metadata) - - let container = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 220)) - container.addSubview(headerView) - tableView.tableHeaderView = container + headerView.ocId = metadata.ocId + headerView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 190) + self.tableView.tableHeaderView = headerView headerView.translatesAutoresizingMaskIntoConstraints = false - headerView.topAnchor.constraint(equalTo: container.topAnchor).isActive = true - headerView.heightAnchor.constraint(equalTo: container.heightAnchor).isActive = true - headerView.widthAnchor.constraint(equalTo: container.widthAnchor).isActive = true + headerView.heightAnchor.constraint(equalToConstant: 190).isActive = true + headerView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true } - override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { - if section == 0 { - return NSLocalizedString("_permissions_", comment: "") - } else if section == 1 { - return NSLocalizedString("_advanced_", comment: "") - } else { return nil } + func initializeForm() { + let form : XLFormDescriptor + var section : XLFormSectionDescriptor + var row : XLFormRowDescriptor + + form = XLFormDescriptor(title: "Other Cells") + + //Sharing + section = XLFormSectionDescriptor.formSection(withTitle: "") + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFilePermissionCell"] = NCFilePermissionCell.self + row = XLFormRowDescriptor(tag: "NCFilePermissionCellSharing", rowType: "kNMCFilePermissionCell", title: "") + row.cellConfig["titleLabel.text"] = NSLocalizedString("_sharing_", comment: "") + row.height = 44 + section.addFormRow(row) + + //PERMISSION + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCShareHeaderCustomCell"] = NCShareHeaderCustomCell.self + row = XLFormRowDescriptor(tag: "kNMCShareHeaderCustomCell", rowType: "kNMCShareHeaderCustomCell", title: NSLocalizedString("_PERMISSIONS_", comment: "")) + row.height = 26 + row.cellConfig["titleLabel.text"] = NSLocalizedString("_PERMISSIONS_", comment: "") + section.addFormRow(row) + + //read only + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFilePermissionCell"] = NCFilePermissionCell.self + row = XLFormRowDescriptor(tag: "NCFilePermissionCellRead", rowType: "kNMCFilePermissionCell", title: NSLocalizedString("_PERMISSIONS_", comment: "")) + row.cellConfig["titleLabel.text"] = NSLocalizedString("_share_read_only_", comment: "") + row.height = 44 + + if let permission = oldTableShare?.permissions, !CCUtility.isAnyPermission(toEdit: permission), permission != NCGlobal.shared.permissionCreateShare { + row.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: NCBrandColor.shared.customer, size: 25.0) + } + if isNewShare { + row.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: NCBrandColor.shared.customer, size: 25.0) + share.permissions = NCGlobal.shared.permissionReadShare + } + section.addFormRow(row) + + //editing + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFilePermissionCell"] = NCFilePermissionCell.self + + row = XLFormRowDescriptor(tag: "kNMCFilePermissionCellEditing", rowType: "kNMCFilePermissionCell", title: NSLocalizedString("_PERMISSIONS_", comment: "")) + row.cellConfig["titleLabel.text"] = NSLocalizedString("_share_allow_editing_", comment: "") + row.height = 44 + if let permission = oldTableShare?.permissions { + if CCUtility.isAnyPermission(toEdit: permission), permission != NCGlobal.shared.permissionCreateShare { + row.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: NCBrandColor.shared.customer, size: 25.0) + } + } + let enabled = NCShareCommon.shared.isEditingEnabled(isDirectory: metadata.directory, fileExtension: metadata.fileExtension, shareType: shareType) || checkIsCollaboraFile() + row.cellConfig["titleLabel.textColor"] = enabled ? NCBrandColor.shared.label : NCBrandColor.shared.systemGray + row.disabled = !enabled + section.addFormRow(row) + + if !enabled { + row = XLFormRowDescriptor(tag: "kNMCFilePermissionCellEditingMsg", rowType: "kNMCFilePermissionCell", title: NSLocalizedString("_PERMISSIONS_", comment: "")) + row.cellConfig["titleLabel.text"] = NSLocalizedString("share_editing_message", comment: "") + row.cellConfig["titleLabel.textColor"] = NCBrandColor.shared.gray60 + row.height = 80 + section.addFormRow(row) + } + + //file drop + if isFileDropOptionVisible() { + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFilePermissionCell"] = NCFilePermissionCell.self + row = XLFormRowDescriptor(tag: "NCFilePermissionCellFileDrop", rowType: "kNMCFilePermissionCell", title: NSLocalizedString("_PERMISSIONS_", comment: "")) + row.cellConfig["titleLabel.text"] = NSLocalizedString("_share_file_drop_", comment: "") + if oldTableShare?.permissions == NCGlobal.shared.permissionCreateShare { + row.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: NCBrandColor.shared.customer, size: 25.0) + } + row.height = 44 + section.addFormRow(row) + + //sammelbox message + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFilePermissionCell"] = NCFilePermissionCell.self + + row = XLFormRowDescriptor(tag: "kNMCFilePermissionCellFiledropMessage", rowType: "kNMCFilePermissionCell", title: NSLocalizedString("_PERMISSIONS_", comment: "")) + row.cellConfig["titleLabel.text"] = NSLocalizedString("_file_drop_message_", comment: "") + row.cellConfig["titleLabel.textColor"] = NCBrandColor.shared.gray60 + row.cellConfig["imageCheck.image"] = UIImage() + row.height = 84 + section.addFormRow(row) + } + + //empty cell + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCXLFormBaseCell"] = NCSeparatorCell.self + row = XLFormRowDescriptor(tag: "kNMCXLFormBaseCell", rowType: "kNMCXLFormBaseCell", title: NSLocalizedString("", comment: "")) + row.height = 16 + section.addFormRow(row) + + //ADVANCE PERMISSION + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFilePermissionCell"] = NCFilePermissionCell.self + + row = XLFormRowDescriptor(tag: "NCFilePermissionCellAdvanceTxt", rowType: "kNMCFilePermissionCell", title: NSLocalizedString("_PERMISSIONS_", comment: "")) + row.cellConfig["titleLabel.text"] = NSLocalizedString("_advance_permissions_", comment: "") + row.height = 52 + section.addFormRow(row) + + if isLinkShare() { + //link label section header + + // Custom Link label + XLFormViewController.cellClassesForRowDescriptorTypes()["kNCShareTextInputCell"] = NCShareTextInputCell.self + row = XLFormRowDescriptor(tag: "kNCShareTextInputCellCustomLinkField", rowType: "kNCShareTextInputCell", title: "") + row.cellConfig["cellTextField.placeholder"] = NSLocalizedString("_custom_link_label", comment: "") + row.cellConfig["cellTextField.text"] = oldTableShare?.label + row.cellConfig["cellTextField.textAlignment"] = NSTextAlignment.left.rawValue + row.cellConfig["cellTextField.font"] = UIFont.systemFont(ofSize: 15.0) + row.cellConfig["cellTextField.textColor"] = NCBrandColor.shared.label + row.height = 44 + section.addFormRow(row) + } + + //can reshare + if isCanReshareOptionVisible() { + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFilePermissionEditCell"] = NCFilePermissionEditCell.self + + row = XLFormRowDescriptor(tag: "kNMCFilePermissionEditCellEditingCanShare", rowType: "kNMCFilePermissionEditCell", title: "") + row.cellConfig["switchControl.onTintColor"] = NCBrandColor.shared.customer + row.cellClass = NCFilePermissionEditCell.self + row.cellConfig["titleLabel.text"] = NSLocalizedString("_share_can_reshare_", comment: "") + row.height = 44 + section.addFormRow(row) + } + + //hide download + if isHideDownloadOptionVisible() { + + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFilePermissionEditCell"] = NCFilePermissionEditCell.self + row = XLFormRowDescriptor(tag: "kNMCFilePermissionEditCellHideDownload", rowType: "kNMCFilePermissionEditCell", title: NSLocalizedString("_PERMISSIONS_", comment: "")) + row.cellConfig["titleLabel.text"] = NSLocalizedString("_share_hide_download_", comment: "") + row.cellConfig["switchControl.onTintColor"] = NCBrandColor.shared.customer + row.cellClass = NCFilePermissionEditCell.self + row.height = 44 + section.addFormRow(row) + } + + //password + if isPasswordOptionsVisible() { + + // Set password + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFilePermissionEditCell"] = NCFilePermissionEditCell.self + row = XLFormRowDescriptor(tag: "kNMCFilePermissionEditPasswordCellWithText", rowType: "kNMCFilePermissionEditCell", title: NSLocalizedString("_PERMISSIONS_", comment: "")) + row.cellConfig["titleLabel.text"] = NSLocalizedString("_set_password_", comment: "") + row.cellConfig["switchControl.onTintColor"] = NCBrandColor.shared.customer + row.cellClass = NCFilePermissionEditCell.self + row.height = 44 + section.addFormRow(row) + + // enter password input field + XLFormViewController.cellClassesForRowDescriptorTypes()["NMCSetPasswordCustomInputField"] = PasswordInputField.self + row = XLFormRowDescriptor(tag: "SetPasswordInputField", rowType: "NMCSetPasswordCustomInputField", title: NSLocalizedString("_filename_", comment: "")) + row.cellClass = PasswordInputField.self + row.cellConfig["fileNameInputTextField.placeholder"] = NSLocalizedString("_password_", comment: "") + row.cellConfig["fileNameInputTextField.textAlignment"] = NSTextAlignment.left.rawValue + row.cellConfig["fileNameInputTextField.font"] = UIFont.systemFont(ofSize: 15.0) + row.cellConfig["fileNameInputTextField.textColor"] = NCBrandColor.shared.label + row.cellConfig["backgroundColor"] = NCBrandColor.shared.secondarySystemGroupedBackground + row.height = 44 + let hasPassword = oldTableShare?.password != nil && !oldTableShare!.password.isEmpty + row.hidden = NSNumber.init(booleanLiteral: !hasPassword) + section.addFormRow(row) + } + + //expiration + + // expiry date switch + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFilePermissionEditCell"] = NCFilePermissionEditCell.self + row = XLFormRowDescriptor(tag: "kNMCFilePermissionEditCellExpiration", rowType: "kNMCFilePermissionEditCell", title: NSLocalizedString("_share_expiration_date_", comment: "")) + row.cellConfig["titleLabel.text"] = NSLocalizedString("_share_expiration_date_", comment: "") + row.cellConfig["switchControl.onTintColor"] = NCBrandColor.shared.customer + row.cellClass = NCFilePermissionEditCell.self + row.height = 44 + section.addFormRow(row) + + // set expiry date field + XLFormViewController.cellClassesForRowDescriptorTypes()["kNCShareTextInputCell"] = NCShareTextInputCell.self + row = XLFormRowDescriptor(tag: "NCShareTextInputCellExpiry", rowType: "kNCShareTextInputCell", title: "") + row.cellClass = NCShareTextInputCell.self + row.cellConfig["cellTextField.placeholder"] = NSLocalizedString("_share_expiration_date_placeholder_", comment: "") + if !isNewShare { + if let date = oldTableShare?.expirationDate { + row.cellConfig["cellTextField.text"] = DateFormatter.shareExpDate.string(from: date as Date) + } + } + row.cellConfig["cellTextField.textAlignment"] = NSTextAlignment.left.rawValue + row.cellConfig["cellTextField.font"] = UIFont.systemFont(ofSize: 15.0) + row.cellConfig["cellTextField.textColor"] = NCBrandColor.shared.label + if let date = oldTableShare?.expirationDate { + row.cellConfig["cellTextField.text"] = DateFormatter.shareExpDate.string(from: date as Date) + } + row.height = 44 + let hasExpiry = oldTableShare?.expirationDate != nil + row.hidden = NSNumber.init(booleanLiteral: !hasExpiry) + section.addFormRow(row) + + if isDownloadLimitVisible() { + // DownloadLimit switch + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFilePermissionEditCell"] = NCFilePermissionEditCell.self + row = XLFormRowDescriptor(tag: "kNMCFilePermissionEditCellDownloadLimit", rowType: "kNMCFilePermissionEditCell", title: NSLocalizedString("_share_download_limit_", comment: "")) + row.cellConfig["titleLabel.text"] = NSLocalizedString("_share_download_limit_", comment: "") + row.cellConfig["switchControl.onTintColor"] = NCBrandColor.shared.customer + row.cellClass = NCFilePermissionEditCell.self + row.height = 44 + section.addFormRow(row) + + // set Download Limit field + XLFormViewController.cellClassesForRowDescriptorTypes()["kNCShareTextInputCell"] = NCShareTextInputCell.self + row = XLFormRowDescriptor(tag: "NCShareTextInputCellDownloadLimit", rowType: "kNCShareTextInputCell", title: "") + row.cellClass = NCShareTextInputCell.self + row.cellConfig["cellTextField.placeholder"] = NSLocalizedString("_share_download_limit_placeholder_", comment: "") + row.cellConfig["cellTextField.textAlignment"] = NSTextAlignment.left.rawValue + row.cellConfig["cellTextField.font"] = UIFont.systemFont(ofSize: 15.0) + row.cellConfig["cellTextField.textColor"] = NCBrandColor.shared.label + row.height = 44 + let downloadLimitSet = downloadLimit?.limit != nil + row.hidden = NSNumber.init(booleanLiteral: !downloadLimitSet) + if let value = downloadLimit?.limit { + row.cellConfig["cellTextField.text"] = "\(value)" + } + section.addFormRow(row) + + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFilePermissionCell"] = NCFilePermissionCell.self + row = XLFormRowDescriptor(tag: "kNMCDownloadLimitCell", rowType: "kNMCFilePermissionCell", title: "") + row.cellClass = NCFilePermissionCell.self + row.height = 44 + if downloadLimit?.limit != nil { + row.cellConfig["titleLabel.text"] = NSLocalizedString("_share_remaining_download_", comment: "") + " \(downloadLimit?.count ?? 0)" + } + row.cellConfig["titleLabel.textColor"] = NCBrandColor.shared.systemGray + row.disabled = true + row.hidden = NSNumber.init(booleanLiteral: !downloadLimitSet) + section.addFormRow(row) + } + + form.addFormSection(section) + self.form = form + } + + func reloadForm() { + self.form.delegate = nil + self.tableView.reloadData() + self.form.delegate = self + } + + func updateDownloadLimitUI() { + if let value = downloadLimit?.limit { + if let downloadLimitSwitchField: XLFormRowDescriptor = self.form.formRow(withTag: "kNMCFilePermissionEditCellDownloadLimit") { + if let indexPath = self.form.indexPath(ofFormRow: downloadLimitSwitchField) { + let cell = tableView.cellForRow(at: indexPath) as? NCFilePermissionEditCell + cell?.switchControl.isOn = true + } + + if let downloadLimitInputField: XLFormRowDescriptor = self.form.formRow(withTag: "NCShareTextInputCellDownloadLimit") { + downloadLimitInputField.hidden = false + if let indexPath = self.form.indexPath(ofFormRow: downloadLimitInputField) { + let cell = tableView.cellForRow(at: indexPath) as? NCShareTextInputCell + cell?.cellTextField.text = "\(value)" + } + } + + if let downloadLimitInputField: XLFormRowDescriptor = self.form.formRow(withTag: "kNMCDownloadLimitCell") { + downloadLimitInputField.hidden = false + if let indexPath = self.form.indexPath(ofFormRow: downloadLimitInputField) { + let cell = tableView.cellForRow(at: indexPath) as? NCFilePermissionCell + cell?.titleLabel.text = NSLocalizedString("_share_remaining_download_", comment: "") + " \(downloadLimit?.count ?? 0)" + } + } + } + } + } + + func getDownloadLimitSwitchCell() -> NCFilePermissionEditCell? { + if let downloadLimitSwitchField: XLFormRowDescriptor = self.form.formRow(withTag: "kNMCFilePermissionEditCellDownloadLimit") { + if let indexPath = self.form.indexPath(ofFormRow: downloadLimitSwitchField) { + let cell = tableView.cellForRow(at: indexPath) as? NCFilePermissionEditCell + return cell + } + } + return nil } + + func getDownloadLimitInputCell() -> NCShareTextInputCell? { + if let downloadLimitInputField: XLFormRowDescriptor = self.form.formRow(withTag: "NCShareTextInputCellDownloadLimit") { + if let indexPath = self.form.indexPath(ofFormRow: downloadLimitInputField) { + let cell = tableView.cellForRow(at: indexPath) as? NCShareTextInputCell + return cell + } + } + return nil + } + + // MARK: - Row Descriptor Value Changed + + override func didSelectFormRow(_ formRow: XLFormRowDescriptor!) { + guard let metadata = self.metadata else { return } + + switch formRow.tag { + case "NCFilePermissionCellRead": - override func numberOfSections(in tableView: UITableView) -> Int { - return 2 + let value = CCUtility.getPermissionsValue(byCanEdit: false, andCanCreate: false, andCanChange: false, andCanDelete: false, andCanShare: canReshareTheShare(), andIsFolder: metadata.directory) + share.permissions = value + self.oldTableShare?.setPermission(value: value) +// self.permissions = "RDNVCK" + metadata.permissions = "RDNVCK" + if let row : XLFormRowDescriptor = self.form.formRow(withTag: "NCFilePermissionCellRead") { + row.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: NCBrandColor.shared.customer, size: 25.0) + if let row1 : XLFormRowDescriptor = self.form.formRow(withTag: "kNMCFilePermissionCellEditing") { + row1.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: .clear, size: 25.0) + } + if let row2 : XLFormRowDescriptor = self.form.formRow(withTag: "NCFilePermissionCellFileDrop") { + row2.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: .clear, size: 25.0) + } + } + + self.reloadForm() + break + case "kNMCFilePermissionCellEditing": + let value = CCUtility.getPermissionsValue(byCanEdit: true, andCanCreate: true, andCanChange: true, andCanDelete: true, andCanShare: canReshareTheShare(), andIsFolder: metadata.directory) + share.permissions = value + self.oldTableShare?.setPermission(value: value) +// self.permissions = "RGDNV" + metadata.permissions = "RGDNV" + if let row : XLFormRowDescriptor = self.form.formRow(withTag: "NCFilePermissionCellRead") { + row.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: .clear, size: 25.0) + } + if let row1 : XLFormRowDescriptor = self.form.formRow(withTag: "kNMCFilePermissionCellEditing") { + row1.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: NCBrandColor.shared.customer, size: 25.0) + } + if let row2 : XLFormRowDescriptor = self.form.formRow(withTag: "NCFilePermissionCellFileDrop") { + row2.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: .clear, size: 25.0) + } + self.reloadForm() + break + case "NCFilePermissionCellFileDrop": + share.permissions = NCGlobal.shared.permissionCreateShare + + self.oldTableShare?.setPermission(value: NCGlobal.shared.permissionCreateShare) +// self.permissions = "RGDNVCK" + metadata.permissions = "RGDNVCK" + if let row : XLFormRowDescriptor = self.form.formRow(withTag: "NCFilePermissionCellRead") { + row.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: .clear, size: 25.0) + } + if let row1 : XLFormRowDescriptor = self.form.formRow(withTag: "kNMCFilePermissionCellEditing") { + row1.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: .clear, size: 25.0) + } + if let row2 : XLFormRowDescriptor = self.form.formRow(withTag: "NCFilePermissionCellFileDrop") { + row2.cellConfig["imageCheck.image"] = UIImage(named: "success")!.image(color: NCBrandColor.shared.customer, size: 25.0) + } + self.reloadForm() + break + default: + break + } } - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - if section == 0 { - // check reshare permission, if restricted add note - let maxPermission = metadata.directory ? NCGlobal.shared.permissionMaxFolderShare : NCGlobal.shared.permissionMaxFileShare - return shareConfig.resharePermission != maxPermission ? shareConfig.permissions.count + 1 : shareConfig.permissions.count - } else if section == 1 { - return shareConfig.advanced.count - } else { return 0 } + func canReshareTheShare() -> Bool { + if let permissionValue = oldTableShare?.permissions { + let canReshare = CCUtility.isPermission(toCanShare: permissionValue) + return canReshare + } else { + return false + } } - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - guard let cell = shareConfig.cellFor(indexPath: indexPath) else { - let noteCell = UITableViewCell(style: .subtitle, reuseIdentifier: "noteCell") - noteCell.detailTextLabel?.text = NSLocalizedString("_share_reshare_restricted_", comment: "") - noteCell.detailTextLabel?.isEnabled = false - noteCell.isUserInteractionEnabled = false - noteCell.detailTextLabel?.numberOfLines = 0 - return noteCell + override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { + if let advancePermissionHeaderRow: XLFormRowDescriptor = self.form.formRow(withTag: "NCFilePermissionCellAdvanceTxt") { + if let advancePermissionHeaderRowIndexPath = form.indexPath(ofFormRow: advancePermissionHeaderRow), indexPath == advancePermissionHeaderRowIndexPath { + let cell = cell as? NCFilePermissionCell + cell?.seperatorBelowFull.isHidden = isLinkShare() + } + } + + //can Reshare + if let canReshareRow: XLFormRowDescriptor = self.form.formRow(withTag: "kNMCFilePermissionEditCellEditingCanShare") { + if let canReShareRowIndexPath = form.indexPath(ofFormRow: canReshareRow), indexPath == canReShareRowIndexPath { + let cell = cell as? NCFilePermissionEditCell + // Can reshare (file) + if let permissionValue = oldTableShare?.permissions { + let canReshare = CCUtility.isPermission(toCanShare: permissionValue) + cell?.switchControl.isOn = canReshare + } else { + //new share + cell?.switchControl.isOn = false + } + } + } + //hide download + if let hideDownloadRow: XLFormRowDescriptor = self.form.formRow(withTag: "kNMCFilePermissionEditCellHideDownload"){ + if let hideDownloadRowIndexPath = form.indexPath(ofFormRow: hideDownloadRow), indexPath == hideDownloadRowIndexPath { + let cell = cell as? NCFilePermissionEditCell + cell?.switchControl.isOn = oldTableShare?.hideDownload ?? false + cell?.titleLabel.isEnabled = !(share.permissions == NCGlobal.shared.permissionCreateShare) + cell?.switchControl.isEnabled = !(share.permissions == NCGlobal.shared.permissionCreateShare) + cell?.isUserInteractionEnabled = !(share.permissions == NCGlobal.shared.permissionCreateShare) + } + + // set password + if let setPassword : XLFormRowDescriptor = self.form.formRow(withTag: "kNMCFilePermissionEditPasswordCellWithText") { + if let setPasswordIndexPath = self.form.indexPath(ofFormRow: setPassword), indexPath == setPasswordIndexPath { + let passwordCell = cell as? NCFilePermissionEditCell + if let password = oldTableShare?.password { + passwordCell?.switchControl.isOn = !password.isEmpty + } else { + passwordCell?.switchControl.isOn = false + } + } + } + } + + //updateExpiryDateSwitch + if let expiryRow : XLFormRowDescriptor = self.form.formRow(withTag: "kNMCFilePermissionEditCellExpiration") { + if let expiryIndexPath = self.form.indexPath(ofFormRow: expiryRow), indexPath == expiryIndexPath { + let cell = cell as? NCFilePermissionEditCell + if oldTableShare?.expirationDate != nil { + cell?.switchControl.isOn = true + } else { + //new share + cell?.switchControl.isOn = false + } + } + } + + //SetDownloadLimitSwitch + if let limitRow : XLFormRowDescriptor = self.form.formRow(withTag: "kNMCFilePermissionEditCellDownloadLimit") { + if let expiryIndexPath = self.form.indexPath(ofFormRow: limitRow), indexPath == expiryIndexPath { + let cell = cell as? NCFilePermissionEditCell + cell?.switchControl.isOn = downloadLimit?.limit != nil + } + } + + //SetDownloadLimitSwitch + if let downloadlimitFieldRow : XLFormRowDescriptor = self.form.formRow(withTag: "NCShareTextInputCellDownloadLimit") { + if let downloadlimitIndexPath = self.form.indexPath(ofFormRow: downloadlimitFieldRow), indexPath == downloadlimitIndexPath { + let cell = cell as? NCShareTextInputCell + cell?.cellTextField.text = "\(downloadLimit?.limit ?? 0)" + } + } + + //SetDownloadLimitSwitch + if downloadLimit?.count != nil { + if let downloadlimitFieldRow : XLFormRowDescriptor = self.form.formRow(withTag: "kNMCDownloadLimitCell") { + if let downloadlimitIndexPath = self.form.indexPath(ofFormRow: downloadlimitFieldRow), indexPath == downloadlimitIndexPath { + let cell = cell as? NCFilePermissionCell + cell?.titleLabel.text = NSLocalizedString("_share_remaining_download_", comment: "") + " \(downloadLimit?.count ?? 0)" + cell?.seperatorBelowFull.isHidden = true + cell?.seperatorBelow.isHidden = true + } + } } - if let cell = cell as? NCShareDateCell { cell.onReload = tableView.reloadData } - return cell } - override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - tableView.deselectRow(at: indexPath, animated: true) - guard let cellConfig = shareConfig.config(for: indexPath) else { return } - guard let cellConfig = cellConfig as? NCShareDetails else { - cellConfig.didSelect(for: share) - tableView.reloadData() + override func formRowDescriptorValueHasChanged(_ formRow: XLFormRowDescriptor!, oldValue: Any!, newValue: Any!) { + super.formRowDescriptorValueHasChanged(formRow, oldValue: oldValue, newValue: newValue) + + switch formRow.tag { + + case "kNMCFilePermissionEditCellEditingCanShare": + if let value = newValue as? Bool { + canReshareValueChanged(isOn: value) + } + + case "kNMCFilePermissionEditCellHideDownload": + if let value = newValue as? Bool { + share.hideDownload = value + } + + case "kNMCFilePermissionEditPasswordCellWithText": + if let value = newValue as? Bool { + if let setPasswordInputField : XLFormRowDescriptor = self.form.formRow(withTag: "SetPasswordInputField") { + if let indexPath = self.form.indexPath(ofFormRow: setPasswordInputField) { + let cell = tableView.cellForRow(at: indexPath) as? PasswordInputField + cell?.fileNameInputTextField.text = "" + } + share.password = "" + setPasswordInputField.hidden = !value + } + } + + case "kNCShareTextInputCellCustomLinkField": + if let label = formRow.value as? String { + self.form.delegate = nil + share.label = label + self.form.delegate = self + } + + case "SetPasswordInputField": + if let pwd = formRow.value as? String { + self.form.delegate = nil + share.password = pwd + self.form.delegate = self + } + + case "kNMCFilePermissionEditCellLinkLabel": + if let label = formRow.value as? String { + self.form.delegate = nil + share.label = label + self.form.delegate = self + } + + case "kNMCFilePermissionEditCellExpiration": + if let value = newValue as? Bool { + if let inputField : XLFormRowDescriptor = self.form.formRow(withTag: "NCShareTextInputCellExpiry") { + inputField.hidden = !value + } + } + + case "kNMCFilePermissionEditCellDownloadLimit": + if let value = newValue as? Bool { + self.downloadLimit = DownloadLimit() + self.downloadLimit?.limit = value ? 0 : nil + if let inputField : XLFormRowDescriptor = self.form.formRow(withTag: "NCShareTextInputCellDownloadLimit") { + inputField.hidden = !value + if let indexPath = self.form.indexPath(ofFormRow: inputField) { + let cell = tableView.cellForRow(at: indexPath) as? NCShareTextInputCell + cell?.cellTextField.text = "" + } + } + + if let inputField : XLFormRowDescriptor = self.form.formRow(withTag: "kNMCDownloadLimitCell") { + inputField.hidden = !value + if let indexPath = self.form.indexPath(ofFormRow: inputField) { + let cell = tableView.cellForRow(at: indexPath) as? NCFilePermissionCell + cell?.seperatorBelowFull.isHidden = true + cell?.seperatorBelow.isHidden = true + cell?.titleLabel.text = "" + } + } + } + + case "NCShareTextInputCellExpiry": + if let exp = formRow.value as? Date { + self.form.delegate = nil + self.share.expirationDate = exp as NSDate + self.form.delegate = self + } + + default: + break + } + } + //Check file type is collabora + func checkIsCollaboraFile() -> Bool { + guard let metadata = metadata else { + return false + } + + // EDITORS + let editors = NCUtility.shared.isDirectEditing(account: metadata.account, contentType: metadata.contentType) + let availableRichDocument = NCUtility.shared.isRichDocument(metadata) + + // RichDocument: Collabora + return (availableRichDocument && editors.count == 0) + } + + func isFileDropOptionVisible() -> Bool { + return (metadata.directory && (isLinkShare() || isExternalUserShare())) + } + + func isLinkShare() -> Bool { + return NCShareCommon.shared.isLinkShare(shareType: shareType) + } + + func isExternalUserShare() -> Bool { + return NCShareCommon.shared.isExternalUserShare(shareType: shareType) + } + + func isInternalUser() -> Bool { + return NCShareCommon.shared.isInternalUser(shareType: shareType) + } + + func isCanReshareOptionVisible() -> Bool { + return isInternalUser() + } + + func isHideDownloadOptionVisible() -> Bool { + return !isInternalUser() + } + + func isPasswordOptionsVisible() -> Bool { + return !isInternalUser() + } + + func isDownloadLimitVisible() -> Bool { + return isLinkShare() && !(metadata.directory) + } + + func canReshareValueChanged(isOn: Bool) { + + guard let oldTableShare = oldTableShare else { + self.oldTableShare?.setPermission(value: 0) + self.share.permissions = isOn ? self.share.permissions + NCGlobal.shared.permissionShareShare : self.share.permissions return } - switch cellConfig { - case .hideDownload: - share.hideDownload.toggle() - tableView.reloadData() - case .expirationDate: - let cell = tableView.cellForRow(at: indexPath) as? NCShareDateCell - cell?.textField.becomeFirstResponder() - cell?.checkMaximumDate(account: metadata.account) - case .password: - guard share.password.isEmpty else { - share.password = "" - tableView.reloadData() - return - } - let alertController = UIAlertController.password(titleKey: "_share_password_") { password in - self.share.password = password ?? "" - tableView.reloadData() - } - self.present(alertController, animated: true) - case .note: - let storyboard = UIStoryboard(name: "NCShare", bundle: nil) - guard let viewNewUserComment = storyboard.instantiateViewController(withIdentifier: "NCShareNewUserAddComment") as? NCShareNewUserAddComment else { return } - viewNewUserComment.metadata = self.metadata - viewNewUserComment.share = self.share - viewNewUserComment.onDismiss = tableView.reloadData - self.navigationController?.pushViewController(viewNewUserComment, animated: true) - case .label: - let alertController = UIAlertController.withTextField(titleKey: "_share_link_name_") { textField in - textField.placeholder = cellConfig.title - textField.text = self.share.label - } completion: { newValue in - self.share.label = newValue ?? "" - self.setNavigationTitle() - tableView.reloadData() - } - self.present(alertController, animated: true) + let canEdit = CCUtility.isAnyPermission(toEdit: oldTableShare.permissions) + let canCreate = CCUtility.isPermission(toCanCreate: oldTableShare.permissions) + let canChange = CCUtility.isPermission(toCanChange: oldTableShare.permissions) + let canDelete = CCUtility.isPermission(toCanDelete: oldTableShare.permissions) + + var permission: Int = 0 + + if metadata.directory { + permission = CCUtility.getPermissionsValue(byCanEdit: canEdit, andCanCreate: canCreate, andCanChange: canChange, andCanDelete: canDelete, andCanShare: isOn, andIsFolder: metadata.directory) + } else { + if isOn { + if canEdit { + permission = CCUtility.getPermissionsValue(byCanEdit: true, andCanCreate: true, andCanChange: true, andCanDelete: true, andCanShare: isOn, andIsFolder: metadata.directory) + } else { + permission = CCUtility.getPermissionsValue(byCanEdit: false, andCanCreate: false, andCanChange: false, andCanDelete: false, andCanShare: isOn, andIsFolder: metadata.directory) + } + } else { + if canEdit { + permission = CCUtility.getPermissionsValue(byCanEdit: true, andCanCreate: true, andCanChange: true, andCanDelete: true, andCanShare: isOn, andIsFolder: metadata.directory) + } else { + permission = CCUtility.getPermissionsValue(byCanEdit: false, andCanCreate: false, andCanChange: false, andCanDelete: false, andCanShare: isOn, andIsFolder: metadata.directory) + } + } + } + self.oldTableShare?.setPermission(value: permission) + self.share.permissions = permission + + } + + func getDownloadLimit() { + NCActivityIndicator.shared.start(backgroundView: view) + NMCCommunication.shared.getDownloadLimit(token: oldTableShare?.token ?? "") { [weak self] (downloadLimit: DownloadLimit?, error: String) in + DispatchQueue.main.async { + NCActivityIndicator.shared.stop() + if let downloadLimit = downloadLimit { + self?.downloadLimit = downloadLimit + } + self?.updateDownloadLimitUI() + } + } + } + + func setDownloadLimit(deleteLimit: Bool, limit: String) { + NMCCommunication.shared.setDownloadLimit(deleteLimit: deleteLimit, limit: limit, token: oldTableShare?.token ?? "") { (success, errorMessage) in + print(success) } } + + func showDownloadLimitError(message: String) { + let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { action in })) + self.present(alertController, animated: true) + } } diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.swift b/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.swift index d8d94aa410..ce15a5705e 100644 --- a/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.swift +++ b/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.swift @@ -32,32 +32,33 @@ class NCShareAdvancePermissionFooter: UIView { @IBOutlet weak var buttonCancel: UIButton! @IBOutlet weak var buttonNext: UIButton! weak var delegate: NCShareAdvanceFotterDelegate? - + func setupUI(delegate: NCShareAdvanceFotterDelegate?) { self.delegate = delegate - backgroundColor = .clear - + buttonCancel.addTarget(self, action: #selector(cancelClicked), for: .touchUpInside) + buttonNext.addTarget(self, action: #selector(nextClicked), for: .touchUpInside) buttonCancel.setTitle(NSLocalizedString("_cancel_", comment: ""), for: .normal) - buttonCancel.layer.cornerRadius = 25 + buttonNext.setTitle(NSLocalizedString(delegate?.isNewShare == true ? "_next_" : "_apply_changes_", comment: ""), for: .normal) + buttonCancel.layer.cornerRadius = 10 buttonCancel.layer.masksToBounds = true buttonCancel.layer.borderWidth = 1 - buttonCancel.layer.borderColor = UIColor.systemGray.cgColor - buttonCancel.backgroundColor = .secondarySystemBackground - buttonCancel.addTarget(self, action: #selector(cancelClicked), for: .touchUpInside) - buttonCancel.setTitleColor(.systemGray, for: .normal) - - buttonNext.setTitle(NSLocalizedString(delegate?.isNewShare == true ? "_share_" : "_save_", comment: ""), for: .normal) - buttonNext.layer.cornerRadius = 25 + addShadow(location: .top) + layer.cornerRadius = 10 + layer.masksToBounds = true + backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + buttonCancel.setTitleColor(NCBrandColor.shared.label, for: .normal) + buttonCancel.layer.borderColor = NCBrandColor.shared.label.cgColor + buttonCancel.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + buttonNext.setBackgroundColor(NCBrandColor.shared.customer, for: .normal) + buttonNext.setTitleColor(.white, for: .normal) + buttonNext.layer.cornerRadius = 10 buttonNext.layer.masksToBounds = true - buttonNext.backgroundColor = NCBrandColor.shared.brand - buttonNext.addTarget(self, action: #selector(nextClicked), for: .touchUpInside) - buttonNext.setTitleColor(NCBrandColor.shared.brandText, for: .normal) } - + @objc func cancelClicked() { delegate?.dismissShareAdvanceView(shouldSave: false) } - + @objc func nextClicked() { delegate?.dismissShareAdvanceView(shouldSave: true) } diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.xib b/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.xib index 40b515e7d5..f38b4931fb 100644 --- a/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.xib +++ b/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.xib @@ -1,65 +1,60 @@ - + - + - - - + + - + + - + - - - - - - - + - + - - - - - - - + + + - - + + - + - - - - - - - - diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.swift b/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.swift index e5291e8c2d..5cd55f7298 100644 --- a/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.swift +++ b/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.swift @@ -27,25 +27,54 @@ class NCShareAdvancePermissionHeader: UIView { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var fileName: UILabel! @IBOutlet weak var info: UILabel! + @IBOutlet weak var favorite: UIButton! @IBOutlet weak var fullWidthImageView: UIImageView! - + var ocId = "" + func setupUI(with metadata: tableMetadata) { + backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + fileName.textColor = NCBrandColor.shared.label + info.textColor = NCBrandColor.shared.textInfo + backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground if FileManager.default.fileExists(atPath: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) { fullWidthImageView.image = NCUtility.shared.getImageMetadata(metadata, for: frame.height) fullWidthImageView.contentMode = .scaleAspectFill imageView.isHidden = true } else { if metadata.directory { - imageView.image = metadata.e2eEncrypted ? UIImage(named: "folderEncrypted") : UIImage(named: "folder") + imageView.image = UIImage.init(named: "folder") } else if !metadata.iconName.isEmpty { - imageView.image = UIImage(named: metadata.iconName) + imageView.image = UIImage.init(named: metadata.iconName) } else { - imageView.image = NCBrandColor.cacheImages.file + imageView.image = UIImage.init(named: "file") } } + favorite.setNeedsUpdateConstraints() + favorite.layoutIfNeeded() fileName.text = metadata.fileNameView - fileName.textColor = .label - info.textColor = .secondaryLabel + fileName.textColor = NCBrandColor.shared.fileFolderName + if metadata.favorite { + favorite.setImage(NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.yellowFavorite, size: 24), for: .normal) + } else { + favorite.setImage(NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.textInfo, size: 24), for: .normal) + } + info.textColor = NCBrandColor.shared.optionItem info.text = CCUtility.transformedSize(metadata.size) + ", " + CCUtility.dateDiff(metadata.date as Date) } + + @IBAction func touchUpInsideFavorite(_ sender: UIButton) { + guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) else { return } + NCNetworking.shared.favoriteMetadata(metadata) { error in + if error == .success { + guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(metadata.ocId) else { return } + if metadata.favorite { + self.favorite.setImage(NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.yellowFavorite, size: 24), for: .normal) + } else { + self.favorite.setImage(NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.textInfo, size: 24), for: .normal) + } + } else { + NCContentPresenter.shared.showError(error: error) + } + } + } } diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.xib b/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.xib index beb60d8c5e..858193894a 100644 --- a/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.xib +++ b/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.xib @@ -1,67 +1,84 @@ - + - + - - + + - - + + - + - - + + - - + + - - + - - - - - - - - - - - + + + + + + + + + + + + + - - - - + + + + + - + + + + diff --git a/iOSClient/Share/Advanced/NCShareHeaderCustomCell.swift b/iOSClient/Share/Advanced/NCShareHeaderCustomCell.swift new file mode 100644 index 0000000000..cb5dae8c1f --- /dev/null +++ b/iOSClient/Share/Advanced/NCShareHeaderCustomCell.swift @@ -0,0 +1,30 @@ +// +// NCShareHeaderCustomCell.swift +// Nextcloud +// +// Created by T-systems on 11/08/21. +// Copyright © 2021 Marino Faggiana. All rights reserved. +// + +import UIKit + +class NCShareHeaderCustomCell: XLFormBaseCell { + + @IBOutlet weak var titleLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + self.selectionStyle = .none + self.backgroundColor = .clear + } + + override func configure() { + super.configure() + } + + override func update() { + self.backgroundColor = .clear + self.titleLabel.textColor = NCBrandColor.shared.systemGray + super.update() + } +} diff --git a/iOSClient/Share/Advanced/NCShareHeaderCustomCell.xib b/iOSClient/Share/Advanced/NCShareHeaderCustomCell.xib new file mode 100644 index 0000000000..89ba3781e5 --- /dev/null +++ b/iOSClient/Share/Advanced/NCShareHeaderCustomCell.xib @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOSClient/Share/Advanced/NCShareNewUserAddComment.swift b/iOSClient/Share/Advanced/NCShareNewUserAddComment.swift index c9a19f2740..3d9fc76141 100644 --- a/iOSClient/Share/Advanced/NCShareNewUserAddComment.swift +++ b/iOSClient/Share/Advanced/NCShareNewUserAddComment.swift @@ -26,41 +26,62 @@ import NextcloudKit import SVGKit class NCShareNewUserAddComment: UIViewController, NCShareDetail { - + @IBOutlet weak var headerContainerView: UIView! - @IBOutlet weak var sharingLabel: UILabel! - @IBOutlet weak var noteTextField: UITextView! - + @IBOutlet weak var labelSharing: UILabel! + @IBOutlet weak var labelNote: UILabel! + @IBOutlet weak var commentTextView: UITextView! + @IBOutlet weak var btnCancel: UIButton! + @IBOutlet weak var btnSendShare: UIButton! + @IBOutlet weak var buttonContainerView: UIView! let contentInsets: CGFloat = 16 - var onDismiss: (() -> Void)? - public var share: NCTableShareable! public var metadata: tableMetadata! - + var isNewShare: Bool { share is NCTableShareOptions } + var networking: NCShareNetworking? + override func viewDidLoad() { super.viewDidLoad() self.setNavigationTitle() - - NotificationCenter.default.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil) + changeTheming() + setupHeader() + } - sharingLabel.text = NSLocalizedString("_share_note_recipient_", comment: "") - - noteTextField.textContainerInset = UIEdgeInsets(top: contentInsets, left: contentInsets, bottom: contentInsets, right: contentInsets) - noteTextField.text = share.note - let toolbar = UIToolbar.toolbar { - self.noteTextField.resignFirstResponder() - self.noteTextField.text = "" - self.share.note = "" - } onDone: { - self.noteTextField.resignFirstResponder() - self.share.note = self.noteTextField.text - self.navigationController?.popViewController(animated: true) + @objc func changeTheming() { + self.view.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + self.commentTextView.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + commentTextView.textColor = NCBrandColor.shared.label + btnCancel.setTitleColor(NCBrandColor.shared.label, for: .normal) + btnCancel.layer.borderColor = NCBrandColor.shared.label.cgColor + btnCancel.backgroundColor = .clear + buttonContainerView.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + btnSendShare.setBackgroundColor(NCBrandColor.shared.customer, for: .normal) + btnSendShare.setTitleColor(.white, for: .normal) + commentTextView.layer.borderColor = NCBrandColor.shared.label.cgColor + commentTextView.layer.borderWidth = 1 + commentTextView.layer.cornerRadius = 4.0 + commentTextView.showsVerticalScrollIndicator = false + commentTextView.textContainerInset = UIEdgeInsets(top: contentInsets, left: contentInsets, bottom: contentInsets, right: contentInsets) + btnCancel.setTitle(NSLocalizedString("_cancel_", comment: ""), for: .normal) + btnCancel.layer.cornerRadius = 10 + btnCancel.layer.masksToBounds = true + btnCancel.layer.borderWidth = 1 + btnSendShare.setTitle(NSLocalizedString("_send_share_", comment: ""), for: .normal) + btnSendShare.layer.cornerRadius = 10 + btnSendShare.layer.masksToBounds = true + labelSharing.text = NSLocalizedString("_sharing_", comment: "") + labelNote.text = NSLocalizedString("_share_note_recipient_", comment: "") + commentTextView.inputAccessoryView = UIToolbar.doneToolbar { [weak self] in + self?.commentTextView.resignFirstResponder() } - - noteTextField.inputAccessoryView = toolbar.wrappedSafeAreaContainer - + } + + func setupHeader(){ guard let headerView = (Bundle.main.loadNibNamed("NCShareAdvancePermissionHeader", owner: self, options: nil)?.first as? NCShareAdvancePermissionHeader) else { return } + headerView.ocId = metadata.ocId headerContainerView.addSubview(headerView) headerView.frame = headerContainerView.frame headerView.translatesAutoresizingMaskIntoConstraints = false @@ -68,29 +89,48 @@ class NCShareNewUserAddComment: UIViewController, NCShareDetail { headerView.bottomAnchor.constraint(equalTo: headerContainerView.bottomAnchor).isActive = true headerView.leftAnchor.constraint(equalTo: headerContainerView.leftAnchor).isActive = true headerView.rightAnchor.constraint(equalTo: headerContainerView.rightAnchor).isActive = true - headerView.setupUI(with: metadata) } - - override func viewWillDisappear(_ animated: Bool) { - super.viewWillDisappear(animated) - share.note = noteTextField.text - onDismiss?() + + @IBAction func cancelClicked(_ sender: Any) { + self.navigationController?.popToRootViewController(animated: true) + } + + @IBAction func sendShareClicked(_ sender: Any) { + share.note = commentTextView.text + if isNewShare { + networking?.createShare(option: share) + } else { + networking?.updateShare(option: share) + } + self.navigationController?.popToRootViewController(animated: true) } @objc func adjustForKeyboard(notification: Notification) { guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue, - let globalTextViewFrame = noteTextField.superview?.convert(noteTextField.frame, to: nil) else { return } - + let globalTextViewFrame = commentTextView.superview?.convert(commentTextView.frame, to: nil) else { return } let keyboardScreenEndFrame = keyboardValue.cgRectValue let portionCovoredByLeyboard = globalTextViewFrame.maxY - keyboardScreenEndFrame.minY if notification.name == UIResponder.keyboardWillHideNotification || portionCovoredByLeyboard < 0 { - noteTextField.contentInset = .zero + commentTextView.contentInset = .zero } else { - noteTextField.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: portionCovoredByLeyboard, right: 0) + commentTextView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: portionCovoredByLeyboard, right: 0) + } + commentTextView.scrollIndicatorInsets = commentTextView.contentInset + } + + @objc func keyboardWillShow(notification: Notification) { + if UIScreen.main.bounds.width <= 375 { + if view.frame.origin.y == 0 { + self.view.frame.origin.y -= 200 + } + } + } + + @objc func keyboardWillHide(notification: Notification) { + if view.frame.origin.y != 0 { + self.view.frame.origin.y = 0 } - - noteTextField.scrollIndicatorInsets = noteTextField.contentInset } } diff --git a/iOSClient/Share/Advanced/NCShareTextInputCell.swift b/iOSClient/Share/Advanced/NCShareTextInputCell.swift new file mode 100644 index 0000000000..26da27ef03 --- /dev/null +++ b/iOSClient/Share/Advanced/NCShareTextInputCell.swift @@ -0,0 +1,151 @@ +// +// NCShareTextInputCell.swift +// Nextcloud +// +// Created by T-systems on 20/09/21. +// Copyright © 2021 Kunal. All rights reserved. +// + +import UIKit + +class NCShareTextInputCell: XLFormBaseCell, UITextFieldDelegate { + + @IBOutlet weak var seperator: UIView! + @IBOutlet weak var seperatorBottom: UIView! + @IBOutlet weak var cellTextField: UITextField! + @IBOutlet weak var calendarImageView: UIImageView! + + let datePicker = UIDatePicker() + var expirationDateText: String! + var expirationDate: NSDate! + + override func awakeFromNib() { + super.awakeFromNib() + self.cellTextField.delegate = self + self.cellTextField.isEnabled = true + calendarImageView.image = UIImage(named: "calender")?.imageColor(NCBrandColor.shared.brandElement) + self.selectionStyle = .none + self.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + self.cellTextField.attributedPlaceholder = NSAttributedString(string: "", + attributes: [NSAttributedString.Key.foregroundColor: NCBrandColor.shared.fileFolderName]) + self.cellTextField.textColor = NCBrandColor.shared.singleTitleColorButton + } + + override func configure() { + super.configure() + } + + override func update() { + super.update() + calendarImageView.isHidden = rowDescriptor.tag != "NCShareTextInputCellExpiry" + if rowDescriptor.tag == "NCShareTextInputCellExpiry" { + seperator.isHidden = true + setDatePicker(sender: self.cellTextField) + } else if rowDescriptor.tag == "NCShareTextInputCellDownloadLimit" { + seperator.isHidden = true + cellTextField.keyboardType = .numberPad + setDoneButton(sender: self.cellTextField) + } + } + + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + if self.cellTextField == textField { + if let rowDescriptor = rowDescriptor, let text = self.cellTextField.text { + + if (text + " ").isEmpty == false { + rowDescriptor.value = self.cellTextField.text! + string + } else { + rowDescriptor.value = nil + } + } + } + + self.formViewController().textField(textField, shouldChangeCharactersIn: range, replacementString: string) + return true + } + + func textFieldDidEndEditing(_ textField: UITextField) { + rowDescriptor.value = cellTextField.text + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + self.formViewController()?.textFieldShouldReturn(textField) + return true + } + + func textFieldShouldClear(_ textField: UITextField) -> Bool { + self.formViewController()?.textFieldShouldClear(textField) + return true + } + + override class func formDescriptorCellHeight(for rowDescriptor: XLFormRowDescriptor!) -> CGFloat { + return 30 + } + + override func formDescriptorCellDidSelected(withForm controller: XLFormViewController!) { + self.selectionStyle = .none + } + + func setDatePicker(sender: UITextField) { + //Format Date + datePicker.datePickerMode = .date + datePicker.minimumDate = Date.tomorrow + if #available(iOS 13.4, *) { + datePicker.preferredDatePickerStyle = .wheels + datePicker.sizeToFit() + } + //ToolBar + let toolbar = UIToolbar(); + toolbar.sizeToFit() + let doneButton = UIBarButtonItem(title: NSLocalizedString("_done_", comment: ""), style: .plain, target: self, action: #selector(doneDatePicker)); + let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil) + let cancelButton = UIBarButtonItem(title: NSLocalizedString("_cancel_", comment: ""), style: .plain, target: self, action: #selector(cancelDatePicker)); + + toolbar.setItems([cancelButton, spaceButton, doneButton], animated: false) + + sender.inputAccessoryView = toolbar + sender.inputView = datePicker + } + + @objc func doneDatePicker() { + let dateFormatter = DateFormatter() + dateFormatter.formatterBehavior = .behavior10_4 + dateFormatter.dateStyle = .medium + dateFormatter.dateFormat = NCShareAdvancePermission.displayDateFormat + + var expiryDate = dateFormatter.string(from: datePicker.date) + expiryDate = expiryDate.replacingOccurrences(of: "..", with: ".") + self.expirationDateText = expiryDate + + self.expirationDate = datePicker.date as NSDate + self.cellTextField.text = self.expirationDateText + self.rowDescriptor.value = self.expirationDate + self.cellTextField.endEditing(true) + } + + @objc func cancelDatePicker() { + self.cellTextField.endEditing(true) + } + + func setDoneButton(sender: UITextField) { + //ToolBar + let toolbar = UIToolbar(); + toolbar.sizeToFit() + let doneButton = UIBarButtonItem(title: NSLocalizedString("_done_", comment: ""), style: .plain, target: self, action: #selector(cancelDatePicker)); + let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil) + toolbar.setItems([spaceButton, doneButton], animated: false) + sender.inputAccessoryView = toolbar + } +} + +class NCSeparatorCell: XLFormBaseCell { + override func awakeFromNib() { + super.awakeFromNib() + selectionStyle = .none + } + + override func update() { + super.update() + self.selectionStyle = .none + } +} diff --git a/iOSClient/Share/Advanced/NCShareTextInputCell.xib b/iOSClient/Share/Advanced/NCShareTextInputCell.xib new file mode 100644 index 0000000000..eaa2f0cd13 --- /dev/null +++ b/iOSClient/Share/Advanced/NCShareTextInputCell.xib @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOSClient/Share/NCSearchUserDropDownCell.xib b/iOSClient/Share/NCSearchUserDropDownCell.xib index fa63960bcf..6c2ffde821 100755 --- a/iOSClient/Share/NCSearchUserDropDownCell.xib +++ b/iOSClient/Share/NCSearchUserDropDownCell.xib @@ -1,9 +1,9 @@ - + - + @@ -29,7 +29,7 @@ diff --git a/iOSClient/Share/NCShareLinkCell.swift b/iOSClient/Share/NCShareLinkCell.swift index 59c1c6164e..109bdf8622 100644 --- a/iOSClient/Share/NCShareLinkCell.swift +++ b/iOSClient/Share/NCShareLinkCell.swift @@ -24,12 +24,16 @@ import UIKit class NCShareLinkCell: UITableViewCell { - @IBOutlet private weak var imageItem: UIImageView! - @IBOutlet private weak var labelTitle: UILabel! - @IBOutlet private weak var descriptionLabel: UILabel! - - @IBOutlet private weak var menuButton: UIButton! - @IBOutlet private weak var copyButton: UIButton! + @IBOutlet weak var imageItem: UIImageView! + @IBOutlet weak var labelTitle: UILabel! + @IBOutlet weak var buttonCopy: UIButton! + @IBOutlet weak var buttonMenu: UIButton! + @IBOutlet weak var status: UILabel! + @IBOutlet weak var btnQuickStatus: UIButton! + @IBOutlet weak var imageDownArrow: UIImageView! + @IBOutlet weak var labelQuickStatus: UILabel! + + private let iconShare: CGFloat = 200 var tableShare: tableShare? weak var delegate: NCShareLinkCellDelegate? var isInternalLink = false @@ -40,55 +44,50 @@ class NCShareLinkCell: UITableViewCell { isInternalLink = false tableShare = nil } + + override func awakeFromNib() { + super.awakeFromNib() - func setupCellUI() { - var imageName: String - var imageBGColor: UIColor - var menuImageName = "shareMenu" - - menuButton.isHidden = isInternalLink - descriptionLabel.isHidden = !isInternalLink - copyButton.isHidden = !isInternalLink && tableShare == nil - copyButton.accessibilityLabel = NSLocalizedString("_copy_", comment: "") - menuButton.accessibilityLabel = NSLocalizedString("_more_", comment: "") + imageItem.image = UIImage(named: "sharebylink")?.image(color: NCBrandColor.shared.label, size: 30) + buttonCopy.setImage(UIImage.init(named: "shareCopy")!.image(color: NCBrandColor.shared.customer, size: 24), for: .normal) + buttonMenu.setImage(UIImage.init(named: "shareMenu")!.image(color: NCBrandColor.shared.customer, size: 24), for: .normal) + labelQuickStatus.textColor = NCBrandColor.shared.customer + } - if isInternalLink { - imageName = "shareInternalLink" - imageBGColor = .gray - labelTitle.text = NSLocalizedString("_share_internal_link_", comment: "") - descriptionLabel.text = NSLocalizedString("_share_internal_link_des_", comment: "") + func setupCellUI() { + guard let tableShare = tableShare else { + return + } + contentView.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground + labelTitle.textColor = NCBrandColor.shared.label + + if tableShare.permissions == NCGlobal.shared.permissionCreateShare { + labelQuickStatus.text = NSLocalizedString("_share_file_drop_", comment: "") } else { - labelTitle.text = NSLocalizedString("_share_link_", comment: "") - if let tableShare = tableShare { - if !tableShare.label.isEmpty { - labelTitle.text? += " (\(tableShare.label))" - } + // Read Only + if CCUtility.isAnyPermission(toEdit: tableShare.permissions) { + labelQuickStatus.text = NSLocalizedString("_share_editing_", comment: "") } else { - menuImageName = "shareAdd" - menuButton.accessibilityLabel = NSLocalizedString("_add_", comment: "") + labelQuickStatus.text = NSLocalizedString("_share_read_only_", comment: "") } - - imageName = "sharebylink" - imageBGColor = NCBrandColor.shared.brandElement - - menuButton.setImage(UIImage(named: menuImageName)?.image(color: .gray, size: 50), for: .normal) } - - labelTitle.textColor = .label - imageItem.image = NCShareCommon.shared.createLinkAvatar(imageName: imageName, colorCircle: imageBGColor) - copyButton.setImage(UIImage(named: "shareCopy")?.image(color: .gray, size: 50), for: .normal) } - - @IBAction func touchUpCopy(_ sender: Any) { + + @IBAction func touchUpInsideCopy(_ sender: Any) { delegate?.tapCopy(with: tableShare, sender: sender) } - - @IBAction func touchUpMenu(_ sender: Any) { + + @IBAction func touchUpInsideMenu(_ sender: Any) { delegate?.tapMenu(with: tableShare, sender: sender) } + + @IBAction func quickStatusClicked(_ sender: UIButton) { + delegate?.quickStatus(with: tableShare, sender: sender) + } } protocol NCShareLinkCellDelegate: AnyObject { func tapCopy(with tableShare: tableShare?, sender: Any) func tapMenu(with tableShare: tableShare?, sender: Any) + func quickStatus(with tableShare: tableShare?, sender: Any) } diff --git a/iOSClient/Share/NCShareLinkCell.xib b/iOSClient/Share/NCShareLinkCell.xib index b5172d16f8..c3f13f8fec 100755 --- a/iOSClient/Share/NCShareLinkCell.xib +++ b/iOSClient/Share/NCShareLinkCell.xib @@ -1,107 +1,120 @@ - + - - + - + - + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + - - - - - + + + + + + + + - + - - - diff --git a/iOSClient/Share/NCShareNetworking.swift b/iOSClient/Share/NCShareNetworking.swift index e17da597c9..64078616e2 100644 --- a/iOSClient/Share/NCShareNetworking.swift +++ b/iOSClient/Share/NCShareNetworking.swift @@ -25,9 +25,7 @@ import NextcloudKit class NCShareNetworking: NSObject { - // swiftlint:disable force_cast private let appDelegate = UIApplication.shared.delegate as! AppDelegate - // swiftlint:enable force_cast weak var delegate: NCShareNetworkingDelegate? var view: UIView @@ -50,12 +48,12 @@ class NCShareNetworking: NSObject { let filenamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account)! let parameter = NKShareParameter(path: filenamePath) - NextcloudKit.shared.readShares(parameters: parameter) { account, shares, _, error in + NextcloudKit.shared.readShares(parameters: parameter) { account, shares, data, error in if error == .success, let shares = shares { - NCManageDatabase.shared.deleteTableShare(account: account, path: "/" + filenamePath) + NCManageDatabase.shared.deleteTableShare(account: account, filePath: filenamePath) let home = NCUtilityFileSystem.shared.getHomeServer(urlBase: self.metadata.urlBase, userId: self.metadata.userId) - NCManageDatabase.shared.addShare(account: self.metadata.account, home: home, shares: shares) - NextcloudKit.shared.getGroupfolders { account, results, _, error in + NCManageDatabase.shared.addShare(account: self.metadata.account, home:home, shares: shares) + NextcloudKit.shared.getGroupfolders() { account, results, data, error in if showLoadingIndicator { NCActivityIndicator.shared.stop() } @@ -73,19 +71,34 @@ class NCShareNetworking: NSObject { } } } + + func createShareLink(password: String?) { + NCActivityIndicator.shared.start(backgroundView: view) + let filenamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account)! + NextcloudKit.shared.createShareLink(path: filenamePath) { account, share, data, error in + NCActivityIndicator.shared.stop() + if error == .success && share != nil { + let home = NCUtilityFileSystem.shared.getHomeServer(urlBase: self.metadata.urlBase, userId: self.metadata.userId) + NCManageDatabase.shared.addShare(account: self.metadata.account, home:home, shares: [share!]) + } else if error != .success{ + NCContentPresenter.shared.showError(error: error) + } + self.delegate?.shareCompleted() + } + } func createShare(option: NCTableShareable) { // NOTE: Permissions don't work for creating with file drop! // https://github.com/nextcloud/server/issues/17504 - // NOTE: Can't save label and expirationDate in the same request. + // NOTE: Can't save label, expirationDate, and note in same request. // Library update needed: // https://github.com/nextcloud/ios-communication-library/pull/104 NCActivityIndicator.shared.start(backgroundView: view) let filenamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account)! - NextcloudKit.shared.createShare(path: filenamePath, shareType: option.shareType, shareWith: option.shareWith, password: option.password, note: option.note, permissions: option.permissions, attributes: option.attributes) { _, share, _, error in + NextcloudKit.shared.createShare(path: filenamePath, shareType: option.shareType, shareWith: option.shareWith, password: option.password, permissions: option.permissions, attributes: option.attributes) { (account, share, data, error) in NCActivityIndicator.shared.stop() if error == .success, let share = share { option.idShare = share.idShare @@ -116,7 +129,7 @@ class NCShareNetworking: NSObject { func updateShare(option: NCTableShareable) { NCActivityIndicator.shared.start(backgroundView: view) - NextcloudKit.shared.updateShare(idShare: option.idShare, password: option.password, expireDate: option.expDateString, permissions: option.permissions, note: option.note, label: option.label, hideDownload: option.hideDownload, attributes: option.attributes) { _, share, _, error in + NextcloudKit.shared.updateShare(idShare: option.idShare, password: option.password, expireDate: option.expDateString, permissions: option.permissions, note: option.note, label: option.label, hideDownload: option.hideDownload, attributes: option.attributes) { account, share, data, error in NCActivityIndicator.shared.stop() if error == .success, let share = share { let home = NCUtilityFileSystem.shared.getHomeServer(urlBase: self.metadata.urlBase, userId: self.metadata.userId) @@ -131,7 +144,7 @@ class NCShareNetworking: NSObject { func getSharees(searchString: String) { NCActivityIndicator.shared.start(backgroundView: view) - NextcloudKit.shared.searchSharees(search: searchString) { _, sharees, _, error in + NextcloudKit.shared.searchSharees(search: searchString) { _, sharees, data, error in NCActivityIndicator.shared.stop() if error == .success { self.delegate?.getSharees(sharees: sharees) diff --git a/iOSClient/Share/NCSharePaging.swift b/iOSClient/Share/NCSharePaging.swift index 64bde1f20f..ad37aa29e9 100644 --- a/iOSClient/Share/NCSharePaging.swift +++ b/iOSClient/Share/NCSharePaging.swift @@ -52,7 +52,7 @@ class NCSharePaging: UIViewController { view.backgroundColor = .systemBackground title = NSLocalizedString("_details_", comment: "") - navigationItem.leftBarButtonItem = UIBarButtonItem(title: NSLocalizedString("_close_", comment: ""), style: .done, target: self, action: #selector(exitTapped)) + navigationItem.leftBarButtonItem = UIBarButtonItem(title: NSLocalizedString("_cancel_", comment: ""), style: .done, target: self, action: #selector(exitTapped)) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(applicationDidEnterBackground(notification:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterApplicationDidEnterBackground), object: nil) @@ -265,129 +265,72 @@ class NCSharePagingView: PagingView { fatalError("init(coder:) has not been implemented") } - override func setupConstraints() { - - guard let headerView = Bundle.main.loadNibNamed("NCShareHeaderView", owner: self, options: nil)?.first as? NCShareHeaderView else { return } - headerView.backgroundColor = .systemBackground - headerView.ocId = metadata.ocId - - let dateFormatter = DateFormatter() - dateFormatter.dateStyle = .short - dateFormatter.timeStyle = .short - dateFormatter.locale = Locale.current - - if FileManager.default.fileExists(atPath: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) { - headerView.imageView.image = UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) - } else { - if metadata.directory { - let image = metadata.e2eEncrypted ? UIImage(named: "folderEncrypted") : UIImage(named: "folder") - headerView.imageView.image = image?.image(color: NCBrandColor.shared.brandElement, size: image?.size.width ?? 0) - headerView.imageView.image = headerView.imageView.image?.colorizeFolder(metadata: metadata) - } else if !metadata.iconName.isEmpty { - headerView.imageView.image = UIImage(named: metadata.iconName) - } else { - headerView.imageView.image = UIImage(named: "file") - } - } - headerView.path.text = NCUtilityFileSystem.shared.getPath(path: metadata.path, user: metadata.user, fileName: metadata.fileName) - headerView.path.textColor = .label - headerView.path.trailingBuffer = headerView.path.frame.width - if metadata.favorite { - headerView.favorite.setImage(NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.yellowFavorite, size: 20), for: .normal) - } else { - headerView.favorite.setImage(NCUtility.shared.loadImage(named: "star.fill", color: .systemGray, size: 20), for: .normal) - } - headerView.info.text = CCUtility.transformedSize(metadata.size) + ", " + NSLocalizedString("_modified_", comment: "") + " " + dateFormatter.string(from: metadata.date as Date) - headerView.info.textColor = .systemGray - headerView.creation.text = NSLocalizedString("_creation_", comment: "") + " " + dateFormatter.string(from: metadata.creationDate as Date) - headerView.creation.textColor = .systemGray - headerView.upload.text = NSLocalizedString("_upload_", comment: "") + " " + dateFormatter.string(from: metadata.uploadDate as Date) - headerView.upload.textColor = .systemGray - - headerView.details.setTitleColor(.label, for: .normal) - headerView.details.setTitle(NSLocalizedString("_details_", comment: ""), for: .normal) - headerView.details.layer.cornerRadius = 9 - headerView.details.layer.masksToBounds = true - headerView.details.layer.backgroundColor = UIColor(red: 152.0 / 255.0, green: 167.0 / 255.0, blue: 181.0 / 255.0, alpha: 0.8).cgColor - - for tag in metadata.tags { - headerView.tagListView.addTag(tag) - } - - if metadata.tags.isEmpty { - NCSharePagingView.tagHeaderHeight = 0 - } else { - NCSharePagingView.tagHeaderHeight = headerView.tagListView.intrinsicContentSize.height + 10 - } - - addSubview(headerView) - - collectionView.translatesAutoresizingMaskIntoConstraints = false - headerView.translatesAutoresizingMaskIntoConstraints = false - pageView.translatesAutoresizingMaskIntoConstraints = false - - NSLayoutConstraint.activate([ - collectionView.leadingAnchor.constraint(equalTo: leadingAnchor), - collectionView.trailingAnchor.constraint(equalTo: trailingAnchor), - collectionView.heightAnchor.constraint(equalToConstant: options.menuHeight), - collectionView.topAnchor.constraint(equalTo: headerView.bottomAnchor), - - headerView.topAnchor.constraint(equalTo: topAnchor), - headerView.leadingAnchor.constraint(equalTo: leadingAnchor), - headerView.trailingAnchor.constraint(equalTo: trailingAnchor), - headerView.heightAnchor.constraint(equalToConstant: NCSharePagingView.headerHeight + NCSharePagingView.tagHeaderHeight), - - pageView.leadingAnchor.constraint(equalTo: leadingAnchor), - pageView.trailingAnchor.constraint(equalTo: trailingAnchor), - pageView.bottomAnchor.constraint(equalTo: bottomAnchor), - pageView.topAnchor.constraint(equalTo: topAnchor, constant: 10) - ]) - } } class NCShareHeaderView: UIView { @IBOutlet weak var imageView: UIImageView! - @IBOutlet weak var path: MarqueeLabel! + @IBOutlet weak var fileName: UILabel! @IBOutlet weak var info: UILabel! - @IBOutlet weak var creation: UILabel! - @IBOutlet weak var upload: UILabel! @IBOutlet weak var favorite: UIButton! - @IBOutlet weak var details: UIButton! - @IBOutlet weak var tagListView: TagListView! + @IBOutlet weak var labelSharing: UILabel! + @IBOutlet weak var labelSharingInfo: UILabel! + @IBOutlet weak var fullWidthImageView: UIImageView! + @IBOutlet weak var canShareInfoView: UIView! + @IBOutlet weak var sharedByLabel: UILabel! + @IBOutlet weak var resharingAllowedLabel: UILabel! + @IBOutlet weak var sharedByImageView: UIImageView! + @IBOutlet weak var constraintTopSharingLabel: NSLayoutConstraint! var ocId = "" override func awakeFromNib() { super.awakeFromNib() - let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.longTap)) - path.addGestureRecognizer(longGesture) + setupUI() } + func setupUI() { + labelSharing.text = NSLocalizedString("_sharing_", comment: "") + labelSharingInfo.text = NSLocalizedString("_sharing_message_", comment: "") + + if UIScreen.main.bounds.width < 376 { + constraintTopSharingLabel.constant = 15 + } + } + + func updateCanReshareUI() { + let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) + var isCurrentUser = true + if let ownerId = metadata?.ownerId, !ownerId.isEmpty { + isCurrentUser = NCShareCommon.shared.isCurrentUserIsFileOwner(fileOwnerId: ownerId) + } + let canReshare = NCShareCommon.shared.canReshare(withPermission: metadata?.permissions ?? "") + canShareInfoView.isHidden = isCurrentUser + labelSharingInfo.isHidden = !isCurrentUser + + if !isCurrentUser { + sharedByImageView.image = UIImage(named: "cloudUpload")?.image(color: .systemBlue, size: 26) + let ownerName = metadata?.ownerDisplayName ?? "" + sharedByLabel.text = NSLocalizedString("_shared_with_you_by_", comment: "") + " " + ownerName + let resharingAllowedMessage = NSLocalizedString("_share_reshare_allowed_", comment: "") + " " + NSLocalizedString("_sharing_message_", comment: "") + let resharingNotAllowedMessage = NSLocalizedString("_share_reshare_not_allowed_", comment: "") + resharingAllowedLabel.text = canReshare ? resharingAllowedMessage : resharingNotAllowedMessage + } + } + @IBAction func touchUpInsideFavorite(_ sender: UIButton) { guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) else { return } NCNetworking.shared.favoriteMetadata(metadata) { error in if error == .success { guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(metadata.ocId) else { return } - self.favorite.setImage(NCUtility.shared.loadImage( - named: "star.fill", - color: metadata.favorite ? NCBrandColor.shared.yellowFavorite : .systemGray, - size: 20), for: .normal) + if metadata.favorite { + self.favorite.setImage(NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.yellowFavorite, size: 24), for: .normal) + } else { + self.favorite.setImage(NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.textInfo, size: 24), for: .normal) + } } else { NCContentPresenter.shared.showError(error: error) } } } - - @IBAction func touchUpInsideDetails(_ sender: UIButton) { - - creation.isHidden = !creation.isHidden - upload.isHidden = !upload.isHidden - } - - @objc func longTap(sender: UIGestureRecognizer) { - UIPasteboard.general.string = path.text - let error = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_copied_path_") - NCContentPresenter.shared.showInfo(error: error) - } } diff --git a/iOSClient/Share/NCShareSectionHeaderView.swift b/iOSClient/Share/NCShareSectionHeaderView.swift new file mode 100644 index 0000000000..dd0fff1458 --- /dev/null +++ b/iOSClient/Share/NCShareSectionHeaderView.swift @@ -0,0 +1,85 @@ +// +// NCShareSectionHeaderView.swift +// Nextcloud +// +// Created by A200020526 on 04/03/22. +// Copyright © 2022 Marino Faggiana. All rights reserved. +// + +import UIKit + +class NCShareSectionHeaderView: UITableViewHeaderFooterView { + + @IBOutlet weak var imageView: UIImageView! + @IBOutlet weak var fileName: UILabel! + @IBOutlet weak var info: UILabel! + @IBOutlet weak var favorite: UIButton! + @IBOutlet weak var labelSharing: UILabel! + @IBOutlet weak var labelSharingInfo: UILabel! + @IBOutlet weak var fullWidthImageView: UIImageView! + @IBOutlet weak var canShareInfoView: UIView! + @IBOutlet weak var sharedByLabel: UILabel! + @IBOutlet weak var resharingAllowedLabel: UILabel! + @IBOutlet weak var sharedByImageView: UIImageView! + @IBOutlet weak var constraintTopSharingLabel: NSLayoutConstraint! + + var ocId = "" + + static var nib: UINib { + return UINib(nibName: identifier, bundle: nil) + } + + static var identifier: String { + return String(describing: self) + } + + override func awakeFromNib() { + super.awakeFromNib() + setupUI() + } + + func setupUI() { + labelSharing.text = NSLocalizedString("_sharing_", comment: "") + labelSharingInfo.text = NSLocalizedString("_sharing_message_", comment: "") + + if UIScreen.main.bounds.width < 350 { + constraintTopSharingLabel.constant = 15 + } + } + + func updateCanReshareUI() { + let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) + var isCurrentUser = true + if let ownerId = metadata?.ownerId, !ownerId.isEmpty { + isCurrentUser = NCShareCommon.shared.isCurrentUserIsFileOwner(fileOwnerId: ownerId) + } + let canReshare = NCShareCommon.shared.canReshare(withPermission: metadata?.permissions ?? "") + canShareInfoView.isHidden = isCurrentUser + labelSharingInfo.isHidden = !isCurrentUser + + if !isCurrentUser { + sharedByImageView.image = UIImage(named: "cloudUpload")?.image(color: .systemBlue, size: 26) + let ownerName = metadata?.ownerDisplayName ?? "" + sharedByLabel.text = NSLocalizedString("_shared_with_you_by_", comment: "") + " " + ownerName + let resharingAllowedMessage = NSLocalizedString("_share_reshare_allowed_", comment: "") + let resharingNotAllowedMessage = NSLocalizedString("_share_reshare_not_allowed_", comment: "") + resharingAllowedLabel.text = canReshare ? resharingAllowedMessage : resharingNotAllowedMessage + } + } + + @IBAction func touchUpInsideFavorite(_ sender: UIButton) { + if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) { + NCNetworking.shared.favoriteMetadata(metadata) { error in + if error == .success { + if !metadata.favorite { + self.favorite.setImage(NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.yellowFavorite, size: 24), for: .normal) + } else { + self.favorite.setImage(NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.textInfo, size: 24), for: .normal) + } + } else { + NCContentPresenter.shared.showError(error: error) + } + } + } + } +} diff --git a/iOSClient/Share/NCShareSectionHeaderView.xib b/iOSClient/Share/NCShareSectionHeaderView.xib new file mode 100644 index 0000000000..e961e99153 --- /dev/null +++ b/iOSClient/Share/NCShareSectionHeaderView.xib @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOSClient/Share/NCShareUserCell.swift b/iOSClient/Share/NCShareUserCell.swift index 2e4efffdff..3ff19fabae 100644 --- a/iOSClient/Share/NCShareUserCell.swift +++ b/iOSClient/Share/NCShareUserCell.swift @@ -28,25 +28,19 @@ class NCShareUserCell: UITableViewCell, NCCellProtocol { @IBOutlet weak var imageItem: UIImageView! @IBOutlet weak var labelTitle: UILabel! + @IBOutlet weak var labelCanEdit: UILabel! + @IBOutlet weak var switchCanEdit: UISwitch! @IBOutlet weak var buttonMenu: UIButton! @IBOutlet weak var imageStatus: UIImageView! @IBOutlet weak var status: UILabel! @IBOutlet weak var btnQuickStatus: UIButton! + @IBOutlet weak var labelQuickStatus: UILabel! @IBOutlet weak var imageDownArrow: UIImageView! - private var index = IndexPath() - var tableShare: tableShare? weak var delegate: NCShareUserCellDelegate? - var indexPath: IndexPath { - get { return index } - set { index = newValue } - } - var fileAvatarImageView: UIImageView? { - return imageItem - } var fileUser: String? { get { return tableShare?.shareWith } set {} @@ -56,36 +50,40 @@ class NCShareUserCell: UITableViewCell, NCCellProtocol { guard let tableShare = tableShare else { return } - self.accessibilityCustomActions = [UIAccessibilityCustomAction( - name: NSLocalizedString("_show_profile_", comment: ""), - target: self, - selector: #selector(tapAvatarImage))] - + contentView.backgroundColor = NCBrandColor.shared.secondarySystemGroupedBackground labelTitle.text = tableShare.shareWithDisplayname - labelTitle.textColor = .label + labelTitle.textColor = NCBrandColor.shared.label + labelCanEdit.text = NSLocalizedString("_share_permission_edit_", comment: "") + labelCanEdit.textColor = NCBrandColor.shared.iconColor isUserInteractionEnabled = true - labelQuickStatus.isHidden = false - imageDownArrow.isHidden = false + switchCanEdit.isHidden = true//false + labelCanEdit.isHidden = true//false buttonMenu.isHidden = false - buttonMenu.accessibilityLabel = NSLocalizedString("_more_", comment: "") imageItem.image = NCShareCommon.shared.getImageShareType(shareType: tableShare.shareType) - let status = NCUtility.shared.getUserStatus(userIcon: tableShare.userIcon, userStatus: tableShare.userStatus, userMessage: tableShare.userMessage) imageStatus.image = status.onlineStatus self.status.text = status.statusMessage - + + if CCUtility.isAnyPermission(toEdit: tableShare.permissions) { + switchCanEdit.setOn(true, animated: false) + } else { + switchCanEdit.setOn(false, animated: false) + } + // If the initiator or the recipient is not the current user, show the list of sharees without any options to edit it. if tableShare.uidOwner != userId && tableShare.uidFileOwner != userId { - isUserInteractionEnabled = false - labelQuickStatus.isHidden = true - imageDownArrow.isHidden = true - buttonMenu.isHidden = true + isUserInteractionEnabled = false + switchCanEdit.isHidden = true + labelCanEdit.isHidden = true + buttonMenu.isHidden = true } - - btnQuickStatus.accessibilityHint = NSLocalizedString("_user_sharee_footer_", comment: "") btnQuickStatus.setTitle("", for: .normal) btnQuickStatus.contentHorizontalAlignment = .left - + + btnQuickStatus.isEnabled = true + labelQuickStatus.textColor = NCBrandColor.shared.brand + imageDownArrow.image = UIImage(named: "downArrow")?.imageColor(NCBrandColor.shared.brand) + if tableShare.permissions == NCGlobal.shared.permissionCreateShare { labelQuickStatus.text = NSLocalizedString("_share_file_drop_", comment: "") } else { @@ -100,12 +98,11 @@ class NCShareUserCell: UITableViewCell, NCCellProtocol { override func awakeFromNib() { super.awakeFromNib() - let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapAvatarImage)) - imageItem?.addGestureRecognizer(tapGesture) - - buttonMenu.setImage(UIImage(named: "shareMenu")?.image(color: .gray, size: 50), for: .normal) + switchCanEdit.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) + switchCanEdit.onTintColor = NCBrandColor.shared.brandElement + buttonMenu.setImage(UIImage.init(named: "shareMenu")!.image(color: NCBrandColor.shared.customer, size: 24), for: .normal) labelQuickStatus.textColor = NCBrandColor.shared.customer - imageDownArrow.image = NCUtility.shared.loadImage(named: "arrowtriangle.down.fill", color: NCBrandColor.shared.customer) + imageDownArrow.image = UIImage(named: "downArrow")?.imageColor(NCBrandColor.shared.customer) } @objc func tapAvatarImage(_ sender: UITapGestureRecognizer) { @@ -138,12 +135,7 @@ class NCSearchUserDropDownCell: DropDownCell, NCCellProtocol { @IBOutlet weak var centerTitle: NSLayoutConstraint! private var user: String = "" - private var index = IndexPath() - var indexPath: IndexPath { - get { return index } - set { index = newValue } - } var fileAvatarImageView: UIImageView? { return imageItem } @@ -153,8 +145,7 @@ class NCSearchUserDropDownCell: DropDownCell, NCCellProtocol { } func setupCell(sharee: NKSharee, baseUrl: NCUserBaseUrl) { - imageItem.image = NCShareCommon.shared.getImageShareType(shareType: sharee.shareType) - imageShareeType.image = NCShareCommon.shared.getImageShareType(shareType: sharee.shareType) + imageShareeType.image = NCShareCommon.shared.getImageShareType(shareType: sharee.shareType, isDropDown: true) let status = NCUtility.shared.getUserStatus(userIcon: sharee.userIcon, userStatus: sharee.userStatus, userMessage: sharee.userMessage) imageStatus.image = status.onlineStatus self.status.text = status.statusMessage @@ -163,31 +154,5 @@ class NCSearchUserDropDownCell: DropDownCell, NCCellProtocol { } else { centerTitle.constant = 0 } - - imageItem.image = NCUtility.shared.loadUserImage( - for: sharee.shareWith, - displayName: nil, - userBaseUrl: baseUrl) - - let fileName = baseUrl.userBaseUrl + "-" + sharee.shareWith + ".png" - if NCManageDatabase.shared.getImageAvatarLoaded(fileName: fileName) == nil { - let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + fileName - let etag = NCManageDatabase.shared.getTableAvatar(fileName: fileName)?.etag - - NextcloudKit.shared.downloadAvatar( - user: sharee.shareWith, - fileNameLocalPath: fileNameLocalPath, - sizeImage: NCGlobal.shared.avatarSize, - avatarSizeRounded: NCGlobal.shared.avatarSizeRounded, - etag: etag) { _, imageAvatar, _, etag, error in - - if error == .success, let etag = etag, let imageAvatar = imageAvatar { - NCManageDatabase.shared.addAvatar(fileName: fileName, etag: etag) - self.imageItem.image = imageAvatar - } else if error.errorCode == NCGlobal.shared.errorNotModified, let imageAvatar = NCManageDatabase.shared.setAvatarLoaded(fileName: fileName) { - self.imageItem.image = imageAvatar - } - } - } } } diff --git a/iOSClient/Share/NCShareUserCell.xib b/iOSClient/Share/NCShareUserCell.xib index ee4046f986..d4a63e809b 100755 --- a/iOSClient/Share/NCShareUserCell.xib +++ b/iOSClient/Share/NCShareUserCell.xib @@ -1,26 +1,26 @@ - + - + - + - + - - + + - - + + @@ -32,101 +32,128 @@ - - + - - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + - diff --git a/iOSClient/Share/ShareDownloadLimitNetwork.swift b/iOSClient/Share/ShareDownloadLimitNetwork.swift new file mode 100644 index 0000000000..41a55f9324 --- /dev/null +++ b/iOSClient/Share/ShareDownloadLimitNetwork.swift @@ -0,0 +1,146 @@ +// +// ShareDownloadLimitNetwork.swift +// Nextcloud +// +// Created by A118830248 on 11/11/21. +// Copyright © 2021 Marino Faggiana. All rights reserved. +// + +import Foundation +import SwiftyJSON +import NextcloudKit +import Alamofire + +class NMCCommunication: NSObject, XMLParserDelegate { + + public static let shared: NMCCommunication = { + let instance = NMCCommunication() + return instance + }() + + var message = "" + var foundCharacters = ""; + var downloadLimit = DownloadLimit() + private lazy var appDelegate = UIApplication.shared.delegate as? AppDelegate + + func getDownloadLimit(token: String, completion: @escaping (_ downloadLimit: DownloadLimit?, _ errorDescription: String) -> Void) { + let baseUrl = appDelegate?.urlBase ?? "" // NCBrandOptions.shared.loginBaseUrl + let endPoint = "/ocs/v2.php/apps/files_downloadlimit/\(token)/limit" + let path = baseUrl+endPoint + do { + var urlRequest = try URLRequest(url: URL(string: path)!, method: .get) + urlRequest.addValue("true", forHTTPHeaderField: "OCS-APIREQUEST") + + let sessionConfiguration = URLSessionConfiguration.default + let urlSession = URLSession(configuration: sessionConfiguration) + + let task = urlSession.dataTask(with: urlRequest) { [self] (data, response, error) in + guard error == nil else { + completion(nil, error?.localizedDescription ?? "") + return + } + + if let httpResponse = response as? HTTPURLResponse { + let statusCode = httpResponse.statusCode + print("url: \(String(describing: httpResponse.url))\nStatus Code: \(statusCode)") + if httpResponse.statusCode == 200 { + let parser = XMLParser(data: data!) + parser.delegate = self + parser.parse() + completion(self.downloadLimit, self.message) + } else { + completion(nil, "Invalid Response code: \(statusCode)") + } + } else { + completion(nil, error?.localizedDescription ?? "Invalid Response") + } + } + task.resume() + } catch { + completion(nil, error.localizedDescription) + } + } + + func setDownloadLimit(deleteLimit: Bool, limit: String, token: String, completion: @escaping (_ success: Bool, _ errorDescription: String) -> Void) { + let baseUrl = appDelegate?.urlBase ?? "" //NCBrandOptions.shared.loginBaseUrl + let endPoint = "/ocs/v2.php/apps/files_downloadlimit/\(token)/limit" + let path = baseUrl+endPoint + do { + + let method = deleteLimit ? HTTPMethod.delete : .put + var urlRequest = try URLRequest(url: URL(string: path)!, method: method) + + urlRequest.addValue("true", forHTTPHeaderField: "OCS-APIREQUEST") + urlRequest.addValue(authorizationToken(), forHTTPHeaderField: "Authorization") + urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type") + + let parameters = ["token": token, "limit": limit] + + let encoder = JSONEncoder() + let jsonData = try encoder.encode(parameters) + urlRequest.httpBody = jsonData + + let sessionConfiguration = URLSessionConfiguration.default + let urlSession = URLSession(configuration: sessionConfiguration) + + let task = urlSession.dataTask(with: urlRequest) { (data, response, error) in + guard error == nil else { + completion(false, error?.localizedDescription ?? "") + return + } + + if let httpResponse = response as? HTTPURLResponse { + let statusCode = httpResponse.statusCode + print("url: \(String(describing: httpResponse.url))\nStatus Code: \(statusCode)") + if httpResponse.statusCode == 200 { + completion(true, error?.localizedDescription ?? "") + } else { + completion(false, "Invalid Response code: \(statusCode)") + } + } else { + completion(false, error?.localizedDescription ?? "Invalid Response") + } + } + task.resume() + } catch { + completion(false, error.localizedDescription) + } + } + + public func authorizationToken() -> String { + let accountDetails = NCManageDatabase.shared.getAllAccount().first + let password = CCUtility.getPassword(accountDetails?.account) ?? "" + let username = accountDetails?.user ?? "" + let credential = Data("\(username):\(password)".utf8).base64EncodedString() + return ("Basic \(credential)") + } + + + // MARK:- XML Parser Delegate + public func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) { + + } + public func parser(_ parser: XMLParser, foundCharacters string: String) { + self.foundCharacters += string; + } + + public func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { + if elementName == "limit" { + let limit = self.foundCharacters.replacingOccurrences(of: "\n", with: "") + self.downloadLimit.limit = Int(limit.trimmingCharacters(in: .whitespaces)) + } + if elementName == "count" { + let count = self.foundCharacters.replacingOccurrences(of: "\n", with: "") + self.downloadLimit.count = Int(count.trimmingCharacters(in: .whitespaces)) + } + if elementName == "message"{ + self.message = self.foundCharacters + } + self.foundCharacters = "" + } +} + +struct DownloadLimit: Codable { + var limit: Int? + var count: Int? +}