Browse Source

Merge pull request #1101 from Infomaniak/newdrawer

Menu displayed as drawer
Marino Faggiana 5 years ago
parent
commit
ce9b7b63f4

+ 1 - 0
Cartfile

@@ -17,6 +17,7 @@ github "WenchaoD/FSCalendar" "2.8.0"
 github "AssistoLab/DropDown" "v2.3.13"
 github "krzyzanowskim/OpenSSL" "1.0.218"
 github "huri000/SwiftEntryKit" "1.2.3"
+github "scenee/FloatingPanel"
 
 github "https://github.com/marinofaggiana/FastScroll" "master"
 github "https://github.com/marinofaggiana/AFNetworking" "master"

+ 1 - 0
Cartfile.resolved

@@ -20,6 +20,7 @@ github "marinofaggiana/FastScroll" "81967c2309d29bc2c330d422da612160a30bade8"
 github "nextcloud/ios-communication-library" "v0.5"
 github "realm/realm-cocoa" "v4.1.1"
 github "rechsteiner/Parchment" "v1.7.0"
+github "scenee/FloatingPanel" "v1.7.1"
 github "tilltue/TLPhotoPicker" "2.0.7"
 github "weichsel/ZIPFoundation" "0.9.10"
 github "yahoojapan/SwiftyXMLParser" "5.1.0"

+ 41 - 0
Nextcloud.xcodeproj/project.pbxproj

@@ -7,6 +7,14 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		3704EB2A23D5A58400455C5B /* Menu.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3704EB2923D5A58400455C5B /* Menu.storyboard */; };
+		371B5A2E23D0B04500FAFAE9 /* MainMenuTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371B5A2D23D0B04500FAFAE9 /* MainMenuTableViewController.swift */; };
+		371B5A3323D0BD5500FAFAE9 /* FloatingPanel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 371B5A3223D0BD5500FAFAE9 /* FloatingPanel.framework */; };
+		3757A35523D9D76300EC369E /* MenuPanelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3757A35423D9D76300EC369E /* MenuPanelController.swift */; };
+		3781B9B023DB2B7E006B4B1D /* AppDelegate+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3781B9AF23DB2B7E006B4B1D /* AppDelegate+Menu.swift */; };
+		3781B9B223DB2B9F006B4B1D /* CCMain+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3781B9B123DB2B9F006B4B1D /* CCMain+Menu.swift */; };
+		3781B9B423DB2BC9006B4B1D /* CCFavorites+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3781B9B323DB2BC9006B4B1D /* CCFavorites+Menu.swift */; };
+		37ECC83B23D0C7410082EFA2 /* MenuAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37ECC83A23D0C7400082EFA2 /* MenuAction.swift */; };
 		F700222C1EC479840080073F /* Custom.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F700222B1EC479840080073F /* Custom.xcassets */; };
 		F700222D1EC479840080073F /* Custom.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F700222B1EC479840080073F /* Custom.xcassets */; };
 		F70022B31EC4C9100080073F /* OCActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = F70022671EC4C9100080073F /* OCActivity.m */; };
@@ -663,6 +671,14 @@
 		08EA97451E6554FC004C83FA /* FirebaseCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = FirebaseCore.framework; sourceTree = "<group>"; };
 		08EA97461E6554FC004C83FA /* FirebaseInstanceID.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = FirebaseInstanceID.framework; sourceTree = "<group>"; };
 		08EA97471E6554FC004C83FA /* GoogleToolboxForMac.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = GoogleToolboxForMac.framework; sourceTree = "<group>"; };
+		3704EB2923D5A58400455C5B /* Menu.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Menu.storyboard; sourceTree = "<group>"; };
+		371B5A2D23D0B04500FAFAE9 /* MainMenuTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenuTableViewController.swift; sourceTree = "<group>"; };
+		371B5A3223D0BD5500FAFAE9 /* FloatingPanel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FloatingPanel.framework; path = Carthage/Build/iOS/FloatingPanel.framework; sourceTree = "<group>"; };
+		3757A35423D9D76300EC369E /* MenuPanelController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuPanelController.swift; sourceTree = "<group>"; };
+		3781B9AF23DB2B7E006B4B1D /* AppDelegate+Menu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+Menu.swift"; sourceTree = "<group>"; };
+		3781B9B123DB2B9F006B4B1D /* CCMain+Menu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CCMain+Menu.swift"; sourceTree = "<group>"; };
+		3781B9B323DB2BC9006B4B1D /* CCFavorites+Menu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CCFavorites+Menu.swift"; sourceTree = "<group>"; };
+		37ECC83A23D0C7400082EFA2 /* MenuAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuAction.swift; sourceTree = "<group>"; };
 		F700222B1EC479840080073F /* Custom.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Custom.xcassets; sourceTree = "<group>"; };
 		F70022661EC4C9100080073F /* OCActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCActivity.h; sourceTree = "<group>"; };
 		F70022671EC4C9100080073F /* OCActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCActivity.m; sourceTree = "<group>"; };
@@ -1490,6 +1506,7 @@
 				F7D4B68A2295663D000C2C86 /* FIRAnalyticsConnector.framework in Frameworks */,
 				F700510322DF6897003A3356 /* Parchment.framework in Frameworks */,
 				F7D4B6882295663D000C2C86 /* GoogleUtilities.framework in Frameworks */,
+				371B5A3323D0BD5500FAFAE9 /* FloatingPanel.framework in Frameworks */,
 				F70F2BA5225F2D8900EBB73E /* ZIPFoundation.framework in Frameworks */,
 				F7D4B6972295666E000C2C86 /* GoogleAPIClientForREST.framework in Frameworks */,
 			);
@@ -1498,6 +1515,20 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		371B5A2F23D0B04B00FAFAE9 /* Menu */ = {
+			isa = PBXGroup;
+			children = (
+				371B5A2D23D0B04500FAFAE9 /* MainMenuTableViewController.swift */,
+				3781B9B323DB2BC9006B4B1D /* CCFavorites+Menu.swift */,
+				3781B9B123DB2B9F006B4B1D /* CCMain+Menu.swift */,
+				3781B9AF23DB2B7E006B4B1D /* AppDelegate+Menu.swift */,
+				3757A35423D9D76300EC369E /* MenuPanelController.swift */,
+				37ECC83A23D0C7400082EFA2 /* MenuAction.swift */,
+				3704EB2923D5A58400455C5B /* Menu.storyboard */,
+			);
+			path = Menu;
+			sourceTree = "<group>";
+		};
 		F70022561EC4C9100080073F /* OCCommunicationLib */ = {
 			isa = PBXGroup;
 			children = (
@@ -1592,6 +1623,7 @@
 				F78ACD3E21903BA20088454D /* Cell */,
 				F7DFB7E9219C5A0500680748 /* Create cloud */,
 				F78ACD4D219043E70088454D /* Layout */,
+				371B5A2F23D0B04B00FAFAE9 /* Menu */,
 				F78ACD50219046AC0088454D /* Section */,
 				F7D0E65E1BC5042E008D989A /* CCDetail.h */,
 				F7D0E65F1BC5042E008D989A /* CCDetail.m */,
@@ -2847,6 +2879,7 @@
 		F7FC7D541DC1F93700BB2C6A /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				371B5A3223D0BD5500FAFAE9 /* FloatingPanel.framework */,
 				F765608A23BF80A400765969 /* SwiftEntryKit.framework */,
 				F765608623BF806C00765969 /* QuickLayout.framework */,
 				F716FE7723795E5000FABE50 /* NCCommunication.framework */,
@@ -3174,6 +3207,7 @@
 				F7D4233E1F0596AC009C9782 /* Reader-Email.png in Resources */,
 				F7D423361F0596AC009C9782 /* AppIcon-167.png in Resources */,
 				F7F54CF71E5B14C700E19C62 /* PlayButtonOverlayLargeTap.png in Resources */,
+				3704EB2A23D5A58400455C5B /* Menu.storyboard in Resources */,
 				F7E0E1DE22327DBA006B0911 /* NCAudioRecorderViewController.storyboard in Resources */,
 				F710E8111EF95C9C00DC2427 /* ImagesIntro.xcassets in Resources */,
 				F7F54D021E5B14C700E19C62 /* UIBarButtonItemGrid@3x.png in Resources */,
@@ -3310,6 +3344,7 @@
 				"$(SRCROOT)/Carthage/Build/iOS/SwiftyJSON.framework",
 				"$(SRCROOT)/Carthage/Build/iOS/QuickLayout.framework",
 				"$(SRCROOT)/Carthage/Build/iOS/SwiftEntryKit.framework",
+				"$(SRCROOT)/Carthage/Build/iOS/FloatingPanel.framework",
 			);
 			outputPaths = (
 			);
@@ -3494,6 +3529,7 @@
 				F754EECA21772B6100BB1CDF /* DropUpMenu.swift in Sources */,
 				F77B0E041D118A16002130FE /* UIImage+animatedGIF.m in Sources */,
 				F7D423881F0596C6009C9782 /* ReaderThumbView.m in Sources */,
+				37ECC83B23D0C7410082EFA2 /* MenuAction.swift in Sources */,
 				F73B4EFE1F470D9100BBEE4B /* LangHungarianModel.cpp in Sources */,
 				F7D4238A1F0596C6009C9782 /* ThumbsMainToolbar.m in Sources */,
 				F769454022E9F077000A798A /* NCSharePaging.swift in Sources */,
@@ -3518,6 +3554,7 @@
 				F762CB0C1EACB66200B38484 /* XLFormSectionDescriptor.m in Sources */,
 				F760F79421F21F61006B1A73 /* ResizeControl.swift in Sources */,
 				F7DFB7F2219C5C0000680748 /* NCCreateFormUploadFileText.swift in Sources */,
+				371B5A2E23D0B04500FAFAE9 /* MainMenuTableViewController.swift in Sources */,
 				F762CB861EACB81000B38484 /* RECommonFunctions.m in Sources */,
 				F76C6F8E21943C8C0063591B /* NCActionSheetHeader.swift in Sources */,
 				F760F79121F21F61006B1A73 /* EmojiCollectionViewCell.swift in Sources */,
@@ -3543,6 +3580,7 @@
 				F749C10C23C4A5340027D966 /* IntroViewController.swift in Sources */,
 				F77B0E1B1D118A16002130FE /* CCGraphics.m in Sources */,
 				F70022CB1EC4C9100080073F /* OCSharedDto.m in Sources */,
+				3757A35523D9D76300EC369E /* MenuPanelController.swift in Sources */,
 				F7CA1ED320E7E3FE002CC65E /* PKStopDownloadButton.m in Sources */,
 				F762CB111EACB66200B38484 /* NSString+XLFormAdditions.m in Sources */,
 				F7D423871F0596C6009C9782 /* ReaderThumbsView.m in Sources */,
@@ -3619,6 +3657,7 @@
 				F73CC07E1E813DFF006E3047 /* BKTouchIDSwitchView.m in Sources */,
 				F77B0E5F1D118A16002130FE /* CCSettings.m in Sources */,
 				F78F74362163781100C2ADAD /* NCTrash.swift in Sources */,
+				3781B9B223DB2B9F006B4B1D /* CCMain+Menu.swift in Sources */,
 				F7651A8B23A2A3F2001403D2 /* NCCreateFormUploadDocuments.swift in Sources */,
 				F7417DB3216CE925007D05F5 /* NCTrashSectionHeaderFooter.swift in Sources */,
 				F7F878AE1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */,
@@ -3626,6 +3665,7 @@
 				F762CB141EACB66200B38484 /* XLFormRightImageButton.m in Sources */,
 				F73D71621F2673C200E233EB /* NCText.swift in Sources */,
 				F73B4EF81F470D9100BBEE4B /* LangDanishModel.cpp in Sources */,
+				3781B9B023DB2B7E006B4B1D /* AppDelegate+Menu.swift in Sources */,
 				F73B4F051F470D9100BBEE4B /* nsCharSetProber.cpp in Sources */,
 				F77B0E671D118A16002130FE /* Reachability.m in Sources */,
 				F762CB121EACB66200B38484 /* UIView+XLFormAdditions.m in Sources */,
@@ -3692,6 +3732,7 @@
 				F79A65C62191D95E00FF6DCC /* NCSelect.swift in Sources */,
 				F7E0E1DC22327885006B0911 /* NCAudioRecorderViewController.swift in Sources */,
 				F70CAE3A1F8CF31A008125FD /* NCEndToEndEncryption.m in Sources */,
+				3781B9B423DB2BC9006B4B1D /* CCFavorites+Menu.swift in Sources */,
 				F7AE00F5230D5F9E007ACF8A /* NCLoginWeb.swift in Sources */,
 				F73B4F0C1F470D9100BBEE4B /* nsHebrewProber.cpp in Sources */,
 				F762CAFB1EACB66200B38484 /* XLFormDatePickerCell.m in Sources */,

+ 0 - 24
iOSClient/AppDelegate.h

@@ -83,30 +83,6 @@
 // Push Norification Token
 @property (nonatomic, strong) NSString *pushKitToken;
 
-// Remenu
-@property (nonatomic, strong) REMenu *reMainMenu;
-@property (nonatomic, strong) REMenuItem *selezionaItem;
-@property (nonatomic, strong) REMenuItem *sortFileNameAZItem;
-@property (nonatomic, strong) REMenuItem *sortFileNameZAItem;
-@property (nonatomic, strong) REMenuItem *sortDateMoreRecentItem;
-@property (nonatomic, strong) REMenuItem *sortDateLessRecentItem;
-@property (nonatomic, strong) REMenuItem *sortSmallestItem;
-@property (nonatomic, strong) REMenuItem *sortLargestItem;
-@property (nonatomic, strong) REMenuItem *alphabeticItem;
-@property (nonatomic, strong) REMenuItem *typefileItem;
-@property (nonatomic, strong) REMenuItem *dateItem;
-@property (nonatomic, strong) REMenuItem *directoryOnTopItem;
-@property (nonatomic, strong) REMenuItem *addFolderInfo;
-
-@property (nonatomic, strong) REMenu *reSelectMenu;
-@property (nonatomic, strong) REMenuItem *selectAllItem;
-@property (nonatomic, strong) REMenuItem *deleteItem;
-@property (nonatomic, strong) REMenuItem *moveItem;
-@property (nonatomic, strong) REMenuItem *encryptItem;
-@property (nonatomic, strong) REMenuItem *decryptItem;
-@property (nonatomic, strong) REMenuItem *downloadItem;
-@property (nonatomic, strong) REMenuItem *saveItem;
-
 // Reachability
 @property (nonatomic, strong) Reachability *reachability;
 @property BOOL lastReachability;

+ 3 - 4
iOSClient/AppDelegate.m

@@ -194,9 +194,7 @@ PKPushRegistry *pushRegistry;
     // Test Maintenance
     if (self.activeAccount.length == 0 || self.maintenanceMode)
         return;
-    
-    [_activeMain closeAllMenu];
-    
+        
     [self updateApplicationIconBadgeNumber];
 }
 
@@ -873,7 +871,8 @@ PKPushRegistry *pushRegistry;
     tableDirectory *tableDirectory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", self.activeAccount, self.activeMain.serverUrl]];
     
     if ([tableDirectory.permissions containsString:@"CK"]) {
-        (void)[[NCCreateMenuAdd alloc] initWithViewController:self.window.rootViewController view:[(UIButton *)sender superview]];
+        UIViewController *vc = _activeMain.splitViewController.viewControllers[0];
+        [self showMenuInViewController: vc];
     } else {
         [[NCContentPresenter shared] messageNotification:@"_warning_" description:@"_no_permission_add_file_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0];
     }

+ 3 - 0
iOSClient/Favorites/CCFavorites.h

@@ -50,4 +50,7 @@
 - (void)reloadDatasource:(NSString *)ocId action:(NSInteger)action;
 - (void)listingFavorites;
 
+- (void)actionDelete:(NSIndexPath *)indexPath;
+- (void)settingFavorite:(tableMetadata *)metadata favorite:(BOOL)favorite;
+
 @end

+ 2 - 77
iOSClient/Favorites/CCFavorites.m

@@ -426,85 +426,10 @@
 - (void)actionMore:(UITapGestureRecognizer *)gestureRecognizer
 {
     CGPoint touch = [gestureRecognizer locationInView:self.tableView];
-    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:touch];
-    UIImage *iconHeader;
-    
+    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:touch];    
     tableMetadata *metadata = [[NCMainCommon sharedInstance] getMetadataFromSectionDataSourceIndexPath:indexPath sectionDataSource:sectionDataSource];
     
-    AHKActionSheet *actionSheet = [[AHKActionSheet alloc] initWithView:self.tabBarController.view title:nil];
-    
-    actionSheet.animationDuration = 0.2;
-    
-    actionSheet.buttonHeight = 50.0;
-    actionSheet.cancelButtonHeight = 50.0f;
-    actionSheet.separatorHeight = 5.0f;
-    
-    actionSheet.automaticallyTintButtonImages = @(NO);
-    
-    actionSheet.encryptedButtonTextAttributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:16], NSForegroundColorAttributeName:NCBrandColor.sharedInstance.encrypted };
-    actionSheet.buttonTextAttributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:16], NSForegroundColorAttributeName:NCBrandColor.sharedInstance.textView };
-    actionSheet.cancelButtonTextAttributes = @{ NSFontAttributeName:[UIFont boldSystemFontOfSize:17], NSForegroundColorAttributeName:NCBrandColor.sharedInstance.textView };
-    actionSheet.disableButtonTextAttributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:16], NSForegroundColorAttributeName:NCBrandColor.sharedInstance.textView };
-    
-    actionSheet.separatorColor = NCBrandColor.sharedInstance.separator;
-    actionSheet.cancelButtonTitle = NSLocalizedString(@"_cancel_",nil);
-    actionSheet.cancelButtonBackgroudColor = NCBrandColor.sharedInstance.backgroundForm;
-    
-    // assegnamo l'immagine anteprima se esiste, altrimenti metti quella standars
-    if ([[NSFileManager defaultManager] fileExistsAtPath:[CCUtility getDirectoryProviderStorageIconOcId:metadata.ocId fileNameView:metadata.fileNameView]]) {
-        
-        iconHeader = [UIImage imageWithContentsOfFile:[CCUtility getDirectoryProviderStorageIconOcId:metadata.ocId fileNameView:metadata.fileNameView]];
-        
-    } else {
-        
-        if (metadata.directory)
-            iconHeader = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"folder"] multiplier:2 color:NCBrandColor.sharedInstance.icon];
-        else
-            iconHeader = [UIImage imageNamed:metadata.iconName];
-    }
-    
-    [actionSheet addButtonWithTitle: metadata.fileNameView image: iconHeader backgroundColor: NCBrandColor.sharedInstance.backgroundForm height: 50.0 type: AHKActionSheetButtonTypeDisabled handler: nil
-     ];
-    
-    // Favorite : ONLY root
-    if (_serverUrl == nil) {
-        [actionSheet addButtonWithTitle: NSLocalizedString(@"_remove_favorites_", nil)
-                                  image: [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"favorite"] multiplier:2 color:NCBrandColor.sharedInstance.yellowFavorite]
-                        backgroundColor: NCBrandColor.sharedInstance.backgroundForm
-                                 height: 50.0
-                                   type: AHKActionSheetButtonTypeDefault
-                                handler: ^(AHKActionSheet *as) {
-                                    [self settingFavorite:metadata favorite:NO];
-                                }];
-    }
-    
-    // Share
-    [actionSheet addButtonWithTitle:NSLocalizedString(@"_details_", nil) image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"details"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] backgroundColor:NCBrandColor.sharedInstance.backgroundForm height: 50.0 type:AHKActionSheetButtonTypeDefault handler:^(AHKActionSheet *as) {
-        
-        [[NCMainCommon sharedInstance] openShareWithViewController:self metadata:metadata indexPage:0];
-    }];
-    
-    // NO Directory
-    if (metadata.directory == NO && [NCBrandOptions sharedInstance].disable_openin_file == NO) {
-        
-        [actionSheet addButtonWithTitle:NSLocalizedString(@"_open_in_", nil) image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"openFile"] multiplier:2 color:NCBrandColor.sharedInstance.icon] backgroundColor:NCBrandColor.sharedInstance.backgroundForm height: 50.0 type:AHKActionSheetButtonTypeDefault handler:^(AHKActionSheet *as) {
-            [self.tableView setEditing:NO animated:YES];
-            
-            [[NCMainCommon sharedInstance] downloadOpenWithMetadata:metadata selector:selectorOpenIn];
-        }];
-    }
-    
-    // Delete
-    [actionSheet addButtonWithTitle:NSLocalizedString(@"_delete_", nil)
-                              image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"trash"] width:50 height:50 color:[UIColor redColor]]
-                    backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                             height:50.0
-                               type:AHKActionSheetButtonTypeDestructive
-                            handler:^(AHKActionSheet *as) {
-                                [self actionDelete:indexPath];
-                            }];
-    
-    [actionSheet show];
+    [self toggleMoreMenuWithViewController:self.tabBarController indexPath:indexPath metadata:metadata];
 }
 
 #pragma --------------------------------------------------------------------------------------------

+ 24 - 0
iOSClient/Images.xcassets/navigationMore.imageset/Contents.json

@@ -0,0 +1,24 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "more-round.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  },
+  "properties" : {
+    "template-rendering-intent" : "template"
+  }
+}

BIN
iOSClient/Images.xcassets/navigationMore.imageset/more-round.png


+ 24 - 0
iOSClient/Images.xcassets/navigationSort.imageset/Contents.json

@@ -0,0 +1,24 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "navigationSort.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  },
+  "properties" : {
+    "template-rendering-intent" : "template"
+  }
+}

BIN
iOSClient/Images.xcassets/navigationSort.imageset/navigationSort.png


+ 16 - 2
iOSClient/Main/CCMain.h

@@ -74,8 +74,6 @@
 
 - (void)copyFileToPasteboard:(tableMetadata *)metadata;
 
-- (void)closeAllMenu;
-
 - (void)setUINavigationBarDefault;
 
 - (void)readFolder:(NSString *)serverUrl;
@@ -92,5 +90,21 @@
 - (void)openImportDocumentPicker;
 - (void)createFolder;
 
+- (void)setTableViewHeader;
+
+//expose methods for swift
+- (void)didSelectAll;
+- (void)deleteFile;
+- (void)saveSelectedFiles;
+- (void)downloadSelectedFilesFolders;
+- (void)moveOpenWindow:(NSArray *)indexPaths;
+
+- (void)settingFavorite:(tableMetadata *)metadata favorite:(BOOL)favorite;
+- (void)minCharTextFieldDidChange:(UITextField *)sender;
+- (void)renameFile:(NSArray *)arguments;
+- (void)comandoLockPassword;
+- (void)actionDelete:(NSIndexPath *)indexPath;
+- (void)openinFile:(id)sender;
+
 @end
 

+ 26 - 785
iOSClient/Main/CCMain.m

@@ -264,8 +264,6 @@
 - (void)viewWillDisappear:(BOOL)animated
 {
     [super viewWillDisappear:animated];
-    
-    [self closeAllMenu];
 }
 
 - (void) viewDidLayoutSubviews
@@ -278,8 +276,6 @@
 {
     [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
 
-    [self closeAllMenu];
-
     [coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
         
         if (self.view.frame.size.width == ([[UIScreen mainScreen] bounds].size.width*([[UIScreen mainScreen] bounds].size.width<[[UIScreen mainScreen] bounds].size.height))+([[UIScreen mainScreen] bounds].size.height*([[UIScreen mainScreen] bounds].size.width>[[UIScreen mainScreen] bounds].size.height))) {
@@ -649,12 +645,15 @@
 
 - (void)setUINavigationBarDefault
 {
-    UIBarButtonItem *buttonMore, *buttonNotification;
+    UIBarButtonItem *buttonMore, *buttonNotification, *buttonSelect;
     
     // =
-    buttonMore = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"navigationControllerMenu"] style:UIBarButtonItemStylePlain target:self action:@selector(toggleReMainMenu)];
+    buttonMore = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"navigationSort"] style:UIBarButtonItemStylePlain target:self action:@selector(toggleReMainMenu)];
     buttonMore.enabled = true;
     
+    buttonSelect = [[UIBarButtonItem alloc] initWithImage:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"select"] width:50 height:50 color:NCBrandColor.sharedInstance.textView] style:UIBarButtonItemStylePlain target:self action:@selector(tableViewSelect)];
+    buttonSelect.enabled = true;
+    
     // <
     self.navigationController.navigationBar.hidden = NO;
     
@@ -667,16 +666,16 @@
     }
     
     if (buttonNotification)
-        self.navigationItem.rightBarButtonItems = [[NSArray alloc] initWithObjects:buttonMore, buttonNotification, nil];
+        self.navigationItem.rightBarButtonItems = [[NSArray alloc] initWithObjects:buttonMore, buttonSelect, buttonNotification, nil];
     else
-        self.navigationItem.rightBarButtonItems = [[NSArray alloc] initWithObjects:buttonMore, nil];
-
+        self.navigationItem.rightBarButtonItems = [[NSArray alloc] initWithObjects:buttonMore, buttonSelect, nil];
+    
     self.navigationItem.leftBarButtonItem = nil;
 }
 
 - (void)setUINavigationBarSelected
 {    
-    UIImage *icon = [UIImage imageNamed:@"navigationControllerMenu"];
+    UIImage *icon = [UIImage imageNamed:@"navigationMore"];
     UIBarButtonItem *buttonMore = [[UIBarButtonItem alloc] initWithImage:icon style:UIBarButtonItemStylePlain target:self action:@selector(toggleReSelectMenu)];
 
     UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"_cancel_", nil) style:UIBarButtonItemStylePlain target:self action:@selector(cancelSelect)];
@@ -687,18 +686,7 @@
 
 - (void)cancelSelect
 {
-    [self tableViewSelect:NO];
-    [appDelegate.reSelectMenu close];
-}
-
-- (void)closeAllMenu
-{
-    // close Menu
-    [appDelegate.reSelectMenu close];
-    [appDelegate.reMainMenu close];
-    
-    // Close Menu Logo
-    [CCMenuAccount dismissMenu];
+    [self tableViewSelect];
 }
 
 #pragma --------------------------------------------------------------------------------------------
@@ -926,7 +914,7 @@
         [[NCMainCommon sharedInstance] reloadDatasourceWithServerUrl:self.serverUrl ocId:nil action:k_action_NULL];
     });
     
-    [self tableViewSelect:NO];
+    [self tableViewSelect];
 }
 
 #pragma --------------------------------------------------------------------------------------------
@@ -1015,7 +1003,7 @@
         [_hud hideHud];
     });
     
-    [self tableViewSelect:NO];
+    [self tableViewSelect];
 }
 
 #pragma --------------------------------------------------------------------------------------------
@@ -1454,7 +1442,7 @@
     }];
     
     // End Select Table View
-    [self tableViewSelect:NO];
+    [self tableViewSelect];
 }
 
 #pragma --------------------------------------------------------------------------------------------
@@ -1616,7 +1604,7 @@
             [self presentViewController:alert animated:YES completion:nil];
             
             // End Select Table View
-            [self tableViewSelect:NO];
+            [self tableViewSelect];
             
             // reload Datasource
             [self readFileReloadFolder];
@@ -1655,7 +1643,7 @@
                         } else {
                             
                             // End Select Table View
-                            [self tableViewSelect:NO];
+                            [self tableViewSelect];
                             
                             // reload Datasource
                             if (self.searchController.isActive)
@@ -1669,7 +1657,7 @@
                         [[NCContentPresenter shared] messageNotification:@"_move_" description:message delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
                         
                         // End Select Table View
-                        [self tableViewSelect:NO];
+                        [self tableViewSelect];
                         
                         // reload Datasource
                         if (self.searchController.isActive)
@@ -2030,8 +2018,6 @@
 
 - (void)menuLogo:(UIGestureRecognizer *)theGestureRecognizer
 {
-    if (appDelegate.reSelectMenu.isOpen || appDelegate.reMainMenu.isOpen)
-        return;
     
     // Brand
     if ([NCBrandOptions sharedInstance].disable_multiaccount)
@@ -2149,361 +2135,14 @@
     [appDelegate openLoginView:self selector:k_intro_login openLoginWeb:false];
 }
 
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ==== ReMenu ====
-#pragma --------------------------------------------------------------------------------------------
-
-- (void)createReMenuBackgroundView:(REMenu *)menu
-{
-    CGFloat safeAreaBottom = 0;
-    CGFloat safeAreaTop = 0;
-    CGFloat statusBar = 0;
-    
-    if (@available(iOS 11, *)) {
-        safeAreaTop = [UIApplication sharedApplication].delegate.window.safeAreaInsets.top;
-        safeAreaBottom = [UIApplication sharedApplication].delegate.window.safeAreaInsets.bottom;
-    }
-    if ([UIApplication sharedApplication].isStatusBarHidden) {
-        statusBar = 13;
-    }
-    
-    CGFloat computeNavigationBarOffset = [menu computeNavigationBarOffset];
-    UIViewController *rootController = [[[[UIApplication sharedApplication]delegate] window] rootViewController];
-    CGRect globalPositionMenu = [menu.menuView convertRect:menu.menuView.bounds toView:rootController.view];
-
-    _reMenuBackgroundView.frame = CGRectMake(0, computeNavigationBarOffset, globalPositionMenu.size.width,  rootController.view.frame.size.height);
-
-    [UIView animateWithDuration:0.2 animations:^{
-
-        CGFloat minimum = safeAreaBottom + self.tabBarController.tabBar.frame.size.height;
-        CGFloat y =  rootController.view.frame.size.height - menu.menuView.frame.size.height - globalPositionMenu.origin.y + statusBar;
-        
-        if (y>minimum) {
-            
-            _reMenuBackgroundView.frame = CGRectMake(0, rootController.view.frame.size.height, globalPositionMenu.size.width, - y);
-            [self.tabBarController.view addSubview:_reMenuBackgroundView];
-        }
-    }];
-}
-
-- (void)createReMainMenu
-{
-    NSString *title;
-    //NSString *groupBy = [CCUtility getGroupBySettings];
-    NSString *sorted = [CCUtility getOrderSettings];
-    BOOL ascending = [CCUtility getAscendingSettings];
-    tableCapabilities *capabilities = [[NCManageDatabase sharedInstance] getCapabilitesWithAccount:appDelegate.activeAccount];
-    
-    // ITEM SELECT ----------------------------------------------------------------------------------------------------
-    
-    appDelegate.selezionaItem = [[REMenuItem alloc] initWithTitle:NSLocalizedString(@"_select_", nil)subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"selectLight"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        if ([sectionDataSource.allRecordsDataSource count] > 0) [self tableViewSelect:YES];
-    }];
-    
-    // ITEM ORDER ----------------------------------------------------------------------------------------------------
-
-    if ([sorted isEqualToString:@"fileName"] && ascending) { title = [NSString stringWithFormat:@"✓ %@", NSLocalizedString(@"_order_by_name_a_z_", nil)]; }
-    else title = NSLocalizedString(@"_order_by_name_a_z_", nil);
-    
-    appDelegate.sortFileNameAZItem = [[REMenuItem alloc] initWithTitle:title subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"sortFileNameAZ"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        [CCUtility setOrderSettings:@"fileName"];
-        [CCUtility setAscendingSettings:true];
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"clearDateReadDataSource" object:nil];
-    }];
-
-    if ([sorted isEqualToString:@"fileName"] && !ascending) { title = [NSString stringWithFormat:@"✓ %@", NSLocalizedString(@"_order_by_name_z_a_", nil)]; }
-    else title = NSLocalizedString(@"_order_by_name_z_a_", nil);
-    
-    appDelegate.sortFileNameZAItem = [[REMenuItem alloc] initWithTitle:title subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"sortFileNameZA"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        [CCUtility setOrderSettings:@"fileName"];
-        [CCUtility setAscendingSettings:false];
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"clearDateReadDataSource" object:nil];
-    }];
-    
-    if ([sorted isEqualToString:@"date"] && !ascending) { title = [NSString stringWithFormat:@"✓ %@", NSLocalizedString(@"_order_by_date_more_recent_", nil)]; }
-    else title = NSLocalizedString(@"_order_by_date_more_recent_", nil);
-    
-    appDelegate.sortDateMoreRecentItem = [[REMenuItem alloc] initWithTitle:title subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"sortDateMoreRecent"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        [CCUtility setOrderSettings:@"date"];
-        [CCUtility setAscendingSettings:false];
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"clearDateReadDataSource" object:nil];
-    }];
-    
-    if ([sorted isEqualToString:@"date"] && ascending) { title = [NSString stringWithFormat:@"✓ %@", NSLocalizedString(@"_order_by_date_less_recent_", nil)]; }
-    else title = NSLocalizedString(@"_order_by_date_less_recent_", nil);
-    
-    appDelegate.sortDateLessRecentItem = [[REMenuItem alloc] initWithTitle:title subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"sortDateLessRecent"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        [CCUtility setOrderSettings:@"date"];
-        [CCUtility setAscendingSettings:true];
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"clearDateReadDataSource" object:nil];
-    }];
-    
-    if ([sorted isEqualToString:@"size"] && ascending) { title = [NSString stringWithFormat:@"✓ %@", NSLocalizedString(@"_order_by_size_smallest_", nil)]; }
-    else title = NSLocalizedString(@"_order_by_size_smallest_", nil);
-    
-    appDelegate.sortSmallestItem = [[REMenuItem alloc] initWithTitle:title subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"sortSmallest"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        [CCUtility setOrderSettings:@"size"];
-        [CCUtility setAscendingSettings:true];
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"clearDateReadDataSource" object:nil];
-    }];
-    
-    if ([sorted isEqualToString:@"size"] && !ascending) { title = [NSString stringWithFormat:@"✓ %@", NSLocalizedString(@"_order_by_size_largest_", nil)]; }
-    else title = NSLocalizedString(@"_order_by_size_largest_", nil);
-    
-    appDelegate.sortLargestItem = [[REMenuItem alloc] initWithTitle:title subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"sortLargest"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        [CCUtility setOrderSettings:@"size"];
-        [CCUtility setAscendingSettings:false];
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"clearDateReadDataSource" object:nil];
-    }];
-    
-    
-    
-    /*
-    // ITEM GROUP ALPHABETIC -----------------------------------------------------------------------------------------------------
-    
-    if ([groupBy isEqualToString:@"alphabetic"])  { title = NSLocalizedString(@"_group_alphabetic_yes_", nil); }
-    else { title = NSLocalizedString(@"_group_alphabetic_no_", nil); }
-    
-    appDelegate.alphabeticItem = [[REMenuItem alloc] initWithTitle:title subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"MenuGroupByAlphabetic"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        if ([groupBy isEqualToString:@"alphabetic"]) [CCUtility setGroupBySettings:@"none"];
-        else [CCUtility setGroupBySettings:@"alphabetic"];
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"clearDateReadDataSource" object:nil];
-    }];
-    
-    // ITEM GROUP TYPEFILE -------------------------------------------------------------------------------------------------------
-    
-    if ([groupBy isEqualToString:@"typefile"])  { title = NSLocalizedString(@"_group_typefile_yes_", nil); }
-    else { title = NSLocalizedString(@"_group_typefile_no_", nil); }
-    
-    appDelegate.typefileItem = [[REMenuItem alloc] initWithTitle:title subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"MenuGroupByFile"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        if ([groupBy isEqualToString:@"typefile"]) [CCUtility setGroupBySettings:@"none"];
-        else [CCUtility setGroupBySettings:@"typefile"];
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"clearDateReadDataSource" object:nil];
-    }];
-   
-    // ITEM GROUP DATE -------------------------------------------------------------------------------------------------------
-    
-    if ([groupBy isEqualToString:@"date"])  { title = NSLocalizedString(@"_group_date_yes_", nil); }
-    else { title = NSLocalizedString(@"_group_date_no_", nil); }
-    
-    appDelegate.dateItem = [[REMenuItem alloc] initWithTitle:title   subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"MenuGroupByDate"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        if ([groupBy isEqualToString:@"date"]) [CCUtility setGroupBySettings:@"none"];
-        else [CCUtility setGroupBySettings:@"date"];
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"clearDateReadDataSource" object:nil];
-    }];
-    */
-    
-    // ITEM DIRECTORY ON TOP ------------------------------------------------------------------------------------------------
-    
-    if ([CCUtility getDirectoryOnTop])  { title = NSLocalizedString(@"_directory_on_top_yes_", nil); }
-    else { title = NSLocalizedString(@"_directory_on_top_no_", nil); }
-    
-    appDelegate.directoryOnTopItem = [[REMenuItem alloc] initWithTitle:title subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"foldersOnTop"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        if ([CCUtility getDirectoryOnTop]) [CCUtility setDirectoryOnTop:NO];
-        else [CCUtility setDirectoryOnTop:YES];
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"clearDateReadDataSource" object:nil];
-    }];
-    
-    // ITEM ADD FOLDER INFO -----------------------------------------------------------------------------------------------
-    
-    appDelegate.addFolderInfo = [[REMenuItem alloc] initWithTitle:NSLocalizedString(@"_add_folder_info_", nil) subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"addFolderInfo"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        [self createRichWorkspace];
-    }];
-                                 
-    // REMENU --------------------------------------------------------------------------------------------------------------
-
-    if (capabilities.versionMajor >= k_nextcloud_version_18_0 && self.richWorkspaceText.length == 0) {
-        appDelegate.reMainMenu = [[REMenu alloc] initWithItems:@[appDelegate.selezionaItem, appDelegate.sortFileNameAZItem, appDelegate.sortFileNameZAItem, appDelegate.sortDateMoreRecentItem, appDelegate.sortDateLessRecentItem, appDelegate.sortSmallestItem, appDelegate.sortLargestItem, appDelegate.directoryOnTopItem, appDelegate.addFolderInfo]];
-    } else {
-        appDelegate.reMainMenu = [[REMenu alloc] initWithItems:@[appDelegate.selezionaItem, appDelegate.sortFileNameAZItem, appDelegate.sortFileNameZAItem, appDelegate.sortDateMoreRecentItem, appDelegate.sortDateLessRecentItem, appDelegate.sortSmallestItem, appDelegate.sortLargestItem, appDelegate.directoryOnTopItem]];
-    }
-        
-    appDelegate.reMainMenu.itemHeight = 40;
-    
-    appDelegate.reMainMenu.imageOffset = CGSizeMake(5, -1);
-    
-    appDelegate.reMainMenu.separatorOffset = CGSizeMake(50.0, 0.0);
-    appDelegate.reMainMenu.imageOffset = CGSizeMake(0, 0);
-    appDelegate.reMainMenu.waitUntilAnimationIsComplete = NO;
-    
-    appDelegate.reMainMenu.separatorHeight = 0.5;
-    appDelegate.reMainMenu.separatorColor = NCBrandColor.sharedInstance.separator;
-    
-    appDelegate.reMainMenu.backgroundColor = NCBrandColor.sharedInstance.backgroundForm;
-    appDelegate.reMainMenu.textColor =  NCBrandColor.sharedInstance.textView;
-    appDelegate.reMainMenu.textAlignment = NSTextAlignmentLeft;
-    appDelegate.reMainMenu.textShadowColor = nil;
-    appDelegate.reMainMenu.textOffset = CGSizeMake(50, 0.0);
-    appDelegate.reMainMenu.font = [UIFont systemFontOfSize:14.0];
-    
-    appDelegate.reMainMenu.highlightedBackgroundColor =  NCBrandColor.sharedInstance.select;
-    appDelegate.reMainMenu.highlightedSeparatorColor = nil;
-    appDelegate.reMainMenu.highlightedTextColor = [UIColor blackColor];
-    appDelegate.reMainMenu.highlightedTextShadowColor = nil;
-    appDelegate.reMainMenu.highlightedTextShadowOffset = CGSizeMake(0, 0);
-    
-    appDelegate.reMainMenu.subtitleTextColor = [UIColor colorWithWhite:0.425 alpha:1];
-    appDelegate.reMainMenu.subtitleTextAlignment = NSTextAlignmentLeft;
-    appDelegate.reMainMenu.subtitleTextShadowColor = nil;
-    appDelegate.reMainMenu.subtitleTextShadowOffset = CGSizeMake(0, 0.0);
-    appDelegate.reMainMenu.subtitleTextOffset = CGSizeMake(50, 0.0);
-    appDelegate.reMainMenu.subtitleFont = [UIFont systemFontOfSize:12.0];
-    
-    appDelegate.reMainMenu.subtitleHighlightedTextColor = [UIColor lightGrayColor];
-    appDelegate.reMainMenu.subtitleHighlightedTextShadowColor = nil;
-    appDelegate.reMainMenu.subtitleHighlightedTextShadowOffset = CGSizeMake(0, 0);
-    
-    appDelegate.reMainMenu.borderWidth = 0;
-    appDelegate.reMainMenu.borderColor = NCBrandColor.sharedInstance.backgroundForm;
-    
-    appDelegate.reMainMenu.animationDuration = 0.2;
-    appDelegate.reMainMenu.closeAnimationDuration = 0.2;
-    
-    appDelegate.reMainMenu.bounce = NO;
-    
-    __weak typeof(self) weakSelf = self;
-    [appDelegate.reMainMenu setClosePreparationBlock:^{
-        
-        // Backgroun reMenu (Gesture)
-        [weakSelf.reMenuBackgroundView removeFromSuperview];
-        [weakSelf.reMenuBackgroundView removeGestureRecognizer:weakSelf.singleFingerTap];
-    }];
-}
-
 - (void)toggleReMainMenu
 {
-    if (appDelegate.reMainMenu.isOpen) {
-        
-        [appDelegate.reMainMenu close];
-        
-    } else {
-        
-        [self createReMainMenu];
-        [appDelegate.reMainMenu showFromNavigationController:self.navigationController];
-        
-        // Backgroun reMenu & (Gesture)
-        [self createReMenuBackgroundView:appDelegate.reMainMenu];
-        
-        _singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(toggleReMainMenu)];
-        [_reMenuBackgroundView addGestureRecognizer:_singleFingerTap];
-    }
-}
-
-- (void)createReSelectMenu
-{
-    // ITEM SELECT ALL --------------------------------------------------------------------------------------------------
-    
-    appDelegate.selectAllItem = [[REMenuItem alloc] initWithTitle:NSLocalizedString(@"_select_all_", nil) subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"selectFull"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        [self didSelectAll];
-    }];
-    
-    // ITEM MOVE --------------------------------------------------------------------------------------------------------
-    
-    appDelegate.moveItem = [[REMenuItem alloc] initWithTitle:NSLocalizedString(@"_move_selected_files_", nil) subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"move"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-            [self moveOpenWindow:[self.tableView indexPathsForSelectedRows]];
-    }];
-    
-    // ITEM DOWNLOAD ----------------------------------------------------------------------------------------------------
-    
-    appDelegate.downloadItem = [[REMenuItem alloc] initWithTitle:NSLocalizedString(@"_download_selected_files_folders_", nil) subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"downloadSelectedFiles"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-            [self downloadSelectedFilesFolders];
-    }];
-    
-    // ITEM SAVE IMAGE & VIDEO -------------------------------------------------------------------------------------------
-    
-    appDelegate.saveItem = [[REMenuItem alloc] initWithTitle:NSLocalizedString(@"_save_selected_files_", nil) subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"saveSelectedFiles"] multiplier:2 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-            [self saveSelectedFiles];
-    }];
-    
-    // ITEM DELETE ------------------------------------------------------------------------------------------------------
-    appDelegate.deleteItem = [[REMenuItem alloc] initWithTitle:NSLocalizedString(@"_delete_selected_files_", nil) subtitle:@"" image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"trash"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] highlightedImage:nil action:^(REMenuItem *item) {
-        [self deleteFile];
-    }];
-    
-    // E2EE
-    if (_metadataFolder.e2eEncrypted) {
-        if ([NCBrandOptions sharedInstance].disable_openin_file) {
-            appDelegate.reSelectMenu = [[REMenu alloc] initWithItems:@[appDelegate.selectAllItem, appDelegate.downloadItem, appDelegate.deleteItem]];
-        } else {
-            appDelegate.reSelectMenu = [[REMenu alloc] initWithItems:@[appDelegate.selectAllItem, appDelegate.downloadItem, appDelegate.saveItem, appDelegate.deleteItem]];
-        }
-    } else {
-        if ([NCBrandOptions sharedInstance].disable_openin_file) {
-            appDelegate.reSelectMenu = [[REMenu alloc] initWithItems:@[appDelegate.selectAllItem, appDelegate.moveItem, appDelegate.downloadItem, appDelegate.deleteItem]];
-        } else {
-            appDelegate.reSelectMenu = [[REMenu alloc] initWithItems:@[appDelegate.selectAllItem, appDelegate.moveItem, appDelegate.downloadItem, appDelegate.saveItem, appDelegate.deleteItem]];
-        }
-    }
-    
-    appDelegate.reSelectMenu.itemHeight = 50;
-
-    appDelegate.reSelectMenu.imageOffset = CGSizeMake(5, -1);
-    
-    appDelegate.reSelectMenu.separatorOffset = CGSizeMake(50.0, 0.0);
-    appDelegate.reSelectMenu.imageOffset = CGSizeMake(0, 0);
-    appDelegate.reSelectMenu.waitUntilAnimationIsComplete = NO;
-    
-    appDelegate.reSelectMenu.separatorHeight = 0.5;
-    appDelegate.reSelectMenu.separatorColor = NCBrandColor.sharedInstance.separator;
-    
-    appDelegate.reSelectMenu.backgroundColor = NCBrandColor.sharedInstance.backgroundForm;
-    appDelegate.reSelectMenu.textColor = NCBrandColor.sharedInstance.textView;
-    appDelegate.reSelectMenu.textAlignment = NSTextAlignmentLeft;
-    appDelegate.reSelectMenu.textShadowColor = nil;
-    appDelegate.reSelectMenu.textOffset = CGSizeMake(50, 0.0);
-    appDelegate.reSelectMenu.font = [UIFont systemFontOfSize:14.0];
-    
-    appDelegate.reSelectMenu.highlightedBackgroundColor = NCBrandColor.sharedInstance.select;
-    appDelegate.reSelectMenu.highlightedSeparatorColor = nil;
-    appDelegate.reSelectMenu.highlightedTextColor = [UIColor blackColor];
-    appDelegate.reSelectMenu.highlightedTextShadowColor = nil;
-    appDelegate.reSelectMenu.highlightedTextShadowOffset = CGSizeMake(0, 0);
-    
-    appDelegate.reSelectMenu.subtitleTextColor = [UIColor colorWithWhite:0.425 alpha:1.000];
-    appDelegate.reSelectMenu.subtitleTextAlignment = NSTextAlignmentLeft;
-    appDelegate.reSelectMenu.subtitleTextShadowColor = nil;
-    appDelegate.reSelectMenu.subtitleTextShadowOffset = CGSizeMake(0, 0.0);
-    appDelegate.reSelectMenu.subtitleTextOffset = CGSizeMake(50, 0.0);
-    appDelegate.reSelectMenu.subtitleFont = [UIFont systemFontOfSize:12.0];
-    
-    appDelegate.reSelectMenu.subtitleHighlightedTextColor = [UIColor lightGrayColor];
-    appDelegate.reSelectMenu.subtitleHighlightedTextShadowColor = nil;
-    appDelegate.reSelectMenu.subtitleHighlightedTextShadowOffset = CGSizeMake(0, 0);
-    
-    appDelegate.reMainMenu.borderWidth = 0;
-    appDelegate.reMainMenu.borderColor = NCBrandColor.sharedInstance.backgroundForm;
-    
-    appDelegate.reSelectMenu.closeAnimationDuration = 0.2;
-    appDelegate.reSelectMenu.animationDuration = 0.2;
-
-    appDelegate.reSelectMenu.bounce = NO;
-    
-    __weak typeof(self) weakSelf = self;
-    [appDelegate.reSelectMenu setClosePreparationBlock:^{
-        
-        // Backgroun reMenu (Gesture)
-        [weakSelf.reMenuBackgroundView removeFromSuperview];
-        [weakSelf.reMenuBackgroundView removeGestureRecognizer:weakSelf.singleFingerTap];
-    }];
+    [self toggleMenuWithViewController:self.navigationController];
 }
 
 - (void)toggleReSelectMenu
 {
-    if (appDelegate.reSelectMenu.isOpen) {
-        
-        [appDelegate.reSelectMenu close];
-        
-    } else {
-        
-        [self createReSelectMenu];
-        [appDelegate.reSelectMenu showFromNavigationController:self.navigationController];
-        
-        // Backgroun reMenu & (Gesture)
-        [self createReMenuBackgroundView:appDelegate.reSelectMenu];
-        
-        _singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(toggleReSelectMenu)];
-        [_reMenuBackgroundView addGestureRecognizer:_singleFingerTap];
-    }
+    [self toggleSelectMenuWithViewController:self.navigationController];
 }
 
 #pragma --------------------------------------------------------------------------------------------
@@ -2703,7 +2342,7 @@
         }
     }
     
-    [self tableViewSelect:NO];
+    [self tableViewSelect];
 }
 
 - (void)copyFileToPasteboard:(tableMetadata *)metadata
@@ -3021,405 +2660,7 @@
     
     self.metadata = [[NCMainCommon sharedInstance] getMetadataFromSectionDataSourceIndexPath:indexPath sectionDataSource:sectionDataSource];
     
-    NSString *titoloLock, *titleFavorite;
-    
-    if (self.metadata.favorite) {
-        titleFavorite = NSLocalizedString(@"_remove_favorites_", nil);
-    } else {
-        titleFavorite = NSLocalizedString(@"_add_favorites_", nil);
-    }
-    
-    if (self.metadata.directory) {
-        
-        // calcolo lockServerUrl
-        NSString *lockServerUrl = [CCUtility stringAppendServerUrl:self.metadata.serverUrl addFileName:self.metadata.fileName];
-        
-        tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, lockServerUrl]];
-        
-        if (directory.lock)
-            titoloLock = [NSString stringWithFormat:NSLocalizedString(@"_remove_passcode_", nil)];
-        else
-            titoloLock = [NSString stringWithFormat:NSLocalizedString(@"_protect_passcode_", nil)];
-    }
-    
-    // ******************************************* AHKActionSheet *******************************************
-    
-    AHKActionSheet *actionSheet = [[AHKActionSheet alloc] initWithView:self.tabBarController.view title:nil];
-    
-    actionSheet.animationDuration = 0.2;
-        
-    actionSheet.buttonHeight = 50.0;
-    actionSheet.cancelButtonHeight = 50.0f;
-    actionSheet.separatorHeight = 5.0f;
-    
-    actionSheet.automaticallyTintButtonImages = @(NO);
-    
-    actionSheet.encryptedButtonTextAttributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:16], NSForegroundColorAttributeName:NCBrandColor.sharedInstance.encrypted };
-    actionSheet.buttonTextAttributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:16], NSForegroundColorAttributeName:NCBrandColor.sharedInstance.textView };
-    actionSheet.cancelButtonTextAttributes = @{ NSFontAttributeName:[UIFont boldSystemFontOfSize:17], NSForegroundColorAttributeName:NCBrandColor.sharedInstance.textView };
-    actionSheet.disableButtonTextAttributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:16], NSForegroundColorAttributeName:NCBrandColor.sharedInstance.textView };
-    
-    actionSheet.separatorColor = NCBrandColor.sharedInstance.separator;
-    actionSheet.cancelButtonTitle = NSLocalizedString(@"_cancel_",nil);
-    actionSheet.cancelButtonBackgroudColor = NCBrandColor.sharedInstance.backgroundForm;
-    
-    // ******************************************* DIRECTORY *******************************************
-    
-    if (self.metadata.directory) {
-        
-        BOOL lockDirectory = NO;
-        BOOL isOffline = NO;
-        NSString *dirServerUrl = [CCUtility stringAppendServerUrl:self.metadata.serverUrl addFileName:self.metadata.fileName];
-        BOOL isFolderEncrypted = [CCUtility isFolderEncrypted:[NSString stringWithFormat:@"%@/%@", self.serverUrl, self.metadata.fileName] account:appDelegate.activeAccount];
-        
-        // Directory bloccata ?
-        tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, dirServerUrl]];
-        if (directory.lock && [[CCUtility getBlockCode] length] && appDelegate.sessionePasscodeLock == nil) lockDirectory = YES;
-        if (directory.offline) isOffline = YES;
-            
-        [actionSheet addButtonWithTitle:self.metadata.fileNameView
-                                  image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"folder"] multiplier:2 color:NCBrandColor.sharedInstance.brandElement]
-                        backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                 height:50.0
-                                   type:AHKActionSheetButtonTypeDisabled
-                                handler:nil
-        ];
-        
-        [actionSheet addButtonWithTitle: titleFavorite
-                                  image: [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"favorite"] multiplier:2 color:NCBrandColor.sharedInstance.yellowFavorite]
-                        backgroundColor: NCBrandColor.sharedInstance.backgroundForm
-                                 height: 50.0
-                                   type: AHKActionSheetButtonTypeDefault
-                                handler: ^(AHKActionSheet *as) {
-                                    if (self.metadata.favorite) [self settingFavorite:self.metadata favorite:NO];
-                                    else [self settingFavorite:self.metadata favorite:YES];
-                                }];
-        
-        if (!lockDirectory && !isFolderEncrypted) {
-            
-            [actionSheet addButtonWithTitle:NSLocalizedString(@"_details_", nil)
-                                      image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"details"] width:50 height:50 color:NCBrandColor.sharedInstance.icon]
-                            backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                     height:50.0
-                                       type:AHKActionSheetButtonTypeDefault
-                                    handler:^(AHKActionSheet *as) {
-                                        [[NCMainCommon sharedInstance] openShareWithViewController:self metadata:self.metadata indexPage:0];
-                                    }];
-        }
-        
-        if (!([self.metadata.fileName isEqualToString:_autoUploadFileName] == YES && [self.metadata.serverUrl isEqualToString:_autoUploadDirectory] == YES) && !lockDirectory && !self.metadata.e2eEncrypted) {
-            
-            [actionSheet addButtonWithTitle:NSLocalizedString(@"_rename_", nil)
-                                      image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"rename"] multiplier:2 color:NCBrandColor.sharedInstance.icon]
-                            backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                     height:50.0
-                                       type:AHKActionSheetButtonTypeDefault
-                                    handler:^(AHKActionSheet *as) {
-                                        
-                                        __weak __typeof(UIAlertController) *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_rename_",nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
-                                        
-                                        [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
-                                            textField.text = self.metadata.fileNameView;
-                                            textField.delegate = self;
-                                            [textField addTarget:self action:@selector(minCharTextFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
-                                        }];
-                                        
-                                        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_cancel_",nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
-                                            NSLog(@"[LOG] Cancel action");
-                                        }];
-                                        
-                                        UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
-                                            
-                                            UITextField *fileName = alertController.textFields.firstObject;
-                                            
-                                            [self performSelectorOnMainThread:@selector(renameFile:) withObject:[NSMutableArray arrayWithObjects:self.metadata,fileName.text, nil] waitUntilDone:NO];
-                                        }];
-                                        
-                                        okAction.enabled = NO;
-                                        
-                                        [alertController addAction:cancelAction];
-                                        [alertController addAction:okAction];
-                                        
-                                        [self presentViewController:alertController animated:YES completion:nil];
-                                    }];
-        }
-        
-        if (!([self.metadata.fileName isEqualToString:_autoUploadFileName] == YES && [self.metadata.serverUrl isEqualToString:_autoUploadDirectory] == YES) && !lockDirectory && !isFolderEncrypted) {
-            
-            [actionSheet addButtonWithTitle:NSLocalizedString(@"_move_", nil)
-                                      image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"move"] multiplier:2 color:NCBrandColor.sharedInstance.icon]
-                            backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                     height:50.0
-                                       type:AHKActionSheetButtonTypeDefault
-                                    handler:^(AHKActionSheet *as) {
-                                        [self moveOpenWindow:[[NSArray alloc] initWithObjects:indexPath, nil]];
-                                    }];
-        }
-        
-        if (!isFolderEncrypted) {
-            
-            NSString *title;
-            
-            if (isOffline) {
-                title = NSLocalizedString(@"_remove_available_offline_", nil);
-            } else {
-                title = NSLocalizedString(@"_set_available_offline_", nil);
-            }
-            
-            [actionSheet addButtonWithTitle:title
-                                      image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"offline"] multiplier:2 color:NCBrandColor.sharedInstance.icon]
-                            backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                     height:50.0
-                                       type:AHKActionSheetButtonTypeDefault
-                                    handler:^(AHKActionSheet *as) {
-                                        if (isOffline) {
-                                            [[NCManageDatabase sharedInstance] setDirectoryWithServerUrl:dirServerUrl offline:false account:appDelegate.activeAccount];
-                                            [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
-                                        } else {
-                                            [[NCManageDatabase sharedInstance] setDirectoryWithServerUrl:dirServerUrl offline:true account:appDelegate.activeAccount];
-                                            [[CCSynchronize sharedSynchronize] readFolder:dirServerUrl selector:selectorReadFolderWithDownload account:appDelegate.activeAccount];
-                                            [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
-                                        }
-                                    }];
-        }
-        
-    
-        [actionSheet addButtonWithTitle:titoloLock
-                                  image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"settingsPasscodeYES"] multiplier:2 color:NCBrandColor.sharedInstance.icon]
-                        backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                 height:50.0
-                                   type:AHKActionSheetButtonTypeDefault
-                                handler:^(AHKActionSheet *as) {
-                                    [self performSelector:@selector(comandoLockPassword) withObject:nil];
-                                }];
-        
-        if (!self.metadata.e2eEncrypted && [CCUtility isEndToEndEnabled:appDelegate.activeAccount]) {
-
-            [actionSheet addButtonWithTitle:NSLocalizedString(@"_e2e_set_folder_encrypted_", nil)
-                                      image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"lock"] width:50 height:50 color:NCBrandColor.sharedInstance.icon]
-                            backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                     height:50.0
-                                       type:AHKActionSheetButtonTypeDefault
-                                    handler:^(AHKActionSheet *as) {
-                                        
-                                        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
-                                            NSError *error = [[NCNetworkingEndToEnd sharedManager] markEndToEndFolderEncryptedOnServerUrl:[NSString stringWithFormat:@"%@/%@", self.serverUrl, self.metadata.fileName] ocId:self.metadata.ocId user:appDelegate.activeUser userID:appDelegate.activeUserID password:appDelegate.activePassword url:appDelegate.activeUrl];
-                                            dispatch_async(dispatch_get_main_queue(), ^{
-                                                if (error) {
-                                                    [[NCContentPresenter shared] messageNotification:@"_e2e_error_mark_folder_" description:error.localizedDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code];
-                                                } else {
-                                                    [[NCManageDatabase sharedInstance] deleteE2eEncryptionWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, [NSString stringWithFormat:@"%@/%@", self.serverUrl, self.metadata.fileName]]];
-                                                    [self readFolder:self.serverUrl];
-                                                }
-                                            });
-                                        });
-                                    }];
-        }
-        
-        if (self.metadata.e2eEncrypted && !_metadataFolder.e2eEncrypted && [CCUtility isEndToEndEnabled:appDelegate.activeAccount]) {
-            
-            [actionSheet addButtonWithTitle:NSLocalizedString(@"_e2e_remove_folder_encrypted_", nil)
-                                      image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"lock"] width:50 height:50 color:NCBrandColor.sharedInstance.icon]
-                            backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                     height:50.0
-                                       type:AHKActionSheetButtonTypeDefault
-                                    handler:^(AHKActionSheet *as) {
-                                        
-                                        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
-                                            NSError *error = [[NCNetworkingEndToEnd sharedManager] deletemarkEndToEndFolderEncryptedOnServerUrl:[NSString stringWithFormat:@"%@/%@", self.serverUrl, self.metadata.fileName] ocId:self.metadata.ocId user:appDelegate.activeUser userID:appDelegate.activeUserID password:appDelegate.activePassword url:appDelegate.activeUrl];
-                                            dispatch_async(dispatch_get_main_queue(), ^{
-                                                if (error) {
-                                                    [[NCContentPresenter shared] messageNotification:@"_e2e_error_delete_mark_folder_" description:error.localizedDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code];
-                                                } else {
-                                                    [[NCManageDatabase sharedInstance] deleteE2eEncryptionWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, [NSString stringWithFormat:@"%@/%@", self.serverUrl, self.metadata.fileName]]];
-                                                    [self readFolder:self.serverUrl];
-                                                }
-                                            });
-                                        });
-                                    }];
-        }
-        
-        
-        [actionSheet addButtonWithTitle:NSLocalizedString(@"_delete_", nil)
-                                  image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"trash"] width:50 height:50 color:[UIColor redColor]]
-                        backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                 height:50.0
-                                   type:AHKActionSheetButtonTypeDestructive
-                                handler:^(AHKActionSheet *as) {
-                                        [self actionDelete:indexPath];
-        }];
-        
-        [actionSheet show];
-    }
-    
-    // ******************************************* FILE *******************************************
-    
-    if (!self.metadata.directory) {
-        
-        UIImage *iconHeader;
-
-        // assegnamo l'immagine anteprima se esiste, altrimenti metti quella standars
-        if ([[NSFileManager defaultManager] fileExistsAtPath:[CCUtility getDirectoryProviderStorageIconOcId:self.metadata.ocId fileNameView:self.metadata.fileNameView]])
-            iconHeader = [UIImage imageWithContentsOfFile:[CCUtility getDirectoryProviderStorageIconOcId:self.metadata.ocId fileNameView:self.metadata.fileNameView]];
-        else
-            iconHeader = [UIImage imageNamed:self.metadata.iconName];
-        
-        [actionSheet addButtonWithTitle: self.metadata.fileNameView
-                                  image: iconHeader
-                        backgroundColor: NCBrandColor.sharedInstance.backgroundForm
-                                 height: 50.0
-                                   type: AHKActionSheetButtonTypeDisabled
-                                handler: nil
-        ];
-        
-        
-        [actionSheet addButtonWithTitle: titleFavorite
-                                  image: [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"favorite"] multiplier:2 color:NCBrandColor.sharedInstance.yellowFavorite]
-                        backgroundColor: NCBrandColor.sharedInstance.backgroundForm
-                                 height: 50.0
-                                   type: AHKActionSheetButtonTypeDefault
-                                handler: ^(AHKActionSheet *as) {
-                                    if (self.metadata.favorite) [self settingFavorite:self.metadata favorite:NO];
-                                    else [self settingFavorite:self.metadata favorite:YES];
-                                }];
-        
-        if (!_metadataFolder.e2eEncrypted) {
-
-            [actionSheet addButtonWithTitle:NSLocalizedString(@"_details_", nil)
-                                      image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"details"] width:50 height:50 color:NCBrandColor.sharedInstance.icon]
-                                backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                        height: 50.0
-                                        type:AHKActionSheetButtonTypeDefault
-                                        handler:^(AHKActionSheet *as) {
-                                            [[NCMainCommon sharedInstance] openShareWithViewController:self metadata:self.metadata indexPage:0];
-                                        }];
-        }
-        
-        if (![NCBrandOptions sharedInstance].disable_openin_file) {
-        
-            [actionSheet addButtonWithTitle:NSLocalizedString(@"_open_in_", nil)
-                                      image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"openFile"] multiplier:2 color:NCBrandColor.sharedInstance.icon]
-                            backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                     height: 50.0
-                                       type:AHKActionSheetButtonTypeDefault
-                                    handler:^(AHKActionSheet *as) {
-                                        [self performSelector:@selector(openinFile:) withObject:nil];
-                                    }];
-        }
-        
-        
-            
-        [actionSheet addButtonWithTitle:NSLocalizedString(@"_rename_", nil)
-                                  image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"rename"] multiplier:2 color:NCBrandColor.sharedInstance.icon]
-                        backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                 height: 50.0
-                                   type:AHKActionSheetButtonTypeDefault
-                                handler:^(AHKActionSheet *as) {
-                                    
-                                    __weak __typeof(UIAlertController) *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_rename_",nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
-                                    
-                                    [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
-                                        textField.text = self.metadata.fileNameView;
-                                        textField.delegate = self;
-                                        [textField addTarget:self action:@selector(minCharTextFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
-                                    }];
-                                    
-                                    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_cancel_",nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
-                                        NSLog(@"[LOG] Cancel action");
-                                    }];
-                                    
-                                    UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
-                                        UITextField *fileName = alertController.textFields.firstObject;
-                                        [self performSelectorOnMainThread:@selector(renameFile:) withObject:[NSMutableArray arrayWithObjects:self.metadata,fileName.text, nil] waitUntilDone:NO];
-                                    }];
-                                    
-                                    okAction.enabled = NO;
-                                    
-                                    [alertController addAction:cancelAction];
-                                    [alertController addAction:okAction];
-                                    
-                                    [self presentViewController:alertController animated:YES completion:nil];
-                                }];
-        
-        
-        if (!_metadataFolder.e2eEncrypted) {
-
-            [actionSheet addButtonWithTitle:NSLocalizedString(@"_move_", nil)
-                                      image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"move"] multiplier:2 color:NCBrandColor.sharedInstance.icon]
-                            backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                     height:50.0
-                                       type:AHKActionSheetButtonTypeDefault
-                                    handler:^(AHKActionSheet *as) {
-                                        [self moveOpenWindow:[[NSArray alloc] initWithObjects:indexPath, nil]];
-                                    }];
-        }
-        
-        if ([NCUtility.sharedInstance isEditImage:self.metadata.fileNameView] != nil && !_metadataFolder.e2eEncrypted && self.metadata.status == k_metadataStatusNormal) {
-            
-            [actionSheet addButtonWithTitle:NSLocalizedString(@"_modify_photo_", nil)
-                                      image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"modifyPhoto"] width:50 height:50 color:NCBrandColor.sharedInstance.icon]
-                            backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                     height:50.0
-                                       type:AHKActionSheetButtonTypeDefault
-                                    handler:^(AHKActionSheet *as) {
-                                        self.metadata.session = k_download_session;
-                                        self.metadata.sessionError = @"";
-                                        self.metadata.sessionSelector = selectorDownloadEditPhoto;
-                                        self.metadata.status = k_metadataStatusWaitDownload;
-                                        
-                                        (void)[[NCManageDatabase sharedInstance] addMetadata:self.metadata];
-                                        
-                                        [appDelegate startLoadAutoDownloadUpload];
-                                    }];
-        }
-        
-        if (!_metadataFolder.e2eEncrypted) {
-            
-            NSString *title;
-            tableLocalFile *localFile = [[NCManageDatabase sharedInstance] getTableLocalFileWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", self.metadata.ocId]];
-
-            if (localFile == nil || localFile.offline == false) { title = NSLocalizedString(@"_set_available_offline_", nil); }
-            else { title = NSLocalizedString(@"_remove_available_offline_", nil); }
-            
-            [actionSheet addButtonWithTitle:title
-                                      image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"offline"] multiplier:2 color:NCBrandColor.sharedInstance.icon]
-                            backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                     height:50.0
-                                       type:AHKActionSheetButtonTypeDefault
-                                    handler:^(AHKActionSheet *as) {
-                                        
-                                        if (localFile == nil || ![CCUtility fileProviderStorageExists:self.metadata.ocId fileNameView:self.metadata.fileNameView]) {
-                                            self.metadata.session = k_download_session;
-                                            self.metadata.sessionError = @"";
-                                            self.metadata.sessionSelector = selectorLoadOffline;
-                                            self.metadata.status = k_metadataStatusWaitDownload;
-                                            
-                                            // Add Metadata for Download
-                                            (void)[[NCManageDatabase sharedInstance] addMetadata:self.metadata];
-                                            [[NCMainCommon sharedInstance] reloadDatasourceWithServerUrl:self.serverUrl ocId:self.metadata.ocId action:k_action_MOD];
-                                            
-                                            [appDelegate startLoadAutoDownloadUpload];
-                                        } else if (localFile.offline == false) {
-                                            [[NCManageDatabase sharedInstance] setLocalFileWithOcId:self.metadata.ocId offline:true];
-                                            [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
-                                        } else {
-                                            [[NCManageDatabase sharedInstance] setLocalFileWithOcId:self.metadata.ocId offline:false];
-                                            [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
-                                        }
-                                    }];
-        }
-        
-        [actionSheet addButtonWithTitle:NSLocalizedString(@"_delete_", nil)
-                                  image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"trash"] width:50 height:50 color:[UIColor redColor]]
-                        backgroundColor:NCBrandColor.sharedInstance.backgroundForm
-                                 height:50.0
-                                   type:AHKActionSheetButtonTypeDestructive
-                                handler:^(AHKActionSheet *as) {
-                                    [self actionDelete:indexPath];
-                                }];
-        
-        [actionSheet show];
-    }
+    [self toggleMoreMenuWithViewController:self.tabBarController indexPath:indexPath metadata:self.metadata metadataFolder:_metadataFolder];
 }
 
 #pragma --------------------------------------------------------------------------------------------
@@ -3608,17 +2849,17 @@
 #pragma mark - ==== Table ==== 
 #pragma --------------------------------------------------------------------------------------------
 
-- (void)tableViewSelect:(BOOL)edit
+- (void)tableViewSelect
 {
+    _isSelectedMode = !_isSelectedMode;
     // chiudiamo eventuali swipe aperti
-    if (edit)
+    if (_isSelectedMode)
         [self.tableView setEditing:NO animated:NO];
     
-    [self.tableView setAllowsMultipleSelectionDuringEditing:edit];
-    [self.tableView setEditing:edit animated:YES];
-    _isSelectedMode = edit;
+    [self.tableView setAllowsMultipleSelectionDuringEditing:_isSelectedMode];
+    [self.tableView setEditing:_isSelectedMode animated:YES];
     
-    if (edit)
+    if (_isSelectedMode)
         [self setUINavigationBarSelected];
     else
         [self setUINavigationBarDefault];

+ 2 - 2
iOSClient/Main/Main.storyboard

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="4IE-mo-rkp">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="4IE-mo-rkp">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment version="4352" identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>

+ 140 - 0
iOSClient/Main/Menu/AppDelegate+Menu.swift

@@ -0,0 +1,140 @@
+//
+//  AppDelegate+Menu.swift
+//  Nextcloud
+//
+//  Created by Philippe Weidmann on 24.01.20.
+//  Copyright © 2020 TWS. All rights reserved.
+//
+
+import FloatingPanel
+
+extension AppDelegate {
+
+    private func initMenu() -> [MenuAction] {
+        var actions = [MenuAction]()
+        let appDelegate = UIApplication.shared.delegate as! AppDelegate
+        var isNextcloudTextAvailable = false
+
+        if appDelegate.reachability.isReachable() && NCBrandBeta.shared.directEditing && NCManageDatabase.sharedInstance.getDirectEditingCreators(account: appDelegate.activeAccount) != nil {
+            isNextcloudTextAvailable = true
+        }
+
+        actions.append(MenuAction(title: NSLocalizedString("_upload_photos_videos_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "file_photo"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                appDelegate.activeMain.openAssetsPickerController()
+            }))
+
+        actions.append(MenuAction(title: NSLocalizedString("_upload_file_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "file"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+            action: { menuAction in
+                appDelegate.activeMain.openImportDocumentPicker()
+            }))
+
+        if NCBrandOptions.sharedInstance.use_imi_viewer {
+            actions.append(MenuAction(title: NSLocalizedString("_im_create_new_file", tableName: "IMLocalizable", bundle: Bundle.main, value: "", comment: ""), icon: CCGraphics.scale(UIImage.init(named: "imagemeter"), to: CGSize(width: 25, height: 25), isAspectRation: true), action: { menuAction in
+                    _ = IMCreate.init(serverUrl: appDelegate.activeMain.serverUrl)
+                }))
+        }
+
+        if isNextcloudTextAvailable {
+            actions.append(MenuAction(title: NSLocalizedString("_create_nextcloudtext_document_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "file_txt"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                    guard let navigationController = UIStoryboard(name: "NCCreateFormUploadDocuments", bundle: nil).instantiateInitialViewController() else {
+                        return
+                    }
+                    navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
+
+                    let viewController = (navigationController as! UINavigationController).topViewController as! NCCreateFormUploadDocuments
+                    viewController.typeTemplate = k_nextcloudtext_document
+                    viewController.serverUrl = appDelegate.activeMain.serverUrl
+                    viewController.titleForm = NSLocalizedString("_create_nextcloudtext_document_", comment: "")
+
+                    appDelegate.window.rootViewController?.present(navigationController, animated: true, completion: nil)
+                }))
+        } else {
+            actions.append(MenuAction(title: NSLocalizedString("_upload_file_text_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "file_txt"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                    let storyboard = UIStoryboard(name: "NCText", bundle: nil)
+                    let controller = storyboard.instantiateViewController(withIdentifier: "NCText")
+                    controller.modalPresentationStyle = UIModalPresentationStyle.pageSheet
+                    appDelegate.activeMain.present(controller, animated: true, completion: nil)
+                }))
+        }
+
+        #if !targetEnvironment(simulator)
+            if #available(iOS 11.0, *) {
+                actions.append(MenuAction(title: NSLocalizedString("_scans_document_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "scan"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon)), action: { menuAction in
+                        if #available(iOS 11.0, *) {
+                            NCCreateScanDocument.sharedInstance.openScannerDocument(viewController: appDelegate.activeMain)
+                        }
+                    })
+            }
+        #endif
+
+        actions.append(MenuAction(title: NSLocalizedString("_create_voice_memo_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "microphone"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                NCMainCommon.sharedInstance.startAudioRecorder()
+            }))
+
+        actions.append(MenuAction(title: NSLocalizedString("_create_folder_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "folder"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                appDelegate.activeMain.createFolder()
+            }))
+
+        if let richdocumentsMimetypes = NCManageDatabase.sharedInstance.getRichdocumentsMimetypes(account: appDelegate.activeAccount) {
+            if richdocumentsMimetypes.count > 0 {
+                actions.append(MenuAction(title: NSLocalizedString("_create_new_document_", comment: ""), icon: UIImage.init(named: "create_file_document")!,
+                    action: { menuAction in
+                        guard let navigationController = UIStoryboard(name: "NCCreateFormUploadDocuments", bundle: nil).instantiateInitialViewController() else {
+                            return
+                        }
+                        navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
+
+                        let viewController = (navigationController as! UINavigationController).topViewController as! NCCreateFormUploadDocuments
+                        viewController.typeTemplate = k_richdocument_document
+                        viewController.serverUrl = appDelegate.activeMain.serverUrl
+                        viewController.titleForm = NSLocalizedString("_create_new_document_", comment: "")
+
+                        appDelegate.window.rootViewController?.present(navigationController, animated: true, completion: nil)
+                    }))
+                actions.append(MenuAction(title: NSLocalizedString("_create_new_spreadsheet_", comment: ""), icon: UIImage(named: "create_file_xls")!,
+                    action: { menuAction in
+                        guard let navigationController = UIStoryboard(name: "NCCreateFormUploadDocuments", bundle: nil).instantiateInitialViewController() else {
+                            return
+                        }
+                        navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
+
+                        let viewController = (navigationController as! UINavigationController).topViewController as! NCCreateFormUploadDocuments
+                        viewController.typeTemplate = k_richdocument_spreadsheet
+                        viewController.serverUrl = appDelegate.activeMain.serverUrl
+                        viewController.titleForm = NSLocalizedString("_create_new_spreadsheet_", comment: "")
+
+                        appDelegate.window.rootViewController?.present(navigationController, animated: true, completion: nil)
+                    }))
+                actions.append(MenuAction(title: NSLocalizedString("_create_new_presentation_", comment: ""), icon: UIImage(named: "create_file_ppt")!,
+                    action: { menuAction in
+                        guard let navigationController = UIStoryboard(name: "NCCreateFormUploadDocuments", bundle: nil).instantiateInitialViewController() else {
+                            return
+                        }
+                        navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
+
+                        let viewController = (navigationController as! UINavigationController).topViewController as! NCCreateFormUploadDocuments
+                        viewController.typeTemplate = k_richdocument_presentation
+                        viewController.serverUrl = appDelegate.activeMain.serverUrl
+                        viewController.titleForm = NSLocalizedString("_create_new_presentation_", comment: "")
+
+                        appDelegate.window.rootViewController?.present(navigationController, animated: true, completion: nil)
+                    }))
+            }
+        }
+
+        return actions
+    }
+
+    @objc public func showMenuIn(viewController: UIViewController) {
+        let mainMenuViewController = UIStoryboard.init(name: "Menu", bundle: nil).instantiateViewController(withIdentifier: "MainMenuTableViewController") as! MainMenuTableViewController
+        mainMenuViewController.actions = self.initMenu()
+
+        let menuPanelController = MenuPanelController()
+        menuPanelController.panelWidth = Int(viewController.view.frame.width)
+        menuPanelController.delegate = mainMenuViewController
+        menuPanelController.set(contentViewController: mainMenuViewController)
+        menuPanelController.track(scrollView: mainMenuViewController.tableView)
+        
+        viewController.present(menuPanelController, animated: true, completion: nil)
+    }
+}

+ 67 - 0
iOSClient/Main/Menu/CCFavorites+Menu.swift

@@ -0,0 +1,67 @@
+//
+//  CCFavorites+Menu.swift
+//  Nextcloud
+//
+//  Created by Philippe Weidmann on 24.01.20.
+//  Copyright © 2020 TWS. All rights reserved.
+//
+
+import FloatingPanel
+
+extension CCFavorites {
+
+    private func initMoreMenu(indexPath: IndexPath, metadata: tableMetadata) -> [MenuAction] {
+        var actions = [MenuAction]()
+        
+        var iconHeader: UIImage!
+        if let icon = UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, fileNameView: metadata.fileNameView)) {
+            iconHeader = icon
+        } else {
+            if(metadata.directory){
+                iconHeader = CCGraphics.changeThemingColorImage(UIImage.init(named: "folder"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon)
+            } else {
+                iconHeader = UIImage(named: metadata.iconName)
+            }
+        }
+
+        actions.append(MenuAction(title: metadata.fileNameView, icon: iconHeader, action: { menuAction in
+        }))
+
+        if(self.serverUrl == nil) {
+            actions.append(MenuAction(title: NSLocalizedString("_remove_favorites_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "favorite"), width: 50, height: 50, color: NCBrandColor.sharedInstance.yellowFavorite), action: { menuAction in
+                self.settingFavorite(metadata, favorite: false)
+                }))
+        }
+
+        actions.append(MenuAction(title: NSLocalizedString("_details_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "details"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                NCMainCommon.sharedInstance.openShare(ViewController: self, metadata: metadata, indexPage: 0)
+            }))
+
+        if(!metadata.directory && !NCBrandOptions.sharedInstance.disable_openin_file) {
+            actions.append(MenuAction(title: NSLocalizedString("_open_in_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "openFile"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                    self.tableView.setEditing(false, animated: true)
+                    NCMainCommon.sharedInstance.downloadOpen(metadata: metadata, selector: selectorOpenIn)
+                }))
+        }
+
+        actions.append(MenuAction(title: NSLocalizedString("_delete_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "trash"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                self.actionDelete(indexPath)
+            }))
+
+        return actions
+    }
+
+    @objc func toggleMoreMenu(viewController: UIViewController, indexPath: IndexPath, metadata: tableMetadata) {
+        let mainMenuViewController = UIStoryboard.init(name: "Menu", bundle: nil).instantiateViewController(withIdentifier: "MainMenuTableViewController") as! MainMenuTableViewController
+        mainMenuViewController.actions = self.initMoreMenu(indexPath: indexPath, metadata: metadata)
+
+        let menuPanelController = MenuPanelController()
+        menuPanelController.panelWidth = Int(viewController.view.frame.width)
+        menuPanelController.delegate = mainMenuViewController
+        menuPanelController.set(contentViewController: mainMenuViewController)
+        menuPanelController.track(scrollView: mainMenuViewController.tableView)
+        
+        viewController.present(menuPanelController, animated: true, completion: nil)
+    }
+}
+

+ 381 - 0
iOSClient/Main/Menu/CCMain+Menu.swift

@@ -0,0 +1,381 @@
+//
+//  CCMain+Menu.swift
+//  Nextcloud
+//
+//  Created by Philippe Weidmann on 24.01.20.
+//  Copyright © 2020 TWS. All rights reserved.
+//
+
+import FloatingPanel
+
+extension CCMain {
+
+    private func initSortMenu() -> [MenuAction] {
+        var actions = [MenuAction]()
+
+        actions.append(MenuAction(
+            title: NSLocalizedString("_order_by_name_a_z_", comment: ""),
+            icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortFileNameAZ"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+            onTitle: NSLocalizedString("_order_by_name_z_a_", comment: ""),
+            onIcon: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortFileNameZA"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+            selected: CCUtility.getOrderSettings() == "fileName",
+            on: CCUtility.getAscendingSettings(),
+            action: { menuAction in
+                if(CCUtility.getOrderSettings() == "fileName" && CCUtility.getAscendingSettings()) {
+                    CCUtility.setAscendingSettings(!CCUtility.getAscendingSettings())
+                } else {
+                    CCUtility.setOrderSettings("fileName")
+                    CCUtility.setAscendingSettings(true)
+                }
+
+                NotificationCenter.default.post(name: Notification.Name.init(rawValue: "clearDateReadDataSource"), object: nil)
+            }))
+
+        actions.append(MenuAction(
+            title: NSLocalizedString("_order_by_date_more_recent_", comment: ""),
+            icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortDateMoreRecent"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+            onTitle: NSLocalizedString("_order_by_date_less_recent_", comment: ""),
+            onIcon: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortDateLessRecent"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+            selected: CCUtility.getOrderSettings() == "date",
+            on: CCUtility.getAscendingSettings(),
+            action: { menuAction in
+                if(CCUtility.getOrderSettings() == "date" && CCUtility.getAscendingSettings()) {
+                    CCUtility.setAscendingSettings(!CCUtility.getAscendingSettings())
+                } else {
+                    CCUtility.setOrderSettings("date")
+                    CCUtility.setAscendingSettings(true)
+                }
+
+                NotificationCenter.default.post(name: Notification.Name.init(rawValue: "clearDateReadDataSource"), object: nil)
+            }))
+
+        actions.append(MenuAction(
+            title: NSLocalizedString("_order_by_size_smallest_", comment: ""),
+            icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortSmallest"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+            onTitle: NSLocalizedString("_order_by_size_largest_", comment: ""),
+            onIcon: CCGraphics.changeThemingColorImage(UIImage.init(named: "sortLargest"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+            selected: CCUtility.getOrderSettings() == "size",
+            on: CCUtility.getAscendingSettings(),
+            action: { menuAction in
+                if(CCUtility.getOrderSettings() == "size" && CCUtility.getAscendingSettings()) {
+                    CCUtility.setAscendingSettings(!CCUtility.getAscendingSettings())
+                } else {
+                    CCUtility.setOrderSettings("size")
+                    CCUtility.setAscendingSettings(true)
+                }
+
+                NotificationCenter.default.post(name: Notification.Name.init(rawValue: "clearDateReadDataSource"), object: nil)
+            }))
+
+        actions.append(MenuAction(
+            title: NSLocalizedString("_directory_on_top_no_", comment: ""),
+            icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "foldersOnTop"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
+            selected: CCUtility.getDirectoryOnTop(),
+            on: CCUtility.getDirectoryOnTop(),
+            action: { menuAction in
+                CCUtility.setDirectoryOnTop(!CCUtility.getDirectoryOnTop())
+                NotificationCenter.default.post(name: Notification.Name.init(rawValue: "clearDateReadDataSource"), object: nil)
+            }))
+
+        return actions
+    }
+
+    @objc func toggleMenu(viewController: UIViewController) {
+        let mainMenuViewController = UIStoryboard.init(name: "Menu", bundle: nil).instantiateViewController(withIdentifier: "MainMenuTableViewController") as! MainMenuTableViewController
+        mainMenuViewController.actions = self.initSortMenu()
+
+        let menuPanelController = MenuPanelController()
+        menuPanelController.panelWidth = Int(viewController.view.frame.width)
+        menuPanelController.delegate = mainMenuViewController
+        menuPanelController.set(contentViewController: mainMenuViewController)
+        menuPanelController.track(scrollView: mainMenuViewController.tableView)
+        
+        viewController.present(menuPanelController, animated: true, completion: nil)
+    }
+
+    @objc func toggleSelectMenu(viewController: UIViewController) {
+        let mainMenuViewController = UIStoryboard.init(name: "Menu", bundle: nil).instantiateViewController(withIdentifier: "MainMenuTableViewController") as! MainMenuTableViewController
+        mainMenuViewController.actions = self.initSelectMenu()
+
+        let menuPanelController = MenuPanelController()
+        menuPanelController.panelWidth = Int(viewController.view.frame.width)
+        menuPanelController.delegate = mainMenuViewController
+        menuPanelController.set(contentViewController: mainMenuViewController)
+        menuPanelController.track(scrollView: mainMenuViewController.tableView)
+        
+        viewController.present(menuPanelController, animated: true, completion: nil)
+    }
+
+
+    private func initSelectMenu() -> [MenuAction] {
+        var actions = [MenuAction]()
+
+        actions.append(MenuAction(title: NSLocalizedString("_select_all_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "selectFull"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                self.didSelectAll()
+            }))
+
+        actions.append(MenuAction(title: NSLocalizedString("_move_selected_files_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "move"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                self.moveOpenWindow(self.tableView.indexPathsForSelectedRows)
+            }))
+
+        actions.append(MenuAction(title: NSLocalizedString("_download_selected_files_folders_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "downloadSelectedFiles"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                self.downloadSelectedFilesFolders()
+            }))
+
+        actions.append(MenuAction(title: NSLocalizedString("_save_selected_files_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "saveSelectedFiles"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                self.saveSelectedFiles()
+            }))
+
+        actions.append(MenuAction(title: NSLocalizedString("_delete_selected_files_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "trash"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                self.deleteFile()
+            }))
+
+        return actions
+    }
+
+    private func initMoreMenu(indexPath: IndexPath, metadata: tableMetadata, metadataFolder: tableMetadata) -> [MenuAction] {
+        let appDelegate = UIApplication.shared.delegate as! AppDelegate
+        let autoUploadFileName = NCManageDatabase.sharedInstance.getAccountAutoUploadFileName()
+        let autoUploadDirectory = NCManageDatabase.sharedInstance.getAccountAutoUploadDirectory(appDelegate.activeUrl)
+
+        var actions = [MenuAction]()
+
+        if (metadata.directory) {
+            var lockDirectory = false
+            var isOffline = false
+            let isFolderEncrypted = CCUtility.isFolderEncrypted("\(self.serverUrl ?? "")/\(metadata.fileName)", account: appDelegate.activeAccount)
+            var passcodeTitle = NSLocalizedString("_protect_passcode_", comment: "")
+
+
+            let dirServerUrl = CCUtility.stringAppendServerUrl(self.metadata.serverUrl, addFileName: metadata.fileName)!
+
+            if let directory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.activeAccount, dirServerUrl)) {
+                if (CCUtility.getBlockCode() != nil && appDelegate.sessionePasscodeLock == nil) {
+                    lockDirectory = true
+                }
+                if (directory.lock) {
+                    passcodeTitle = NSLocalizedString("_protect_passcode_", comment: "")
+                }
+
+                isOffline = directory.offline
+            }
+
+
+
+            actions.append(MenuAction(title: metadata.fileNameView, icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "folder"), width: 50, height: 50, color: NCBrandColor.sharedInstance.brandElement), action: { menuAction in
+                }))
+
+            actions.append(MenuAction(title: metadata.favorite ? NSLocalizedString("_remove_favorites_", comment: "") : NSLocalizedString("_add_favorites_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "favorite"), width: 50, height: 50, color: NCBrandColor.sharedInstance.yellowFavorite), action: { menuAction in
+                    self.settingFavorite(metadata, favorite: !metadata.favorite)
+                }))
+
+            if (!lockDirectory && !isFolderEncrypted) {
+                actions.append(MenuAction(title: NSLocalizedString("_details_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "details"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                        NCMainCommon.sharedInstance.openShare(ViewController: self, metadata: metadata, indexPage: 0)
+                    }))
+            }
+
+            if(!(metadata.fileName == autoUploadFileName && metadata.serverUrl == autoUploadDirectory) && !lockDirectory && !metadata.e2eEncrypted) {
+                actions.append(MenuAction(title: NSLocalizedString("_rename_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "rename"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                        let alertController = UIAlertController(title: NSLocalizedString("_rename_", comment: ""), message: nil, preferredStyle: .alert)
+
+                        alertController.addTextField { (textField) in
+                            textField.text = metadata.fileNameView
+                            textField.delegate = self as? UITextFieldDelegate
+                            textField.addTarget(self, action: #selector(self.minCharTextFieldDidChange(_:)
+                                ), for: UIControl.Event.editingChanged)
+                        }
+
+                        let cancelAction = UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .cancel, handler: nil)
+
+                        let okAction = UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { action in
+                                let fileName = alertController.textFields![0].text
+                                self.perform(#selector(self.renameFile(_:)), on: .main, with: [metadata, fileName!], waitUntilDone: false)
+
+                            })
+                        okAction.isEnabled = false
+                        alertController.addAction(cancelAction)
+                        alertController.addAction(okAction)
+
+                        self.present(alertController, animated: true, completion: nil)
+                    }))
+
+
+            }
+
+            if (!(metadata.fileName == autoUploadFileName && metadata.serverUrl == autoUploadDirectory) && !lockDirectory && !isFolderEncrypted) {
+                actions.append(MenuAction(title: NSLocalizedString("_move_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "move"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                        self.moveOpenWindow([indexPath])
+                    }))
+            }
+
+            if (!isFolderEncrypted) {
+                actions.append(MenuAction(title: isOffline ? NSLocalizedString("_remove_available_offline_", comment: "") : NSLocalizedString("_set_available_offline_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "offline"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                        NCManageDatabase.sharedInstance.setDirectory(serverUrl: dirServerUrl, offline: !isOffline, account: appDelegate.activeAccount)
+                        if(isOffline) {
+                            CCSynchronize.shared()?.readFolder(dirServerUrl, selector: selectorReadFolderWithDownload, account: appDelegate.activeAccount)
+                        }
+                        DispatchQueue.main.async {
+                            self.tableView.reloadRows(at: [indexPath], with: .none)
+                        }
+                    }))
+            }
+
+            actions.append(MenuAction(title: passcodeTitle, icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "settingsPasscodeYES"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                    self.perform(#selector(self.comandoLockPassword))
+                }))
+
+            if (!metadata.e2eEncrypted && CCUtility.isEnd(toEndEnabled: appDelegate.activeAccount)) {
+                actions.append(MenuAction(title: NSLocalizedString("_remove_available_offline_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "lock"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                        DispatchQueue.global(qos: .userInitiated).async {
+                            let error = NCNetworkingEndToEnd.sharedManager()?.markFolderEncrypted(onServerUrl: "\(self.serverUrl ?? "")/\(metadata.fileName)", ocId: metadata.ocId, user: appDelegate.activeUser, userID: appDelegate.activeUserID, password: appDelegate.activePassword, url: appDelegate.activeUrl)
+                            DispatchQueue.main.async {
+                                if(error != nil) {
+                                    NCContentPresenter.shared.messageNotification(NSLocalizedString("_e2e_error_mark_folder_", comment: ""), description: error?.localizedDescription, delay: TimeInterval(k_dismissAfterSecond), type: .error, errorCode: (error! as NSError).code)
+                                } else {
+                                    NCManageDatabase.sharedInstance.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.activeAccount, "\(self.serverUrl ?? "")/\(metadata.fileName)"))
+                                    self.readFolder(self.serverUrl)
+                                }
+                            }
+                        }
+                    }))
+            }
+
+            if (metadata.e2eEncrypted && !metadataFolder.e2eEncrypted && CCUtility.isEnd(toEndEnabled: appDelegate.activeAccount)) {
+                actions.append(MenuAction(title: NSLocalizedString("_e2e_remove_folder_encrypted_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "lock"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                        DispatchQueue.global(qos: .userInitiated).async {
+                            let error = NCNetworkingEndToEnd.sharedManager()?.deletemarkEndToEndFolderEncrypted(onServerUrl: "\(self.serverUrl ?? "")/\(metadata.fileName)", ocId: metadata.ocId, user: appDelegate.activeUser, userID: appDelegate.activeUserID, password: appDelegate.activePassword, url: appDelegate.activeUrl)
+                            DispatchQueue.main.async {
+                                if(error != nil) {
+                                    NCContentPresenter.shared.messageNotification(NSLocalizedString("_e2e_error_delete_mark_folder_", comment: ""), description: error?.localizedDescription, delay: TimeInterval(k_dismissAfterSecond), type: .error, errorCode: (error! as NSError).code)
+                                } else {
+                                    NCManageDatabase.sharedInstance.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.activeAccount, "\(self.serverUrl ?? "")/\(metadata.fileName)"))
+                                    self.readFolder(self.serverUrl)
+                                }
+                            }
+                        }
+                    }))
+            }
+
+
+        } else {
+            var iconHeader: UIImage!
+            if let icon = UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, fileNameView: metadata.fileNameView)) {
+                iconHeader = icon
+            } else {
+                iconHeader = UIImage(named: metadata.iconName)
+            }
+
+            actions.append(MenuAction(title: metadata.fileNameView, icon: iconHeader, action: { menuAction in
+
+            }))
+
+            actions.append(MenuAction(title: metadata.favorite ? NSLocalizedString("_remove_favorites_", comment: "") : NSLocalizedString("_add_favorites_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "favorite"), width: 50, height: 50, color: NCBrandColor.sharedInstance.yellowFavorite), action: { menuAction in
+                    self.settingFavorite(metadata, favorite: !metadata.favorite)
+                }))
+
+            if (!metadataFolder.e2eEncrypted) {
+                actions.append(MenuAction(title: NSLocalizedString("_details_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "details"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                        NCMainCommon.sharedInstance.openShare(ViewController: self, metadata: metadata, indexPage: 0)
+                    }))
+            }
+
+            if(!NCBrandOptions.sharedInstance.disable_openin_file) {
+                actions.append(MenuAction(title: NSLocalizedString("_open_in_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "openFile"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                        self.perform(#selector(self.openinFile(_:)))
+                    }))
+            }
+
+            actions.append(MenuAction(title: NSLocalizedString("_rename_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "rename"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                    let alertController = UIAlertController(title: NSLocalizedString("_rename_", comment: ""), message: nil, preferredStyle: .alert)
+
+                    alertController.addTextField { (textField) in
+                        textField.text = metadata.fileNameView
+                        textField.delegate = self as? UITextFieldDelegate
+                        textField.addTarget(self, action: #selector(self.minCharTextFieldDidChange(_:)
+                            ), for: UIControl.Event.editingChanged)
+                    }
+
+                    let cancelAction = UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .cancel, handler: nil)
+
+                    let okAction = UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { action in
+                            let fileName = alertController.textFields![0].text
+                            self.perform(#selector(self.renameFile(_:)), on: .main, with: [metadata, fileName!], waitUntilDone: false)
+
+                        })
+                    okAction.isEnabled = false
+                    alertController.addAction(cancelAction)
+                    alertController.addAction(okAction)
+
+                    self.present(alertController, animated: true, completion: nil)
+                }))
+
+            if (!metadataFolder.e2eEncrypted) {
+                actions.append(MenuAction(title: NSLocalizedString("_move_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "move"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                        self.moveOpenWindow([indexPath])
+                    }))
+            }
+
+            if(NCUtility.sharedInstance.isEditImage(metadata.fileNameView as NSString) != nil && !metadataFolder.e2eEncrypted && metadata.status == k_metadataStatusNormal) {
+                actions.append(MenuAction(title: NSLocalizedString("_modify_photo_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "modifyPhoto"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                        metadata.session = k_download_session
+                        metadata.sessionError = ""
+                        metadata.sessionSelector = selectorDownloadEditPhoto
+                        metadata.status = Int(k_metadataStatusWaitDownload)
+
+                        _ = NCManageDatabase.sharedInstance.addMetadata(metadata)
+                        appDelegate.startLoadAutoDownloadUpload()
+                    }))
+            }
+
+            if (!metadataFolder.e2eEncrypted) {
+                let localFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
+                var title: String!
+                if (localFile == nil || localFile!.offline == false) {
+                    title = NSLocalizedString("_set_available_offline_", comment: "")
+                } else {
+                    title = NSLocalizedString("_remove_available_offline_", comment: "");
+                }
+
+                actions.append(MenuAction(title: title, icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "offline"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon), action: { menuAction in
+                        if (localFile == nil || !CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView)) {
+                            metadata.session = k_download_session
+                            metadata.sessionError = ""
+                            metadata.sessionSelector = selectorLoadOffline
+                            metadata.status = Int(k_metadataStatusWaitDownload)
+
+                            _ = NCManageDatabase.sharedInstance.addMetadata(metadata)
+                            NCMainCommon.sharedInstance.reloadDatasource(ServerUrl: self.serverUrl, ocId: metadata.ocId, action: k_action_MOD)
+                            appDelegate.startLoadAutoDownloadUpload()
+                        } else {
+                            NCManageDatabase.sharedInstance.setLocalFile(ocId: metadata.ocId, offline: !localFile!.offline)
+                            DispatchQueue.main.async {
+                                self.tableView.reloadRows(at: [indexPath], with: .none)
+                            }
+                        }
+
+                    }))
+            }
+        }
+
+        actions.append(MenuAction(title: NSLocalizedString("_delete_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage.init(named: "trash"), width: 50, height: 50, color: .red), action: { menuAction in
+                self.actionDelete(indexPath)
+            }))
+
+        return actions
+    }
+
+    @objc func toggleMoreMenu(viewController: UIViewController, indexPath: IndexPath, metadata: tableMetadata, metadataFolder: tableMetadata) {
+        let mainMenuViewController = UIStoryboard.init(name: "Menu", bundle: nil).instantiateViewController(withIdentifier: "MainMenuTableViewController") as! MainMenuTableViewController
+        mainMenuViewController.actions = self.initMoreMenu(indexPath: indexPath, metadata: metadata, metadataFolder: metadataFolder)
+
+        let menuPanelController = MenuPanelController()
+        menuPanelController.panelWidth = Int(viewController.view.frame.width)
+        menuPanelController.delegate = mainMenuViewController
+        menuPanelController.set(contentViewController: mainMenuViewController)
+        menuPanelController.track(scrollView: mainMenuViewController.tableView)
+        
+        viewController.present(menuPanelController, animated: true, completion: nil)
+    }
+
+}

+ 111 - 0
iOSClient/Main/Menu/MainMenuTableViewController.swift

@@ -0,0 +1,111 @@
+//
+//  MainMenuTableViewController.swift
+//  Nextcloud
+//
+//  Created by Philippe Weidmann on 16.01.20.
+//  Copyright © 2020 TWS. All rights reserved.
+//
+
+import UIKit
+import FloatingPanel
+
+class MainMenuTableViewController: UITableViewController {
+
+    var actions = [MenuAction]()
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+    }
+
+    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        let menuAction = actions[indexPath.row]
+        self.dismiss(animated: true, completion: nil)
+        menuAction.action?(menuAction)
+    }
+
+    // MARK: - Table view data source
+
+    override func numberOfSections(in tableView: UITableView) -> Int {
+        return 1
+    }
+
+    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return actions.count
+    }
+
+    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        let cell = tableView.dequeueReusableCell(withIdentifier: "menuActionCell", for: indexPath)
+        cell.tintColor = NCBrandColor.sharedInstance.customer
+        let action = actions[indexPath.row]
+        let actionIconView = cell.viewWithTag(1) as! UIImageView
+        let actionNameLabel = cell.viewWithTag(2) as! UILabel
+
+        if (action.isOn) {
+            actionIconView.image = action.onIcon
+            actionNameLabel.text = action.onTitle
+        } else {
+            actionIconView.image = action.icon
+            actionNameLabel.text = action.title
+        }
+
+        cell.accessoryType = action.selectable && action.selected ? .checkmark : .none
+
+        return cell
+    }
+
+}
+extension MainMenuTableViewController: FloatingPanelControllerDelegate {
+
+    func floatingPanel(_ vc: FloatingPanelController, layoutFor newCollection: UITraitCollection) -> FloatingPanelLayout? {
+        return MainMenuFloatingPanelLayout(height: min(self.actions.count * 60, Int(self.view.frame.height) - 48))
+    }
+
+    func floatingPanel(_ vc: FloatingPanelController, behaviorFor newCollection: UITraitCollection) -> FloatingPanelBehavior? {
+        return MainMenuFloatingPanelBehavior()
+    }
+
+}
+
+class MainMenuFloatingPanelLayout: FloatingPanelLayout {
+
+    let height: CGFloat
+
+    init(height: Int) {
+        self.height = CGFloat(height)
+    }
+
+    var initialPosition: FloatingPanelPosition {
+        return .tip
+    }
+
+    var supportedPositions: Set<FloatingPanelPosition> {
+        return [.tip]
+    }
+
+    func insetFor(position: FloatingPanelPosition) -> CGFloat? {
+        switch position {
+        case .tip: return height
+        default: return nil
+        }
+    }
+
+    func backdropAlphaFor(position: FloatingPanelPosition) -> CGFloat {
+        return 0.2
+    }
+}
+
+public class MainMenuFloatingPanelBehavior: FloatingPanelBehavior {
+
+    public func addAnimator(_ fpc: FloatingPanelController, to: FloatingPanelPosition) -> UIViewPropertyAnimator {
+        return UIViewPropertyAnimator(duration: 0.3, curve: .easeInOut)
+    }
+
+    public func removeAnimator(_ fpc: FloatingPanelController, from: FloatingPanelPosition) -> UIViewPropertyAnimator {
+        return UIViewPropertyAnimator(duration: 0.1, curve: .easeInOut)
+    }
+
+    public func moveAnimator(_ fpc: FloatingPanelController, from: FloatingPanelPosition, to: FloatingPanelPosition) -> UIViewPropertyAnimator {
+        return UIViewPropertyAnimator(duration: 0.1, curve: .easeInOut)
+    }
+
+}

+ 61 - 0
iOSClient/Main/Menu/Menu.storyboard

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <!--Main Menu Table View Controller-->
+        <scene sceneID="ibU-BJ-tlj">
+            <objects>
+                <tableViewController storyboardIdentifier="MainMenuTableViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="dbT-V0-aXb" customClass="MainMenuTableViewController" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController">
+                    <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" bounces="NO" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="60" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="pvY-CD-sI6">
+                        <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+                        <prototypes>
+                            <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="menuActionCell" rowHeight="60" id="MT1-Lu-9SA">
+                                <rect key="frame" x="0.0" y="28" width="414" height="60"/>
+                                <autoresizingMask key="autoresizingMask"/>
+                                <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="MT1-Lu-9SA" id="tmT-MO-Dwy">
+                                    <rect key="frame" x="0.0" y="0.0" width="414" height="60"/>
+                                    <autoresizingMask key="autoresizingMask"/>
+                                    <subviews>
+                                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="RV0-3K-eSN">
+                                            <rect key="frame" x="16" y="16" width="28" height="28"/>
+                                            <constraints>
+                                                <constraint firstAttribute="height" constant="28" id="7je-2C-oH0"/>
+                                                <constraint firstAttribute="width" constant="28" id="gxY-bI-V0v"/>
+                                            </constraints>
+                                        </imageView>
+                                        <label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="A8f-xF-j3i">
+                                            <rect key="frame" x="60" y="19.5" width="326" height="21"/>
+                                            <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                            <nil key="textColor"/>
+                                            <nil key="highlightedColor"/>
+                                        </label>
+                                    </subviews>
+                                    <constraints>
+                                        <constraint firstItem="A8f-xF-j3i" firstAttribute="leading" secondItem="RV0-3K-eSN" secondAttribute="trailing" constant="16" id="ADH-SJ-JNh"/>
+                                        <constraint firstItem="RV0-3K-eSN" firstAttribute="leading" secondItem="tmT-MO-Dwy" secondAttribute="leading" constant="16" id="QQt-st-4hA"/>
+                                        <constraint firstItem="RV0-3K-eSN" firstAttribute="centerY" secondItem="tmT-MO-Dwy" secondAttribute="centerY" id="R6O-om-tEz"/>
+                                        <constraint firstAttribute="trailingMargin" secondItem="A8f-xF-j3i" secondAttribute="trailing" constant="8" id="fia-KH-ier"/>
+                                        <constraint firstItem="A8f-xF-j3i" firstAttribute="centerY" secondItem="tmT-MO-Dwy" secondAttribute="centerY" id="kPV-bd-AAL"/>
+                                    </constraints>
+                                </tableViewCellContentView>
+                            </tableViewCell>
+                        </prototypes>
+                        <connections>
+                            <outlet property="dataSource" destination="dbT-V0-aXb" id="sZc-Dc-wQl"/>
+                            <outlet property="delegate" destination="dbT-V0-aXb" id="nv8-45-MsJ"/>
+                        </connections>
+                    </tableView>
+                </tableViewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="C45-Hv-vwv" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="-630" y="-129"/>
+        </scene>
+    </scenes>
+</document>

+ 39 - 0
iOSClient/Main/Menu/MenuAction.swift

@@ -0,0 +1,39 @@
+//
+//  MainMenuAction.swift
+//  Nextcloud
+//
+//  Created by Philippe Weidmann on 16.01.20.
+//  Copyright © 2020 TWS. All rights reserved.
+//
+
+import Foundation
+
+class MenuAction {
+
+    let title: String
+    let icon: UIImage
+    let selectable: Bool
+    var onTitle: String?
+    var onIcon: UIImage?
+    var selected: Bool = false
+    var isOn: Bool = false
+    var action: ((_ menuAction: MenuAction) -> Void)?
+
+    init(title: String, icon: UIImage, action: ((_ menuAction: MenuAction) -> Void)?) {
+        self.title = title
+        self.icon = icon
+        self.action = action
+        self.selectable = false
+    }
+
+    init(title: String, icon: UIImage, onTitle: String? = nil, onIcon: UIImage? = nil, selected: Bool, on: Bool, action: ((_ menuAction: MenuAction) -> Void)?) {
+        self.title = title
+        self.icon = icon
+        self.onTitle = onTitle ?? title
+        self.onIcon = onIcon ?? icon
+        self.action = action
+        self.selected = selected
+        self.isOn = on
+        self.selectable = true
+    }
+}

+ 35 - 0
iOSClient/Main/Menu/MenuPanelController.swift

@@ -0,0 +1,35 @@
+//
+//  MenuPanelController.swift
+//  Nextcloud
+//
+//  Created by Philippe Weidmann on 23.01.20.
+//  Copyright © 2020 TWS. All rights reserved.
+//
+
+import FloatingPanel
+
+class MenuPanelController: FloatingPanelController {
+
+    var panelWidth: Int? = 0
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+                
+        self.surfaceView.grabberHandle.isHidden = true
+        self.isRemovalInteractionEnabled = true
+        if #available(iOS 11, *) {
+            self.surfaceView.cornerRadius = 16
+        } else {
+            self.surfaceView.cornerRadius = 0
+        }
+    }
+    
+    override func viewWillLayoutSubviews() {
+        super.viewWillLayoutSubviews()
+        
+        if let width = panelWidth {
+            self.view.frame = CGRect(x: 0, y: 0, width: width, height: Int(self.view.frame.height))
+        }
+    }
+    
+}