Marino Faggiana 8 жил өмнө
parent
commit
08a6e54bdc

+ 27 - 3
Nextcloud.xcodeproj/project.pbxproj

@@ -277,6 +277,9 @@
 		F7676A7F1D5CB2A400DF734C /* icon-info@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F7676A751D5CB2A400DF734C /* icon-info@2x.png */; };
 		F7676A811D5CB2A400DF734C /* icon-success.png in Resources */ = {isa = PBXBuildFile; fileRef = F7676A761D5CB2A400DF734C /* icon-success.png */; };
 		F7676A831D5CB2A400DF734C /* icon-success@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F7676A771D5CB2A400DF734C /* icon-success@2x.png */; };
+		F769D39A1E9E1506006DBBB4 /* CCLocalStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = F769D3961E9E1506006DBBB4 /* CCLocalStorage.m */; };
+		F769D39B1E9E1506006DBBB4 /* CCLocalStorageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F769D3981E9E1506006DBBB4 /* CCLocalStorageCell.m */; };
+		F769D39C1E9E1506006DBBB4 /* CCLocalStorageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F769D3991E9E1506006DBBB4 /* CCLocalStorageCell.xib */; };
 		F77B0DF01D118A16002130FE /* UIImage+Resizing.m in Sources */ = {isa = PBXBuildFile; fileRef = F70F04CA1C889184008DAB36 /* UIImage+Resizing.m */; };
 		F77B0DF21D118A16002130FE /* CCUploadFromOtherUpp.m in Sources */ = {isa = PBXBuildFile; fileRef = F7956FCA1B4886E60085DEA3 /* CCUploadFromOtherUpp.m */; };
 		F77B0DF41D118A16002130FE /* CCMain.m in Sources */ = {isa = PBXBuildFile; fileRef = F70211FB1BAC56E9003FC03E /* CCMain.m */; };
@@ -1418,6 +1421,11 @@
 		F768EAFB1BFB7CD800B6E341 /* CCShareOC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCShareOC.h; sourceTree = "<group>"; };
 		F768EAFC1BFB7CD800B6E341 /* CCShareOC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCShareOC.m; sourceTree = "<group>"; };
 		F768EB021BFB7EA900B6E341 /* CCShare.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = CCShare.storyboard; sourceTree = "<group>"; };
+		F769D3951E9E1506006DBBB4 /* CCLocalStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLocalStorage.h; sourceTree = "<group>"; };
+		F769D3961E9E1506006DBBB4 /* CCLocalStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLocalStorage.m; sourceTree = "<group>"; };
+		F769D3971E9E1506006DBBB4 /* CCLocalStorageCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLocalStorageCell.h; sourceTree = "<group>"; };
+		F769D3981E9E1506006DBBB4 /* CCLocalStorageCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLocalStorageCell.m; sourceTree = "<group>"; };
+		F769D3991E9E1506006DBBB4 /* CCLocalStorageCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CCLocalStorageCell.xib; sourceTree = "<group>"; };
 		F76A75E01E83D42B005AFFF4 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/CTAssetsPicker.strings; sourceTree = "<group>"; };
 		F76A75E11E83D42B005AFFF4 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/SwiftWebVC.strings; sourceTree = "<group>"; };
 		F76A75E21E83D42B005AFFF4 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/BKPasscodeView.strings; sourceTree = "<group>"; };
@@ -2884,6 +2892,18 @@
 			path = Icons;
 			sourceTree = "<group>";
 		};
+		F769D3941E9E1506006DBBB4 /* Local storage */ = {
+			isa = PBXGroup;
+			children = (
+				F769D3951E9E1506006DBBB4 /* CCLocalStorage.h */,
+				F769D3961E9E1506006DBBB4 /* CCLocalStorage.m */,
+				F769D3971E9E1506006DBBB4 /* CCLocalStorageCell.h */,
+				F769D3981E9E1506006DBBB4 /* CCLocalStorageCell.m */,
+				F769D3991E9E1506006DBBB4 /* CCLocalStorageCell.xib */,
+			);
+			path = "Local storage";
+			sourceTree = "<group>";
+		};
 		F77F86401B4ABF6D009F0A10 /* Table */ = {
 			isa = PBXGroup;
 			children = (
@@ -3054,7 +3074,7 @@
 			path = Utility;
 			sourceTree = "<group>";
 		};
-		F7C00D411E2D0D0F0032160B /* Favorite+Synchronize */ = {
+		F7C00D411E2D0D0F0032160B /* Favorite */ = {
 			isa = PBXGroup;
 			children = (
 				F7C00D421E2D0D0F0032160B /* CCCellOffline.h */,
@@ -3067,7 +3087,7 @@
 				F7EC14791E5D9C0B0046F351 /* CCSynchronize.h */,
 				F7EC147A1E5D9C0B0046F351 /* CCSynchronize.m */,
 			);
-			name = "Favorite+Synchronize";
+			name = Favorite;
 			path = Offline;
 			sourceTree = "<group>";
 		};
@@ -3358,13 +3378,14 @@
 				F7E95CEC1AC40BA40060D08E /* FileSystem */,
 				F744BE911BEBB2EE004FFF66 /* Intro */,
 				F7F54CAC1E5B143100E19C62 /* Library */,
+				F769D3941E9E1506006DBBB4 /* Local storage */,
 				F7BFFA621A24D7300044ED85 /* Login */,
 				F7BFCCBD1B68C21900548E76 /* ManageLocation+ManageAsset */,
 				F7D6A0881D82DBFA0045AD1A /* ControlCenter+MenuAccount */,
 				F7F9E3451BC26B19004B9223 /* Move */,
 				F74D3DB81BAC1941000BAE4B /* Networking */,
 				F7C5259A1E3B441D00FFE02C /* Notification */,
-				F7C00D411E2D0D0F0032160B /* Favorite+Synchronize */,
+				F7C00D411E2D0D0F0032160B /* Favorite */,
 				F7FCFFD51D70798C000E6E29 /* PeekPop */,
 				F719FDAE1CF06645004895D0 /* PhotosCameraUpload */,
 				F7BE6E2A1D2D5C3B00106933 /* QuickActions */,
@@ -3799,6 +3820,7 @@
 				F77B0F1E1D118A16002130FE /* ZSSstrikethrough.png in Resources */,
 				F77B0F211D118A16002130FE /* ZSSh6.png in Resources */,
 				F77B0F231D118A16002130FE /* ZSSh3.png in Resources */,
+				F769D39C1E9E1506006DBBB4 /* CCLocalStorageCell.xib in Resources */,
 				F77B0F241D118A16002130FE /* Reader-Button-H.png in Resources */,
 				F77B0F251D118A16002130FE /* ZSSh1.png in Resources */,
 				F7676A7D1D5CB2A400DF734C /* icon-info.png in Resources */,
@@ -4155,6 +4177,7 @@
 				F77B0E1D1D118A16002130FE /* ReaderThumbQueue.m in Sources */,
 				F7274FED1E6EB6F400C241B6 /* Constant.swift in Sources */,
 				F7659A6E1DC0B760004860C4 /* PSTGridLayoutRow.m in Sources */,
+				F769D39B1E9E1506006DBBB4 /* CCLocalStorageCell.m in Sources */,
 				F77B0E201D118A16002130FE /* CCShareUserOC.m in Sources */,
 				F77B0E211D118A16002130FE /* ThumbsMainToolbar.m in Sources */,
 				F708CF791E56E8CC00271D8B /* TableGPS+CoreDataClass.m in Sources */,
@@ -4360,6 +4383,7 @@
 				F77B0EC31D118A16002130FE /* UIImage+Enhancing.m in Sources */,
 				F77B0EC61D118A16002130FE /* CCCellMain.m in Sources */,
 				F77B0EC71D118A16002130FE /* AESCrypt.m in Sources */,
+				F769D39A1E9E1506006DBBB4 /* CCLocalStorage.m in Sources */,
 				F744FA7E1E57333C00BFAB34 /* APAvatarImageView.m in Sources */,
 				F73CCE091DC13776007E38D8 /* NSObject+XLFormAdditions.m in Sources */,
 				F708CF971E56E8CC00271D8B /* TableAccount+CoreDataClass.m in Sources */,

+ 58 - 0
iOSClient/Local storage/CCLocalStorage.h

@@ -0,0 +1,58 @@
+//
+//  CCLocalStorage.h
+//  Crypto Cloud Technology Nextcloud
+//
+//  Created by Marino Faggiana on 16/01/17.
+//  Copyright (c) 2017 TWS. All rights reserved.
+//
+//  Author Marino Faggiana <m.faggiana@twsweb.it>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+#import <UIKit/UIKit.h>
+
+#import "CCDetail.h"
+#import "UIScrollView+EmptyDataSet.h"
+#import "TWMessageBarManager.h"
+#import "AHKActionSheet.h"
+#import "CCLocalStorageCell.h"
+#import "CCUtility.h"
+#import "CCCoreData.h"
+#import "CCMain.h"
+#import "CCGraphics.h"
+#import "CCAccountWeb.h"
+#import "CCBancomat.h"
+#import "CCCartaDiCredito.h"
+#import "CCCartaIdentita.h"
+#import "CCContoCorrente.h"
+#import "CCNote.h"
+#import "CCPassaporto.h"
+#import "CCPatenteGuida.h"
+
+@interface CCLocalStorage : UIViewController <UITableViewDataSource, UITableViewDelegate, UIDocumentInteractionControllerDelegate, UIActionSheetDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate, CCAccountWebDelegate, CCBancomatDelegate, CCCartaDiCreditoDelegate, CCCartaIdentitaDelegate, CCContoCorrenteDelegate, CCNoteDelegate, CCPassaportoDelegate, CCPatenteGuidaDelegate>
+
+@property (nonatomic, weak) IBOutlet UITableView *tableView;
+
+@property (nonatomic, strong) CCMetadata *metadata;
+@property (nonatomic, strong) NSString *serverUrl;
+@property (nonatomic, strong) NSString *titleViewControl;
+
+@property (nonatomic, weak) CCDetail *detailViewController;
+@property (nonatomic, strong) UIDocumentInteractionController *docController;
+
+- (void)reloadDatasource;
+- (void)readFolderWithForced:(BOOL)forced serverUrl:(NSString *)serverUrl;
+
+@end

+ 608 - 0
iOSClient/Local storage/CCLocalStorage.m

@@ -0,0 +1,608 @@
+//
+//  CCLocalStorage.m
+//  Crypto Cloud Technology Nextcloud
+//
+//  Created by Marino Faggiana on 16/01/17.
+//  Copyright (c) 2017 TWS. All rights reserved.
+//
+//  Author Marino Faggiana <m.faggiana@twsweb.it>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+#import "CCLocalStorage.h"
+
+#import "AppDelegate.h"
+
+#ifdef CUSTOM_BUILD
+    #import "CustomSwift.h"
+#else
+    #import "Nextcloud-Swift.h"
+#endif
+
+@interface CCLocalStorage ()
+{
+    NSArray *dataSource;
+    BOOL _reloadDataSource;
+}
+@end
+
+@implementation CCLocalStorage
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    
+    // Custom Cell
+    [self.tableView registerNib:[UINib nibWithNibName:@"CCLocalStorageCell" bundle:nil] forCellReuseIdentifier:@"Cell"];
+
+    // dataSource
+    dataSource = [NSMutableArray new];
+    
+    // Metadata
+    _metadata = [CCMetadata new];
+    
+    self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 1)];
+    self.tableView.separatorColor = COLOR_SEPARATOR_TABLE;
+    self.tableView.emptyDataSetDelegate = self;
+    self.tableView.emptyDataSetSource = self;
+    self.tableView.allowsMultipleSelectionDuringEditing = NO;
+    
+    _serverUrl = [CCUtility getDirectoryLocal];
+    
+    // Title
+    if (_titleViewControl)
+        self.title = _titleViewControl;
+    else
+        self.title = NSLocalizedString(@"_local_storage_", nil);
+}
+
+// Apparirà
+- (void)viewWillAppear:(BOOL)animated
+{
+    [super viewWillAppear:animated];
+    
+    // Color
+    [CCAspect aspectNavigationControllerBar:self.navigationController.navigationBar encrypted:NO online:[app.reachability isReachable] hidden:NO];
+    [CCAspect aspectTabBar:self.tabBarController.tabBar hidden:NO];
+    
+    // Plus Button
+    [app plusButtonVisibile:true];
+    
+    [self reloadDatasource];
+}
+
+// E' arrivato
+- (void)viewDidAppear:(BOOL)animated
+{
+    [super viewDidAppear:animated];
+        
+    // update Badge
+    [app updateApplicationIconBadgeNumber];
+}
+
+- (void)didReceiveMemoryWarning {
+    [super didReceiveMemoryWarning];
+}
+
+#pragma --------------------------------------------------------------------------------------------
+#pragma mark ==== DZNEmptyDataSetSource ====
+#pragma --------------------------------------------------------------------------------------------
+
+- (BOOL)emptyDataSetShouldDisplay:(UIScrollView *)scrollView
+{
+    // only for root
+    if ([_serverUrl isEqualToString:[CCUtility getDirectoryLocal]])
+        return YES;
+    else
+        return NO;
+}
+
+- (CGFloat)spaceHeightForEmptyDataSet:(UIScrollView *)scrollView
+{
+    return 0.0f;
+}
+
+- (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView
+{
+    return - self.navigationController.navigationBar.frame.size.height;
+}
+
+- (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView
+{
+    return [UIColor whiteColor];
+}
+
+- (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView
+{
+    return [UIImage imageNamed:image_brandBackgroundLite];
+}
+
+- (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView
+{
+    NSString *text = [NSString stringWithFormat:@"%@", @""];
+    
+    NSDictionary *attributes = @{NSFontAttributeName:[UIFont boldSystemFontOfSize:20.0f], NSForegroundColorAttributeName:COLOR_BRAND};
+    
+    return [[NSAttributedString alloc] initWithString:text attributes:attributes];
+}
+
+- (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView
+{
+    NSString *text = [NSString stringWithFormat:@"\n%@", NSLocalizedString(@"_tutorial_local_view_", nil)];
+    
+    NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new];
+    paragraph.lineBreakMode = NSLineBreakByWordWrapping;
+    paragraph.alignment = NSTextAlignmentCenter;
+    
+    NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:14.0], NSForegroundColorAttributeName: [UIColor lightGrayColor], NSParagraphStyleAttributeName: paragraph};
+    
+    return [[NSAttributedString alloc] initWithString:text attributes:attributes];
+}
+
+#pragma --------------------------------------------------------------------------------------------
+#pragma mark ===== UIDocumentInteractionController <delegate> =====
+#pragma --------------------------------------------------------------------------------------------
+
+- (void)documentInteractionControllerDidDismissOptionsMenu:(UIDocumentInteractionController *)controller
+{
+    // evitiamo il rimando della eventuale photo e/o video
+    if ([CCCoreData getCameraUploadActiveAccount:app.activeAccount]) {
+        
+        [CCCoreData setCameraUploadDatePhoto:[NSDate date]];
+        [CCCoreData setCameraUploadDateVideo:[NSDate date]];
+    }
+}
+
+#pragma --------------------------------------------------------------------------------------------
+#pragma mark ===== menu =====
+#pragma--------------------------------------------------------------------------------------------
+
+- (void)openModel:(CCMetadata *)metadata
+{
+    UIViewController *viewController;
+    BOOL isLocal = YES;
+    NSString *serverUrl = [CCCoreData getServerUrlFromDirectoryID:_metadata.directoryID activeAccount:app.activeAccount];
+    
+    if ([metadata.model isEqualToString:@"cartadicredito"])
+        viewController = [[CCCartaDiCredito alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:isLocal serverUrl:serverUrl];
+    
+    if ([metadata.model isEqualToString:@"bancomat"])
+        viewController = [[CCBancomat alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:isLocal serverUrl:serverUrl];
+    
+    if ([metadata.model isEqualToString:@"contocorrente"])
+        viewController = [[CCContoCorrente alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:isLocal serverUrl:serverUrl];
+    
+    if ([metadata.model isEqualToString:@"accountweb"])
+        viewController = [[CCAccountWeb alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:isLocal serverUrl:serverUrl];
+    
+    if ([metadata.model isEqualToString:@"patenteguida"])
+        viewController = [[CCPatenteGuida alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:isLocal serverUrl:serverUrl];
+    
+    if ([metadata.model isEqualToString:@"cartaidentita"])
+        viewController = [[CCCartaIdentita alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:isLocal serverUrl:serverUrl];
+    
+    if ([metadata.model isEqualToString:@"passaporto"])
+        viewController = [[CCPassaporto alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:isLocal serverUrl:serverUrl];
+    
+    if ([metadata.model isEqualToString:@"note"]) {
+        
+        viewController = [[CCNote alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:isLocal serverUrl:serverUrl];
+        
+        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
+        
+        [self presentViewController:navigationController animated:YES completion:nil];
+        
+    } else {
+        
+        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
+        
+        [navigationController setModalPresentationStyle:UIModalPresentationFormSheet];
+        
+        [self presentViewController:navigationController animated:YES completion:nil];
+    }
+}
+
+- (void)openWith:(CCMetadata *)metadata
+{
+    NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@", _serverUrl, metadata.fileNameData];
+        
+    if ([[NSFileManager defaultManager] fileExistsAtPath:fileNamePath]) {
+        
+        [[NSFileManager defaultManager] removeItemAtPath:[NSTemporaryDirectory() stringByAppendingString:metadata.fileNamePrint] error:nil];
+        [[NSFileManager defaultManager] linkItemAtPath:fileNamePath toPath:[NSTemporaryDirectory() stringByAppendingString:metadata.fileNamePrint] error:nil];
+        
+        NSURL *url = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingString:metadata.fileNamePrint]];
+        
+        _docController = [UIDocumentInteractionController interactionControllerWithURL:url];
+        _docController.delegate = self;
+        
+        [_docController presentOptionsMenuFromRect:self.view.frame inView:self.view animated:YES];
+    }
+}
+
+- (void)requestDeleteMetadata:(CCMetadata *)metadata indexPath:(NSIndexPath *)indexPath
+{
+    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
+        
+    [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_delete_", nil) style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
+        
+        NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@", _serverUrl, metadata.fileNameData];
+        NSString *iconPath = [NSString stringWithFormat:@"%@/.%@.ico", _serverUrl, metadata.fileNameData];
+                                                                   
+        [[NSFileManager defaultManager] removeItemAtPath:fileNamePath error:nil];
+        [[NSFileManager defaultManager] removeItemAtPath:iconPath error:nil];
+        
+                                                               
+        [self reloadDatasource];
+    }]];
+        
+        
+    [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_cancel_", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
+    }]];
+        
+    alertController.popoverPresentationController.sourceView = self.view;
+    alertController.popoverPresentationController.sourceRect = [self.tableView rectForRowAtIndexPath:indexPath];
+        
+    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
+        [alertController.view layoutIfNeeded];
+        
+    [self presentViewController:alertController animated:YES completion:nil];
+}
+
+-(void)cellButtonDownWasTapped:(id)sender
+{
+    CGPoint touchPoint = [sender convertPoint:CGPointZero toView:self.tableView];
+    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:touchPoint];
+    CCMetadata *metadata = [CCMetadata new];
+    UIImage *iconHeader;
+    
+    NSString *cameraFolderName = [CCCoreData getCameraUploadFolderNameActiveAccount:app.activeAccount];
+    NSString *cameraFolderPath = [CCCoreData getCameraUploadFolderPathActiveAccount:app.activeAccount activeUrl:app.activeUrl];
+        
+    metadata = [CCUtility insertFileSystemInMetadata:[dataSource objectAtIndex:indexPath.row] directory:_serverUrl activeAccount:app.activeAccount cameraFolderName:cameraFolderName cameraFolderPath:cameraFolderPath];
+        
+    
+    AHKActionSheet *actionSheet = [[AHKActionSheet alloc] initWithView:self.view title:nil];
+    
+    actionSheet.animationDuration = 0.2;
+    
+    actionSheet.blurRadius = 0.0f;
+    actionSheet.blurTintColor = [UIColor colorWithWhite:0.0f alpha:0.50f];
+    
+    actionSheet.buttonHeight = 50.0;
+    actionSheet.cancelButtonHeight = 50.0f;
+    actionSheet.separatorHeight = 5.0f;
+    
+    actionSheet.automaticallyTintButtonImages = @(NO);
+    
+    actionSheet.encryptedButtonTextAttributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:16], NSForegroundColorAttributeName:COLOR_CRYPTOCLOUD };
+    actionSheet.buttonTextAttributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:16], NSForegroundColorAttributeName:COLOR_TEXT_ANTHRACITE };
+    actionSheet.cancelButtonTextAttributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:16], NSForegroundColorAttributeName:COLOR_BRAND };
+    actionSheet.disableButtonTextAttributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:16], NSForegroundColorAttributeName:COLOR_TEXT_ANTHRACITE };
+    
+    actionSheet.separatorColor = COLOR_SEPARATOR_TABLE;
+    actionSheet.cancelButtonTitle = NSLocalizedString(@"_cancel_",nil);
+    
+    // assegnamo l'immagine anteprima se esiste, altrimenti metti quella standars
+    if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@.ico", app.directoryUser, metadata.fileID]])
+        iconHeader = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.ico", app.directoryUser, metadata.fileID]];
+    else
+        iconHeader = [UIImage imageNamed:metadata.iconName];
+    
+    [actionSheet addButtonWithTitle: metadata.fileNamePrint
+                              image: iconHeader
+                    backgroundColor: COLOR_TABBAR
+                             height: 50.0
+                               type: AHKActionSheetButtonTypeDisabled
+                            handler: nil
+    ];
+
+    // Remove file/folder offline
+    if (_serverUrl == nil) {
+        
+        [actionSheet addButtonWithTitle:NSLocalizedString(@"_remove_offline_", nil) image:[UIImage imageNamed:image_actionSheetOffline] backgroundColor:[UIColor whiteColor] height: 50.0 type:AHKActionSheetButtonTypeDefault handler:^(AHKActionSheet *as) {
+                                    
+            if (metadata.directory) {
+                                        
+                // remove tag offline for all folder/subfolder/file
+                NSString *relativeRoot = [CCCoreData getServerUrlFromDirectoryID:metadata.directoryID activeAccount:app.activeAccount];
+                NSString *dirServerUrl = [CCUtility stringAppendServerUrl:relativeRoot addFileName:metadata.fileNameData];
+                NSArray *directories = [CCCoreData getOfflineDirectoryActiveAccount:app.activeAccount];
+                                        
+                for (TableDirectory *directory in directories)
+                    if ([directory.serverUrl containsString:dirServerUrl]) {
+                        [CCCoreData setOfflineDirectoryServerUrl:directory.serverUrl offline:NO activeAccount:app.activeAccount];
+                        [CCCoreData removeOfflineAllFileFromServerUrl:directory.serverUrl activeAccount:app.activeAccount];
+                    }
+                                        
+            } else {
+                                        
+                [CCCoreData setOfflineLocalFileID:metadata.fileID offline:NO activeAccount:app.activeAccount];
+            }
+                                    
+            [self.tableView setEditing:NO animated:YES];
+                                    
+            [self reloadDatasource];
+        }];
+    }
+    
+    // Share
+    if (_metadata.cryptated == NO && app.hasServerShareSupport) {
+        
+        [actionSheet addButtonWithTitle:NSLocalizedString(@"_share_", nil)
+                                  image:[UIImage imageNamed:image_actionSheetShare]
+                        backgroundColor:[UIColor whiteColor]
+                                 height: 50.0
+                                   type:AHKActionSheetButtonTypeDefault
+                                handler:^(AHKActionSheet *as) {
+                                    
+                                    // close swipe
+                                    [self setEditing:NO animated:YES];
+                                    
+                                    [app.activeMain openWindowShare:metadata];
+                                }];
+    }
+
+    // NO Directory - NO Template
+    if (metadata.directory == NO && [metadata.type isEqualToString:k_metadataType_template] == NO) {
+        
+        [actionSheet addButtonWithTitle:NSLocalizedString(@"_open_in_", nil) image:[UIImage imageNamed:image_actionSheetOpenIn] backgroundColor:[UIColor whiteColor] height: 50.0 type:AHKActionSheetButtonTypeDefault handler:^(AHKActionSheet *as) {
+            
+            [self.tableView setEditing:NO animated:YES];
+            [self openWith:metadata];
+        }];
+    }
+    
+    [actionSheet addButtonWithTitle:NSLocalizedString(@"_delete_", nil) image:[UIImage imageNamed:image_delete] backgroundColor:[UIColor whiteColor] height: 50.0 type:AHKActionSheetButtonTypeDestructive handler:^(AHKActionSheet *as) {
+        
+        [self requestDeleteMetadata:metadata indexPath:indexPath];
+    }];
+
+    
+    [actionSheet show];
+}
+
+#pragma --------------------------------------------------------------------------------------------
+#pragma mark ==== Table ====
+#pragma --------------------------------------------------------------------------------------------
+
+- (CCMetadata *)setSelfMetadataFromIndexPath:(NSIndexPath *)indexPath
+{
+    NSString *cameraFolderName = [CCCoreData getCameraUploadFolderNameActiveAccount:app.activeAccount];
+    NSString *cameraFolderPath = [CCCoreData getCameraUploadFolderPathActiveAccount:app.activeAccount activeUrl:app.activeUrl];
+        
+    return [CCUtility insertFileSystemInMetadata:[dataSource objectAtIndex:indexPath.row] directory:_serverUrl activeAccount:app.activeAccount cameraFolderName:cameraFolderName cameraFolderPath:cameraFolderPath];
+    
+}
+
+- (void)readFolderWithForced:(BOOL)forced serverUrl:(NSString *)serverUrl
+{
+    [self reloadDatasource];
+}
+
+- (void)reloadDatasource
+{
+    NSArray *subpaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:_serverUrl error:nil];
+    NSMutableArray *metadatas = [NSMutableArray new];
+        
+    for (NSString *subpath in subpaths)
+        if (![[subpath lastPathComponent] hasPrefix:@"."])
+            [metadatas addObject:subpath];
+        
+    dataSource = [NSArray arrayWithArray:metadatas];
+    
+    [self.tableView reloadData];
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    return 60;
+}
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+    return 1;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+    return [dataSource count];
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    CCLocalStorageCell *cell = (CCLocalStorageCell *)[tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
+    CCMetadata *metadata;
+    
+    // separator
+    cell.separatorInset = UIEdgeInsetsMake(0.f, 60.f, 0.f, 0.f);
+    
+    // Initialize
+    cell.statusImageView.image = nil;
+    cell.offlineImageView.image = nil;
+    
+    // change color selection
+    UIView *selectionColor = [[UIView alloc] init];
+    selectionColor.backgroundColor = COLOR_SELECT_BACKGROUND;
+    cell.selectedBackgroundView = selectionColor;
+
+    NSString *cameraFolderName = [CCCoreData getCameraUploadFolderNameActiveAccount:app.activeAccount];
+    NSString *cameraFolderPath = [CCCoreData getCameraUploadFolderPathActiveAccount:app.activeAccount activeUrl:app.activeUrl];
+        
+    metadata = [CCUtility insertFileSystemInMetadata:[dataSource objectAtIndex:indexPath.row] directory:_serverUrl activeAccount:app.activeAccount cameraFolderName:cameraFolderName cameraFolderPath:cameraFolderPath];
+        
+    cell.fileImageView.image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/.%@.ico", _serverUrl, metadata.fileNamePrint]];
+        
+    if (!cell.fileImageView.image) {
+            
+        UIImage *icon = [CCGraphics createNewImageFrom:metadata.fileID directoryUser:_serverUrl fileNameTo:metadata.fileID fileNamePrint:metadata.fileNamePrint size:@"m" imageForUpload:NO typeFile:metadata.typeFile writePreview:NO optimizedFileName:[CCUtility getOptimizedPhoto]];
+            
+        if (icon) {
+            [CCGraphics saveIcoWithFileID:metadata.fileNamePrint image:icon writeToFile:[NSString stringWithFormat:@"%@/.%@.ico", _serverUrl, metadata.fileNamePrint] copy:NO move:NO fromPath:nil toPath:nil];
+            cell.fileImageView.image = icon;
+        }
+    }
+    
+    // ButtonDown Tapped
+    [cell.buttonDown addTarget:self action:@selector(cellButtonDownWasTapped:) forControlEvents:UIControlEventTouchUpInside];
+    
+    // encrypted color
+    if (metadata.cryptated) {
+        cell.labelTitle.textColor = COLOR_CRYPTOCLOUD;
+    } else {
+        cell.labelTitle.textColor = [UIColor blackColor];
+    }
+    
+    // File name
+    cell.labelTitle.text = metadata.fileNamePrint;
+    cell.labelInfoFile.text = @"";
+    
+    // Immagine del file, se non c'è l'anteprima mettiamo quella standard
+    if (cell.fileImageView.image == nil)
+        cell.fileImageView.image = [UIImage imageNamed:metadata.iconName];
+    
+    // it's encrypted ???
+    if (metadata.cryptated && [metadata.type isEqualToString: k_metadataType_template] == NO)
+        cell.statusImageView.image = [UIImage imageNamed:image_lock];
+    
+    // text and length
+    if (metadata.directory) {
+        
+        cell.labelInfoFile.text = [CCUtility dateDiff:metadata.date];
+        cell.accessoryType = UITableViewCellAccessoryNone;
+        //cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
+          
+    } else {
+        
+        NSString *date = [CCUtility dateDiff:metadata.date];
+        NSString *length = [CCUtility transformedSize:metadata.size];
+        
+        if ([metadata.type isEqualToString: k_metadataType_template])
+            cell.labelInfoFile.text = [NSString stringWithFormat:@"%@", date];
+        
+        if ([metadata.type isEqualToString: k_metadataType_file] || [metadata.type isEqualToString: k_metadataType_local]) {
+            
+            BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@", _serverUrl, metadata.fileName]];
+            
+            if (fileExists)
+                cell.labelInfoFile.text = [NSString stringWithFormat:@"%@ • %@", date, length];
+            else
+                cell.labelInfoFile.text = [NSString stringWithFormat:@"%@ ◦ %@", date, length];
+        }
+        
+        cell.accessoryType = UITableViewCellAccessoryNone;
+        
+    }
+    
+    return cell;
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    // deselect row
+    [tableView deselectRowAtIndexPath:indexPath animated:YES];
+    
+    _metadata = [self setSelfMetadataFromIndexPath:indexPath];
+    
+    // if is in download [do not touch]
+    if ([_metadata.session length] > 0 && [_metadata.session containsString:@"download"])
+        return;
+    
+    // File
+    if (([_metadata.type isEqualToString: k_metadataType_file] || [_metadata.type isEqualToString: k_metadataType_local]) && _metadata.directory == NO) {
+        
+        if ([self shouldPerformSegue])
+            [self performSegueWithIdentifier:@"segueDetail" sender:self];
+    }
+    
+    // Model
+    if ([self.metadata.type isEqualToString: k_metadataType_template])
+        [self openModel:self.metadata];
+    
+    // Directory
+    if (_metadata.directory)
+        [self performSegueDirectoryWithControlPasscode];
+}
+
+-(void)performSegueDirectoryWithControlPasscode
+{
+    CCLocalStorage *vc = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"CCLocalStorage"];
+    
+    vc.serverUrl = [CCUtility stringAppendServerUrl:_serverUrl addFileName:_metadata.fileNameData];
+    vc.titleViewControl = _metadata.fileNamePrint;
+    
+    [self.navigationController pushViewController:vc animated:YES];
+}
+
+#pragma --------------------------------------------------------------------------------------------
+#pragma mark ===== Navigation ====
+#pragma --------------------------------------------------------------------------------------------
+
+- (BOOL)shouldPerformSegue
+{
+    // if i am in background -> exit
+    if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) return NO;
+    
+    // if i am not window -> exit
+    if (self.view.window == NO)
+        return NO;
+    
+    // Collapsed but i am in detail -> exit
+    if (self.splitViewController.isCollapsed)
+        if (self.detailViewController.isViewLoaded && self.detailViewController.view.window) return NO;
+    
+    // Video in run -> exit
+    if (self.detailViewController.photoBrowser.currentVideoPlayerViewController.isViewLoaded && self.detailViewController.photoBrowser.currentVideoPlayerViewController.view.window) return NO;
+    
+    return YES;
+}
+
+-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
+{
+    id viewController = segue.destinationViewController;
+    
+    if ([viewController isKindOfClass:[UINavigationController class]]) {
+        UINavigationController *nav = viewController;
+        _detailViewController = (CCDetail *)nav.topViewController;
+    } else {
+        _detailViewController = segue.destinationViewController;
+    }
+    
+    NSMutableArray *allRecordsDataSourceImagesVideos = [NSMutableArray new];
+    
+    
+    NSString *cameraFolderName = [CCCoreData getCameraUploadFolderNameActiveAccount:app.activeAccount];
+    NSString *cameraFolderPath = [CCCoreData getCameraUploadFolderPathActiveAccount:app.activeAccount activeUrl:app.activeUrl];
+        
+    for (NSString *fileName in dataSource) {
+            
+        CCMetadata *metadata = [CCMetadata new];
+        metadata = [CCUtility insertFileSystemInMetadata:fileName directory:_serverUrl activeAccount:app.activeAccount cameraFolderName:cameraFolderName cameraFolderPath:cameraFolderPath];
+            
+        if ([metadata.typeFile isEqualToString: k_metadataTypeFile_image] || [metadata.typeFile isEqualToString: k_metadataTypeFile_video])
+            [allRecordsDataSourceImagesVideos addObject:metadata];
+    }
+        
+    _detailViewController.sourceDirectoryLocal = YES;
+    _detailViewController.metadataDetail = _metadata;
+    _detailViewController.dateFilterQuery = nil;
+    _detailViewController.isCameraUpload = NO;
+    _detailViewController.dataSourceImagesVideos = allRecordsDataSourceImagesVideos;
+
+    
+    [_detailViewController setTitle:_metadata.fileNamePrint];
+}
+
+@end

+ 45 - 0
iOSClient/Local storage/CCLocalStorageCell.h

@@ -0,0 +1,45 @@
+//
+//  CCLocalStorageCell.h
+//  Crypto Cloud Technology Nextcloud
+//
+//  Created by Marino Faggiana on 05/05/15.
+//  Copyright (c) 2014 TWS. All rights reserved.
+//
+//  Author Marino Faggiana <m.faggiana@twsweb.it>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface CCLocalStorageCell : UITableViewCell
+
+@property(nonatomic, weak) IBOutlet UIImageView *fileImageView;
+@property(nonatomic, weak) IBOutlet UIImageView *statusImageView;
+@property(nonatomic, weak) IBOutlet UIImageView *offlineImageView;
+
+@property(nonatomic, weak) IBOutlet UILabel *labelTitle;
+@property(nonatomic, weak) IBOutlet UILabel *labelInfoFile;
+
+@property(nonatomic, weak) IBOutlet UIButton *buttonDown;
+
+@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *constraints;
+
+//Last position of the scroll of the swipe
+@property (nonatomic, assign) CGFloat lastContentOffset;
+
+//Index path of the cell swipe gesture ocured
+@property (nonatomic, strong) NSIndexPath *indexPath;
+
+@end

+ 68 - 0
iOSClient/Local storage/CCLocalStorageCell.m

@@ -0,0 +1,68 @@
+//
+//  CCCellOffline.m
+//  Crypto Cloud Technology Nextcloud
+//
+//  Created by Marino Faggiana on 05/05/15.
+//  Copyright (c) 2014 TWS. All rights reserved.
+//
+//  Author Marino Faggiana <m.faggiana@twsweb.it>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+#import "CCLocalStorageCell.h"
+
+@implementation CCLocalStorageCell
+
+- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
+{
+    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
+    if (self) {
+        // Initialization code
+
+        
+    }
+    return self;
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated
+{
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+- (void)layoutSubviews {
+    
+    [super layoutSubviews];
+    
+    for (NSLayoutConstraint *constraint in self.constraints) {
+        constraint.constant = self.frame.size.width - self.contentView.frame.size.width;
+    }
+}
+
+///-----------------------------------
+/// @name scrollViewWillBeginDecelerating
+///-----------------------------------
+
+/**
+ * Method to initialize the position where we make the swipe in order to detect the direction
+ *
+ * @param UIScrollView -> scrollView
+ */
+- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
+    _lastContentOffset = scrollView.contentOffset.x;
+}
+
+@end

+ 107 - 0
iOSClient/Local storage/CCLocalStorageCell.xib

@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12118" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
+    <device id="retina4_7" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
+        <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="CustomCellFileAndDirectory"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="blue" indentationWidth="0.0" reuseIdentifier="Cell" rowHeight="60" id="2" userLabel="CCLocalStorageCell" customClass="CCLocalStorageCell">
+            <rect key="frame" x="0.0" y="0.0" width="600" height="60"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="2" id="sQq-jC-UEV">
+                <rect key="frame" x="0.0" y="0.0" width="600" height="60"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view alpha="0.10000000149011612" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hzp-7C-oyF" userLabel="Gray">
+                        <rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                        <color key="backgroundColor" red="0.66666666669999997" green="0.66666666669999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                    </view>
+                    <label opaque="NO" userInteractionEnabled="NO" tag="101" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QNC-8X-DAC">
+                        <rect key="frame" x="68" y="13" width="473" height="20"/>
+                        <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                        <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                        <nil key="highlightedColor"/>
+                    </label>
+                    <imageView userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5">
+                        <rect key="frame" x="8" y="11" width="40" height="40"/>
+                        <constraints>
+                            <constraint firstAttribute="width" constant="40" id="7r4-ao-ayY"/>
+                            <constraint firstAttribute="height" constant="40" id="cGI-9B-eWe"/>
+                        </constraints>
+                    </imageView>
+                    <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="DQR-yN-JaH">
+                        <rect key="frame" x="37" y="40" width="15" height="15"/>
+                        <constraints>
+                            <constraint firstAttribute="width" constant="15" id="O4C-De-dnI"/>
+                            <constraint firstAttribute="height" constant="15" id="bun-Ao-Ysu"/>
+                        </constraints>
+                    </imageView>
+                    <label opaque="NO" userInteractionEnabled="NO" tag="102" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p7I-KN-FVZ">
+                        <rect key="frame" x="68" y="33" width="473" height="15"/>
+                        <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                        <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
+                        <nil key="highlightedColor"/>
+                    </label>
+                    <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="dhG-hb-z3n" userLabel="Offline Image View">
+                        <rect key="frame" x="4" y="40" width="15" height="15"/>
+                        <constraints>
+                            <constraint firstAttribute="width" constant="15" id="ZiA-bt-IkC"/>
+                            <constraint firstAttribute="height" constant="15" id="aQq-XY-pNM"/>
+                        </constraints>
+                    </imageView>
+                    <button opaque="NO" alpha="0.40000000000000002" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6B9-Jc-esJ" userLabel="buttonDown">
+                        <rect key="frame" x="541" y="0.0" width="60" height="60"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="60" id="PcN-jN-71v"/>
+                            <constraint firstAttribute="width" constant="60" id="bAG-EX-HKe"/>
+                        </constraints>
+                        <state key="normal" image="buttonDown"/>
+                    </button>
+                </subviews>
+                <constraints>
+                    <constraint firstItem="p7I-KN-FVZ" firstAttribute="leading" secondItem="DQR-yN-JaH" secondAttribute="trailing" constant="16" id="2xR-G4-B2S"/>
+                    <constraint firstItem="dhG-hb-z3n" firstAttribute="top" secondItem="sQq-jC-UEV" secondAttribute="topMargin" constant="32" id="4Zy-SY-nfT"/>
+                    <constraint firstItem="QNC-8X-DAC" firstAttribute="trailing" secondItem="sQq-jC-UEV" secondAttribute="trailingMargin" constant="-51" id="7zt-c0-CsI"/>
+                    <constraint firstItem="6B9-Jc-esJ" firstAttribute="centerY" secondItem="5" secondAttribute="centerY" constant="-1" id="EoB-vw-kgn"/>
+                    <constraint firstAttribute="centerY" secondItem="5" secondAttribute="centerY" constant="-1.5" id="FQP-wg-vPF"/>
+                    <constraint firstItem="DQR-yN-JaH" firstAttribute="top" secondItem="p7I-KN-FVZ" secondAttribute="top" constant="6.5" id="K6B-gJ-8Fp"/>
+                    <constraint firstItem="p7I-KN-FVZ" firstAttribute="leading" secondItem="5" secondAttribute="trailing" constant="20" id="K7G-0u-f8E"/>
+                    <constraint firstItem="5" firstAttribute="bottom" secondItem="p7I-KN-FVZ" secondAttribute="bottom" constant="3" id="MuE-C8-4UJ"/>
+                    <constraint firstItem="QNC-8X-DAC" firstAttribute="leading" secondItem="5" secondAttribute="trailing" constant="20" id="UYc-Al-a4h"/>
+                    <constraint firstItem="dhG-hb-z3n" firstAttribute="leading" secondItem="sQq-jC-UEV" secondAttribute="leadingMargin" constant="-4" id="dNM-6x-zkx"/>
+                    <constraint firstItem="5" firstAttribute="leading" secondItem="sQq-jC-UEV" secondAttribute="leadingMargin" id="ha0-VA-fF9"/>
+                    <constraint firstItem="p7I-KN-FVZ" firstAttribute="trailing" secondItem="sQq-jC-UEV" secondAttribute="trailingMargin" constant="-51" id="kaB-WS-bDl"/>
+                    <constraint firstItem="5" firstAttribute="top" secondItem="QNC-8X-DAC" secondAttribute="top" constant="-2" id="lyH-lh-z03"/>
+                    <constraint firstItem="6B9-Jc-esJ" firstAttribute="leading" secondItem="QNC-8X-DAC" secondAttribute="trailing" id="mBS-nt-t6R"/>
+                    <constraint firstItem="5" firstAttribute="top" secondItem="sQq-jC-UEV" secondAttribute="topMargin" constant="3" id="pRH-CQ-O4x"/>
+                </constraints>
+            </tableViewCellContentView>
+            <connections>
+                <outlet property="buttonDown" destination="6B9-Jc-esJ" id="tb8-y2-OM0"/>
+                <outlet property="fileImageView" destination="5" id="6"/>
+                <outlet property="labelInfoFile" destination="p7I-KN-FVZ" id="5Yb-hH-k73"/>
+                <outlet property="labelTitle" destination="QNC-8X-DAC" id="dFX-Cb-8IE"/>
+                <outlet property="offlineImageView" destination="dhG-hb-z3n" id="IGh-6c-M89"/>
+                <outlet property="statusImageView" destination="DQR-yN-JaH" id="UmC-pt-kjV"/>
+                <outletCollection property="constraints" destination="mBS-nt-t6R" id="4sz-P1-CPa"/>
+            </connections>
+            <point key="canvasLocation" x="316" y="128"/>
+        </tableViewCell>
+    </objects>
+    <resources>
+        <image name="buttonDown" width="25" height="25"/>
+    </resources>
+    <simulatedMetricsContainer key="defaultSimulatedMetrics">
+        <simulatedStatusBarMetrics key="statusBar"/>
+        <simulatedOrientationMetrics key="orientation"/>
+        <simulatedScreenMetrics key="destination" type="retina4_7.fullscreen"/>
+    </simulatedMetricsContainer>
+</document>

+ 3 - 0
iOSClient/Main/CCMore.swift

@@ -131,6 +131,9 @@ class CCMore: UIViewController, UITableViewDelegate, UITableViewDataSource {
         // Menu Function
         if (indexPath.section == 0) {
             
+            if (indexPath.row == 2) {
+                self.navigationController?.performSegue(withIdentifier: "segueLocalStorage", sender: self)
+            }
         }
         
         // Menu External Site

+ 36 - 2
iOSClient/Main/Main.storyboard

@@ -83,7 +83,7 @@
                                 <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                                 <prototypes>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" rowHeight="50" id="zQQ-52-W9I" customClass="CCCellMore" customModule="Nextcloud" customModuleProvider="target">
-                                        <rect key="frame" x="0.0" y="55.5" width="375" height="50"/>
+                                        <rect key="frame" x="0.0" y="56" width="375" height="50"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="zQQ-52-W9I" id="Zho-os-HYj">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="50"/>
@@ -757,12 +757,46 @@
                     <connections>
                         <segue destination="9DM-ts-oJu" kind="relationship" relationship="rootViewController" id="KD8-1A-v76"/>
                         <segue destination="amx-XG-NId" kind="show" identifier="segueSettings" id="iJw-qx-dwJ"/>
+                        <segue destination="o4I-W3-sMH" kind="show" identifier="segueLocalStorage" id="iz8-HB-F2p"/>
                     </connections>
                 </navigationController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="D7n-Z1-9wU" userLabel="First Responder" sceneMemberID="firstResponder"/>
             </objects>
             <point key="canvasLocation" x="9212" y="326"/>
         </scene>
+        <!--Local Storage-->
+        <scene sceneID="BhE-A6-AqD">
+            <objects>
+                <viewController storyboardIdentifier="CCLocalStorage" id="o4I-W3-sMH" customClass="CCLocalStorage" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="U4b-Rv-dSO"/>
+                        <viewControllerLayoutGuide type="bottom" id="sYe-gZ-wls"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="IkL-Nw-JTF">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="bkD-NK-bSQ">
+                                <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
+                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <connections>
+                                    <outlet property="dataSource" destination="o4I-W3-sMH" id="L2O-Oa-VKV"/>
+                                    <outlet property="delegate" destination="o4I-W3-sMH" id="eqD-vp-sZY"/>
+                                </connections>
+                            </tableView>
+                        </subviews>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                    </view>
+                    <connections>
+                        <outlet property="tableView" destination="bkD-NK-bSQ" id="GQp-y5-f7J"/>
+                        <segue destination="mtc-lf-PRo" kind="showDetail" identifier="segueDetail" id="1IV-5w-SfJ"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="JsH-FD-nZN" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="9849" y="1218"/>
+        </scene>
     </scenes>
     <resources>
         <image name="Plus" width="40" height="40"/>
@@ -775,6 +809,6 @@
         <image name="tabBarPhotos" width="25" height="21"/>
     </resources>
     <inferredMetricsTieBreakers>
-        <segue reference="W5b-lw-8O1"/>
+        <segue reference="1IV-5w-SfJ"/>
     </inferredMetricsTieBreakers>
 </document>