Browse Source

new view share

marinofaggiana 5 years ago
parent
commit
8262cfc511

+ 24 - 0
Nextcloud.xcodeproj/project.pbxproj

@@ -328,6 +328,12 @@
 		F76673EE22C901F6007ED366 /* FileProviderDomain.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76673EC22C901F5007ED366 /* FileProviderDomain.swift */; };
 		F76673F022C90434007ED366 /* FileProviderUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76673EF22C90433007ED366 /* FileProviderUtility.swift */; };
 		F769453C22E9CFFF000A798A /* NCShareUserCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F769453B22E9CFFF000A798A /* NCShareUserCell.xib */; };
+		F769453E22E9E97E000A798A /* NCShareUserMenuView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F769453D22E9E97D000A798A /* NCShareUserMenuView.xib */; };
+		F769454022E9F077000A798A /* NCSharePaging.swift in Sources */ = {isa = PBXBuildFile; fileRef = F769453F22E9F077000A798A /* NCSharePaging.swift */; };
+		F769454222E9F0EE000A798A /* NCShareLinkMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F769454122E9F0EE000A798A /* NCShareLinkMenuView.swift */; };
+		F769454422E9F142000A798A /* NCShareUserMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F769454322E9F142000A798A /* NCShareUserMenuView.swift */; };
+		F769454622E9F1B0000A798A /* NCShareCommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F769454522E9F1B0000A798A /* NCShareCommon.swift */; };
+		F769454822E9F20D000A798A /* NCShareNetworking.swift in Sources */ = {isa = PBXBuildFile; fileRef = F769454722E9F20D000A798A /* NCShareNetworking.swift */; };
 		F76B3CCE1EAE01BD00921AC9 /* NCBrand.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */; };
 		F76B3CCF1EAE01BD00921AC9 /* NCBrand.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */; };
 		F76C6F8E21943C8C0063591B /* NCActionSheetHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76C6F8D21943C8C0063591B /* NCActionSheetHeader.swift */; };
@@ -1108,6 +1114,12 @@
 		F76673EC22C901F5007ED366 /* FileProviderDomain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileProviderDomain.swift; sourceTree = "<group>"; };
 		F76673EF22C90433007ED366 /* FileProviderUtility.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileProviderUtility.swift; sourceTree = "<group>"; };
 		F769453B22E9CFFF000A798A /* NCShareUserCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCShareUserCell.xib; sourceTree = "<group>"; };
+		F769453D22E9E97D000A798A /* NCShareUserMenuView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCShareUserMenuView.xib; sourceTree = "<group>"; };
+		F769453F22E9F077000A798A /* NCSharePaging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCSharePaging.swift; sourceTree = "<group>"; };
+		F769454122E9F0EE000A798A /* NCShareLinkMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareLinkMenuView.swift; sourceTree = "<group>"; };
+		F769454322E9F142000A798A /* NCShareUserMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareUserMenuView.swift; sourceTree = "<group>"; };
+		F769454522E9F1B0000A798A /* NCShareCommon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareCommon.swift; sourceTree = "<group>"; };
+		F769454722E9F20D000A798A /* NCShareNetworking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareNetworking.swift; sourceTree = "<group>"; };
 		F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCBrand.swift; sourceTree = "<group>"; };
 		F76C3B831C6388BC00DC4301 /* CCGraphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCGraphics.h; sourceTree = "<group>"; };
 		F76C3B841C6388BC00DC4301 /* CCGraphics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCGraphics.m; sourceTree = "<group>"; };
@@ -1757,7 +1769,13 @@
 				F787704E22E7019900F287A9 /* NCShareLinkCell.xib */,
 				F769453B22E9CFFF000A798A /* NCShareUserCell.xib */,
 				F7DFAA8922E22EF100FC4527 /* NCShareLinkMenuView.xib */,
+				F769453D22E9E97D000A798A /* NCShareUserMenuView.xib */,
+				F769453F22E9F077000A798A /* NCSharePaging.swift */,
 				F700510422DF6A89003A3356 /* NCShare.swift */,
+				F769454122E9F0EE000A798A /* NCShareLinkMenuView.swift */,
+				F769454322E9F142000A798A /* NCShareUserMenuView.swift */,
+				F769454722E9F20D000A798A /* NCShareNetworking.swift */,
+				F769454522E9F1B0000A798A /* NCShareCommon.swift */,
 			);
 			path = Share;
 			sourceTree = "<group>";
@@ -3315,6 +3333,7 @@
 				F7F54CEA1E5B14C700E19C62 /* ImageSelectedOff@3x.png in Resources */,
 				F760F78621F21F61006B1A73 /* LaunchScreen.storyboard in Resources */,
 				F7381EE5218218C9000B1560 /* NCOffline.storyboard in Resources */,
+				F769453E22E9E97E000A798A /* NCShareUserMenuView.xib in Resources */,
 				F7F54CF11E5B14C700E19C62 /* ImageSelectedSmallOn.png in Resources */,
 				F760F77C21F21F61006B1A73 /* StickersViewController.xib in Resources */,
 				F762CB1B1EACB66200B38484 /* XLForm.bundle in Resources */,
@@ -3613,6 +3632,7 @@
 				F7D423881F0596C6009C9782 /* ReaderThumbView.m in Sources */,
 				F73B4EFE1F470D9100BBEE4B /* LangHungarianModel.cpp in Sources */,
 				F7D4238A1F0596C6009C9782 /* ThumbsMainToolbar.m in Sources */,
+				F769454022E9F077000A798A /* NCSharePaging.swift in Sources */,
 				F760F79921F21F61006B1A73 /* CropViewController.swift in Sources */,
 				F70022EC1EC4C9100080073F /* OCXMLSharedParser.m in Sources */,
 				F7F54D061E5B14C800E19C62 /* MWCaptionView.m in Sources */,
@@ -3645,6 +3665,7 @@
 				F77444F8222816D5000D5EB0 /* NCPhotosPickerViewController.swift in Sources */,
 				F77B0E141D118A16002130FE /* CCError.m in Sources */,
 				F73B4F131F470D9100BBEE4B /* nsUniversalDetector.cpp in Sources */,
+				F769454622E9F1B0000A798A /* NCShareCommon.swift in Sources */,
 				F7B0C1751EE839A30033AC24 /* NCAutoUpload.m in Sources */,
 				F77B0E161D118A16002130FE /* AFViewShaker.m in Sources */,
 				F760F77E21F21F61006B1A73 /* PhotoEditor+Keyboard.swift in Sources */,
@@ -3682,6 +3703,7 @@
 				F73B4EF61F470D9100BBEE4B /* LangArabicModel.cpp in Sources */,
 				F7CA1ED420E7E3FE002CC65E /* PKPendingView.m in Sources */,
 				F7DFB7E0219C312D00680748 /* NCRichDocumentTemplate.m in Sources */,
+				F769454222E9F0EE000A798A /* NCShareLinkMenuView.swift in Sources */,
 				F73B4F0B1F470D9100BBEE4B /* nsGB2312Prober.cpp in Sources */,
 				F762CAFE1EACB66200B38484 /* XLFormLeftRightSelectorCell.m in Sources */,
 				F77B0E301D118A16002130FE /* CCHud.m in Sources */,
@@ -3759,6 +3781,7 @@
 				F7BF1B431D51E893000854F6 /* CCLogin.m in Sources */,
 				F760F79821F21F61006B1A73 /* StickerCollectionViewCell.swift in Sources */,
 				F70022FB1EC4C9100080073F /* NSString+Encode.m in Sources */,
+				F769454422E9F142000A798A /* NCShareUserMenuView.swift in Sources */,
 				F75037511DBFA91A008FB480 /* NSLayoutConstraint+PureLayout.m in Sources */,
 				F762CAFA1EACB66200B38484 /* XLFormDateCell.m in Sources */,
 				F70022B91EC4C9100080073F /* OCCommunication.m in Sources */,
@@ -3826,6 +3849,7 @@
 				F745B253222D88AE00346520 /* NCLoginQRCode.swift in Sources */,
 				F760F79221F21F61006B1A73 /* EmojisCollectionViewDelegate.swift in Sources */,
 				F7169A1C1EE590930086BD69 /* NCShares.m in Sources */,
+				F769454822E9F20D000A798A /* NCShareNetworking.swift in Sources */,
 				F77B0EC61D118A16002130FE /* CCCellMain.m in Sources */,
 				F7C9555521F0C5470024296E /* NCActivity.swift in Sources */,
 				F7D4238B1F0596C6009C9782 /* ThumbsViewController.m in Sources */,

+ 25 - 715
iOSClient/Share/NCShare.swift

@@ -23,211 +23,6 @@
 
 import Foundation
 import Parchment
-import FSCalendar
-
-class NCSharePaging: UIViewController {
-    
-    private let pagingViewController = NCShareHeaderViewController()
-    
-    @objc var metadata: tableMetadata?
-
-    override func viewDidLoad() {
-        super.viewDidLoad()
-        
-        pagingViewController.metadata = metadata
-        
-        // Navigation Controller
-        var image = CCGraphics.changeThemingColorImage(UIImage(named: "exit")!, width: 40, height: 40, color: UIColor.gray)
-        image = image?.withRenderingMode(.alwaysOriginal)
-        self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: self, action: #selector(exitTapped))
-
-        // Pagination
-        addChild(pagingViewController)
-        view.addSubview(pagingViewController.view)
-        pagingViewController.didMove(toParent: self)
-        
-        pagingViewController.selectedTextColor = .black
-        pagingViewController.indicatorColor = .black
-        pagingViewController.indicatorOptions = .visible(
-            height: 1,
-            zIndex: Int.max,
-            spacing: .zero,
-            insets: .zero
-        )
-        
-        // Contrain the paging view to all edges.
-        pagingViewController.view.translatesAutoresizingMaskIntoConstraints = false
-        NSLayoutConstraint.activate([
-            pagingViewController.view.topAnchor.constraint(equalTo: view.topAnchor),
-            pagingViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
-            pagingViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
-            pagingViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
-        ])
-        
-        // Set our data source and delegate.
-        pagingViewController.dataSource = self
-    }
-    
-    @objc func exitTapped() {
-        self.dismiss(animated: true, completion: nil)
-    }
-}
-
-extension NCSharePaging: PagingViewControllerDataSource {
-    
-    func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, viewControllerForIndex index: Int) -> UIViewController {
-        
-        let height = pagingViewController.options.menuHeight + NCSharePagingView.HeaderHeight
-        
-        switch index {
-        case 0:
-            let viewController = UIStoryboard(name: "NCActivity", bundle: nil).instantiateInitialViewController() as! NCActivity
-            viewController.insets = UIEdgeInsets(top: height, left: 0, bottom: 0, right: 0)
-            viewController.refreshControlEnable = false
-            viewController.didSelectItemEnable = false
-            viewController.filterFileID = metadata!.fileID
-            return viewController
-        case 1:
-            let viewController = UIStoryboard(name: "NCShare", bundle: nil).instantiateViewController(withIdentifier: "comments") as! NCShareComments
-            viewController.metadata = metadata!
-            return viewController
-        case 2:
-            let viewController = UIStoryboard(name: "NCShare", bundle: nil).instantiateViewController(withIdentifier: "sharing") as! NCShare
-            viewController.metadata = metadata!
-            viewController.height = height
-            return viewController
-        default:
-            return UIViewController()
-        }
-    }
-    
-    func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemForIndex index: Int) -> T {
-        switch index {
-        case 0:
-            return PagingIndexItem(index: index, title: NSLocalizedString("_activity_", comment: "")) as! T
-        case 1:
-            return PagingIndexItem(index: index, title: NSLocalizedString("_comments_", comment: "")) as! T
-        case 2:
-            return PagingIndexItem(index: index, title: NSLocalizedString("_sharing_", comment: "")) as! T
-        default:
-            return PagingIndexItem(index: index, title: "") as! T
-        }
-    }
-    
-    func numberOfViewControllers<T>(in: PagingViewController<T>) -> Int{
-        return 3
-    }
-}
-
-class NCShareHeaderViewController: PagingViewController<PagingIndexItem> {
-    
-    public var image: UIImage?
-    public var metadata: tableMetadata?
-
-    override func loadView() {
-        view = NCSharePagingView(
-            options: options,
-            collectionView: collectionView,
-            pageView: pageViewController.view,
-            metadata: metadata
-        )
-    }
-}
-
-class NCSharePagingView: PagingView {
-    
-    static let HeaderHeight: CGFloat = 200
-    var metadata: tableMetadata?
-    
-    var headerHeightConstraint: NSLayoutConstraint?
-    
-    public init(options: Parchment.PagingOptions, collectionView: UICollectionView, pageView: UIView, metadata: tableMetadata?) {
-        super.init(options: options, collectionView: collectionView, pageView: pageView)
-        
-        self.metadata = metadata
-    }
-    
-    required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    override func setupConstraints() {
-        
-        let headerView = Bundle.main.loadNibNamed("NCShareHeaderView", owner: self, options: nil)?.first as! NCShareHeaderView
-        
-        if FileManager.default.fileExists(atPath: CCUtility.getDirectoryProviderStorageIconFileID(metadata!.fileID, fileNameView: metadata!.fileNameView)) {
-            headerView.imageView.image = UIImage.init(contentsOfFile: CCUtility.getDirectoryProviderStorageIconFileID(metadata!.fileID, fileNameView: metadata!.fileNameView))
-        } else {
-            if metadata!.iconName.count > 0 {
-                headerView.imageView.image = UIImage.init(named: metadata!.iconName)
-            } else if metadata!.directory {
-                let image = UIImage.init(named: "folder")!
-                headerView.imageView.image = CCGraphics.changeThemingColorImage(image, width: image.size.width*2, height: image.size.height*2, color: NCBrandColor.sharedInstance.brandElement)
-            } else {
-                headerView.imageView.image = UIImage.init(named: "file")
-            }
-        }
-        headerView.fileName.text = metadata?.fileNameView
-        if metadata!.favorite {
-            headerView.favorite.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "favorite"), width: 40, height: 40, color: NCBrandColor.sharedInstance.yellowFavorite), for: .normal)
-        } else {
-            headerView.favorite.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "favorite"), width: 40, height: 40, color: NCBrandColor.sharedInstance.textInfo), for: .normal)
-        }
-        headerView.info.text = CCUtility.transformedSize(metadata!.size) + ", " + CCUtility.dateDiff(metadata!.date as Date)
-        addSubview(headerView)
-        
-        pageView.translatesAutoresizingMaskIntoConstraints = false
-        collectionView.translatesAutoresizingMaskIntoConstraints = false
-        headerView.translatesAutoresizingMaskIntoConstraints = false
-        
-        headerHeightConstraint = headerView.heightAnchor.constraint(
-            equalToConstant: NCSharePagingView.HeaderHeight
-        )
-        headerHeightConstraint?.isActive = true
-        
-        NSLayoutConstraint.activate([
-            collectionView.leadingAnchor.constraint(equalTo: leadingAnchor),
-            collectionView.trailingAnchor.constraint(equalTo: trailingAnchor),
-            collectionView.heightAnchor.constraint(equalToConstant: options.menuHeight),
-            collectionView.topAnchor.constraint(equalTo: headerView.bottomAnchor),
-            
-            headerView.topAnchor.constraint(equalTo: topAnchor),
-            headerView.leadingAnchor.constraint(equalTo: leadingAnchor),
-            headerView.trailingAnchor.constraint(equalTo: trailingAnchor),
-            
-            pageView.leadingAnchor.constraint(equalTo: leadingAnchor),
-            pageView.trailingAnchor.constraint(equalTo: trailingAnchor),
-            pageView.bottomAnchor.constraint(equalTo: bottomAnchor),
-            pageView.topAnchor.constraint(equalTo: topAnchor)
-        ])
-    }
-}
-
-class NCShareHeaderView: UIView {
-
-    @IBOutlet weak var imageView: UIImageView!
-    @IBOutlet weak var fileName: UILabel!
-    @IBOutlet weak var info: UILabel!
-    @IBOutlet weak var favorite: UIButton!
-}
-
-// MARK: - Comments
-
-class NCShareComments: UIViewController {
-    
-    var metadata: tableMetadata?
-    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
-
-    override func viewDidLoad() {
-        super.viewDidLoad()
-        
-        OCNetworking.sharedManager()?.getCommentsWithAccount(appDelegate.activeAccount, fileID: metadata?.fileID, completion: { (account, list, message, errorCode) in
-            print("ciao")
-        })
-    }
-}
-
-// MARK: - Share
 
 class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareLinkCellDelegate, NCShareUserCellDelegate, NCShareNetworkingDelegate {
     
@@ -245,7 +40,8 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareLinkCellDel
     var metadata: tableMetadata?
     public var height: CGFloat = 0
     private var shareLinkMenuView: NCShareLinkMenuView?
-    private var shareLinkMenuViewWindow: UIView?
+    private var shareUserMenuView: NCShareUserMenuView?
+    private var shareMenuViewWindow: UIView?
 
     override func viewDidLoad() {
         super.viewDidLoad()
@@ -277,6 +73,8 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareLinkCellDel
     override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
         shareLinkMenuView?.unLoad()
         shareLinkMenuView = nil
+        shareUserMenuView?.unLoad()
+        shareUserMenuView = nil
     }
     
     @IBAction func touchUpInsideButtonCopy(_ sender: Any) {
@@ -297,6 +95,8 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareLinkCellDel
     @objc func tapLinkMenuViewWindow(gesture: UITapGestureRecognizer) {
         shareLinkMenuView?.unLoad()
         shareLinkMenuView = nil
+        shareUserMenuView?.unLoad()
+        shareUserMenuView = nil
     }
     
     func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
@@ -312,13 +112,25 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareLinkCellDel
     }
     
     func tapMenu(with tableShare: tableShare?, sender: Any) {
-        let views = NCShareCommon.sharedInstance.openViewMenuShareLink(view: self.view, tableShare: tableShare, metadata: metadata!)
-        shareLinkMenuView = views.shareLinkMenuView
-        shareLinkMenuViewWindow = views.viewWindow
-        
-        let tap = UITapGestureRecognizer(target: self, action: #selector(tapLinkMenuViewWindow))
-        tap.delegate = self
-        shareLinkMenuViewWindow?.addGestureRecognizer(tap)
+        guard let tableShare = tableShare else { return }
+
+        if tableShare.shareType == Int(shareTypeLink.rawValue) {
+            let views = NCShareCommon.sharedInstance.openViewMenuShareLink(view: self.view, tableShare: tableShare, metadata: metadata!)
+            shareLinkMenuView = views.shareLinkMenuView
+            shareMenuViewWindow = views.viewWindow
+            
+            let tap = UITapGestureRecognizer(target: self, action: #selector(tapLinkMenuViewWindow))
+            tap.delegate = self
+            shareMenuViewWindow?.addGestureRecognizer(tap)
+        } else {
+            let views = NCShareCommon.sharedInstance.openViewMenuUser(view: self.view, tableShare: tableShare, metadata: metadata!)
+            shareUserMenuView = views.shareUserMenuView
+            shareMenuViewWindow = views.viewWindow
+            
+            let tap = UITapGestureRecognizer(target: self, action: #selector(tapLinkMenuViewWindow))
+            tap.delegate = self
+            shareMenuViewWindow?.addGestureRecognizer(tap)
+        }
     }
     
     @objc func reloadData() {
@@ -389,7 +201,6 @@ extension NCShare: UITableViewDataSource {
                 cell.delegate = self
                 cell.labelTitle.text = tableShare.shareWith
                 NCShareCommon.sharedInstance.downloadAvatar(user: tableShare.shareWith, cell: cell)
-                
                 if UtilsFramework.isAnyPermission(toEdit: tableShare.permissions) {
                     cell.switchCanEdit.setOn(true, animated: false)
                 } else {
@@ -469,504 +280,3 @@ protocol NCShareUserCellDelegate {
     func switchCanEdit(with tableShare: tableShare?, switch: Bool, sender: Any)
 }
 
-// MARK: - ShareLinkMenuView
-
-class NCShareLinkMenuView: UIView, UIGestureRecognizerDelegate, NCShareNetworkingDelegate, FSCalendarDelegate, FSCalendarDelegateAppearance {
-    
-    @IBOutlet weak var switchAllowEditing: UISwitch!
-    @IBOutlet weak var labelAllowEditing: UILabel!
-    
-    @IBOutlet weak var switchHideDownload: UISwitch!
-    @IBOutlet weak var labelHideDownload: UILabel!
-    
-    @IBOutlet weak var switchPasswordProtect: UISwitch!
-    @IBOutlet weak var labelPasswordProtect: UILabel!
-    @IBOutlet weak var fieldPasswordProtect: UITextField!
-
-    @IBOutlet weak var switchSetExpirationDate: UISwitch!
-    @IBOutlet weak var labelSetExpirationDate: UILabel!
-    @IBOutlet weak var fieldSetExpirationDate: UITextField!
-    
-    @IBOutlet weak var imageNoteToRecipient: UIImageView!
-    @IBOutlet weak var labelNoteToRecipient: UILabel!
-    @IBOutlet weak var fieldNoteToRecipient: UITextField!
-
-    @IBOutlet weak var buttonDeleteShareLink: UIButton!
-    @IBOutlet weak var labelDeleteShareLink: UILabel!
-    @IBOutlet weak var imageDeleteShareLink: UIImageView!
-
-    @IBOutlet weak var buttonAddAnotherLink: UIButton!
-    @IBOutlet weak var labelAddAnotherLink: UILabel!
-    @IBOutlet weak var imageAddAnotherLink: UIImageView!
-
-    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
-
-    public let width: CGFloat = 250
-    public let height: CGFloat = 440
-    private var tableShare: tableShare?
-    public var metadata: tableMetadata?
-    
-    public var viewWindow: UIView?
-    public var viewWindowCalendar: UIView?
-    
-    override func awakeFromNib() {
-        
-        self.frame.size.width = width
-        self.frame.size.height = height
-
-        layer.borderColor = UIColor.lightGray.cgColor
-        layer.borderWidth = 0.5
-        layer.cornerRadius = 5
-        layer.masksToBounds = false
-        layer.shadowOffset = CGSize(width: 2, height: 2)
-        layer.shadowOpacity = 0.2
-        
-        switchAllowEditing.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
-        switchAllowEditing.onTintColor = NCBrandColor.sharedInstance.brand
-        switchHideDownload.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
-        switchHideDownload.onTintColor = NCBrandColor.sharedInstance.brand
-        switchPasswordProtect.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
-        switchPasswordProtect.onTintColor = NCBrandColor.sharedInstance.brand
-        switchSetExpirationDate.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
-        switchSetExpirationDate.onTintColor = NCBrandColor.sharedInstance.brand
-        
-        fieldSetExpirationDate.inputView = UIView()
-
-        imageNoteToRecipient.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "file_txt"), width: 100, height: 100, color: UIColor(red: 76/255, green: 76/255, blue: 76/255, alpha: 1))
-        imageDeleteShareLink.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "trash"), width: 100, height: 100, color: UIColor(red: 76/255, green: 76/255, blue: 76/255, alpha: 1))
-        imageAddAnotherLink.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "add"), width: 100, height: 100, color: UIColor(red: 76/255, green: 76/255, blue: 76/255, alpha: 1))
-    }
-    
-    func unLoad() {
-        viewWindowCalendar?.removeFromSuperview()
-        viewWindow?.removeFromSuperview()
-        
-        viewWindowCalendar = nil
-        viewWindow = nil
-    }
-    
-    func reloadData(idRemoteShared: Int) {
-        tableShare = NCManageDatabase.sharedInstance.getTableShare(account: metadata!.account, idRemoteShared: idRemoteShared)
-        
-        // Allow editing
-        if tableShare != nil && tableShare!.permissions > Int(k_read_share_permission) {
-            switchAllowEditing.setOn(true, animated: false)
-        } else {
-            switchAllowEditing.setOn(false, animated: false)
-        }
-        
-        // Hide download
-        if tableShare != nil && tableShare!.hideDownload {
-            switchHideDownload.setOn(true, animated: false)
-        } else {
-            switchHideDownload.setOn(false, animated: false)
-        }
-        
-        // Password protect
-        if tableShare != nil && tableShare!.shareWith.count > 0 {
-            switchPasswordProtect.setOn(true, animated: false)
-            fieldPasswordProtect.isEnabled = true
-            fieldPasswordProtect.text = tableShare!.shareWith
-        } else {
-            switchPasswordProtect.setOn(false, animated: false)
-            fieldPasswordProtect.isEnabled = false
-            fieldPasswordProtect.text = ""
-        }
-        
-        // Set expiration date
-        if tableShare != nil && tableShare!.expirationDate != nil {
-            switchSetExpirationDate.setOn(true, animated: false)
-            fieldSetExpirationDate.isEnabled = true
-
-            let dateFormatter = DateFormatter()
-            dateFormatter.formatterBehavior = .behavior10_4
-            dateFormatter.dateStyle = .medium
-            fieldSetExpirationDate.text = dateFormatter.string(from: tableShare!.expirationDate! as Date)
-        } else {
-            switchSetExpirationDate.setOn(false, animated: false)
-            fieldSetExpirationDate.isEnabled = false
-            fieldSetExpirationDate.text = ""
-        }
-        
-        // Note to recipient
-        if tableShare != nil {
-            fieldNoteToRecipient.text = tableShare!.note
-        } else {
-            fieldNoteToRecipient.text = ""
-        }
-    }
-    
-    // Allow editing
-    @IBAction func switchAllowEditingChanged(sender: UISwitch) {
-        
-        guard let tableShare = self.tableShare else { return }
-        
-        var permission = 0
-        if sender.isOn {
-            permission = Int(k_read_share_permission) + Int(k_update_share_permission)
-        } else {
-            permission = Int(k_read_share_permission)
-        }
-        
-        let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
-        networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: nil, permission: permission, note: nil, expirationTime: nil, hideDownload: tableShare.hideDownload)
-    }
-    
-    // Hide download
-    @IBAction func switchHideDownloadChanged(sender: UISwitch) {
-        
-        guard let tableShare = self.tableShare else { return }
-        
-        let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
-        networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: nil, permission: 0, note: nil, expirationTime: nil, hideDownload: sender.isOn)
-    }
-    
-    // Password protect
-    @IBAction func switchPasswordProtectChanged(sender: UISwitch) {
-        
-        guard let tableShare = self.tableShare else { return }
-        
-        if sender.isOn {
-            fieldPasswordProtect.isEnabled = true
-            fieldPasswordProtect.text = ""
-            fieldPasswordProtect.becomeFirstResponder()
-        } else {
-            let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
-            networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: "", permission: 0, note: nil, expirationTime: nil, hideDownload: tableShare.hideDownload)
-        }
-    }
-    
-    @IBAction func fieldPasswordProtectDidEndOnExit(textField: UITextField) {
-        
-        guard let tableShare = self.tableShare else { return }
-        
-        let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
-        networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: fieldPasswordProtect.text, permission: 0, note: nil, expirationTime: nil, hideDownload: tableShare.hideDownload)
-    }
-    
-    // Set expiration date
-    @IBAction func switchSetExpirationDate(sender: UISwitch) {
-        
-        guard let tableShare = self.tableShare else { return }
-        
-        if sender.isOn {
-            fieldSetExpirationDate.isEnabled = true
-            fieldSetExpirationDate(sender: fieldSetExpirationDate)
-        } else {
-            let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
-            networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: nil, permission: 0, note: nil, expirationTime: "", hideDownload: tableShare.hideDownload)
-        }
-    }
-    
-    @IBAction func fieldSetExpirationDate(sender: UITextField) {
-        
-        let calendar = NCShareCommon.sharedInstance.openCalendar(view: self, width: width, height: height)
-        calendar.calendarView.delegate = self
-        viewWindowCalendar = calendar.viewWindow
-    }
-    
-    // Note to recipient
-    @IBAction func fieldNoteToRecipientDidEndOnExit(textField: UITextField) {
-
-        guard let tableShare = self.tableShare else { return }
-        if fieldNoteToRecipient.text == nil { return }
-        
-        let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
-        networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: nil, permission: 0, note: fieldNoteToRecipient.text, expirationTime: nil, hideDownload: tableShare.hideDownload)
-    }
-    
-    // Delete share link
-    @IBAction func buttonDeleteShareLink(sender: UIButton) {
-        
-        guard let tableShare = self.tableShare else { return }
-        let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
-
-        networking.unShare(idRemoteShared: tableShare.idRemoteShared)
-    }
-    
-    // Add another link
-    @IBAction func buttonAddAnotherLink(sender: UIButton) {
-        
-        let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
-        
-        networking.share(metadata: metadata!, password: "", permission: 1, hideDownload: false)
-    }
-    
-    // delegate networking
-    
-    func readShareCompleted(errorCode: Int) {
-        reloadData(idRemoteShared: tableShare?.idRemoteShared ?? 0)
-    }
-    
-    func shareCompleted(errorCode: Int) {
-        unLoad()
-        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadDataNCShare"), object: nil, userInfo: nil)
-    }
-    
-    func unShareCompleted() {
-        unLoad()
-        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadDataNCShare"), object: nil, userInfo: nil)
-    }
-    
-    func updateShareWithError(idRemoteShared: Int) {
-        reloadData(idRemoteShared: idRemoteShared)
-    }
-    
-    // delegate/appearance calendar
-    func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
-        
-        if monthPosition == .previous || monthPosition == .next {
-            calendar.setCurrentPage(date, animated: true)
-        } else {
-            let dateFormatter = DateFormatter()
-            dateFormatter.formatterBehavior = .behavior10_4
-            dateFormatter.dateStyle = .medium
-            fieldSetExpirationDate.text = dateFormatter.string(from:date)
-            fieldSetExpirationDate.endEditing(true)
-            
-            viewWindowCalendar?.removeFromSuperview()
-            
-            guard let tableShare = self.tableShare else { return }
-
-            let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
-            dateFormatter.dateFormat = "YYYY-MM-dd"
-            let expirationTime = dateFormatter.string(from: date)
-            networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: nil, permission: 0, note: nil, expirationTime: expirationTime, hideDownload: tableShare.hideDownload)
-        }
-    }
-    
-    func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
-        return date > Date()
-    }
-    
-    func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, titleDefaultColorFor date: Date) -> UIColor? {
-        if date > Date() {
-            return UIColor(red: 60/255, green: 60/255, blue: 60/255, alpha: 1)
-        } else {
-            return UIColor(red: 190/255, green: 190/255, blue: 190/255, alpha: 1)
-        }
-    }
-}
-
-// --------------------------------------------------------------------------------------------
-// ===== Common =====
-// --------------------------------------------------------------------------------------------
-
-class NCShareCommon: NSObject {
-    @objc static let sharedInstance: NCShareCommon = {
-        let instance = NCShareCommon()
-        return instance
-    }()
-    
-    func createLinkAvatar() -> UIImage? {
-        
-        let size: CGFloat = 200
-        
-        let bottomImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "circle"), width: size, height: size, color: NCBrandColor.sharedInstance.brand)
-        let topImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "sharebylink"), width: size, height: size, color: UIColor.white)
-        UIGraphicsBeginImageContextWithOptions(CGSize(width: size, height: size), false, 0.0)
-        bottomImage?.draw(in: CGRect(origin: CGPoint.zero, size: CGSize(width: size, height: size)))
-        topImage?.draw(in: CGRect(origin:  CGPoint(x: size/4, y: size/4), size: CGSize(width: size/2, height: size/2)))
-        let image = UIGraphicsGetImageFromCurrentImageContext()
-        UIGraphicsEndImageContext()
-        
-        return image
-    }
-    
-    func downloadAvatar(user: String, cell: NCShareUserCell) {
-        
-        let appDelegate = UIApplication.shared.delegate as! AppDelegate
-        let fileNameLocalPath = CCUtility.getDirectoryUserData() + "/" + CCUtility.getStringUser(appDelegate.activeUser, activeUrl: appDelegate.activeUrl) + "-" + user + ".png"
-        
-        if FileManager.default.fileExists(atPath: fileNameLocalPath) {
-            if let image = UIImage(contentsOfFile: fileNameLocalPath) {
-                cell.imageItem.image = image
-            }
-        } else {
-            DispatchQueue.global().async {
-                let url = appDelegate.activeUrl + k_avatar + user + "/128"
-                let encodedString = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
-                OCNetworking.sharedManager()?.downloadContents(ofUrl: encodedString, completion: { (data, message, errorCode) in
-                    if errorCode == 0 {
-                        do {
-                            try data!.write(to: NSURL(fileURLWithPath: fileNameLocalPath) as URL, options: .atomic)
-                        } catch { return }
-                        cell.imageItem.image = UIImage(data: data!)
-                    }
-                })
-            }
-        }
-    }
-    
-    func openViewMenuShareLink(view: UIView, tableShare: tableShare?, metadata: tableMetadata) -> (shareLinkMenuView: NCShareLinkMenuView, viewWindow: UIView) {
-        
-        let globalPoint = view.superview?.convert(view.frame.origin, to: nil)
-        
-        let window = UIApplication.shared.keyWindow!
-        let viewWindow = UIView(frame: window.bounds)
-        window.addSubview(viewWindow)
-        
-        let shareLinkMenuView = Bundle.main.loadNibNamed("NCShareLinkMenuView", owner: self, options: nil)?.first as! NCShareLinkMenuView
-        shareLinkMenuView.metadata = metadata
-        shareLinkMenuView.viewWindow = viewWindow
-        shareLinkMenuView.reloadData(idRemoteShared: tableShare?.idRemoteShared ?? 0)
-        let shareLinkMenuViewX = view.bounds.width/2 - shareLinkMenuView.frame.width/2 + globalPoint!.x
-        let shareLinkMenuViewY = globalPoint!.y + 10
-       
-        shareLinkMenuView.frame = CGRect(x: shareLinkMenuViewX, y: shareLinkMenuViewY, width: shareLinkMenuView.width, height: shareLinkMenuView.height)
-        viewWindow.addSubview(shareLinkMenuView)
-        
-        return(shareLinkMenuView: shareLinkMenuView, viewWindow: viewWindow)
-    }
-    
-    func openCalendar(view: UIView, width: CGFloat, height: CGFloat) -> (calendarView: FSCalendar, viewWindow: UIView) {
-        
-        let globalPoint = view.superview?.convert(view.frame.origin, to: nil)
-
-        let window = UIApplication.shared.keyWindow!
-        let viewWindow = UIView(frame: window.bounds)
-        window.addSubview(viewWindow)
-        
-        let calendar = FSCalendar(frame: CGRect(x: globalPoint!.x + 10, y: globalPoint!.y + 100, width: width - 20, height: 300))
-        
-        calendar.backgroundColor = .white
-        calendar.placeholderType = .none
-        calendar.appearance.headerMinimumDissolvedAlpha = 0.0
-
-        calendar.layer.borderColor = UIColor.lightGray.cgColor
-        calendar.layer.borderWidth = 0.5
-        calendar.layer.masksToBounds = false
-        calendar.layer.cornerRadius = 5
-        calendar.layer.masksToBounds = false
-        calendar.layer.shadowOffset = CGSize(width: 2, height: 2)
-        calendar.layer.shadowOpacity = 0.2
-        
-        calendar.appearance.headerTitleColor = .black
-        calendar.appearance.headerTitleFont = UIFont.systemFont(ofSize: 13)
-        
-        calendar.appearance.weekdayTextColor = UIColor(red: 100/255, green: 100/255, blue: 100/255, alpha: 1)
-        calendar.appearance.weekdayFont = UIFont.systemFont(ofSize: 12)
-        
-        calendar.appearance.todayColor = NCBrandColor.sharedInstance.brand
-        calendar.appearance.titleFont = UIFont.systemFont(ofSize: 12)
-        
-        viewWindow.addSubview(calendar)
-        
-        return(calendarView: calendar, viewWindow: viewWindow)
-    }
-    
-    func copyLink(tableShare: tableShare?, viewController: UIViewController) {
-        
-        let appDelegate = UIApplication.shared.delegate as! AppDelegate
-        var url: String = ""
-        
-        guard let tableShare = tableShare else { return }
-        
-        if tableShare.token.hasPrefix("http://") || tableShare.token.hasPrefix("https://") {
-            url = tableShare.token
-        } else if tableShare.url != "" {
-            url = tableShare.url
-        } else {
-            url = appDelegate.activeUrl + "/" + k_share_link_middle_part_url_after_version_8 + tableShare.token
-        }
-        
-        if let name = URL(string: url), !name.absoluteString.isEmpty {
-            let objectsToShare = [name]
-            
-            let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
-            viewController.present(activityVC, animated: true, completion: nil)
-        }
-    }
-}
-
-// --------------------------------------------------------------------------------------------
-// ===== Networking =====
-// --------------------------------------------------------------------------------------------
-
-class NCShareNetworking: NSObject {
-
-    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
-    
-    var account: String
-    var activeUrl: String
-    var delegate: NCShareNetworkingDelegate?
-    var view: UIView?
-    
-    init(account: String, activeUrl: String, view: UIView?, delegate: NCShareNetworkingDelegate?) {
-        self.account = account
-        self.activeUrl = activeUrl
-        self.view = view
-        self.delegate = delegate
-        
-        super.init()
-    }
-    
-    func readShare() {
-        NCUtility.sharedInstance.startActivityIndicator(view: view, bottom: 0)
-        OCNetworking.sharedManager()?.readShare(withAccount: account, completion: { (account, items, message, errorCode) in
-            NCUtility.sharedInstance.stopActivityIndicator()
-            if errorCode == 0 {
-                let itemsOCSharedDto = items as! [OCSharedDto]
-                NCManageDatabase.sharedInstance.addShare(account: self.account, activeUrl: self.activeUrl, items: itemsOCSharedDto)
-            } else {
-                self.appDelegate.messageNotification("_share_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
-            }
-            self.delegate?.readShareCompleted(errorCode: errorCode)
-        })
-    }
-    
-    func share(metadata: tableMetadata, password: String, permission: Int, hideDownload: Bool) {
-        NCUtility.sharedInstance.startActivityIndicator(view: view, bottom: 0)
-        let fileName = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, activeUrl: activeUrl)!
-        OCNetworking.sharedManager()?.share(withAccount: metadata.account, fileName: fileName, password: password, permission: permission, hideDownload: hideDownload, completion: { (account, message, errorCode) in
-            if errorCode == 0 {
-                OCNetworking.sharedManager()?.readShare(withAccount: account, completion: { (account, items, message, errorCode) in
-                    NCUtility.sharedInstance.stopActivityIndicator()
-                    if errorCode == 0 {
-                        let itemsOCSharedDto = items as! [OCSharedDto]
-                        NCManageDatabase.sharedInstance.addShare(account: self.account, activeUrl: self.activeUrl, items: itemsOCSharedDto)
-                    } else {
-                        self.appDelegate.messageNotification("_share_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
-                    }
-                    self.delegate?.shareCompleted(errorCode: errorCode)
-                })
-            } else {
-                NCUtility.sharedInstance.stopActivityIndicator()
-                self.appDelegate.messageNotification("_share_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
-            }
-        })
-    }
-    
-    func unShare(idRemoteShared: Int) {
-        NCUtility.sharedInstance.startActivityIndicator(view: view, bottom: 0)
-        OCNetworking.sharedManager()?.unshareAccount(account, shareID: idRemoteShared, completion: { (account, message, errorCode) in
-            NCUtility.sharedInstance.stopActivityIndicator()
-            if errorCode == 0 {
-                NCManageDatabase.sharedInstance.deleteTableShare(account: account!, idRemoteShared: idRemoteShared)
-                self.delegate?.unShareCompleted()
-            } else {
-                self.appDelegate.messageNotification("_share_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
-            }
-        })
-    }
-    
-    func updateShare(idRemoteShared: Int, password: String?, permission: Int, note: String?, expirationTime: String?, hideDownload: Bool) {
-        NCUtility.sharedInstance.startActivityIndicator(view: view, bottom: 0)
-        OCNetworking.sharedManager()?.shareUpdateAccount(account, shareID: idRemoteShared, password: password, note:note, permission: permission, expirationTime: expirationTime, hideDownload: hideDownload, completion: { (account, message, errorCode) in
-            NCUtility.sharedInstance.stopActivityIndicator()
-            if errorCode == 0 {
-                self.readShare()
-            } else {
-                self.appDelegate.messageNotification("_share_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
-                self.delegate?.updateShareWithError(idRemoteShared: idRemoteShared)
-            }
-        })
-    }
-}
-
-protocol NCShareNetworkingDelegate {
-    func readShareCompleted(errorCode: Int)
-    func shareCompleted(errorCode: Int)
-    func unShareCompleted()
-    func updateShareWithError(idRemoteShared: Int)
-}

+ 172 - 0
iOSClient/Share/NCShareCommon.swift

@@ -0,0 +1,172 @@
+//
+//  NCShareCommon.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 25/07/2019.
+//  Copyright © 2019 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  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 Foundation
+import FSCalendar
+
+class NCShareCommon: NSObject {
+    @objc static let sharedInstance: NCShareCommon = {
+        let instance = NCShareCommon()
+        return instance
+    }()
+    
+    func createLinkAvatar() -> UIImage? {
+        
+        let size: CGFloat = 200
+        
+        let bottomImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "circle"), width: size, height: size, color: NCBrandColor.sharedInstance.brand)
+        let topImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "sharebylink"), width: size, height: size, color: UIColor.white)
+        UIGraphicsBeginImageContextWithOptions(CGSize(width: size, height: size), false, 0.0)
+        bottomImage?.draw(in: CGRect(origin: CGPoint.zero, size: CGSize(width: size, height: size)))
+        topImage?.draw(in: CGRect(origin:  CGPoint(x: size/4, y: size/4), size: CGSize(width: size/2, height: size/2)))
+        let image = UIGraphicsGetImageFromCurrentImageContext()
+        UIGraphicsEndImageContext()
+        
+        return image
+    }
+    
+    func downloadAvatar(user: String, cell: NCShareUserCell) {
+        
+        let appDelegate = UIApplication.shared.delegate as! AppDelegate
+        let fileNameLocalPath = CCUtility.getDirectoryUserData() + "/" + CCUtility.getStringUser(appDelegate.activeUser, activeUrl: appDelegate.activeUrl) + "-" + user + ".png"
+        
+        if FileManager.default.fileExists(atPath: fileNameLocalPath) {
+            if let image = UIImage(contentsOfFile: fileNameLocalPath) {
+                cell.imageItem.image = image
+            }
+        } else {
+            DispatchQueue.global().async {
+                let url = appDelegate.activeUrl + k_avatar + user + "/128"
+                let encodedString = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
+                OCNetworking.sharedManager()?.downloadContents(ofUrl: encodedString, completion: { (data, message, errorCode) in
+                    if errorCode == 0 {
+                        do {
+                            try data!.write(to: NSURL(fileURLWithPath: fileNameLocalPath) as URL, options: .atomic)
+                        } catch { return }
+                        cell.imageItem.image = UIImage(data: data!)
+                    }
+                })
+            }
+        }
+    }
+    
+    func openViewMenuShareLink(view: UIView, tableShare: tableShare?, metadata: tableMetadata) -> (shareLinkMenuView: NCShareLinkMenuView, viewWindow: UIView) {
+        
+        let globalPoint = view.superview?.convert(view.frame.origin, to: nil)
+        
+        let window = UIApplication.shared.keyWindow!
+        let viewWindow = UIView(frame: window.bounds)
+        window.addSubview(viewWindow)
+        
+        let shareLinkMenuView = Bundle.main.loadNibNamed("NCShareLinkMenuView", owner: self, options: nil)?.first as! NCShareLinkMenuView
+        shareLinkMenuView.metadata = metadata
+        shareLinkMenuView.viewWindow = viewWindow
+        shareLinkMenuView.reloadData(idRemoteShared: tableShare?.idRemoteShared ?? 0)
+        let shareLinkMenuViewX = view.bounds.width/2 - shareLinkMenuView.frame.width/2 + globalPoint!.x
+        let shareLinkMenuViewY = globalPoint!.y + 10
+        
+        shareLinkMenuView.frame = CGRect(x: shareLinkMenuViewX, y: shareLinkMenuViewY, width: shareLinkMenuView.width, height: shareLinkMenuView.height)
+        viewWindow.addSubview(shareLinkMenuView)
+        
+        return(shareLinkMenuView: shareLinkMenuView, viewWindow: viewWindow)
+    }
+    
+    func openViewMenuUser(view: UIView, tableShare: tableShare?, metadata: tableMetadata) -> (shareUserMenuView: NCShareUserMenuView, viewWindow: UIView) {
+        
+        let globalPoint = view.superview?.convert(view.frame.origin, to: nil)
+        
+        let window = UIApplication.shared.keyWindow!
+        let viewWindow = UIView(frame: window.bounds)
+        window.addSubview(viewWindow)
+        
+        let shareUserMenuView = Bundle.main.loadNibNamed("NCShareUserMenuView", owner: self, options: nil)?.first as! NCShareUserMenuView
+        shareUserMenuView.metadata = metadata
+        shareUserMenuView.viewWindow = viewWindow
+        shareUserMenuView.reloadData(idRemoteShared: tableShare?.idRemoteShared ?? 0)
+        let shareUserMenuViewX = view.bounds.width/2 - shareUserMenuView.frame.width/2 + globalPoint!.x
+        let shareUserMenuViewY = globalPoint!.y + 10
+        
+        shareUserMenuView.frame = CGRect(x: shareUserMenuViewX, y: shareUserMenuViewY, width: shareUserMenuView.width, height: shareUserMenuView.height)
+        viewWindow.addSubview(shareUserMenuView)
+        
+        return(shareUserMenuView: shareUserMenuView, viewWindow: viewWindow)
+    }
+    
+    func openCalendar(view: UIView, width: CGFloat, height: CGFloat) -> (calendarView: FSCalendar, viewWindow: UIView) {
+        
+        let globalPoint = view.superview?.convert(view.frame.origin, to: nil)
+        
+        let window = UIApplication.shared.keyWindow!
+        let viewWindow = UIView(frame: window.bounds)
+        window.addSubview(viewWindow)
+        
+        let calendar = FSCalendar(frame: CGRect(x: globalPoint!.x + 10, y: globalPoint!.y + 100, width: width - 20, height: 300))
+        
+        calendar.backgroundColor = .white
+        calendar.placeholderType = .none
+        calendar.appearance.headerMinimumDissolvedAlpha = 0.0
+        
+        calendar.layer.borderColor = UIColor.lightGray.cgColor
+        calendar.layer.borderWidth = 0.5
+        calendar.layer.masksToBounds = false
+        calendar.layer.cornerRadius = 5
+        calendar.layer.masksToBounds = false
+        calendar.layer.shadowOffset = CGSize(width: 2, height: 2)
+        calendar.layer.shadowOpacity = 0.2
+        
+        calendar.appearance.headerTitleColor = .black
+        calendar.appearance.headerTitleFont = UIFont.systemFont(ofSize: 13)
+        
+        calendar.appearance.weekdayTextColor = UIColor(red: 100/255, green: 100/255, blue: 100/255, alpha: 1)
+        calendar.appearance.weekdayFont = UIFont.systemFont(ofSize: 12)
+        
+        calendar.appearance.todayColor = NCBrandColor.sharedInstance.brand
+        calendar.appearance.titleFont = UIFont.systemFont(ofSize: 12)
+        
+        viewWindow.addSubview(calendar)
+        
+        return(calendarView: calendar, viewWindow: viewWindow)
+    }
+    
+    func copyLink(tableShare: tableShare?, viewController: UIViewController) {
+        
+        let appDelegate = UIApplication.shared.delegate as! AppDelegate
+        var url: String = ""
+        
+        guard let tableShare = tableShare else { return }
+        
+        if tableShare.token.hasPrefix("http://") || tableShare.token.hasPrefix("https://") {
+            url = tableShare.token
+        } else if tableShare.url != "" {
+            url = tableShare.url
+        } else {
+            url = appDelegate.activeUrl + "/" + k_share_link_middle_part_url_after_version_8 + tableShare.token
+        }
+        
+        if let name = URL(string: url), !name.absoluteString.isEmpty {
+            let objectsToShare = [name]
+            
+            let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
+            viewController.present(activityVC, animated: true, completion: nil)
+        }
+    }
+}

+ 301 - 0
iOSClient/Share/NCShareLinkMenuView.swift

@@ -0,0 +1,301 @@
+//
+//  NCShareLinkMenuView.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 25/07/2019.
+//  Copyright © 2019 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  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 Foundation
+import FSCalendar
+
+class NCShareLinkMenuView: UIView, UIGestureRecognizerDelegate, NCShareNetworkingDelegate, FSCalendarDelegate, FSCalendarDelegateAppearance {
+    
+    @IBOutlet weak var switchAllowEditing: UISwitch!
+    @IBOutlet weak var labelAllowEditing: UILabel!
+    
+    @IBOutlet weak var switchHideDownload: UISwitch!
+    @IBOutlet weak var labelHideDownload: UILabel!
+    
+    @IBOutlet weak var switchPasswordProtect: UISwitch!
+    @IBOutlet weak var labelPasswordProtect: UILabel!
+    @IBOutlet weak var fieldPasswordProtect: UITextField!
+    
+    @IBOutlet weak var switchSetExpirationDate: UISwitch!
+    @IBOutlet weak var labelSetExpirationDate: UILabel!
+    @IBOutlet weak var fieldSetExpirationDate: UITextField!
+    
+    @IBOutlet weak var imageNoteToRecipient: UIImageView!
+    @IBOutlet weak var labelNoteToRecipient: UILabel!
+    @IBOutlet weak var fieldNoteToRecipient: UITextField!
+    
+    @IBOutlet weak var buttonDeleteShareLink: UIButton!
+    @IBOutlet weak var labelDeleteShareLink: UILabel!
+    @IBOutlet weak var imageDeleteShareLink: UIImageView!
+    
+    @IBOutlet weak var buttonAddAnotherLink: UIButton!
+    @IBOutlet weak var labelAddAnotherLink: UILabel!
+    @IBOutlet weak var imageAddAnotherLink: UIImageView!
+    
+    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
+    
+    public let width: CGFloat = 250
+    public let height: CGFloat = 440
+    private var tableShare: tableShare?
+    public var metadata: tableMetadata?
+    
+    public var viewWindow: UIView?
+    public var viewWindowCalendar: UIView?
+    
+    override func awakeFromNib() {
+        
+        self.frame.size.width = width
+        self.frame.size.height = height
+        
+        layer.borderColor = UIColor.lightGray.cgColor
+        layer.borderWidth = 0.5
+        layer.cornerRadius = 5
+        layer.masksToBounds = false
+        layer.shadowOffset = CGSize(width: 2, height: 2)
+        layer.shadowOpacity = 0.2
+        
+        switchAllowEditing.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
+        switchAllowEditing.onTintColor = NCBrandColor.sharedInstance.brand
+        switchHideDownload.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
+        switchHideDownload.onTintColor = NCBrandColor.sharedInstance.brand
+        switchPasswordProtect.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
+        switchPasswordProtect.onTintColor = NCBrandColor.sharedInstance.brand
+        switchSetExpirationDate.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
+        switchSetExpirationDate.onTintColor = NCBrandColor.sharedInstance.brand
+        
+        fieldSetExpirationDate.inputView = UIView()
+        
+        imageNoteToRecipient.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "file_txt"), width: 100, height: 100, color: UIColor(red: 76/255, green: 76/255, blue: 76/255, alpha: 1))
+        imageDeleteShareLink.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "trash"), width: 100, height: 100, color: UIColor(red: 76/255, green: 76/255, blue: 76/255, alpha: 1))
+        imageAddAnotherLink.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "add"), width: 100, height: 100, color: UIColor(red: 76/255, green: 76/255, blue: 76/255, alpha: 1))
+    }
+    
+    func unLoad() {
+        viewWindowCalendar?.removeFromSuperview()
+        viewWindow?.removeFromSuperview()
+        
+        viewWindowCalendar = nil
+        viewWindow = nil
+    }
+    
+    func reloadData(idRemoteShared: Int) {
+        tableShare = NCManageDatabase.sharedInstance.getTableShare(account: metadata!.account, idRemoteShared: idRemoteShared)
+        
+        // Allow editing
+        if tableShare != nil && tableShare!.permissions > Int(k_read_share_permission) {
+            switchAllowEditing.setOn(true, animated: false)
+        } else {
+            switchAllowEditing.setOn(false, animated: false)
+        }
+        
+        // Hide download
+        if tableShare != nil && tableShare!.hideDownload {
+            switchHideDownload.setOn(true, animated: false)
+        } else {
+            switchHideDownload.setOn(false, animated: false)
+        }
+        
+        // Password protect
+        if tableShare != nil && tableShare!.shareWith.count > 0 {
+            switchPasswordProtect.setOn(true, animated: false)
+            fieldPasswordProtect.isEnabled = true
+            fieldPasswordProtect.text = tableShare!.shareWith
+        } else {
+            switchPasswordProtect.setOn(false, animated: false)
+            fieldPasswordProtect.isEnabled = false
+            fieldPasswordProtect.text = ""
+        }
+        
+        // Set expiration date
+        if tableShare != nil && tableShare!.expirationDate != nil {
+            switchSetExpirationDate.setOn(true, animated: false)
+            fieldSetExpirationDate.isEnabled = true
+            
+            let dateFormatter = DateFormatter()
+            dateFormatter.formatterBehavior = .behavior10_4
+            dateFormatter.dateStyle = .medium
+            fieldSetExpirationDate.text = dateFormatter.string(from: tableShare!.expirationDate! as Date)
+        } else {
+            switchSetExpirationDate.setOn(false, animated: false)
+            fieldSetExpirationDate.isEnabled = false
+            fieldSetExpirationDate.text = ""
+        }
+        
+        // Note to recipient
+        if tableShare != nil {
+            fieldNoteToRecipient.text = tableShare!.note
+        } else {
+            fieldNoteToRecipient.text = ""
+        }
+    }
+    
+    // Allow editing
+    @IBAction func switchAllowEditingChanged(sender: UISwitch) {
+        
+        guard let tableShare = self.tableShare else { return }
+        
+        var permission = 0
+        if sender.isOn {
+            permission = Int(k_read_share_permission) + Int(k_update_share_permission)
+        } else {
+            permission = Int(k_read_share_permission)
+        }
+        
+        let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
+        networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: nil, permission: permission, note: nil, expirationTime: nil, hideDownload: tableShare.hideDownload)
+    }
+    
+    // Hide download
+    @IBAction func switchHideDownloadChanged(sender: UISwitch) {
+        
+        guard let tableShare = self.tableShare else { return }
+        
+        let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
+        networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: nil, permission: 0, note: nil, expirationTime: nil, hideDownload: sender.isOn)
+    }
+    
+    // Password protect
+    @IBAction func switchPasswordProtectChanged(sender: UISwitch) {
+        
+        guard let tableShare = self.tableShare else { return }
+        
+        if sender.isOn {
+            fieldPasswordProtect.isEnabled = true
+            fieldPasswordProtect.text = ""
+            fieldPasswordProtect.becomeFirstResponder()
+        } else {
+            let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
+            networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: "", permission: 0, note: nil, expirationTime: nil, hideDownload: tableShare.hideDownload)
+        }
+    }
+    
+    @IBAction func fieldPasswordProtectDidEndOnExit(textField: UITextField) {
+        
+        guard let tableShare = self.tableShare else { return }
+        
+        let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
+        networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: fieldPasswordProtect.text, permission: 0, note: nil, expirationTime: nil, hideDownload: tableShare.hideDownload)
+    }
+    
+    // Set expiration date
+    @IBAction func switchSetExpirationDate(sender: UISwitch) {
+        
+        guard let tableShare = self.tableShare else { return }
+        
+        if sender.isOn {
+            fieldSetExpirationDate.isEnabled = true
+            fieldSetExpirationDate(sender: fieldSetExpirationDate)
+        } else {
+            let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
+            networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: nil, permission: 0, note: nil, expirationTime: "", hideDownload: tableShare.hideDownload)
+        }
+    }
+    
+    @IBAction func fieldSetExpirationDate(sender: UITextField) {
+        
+        let calendar = NCShareCommon.sharedInstance.openCalendar(view: self, width: width, height: height)
+        calendar.calendarView.delegate = self
+        viewWindowCalendar = calendar.viewWindow
+    }
+    
+    // Note to recipient
+    @IBAction func fieldNoteToRecipientDidEndOnExit(textField: UITextField) {
+        
+        guard let tableShare = self.tableShare else { return }
+        if fieldNoteToRecipient.text == nil { return }
+        
+        let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
+        networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: nil, permission: 0, note: fieldNoteToRecipient.text, expirationTime: nil, hideDownload: tableShare.hideDownload)
+    }
+    
+    // Delete share link
+    @IBAction func buttonDeleteShareLink(sender: UIButton) {
+        
+        guard let tableShare = self.tableShare else { return }
+        let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
+        
+        networking.unShare(idRemoteShared: tableShare.idRemoteShared)
+    }
+    
+    // Add another link
+    @IBAction func buttonAddAnotherLink(sender: UIButton) {
+        
+        let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
+        
+        networking.share(metadata: metadata!, password: "", permission: 1, hideDownload: false)
+    }
+    
+    // delegate networking
+    
+    func readShareCompleted(errorCode: Int) {
+        reloadData(idRemoteShared: tableShare?.idRemoteShared ?? 0)
+    }
+    
+    func shareCompleted(errorCode: Int) {
+        unLoad()
+        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadDataNCShare"), object: nil, userInfo: nil)
+    }
+    
+    func unShareCompleted() {
+        unLoad()
+        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadDataNCShare"), object: nil, userInfo: nil)
+    }
+    
+    func updateShareWithError(idRemoteShared: Int) {
+        reloadData(idRemoteShared: idRemoteShared)
+    }
+    
+    // delegate/appearance calendar
+    func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
+        
+        if monthPosition == .previous || monthPosition == .next {
+            calendar.setCurrentPage(date, animated: true)
+        } else {
+            let dateFormatter = DateFormatter()
+            dateFormatter.formatterBehavior = .behavior10_4
+            dateFormatter.dateStyle = .medium
+            fieldSetExpirationDate.text = dateFormatter.string(from:date)
+            fieldSetExpirationDate.endEditing(true)
+            
+            viewWindowCalendar?.removeFromSuperview()
+            
+            guard let tableShare = self.tableShare else { return }
+            
+            let networking = NCShareNetworking.init(account: metadata!.account, activeUrl: appDelegate.activeUrl,  view: self, delegate: self)
+            dateFormatter.dateFormat = "YYYY-MM-dd"
+            let expirationTime = dateFormatter.string(from: date)
+            networking.updateShare(idRemoteShared: tableShare.idRemoteShared, password: nil, permission: 0, note: nil, expirationTime: expirationTime, hideDownload: tableShare.hideDownload)
+        }
+    }
+    
+    func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
+        return date > Date()
+    }
+    
+    func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, titleDefaultColorFor date: Date) -> UIColor? {
+        if date > Date() {
+            return UIColor(red: 60/255, green: 60/255, blue: 60/255, alpha: 1)
+        } else {
+            return UIColor(red: 190/255, green: 190/255, blue: 190/255, alpha: 1)
+        }
+    }
+}

+ 111 - 0
iOSClient/Share/NCShareNetworking.swift

@@ -0,0 +1,111 @@
+//
+//  NCShareNetworking.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 25/07/2019.
+//  Copyright © 2019 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  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 Foundation
+
+class NCShareNetworking: NSObject {
+    
+    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
+    
+    var account: String
+    var activeUrl: String
+    var delegate: NCShareNetworkingDelegate?
+    var view: UIView?
+    
+    init(account: String, activeUrl: String, view: UIView?, delegate: NCShareNetworkingDelegate?) {
+        self.account = account
+        self.activeUrl = activeUrl
+        self.view = view
+        self.delegate = delegate
+        
+        super.init()
+    }
+    
+    func readShare() {
+        NCUtility.sharedInstance.startActivityIndicator(view: view, bottom: 0)
+        OCNetworking.sharedManager()?.readShare(withAccount: account, completion: { (account, items, message, errorCode) in
+            NCUtility.sharedInstance.stopActivityIndicator()
+            if errorCode == 0 {
+                let itemsOCSharedDto = items as! [OCSharedDto]
+                NCManageDatabase.sharedInstance.addShare(account: self.account, activeUrl: self.activeUrl, items: itemsOCSharedDto)
+            } else {
+                self.appDelegate.messageNotification("_share_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
+            }
+            self.delegate?.readShareCompleted(errorCode: errorCode)
+        })
+    }
+    
+    func share(metadata: tableMetadata, password: String, permission: Int, hideDownload: Bool) {
+        NCUtility.sharedInstance.startActivityIndicator(view: view, bottom: 0)
+        let fileName = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, activeUrl: activeUrl)!
+        OCNetworking.sharedManager()?.share(withAccount: metadata.account, fileName: fileName, password: password, permission: permission, hideDownload: hideDownload, completion: { (account, message, errorCode) in
+            if errorCode == 0 {
+                OCNetworking.sharedManager()?.readShare(withAccount: account, completion: { (account, items, message, errorCode) in
+                    NCUtility.sharedInstance.stopActivityIndicator()
+                    if errorCode == 0 {
+                        let itemsOCSharedDto = items as! [OCSharedDto]
+                        NCManageDatabase.sharedInstance.addShare(account: self.account, activeUrl: self.activeUrl, items: itemsOCSharedDto)
+                    } else {
+                        self.appDelegate.messageNotification("_share_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
+                    }
+                    self.delegate?.shareCompleted(errorCode: errorCode)
+                })
+            } else {
+                NCUtility.sharedInstance.stopActivityIndicator()
+                self.appDelegate.messageNotification("_share_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
+            }
+        })
+    }
+    
+    func unShare(idRemoteShared: Int) {
+        NCUtility.sharedInstance.startActivityIndicator(view: view, bottom: 0)
+        OCNetworking.sharedManager()?.unshareAccount(account, shareID: idRemoteShared, completion: { (account, message, errorCode) in
+            NCUtility.sharedInstance.stopActivityIndicator()
+            if errorCode == 0 {
+                NCManageDatabase.sharedInstance.deleteTableShare(account: account!, idRemoteShared: idRemoteShared)
+                self.delegate?.unShareCompleted()
+            } else {
+                self.appDelegate.messageNotification("_share_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
+            }
+        })
+    }
+    
+    func updateShare(idRemoteShared: Int, password: String?, permission: Int, note: String?, expirationTime: String?, hideDownload: Bool) {
+        NCUtility.sharedInstance.startActivityIndicator(view: view, bottom: 0)
+        OCNetworking.sharedManager()?.shareUpdateAccount(account, shareID: idRemoteShared, password: password, note:note, permission: permission, expirationTime: expirationTime, hideDownload: hideDownload, completion: { (account, message, errorCode) in
+            NCUtility.sharedInstance.stopActivityIndicator()
+            if errorCode == 0 {
+                self.readShare()
+            } else {
+                self.appDelegate.messageNotification("_share_", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
+                self.delegate?.updateShareWithError(idRemoteShared: idRemoteShared)
+            }
+        })
+    }
+}
+
+protocol NCShareNetworkingDelegate {
+    func readShareCompleted(errorCode: Int)
+    func shareCompleted(errorCode: Int)
+    func unShareCompleted()
+    func updateShareWithError(idRemoteShared: Int)
+}

+ 228 - 0
iOSClient/Share/NCSharePaging.swift

@@ -0,0 +1,228 @@
+//
+//  NCSharePaging.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 25/07/2019.
+//  Copyright © 2019 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  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 Foundation
+import Parchment
+
+class NCSharePaging: UIViewController {
+    
+    private let pagingViewController = NCShareHeaderViewController()
+    
+    @objc var metadata: tableMetadata?
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        
+        pagingViewController.metadata = metadata
+        
+        // Navigation Controller
+        var image = CCGraphics.changeThemingColorImage(UIImage(named: "exit")!, width: 40, height: 40, color: UIColor.gray)
+        image = image?.withRenderingMode(.alwaysOriginal)
+        self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: self, action: #selector(exitTapped))
+        
+        // Pagination
+        addChild(pagingViewController)
+        view.addSubview(pagingViewController.view)
+        pagingViewController.didMove(toParent: self)
+        
+        pagingViewController.selectedTextColor = .black
+        pagingViewController.indicatorColor = .black
+        pagingViewController.indicatorOptions = .visible(
+            height: 1,
+            zIndex: Int.max,
+            spacing: .zero,
+            insets: .zero
+        )
+        
+        // Contrain the paging view to all edges.
+        pagingViewController.view.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            pagingViewController.view.topAnchor.constraint(equalTo: view.topAnchor),
+            pagingViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
+            pagingViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
+            pagingViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
+            ])
+        
+        // Set our data source and delegate.
+        pagingViewController.dataSource = self
+    }
+    
+    @objc func exitTapped() {
+        self.dismiss(animated: true, completion: nil)
+    }
+}
+
+extension NCSharePaging: PagingViewControllerDataSource {
+    
+    func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, viewControllerForIndex index: Int) -> UIViewController {
+        
+        let height = pagingViewController.options.menuHeight + NCSharePagingView.HeaderHeight
+        
+        switch index {
+        case 0:
+            let viewController = UIStoryboard(name: "NCActivity", bundle: nil).instantiateInitialViewController() as! NCActivity
+            viewController.insets = UIEdgeInsets(top: height, left: 0, bottom: 0, right: 0)
+            viewController.refreshControlEnable = false
+            viewController.didSelectItemEnable = false
+            viewController.filterFileID = metadata!.fileID
+            return viewController
+        case 1:
+            let viewController = UIStoryboard(name: "NCShare", bundle: nil).instantiateViewController(withIdentifier: "comments") as! NCShareComments
+            viewController.metadata = metadata!
+            return viewController
+        case 2:
+            let viewController = UIStoryboard(name: "NCShare", bundle: nil).instantiateViewController(withIdentifier: "sharing") as! NCShare
+            viewController.metadata = metadata!
+            viewController.height = height
+            return viewController
+        default:
+            return UIViewController()
+        }
+    }
+    
+    func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemForIndex index: Int) -> T {
+        switch index {
+        case 0:
+            return PagingIndexItem(index: index, title: NSLocalizedString("_activity_", comment: "")) as! T
+        case 1:
+            return PagingIndexItem(index: index, title: NSLocalizedString("_comments_", comment: "")) as! T
+        case 2:
+            return PagingIndexItem(index: index, title: NSLocalizedString("_sharing_", comment: "")) as! T
+        default:
+            return PagingIndexItem(index: index, title: "") as! T
+        }
+    }
+    
+    func numberOfViewControllers<T>(in: PagingViewController<T>) -> Int{
+        return 3
+    }
+}
+
+class NCShareHeaderViewController: PagingViewController<PagingIndexItem> {
+    
+    public var image: UIImage?
+    public var metadata: tableMetadata?
+    
+    override func loadView() {
+        view = NCSharePagingView(
+            options: options,
+            collectionView: collectionView,
+            pageView: pageViewController.view,
+            metadata: metadata
+        )
+    }
+}
+
+class NCSharePagingView: PagingView {
+    
+    static let HeaderHeight: CGFloat = 200
+    var metadata: tableMetadata?
+    
+    var headerHeightConstraint: NSLayoutConstraint?
+    
+    public init(options: Parchment.PagingOptions, collectionView: UICollectionView, pageView: UIView, metadata: tableMetadata?) {
+        super.init(options: options, collectionView: collectionView, pageView: pageView)
+        
+        self.metadata = metadata
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    override func setupConstraints() {
+        
+        let headerView = Bundle.main.loadNibNamed("NCShareHeaderView", owner: self, options: nil)?.first as! NCShareHeaderView
+        
+        if FileManager.default.fileExists(atPath: CCUtility.getDirectoryProviderStorageIconFileID(metadata!.fileID, fileNameView: metadata!.fileNameView)) {
+            headerView.imageView.image = UIImage.init(contentsOfFile: CCUtility.getDirectoryProviderStorageIconFileID(metadata!.fileID, fileNameView: metadata!.fileNameView))
+        } else {
+            if metadata!.iconName.count > 0 {
+                headerView.imageView.image = UIImage.init(named: metadata!.iconName)
+            } else if metadata!.directory {
+                let image = UIImage.init(named: "folder")!
+                headerView.imageView.image = CCGraphics.changeThemingColorImage(image, width: image.size.width*2, height: image.size.height*2, color: NCBrandColor.sharedInstance.brandElement)
+            } else {
+                headerView.imageView.image = UIImage.init(named: "file")
+            }
+        }
+        headerView.fileName.text = metadata?.fileNameView
+        if metadata!.favorite {
+            headerView.favorite.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "favorite"), width: 40, height: 40, color: NCBrandColor.sharedInstance.yellowFavorite), for: .normal)
+        } else {
+            headerView.favorite.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "favorite"), width: 40, height: 40, color: NCBrandColor.sharedInstance.textInfo), for: .normal)
+        }
+        headerView.info.text = CCUtility.transformedSize(metadata!.size) + ", " + CCUtility.dateDiff(metadata!.date as Date)
+        addSubview(headerView)
+        
+        pageView.translatesAutoresizingMaskIntoConstraints = false
+        collectionView.translatesAutoresizingMaskIntoConstraints = false
+        headerView.translatesAutoresizingMaskIntoConstraints = false
+        
+        headerHeightConstraint = headerView.heightAnchor.constraint(
+            equalToConstant: NCSharePagingView.HeaderHeight
+        )
+        headerHeightConstraint?.isActive = true
+        
+        NSLayoutConstraint.activate([
+            collectionView.leadingAnchor.constraint(equalTo: leadingAnchor),
+            collectionView.trailingAnchor.constraint(equalTo: trailingAnchor),
+            collectionView.heightAnchor.constraint(equalToConstant: options.menuHeight),
+            collectionView.topAnchor.constraint(equalTo: headerView.bottomAnchor),
+            
+            headerView.topAnchor.constraint(equalTo: topAnchor),
+            headerView.leadingAnchor.constraint(equalTo: leadingAnchor),
+            headerView.trailingAnchor.constraint(equalTo: trailingAnchor),
+            
+            pageView.leadingAnchor.constraint(equalTo: leadingAnchor),
+            pageView.trailingAnchor.constraint(equalTo: trailingAnchor),
+            pageView.bottomAnchor.constraint(equalTo: bottomAnchor),
+            pageView.topAnchor.constraint(equalTo: topAnchor)
+            ])
+    }
+}
+
+class NCShareHeaderView: UIView {
+    
+    @IBOutlet weak var imageView: UIImageView!
+    @IBOutlet weak var fileName: UILabel!
+    @IBOutlet weak var info: UILabel!
+    @IBOutlet weak var favorite: UIButton!
+}
+
+// MARK: - Comments
+
+class NCShareComments: UIViewController {
+    
+    var metadata: tableMetadata?
+    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        
+        OCNetworking.sharedManager()?.getCommentsWithAccount(appDelegate.activeAccount, fileID: metadata?.fileID, completion: { (account, list, message, errorCode) in
+            print("ciao")
+        })
+    }
+}

+ 136 - 0
iOSClient/Share/NCShareUserMenuView.swift

@@ -0,0 +1,136 @@
+//
+//  NCShareUserMenuView.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 25/07/2019.
+//  Copyright © 2019 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  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 Foundation
+import FSCalendar
+
+class NCShareUserMenuView: UIView, UIGestureRecognizerDelegate, NCShareNetworkingDelegate, FSCalendarDelegate, FSCalendarDelegateAppearance {
+    
+    @IBOutlet weak var switchCanReshare: UISwitch!
+    @IBOutlet weak var labelCanReshare: UILabel!
+    
+    @IBOutlet weak var switchSetExpirationDate: UISwitch!
+    @IBOutlet weak var labelSetExpirationDate: UILabel!
+    @IBOutlet weak var fieldSetExpirationDate: UITextField!
+    
+    @IBOutlet weak var imageNoteToRecipient: UIImageView!
+    @IBOutlet weak var labelNoteToRecipient: UILabel!
+    @IBOutlet weak var fieldNoteToRecipient: UITextField!
+    
+    @IBOutlet weak var buttonUnshare: UIButton!
+    @IBOutlet weak var labelUnshare: UILabel!
+    @IBOutlet weak var imageUnshare: UIImageView!
+    
+    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
+    
+    public let width: CGFloat = 250
+    public let height: CGFloat = 340
+    private var tableShare: tableShare?
+    public var metadata: tableMetadata?
+    
+    public var viewWindow: UIView?
+    public var viewWindowCalendar: UIView?
+    
+    override func awakeFromNib() {
+        
+        self.frame.size.width = width
+        self.frame.size.height = height
+        
+        layer.borderColor = UIColor.lightGray.cgColor
+        layer.borderWidth = 0.5
+        layer.cornerRadius = 5
+        layer.masksToBounds = false
+        layer.shadowOffset = CGSize(width: 2, height: 2)
+        layer.shadowOpacity = 0.2
+        
+        switchCanReshare.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
+        switchCanReshare.onTintColor = NCBrandColor.sharedInstance.brand
+        switchSetExpirationDate.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
+        switchSetExpirationDate.onTintColor = NCBrandColor.sharedInstance.brand
+        
+        fieldSetExpirationDate.inputView = UIView()
+        
+        imageNoteToRecipient.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "file_txt"), width: 100, height: 100, color: UIColor(red: 76/255, green: 76/255, blue: 76/255, alpha: 1))
+        imageUnshare.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "trash"), width: 100, height: 100, color: UIColor(red: 76/255, green: 76/255, blue: 76/255, alpha: 1))
+    }
+    
+    func unLoad() {
+        viewWindowCalendar?.removeFromSuperview()
+        viewWindow?.removeFromSuperview()
+        
+        viewWindowCalendar = nil
+        viewWindow = nil
+    }
+    
+    func reloadData(idRemoteShared: Int) {
+        tableShare = NCManageDatabase.sharedInstance.getTableShare(account: metadata!.account, idRemoteShared: idRemoteShared)
+        
+        // Can reshare
+        if tableShare != nil && tableShare!.permissions > Int(k_read_share_permission) {
+            //switchAllowEditing.setOn(true, animated: false)
+        } else {
+            //switchAllowEditing.setOn(false, animated: false)
+        }
+        
+        // Set expiration date
+        if tableShare != nil && tableShare!.expirationDate != nil {
+            switchSetExpirationDate.setOn(true, animated: false)
+            fieldSetExpirationDate.isEnabled = true
+            
+            let dateFormatter = DateFormatter()
+            dateFormatter.formatterBehavior = .behavior10_4
+            dateFormatter.dateStyle = .medium
+            fieldSetExpirationDate.text = dateFormatter.string(from: tableShare!.expirationDate! as Date)
+        } else {
+            switchSetExpirationDate.setOn(false, animated: false)
+            fieldSetExpirationDate.isEnabled = false
+            fieldSetExpirationDate.text = ""
+        }
+        
+        // Note to recipient
+        if tableShare != nil {
+            fieldNoteToRecipient.text = tableShare!.note
+        } else {
+            fieldNoteToRecipient.text = ""
+        }
+    }
+    
+    // delegate networking
+    
+    func readShareCompleted(errorCode: Int) {
+        reloadData(idRemoteShared: tableShare?.idRemoteShared ?? 0)
+    }
+    
+    func shareCompleted(errorCode: Int) {
+        unLoad()
+        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadDataNCShare"), object: nil, userInfo: nil)
+    }
+    
+    func unShareCompleted() {
+        unLoad()
+        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadDataNCShare"), object: nil, userInfo: nil)
+    }
+    
+    func updateShareWithError(idRemoteShared: Int) {
+        reloadData(idRemoteShared: idRemoteShared)
+    }
+}

+ 148 - 0
iOSClient/Share/NCShareUserMenuView.xib

@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina3_5" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view opaque="NO" contentMode="scaleToFill" id="iN0-l3-epB" customClass="NCShareUserMenuView" customModule="Nextcloud" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="sjf-wF-y07">
+                    <rect key="frame" x="10" y="10" width="51" height="31"/>
+                </switch>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Can reshare" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IHP-P8-rm2">
+                    <rect key="frame" x="70" y="18" width="240" height="15"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="15" id="lcS-7f-bEg"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                    <nil key="textColor"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="dB8-1M-WZr">
+                    <rect key="frame" x="10" y="61" width="51" height="31"/>
+                </switch>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Set expiration date" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qll-9F-4DA">
+                    <rect key="frame" x="70" y="69" width="240" height="15"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="15" id="KyU-PL-PRI"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                    <nil key="textColor"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="ymk-0u-ddH">
+                    <rect key="frame" x="70" y="94" width="240" height="30"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="30" id="G4f-LN-v7k"/>
+                    </constraints>
+                    <nil key="textColor"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                    <textInputTraits key="textInputTraits"/>
+                </textField>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="file_txt" translatesAutoresizingMaskIntoConstraints="NO" id="F4T-wQ-tBU">
+                    <rect key="frame" x="13" y="144" width="25" height="25"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="25" id="7uC-w2-XPl"/>
+                        <constraint firstAttribute="width" constant="25" id="YkI-0i-Hbj"/>
+                    </constraints>
+                </imageView>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Note to recipient" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="grT-sd-j7q">
+                    <rect key="frame" x="70" y="149" width="245" height="15"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="15" id="gof-GU-toa"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                    <nil key="textColor"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="FyH-3p-EdC">
+                    <rect key="frame" x="70" y="174" width="240" height="30"/>
+                    <nil key="textColor"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                    <textInputTraits key="textInputTraits"/>
+                </textField>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="trash" translatesAutoresizingMaskIntoConstraints="NO" id="hr8-Qe-xD0" userLabel="Image Delete Share Link">
+                    <rect key="frame" x="13" y="224" width="25" height="25"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="25" id="Ktg-2f-87b"/>
+                        <constraint firstAttribute="width" constant="25" id="ZJu-Y5-U67"/>
+                    </constraints>
+                </imageView>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Unshare" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ff4-JE-zGU">
+                    <rect key="frame" x="70" y="229" width="240" height="15"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="15" id="gYi-S0-IOg"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                    <nil key="textColor"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CLA-UL-mYb">
+                    <rect key="frame" x="13" y="224" width="287" height="25"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="25" id="fWP-XF-kQx"/>
+                    </constraints>
+                </button>
+            </subviews>
+            <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+            <constraints>
+                <constraint firstItem="Ff4-JE-zGU" firstAttribute="centerY" secondItem="hr8-Qe-xD0" secondAttribute="centerY" id="0WP-PE-HTp"/>
+                <constraint firstItem="IHP-P8-rm2" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="2RV-rL-sYG"/>
+                <constraint firstItem="grT-sd-j7q" firstAttribute="centerY" secondItem="F4T-wQ-tBU" secondAttribute="centerY" id="4KH-Py-OgY"/>
+                <constraint firstItem="qll-9F-4DA" firstAttribute="centerY" secondItem="dB8-1M-WZr" secondAttribute="centerY" id="5QL-7q-jdE"/>
+                <constraint firstItem="FyH-3p-EdC" firstAttribute="top" secondItem="grT-sd-j7q" secondAttribute="bottom" constant="10" id="7al-MO-ezA"/>
+                <constraint firstItem="CLA-UL-mYb" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="13" id="8lb-ki-xfh"/>
+                <constraint firstAttribute="trailing" secondItem="ymk-0u-ddH" secondAttribute="trailing" constant="10" id="Chd-iQ-EdR"/>
+                <constraint firstItem="sjf-wF-y07" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="EW6-D3-tml"/>
+                <constraint firstItem="IHP-P8-rm2" firstAttribute="centerY" secondItem="sjf-wF-y07" secondAttribute="centerY" id="HiA-pE-L6l"/>
+                <constraint firstAttribute="trailing" secondItem="grT-sd-j7q" secondAttribute="trailing" constant="5" id="Nyn-RD-jTz"/>
+                <constraint firstItem="dB8-1M-WZr" firstAttribute="top" secondItem="sjf-wF-y07" secondAttribute="bottom" constant="20" id="P2C-Pq-hSl"/>
+                <constraint firstAttribute="trailing" secondItem="FyH-3p-EdC" secondAttribute="trailing" constant="10" id="RhU-wl-afT"/>
+                <constraint firstItem="sjf-wF-y07" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="TFC-63-muN"/>
+                <constraint firstItem="FyH-3p-EdC" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="TXe-jF-DdS"/>
+                <constraint firstItem="dB8-1M-WZr" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="Ua2-93-05m"/>
+                <constraint firstItem="CLA-UL-mYb" firstAttribute="centerY" secondItem="hr8-Qe-xD0" secondAttribute="centerY" id="Zoj-Ro-jFv"/>
+                <constraint firstAttribute="trailing" secondItem="IHP-P8-rm2" secondAttribute="trailing" constant="10" id="Zsj-Ja-2wq"/>
+                <constraint firstItem="F4T-wQ-tBU" firstAttribute="top" secondItem="ymk-0u-ddH" secondAttribute="bottom" constant="20" id="aj8-2w-ySe"/>
+                <constraint firstItem="hr8-Qe-xD0" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="13" id="elF-be-kqS"/>
+                <constraint firstItem="hr8-Qe-xD0" firstAttribute="top" secondItem="FyH-3p-EdC" secondAttribute="bottom" constant="20" id="itX-To-Hbm"/>
+                <constraint firstItem="ymk-0u-ddH" firstAttribute="top" secondItem="qll-9F-4DA" secondAttribute="bottom" constant="10" id="k4G-Yb-xBy"/>
+                <constraint firstItem="grT-sd-j7q" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="lRX-gv-77N"/>
+                <constraint firstAttribute="trailing" secondItem="Ff4-JE-zGU" secondAttribute="trailing" constant="10" id="ljN-WF-OVS"/>
+                <constraint firstAttribute="trailing" secondItem="CLA-UL-mYb" secondAttribute="trailing" constant="20" id="oEb-Su-Nu5"/>
+                <constraint firstItem="qll-9F-4DA" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="qEq-8J-iTD"/>
+                <constraint firstItem="ymk-0u-ddH" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="qrv-wQ-p6E"/>
+                <constraint firstAttribute="trailing" secondItem="qll-9F-4DA" secondAttribute="trailing" constant="10" id="vaT-9Q-m84"/>
+                <constraint firstItem="F4T-wQ-tBU" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="13" id="x4S-GE-lJ8"/>
+                <constraint firstItem="Ff4-JE-zGU" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="zc7-db-OeN"/>
+            </constraints>
+            <connections>
+                <outlet property="buttonUnshare" destination="CLA-UL-mYb" id="fwq-pr-JO0"/>
+                <outlet property="fieldNoteToRecipient" destination="FyH-3p-EdC" id="389-TM-dhC"/>
+                <outlet property="fieldSetExpirationDate" destination="ymk-0u-ddH" id="erm-BP-BWD"/>
+                <outlet property="imageNoteToRecipient" destination="F4T-wQ-tBU" id="hv7-Ln-aYs"/>
+                <outlet property="imageUnshare" destination="hr8-Qe-xD0" id="kfC-D4-Ak0"/>
+                <outlet property="labelCanReshare" destination="IHP-P8-rm2" id="dkZ-O3-1cB"/>
+                <outlet property="labelNoteToRecipient" destination="grT-sd-j7q" id="0Rj-H1-Bqv"/>
+                <outlet property="labelSetExpirationDate" destination="qll-9F-4DA" id="SsD-jd-FX1"/>
+                <outlet property="labelUnshare" destination="Ff4-JE-zGU" id="Ubq-EL-yOd"/>
+                <outlet property="switchCanReshare" destination="sjf-wF-y07" id="3jS-Gr-YMT"/>
+                <outlet property="switchSetExpirationDate" destination="dB8-1M-WZr" id="0Ki-ah-3FE"/>
+            </connections>
+            <point key="canvasLocation" x="2" y="196"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="file_txt" width="300" height="300"/>
+        <image name="trash" width="300" height="300"/>
+    </resources>
+</document>