Эх сурвалжийг харах

Merge branch 'develop' of https://github.com/nextcloud/ios into 2460-add-other-nextcloud-apps-to-settings-as-suggestions

Milen Pivchev 1 жил өмнө
parent
commit
98976eeacc

+ 1 - 1
Brand/Database.swift

@@ -26,4 +26,4 @@ import Foundation
 // Database Realm
 //
 let databaseName                    = "nextcloud.realm"
-let databaseSchemaVersion: UInt64   = 299
+let databaseSchemaVersion: UInt64   = 301

+ 2 - 2
ExternalResources/NCApplicationHandle.swift

@@ -32,8 +32,8 @@ class NCApplicationHandle: NSObject {
 
     // class: AppDelegate
     // func nextcloudPushNotificationAction(data: [String: AnyObject])
-    func nextcloudPushNotificationAction(data: [String: AnyObject], completion: @escaping (_ detected: Bool) -> Void) {
-        completion(false)
+    func nextcloudPushNotificationAction(data: [String: AnyObject], completion: @escaping () -> Void) {
+        completion()
     }
 
     // class: AppDelegate

+ 3 - 3
Nextcloud.xcodeproj/project.pbxproj

@@ -4604,7 +4604,7 @@
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 1;
+				CURRENT_PROJECT_VERSION = 2;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DEVELOPMENT_TEAM = NKUJUXUJ3B;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -4669,7 +4669,7 @@
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 1;
+				CURRENT_PROJECT_VERSION = 2;
 				DEVELOPMENT_TEAM = NKUJUXUJ3B;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;
@@ -4976,7 +4976,7 @@
 			repositoryURL = "https://github.com/nextcloud/NextcloudKit";
 			requirement = {
 				kind = exactVersion;
-				version = 2.6.0;
+				version = 2.7.0;
 			};
 		};
 		F788ECC5263AAAF900ADC67F /* XCRemoteSwiftPackageReference "MarkdownKit" */ = {

+ 28 - 32
iOSClient/AppDelegate.swift

@@ -230,9 +230,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         // Request TouchID, FaceID
         enableTouchFaceID()
         
-        NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterApplicationWillEnterForeground)
         NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterRichdocumentGrabFocus)
-        NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataSourceNetwork)
+        NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataSourceNetwork, second: 2)
     }
 
     // L' applicazione si dimetterà dallo stato di attivo
@@ -440,37 +439,35 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
     }
 
     func nextcloudPushNotificationAction(data: [String: AnyObject]) {
-        NCApplicationHandle().nextcloudPushNotificationAction(data: data) { detected in
-            if !detected {
-
-                var findAccount: Bool = false
-
-                if let accountPush = data["account"] as? String,
-                   let app = data["app"] as? String,
-                   app == NCGlobal.shared.twofactorNotificatioName {
-                    if accountPush == self.account {
-                        findAccount = true
-                    } else {
-                        let accounts = NCManageDatabase.shared.getAllAccount()
-                        for account in accounts {
-                            if account.account == accountPush {
-                                self.changeAccount(account.account)
-                                findAccount = true
-                            }
+        NCApplicationHandle().nextcloudPushNotificationAction(data: data) {
+
+            var findAccount: Bool = false
+
+            if let accountPush = data["account"] as? String,
+               let app = data["app"] as? String,
+               app == NCGlobal.shared.twoFactorNotificatioName {
+                if accountPush == self.account {
+                    findAccount = true
+                } else {
+                    let accounts = NCManageDatabase.shared.getAllAccount()
+                    for account in accounts {
+                        if account.account == accountPush {
+                            self.changeAccount(account.account)
+                            findAccount = true
                         }
                     }
-                    if findAccount, let viewController = UIStoryboard(name: "NCNotification", bundle: nil).instantiateInitialViewController() as? NCNotification {
-                        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
-                            let navigationController = UINavigationController(rootViewController: viewController)
-                            navigationController.modalPresentationStyle = .fullScreen
-                            self.window?.rootViewController?.present(navigationController, animated: true)
-                        }
-                    } else if !findAccount {
-                        let message = NSLocalizedString("_the_account_", comment: "") + " " + accountPush + " " + NSLocalizedString("_does_not_exist_", comment: "")
-                        let alertController = UIAlertController(title: NSLocalizedString("_info_", comment: ""), message: message, preferredStyle: .alert)
-                        alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in }))
-                        self.window?.rootViewController?.present(alertController, animated: true, completion: { })
+                }
+                if findAccount, let viewController = UIStoryboard(name: "NCNotification", bundle: nil).instantiateInitialViewController() as? NCNotification {
+                    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
+                        let navigationController = UINavigationController(rootViewController: viewController)
+                        navigationController.modalPresentationStyle = .fullScreen
+                        self.window?.rootViewController?.present(navigationController, animated: true)
                     }
+                } else if !findAccount {
+                    let message = NSLocalizedString("_the_account_", comment: "") + " " + accountPush + " " + NSLocalizedString("_does_not_exist_", comment: "")
+                    let alertController = UIAlertController(title: NSLocalizedString("_info_", comment: ""), message: message, preferredStyle: .alert)
+                    alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in }))
+                    self.window?.rootViewController?.present(alertController, animated: true, completion: { })
                 }
             }
         }
@@ -878,8 +875,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
                 guard let userScheme = CCUtility.value(forKey: "user", fromQueryItems: queryItems) else { return false }
                 guard let urlScheme = CCUtility.value(forKey: "url", fromQueryItems: queryItems) else { return false }
                 if getMatchedAccount(userId: userScheme, url: urlScheme) == nil {
-                    let message = String(format: NSLocalizedString("_account_not_exists_", comment: ""), userScheme, urlScheme)
-
+                    let message = NSLocalizedString("_the_account_", comment: "") + " " + userScheme + NSLocalizedString("_of_", comment: "") + " " + urlScheme + " " + NSLocalizedString("_does_not_exist_", comment: "")
                     let alertController = UIAlertController(title: NSLocalizedString("_info_", comment: ""), message: message, preferredStyle: .alert)
                     alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in }))
 

+ 32 - 0
iOSClient/Data/NCManageDatabase+Share.swift

@@ -67,6 +67,7 @@ class tableShareV2: Object {
     @objc dynamic var userIcon = ""
     @objc dynamic var userMessage = ""
     @objc dynamic var userStatus = ""
+    @objc dynamic var attributes: String?
 
     override static func primaryKey() -> String {
         return "primaryKey"
@@ -80,6 +81,8 @@ extension NCManageDatabase {
         do {
             let realm = try Realm()
             try realm.write {
+                let result = realm.objects(tableShare.self).filter("account == %@", account)
+                realm.delete(result)
                 for share in shares {
                     let serverUrlPath = home + share.path
                     guard let serverUrl = NCUtilityFileSystem.shared.deleteLastPath(serverUrlPath: serverUrlPath, home: home) else { continue }
@@ -125,6 +128,7 @@ extension NCManageDatabase {
                     object.userIcon = share.userIcon
                     object.userMessage = share.userMessage
                     object.userStatus = share.userStatus
+                    object.attributes = share.attributes
                     realm.add(object, update: .all)
                 }
             }
@@ -234,4 +238,32 @@ extension NCManageDatabase {
             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? {
+        if state {
+            return nil
+        } else {
+            return "[{\"scope\":\"permissions\",\"key\":\"download\",\"enabled\":false}]"
+        }
+    }
+
+    func isAttributeDownloadEnabled(attributes: String?) -> Bool {
+        if let attributes = attributes, let data = attributes.data(using: .utf8) {
+            do {
+                if let json = try JSONSerialization.jsonObject(with: data) as? [Dictionary<String, Any>] {
+                    for sub in json {
+                        let key = sub["key"] as? String
+                        let enabled = sub["enabled"] as? Bool
+                        let scope = sub["scope"] as? String
+                        if key == "download", scope == "permissions", let enabled = enabled {
+                            return enabled
+                        }
+                    }
+                }
+            } catch let error as NSError { print(error) }
+        }
+        return true
+    }
+
 }

+ 3 - 2
iOSClient/NCGlobal.swift

@@ -92,7 +92,7 @@ class NCGlobal: NSObject {
     let appScheme                                   = "nextcloud"
     let talkName                                    = "talk-message"
     let spreedName                                  = "spreed"
-    let twofactorNotificatioName                    = "twofactor_nextcloud_notification"
+    let twoFactorNotificatioName                    = "twofactor_nextcloud_notification"
 
     // Nextcloud version
     //
@@ -257,6 +257,8 @@ class NCGlobal: NSObject {
     @objc let permissionMaxFolderShare: Int         = 31
     @objc let permissionDefaultFileRemoteShareNoSupportShareOption: Int     = 3
     @objc let permissionDefaultFolderRemoteShareNoSupportShareOption: Int   = 15
+    // ATTRIBUTES
+    @objc let permissionDownloadShare: Int          = 0
 
     // Filename Mask and Type
     //
@@ -321,7 +323,6 @@ class NCGlobal: NSObject {
     // Notification Center
     //
     @objc let notificationCenterApplicationDidEnterBackground   = "applicationDidEnterBackground"
-    let notificationCenterApplicationWillEnterForeground        = "applicationWillEnterForeground"
     let notificationCenterApplicationDidBecomeActive            = "applicationDidBecomeActive"
     let notificationCenterApplicationWillResignActive           = "applicationWillResignActive"
 

+ 1 - 1
iOSClient/Notification/NCNotification.swift

@@ -287,7 +287,7 @@ class NCNotification: UITableViewController, NCNotificationCellDelegate, NCEmpty
                         self.notifications.remove(at: index)
                     }
                     self.tableView.reloadData()
-                    if self.navigationController?.presentingViewController != nil, notification.app == NCGlobal.shared.twofactorNotificatioName {
+                    if self.navigationController?.presentingViewController != nil, notification.app == NCGlobal.shared.twoFactorNotificatioName {
                         self.dismiss(animated: true)
                     }
                 } else if error != .success {

+ 25 - 4
iOSClient/Share/Advanced/NCShareCells.swift

@@ -49,31 +49,46 @@ protocol NCPermission: NCToggleCellConfig {
     static var forDirectoryE2EE: [Self] { get }
     static var forFile: [Self] { get }
     func hasResharePermission(for parentPermission: Int) -> Bool
+    func hasDownload() -> Bool
 }
 
 enum NCUserPermission: CaseIterable, NCPermission {
     func hasResharePermission(for parentPermission: Int) -> Bool {
+        if self == .download { return true }
         return ((permissionBitFlag & parentPermission) != 0)
     }
 
+    func hasDownload() -> Bool {
+        return self == .download
+    }
+
     var permissionBitFlag: Int {
         switch self {
         case .reshare: return NCGlobal.shared.permissionShareShare
         case .edit: return NCGlobal.shared.permissionUpdateShare
         case .create: return NCGlobal.shared.permissionCreateShare
         case .delete: return NCGlobal.shared.permissionDeleteShare
+        case .download: return NCGlobal.shared.permissionDownloadShare
         }
     }
 
     func didChange(_ share: NCTableShareable, to newValue: Bool) {
-        share.permissions ^= permissionBitFlag
+        if self == .download {
+            share.attributes = NCManageDatabase.shared.setAttibuteDownload(state: newValue)
+        } else {
+            share.permissions ^= permissionBitFlag
+        }
     }
 
     func isOn(for share: NCTableShareable) -> Bool {
-        return (share.permissions & permissionBitFlag) != 0
+        if self == .download {
+            return NCManageDatabase.shared.isAttributeDownloadEnabled(attributes: share.attributes)
+        } else {
+            return (share.permissions & permissionBitFlag) != 0
+        }
     }
 
-    case reshare, edit, create, delete
+    case reshare, edit, create, delete, download
     static let forDirectory: [NCUserPermission] = NCUserPermission.allCases
     static let forDirectoryE2EE: [NCUserPermission] = []
     static let forFile: [NCUserPermission] = [.reshare, .edit]
@@ -84,11 +99,13 @@ enum NCUserPermission: CaseIterable, NCPermission {
         case .edit: return NSLocalizedString("_share_can_change_", comment: "")
         case .create: return NSLocalizedString("_share_can_create_", comment: "")
         case .delete: return NSLocalizedString("_share_can_delete_", comment: "")
+        case .download: return NSLocalizedString("_share_can_download_", comment: "")
         }
     }
 }
 
 enum NCLinkPermission: NCPermission {
+
     func didChange(_ share: NCTableShareable, to newValue: Bool) {
         guard self != .allowEdit || newValue else {
             share.permissions = NCGlobal.shared.permissionReadShare
@@ -101,6 +118,10 @@ enum NCLinkPermission: NCPermission {
         permissionValue & parentPermission == permissionValue
     }
 
+    func hasDownload() -> Bool {
+        return false
+    }
+
     var permissionValue: Int {
         switch self {
         case .allowEdit:
@@ -225,7 +246,7 @@ struct NCShareConfig {
         let cellConfig = config(for: indexPath)
         let cell = cellConfig?.getCell(for: share)
         cell?.textLabel?.text = cellConfig?.title
-        if let cellConfig = cellConfig as? NCPermission, !cellConfig.hasResharePermission(for: resharePermission) {
+        if let cellConfig = cellConfig as? NCPermission, !cellConfig.hasResharePermission(for: resharePermission), !cellConfig.hasDownload() {
             cell?.isUserInteractionEnabled = false
             cell?.textLabel?.isEnabled = false
         }

+ 5 - 0
iOSClient/Share/NCShare+Helper.swift

@@ -40,6 +40,8 @@ protocol NCTableShareable: AnyObject {
     var note: String { get set }
     var expirationDate: NSDate? { get set }
     var shareWithDisplayname: String { get set }
+
+    var attributes: String? { get set }
 }
 
 extension NCTableShareable {
@@ -62,6 +64,7 @@ extension NCTableShareable {
 }
 
 class NCTableShareOptions: NCTableShareable {
+
     var shareType: Int
     var permissions: Int
 
@@ -75,6 +78,8 @@ class NCTableShareOptions: NCTableShareable {
     var expirationDate: NSDate?
     var shareWithDisplayname: String = ""
 
+    var attributes: String?
+
     private init(shareType: Int, metadata: tableMetadata, password: String?) {
         if metadata.e2eEncrypted {
             self.permissions = NCGlobal.shared.permissionCreateShare

+ 2 - 2
iOSClient/Share/NCShareNetworking.swift

@@ -82,7 +82,7 @@ class NCShareNetworking: NSObject {
         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, permissions: option.permissions) { (account, share, data, 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
@@ -113,7 +113,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) { account, share, data, 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)

+ 22 - 27
iOSClient/Shares/NCShares.swift

@@ -52,40 +52,34 @@ class NCShares: NCCollectionViewCommon {
     override func reloadDataSource(forced: Bool = true) {
         super.reloadDataSource()
 
-        DispatchQueue.global().async {
-            let sharess = NCManageDatabase.shared.getTableShares(account: self.appDelegate.account)
-            var metadatas: [tableMetadata] = []
-            for share in sharess {
-                if let metadata = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", self.appDelegate.account, share.serverUrl, share.fileName)) {
-                    if !(metadatas.contains { $0.ocId == metadata.ocId }) {
-                        metadatas.append(metadata)
-                    }
+        let sharess = NCManageDatabase.shared.getTableShares(account: self.appDelegate.account)
+        var metadatas: [tableMetadata] = []
+        for share in sharess {
+            if let metadata = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", self.appDelegate.account, share.serverUrl, share.fileName)) {
+                if !(metadatas.contains { $0.ocId == metadata.ocId }) {
+                    metadatas.append(metadata)
                 }
             }
-
-            self.dataSource = NCDataSource(metadatas: metadatas,
-                                           account: self.appDelegate.account,
-                                           sort: self.layoutForView?.sort,
-                                           ascending: self.layoutForView?.ascending,
-                                           directoryOnTop: self.layoutForView?.directoryOnTop,
-                                           favoriteOnTop: true,
-                                           filterLivePhoto: true,
-                                           groupByField: self.groupByField,
-                                           providers: self.providers,
-                                           searchResults: self.searchResults)
-
-            DispatchQueue.main.async {
-                self.refreshControl.endRefreshing()
-                self.collectionView.reloadData()
-            }
         }
+        self.dataSource = NCDataSource(metadatas: metadatas,
+                                       account: self.appDelegate.account,
+                                       sort: self.layoutForView?.sort,
+                                       ascending: self.layoutForView?.ascending,
+                                       directoryOnTop: self.layoutForView?.directoryOnTop,
+                                       favoriteOnTop: true,
+                                       filterLivePhoto: true,
+                                       groupByField: self.groupByField,
+                                       providers: self.providers,
+                                       searchResults: self.searchResults)
+
+
+        self.refreshControl.endRefreshing()
+        self.collectionView.reloadData()
     }
 
     override func reloadDataSourceNetwork(forced: Bool = false) {
         super.reloadDataSourceNetwork(forced: forced)
 
-        if UIApplication.shared.applicationState != .active { return }
-
         isReloadDataSourceNetworkInProgress = true
         collectionView?.reloadData()
 
@@ -95,10 +89,11 @@ class NCShares: NCCollectionViewCommon {
             self.isReloadDataSourceNetworkInProgress = false
 
             if error == .success {
-                NCManageDatabase.shared.deleteTableShare(account: account)
                 if let shares = shares, !shares.isEmpty {
                     let home = NCUtilityFileSystem.shared.getHomeServer(urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId)
                     NCManageDatabase.shared.addShare(account: self.appDelegate.account, home: home, shares: shares)
+                } else {
+                    NCManageDatabase.shared.deleteTableShare(account: account)
                 }
                 self.reloadDataSource()
 

BIN
iOSClient/Supporting Files/ar.lproj/Localizable.strings


+ 1 - 1
iOSClient/Supporting Files/en.lproj/Localizable.strings

@@ -112,7 +112,6 @@
 "_force_start_"             = "Force the start";
 "_purchase_"                = "Purchase";
 "_account_not_available_"   = "The account %@ of %@ does not exist, please add it to be able to read the file %@";
-"_account_not_exists_"      = "The account %@ of %@ does not exist";
 "_the_account_"             = "The account";
 "_does_not_exist_"          = "does not exist";
 "_error_parameter_schema_"  = "Wrong parameters, impossible to continue";
@@ -650,6 +649,7 @@
 "_share_can_create_"            = "Allow creating";
 "_share_can_change_"            = "Allow editing";
 "_share_can_delete_"            = "Allow deleting";
+"_share_can_download_"          = "Allow download";
 "_share_unshare_"               = "Unshare";
 "_share_internal_link_"         = "Internal link";
 "_share_internal_link_des_"     = "Only works for users with access to this folder";

BIN
iOSClient/Supporting Files/es.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/eu.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/gl.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/tr.lproj/Localizable.strings