Browse Source

Merge branch 'develop'

marinofaggiana 5 years ago
parent
commit
f192e8e611
94 changed files with 1266 additions and 448 deletions
  1. 3 1
      Share/CCloadItemData.swift
  2. 10 11
      iOSClient/Activity/NCActivity.swift
  3. 4 0
      iOSClient/AppDelegate.h
  4. 171 8
      iOSClient/AppDelegate.m
  5. 2 2
      iOSClient/Brand/File_Provider_Extension.plist
  6. 2 2
      iOSClient/Brand/Share.plist
  7. 15 2
      iOSClient/Brand/iOSClient.plist
  8. 2 1
      iOSClient/CCGlobal.h
  9. 4 0
      iOSClient/Database/NCDatabase.swift
  10. 92 28
      iOSClient/Database/NCManageDatabase.swift
  11. 0 8
      iOSClient/Favorites/CCFavorites.m
  12. 2 2
      iOSClient/Imagemeter/IMImagemeter.swift
  13. 2 0
      iOSClient/Library/OCCommunicationLib/HCFeatures.m
  14. 2 2
      iOSClient/Library/OCCommunicationLib/OCCommunication.m
  15. 6 0
      iOSClient/Library/OCCommunicationLib/OCSharedDto.h
  16. 10 0
      iOSClient/Library/OCCommunicationLib/OCWebDavClient/OCWebDAVClient.m
  17. 29 0
      iOSClient/Library/OCCommunicationLib/OCWebDavClient/Parsers/OCXMLSharedParser.m
  18. 1 1
      iOSClient/Library/SwiftWebVC/SwiftModalWebVC.swift
  19. 1 1
      iOSClient/Login/CCLogin.h
  20. 7 1
      iOSClient/Login/CCLogin.m
  21. 6 3
      iOSClient/Login/CCLoginWeb.swift
  22. 3 1
      iOSClient/Main/CCMain.h
  23. 82 94
      iOSClient/Main/CCMain.m
  24. 4 4
      iOSClient/Main/CCMore.swift
  25. 1 1
      iOSClient/Main/CCSplit.m
  26. 1 0
      iOSClient/Main/Cell/CCCellMain.m
  27. 2 2
      iOSClient/Main/Cell/CCCellMain.xib
  28. 23 29
      iOSClient/Main/NCMainCommon.swift
  29. 1 1
      iOSClient/Media/NCMedia.swift
  30. 30 1
      iOSClient/Networking/CCNetworking.m
  31. 111 100
      iOSClient/Networking/NCService.swift
  32. 1 0
      iOSClient/Networking/OCNetworking.h
  33. 436 35
      iOSClient/Networking/OCNetworking.m
  34. 1 1
      iOSClient/Security/CCCertificate.h
  35. 16 7
      iOSClient/Security/CCCertificate.m
  36. 42 16
      iOSClient/Settings/CCManageAccount.m
  37. 6 1
      iOSClient/Share/CCShareOC.m
  38. 0 4
      iOSClient/Shares/NCShares.m
  39. BIN
      iOSClient/Supporting Files/ast.lproj/Localizable.strings
  40. BIN
      iOSClient/Supporting Files/ca.lproj/Localizable.strings
  41. BIN
      iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings
  42. BIN
      iOSClient/Supporting Files/da.lproj/Localizable.strings
  43. BIN
      iOSClient/Supporting Files/de.lproj/Localizable.strings
  44. BIN
      iOSClient/Supporting Files/el.lproj/Localizable.strings
  45. BIN
      iOSClient/Supporting Files/en-GB.lproj/Localizable.strings
  46. 10 0
      iOSClient/Supporting Files/en.lproj/Localizable.strings
  47. BIN
      iOSClient/Supporting Files/es-419.lproj/Localizable.strings
  48. BIN
      iOSClient/Supporting Files/es-AR.lproj/Localizable.strings
  49. BIN
      iOSClient/Supporting Files/es-CL.lproj/Localizable.strings
  50. BIN
      iOSClient/Supporting Files/es-CO.lproj/Localizable.strings
  51. BIN
      iOSClient/Supporting Files/es-CR.lproj/Localizable.strings
  52. BIN
      iOSClient/Supporting Files/es-DO.lproj/Localizable.strings
  53. BIN
      iOSClient/Supporting Files/es-EC.lproj/Localizable.strings
  54. BIN
      iOSClient/Supporting Files/es-GT.lproj/Localizable.strings
  55. BIN
      iOSClient/Supporting Files/es-HN.lproj/Localizable.strings
  56. BIN
      iOSClient/Supporting Files/es-MX.lproj/Localizable.strings
  57. BIN
      iOSClient/Supporting Files/es-NI.lproj/Localizable.strings
  58. BIN
      iOSClient/Supporting Files/es-PA.lproj/Localizable.strings
  59. BIN
      iOSClient/Supporting Files/es-PE.lproj/Localizable.strings
  60. BIN
      iOSClient/Supporting Files/es-PR.lproj/Localizable.strings
  61. BIN
      iOSClient/Supporting Files/es-PY.lproj/Localizable.strings
  62. BIN
      iOSClient/Supporting Files/es-SV.lproj/Localizable.strings
  63. BIN
      iOSClient/Supporting Files/es-UY.lproj/Localizable.strings
  64. BIN
      iOSClient/Supporting Files/es.lproj/Localizable.strings
  65. BIN
      iOSClient/Supporting Files/eu.lproj/Localizable.strings
  66. BIN
      iOSClient/Supporting Files/fa.lproj/Localizable.strings
  67. BIN
      iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings
  68. BIN
      iOSClient/Supporting Files/fr.lproj/Localizable.strings
  69. BIN
      iOSClient/Supporting Files/gl.lproj/Localizable.strings
  70. BIN
      iOSClient/Supporting Files/hu.lproj/Localizable.strings
  71. BIN
      iOSClient/Supporting Files/is.lproj/Localizable.strings
  72. BIN
      iOSClient/Supporting Files/it.lproj/Localizable.strings
  73. BIN
      iOSClient/Supporting Files/ja-JP.lproj/Localizable.strings
  74. BIN
      iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings
  75. BIN
      iOSClient/Supporting Files/ko.lproj/Localizable.strings
  76. BIN
      iOSClient/Supporting Files/lt_LT.lproj/Localizable.strings
  77. BIN
      iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings
  78. BIN
      iOSClient/Supporting Files/nl.lproj/Localizable.strings
  79. BIN
      iOSClient/Supporting Files/pl.lproj/Localizable.strings
  80. BIN
      iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings
  81. BIN
      iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings
  82. BIN
      iOSClient/Supporting Files/ru.lproj/Localizable.strings
  83. BIN
      iOSClient/Supporting Files/sk-SK.lproj/Localizable.strings
  84. BIN
      iOSClient/Supporting Files/sq.lproj/Localizable.strings
  85. BIN
      iOSClient/Supporting Files/sr.lproj/Localizable.strings
  86. BIN
      iOSClient/Supporting Files/sv.lproj/Localizable.strings
  87. BIN
      iOSClient/Supporting Files/tr.lproj/Localizable.strings
  88. BIN
      iOSClient/Supporting Files/zh-Hans.lproj/Localizable.strings
  89. BIN
      iOSClient/Supporting Files/zh-Hant-TW.lproj/Localizable.strings
  90. 11 18
      iOSClient/Trash/NCTrash.swift
  91. 6 1
      iOSClient/Utility/CCUtility.h
  92. 38 0
      iOSClient/Utility/CCUtility.m
  93. 68 57
      iOSClient/Utility/NCUtility.swift
  94. 2 2
      iOSClient/Viewer/NCViewerImagemeter.swift

+ 3 - 1
Share/CCloadItemData.swift

@@ -87,7 +87,9 @@ class CCloadItemData: NSObject {
                                         
                                         print("item as url: \(String(describing: item))")
                                         
-                                        let fileName = url.lastPathComponent
+                                        let ext = url.pathExtension
+                                        let fileName = "\(dateFormatter.string(from: Date()))\(conuter)." + ext
+
                                         let filenamePath = directory + fileName
                                         
                                         do {

+ 10 - 11
iOSClient/Activity/NCActivity.swift

@@ -192,15 +192,14 @@ extension NCActivity: UITableViewDataSource {
                     DispatchQueue.global().async {
                         
                         let encodedString = activity.icon.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
-                        if let data = try? Data(contentsOf: URL(string: encodedString!)!) {
-                            
-                            DispatchQueue.main.async {
+                        OCNetworking.sharedManager()?.downloadContents(ofUrl: encodedString, completion: { (data, message, errorCode) in
+                            if errorCode == 0 {
                                 do {
-                                    try data.write(to: fileNameLocalPath.url, options: .atomic)
+                                    try data!.write(to: fileNameLocalPath.url, options: .atomic)
                                 } catch { return }
-                                cell.icon.image = UIImage(data: data)
+                                cell.icon.image = UIImage(data: data!)
                             }
-                        }
+                        })
                     }
                 }
             }
@@ -220,14 +219,14 @@ extension NCActivity: UITableViewDataSource {
                     DispatchQueue.global().async {
                         let url = self.appDelegate.activeUrl + k_avatar + activity.user + "/128"
                         let encodedString = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
-                        if let data = try? Data(contentsOf: URL(string: encodedString!)!) {
-                            DispatchQueue.main.async {
+                        OCNetworking.sharedManager()?.downloadContents(ofUrl: encodedString, completion: { (data, message, errorCode) in
+                            if errorCode == 0 {
                                 do {
-                                    try data.write(to: fileNameLocalPath.url, options: .atomic)
+                                    try data!.write(to: fileNameLocalPath.url, options: .atomic)
                                 } catch { return }
-                                cell.avatar.image = UIImage(data: data)
+                                cell.avatar.image = UIImage(data: data!)
                             }
-                        }
+                        })
                     }
                 }
             }

+ 4 - 0
iOSClient/AppDelegate.h

@@ -46,6 +46,7 @@
 // Timer Process
 @property (nonatomic, strong) NSTimer *timerProcessAutoDownloadUpload;
 @property (nonatomic, strong) NSTimer *timerUpdateApplicationIconBadgeNumber;
+@property (nonatomic, strong) NSTimer *timerErrorNetworking;
 
 // For LMMediaPlayerView
 @property (strong, nonatomic) UIWindow *window;
@@ -137,6 +138,9 @@
 // UserDefaults
 @property (nonatomic, strong) NSUserDefaults *ncUserDefaults;
 
+// Timer Error Networking
+- (void)startTimerErrorNetworking;
+
 // Login View
 - (void)openLoginView:(UIViewController *)viewController delegate:(id)delegate loginType:(NSInteger)loginType selector:(NSInteger)selector;
 

+ 171 - 8
iOSClient/AppDelegate.m

@@ -34,7 +34,7 @@
 #import "NCAutoUpload.h"
 #import "NCPushNotificationEncryption.h"
 
-@interface AppDelegate () <UNUserNotificationCenterDelegate>
+@interface AppDelegate () <UNUserNotificationCenterDelegate, CCLoginDelegate, CCLoginDelegateWeb>
 {
 PKPushRegistry *pushRegistry;
 }
@@ -200,6 +200,7 @@ PKPushRegistry *pushRegistry;
     // Start Timer
     self.timerProcessAutoDownloadUpload = [NSTimer scheduledTimerWithTimeInterval:k_timerProcessAutoDownloadUpload target:self selector:@selector(loadAutoDownloadUpload) userInfo:nil repeats:YES];
     self.timerUpdateApplicationIconBadgeNumber = [NSTimer scheduledTimerWithTimeInterval:k_timerUpdateApplicationIconBadgeNumber target:self selector:@selector(updateApplicationIconBadgeNumber) userInfo:nil repeats:YES];
+    [self startTimerErrorNetworking];
 
     // Fabric
     if (![CCUtility getDisableCrashservice]) {
@@ -221,6 +222,10 @@ PKPushRegistry *pushRegistry;
 //
 - (void)applicationWillResignActive:(UIApplication *)application
 {
+    // Test Maintenance
+    if (self.activeAccount.length == 0 || self.maintenanceMode)
+        return;
+    
     [_activeMain closeAllMenu];
     
     [self updateApplicationIconBadgeNumber];
@@ -266,7 +271,7 @@ PKPushRegistry *pushRegistry;
     // Brand
 #if defined(HC)
     tableAccount *account = [[NCManageDatabase sharedInstance] getAccountActive];
-    if (account.hcIsTrial == true) {
+    if (account.hcIsTrial == true || account.hcTrialExpired == true || account.hcNextGroupExpirationGroupExpired == true) {
         
         HCTrial *vc = [[UIStoryboard storyboardWithName:@"HCTrial" bundle:nil] instantiateInitialViewController];
         vc.account = account;
@@ -307,9 +312,26 @@ PKPushRegistry *pushRegistry;
 }
 
 #pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== Login =====
+#pragma mark ===== Login / checkErrorNetworking =====
 #pragma --------------------------------------------------------------------------------------------
 
+- (void)checkErrorNetworking
+{
+    // test
+    if (self.activeAccount.length == 0 || self.maintenanceMode)
+        return;
+    
+    // check unauthorized server (401)
+    if ([CCUtility getPassword:self.activeAccount].length == 0) {
+        [self openLoginView:self.window.rootViewController delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
+    }
+    
+    // check certificate untrusted (-1202)
+    if ([CCUtility getCertificateError:self.activeAccount]) {
+        [[CCCertificate sharedManager] presentViewControllerCertificateWithAccount:self.activeAccount viewController:self.window.rootViewController delegate:self];
+    }
+}
+
 - (void)openLoginView:(UIViewController *)viewController delegate:(id)delegate loginType:(NSInteger)loginType selector:(NSInteger)selector
 {
     BOOL loginWebFlow = NO;
@@ -389,6 +411,20 @@ PKPushRegistry *pushRegistry;
     }
 }
 
+- (void)loginSuccess:(NSInteger)loginType
+{
+    //
+}
+- (void)webDismiss
+{
+    [self startTimerErrorNetworking];
+}
+
+- (void)startTimerErrorNetworking
+{
+    self.timerErrorNetworking = [NSTimer scheduledTimerWithTimeInterval:k_timerErrorNetworking target:self selector:@selector(checkErrorNetworking) userInfo:nil repeats:YES];
+}
+
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== Setting Active Account for all APP =====
 #pragma --------------------------------------------------------------------------------------------
@@ -532,7 +568,7 @@ PKPushRegistry *pushRegistry;
                     
                     NSString *app = [json objectForKey:@"app"];
                     NSString *subject = [json objectForKey:@"subject"];
-                    NSInteger notificationId = [[json objectForKey:@"nid"] integerValue];
+                    //NSInteger notificationId = [[json objectForKey:@"nid"] integerValue];
                     
                     NSURL *url = [NSURL URLWithString:result.url];
                     NSString *domain = [url host];
@@ -540,7 +576,7 @@ PKPushRegistry *pushRegistry;
                     if ([app isEqualToString:@"spreed"]) {
                         content.title = @"Nextcloud Talk";
                     } else {
-                        content.title = app.capitalizedString;
+                        content.title = NSLocalizedString(app.capitalizedString, nil);
                     }
                     if (results.count == 1) {
                         content.title = content.title;
@@ -555,10 +591,12 @@ PKPushRegistry *pushRegistry;
                     }
                     content.sound = [UNNotificationSound defaultSound];
 
+                    /*
                     [[OCNetworking sharedManager] getServerNotification:result.url notificationId:notificationId completion:^(NSDictionary *json, NSString *message, NSInteger errorCode) {
                         //
                     }];
-                                        
+                    */
+                    
                     NSString *identifier = [NSString stringWithFormat:@"Notification-%@", [NSDate new]];
                     
                     UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.1 repeats:NO];
@@ -1282,7 +1320,7 @@ PKPushRegistry *pushRegistry;
         sizeUpload = sizeUpload + metadata.size;
     }
     
-    NSLog(@"%@", [NSString stringWithFormat:@"[LOG] -PROCESS-AUTO-UPLOAD- | Download %ld - %@ | Upload %ld - %@", counterDownload, [CCUtility transformedSize:sizeDownload], counterUpload, [CCUtility transformedSize:sizeUpload]]);
+    NSLog(@"%@", [NSString stringWithFormat:@"[LOG] PROCESS-AUTO-UPLOAD | Download %ld - %@ | Upload %ld - %@", counterDownload, [CCUtility transformedSize:sizeDownload], counterUpload, [CCUtility transformedSize:sizeUpload]]);
     
     // ------------------------- <selector Download> -------------------------
     
@@ -1495,6 +1533,131 @@ PKPushRegistry *pushRegistry;
 // Method called from iOS system to send a file from other app.
 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
 {
+    if (self.activeAccount.length == 0 || self.maintenanceMode)
+        return YES;
+    
+    NSString *scheme = url.scheme;
+
+    dispatch_time_t timer = 0;
+    if (self.activeMain == nil) timer = 1;
+
+    if ([scheme isEqualToString:@"nextcloud"]) {
+        
+        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timer * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
+        
+            NSString *action = url.host;
+            if ([action isEqualToString:@"open-file"]) {
+                NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
+                NSArray *queryItems = urlComponents.queryItems;
+                NSString *user = [CCUtility valueForKey:@"user" fromQueryItems:queryItems];
+                NSString *path = [CCUtility valueForKey:@"path" fromQueryItems:queryItems];
+                NSString *link = [CCUtility valueForKey:@"link" fromQueryItems:queryItems];
+                tableAccount *matchedAccount = nil;
+
+                // verify parameter
+                if (user.length == 0 || path.length == 0 || [[NSURL URLWithString:link] host].length == 0) {
+                    
+                    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_error_", nil) message:NSLocalizedString(@"_error_parameter_schema_", nil) preferredStyle:UIAlertControllerStyleAlert];
+                    UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}];
+                    
+                    [alertController addAction:okAction];
+                    [self.window.rootViewController presentViewController:alertController animated:YES completion:nil];
+                    
+                } else {
+                
+                    tableAccount *account = [[NCManageDatabase sharedInstance] getAccountActive];
+                    if (account) {
+                        NSURL *activeAccountURL = [NSURL URLWithString:account.url];
+                        NSString *activeAccountUser = account.user;
+                        if ([link containsString:activeAccountURL.host] && [user isEqualToString:activeAccountUser]) {
+                            matchedAccount = account;
+                        } else {
+                            NSArray *accounts = [[NCManageDatabase sharedInstance] getAllAccount];
+                            for (tableAccount *account in accounts) {
+                                NSURL *accountURL = [NSURL URLWithString:account.url];
+                                NSString *accountUser = account.user;
+                                if ([link containsString:accountURL.host] && [user isEqualToString:accountUser]) {
+                                    matchedAccount = [[NCManageDatabase sharedInstance] setAccountActive:account.account];
+                                    [self settingActiveAccount:matchedAccount.account activeUrl:matchedAccount.url activeUser:matchedAccount.user activeUserID:matchedAccount.userID activePassword:[CCUtility getPassword:matchedAccount.account]];
+                                    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"initializeMain" object:nil userInfo:nil];
+                                }
+                            }
+                        }
+                        
+                        if (matchedAccount) {
+                            UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
+                            UITabBarController *tbc;
+                            
+                            if (splitViewController.isCollapsed) {
+                                
+                                tbc = splitViewController.viewControllers.firstObject;
+                                for (UINavigationController *nvc in tbc.viewControllers) {
+                                    
+                                    if ([nvc.topViewController isKindOfClass:[CCDetail class]])
+                                        [nvc popToRootViewControllerAnimated:NO];
+                                }
+                                
+                            } else {
+                                
+                                UINavigationController *nvcDetail = splitViewController.viewControllers.lastObject;
+                                [nvcDetail popToRootViewControllerAnimated:NO];
+                                
+                                tbc = splitViewController.viewControllers.firstObject;
+                            }
+                            
+                            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
+                                
+                                [tbc setSelectedIndex: k_tabBarApplicationIndexFile];
+                                
+                                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
+                                    
+                                    [self.activeMain.navigationController popToRootViewControllerAnimated:NO];
+                                    
+                                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
+                                        
+                                        NSString *fileNamePath = [NSString stringWithFormat:@"%@%@/%@", matchedAccount.url, k_webDAV, path];
+                                        
+                                        if ([path containsString:@"/"]) {
+                                            
+                                            // Push
+                                            NSString *directoryName = [[path stringByDeletingLastPathComponent] lastPathComponent];
+                                            NSString *serverUrl = [CCUtility deletingLastPathComponentFromServerUrl:[NSString stringWithFormat:@"%@%@/%@", matchedAccount.url, k_webDAV, [path stringByDeletingLastPathComponent]]];
+                                            tableMetadata *metadata = [CCUtility createMetadataWithAccount:matchedAccount.account date:[NSDate date] directory:NO fileID:[[NSUUID UUID] UUIDString] serverUrl:serverUrl fileName:directoryName etag:@"" size:0 status:k_metadataStatusNormal url:@""];
+                                            
+                                            [self.activeMain performSegueDirectoryWithControlPasscode:true metadata:metadata scrollToFileNamePath:fileNamePath];
+                                            
+                                        } else {
+                                            
+                                            // Reload folder
+                                            NSString *serverUrl = [NSString stringWithFormat:@"%@%@", matchedAccount.url, k_webDAV];
+                                            
+                                            self.activeMain.scrollToFileNamePath = fileNamePath;
+                                            [self.activeMain readFolder:serverUrl];
+                                        }
+                                    });
+                                });
+                            });
+              
+                        } else {
+                            
+                            NSString *domain = [[NSURL URLWithString:link] host];
+                            NSString *fileName = [path lastPathComponent];
+                            NSString *message = [NSString stringWithFormat:NSLocalizedString(@"_account_not_available_", nil), user, domain, fileName];
+                            
+                            UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_info_", nil) message:message preferredStyle:UIAlertControllerStyleAlert];
+                            UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}];
+                            
+                            [alertController addAction:okAction];
+                            [self.window.rootViewController presentViewController:alertController animated:YES completion:nil];
+                        }
+                    }
+                }
+            }
+        });
+        
+        return YES;
+    }
+    
     NSError *error;
     NSLog(@"[LOG] the path is: %@", url.path);
         
@@ -1513,7 +1676,7 @@ PKPushRegistry *pushRegistry;
             
             UINavigationController *navigationController = [[UIStoryboard storyboardWithName:@"CCUploadFromOtherUpp" bundle:nil] instantiateViewControllerWithIdentifier:@"CCUploadNavigationViewController"];
             
-            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
+            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timer * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
                 [splitNavigationController presentViewController:navigationController animated:YES completion:nil];
             });
         }

+ 2 - 2
iOSClient/Brand/File_Provider_Extension.plist

@@ -17,9 +17,9 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.23.5</string>
+	<string>2.23.6</string>
 	<key>CFBundleVersion</key>
-	<string>1</string>
+	<string>15</string>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>

+ 2 - 2
iOSClient/Brand/Share.plist

@@ -17,9 +17,9 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.23.5</string>
+	<string>2.23.6</string>
 	<key>CFBundleVersion</key>
-	<string>1</string>
+	<string>15</string>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>

+ 15 - 2
iOSClient/Brand/iOSClient.plist

@@ -46,11 +46,24 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.23.5</string>
+	<string>2.23.6</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
+	<key>CFBundleURLTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+			<key>CFBundleURLName</key>
+			<string>it.twsweb.Nextcloud</string>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>nextcloud</string>
+			</array>
+		</dict>
+	</array>
 	<key>CFBundleVersion</key>
-	<string>1</string>
+	<string>15</string>
 	<key>FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED</key>
 	<true/>
 	<key>Fabric</key>

+ 2 - 1
iOSClient/CCGlobal.h

@@ -82,7 +82,7 @@
 
 // Database Realm
 #define k_databaseDefault                               @"nextcloud.realm"
-#define k_databaseSchemaVersion                         50
+#define k_databaseSchemaVersion                         51
 
 // Intro selector
 #define k_intro_login                                   0
@@ -171,6 +171,7 @@
 // Timer
 #define k_timerProcessAutoDownloadUpload                5
 #define k_timerUpdateApplicationIconBadgeNumber         3
+#define k_timerErrorNetworking                          3
 
 // ConcurrentOperation
 #define k_maxHTTPConnectionsPerHost                     5

+ 4 - 0
iOSClient/Database/NCDatabase.swift

@@ -72,6 +72,10 @@ class tableAccount: Object {
     @objc dynamic var hcAccountRemoveExpired: Bool = false
     @objc dynamic var hcAccountRemoveRemainingSec: Double = 0
     @objc dynamic var hcAccountRemoveTime: NSDate? = nil
+    @objc dynamic var hcNextGroupExpirationGroup = ""
+    @objc dynamic var hcNextGroupExpirationGroupExpired: Bool = false
+    @objc dynamic var hcNextGroupExpirationExpiresTime: NSDate? = nil
+    @objc dynamic var hcNextGroupExpirationExpires = ""
     
     override static func primaryKey() -> String {
         return "account"

+ 92 - 28
iOSClient/Database/NCManageDatabase.swift

@@ -39,8 +39,26 @@ class NCManageDatabase: NSObject {
             
             fileURL: databaseFilePath,
             schemaVersion: UInt64(k_databaseSchemaVersion),
-
-                shouldCompactOnLaunch: { totalBytes, usedBytes in
+            
+            migrationBlock: { migration, oldSchemaVersion in
+                
+                if oldSchemaVersion < 41 {
+                    migration.deleteData(forType: tableActivity.className())
+                    migration.deleteData(forType: tableMetadata.className())
+                    migration.deleteData(forType: tableDirectory.className())
+                }
+                
+                /*
+                 if oldSchemaVersion < 44 {
+                 migration.enumerateObjects(ofType: tableAccount.className()) { oldObject, newObject in
+                 let account = oldObject!["account"] as! String
+                 let password = oldObject!["password"] as! String
+                 }
+                 }
+                 */
+                
+            }, shouldCompactOnLaunch: { totalBytes, usedBytes in
+                
                 // totalBytes refers to the size of the file on disk in bytes (data + free space)
                 // usedBytes refers to the number of bytes used by data in the file
                 
@@ -60,25 +78,7 @@ class NCManageDatabase: NSObject {
         let config = Realm.Configuration(
         
             fileURL: dirGroup?.appendingPathComponent("\(k_appDatabaseNextcloud)/\(k_databaseDefault)"),
-            schemaVersion: UInt64(k_databaseSchemaVersion),
-            
-            migrationBlock: { migration, oldSchemaVersion in
-                
-                if oldSchemaVersion < 41 {
-                    migration.deleteData(forType: tableActivity.className())
-                    migration.deleteData(forType: tableMetadata.className())
-                    migration.deleteData(forType: tableDirectory.className())
-                }
-                
-                /*
-                if oldSchemaVersion < 44 {
-                    migration.enumerateObjects(ofType: tableAccount.className()) { oldObject, newObject in
-                        let account = oldObject!["account"] as! String
-                        let password = oldObject!["password"] as! String
-                    }
-                }
-                */
-            }
+            schemaVersion: UInt64(k_databaseSchemaVersion)
         )
         
         Realm.Configuration.defaultConfiguration = config
@@ -515,6 +515,7 @@ class NCManageDatabase: NSObject {
                 } else {
                     result.hcTrialEndTime = nil
                 }
+                
                 result.hcAccountRemoveExpired = features.accountRemoveExpired
                 result.hcAccountRemoveRemainingSec = features.accountRemoveRemainingSec
                 if features.accountRemoveTime > 0 {
@@ -523,6 +524,15 @@ class NCManageDatabase: NSObject {
                     result.hcAccountRemoveTime = nil
                 }
                 
+                result.hcNextGroupExpirationGroup = features.nextGroupExpirationGroup
+                result.hcNextGroupExpirationGroupExpired = features.nextGroupExpirationGroupExpired
+                if features.nextGroupExpirationExpiresTime > 0 {
+                    result.hcNextGroupExpirationExpiresTime = Date(timeIntervalSince1970: features.nextGroupExpirationExpiresTime) as NSDate
+                } else {
+                    result.hcNextGroupExpirationExpiresTime = nil
+                }
+                result.hcNextGroupExpirationExpires = features.nextGroupExpirationExpires
+                
                 returnAccount = result
             }
         } catch let error {
@@ -1987,21 +1997,47 @@ class NCManageDatabase: NSObject {
         return tableMetadata.init(value: result)
     }
    
-    @objc func getTableMedias(predicate: NSPredicate) -> [tableMetadata]? {
+    @objc func getTablesMedia(account: String) -> [tableMetadata]? {
         
         let realm = try! Realm()
         realm.refresh()
         
-        let results = realm.objects(tableMedia.self).filter(predicate).sorted(byKeyPath: "date", ascending: false)
-        
-        if (results.count > 0) {
-            return Array(results.map { tableMetadata.init(value:$0) })
-        } else {
+        let sortProperties = [SortDescriptor(keyPath: "date", ascending: false), SortDescriptor(keyPath: "fileNameView", ascending: false)]
+        let results = realm.objects(tableMedia.self).filter(NSPredicate(format: "account == %@", account)).sorted(by: sortProperties)
+        if results.count == 0 {
             return nil
         }
+        
+        let serversUrlLocked = realm.objects(tableDirectory.self).filter(NSPredicate(format: "account == %@ AND lock == true", account)).map { $0.serverUrl } as Array
+        
+        var metadatas = [tableMetadata]()
+        var oldServerUrl = ""
+        var isValidMetadata = true
+
+        for result in results {
+            let metadata = tableMetadata.init(value: result)
+        
+            // Verify Lock
+            if (serversUrlLocked.count > 0) && (metadata.serverUrl != oldServerUrl) {
+                var foundLock = false
+                oldServerUrl = metadata.serverUrl
+                for serverUrlLocked in serversUrlLocked {
+                    if metadata.serverUrl.contains(serverUrlLocked) {
+                        foundLock = true
+                        break
+                    }
+                }
+                isValidMetadata = !foundLock
+            }
+            if isValidMetadata {
+                metadatas.append(tableMetadata.init(value: metadata))
+            }
+        }
+      
+        return metadatas
     }
     
-    func createTableMedia(_ metadatas: [tableMetadata], lteDate: Date, gteDate: Date,account: String) -> (isDifferent: Bool, newInsert: Int) {
+    func createTableMedia(_ metadatasSource: [tableMetadata], lteDate: Date, gteDate: Date, account: String) -> (isDifferent: Bool, newInsert: Int) {
 
         let realm = try! Realm()
         realm.refresh()
@@ -2015,6 +2051,34 @@ class NCManageDatabase: NSObject {
         var isDifferent: Bool = false
         var newInsert: Int = 0
         
+        var oldServerUrl = ""
+        var isValidMetadata = true
+        
+        var metadatas = [tableMetadata]()
+        
+        let serversUrlLocked = realm.objects(tableDirectory.self).filter(NSPredicate(format: "account == %@ AND lock == true", account)).map { $0.serverUrl } as Array
+        if (serversUrlLocked.count > 0) {
+            for metadata in metadatasSource {
+                // Verify Lock
+                if (metadata.serverUrl != oldServerUrl) {
+                    var foundLock = false
+                    oldServerUrl = metadata.serverUrl
+                    for serverUrlLocked in serversUrlLocked {
+                        if metadata.serverUrl.contains(serverUrlLocked) {
+                            foundLock = true
+                            break
+                        }
+                    }
+                    isValidMetadata = !foundLock
+                }
+                if isValidMetadata {
+                    metadatas.append(tableMetadata.init(value: metadata))
+                }
+            }
+        } else {
+            metadatas = metadatasSource
+        }
+        
         do {
             try realm.write {
                 

+ 0 - 8
iOSClient/Favorites/CCFavorites.m

@@ -179,10 +179,6 @@
         if (errorCode == 0 && [account isEqualToString:appDelegate.activeAccount]) {
             [[NCManageDatabase sharedInstance] setMetadataFavoriteWithFileID:metadata.fileID favorite:favorite];
             [[NCMainCommon sharedInstance] reloadDatasourceWithServerUrl:metadata.serverUrl fileID:metadata.fileID action:k_action_MOD];
-        } else if (errorCode == kOCErrorServerUnauthorized) {
-            [appDelegate openLoginView:self delegate:appDelegate.activeMain loginType:k_login_Modify_Password selector:k_intro_login];
-        } else if (errorCode == NSURLErrorServerCertificateUntrusted) {
-            [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:message viewController:self delegate:self];
         } else if (errorCode != 0) {
             [appDelegate messageNotification:@"_error_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         } else {
@@ -246,10 +242,6 @@
             
             [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"clearDateReadDataSource" object:nil];
             
-        } else if (errorCode == kOCErrorServerUnauthorized) {
-            [appDelegate openLoginView:self delegate:appDelegate.activeMain loginType:k_login_Modify_Password selector:k_intro_login];
-        } else if (errorCode == NSURLErrorServerCertificateUntrusted) {
-            [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:message viewController:self delegate:self];
         } else if (errorCode != 0) {
             [appDelegate messageNotification:@"_error_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         } else {

+ 2 - 2
iOSClient/Imagemeter/IMImagemeter.swift

@@ -33,7 +33,7 @@ class IMImagemeterCodable: NSObject {
         }
         
         struct color: Codable {
-            let rgba: [Int]
+            let rgba: [Int]?
         }
         
         struct end_pt: Codable {
@@ -114,7 +114,7 @@ class IMImagemeterCodable: NSObject {
         struct elements: Codable {
             let id: Int
             let class_: String
-            let center: coordinates
+            let center: coordinates?
             let width: CGFloat?
             let arrows: [end_pt]?
             let text: String?

+ 2 - 0
iOSClient/Library/OCCommunicationLib/HCFeatures.m

@@ -30,6 +30,8 @@
     
     self.trialEnd = @"";
     self.accountRemove = @"";
+    self.nextGroupExpirationGroup = @"";
+    self.nextGroupExpirationExpires = @"";
     
     return self;
 }

+ 2 - 2
iOSClient/Library/OCCommunicationLib/OCCommunication.m

@@ -3302,7 +3302,7 @@
                 NSDictionary *nextGroupExpirationDic = [data valueForKey:@"next_group_expiration"];
                 if (nextGroupExpirationDic) {
                     if ([nextGroupExpirationDic valueForKey:@"group"] && ![[nextGroupExpirationDic valueForKey:@"group"] isKindOfClass:[NSNull class]])
-                        features.nextGroupExpirationGroup = [data valueForKey:@"group"];
+                        features.nextGroupExpirationGroup = [nextGroupExpirationDic valueForKey:@"group"];
                     
                     if ([nextGroupExpirationDic valueForKey:@"group_expired"] && ![[nextGroupExpirationDic valueForKey:@"group_expired"] isKindOfClass:[NSNull class]])
                         features.nextGroupExpirationGroupExpired = [[nextGroupExpirationDic valueForKey:@"group_expired"] boolValue];
@@ -3311,7 +3311,7 @@
                         features.nextGroupExpirationExpiresTime = [[nextGroupExpirationDic valueForKey:@"expires_time"] integerValue];
                     
                     if ([nextGroupExpirationDic valueForKey:@"expires"] && ![[nextGroupExpirationDic valueForKey:@"expires"] isKindOfClass:[NSNull class]])
-                        features.nextGroupExpirationExpires = [data valueForKey:@"expires"];
+                        features.nextGroupExpirationExpires = [nextGroupExpirationDic valueForKey:@"expires"];
                 }
                 
                 successRequest(response, features, request.redirectedServer);

+ 6 - 0
iOSClient/Library/OCCommunicationLib/OCSharedDto.h

@@ -57,5 +57,11 @@ typedef enum {
 @property (nonatomic, copy) NSString *uidFileOwner;
 @property (nonatomic, copy) NSString *fileTarget;
 @property BOOL hideDownload;
+@property (nonatomic, copy) NSString *note;
+@property (nonatomic, copy) NSString *label;
+@property (nonatomic, copy) NSString *displayNameFileOwner;
+@property (nonatomic, copy) NSString *mimeType;
+@property (nonatomic, copy) NSString *storageID;
+@property (nonatomic, copy) NSString *fileParent;
 
 @end

+ 10 - 0
iOSClient/Library/OCCommunicationLib/OCWebDavClient/OCWebDAVClient.m

@@ -304,6 +304,16 @@ NSString const *OCWebDAVModificationDateKey	= @"modificationdate";
                         "<d:depth>infinity</d:depth>"
                     "</d:scope>"
                 "</d:from>"
+                "<d:orderby>"
+                    "<d:order>"
+                        "<d:prop><d:getlastmodified/></d:prop>"
+                        "<d:descending/>"
+                    "</d:order>"
+                    "<d:order>"
+                        "<d:prop><d:displayname/></d:prop>"
+                        "<d:descending/>"
+                    "</d:order>"
+                "</d:orderby>"
                 "<d:where><d:and><d:or>", userID, folder];
         
         for (NSString *type in contentType) {

+ 29 - 0
iOSClient/Library/OCCommunicationLib/OCWebDavClient/Parsers/OCXMLSharedParser.m

@@ -196,7 +196,36 @@
         }
         
     } else if ([elementName isEqualToString:@"hide_download"]) {
+        
         _currentShared.hideDownload = [_xmlChars boolValue];
+        
+    } else if ([elementName isEqualToString:@"note"]) {
+        
+        _currentShared.note = _xmlChars;
+        
+    } else if ([elementName isEqualToString:@"label"]) {
+        
+        _currentShared.label = _xmlChars;
+        
+    } else if ([elementName isEqualToString:@"displayname_file_owner"]) {
+        
+        _currentShared.displayNameFileOwner = _xmlChars;
+        
+    } else if ([elementName isEqualToString:@"mimetype"]) {
+        
+        _currentShared.mimeType = _xmlChars;
+        
+    } else if ([elementName isEqualToString:@"storage_id"]) {
+        
+        _currentShared.storageID = _xmlChars;
+        
+    } else if ([elementName isEqualToString:@"file_parent"]) {
+        
+        _currentShared.fileParent = _xmlChars;
+        
+    } else if ([elementName isEqualToString:@"file_target"]) {
+        
+        _currentShared.fileTarget = _xmlChars;
     }
 }
 

+ 1 - 1
iOSClient/Library/SwiftWebVC/SwiftModalWebVC.swift

@@ -85,7 +85,7 @@ extension SwiftModalWebVC: SwiftWebVCDelegate {
     }
     
     public func didFinishLoading(success: Bool) {
-        print("Finished loading. Success: \(success).")
+        //print("Finished loading. Success: \(success).")
     }
     
     public func didFinishLoading(success: Bool, url: URL) {

+ 1 - 1
iOSClient/Login/CCLogin.h

@@ -32,7 +32,7 @@
 
 @protocol CCLoginDelegate <NSObject>
 
-- (void) loginSuccess:(NSInteger)loginType;
+- (void)loginSuccess:(NSInteger)loginType;
 
 @end
 

+ 7 - 1
iOSClient/Login/CCLogin.m

@@ -137,12 +137,18 @@
 - (void)viewDidAppear:(BOOL)animated
 {
     [super viewDidAppear:animated];
+    
+    // Stop timer error network
+    [appDelegate.timerErrorNetworking invalidate];
 }
 
 //
 - (void)viewDidDisappear:(BOOL)animated
 {
     [super viewDidDisappear:animated];
+    
+    // Start timer
+    [appDelegate startTimerErrorNetworking];
 }
 
 - (BOOL)textFieldShouldReturn:(UITextField *)textField
@@ -207,7 +213,7 @@
             
             if (errorCode == NSURLErrorServerCertificateUntrusted) {
                 
-                [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:message viewController:self delegate:self];
+                [[CCCertificate sharedManager] presentViewControllerCertificateWithAccount:nil viewController:self delegate:self];
                 
             } else {
                 

+ 6 - 3
iOSClient/Login/CCLoginWeb.swift

@@ -55,14 +55,17 @@ public class CCLoginWeb: UIViewController {
         let webVC = SwiftModalWebVC(urlString: urlString, colorText: UIColor.black, colorDoneButton: UIColor.black, doneButtonVisible: doneButtonVisible, hideToolbar: true)
         webVC.delegateWeb = self
 
-        vc.present(webVC, animated: false, completion: nil)
+        vc.present(webVC, animated: false) {
+            // Stop timer
+            self.appDelegate.timerErrorNetworking.invalidate()
+        }
     }
 }
 
 extension CCLoginWeb: SwiftModalWebVCDelegate {
     
     public func didStartLoading() {
-        print("Started loading.")
+        //print("Started loading.")
     }
     
     public func didReceiveServerRedirectForProvisionalNavigation(url: URL) {
@@ -142,7 +145,7 @@ extension CCLoginWeb: SwiftModalWebVCDelegate {
     }
 
     public func didFinishLoading(success: Bool, url: URL) {
-        print("Finished loading. Success: \(success).")
+        //print("Finished loading. Success: \(success).")
     }
     
     public func webDismiss() {

+ 3 - 1
iOSClient/Main/CCMain.h

@@ -59,9 +59,12 @@
 @property (nonatomic, strong) UISearchController *searchController;
 @property (nonatomic, strong) UIView *reMenuBackgroundView;
 @property (nonatomic, strong) UITapGestureRecognizer *singleFingerTap;
+@property (nonatomic, strong) NSString *scrollToFileNamePath;
+
 @property BOOL isSelectedMode;
 
 - (void)shouldPerformSegue:(tableMetadata *)metadata;
+- (void)performSegueDirectoryWithControlPasscode:(BOOL)controlPasscode metadata:(tableMetadata *)metadata scrollToFileNamePath:(NSString *)scrollToFileNamePath;
 
 - (void)saveToPhotoAlbum:(tableMetadata *)metadata;
 
@@ -73,7 +76,6 @@
 
 - (void)readFolder:(NSString *)serverUrl;
 - (void)readFileReloadFolder;
-- (void)tableViewReloadData;
 
 - (void)uploadFileAsset:(NSMutableArray *)assets serverUrl:(NSString *)serverUrl useSubFolder:(BOOL)useSubFolder session:(NSString *)session;
 

+ 82 - 94
iOSClient/Main/CCMain.m

@@ -292,7 +292,7 @@
     [self setTitle];
     
     // Reload Table View
-    [self tableViewReloadData];
+    [self tableViewReloadDataWithScrollToFileName:false];
 }
 
 #pragma --------------------------------------------------------------------------------------------
@@ -329,6 +329,9 @@
         // Remove search mode
         [self cancelSearchBar];
         
+        // Clear error certificate
+        [CCUtility setCertificateError:appDelegate.activeAccount error:NO];
+        
         // populate shared Link & User
         NSArray *results = [[NCManageDatabase sharedInstance] getSharesWithAccount:appDelegate.activeAccount];
         if (results) {
@@ -1131,10 +1134,6 @@
                 [self readFolder:metadata.serverUrl];
             }
             
-        } else if (errorCode == kOCErrorServerUnauthorized) {
-            [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-        } else if (errorCode == NSURLErrorServerCertificateUntrusted) {
-            [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:message viewController:self delegate:self];
         } else if (errorCode != 0) {
             [appDelegate messageNotification:@"_error_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         } else {
@@ -1203,7 +1202,7 @@
         // reload
         [[NCMainCommon sharedInstance] reloadDatasourceWithServerUrl:serverUrl fileID:nil action:k_action_NULL];
         
-        [self tableViewReloadData];
+        [self tableViewReloadDataWithScrollToFileName:false];
     }
     
     // E2EE Is encrypted folder get metadata
@@ -1257,16 +1256,12 @@
     
     _loadingFolder = YES;
 
-    [self tableViewReloadData];
+    [self tableViewReloadDataWithScrollToFileName:false];
     
     [[OCNetworking sharedManager] readFolderWithAccount:appDelegate.activeAccount serverUrl:serverUrl depth:@"1" completion:^(NSString *account, NSArray *metadatas, tableMetadata *metadataFolder, NSString *message, NSInteger errorCode) {
         
         if (errorCode == 0 && [account isEqualToString:appDelegate.activeAccount]) {
             [self insertMetadatasWithAccount:account serverUrl:serverUrl metadataFolder:metadataFolder metadatas:metadatas];
-        } else if (errorCode == kOCErrorServerUnauthorized) {
-            [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-        } else if (errorCode == NSURLErrorServerCertificateUntrusted) {
-            [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:message viewController:self delegate:self];
         } else if (errorCode != 0) {
             [appDelegate messageNotification:@"_error_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         } else {
@@ -1326,11 +1321,7 @@
             
         } else {
             
-            if (errorCode == kOCErrorServerUnauthorized) {
-                [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-            } else if (errorCode == NSURLErrorServerCertificateUntrusted) {
-                [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:message viewController:self delegate:self];
-            } else if (errorCode != 0) {
+            if (errorCode != 0) {
                 [appDelegate messageNotification:@"_error_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
             } else {
                 NSLog(@"[LOG] It has been changed user during networking process, error.");
@@ -1516,11 +1507,7 @@
                 
             } else if (errorCode != 0) {
                 
-                if (errorCode == kOCErrorServerUnauthorized) {
-                    [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-                } else if (errorCode == NSURLErrorServerCertificateUntrusted) {
-                    [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:message viewController:self delegate:self];
-                } else if (errorCode == kOCErrorServerPathNotFound) {
+                if (errorCode == kOCErrorServerPathNotFound) {
                 
                     NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@", metadata.serverUrl, metadata.fileName];
                     NSString *fileNameToPath = [NSString stringWithFormat:@"%@/%@", metadata.serverUrl, fileNameNew];
@@ -1603,11 +1590,7 @@
             
         } else if (errorCode != 0) {
             
-            if (errorCode == kOCErrorServerUnauthorized) {
-                [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-            } else if (errorCode == NSURLErrorServerCertificateUntrusted) {
-                [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:message viewController:self delegate:self];
-            } else if (errorCode == kOCErrorServerPathNotFound) {
+            if (errorCode == kOCErrorServerPathNotFound) {
             
                 NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@", metadata.serverUrl, metadata.fileName];
                 NSString *fileNameToPath = [NSString stringWithFormat:@"%@/%@", serverUrlTo, metadata.fileName];
@@ -1813,11 +1796,7 @@
             [[NCManageDatabase sharedInstance] deleteMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileID == %@", fileIDTemp]];
             [[NCMainCommon sharedInstance] reloadDatasourceWithServerUrl:self.serverUrl fileID:nil action:k_action_NULL];
             
-            if (errorCode == kOCErrorServerUnauthorized) {
-                [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-            } else if (errorCode == NSURLErrorServerCertificateUntrusted) {
-                [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:message viewController:self delegate:self];
-            } else if (errorCode != 0) {
+            if (errorCode != 0) {
                 [appDelegate messageNotification:@"_create_folder_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
             } else {
                 NSLog(@"[LOG] It has been changed user during networking process, error.");
@@ -1927,14 +1906,11 @@
                 }
             }
             
-            [self tableViewReloadData];
+            [self tableViewReloadDataWithScrollToFileName:false];
             
         } else if (errorCode != 0) {
             
-            if (errorCode == kOCErrorServerUnauthorized)
-                [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-            else
-                [appDelegate messageNotification:@"_share_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
+            [appDelegate messageNotification:@"_share_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         }
     }];
     
@@ -1957,16 +1933,13 @@
             
         } else if (errorCode != 0) {
             
-            if (errorCode == kOCErrorServerUnauthorized)
-                [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-            else
-                [appDelegate messageNotification:@"_share_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
+            [appDelegate messageNotification:@"_share_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         }
         
         if (_shareOC)
             [_shareOC reloadData];
         
-        [self tableViewReloadData];
+        [self tableViewReloadDataWithScrollToFileName:false];
     }];
     
     [_hud visibleHudTitle:NSLocalizedString(@"_creating_sharing_", nil) mode:MBProgressHUDModeIndeterminate color:nil];
@@ -1992,16 +1965,13 @@
             
         } else if (errorCode != 0) {
             
-            if (errorCode == kOCErrorServerUnauthorized)
-                [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-            else
-                [appDelegate messageNotification:@"_share_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
+            [appDelegate messageNotification:@"_share_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         }
         
         if (_shareOC)
             [_shareOC reloadData];
         
-        [self tableViewReloadData];
+        [self tableViewReloadDataWithScrollToFileName:false];
     }];
     
     [_hud visibleHudTitle:NSLocalizedString(@"_updating_sharing_", nil) mode:MBProgressHUDModeIndeterminate color:nil];
@@ -2019,16 +1989,13 @@
             
         } else if (errorCode != 0) {
             
-            if (errorCode == kOCErrorServerUnauthorized)
-                [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-            else
-                [appDelegate messageNotification:@"_share_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
+            [appDelegate messageNotification:@"_share_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         }
         
         if (_shareOC)
             [_shareOC reloadData];
         
-        [self tableViewReloadData];
+        [self tableViewReloadDataWithScrollToFileName:false];
     }];
     
     
@@ -2048,10 +2015,7 @@
             
         } else if (errorCode != 0) {
             
-            if (errorCode == kOCErrorServerUnauthorized)
-                [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-            else
-                [appDelegate messageNotification:@"_error_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
+            [appDelegate messageNotification:@"_error_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         }
 
     }];
@@ -2073,16 +2037,13 @@
             
         } else if (errorCode != 0) {
             
-            if (errorCode == kOCErrorServerUnauthorized)
-                [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-            else
-                [appDelegate messageNotification:@"_share_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
+            [appDelegate messageNotification:@"_share_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         }
         
         if (_shareOC)
             [_shareOC reloadData];
         
-        [self tableViewReloadData];
+        [self tableViewReloadDataWithScrollToFileName:false];
     }];
     
     [_hud visibleHudTitle:NSLocalizedString(@"_creating_sharing_", nil) mode:MBProgressHUDModeIndeterminate color:nil];
@@ -2164,10 +2125,6 @@
                 [appDelegate startLoadAutoDownloadUpload];
             }
             
-        } else if (errorCode == kOCErrorServerUnauthorized) {
-            [appDelegate openLoginView:self delegate:self loginType:k_login_Modify_Password selector:k_intro_login];
-        } else if (errorCode == NSURLErrorServerCertificateUntrusted) {
-            [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:message viewController:self delegate:self];
         } else if (errorCode != 0) {
             [appDelegate messageNotification:@"_error_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         } else {
@@ -2970,7 +2927,7 @@
             if (aViewController.fromType == CCBKPasscodeFromLockDirectory) {
                 
                 // possiamo procedere alla prossima directory
-                [self performSegueDirectoryWithControlPasscode:false];
+                [self performSegueDirectoryWithControlPasscode:false metadata:self.metadata scrollToFileNamePath:self.scrollToFileNamePath];
                 
                 // avviamo la sessione Passcode Lock con now
                 appDelegate.sessionePasscodeLock = [NSDate date];
@@ -2986,7 +2943,7 @@
                     [appDelegate messageNotification:@"_error_" description:@"_error_operation_canc_" visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:k_CCErrorInternalError];
                 }
                 
-                [self tableViewReloadData];
+                [self tableViewReloadDataWithScrollToFileName:false];
             }
         }
             break;
@@ -3318,17 +3275,15 @@
                                     }];
         }
         
-        if (!([self.metadata.fileName isEqualToString:_autoUploadFileName] == YES && [self.metadata.serverUrl isEqualToString:_autoUploadDirectory] == YES)) {
-            
-            [actionSheet addButtonWithTitle:titoloLock
-                                      image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"settingsPasscodeYES"] multiplier:2 color:[NCBrandColor sharedInstance].icon]
-                            backgroundColor:[NCBrandColor sharedInstance].backgroundView
-                                     height:50.0
-                                       type:AHKActionSheetButtonTypeDefault
-                                    handler:^(AHKActionSheet *as) {
-                                        [self performSelector:@selector(comandoLockPassword) withObject:nil];
-                                    }];
-        }
+    
+        [actionSheet addButtonWithTitle:titoloLock
+                                  image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"settingsPasscodeYES"] multiplier:2 color:[NCBrandColor sharedInstance].icon]
+                        backgroundColor:[NCBrandColor sharedInstance].backgroundView
+                                 height:50.0
+                                   type:AHKActionSheetButtonTypeDefault
+                                handler:^(AHKActionSheet *as) {
+                                    [self performSelector:@selector(comandoLockPassword) withObject:nil];
+                                }];
         
         if (!self.metadata.e2eEncrypted && [CCUtility isEndToEndEnabled:appDelegate.activeAccount]) {
 
@@ -3376,14 +3331,16 @@
                                     }];
         }
         
+        
         [actionSheet addButtonWithTitle:NSLocalizedString(@"_delete_", nil)
                                   image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"trash"] width:50 height:50 color:[UIColor redColor]]
                         backgroundColor:[NCBrandColor sharedInstance].backgroundView
                                  height:50.0
                                    type:AHKActionSheetButtonTypeDestructive
                                 handler:^(AHKActionSheet *as) {
-                                    [self actionDelete:indexPath];
-                                }];
+                                        [self actionDelete:indexPath];
+        }];
+        
 
         [actionSheet show];
     }
@@ -3443,6 +3400,8 @@
                                     }];
         }
         
+        
+            
         [actionSheet addButtonWithTitle:NSLocalizedString(@"_rename_", nil)
                                   image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"rename"] multiplier:2 color:[NCBrandColor sharedInstance].icon]
                         backgroundColor:[NCBrandColor sharedInstance].backgroundView
@@ -3475,6 +3434,7 @@
                                     [self presentViewController:alertController animated:YES completion:nil];
                                 }];
         
+        
         if (!_metadataFolder.e2eEncrypted) {
 
             [actionSheet addButtonWithTitle:NSLocalizedString(@"_move_", nil)
@@ -3586,7 +3546,7 @@
         
         sectionDataSource = [CCSectionMetadata creataDataSourseSectionMetadata:metadatas listProgressMetadata:nil groupByField:[CCUtility getGroupBySettings] filterFileID:appDelegate.filterFileID filterTypeFileImage:NO filterTypeFileVideo:NO sorted:@"fileName" ascending:NO activeAccount:appDelegate.activeAccount];
 
-        [self tableViewReloadData];
+        [self tableViewReloadDataWithScrollToFileName:false];
         
         if ([sectionDataSource.allRecordsDataSource count] == 0 && [_searchFileName length] >= k_minCharsSearch) {
             
@@ -3642,13 +3602,13 @@
             
             dispatch_async(dispatch_get_main_queue(), ^{
                 sectionDataSource = sectionDataSourceTemp;
-                [self tableViewReloadData];
+                [self tableViewReloadDataWithScrollToFileName:true];
             });
         });
         
     } else {
         
-        [self tableViewReloadData];
+        [self tableViewReloadDataWithScrollToFileName:true];
 
          NSLog(@"[LOG] [OPTIMIZATION] Rebuild Data Source File : %@ - %@", _serverUrl, _dateReadDataSource);
     }
@@ -3674,7 +3634,7 @@
     
     if (withReloadData) {
         sectionDataSource = sectionDataSourceTemp;
-        [self tableViewReloadData];
+        [self tableViewReloadDataWithScrollToFileName:false];
     }
     
     return sectionDataSourceTemp;
@@ -3735,7 +3695,7 @@
     [self setTitle];
 }
 
-- (void)tableViewReloadData
+- (void)tableViewReloadDataWithScrollToFileName:(BOOL)withScrollToFileName
 {
     // store selected cells before relod
     NSArray *indexPaths = [self.tableView indexPathsForSelectedRows];
@@ -3754,6 +3714,32 @@
     
     //
     [self.tableView reloadEmptyDataSet];
+    
+    // scrollToFileNamePath
+    if (self.scrollToFileNamePath != nil) {
+        for (NSString *key in sectionDataSource.allRecordsDataSource) {
+            tableMetadata *metadata = [sectionDataSource.allRecordsDataSource objectForKey:key];
+            NSString *metadataFileNamePath = [NSString stringWithFormat:@"%@/%@", metadata.serverUrl, metadata.fileName];
+            if ([metadataFileNamePath isEqualToString:self.scrollToFileNamePath]) {
+                for (NSString *key in sectionDataSource.fileIDIndexPath) {
+                    if ([key isEqualToString:metadata.fileID]) {
+                        NSIndexPath *indexPath = [sectionDataSource.fileIDIndexPath objectForKey:key];
+                        [UIView animateWithDuration:0.5 animations:^{
+                            [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
+                        } completion:^(BOOL finished) {
+                            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
+                                CCCellMain *cell = [self.tableView cellForRowAtIndexPath:indexPath];
+                                if (cell) {
+                                    [[NCUtility sharedInstance] blinkWithCell:cell];
+                                }
+                            });
+                        }];
+                    }
+                }
+                self.scrollToFileNamePath = nil;
+            }
+        }
+    }
 }
 
 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
@@ -4121,7 +4107,7 @@
     
     if (self.metadata.directory) {
         
-        [self performSegueDirectoryWithControlPasscode:true];
+        [self performSegueDirectoryWithControlPasscode:true metadata:self.metadata scrollToFileNamePath:self.scrollToFileNamePath];
     }
 }
 
@@ -4231,15 +4217,15 @@
 }
 
 // can i go to next viewcontroller
-- (void)performSegueDirectoryWithControlPasscode:(BOOL)controlPasscode
+- (void)performSegueDirectoryWithControlPasscode:(BOOL)controlPasscode metadata:(tableMetadata *)metadata scrollToFileNamePath:(NSString *)scrollToFileNamePath
 {
     NSString *nomeDir;
-
+    
     if (self.tableView.editing == NO) {
         
-        NSString *lockServerUrl = [CCUtility stringAppendServerUrl:self.metadata.serverUrl addFileName:self.metadata.fileName];
+        NSString *lockServerUrl = [CCUtility stringAppendServerUrl:metadata.serverUrl addFileName:metadata.fileName];
         
-        tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, lockServerUrl]];
+        tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", metadata.account, lockServerUrl]];
         
         // SE siamo in presenza di una directory bloccata E è attivo il block E la sessione password Lock è senza data ALLORA chiediamo la password per procedere
         if (directory.lock && [[CCUtility getBlockCode] length] && appDelegate.sessionePasscodeLock == nil && controlPasscode) {
@@ -4276,15 +4262,15 @@
         }
         
         // E2EE Check enable
-        if (self.metadata.e2eEncrypted && [CCUtility isEndToEndEnabled:appDelegate.activeAccount] == NO) {
+        if (metadata.e2eEncrypted && [CCUtility isEndToEndEnabled:appDelegate.activeAccount] == NO) {
             
             [appDelegate messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeInfo errorCode:0];
             return;
         }
         
-        nomeDir = self.metadata.fileName;
+        nomeDir = metadata.fileName;
         
-        NSString *serverUrlPush = [CCUtility stringAppendServerUrl:self.metadata.serverUrl addFileName:nomeDir];
+        NSString *serverUrlPush = [CCUtility stringAppendServerUrl:metadata.serverUrl addFileName:nomeDir];
     
         CCMain *viewController = [appDelegate.listMainVC objectForKey:serverUrlPush];
         
@@ -4293,7 +4279,8 @@
             viewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"CCMain"];
             
             viewController.serverUrl = serverUrlPush;
-            viewController.titleMain = self.metadata.fileName;
+            viewController.titleMain = metadata.fileName;
+            viewController.scrollToFileNamePath = scrollToFileNamePath;
             
             // save self
             [appDelegate.listMainVC setObject:viewController forKey:serverUrlPush];
@@ -4304,7 +4291,8 @@
            
             if (viewController.isViewLoaded) {
                 
-                viewController.titleMain = self.metadata.fileName;
+                viewController.titleMain = metadata.fileName;
+                viewController.scrollToFileNamePath = scrollToFileNamePath;
                 
                 // Fix : Application tried to present modally an active controller
                 if ([self.navigationController isBeingPresented]) {

+ 4 - 4
iOSClient/Main/CCMore.swift

@@ -481,7 +481,7 @@ class CCMore: UIViewController, UITableViewDelegate, UITableViewDataSource, CCLo
 extension CCMore: SwiftModalWebVCDelegate, SwiftWebVCDelegate{
     
     public func didStartLoading() {
-        print("Started loading.")
+        //print("Started loading.")
     }
     
     public func didReceiveServerRedirectForProvisionalNavigation(url: URL) {
@@ -500,15 +500,15 @@ extension CCMore: SwiftModalWebVCDelegate, SwiftWebVCDelegate{
     }
     
     public func didFinishLoading(success: Bool) {
-        print("Finished loading. Success: \(success).")
+        //print("Finished loading. Success: \(success).")
     }
     
     public func didFinishLoading(success: Bool, url: URL) {
-        print("Finished loading. Success: \(success).")
+        //print("Finished loading. Success: \(success).")
     }
     
     public func webDismiss() {
-        print("Web dismiss.")
+        //print("Web dismiss.")
     }
 }
 

+ 1 - 1
iOSClient/Main/CCSplit.m

@@ -181,7 +181,7 @@
 
 - (void)loginSuccess:(NSInteger)loginType
 {
-    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"initializeMain" object:nil userInfo:nil];    
+    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"initializeMain" object:nil userInfo:nil];
 }
 
 #pragma --------------------------------------------------------------------------------------------

+ 1 - 0
iOSClient/Main/Cell/CCCellMain.m

@@ -22,6 +22,7 @@
 //
 
 #import "CCCellMain.h"
+#import "NCBridgeSwift.h"
 
 @implementation CCCellMain
 

+ 2 - 2
iOSClient/Main/Cell/CCCellMain.xib

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>

+ 23 - 29
iOSClient/Main/NCMainCommon.swift

@@ -241,8 +241,8 @@ class NCMainCommon: NSObject, PhotoEditorDelegate, NCAudioRecorderViewController
         }
         
         // Share
-        let sharesLink = appDelegate.sharesLink.object(forKey: serverUrl + metadata.fileName)
-        let sharesUserAndGroup = appDelegate.sharesUserAndGroup.object(forKey: serverUrl + metadata.fileName)
+        let sharesLink = appDelegate.sharesLink.object(forKey: serverUrl + metadata.fileName) as? String
+        let sharesUserAndGroup = appDelegate.sharesUserAndGroup.object(forKey: serverUrl + metadata.fileName) as? String
         var isShare = false
         var isMounted = false
         
@@ -534,8 +534,8 @@ class NCMainCommon: NSObject, PhotoEditorDelegate, NCAudioRecorderViewController
             NCNetworkingMain.sharedInstance.downloadThumbnail(with: metadata, view: tableView, indexPath: indexPath)
             
             // Share
-            let sharesLink = appDelegate.sharesLink.object(forKey: serverUrl + metadata.fileName)
-            let sharesUserAndGroup = appDelegate.sharesUserAndGroup.object(forKey: serverUrl + metadata.fileName)
+            let sharesLink = appDelegate.sharesLink.object(forKey: serverUrl + metadata.fileName) as? String
+            let sharesUserAndGroup = appDelegate.sharesUserAndGroup.object(forKey: serverUrl + metadata.fileName) as? String
             var isShare = false
             var isMounted = false
             
@@ -1229,32 +1229,26 @@ class NCNetworkingMain: NSObject, CCNetworkingDelegate {
                 
                 if metadata.typeFile == k_metadataTypeFile_imagemeter {
                     
-                    do {
-                        let source = URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageFileID(metadata.fileID, fileNameView: metadata.fileNameView))
-                        let destination =  URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageFileID(metadata.fileID))
-                        
-                        try FileManager().unzipItem(at: source, to: destination)
-                        
-                        let nameArchiveImagemeter = (metadata.fileNameView as NSString).deletingPathExtension
-                        let pathArchiveImagemeter = CCUtility.getDirectoryProviderStorageFileID(metadata.fileID) + "/" + nameArchiveImagemeter
-                        let annoPath = (pathArchiveImagemeter + "/anno-" + nameArchiveImagemeter + ".imm")
-                        
-                        if let fileHandle = FileHandle(forReadingAtPath: annoPath) {
-                            let data = fileHandle.readData(ofLength: 4)
-                            if data.starts(with: [0x50, 0x4b, 0x03, 0x04]) {
-                                do {
-                                    try FileManager().unzipItem(at: annoPath.url, to: pathArchiveImagemeter.url)
-                                } catch {
-                                    appDelegate.messageNotification("_error_", description: "_error_decompressing_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
-                                    return
-                                }
-                            }
-                            fileHandle.closeFile()
+                    let source = URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageFileID(metadata.fileID, fileNameView: metadata.fileNameView))
+                    let destination =  URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageFileID(metadata.fileID))
+                    
+                    try? FileManager().unzipItem(at: source, to: destination)
+                    
+                    let nameArchiveImagemeter = (metadata.fileNameView as NSString).deletingPathExtension
+                    let pathArchiveImagemeter = CCUtility.getDirectoryProviderStorageFileID(metadata.fileID) + "/" + nameArchiveImagemeter
+                    let annoPath = (pathArchiveImagemeter + "/anno-" + nameArchiveImagemeter + ".imm")
+                    
+                    if let fileHandle = FileHandle(forReadingAtPath: annoPath) {
+                        let dataFormat = fileHandle.readData(ofLength: 1)
+                        if dataFormat.starts(with: [0x01]) {
+                            appDelegate.messageNotification("_error_", description: "File format binary error, library imagemeter not present. 🤷‍♂️", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
+                            return;
                         }
-                        
-                    } catch {
-                        appDelegate.messageNotification("_error_", description: "_error_decompressing_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
-                        return
+                        let dataZip = fileHandle.readData(ofLength: 4)
+                        if dataZip.starts(with: [0x50, 0x4b, 0x03, 0x04]) {
+                            try? FileManager().unzipItem(at: annoPath.url, to: pathArchiveImagemeter.url)
+                        }
+                        fileHandle.closeFile()
                     }
                 }
                 

+ 1 - 1
iOSClient/Media/NCMedia.swift

@@ -502,7 +502,7 @@ extension NCMedia {
         
         DispatchQueue.global().async {
             
-            let metadatas = NCManageDatabase.sharedInstance.getTableMedias(predicate: NSPredicate(format: "account == %@", self.appDelegate.activeAccount))
+            let metadatas = NCManageDatabase.sharedInstance.getTablesMedia(account: self.appDelegate.activeAccount)
             self.sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: "date", filterFileID: nil, filterTypeFileImage: self.filterTypeFileImage, filterTypeFileVideo: self.filterTypeFileVideo, sorted: "date", ascending: false, activeAccount: self.appDelegate.activeAccount)
             
             DispatchQueue.main.async {

+ 30 - 1
iOSClient/Networking/CCNetworking.m

@@ -388,6 +388,15 @@
 
 - (void)downloadFile:(tableMetadata *)metadata taskStatus:(NSInteger)taskStatus
 {
+    // No Password
+    if ([CCUtility getPassword:metadata.account].length == 0) {
+        [self.delegate downloadFileSuccessFailure:metadata.fileName fileID:metadata.fileID serverUrl:metadata.serverUrl selector:metadata.sessionSelector errorMessage:NSLocalizedString(@"_bad_username_password_", nil) errorCode:kOCErrorServerUnauthorized];
+        return;
+    } else if ([CCUtility getCertificateError:metadata.account]) {
+        [self.delegate downloadFileSuccessFailure:metadata.fileName fileID:metadata.fileID serverUrl:metadata.serverUrl selector:metadata.sessionSelector errorMessage:NSLocalizedString(@"_ssl_certificate_untrusted_", nil) errorCode:NSURLErrorServerCertificateUntrusted];
+        return;
+    }
+    
     // File exists ?
     tableLocalFile *localfile = [[NCManageDatabase sharedInstance] getTableLocalFileWithPredicate:[NSPredicate predicateWithFormat:@"fileID == %@", metadata.fileID]];
         
@@ -529,6 +538,8 @@
     [appDelegate.listProgressMetadata removeObjectForKey:fileID];
 #endif
     
+     tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileID == %@", fileID]];
+    
     if (errorCode != 0) {
         
         if (errorCode == kCFURLErrorCancelled) {
@@ -537,6 +548,11 @@
             
         } else {
             
+            if (metadata && errorCode == kOCErrorServerUnauthorized)
+                [CCUtility setPassword:metadata.account password:nil];
+            else if (metadata && errorCode == NSURLErrorServerCertificateUntrusted)
+                [CCUtility setCertificateError:metadata.account error:YES];
+
             [[NCManageDatabase sharedInstance] setMetadataSession:nil sessionError:[CCError manageErrorKCF:errorCode withNumberError:NO] sessionSelector:nil sessionTaskIdentifier:k_taskIdentifierDone status:k_metadataStatusDownloadError predicate:[NSPredicate predicateWithFormat:@"fileID == %@", fileID]];
         }
         
@@ -546,7 +562,6 @@
         
     } else {
         
-        tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileID == %@", fileID]];
         if (!metadata) {
             
             NSLog(@"[LOG] Serious error internal download : metadata not found %@ ", fileName);
@@ -602,6 +617,15 @@
 
 - (void)uploadFile:(tableMetadata *)metadata taskStatus:(NSInteger)taskStatus
 {
+    // Password nil
+    if ([CCUtility getPassword:metadata.account].length == 0) {
+        [self.delegate uploadFileSuccessFailure:metadata.fileName fileID:metadata.fileID assetLocalIdentifier:metadata.assetLocalIdentifier serverUrl:metadata.serverUrl selector:metadata.sessionSelector errorMessage:NSLocalizedString(@"_bad_username_password_", nil) errorCode:kOCErrorServerUnauthorized];
+        return;
+    } else if ([CCUtility getCertificateError:metadata.account]) {
+        [self.delegate uploadFileSuccessFailure:metadata.fileName fileID:metadata.fileID assetLocalIdentifier:metadata.assetLocalIdentifier serverUrl:metadata.serverUrl selector:metadata.sessionSelector errorMessage:NSLocalizedString(@"_ssl_certificate_untrusted_", nil) errorCode:NSURLErrorServerCertificateUntrusted];
+        return;
+    }
+    
     tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", metadata.account]];
     if (tableAccount == nil) {
         [[NCManageDatabase sharedInstance] deleteMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileID == %@", metadata.fileID]];
@@ -1082,6 +1106,11 @@
             
         } else {
 
+            if (metadata && errorCode == kOCErrorServerUnauthorized)
+                [CCUtility setPassword:metadata.account password:nil];
+            else if (metadata && errorCode == NSURLErrorServerCertificateUntrusted)
+                [CCUtility setCertificateError:metadata.account error:YES];
+            
             [[NCManageDatabase sharedInstance] setMetadataSession:nil sessionError:[CCError manageErrorKCF:errorCode withNumberError:NO] sessionSelector:nil sessionTaskIdentifier:k_taskIdentifierDone status:k_metadataStatusUploadError predicate:[NSPredicate predicateWithFormat:@"fileID == %@", tempFileID]];
             
             errorMessage = [CCError manageErrorKCF:errorCode withNumberError:YES];

+ 111 - 100
iOSClient/Networking/NCService.swift

@@ -43,19 +43,91 @@ class NCService: NSObject {
         }
         
         self.requestUserProfile()
-        self.requestServerCapabilities()
         self.requestServerStatus()
-        self.requestListTrash()
-        
-        // Thirt Part
-#if HC
-        self.requestHC()
-#endif
     }
 
     //MARK: -
     //MARK: Internal request Service API NC
     
+    private func requestUserProfile() {
+        
+        if (appDelegate.activeAccount == nil || appDelegate.activeAccount.count == 0 || appDelegate.maintenanceMode == true) {
+            return
+        }
+        
+        OCNetworking.sharedManager().getUserProfile(withAccount: appDelegate.activeAccount, completion: { (account, userProfile, message, errorCode) in
+            
+            if errorCode == 0 && account == self.appDelegate.activeAccount {
+                
+                // Update User (+ userProfile.id) & active account & account network
+                guard let tableAccount = NCManageDatabase.sharedInstance.setAccountUserProfile(userProfile!, HCProperties: false) else {
+                    self.appDelegate.messageNotification("Accopunt", description: "Internal error : account not found on DB", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: Int(k_CCErrorInternalError))
+                    return
+                }
+                
+                let user = tableAccount.user
+                let url = tableAccount.url
+                
+                self.appDelegate.settingActiveAccount(tableAccount.account, activeUrl: tableAccount.url, activeUser: tableAccount.user, activeUserID: tableAccount.userID, activePassword: CCUtility.getPassword(tableAccount.account))
+                
+                // Call func thath required the userdID
+                self.appDelegate.activeFavorites.listingFavorites()
+                self.appDelegate.activeMedia.reloadDataSource(loadNetworkDatasource: true)
+                NCFunctionMain.sharedInstance.synchronizeOffline()
+                
+                DispatchQueue.global().async {
+                    
+                    let avatarUrl = "\(self.appDelegate.activeUrl!)/index.php/avatar/\(self.appDelegate.activeUser!)/128".addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)!
+                    let fileNamePath = CCUtility.getDirectoryUserData() + "/" + CCUtility.getStringUser(user, activeUrl: url) + "-" + self.appDelegate.activeUser + ".png"
+                    
+                    OCNetworking.sharedManager()?.downloadContents(ofUrl: avatarUrl, completion: { (data, message, errorCode) in
+                        if errorCode == 0 {
+                            if let image = UIImage(data: data!) {
+                                try? FileManager.default.removeItem(atPath: fileNamePath)
+                                if let data = image.pngData() {
+                                    try? data.write(to: URL(fileURLWithPath: fileNamePath))
+                                }
+                            }
+                        }
+                    })
+                    
+                    DispatchQueue.main.async {
+                        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "changeUserProfile"), object: nil)
+                    }
+                }
+                
+                // Get Capabilities
+                self.requestServerCapabilities()
+                
+            } else if errorCode != 0 {
+                
+                print("Get user profile failure error")
+                
+            } else {
+                
+                if errorCode == kOCErrorServerUnauthorized {
+                    CCUtility.setPassword(account, password: nil)
+                }
+                
+                print("[LOG] It has been changed user during networking process, error.")
+            }
+        })
+    }
+    
+    private func requestServerStatus() {
+        
+        OCNetworking.sharedManager().serverStatusUrl(appDelegate.activeUrl, completion: { (serverProductName, versionMajor, versionMicro, versionMinor, message, errorCode) in
+            if errorCode == 0 {
+                if serverProductName == "owncloud" {
+                    self.appDelegate.messageNotification("_warning_", description: "_warning_owncloud_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: Int(k_CCErrorInternalError))
+                } else if versionMajor <= k_nextcloud_unsupported {
+                    self.appDelegate.messageNotification("_warning_", description: "_warning_unsupported_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: Int(k_CCErrorInternalError))
+                }
+            }
+            
+        })
+    }
+    
     private func requestServerCapabilities() {
         
         if (appDelegate.activeAccount == nil || appDelegate.activeAccount.count == 0 || appDelegate.maintenanceMode == true) {
@@ -83,14 +155,16 @@ class NCService: NSObject {
                         let backgroundURL = capabilities!.themingBackground!.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)!
                         let fileNamePath = CCUtility.getDirectoryUserData() + "/" + CCUtility.getStringUser(self.appDelegate.activeUser, activeUrl: self.appDelegate.activeUrl) + "-themingBackground.png"
                         
-                        if let imageData = try? Data(contentsOf: URL(string: backgroundURL)!) {
-                            if let image = UIImage(data: imageData) {
-                                try? FileManager.default.removeItem(atPath: fileNamePath)
-                                if let data = image.pngData() {
-                                    try? data.write(to: URL(fileURLWithPath: fileNamePath))
+                        OCNetworking.sharedManager()?.downloadContents(ofUrl: backgroundURL, completion: { (data, message, errorCode) in
+                            if errorCode == 0 {
+                                if let image = UIImage(data: data!) {
+                                    try? FileManager.default.removeItem(atPath: fileNamePath)
+                                    if let data = image.pngData() {
+                                        try? data.write(to: URL(fileURLWithPath: fileNamePath))
+                                    }
                                 }
                             }
-                        }
+                        })
                         
                         DispatchQueue.main.async {
                             self.appDelegate.settingThemingColorBrand()
@@ -110,7 +184,7 @@ class NCService: NSObject {
                 
                 // ------ GET OTHER SERVICE -------------------------------------------------------------
                 
-                // Read Notification
+                // Get Notification
                 if (capabilities!.isNotificationServerEnabled) {
                     
                     OCNetworking.sharedManager().getNotificationWithAccount(account!, completion: { (account, listOfNotifications, message, errorCode) in
@@ -173,7 +247,7 @@ class NCService: NSObject {
                     }
                 }
                 
-                // Read External Sites
+                // Get External Sites
                 if (capabilities!.isExternalSitesServerEnabled) {
                     
                     OCNetworking.sharedManager().getExternalSites(withAccount: account!, completion: { (account, listOfExternalSites, message, errorCode) in
@@ -193,12 +267,13 @@ class NCService: NSObject {
                     NCManageDatabase.sharedInstance.deleteExternalSites(account: account!)
                 }
                 
-                // Read Share
+                // Get Share
                 if (capabilities!.isFilesSharingAPIEnabled && self.appDelegate.activeMain != nil) {
                     
                     self.appDelegate.activeMain.readShare(withAccount: account, openWindow: false, metadata: nil)
                 }
                 
+                // Get Activity
                 if (capabilities!.isActivityV2Enabled) {
                     
                     OCNetworking.sharedManager().getActivityWithAccount(account!, since: 0, limit: 100, link: "", completion: { (account, listOfActivity, message, errorCode) in
@@ -210,70 +285,35 @@ class NCService: NSObject {
                     })
                 }
                 
-            } else if errorCode != 0 {
+                // Get Trash List
+                let pathTrash = k_dav + "/trashbin/" + (self.appDelegate.activeUserID as NSString).addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlFragmentAllowed)! + "/trash/"
                 
-                self.appDelegate.settingThemingColorBrand()
-                
-            } else {
-                print("[LOG] It has been changed user during networking process, error.")
-                // Change Theming color
-                self.appDelegate.settingThemingColorBrand()
-            }
-        })
-    }
-    
-    private func requestUserProfile() {
-        
-        if (appDelegate.activeAccount == nil || appDelegate.activeAccount.count == 0 || appDelegate.maintenanceMode == true) {
-            return
-        }
-        
-        OCNetworking.sharedManager().getUserProfile(withAccount: appDelegate.activeAccount, completion: { (account, userProfile, message, errorCode) in
-            
-            if errorCode == 0 && account == self.appDelegate.activeAccount {
+                OCNetworking.sharedManager().listingTrash(withAccount: account, path: pathTrash, serverUrl: self.appDelegate.activeUrl, depth: "infinity", completion: { (account, item, message, errorCode) in
+                    if errorCode == 0 && account == self.appDelegate.activeAccount {
+                        DispatchQueue.global().async {
+                            NCManageDatabase.sharedInstance.deleteTrash(filePath: nil, account: account!)
+                            NCManageDatabase.sharedInstance.addTrashs(item as! [tableTrash])
+                        }
+                    }
+                })
                 
-                // Update User (+ userProfile.id) & active account & account network
-                guard let tableAccount = NCManageDatabase.sharedInstance.setAccountUserProfile(userProfile!, HCProperties: false) else {
-                    self.appDelegate.messageNotification("Accopunt", description: "Internal error : account not found on DB", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: Int(k_CCErrorInternalError))
-                    return
+                // Get Handwerkcloud
+                if (capabilities!.isHandwerkcloudEnabled) {
+                    self.requestHC()
                 }
+              
+            } else if errorCode != 0 {
                 
-                let user = tableAccount.user
-                let url = tableAccount.url
-                
-                self.appDelegate.settingActiveAccount(tableAccount.account, activeUrl: tableAccount.url, activeUser: tableAccount.user, activeUserID: tableAccount.userID, activePassword: CCUtility.getPassword(tableAccount.account))
-                
-                // Call func thath required the userdID
-                self.appDelegate.activeFavorites.listingFavorites()
-                self.appDelegate.activeMedia.reloadDataSource(loadNetworkDatasource: true)
-                NCFunctionMain.sharedInstance.synchronizeOffline()
+                self.appDelegate.settingThemingColorBrand()
                 
-                DispatchQueue.global().async {
-                    
-                    let address = "\(self.appDelegate.activeUrl!)/index.php/avatar/\(self.appDelegate.activeUser!)/128".addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)!
-                    let fileNamePath = CCUtility.getDirectoryUserData() + "/" + CCUtility.getStringUser(user, activeUrl: url) + "-" + self.appDelegate.activeUser + ".png"
-                    
-                    if let imageData = try? Data(contentsOf: URL(string: address)!) {
-                        if let image = UIImage(data: imageData) {
-                            try? FileManager.default.removeItem(atPath: fileNamePath)
-                            if let data = image.pngData() {
-                                try? data.write(to: URL(fileURLWithPath: fileNamePath))
-                            }
-                        }
-                    }
-                    
-                    DispatchQueue.main.async {
-                        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "changeUserProfile"), object: nil)
-                    }
+                if errorCode == kOCErrorServerUnauthorized {
+                    CCUtility.setPassword(account, password: nil)
                 }
                 
-            } else if errorCode != 0 {
-                
-                print("Get user profile failure error")
-               
             } else {
-                
                 print("[LOG] It has been changed user during networking process, error.")
+                // Change Theming color
+                self.appDelegate.settingThemingColorBrand()
             }
         })
     }
@@ -285,35 +325,6 @@ class NCService: NSObject {
         }
     }
     
-    private func requestServerStatus() {
-
-        OCNetworking.sharedManager().serverStatusUrl(appDelegate.activeUrl, completion: { (serverProductName, versionMajor, versionMicro, versionMinor, message, errorCode) in
-            if errorCode == 0 {
-                if serverProductName == "owncloud" {
-                    self.appDelegate.messageNotification("_warning_", description: "_warning_owncloud_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: Int(k_CCErrorInternalError))
-                } else if versionMajor <= k_nextcloud_unsupported {
-                    self.appDelegate.messageNotification("_warning_", description: "_warning_unsupported_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: Int(k_CCErrorInternalError))
-                }
-            }
-            
-        })
-    }
-    
-    private func requestListTrash() {
-        
-        let userID = (appDelegate.activeUserID as NSString).addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlFragmentAllowed)
-        let path = k_dav + "/trashbin/" + userID! + "/trash/"
-        
-        OCNetworking.sharedManager().listingTrash(withAccount: appDelegate.activeAccount, path: path, serverUrl: appDelegate.activeUrl, depth: "infinity", completion: { (account, item, message, errorCode) in
-            if errorCode == 0 && account == self.appDelegate.activeAccount {
-                DispatchQueue.global().async {
-                    NCManageDatabase.sharedInstance.deleteTrash(filePath: nil, account: account!)
-                    NCManageDatabase.sharedInstance.addTrashs(item as! [tableTrash])
-                }
-            }
-        })
-    }
-    
     //MARK: -
     //MARK: Thirt Part
     

+ 1 - 0
iOSClient/Networking/OCNetworking.h

@@ -38,6 +38,7 @@
 
 - (void)checkServerUrl:(NSString *)serverUrl user:(NSString *)user userID:(NSString *)userID password:(NSString *)password completion:(void (^)(NSString *message, NSInteger errorCode))completion;
 - (void)serverStatusUrl:(NSString *)serverUrl completion:(void(^)(NSString *serverProductName, NSInteger versionMajor, NSInteger versionMicro, NSInteger versionMinor, NSString *message, NSInteger errorCode))completion;
+- (void)downloadContentsOfUrl:(NSString *)serverUrl completion:(void(^)(NSData *data, NSString *message, NSInteger errorCode))completion;
 
 #pragma mark ===== Download / Upload =====
 

File diff suppressed because it is too large
+ 436 - 35
iOSClient/Networking/OCNetworking.m


+ 1 - 1
iOSClient/Security/CCCertificate.h

@@ -41,7 +41,7 @@
 - (BOOL)acceptCertificate;
 - (void)saveCertificate:(SecTrustRef) trust withName:(NSString *) certName;
 
-- (void)presentViewControllerCertificateWithTitle:(NSString *)title viewController:(UIViewController *)viewController delegate:(id)delegate;
+- (void)presentViewControllerCertificateWithAccount:(NSString *)account viewController:(UIViewController *)viewController delegate:(id)delegate;
 
 @end
 

+ 16 - 7
iOSClient/Security/CCCertificate.m

@@ -24,6 +24,7 @@
 #import "CCUtility.h"
 #import "CCCertificate.h"
 #import "NCBridgeSwift.h"
+#import "AppDelegate.h"
 
 #import <openssl/x509.h>
 #import <openssl/bio.h>
@@ -139,32 +140,40 @@ static SecCertificateRef SecTrustGetLeafCertificate(SecTrustRef trust)
     X509_free(x509cert);
 }
 
-- (void)presentViewControllerCertificateWithTitle:(NSString *)title viewController:(UIViewController *)viewController delegate:(id)delegate
-{    
+- (void)presentViewControllerCertificateWithAccount:(NSString *)account viewController:(UIViewController *)viewController delegate:(id)delegate
+{
+    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
+    _delegate = delegate;
+    
     if (![viewController isKindOfClass:[UIViewController class]])
         return;
     
-    _delegate = delegate;
-    
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
     
-        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:NSLocalizedString(@"_connect_server_anyway_", nil)  preferredStyle:UIAlertControllerStyleAlert];
+        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_ssl_certificate_untrusted_", nil) message:NSLocalizedString(@"_connect_server_anyway_", nil)  preferredStyle:UIAlertControllerStyleAlert];
     
         [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_yes_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                                                            
             [[CCCertificate sharedManager] acceptCertificate];
+            if (account != nil) [CCUtility setCertificateError:account error:NO];
+            [appDelegate startTimerErrorNetworking];
             
             if([self.delegate respondsToSelector:@selector(trustedCerticateAccepted)])
                 [self.delegate trustedCerticateAccepted];
         }]];
     
         [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_no_", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
-                                                           
+            
+            [appDelegate startTimerErrorNetworking];
+
             if([self.delegate respondsToSelector:@selector(trustedCerticateDenied)])
                 [self.delegate trustedCerticateDenied];
         }]];
         
-        [viewController presentViewController:alertController animated:YES completion:nil];
+        [viewController presentViewController:alertController animated:YES completion:^{
+            // Stop timer error network
+            [appDelegate.timerErrorNetworking invalidate];
+        }];
     });
 }
 

+ 42 - 16
iOSClient/Settings/CCManageAccount.m

@@ -60,6 +60,7 @@
         
     NSArray *listAccount = [[NCManageDatabase sharedInstance] getAccounts];
     tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountActive];
+    tableCapabilities *tableCapabilities = [[NCManageDatabase sharedInstance] getCapabilitesWithAccount:tableAccount.account];
 
     // Section : ACCOUNTS -------------------------------------------
     
@@ -232,7 +233,7 @@
     
     // Section : THIRT PART -------------------------------------------
 
-#if defined(HC)
+    if (tableCapabilities.isHandwerkcloudEnabled) {
 
         section = [XLFormSectionDescriptor formSectionWithTitle:NSLocalizedString(@"_user_job_", nil)];
         [form addFormSection:section];
@@ -271,7 +272,23 @@
         [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"company"] width:50 height:50 color:[NCBrandColor sharedInstance].icon] forKey:@"imageView.image"];
         row.value = tableAccount.company;
         [section addFormRow:row];
+    
+        if (tableAccount.hcIsTrial) {
         
+            section = [XLFormSectionDescriptor formSectionWithTitle:NSLocalizedString(@"_trial_", nil)];
+            [form addFormSection:section];
+            
+            row = [XLFormRowDescriptor formRowDescriptorWithTag:@"trial" rowType:XLFormRowDescriptorTypeInfo title:NSLocalizedString(@"_trial_expired_day_", nil)];
+            [row.cellConfig setObject:[UIFont systemFontOfSize:15.0]forKey:@"textLabel.font"];
+            [row.cellConfig setObject:[UIFont systemFontOfSize:15.0]forKey:@"detailTextLabel.font"];
+            [row.cellConfig setObject:[UIColor redColor] forKey:@"textLabel.textColor"];
+            [row.cellConfig setObject:[UIColor redColor] forKey:@"detailTextLabel.textColor"];
+            [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"timer"] width:50 height:50 color:[UIColor redColor]] forKey:@"imageView.image"];
+            NSInteger numberOfDays = tableAccount.hcTrialRemainingSec / (24*3600);
+            row.value = [@(numberOfDays) stringValue];
+            [section addFormRow:row];
+        }
+    
         section = [XLFormSectionDescriptor formSection];
         [form addFormSection:section];
         
@@ -281,10 +298,12 @@
         [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"editUserProfile"] width:50 height:50 color:[NCBrandColor sharedInstance].icon] forKey:@"imageView.image"];
         [row.cellConfig setObject:@(NSTextAlignmentLeft) forKey:@"textLabel.textAlignment"];
         [row.cellConfig setObject:[UIColor blackColor] forKey:@"textLabel.textColor"];
+#if defined(HC)
         row.action.viewControllerClass = [HCEditProfile class];
+#endif
         if (listAccount.count == 0) row.disabled = @YES;
         [section addFormRow:row];
-#endif
+    }
     
     self.form = form;
     
@@ -385,26 +404,33 @@
         XLFormPickerCell *pickerAccount = (XLFormPickerCell *)[[self.form formRowWithTag:@"pickerAccount"] cellForFormController:self];
         
         tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", pickerAccount.rowDescriptor.value]];
+        NSString *account = tableAccount.account;
         
-        if (tableAccount) {
+        if (account) {
             
-            [appDelegate unsubscribingNextcloudServerPushNotification:tableAccount.account url:tableAccount.url withSubscribing:false];
+            [appDelegate unsubscribingNextcloudServerPushNotification:account url:tableAccount.url withSubscribing:false];
         
-            [[NCManageDatabase sharedInstance] clearTable:[tableAccount class] account:tableAccount.account];
-            [[NCManageDatabase sharedInstance] clearTable:[tableActivity class] account:tableAccount.account];
-            [[NCManageDatabase sharedInstance] clearTable:[tableActivitySubjectRich class] account:tableAccount.account];
-            [[NCManageDatabase sharedInstance] clearTable:[tableCapabilities class] account:tableAccount.account];
-            [[NCManageDatabase sharedInstance] clearTable:[tableDirectory class] account:tableAccount.account];
-            [[NCManageDatabase sharedInstance] clearTable:[tableE2eEncryption class] account:tableAccount.account];
-            [[NCManageDatabase sharedInstance] clearTable:[tableExternalSites class] account:tableAccount.account];
-            [[NCManageDatabase sharedInstance] clearTable:[tableLocalFile class] account:tableAccount.account];
-            [[NCManageDatabase sharedInstance] clearTable:[tableMetadata class] account:tableAccount.account];
-            [[NCManageDatabase sharedInstance] clearTable:[tableMedia class] account:tableAccount.account];
-            [[NCManageDatabase sharedInstance] clearTable:[tablePhotoLibrary class] account:tableAccount.account];
-            [[NCManageDatabase sharedInstance] clearTable:[tableShare class] account:tableAccount.account];
+            [[NCManageDatabase sharedInstance] clearTable:[tableAccount class] account:account];
+            [[NCManageDatabase sharedInstance] clearTable:[tableActivity class] account:account];
+            [[NCManageDatabase sharedInstance] clearTable:[tableActivitySubjectRich class] account:account];
+            [[NCManageDatabase sharedInstance] clearTable:[tableCapabilities class] account:account];
+            [[NCManageDatabase sharedInstance] clearTable:[tableDirectory class] account:account];
+            [[NCManageDatabase sharedInstance] clearTable:[tableE2eEncryption class] account:account];
+            [[NCManageDatabase sharedInstance] clearTable:[tableExternalSites class] account:account];
+            [[NCManageDatabase sharedInstance] clearTable:[tableLocalFile class] account:account];
+            [[NCManageDatabase sharedInstance] clearTable:[tableMetadata class] account:account];
+            [[NCManageDatabase sharedInstance] clearTable:[tableMedia class] account:account];
+            [[NCManageDatabase sharedInstance] clearTable:[tablePhotoLibrary class] account:account];
+            [[NCManageDatabase sharedInstance] clearTable:[tableShare class] account:account];
         
             // Clear active user
             [appDelegate settingActiveAccount:nil activeUrl:nil activeUser:nil activeUserID:nil activePassword:nil];
+            
+            // Clear keychain
+            [CCUtility clearAllKeysEndToEnd:account];
+            [CCUtility clearAllKeysPushNotification:account];
+            [CCUtility setPassword:account password:nil];
+            [CCUtility setCertificateError:account error:NO];
         }
         
         NSArray *listAccount = [[NCManageDatabase sharedInstance] getAccounts];

+ 6 - 1
iOSClient/Share/CCShareOC.m

@@ -295,7 +295,12 @@
                 
             if (item.shareType == shareTypeGroup) row.title = [item.shareWithDisplayName stringByAppendingString:NSLocalizedString(@"_user_is_group_", nil)];
             else row.title = item.shareWithDisplayName;
-                
+            
+            //If the initiator or the recipient is not the current user, show the list of sharees without any options to edit it.
+            if (![item.uidOwner isEqualToString:appDelegate.activeUserID]) {
+                row.disabled = @YES;
+            }
+            
             [section addFormRow:row];
                 
             // add users

+ 0 - 4
iOSClient/Shares/NCShares.m

@@ -204,10 +204,6 @@
             
             [self reloadDatasource];
             
-        } if (errorCode == kOCErrorServerUnauthorized) {
-            [appDelegate openLoginView:self delegate:appDelegate.activeMain loginType:k_login_Modify_Password selector:k_intro_login];
-        } else if (errorCode == NSURLErrorServerCertificateUntrusted) {
-            [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:message viewController:self delegate:self];
         } else if (errorCode != 0) {
             [appDelegate messageNotification:@"_share_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         } else {

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


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


BIN
iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings


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


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


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


BIN
iOSClient/Supporting Files/en-GB.lproj/Localizable.strings


+ 10 - 0
iOSClient/Supporting Files/en.lproj/Localizable.strings

@@ -101,6 +101,8 @@
 "_denied_camera_"           = "This app does not have access to \"Camera\", you can enable access in Privacy Settings";
 "_start_"                   = "Start";
 "_purchase_"                = "Purchase";
+"_account_not_available_"   = "The account %@ of %@ do not exists, please add it to be able to read the file %@";
+"_error_parameter_schema_"  = "Wrong parameters, impossible to continue";
 
 // App
 
@@ -206,6 +208,8 @@
 "_advanced_"                    = "Advanced";
 "_disable_files_app_"           = "Disable Files App integration";
 "_disable_files_app_footer_"    = "Do not permit the access of files across the Apple Files application";
+"_trial_"                       = "Trial";
+"_trial_expired_day_"           = "Days remaining";
 
 // Manage AutoUpload
 
@@ -695,6 +699,7 @@
 "_server_response_error_"               = "Server response content error";
 "_no_nextcloud_found_"                  = "Nextcloud server not found";
 "_error_decompressing_"                 = "Error during decompressing. Unknown compression method or the file is corrupt";
+"_error_json_decoding_"                 = "Serious internal error in decoding metadata (The data couldn’t be read because it isn’t in the correct format.)";
 
 // BKPasscode
 
@@ -750,3 +755,8 @@
 "_voice_memo_stop_"         = "tap to stop";
 "_voice_memo_filename_"     = "voice memo";
 "_voice_memo_title_"        = "Upload voice memo";
+
+// Dictionary App push Notification
+"Suspicious_Login"          = "Suspicious Login";
+
+

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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


BIN
iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings


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


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


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


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


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


BIN
iOSClient/Supporting Files/ja-JP.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings


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


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


BIN
iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings


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


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


BIN
iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings


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


BIN
iOSClient/Supporting Files/sk-SK.lproj/Localizable.strings


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


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


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


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


BIN
iOSClient/Supporting Files/zh-Hans.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/zh-Hant-TW.lproj/Localizable.strings


+ 11 - 18
iOSClient/Trash/NCTrash.swift

@@ -31,7 +31,6 @@ class NCTrash: UIViewController, UIGestureRecognizerDelegate, NCTrashListCellDel
     var path = ""
     var titleCurrentFolder = NSLocalizedString("_trash_view_", comment: "")
     var scrollToFileID = ""
-    var scrollToIndexPath: IndexPath?
     
     private let appDelegate = UIApplication.shared.delegate as! AppDelegate
     
@@ -653,19 +652,19 @@ extension NCTrash {
             if self.scrollToFileID != "" {
                 for item in 0...self.datasource.count-1 {
                     if self.datasource[item].fileID.contains(self.scrollToFileID) {
-                        self.scrollToIndexPath = IndexPath(item: item, section: 0)
-                        self.collectionView.scrollToItem(at: self.scrollToIndexPath!, at: .top, animated: true)
-                        if let cell = self.collectionView.cellForItem(at: self.scrollToIndexPath!) as? NCTrashListCell {
-                            cell.backgroundColor = NCBrandColor.sharedInstance.brandElement
-                            UIView.animate(withDuration: 1.0, animations: {
-                                cell.backgroundColor = .white
-                            })
-                        }
+                        let indexPath = IndexPath(item: item, section: 0)
+                        UIView.animate(withDuration: 0.5, animations: {
+                            self.collectionView.scrollToItem(at: indexPath, at: .top, animated: true)
+                        }, completion: { (finished) in
+                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
+                                NCUtility.sharedInstance.blink(cell: self.collectionView.cellForItem(at: indexPath))
+                            }
+                        })
+                        self.scrollToFileID = ""
                     }
                 }
-                self.scrollToFileID = ""
             }
-        }
+        }        
     }
     
     @objc func loadListingTrash() {
@@ -677,8 +676,6 @@ extension NCTrash {
             if errorCode == 0 && account == self.appDelegate.activeAccount {
                 NCManageDatabase.sharedInstance.deleteTrash(filePath: self.path, account: self.appDelegate.activeAccount)
                 NCManageDatabase.sharedInstance.addTrashs(item as! [tableTrash])
-            } else if errorCode == kOCErrorServerUnauthorized {
-                self.appDelegate.openLoginView(self, delegate: self.appDelegate.activeMain, loginType: Int(k_login_Modify_Password), selector: Int(k_intro_login))
             } else if errorCode != 0 {
                 self.appDelegate.messageNotification("_error_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
             } else {
@@ -709,9 +706,7 @@ extension NCTrash {
             if errorCode == 0 && account == self.appDelegate.activeAccount {
                 NCManageDatabase.sharedInstance.deleteTrash(fileID: fileID, account: account!)
                 self.loadDatasource()
-            } else if errorCode == kOCErrorServerUnauthorized {
-                self.appDelegate.openLoginView(self, delegate: self.appDelegate.activeMain, loginType: Int(k_login_Modify_Password), selector: Int(k_intro_login))
-            } else if errorCode != 0 {
+            }  else if errorCode != 0 {
                 self.appDelegate.messageNotification("_error_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
             } else {
                 print("[LOG] It has been changed user during networking process, error.")
@@ -724,8 +719,6 @@ extension NCTrash {
         OCNetworking.sharedManager().emptyTrash(withAccount: appDelegate.activeAccount, completion: { (account, message, errorCode) in
             if errorCode == 0 && account == self.appDelegate.activeAccount {
                 NCManageDatabase.sharedInstance.deleteTrash(fileID: nil, account: self.appDelegate.activeAccount)
-            } else if errorCode == kOCErrorServerUnauthorized {
-                self.appDelegate.openLoginView(self, delegate: self.appDelegate.activeMain, loginType: Int(k_login_Modify_Password), selector: Int(k_intro_login))
             } else if errorCode != 0 {
                 self.appDelegate.messageNotification("_error_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
             } else {

+ 6 - 1
iOSClient/Utility/CCUtility.h

@@ -146,6 +146,7 @@
 + (NSString *)getPushNotificationDeviceIdentifier:(NSString *)account;
 + (void)setPushNotificationDeviceIdentifierSignature:(NSString *)account deviceIdentifierSignature:(NSString *)deviceIdentifierSignature;
 + (NSString *)getPushNotificationDeviceIdentifierSignature:(NSString *)account;
++ (void)clearAllKeysPushNotification:(NSString *)account;
 
 + (NSInteger)getMediaWidthImage;
 + (void)setMediaWidthImage:(NSInteger)width;
@@ -161,6 +162,9 @@
 
 + (NSData *)getDatabaseEncryptionKey;
 
++ (BOOL)getCertificateError:(NSString *)account;
++ (void)setCertificateError:(NSString *)account error:(BOOL)error;
+
 // ===== Varius =====
 
 + (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL;
@@ -247,6 +251,7 @@
 + (NSDate *)datetimeWithOutDate:(NSDate *)datDate;
 + (BOOL)isValidEmail:(NSString *)checkString;
 + (NSString *)URLEncodeStringFromString:(NSString *)string;
-+ (NSString*)hexRepresentation:(NSData *)data spaces:(BOOL)spaces;
++ (NSString *)hexRepresentation:(NSData *)data spaces:(BOOL)spaces;
++ (NSString *)valueForKey:(NSString *)key fromQueryItems:(NSArray *)queryItems;
 
 @end

+ 38 - 0
iOSClient/Utility/CCUtility.m

@@ -551,6 +551,16 @@
     return [UICKeyChainStore stringForKey:key service:k_serviceShareKeyChain];
 }
 
++ (void)clearAllKeysPushNotification:(NSString *)account
+{
+    [self setPushNotificationPublicKey:account data:nil];
+    [self setPushNotificationSubscribingPublicKey:account publicKey:nil];
+    [self setPushNotificationPrivateKey:account data:nil];
+    [self setPushNotificationToken:account token:nil];
+    [self setPushNotificationDeviceIdentifier:account deviceIdentifier:nil];
+    [self setPushNotificationDeviceIdentifierSignature:account deviceIdentifierSignature:nil];
+}
+
 + (NSInteger)getMediaWidthImage
 {
     NSString *width = [UICKeyChainStore stringForKey:@"mediaWidthImage" service:k_serviceShareKeyChain];
@@ -619,6 +629,27 @@
     [UICKeyChainStore setData:data forKey:@"databaseEncryptionKey" service:k_serviceShareKeyChain];
 }
 
++ (BOOL)getCertificateError:(NSString *)account
+{
+    NSString *key = [@"certificateError" stringByAppendingString:account];
+    NSString *error = [UICKeyChainStore stringForKey:key service:k_serviceShareKeyChain];
+    
+    if (error == nil) {
+        
+        [self setCertificateError:account error:NO];
+        return  NO;
+    }
+    
+    return [error boolValue];
+}
+
++ (void)setCertificateError:(NSString *)account error:(BOOL)error
+{
+    NSString *key = [@"certificateError" stringByAppendingString:account];
+    NSString *sError = (error) ? @"true" : @"false";
+    
+    [UICKeyChainStore setString:sError forKey:key service:k_serviceShareKeyChain];
+}
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== Various =====
 #pragma --------------------------------------------------------------------------------------------
@@ -1582,4 +1613,11 @@
     return hex;
 }
 
++ (NSString *)valueForKey:(NSString *)key fromQueryItems:(NSArray *)queryItems
+{
+    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=%@", key];
+    NSURLQueryItem *queryItem = [[queryItems filteredArrayUsingPredicate:predicate] firstObject];
+    return queryItem.value;
+}
+
 @end

+ 68 - 57
iOSClient/Utility/NCUtility.swift

@@ -190,68 +190,66 @@ class NCUtility: NSObject {
         
         if !FileManager.default.fileExists(atPath: imageNamePath) || rewrite == true {
             
-            guard let imageData = try? Data(contentsOf:iconURL) else {
-                return closure(nil)
-            }
-            
-            if let image = UIImage.init(data: imageData) {
-                
-                var newImage: UIImage = image
-                
-                if width != nil {
-                    
-                    let ratio = image.size.height / image.size.width
-                    let newSize = CGSize(width: width!, height: width! * ratio)
-                    
-                    let renderFormat = UIGraphicsImageRendererFormat.default()
-                    renderFormat.opaque = false
-                    let renderer = UIGraphicsImageRenderer(size: CGSize(width: newSize.width, height: newSize.height), format: renderFormat)
-                    newImage = renderer.image {
-                        (context) in
-                        image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
-                    }
-                }
-                
-                guard let pngImageData = newImage.pngData() else {
-                    return closure(nil)
-                }
+            OCNetworking.sharedManager()?.downloadContents(ofUrl: iconURL.absoluteString, completion: { (data, message, errorCode) in
                 
-                CCUtility.write(pngImageData, fileNamePath: imageNamePath)
+                if errorCode == 0 && data != nil {
                 
-            } else {
-                
-                let task = URLSession(configuration: .default).dataTask(with: iconURL) { (data, response, error) in
-                    guard error == nil,  response != nil, data != nil else {
-                        return closure(nil)
-                    }
-                    
-                    guard let svgImage: SVGKImage = SVGKImage(data: data) else {
-                        return closure(nil)
-                    }
-                    
-                    if width != nil {
-                        let scale = svgImage.size.height / svgImage.size.width
-                        svgImage.size = CGSize(width: width!, height: width! * scale)
-                    }
-                    
-                    guard let image: UIImage = svgImage.uiImage else {
-                        return closure(nil)
-                    }
-                    guard let pngImageData = image.pngData() else {
-                        return closure(nil)
-                    }
-                    
-                    CCUtility.write(pngImageData, fileNamePath: imageNamePath)
-                    
-                    DispatchQueue.main.async {
+                    if let image = UIImage.init(data: data!) {
+                        
+                        var newImage: UIImage = image
+                        
+                        if width != nil {
+                            
+                            let ratio = image.size.height / image.size.width
+                            let newSize = CGSize(width: width!, height: width! * ratio)
+                            
+                            let renderFormat = UIGraphicsImageRendererFormat.default()
+                            renderFormat.opaque = false
+                            let renderer = UIGraphicsImageRenderer(size: CGSize(width: newSize.width, height: newSize.height), format: renderFormat)
+                            newImage = renderer.image {
+                                (context) in
+                                image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
+                            }
+                        }
+                        
+                        guard let pngImageData = newImage.pngData() else {
+                            return closure(nil)
+                        }
+                        
+                        CCUtility.write(pngImageData, fileNamePath: imageNamePath)
+                        
+                        return closure(imageNamePath)
+                        
+                    } else {
+                        
+                        guard let svgImage: SVGKImage = SVGKImage(data: data) else {
+                            return closure(nil)
+                        }
+                            
+                        if width != nil {
+                            let scale = svgImage.size.height / svgImage.size.width
+                            svgImage.size = CGSize(width: width!, height: width! * scale)
+                        }
+                            
+                        guard let image: UIImage = svgImage.uiImage else {
+                            return closure(nil)
+                        }
+                        guard let pngImageData = image.pngData() else {
+                            return closure(nil)
+                        }
+                            
+                        CCUtility.write(pngImageData, fileNamePath: imageNamePath)
+                            
                         return closure(imageNamePath)
                     }
+                } else {
+                    return closure(nil)
                 }
-                task.resume()
-            }
+            })
+            
+        } else {
+            return closure(imageNamePath)
         }
-        
-        return closure(imageNamePath)
     }
     
     @objc func startActivityIndicator(view: UIView, bottom: CGFloat) {
@@ -311,6 +309,19 @@ class NCUtility: NSObject {
         let hour = Int(seconds / 3600)
         return String(format: "%02d:%02d:%02d", hour, min, sec)
     }
-
+    
+    @objc func blink(cell: AnyObject?) {
+        if let cell = cell as? UITableViewCell {
+            cell.backgroundColor = NCBrandColor.sharedInstance.brand.withAlphaComponent(0.3)
+            UIView.animate(withDuration: 2) {
+                cell.backgroundColor = .clear
+            }
+        } else if let cell = cell as? UICollectionViewCell {
+            cell.backgroundColor = NCBrandColor.sharedInstance.brand.withAlphaComponent(0.3)
+            UIView.animate(withDuration: 2) {
+                cell.backgroundColor = .clear
+            }
+        }
+    }
 }
 

+ 2 - 2
iOSClient/Viewer/NCViewerImagemeter.swift

@@ -87,7 +87,7 @@ class NCViewerImagemeter: NSObject {
                 audioImagemeter()
                 
             } else {
-                appDelegate.messageNotification("_error_", description: "_error_decompressing_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: Int(k_CCErrorInternalError))
+                appDelegate.messageNotification("_error_", description: "_error_json_decoding_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: Int(k_CCErrorInternalError))
             }
             
         } catch {
@@ -124,7 +124,7 @@ class NCViewerImagemeter: NSObject {
                     continue
                 }
                 
-                let center = IMImagemeterCodable.sharedInstance.convertCoordinate(x: element.center.x, y: element.center.y, width: imagemeterView.bounds.width, height: imagemeterView.imageHeightConstraint.constant)
+                let center = IMImagemeterCodable.sharedInstance.convertCoordinate(x: element.center?.x ?? 0, y: element.center?.y ?? 0, width: imagemeterView.bounds.width, height: imagemeterView.imageHeightConstraint.constant)
                 
                 let button = UIButton()
                 button.frame = CGRect(x: center.x - dimButton/2, y: center.y - dimButton/2, width: dimButton, height: dimButton)

Some files were not shown because too many files changed in this diff